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)
159 [(UNSPECV_BLOCKAGE 0)
160 (UNSPECV_STACK_PROBE 1)
169 (UNSPECV_CMPXCHG_1 10)
170 (UNSPECV_CMPXCHG_2 11)
175 ;; Registers by name.
186 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
189 ;; In C guard expressions, put expressions which may be compile-time
190 ;; constants first. This allows for better optimization. For
191 ;; example, write "TARGET_64BIT && reload_completed", not
192 ;; "reload_completed && TARGET_64BIT".
195 ;; Processor type. This attribute must exactly match the processor_type
196 ;; enumeration in i386.h.
197 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
198 (const (symbol_ref "ix86_tune")))
200 ;; A basic instruction type. Refinements due to arguments to be
201 ;; provided in other attributes.
204 alu,alu1,negnot,imov,imovx,lea,
205 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
206 icmp,test,ibr,setcc,icmov,
207 push,pop,call,callv,leave,
209 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
210 sselog,sselog1,sseiadd,sseishft,sseimul,
211 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
212 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
213 (const_string "other"))
215 ;; Main data type used by the insn
217 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
218 (const_string "unknown"))
220 ;; The CPU unit operations uses.
221 (define_attr "unit" "integer,i387,sse,mmx,unknown"
222 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
223 (const_string "i387")
224 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
225 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
227 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
229 (eq_attr "type" "other")
230 (const_string "unknown")]
231 (const_string "integer")))
233 ;; The (bounding maximum) length of an instruction immediate.
234 (define_attr "length_immediate" ""
235 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
237 (eq_attr "unit" "i387,sse,mmx")
239 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
241 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
242 (eq_attr "type" "imov,test")
243 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
244 (eq_attr "type" "call")
245 (if_then_else (match_operand 0 "constant_call_address_operand" "")
248 (eq_attr "type" "callv")
249 (if_then_else (match_operand 1 "constant_call_address_operand" "")
252 ;; We don't know the size before shorten_branches. Expect
253 ;; the instruction to fit for better scheduling.
254 (eq_attr "type" "ibr")
257 (symbol_ref "/* Update immediate_length and other attributes! */
258 gcc_unreachable (),1")))
260 ;; The (bounding maximum) length of an instruction address.
261 (define_attr "length_address" ""
262 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
264 (and (eq_attr "type" "call")
265 (match_operand 0 "constant_call_address_operand" ""))
267 (and (eq_attr "type" "callv")
268 (match_operand 1 "constant_call_address_operand" ""))
271 (symbol_ref "ix86_attr_length_address_default (insn)")))
273 ;; Set when length prefix is used.
274 (define_attr "prefix_data16" ""
275 (if_then_else (ior (eq_attr "mode" "HI")
276 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
280 ;; Set when string REP prefix is used.
281 (define_attr "prefix_rep" ""
282 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
286 ;; Set when 0f opcode prefix is used.
287 (define_attr "prefix_0f" ""
289 (ior (eq_attr "type" "imovx,setcc,icmov")
290 (eq_attr "unit" "sse,mmx"))
294 ;; Set when REX opcode prefix is used.
295 (define_attr "prefix_rex" ""
296 (cond [(and (eq_attr "mode" "DI")
297 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
299 (and (eq_attr "mode" "QI")
300 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
303 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
309 ;; Set when modrm byte is used.
310 (define_attr "modrm" ""
311 (cond [(eq_attr "type" "str,cld,leave")
313 (eq_attr "unit" "i387")
315 (and (eq_attr "type" "incdec")
316 (ior (match_operand:SI 1 "register_operand" "")
317 (match_operand:HI 1 "register_operand" "")))
319 (and (eq_attr "type" "push")
320 (not (match_operand 1 "memory_operand" "")))
322 (and (eq_attr "type" "pop")
323 (not (match_operand 0 "memory_operand" "")))
325 (and (eq_attr "type" "imov")
326 (ior (and (match_operand 0 "register_operand" "")
327 (match_operand 1 "immediate_operand" ""))
328 (ior (and (match_operand 0 "ax_reg_operand" "")
329 (match_operand 1 "memory_displacement_only_operand" ""))
330 (and (match_operand 0 "memory_displacement_only_operand" "")
331 (match_operand 1 "ax_reg_operand" "")))))
333 (and (eq_attr "type" "call")
334 (match_operand 0 "constant_call_address_operand" ""))
336 (and (eq_attr "type" "callv")
337 (match_operand 1 "constant_call_address_operand" ""))
342 ;; The (bounding maximum) length of an instruction in bytes.
343 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
344 ;; Later we may want to split them and compute proper length as for
346 (define_attr "length" ""
347 (cond [(eq_attr "type" "other,multi,fistp,frndint")
349 (eq_attr "type" "fcmp")
351 (eq_attr "unit" "i387")
353 (plus (attr "prefix_data16")
354 (attr "length_address")))]
355 (plus (plus (attr "modrm")
356 (plus (attr "prefix_0f")
357 (plus (attr "prefix_rex")
359 (plus (attr "prefix_rep")
360 (plus (attr "prefix_data16")
361 (plus (attr "length_immediate")
362 (attr "length_address")))))))
364 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
365 ;; `store' if there is a simple memory reference therein, or `unknown'
366 ;; if the instruction is complex.
368 (define_attr "memory" "none,load,store,both,unknown"
369 (cond [(eq_attr "type" "other,multi,str")
370 (const_string "unknown")
371 (eq_attr "type" "lea,fcmov,fpspc,cld")
372 (const_string "none")
373 (eq_attr "type" "fistp,leave")
374 (const_string "both")
375 (eq_attr "type" "frndint")
376 (const_string "load")
377 (eq_attr "type" "push")
378 (if_then_else (match_operand 1 "memory_operand" "")
379 (const_string "both")
380 (const_string "store"))
381 (eq_attr "type" "pop")
382 (if_then_else (match_operand 0 "memory_operand" "")
383 (const_string "both")
384 (const_string "load"))
385 (eq_attr "type" "setcc")
386 (if_then_else (match_operand 0 "memory_operand" "")
387 (const_string "store")
388 (const_string "none"))
389 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
390 (if_then_else (ior (match_operand 0 "memory_operand" "")
391 (match_operand 1 "memory_operand" ""))
392 (const_string "load")
393 (const_string "none"))
394 (eq_attr "type" "ibr")
395 (if_then_else (match_operand 0 "memory_operand" "")
396 (const_string "load")
397 (const_string "none"))
398 (eq_attr "type" "call")
399 (if_then_else (match_operand 0 "constant_call_address_operand" "")
400 (const_string "none")
401 (const_string "load"))
402 (eq_attr "type" "callv")
403 (if_then_else (match_operand 1 "constant_call_address_operand" "")
404 (const_string "none")
405 (const_string "load"))
406 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
407 (match_operand 1 "memory_operand" ""))
408 (const_string "both")
409 (and (match_operand 0 "memory_operand" "")
410 (match_operand 1 "memory_operand" ""))
411 (const_string "both")
412 (match_operand 0 "memory_operand" "")
413 (const_string "store")
414 (match_operand 1 "memory_operand" "")
415 (const_string "load")
417 "!alu1,negnot,ishift1,
418 imov,imovx,icmp,test,
420 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
421 mmx,mmxmov,mmxcmp,mmxcvt")
422 (match_operand 2 "memory_operand" ""))
423 (const_string "load")
424 (and (eq_attr "type" "icmov")
425 (match_operand 3 "memory_operand" ""))
426 (const_string "load")
428 (const_string "none")))
430 ;; Indicates if an instruction has both an immediate and a displacement.
432 (define_attr "imm_disp" "false,true,unknown"
433 (cond [(eq_attr "type" "other,multi")
434 (const_string "unknown")
435 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
436 (and (match_operand 0 "memory_displacement_operand" "")
437 (match_operand 1 "immediate_operand" "")))
438 (const_string "true")
439 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
440 (and (match_operand 0 "memory_displacement_operand" "")
441 (match_operand 2 "immediate_operand" "")))
442 (const_string "true")
444 (const_string "false")))
446 ;; Indicates if an FP operation has an integer source.
448 (define_attr "fp_int_src" "false,true"
449 (const_string "false"))
451 ;; Defines rounding mode of an FP operation.
453 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
454 (const_string "any"))
456 ;; Describe a user's asm statement.
457 (define_asm_attributes
458 [(set_attr "length" "128")
459 (set_attr "type" "multi")])
461 ;; All x87 floating point modes
462 (define_mode_macro X87MODEF [SF DF XF])
464 ;; All integer modes handled by x87 fisttp operator.
465 (define_mode_macro X87MODEI [HI SI DI])
467 ;; All integer modes handled by integer x87 operators.
468 (define_mode_macro X87MODEI12 [HI SI])
470 ;; All SSE floating point modes
471 (define_mode_macro SSEMODEF [SF DF])
473 ;; All integer modes handled by SSE cvtts?2si* operators.
474 (define_mode_macro SSEMODEI24 [SI DI])
477 ;; Scheduling descriptions
479 (include "pentium.md")
482 (include "athlon.md")
486 ;; Operand and operator predicates and constraints
488 (include "predicates.md")
489 (include "constraints.md")
492 ;; Compare instructions.
494 ;; All compare insns have expanders that save the operands away without
495 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
496 ;; after the cmp) will actually emit the cmpM.
498 (define_expand "cmpti"
499 [(set (reg:CC FLAGS_REG)
500 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
501 (match_operand:TI 1 "x86_64_general_operand" "")))]
504 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
505 operands[0] = force_reg (TImode, operands[0]);
506 ix86_compare_op0 = operands[0];
507 ix86_compare_op1 = operands[1];
511 (define_expand "cmpdi"
512 [(set (reg:CC FLAGS_REG)
513 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
514 (match_operand:DI 1 "x86_64_general_operand" "")))]
517 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
518 operands[0] = force_reg (DImode, operands[0]);
519 ix86_compare_op0 = operands[0];
520 ix86_compare_op1 = operands[1];
524 (define_expand "cmpsi"
525 [(set (reg:CC FLAGS_REG)
526 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
527 (match_operand:SI 1 "general_operand" "")))]
530 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
531 operands[0] = force_reg (SImode, operands[0]);
532 ix86_compare_op0 = operands[0];
533 ix86_compare_op1 = operands[1];
537 (define_expand "cmphi"
538 [(set (reg:CC FLAGS_REG)
539 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
540 (match_operand:HI 1 "general_operand" "")))]
543 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
544 operands[0] = force_reg (HImode, operands[0]);
545 ix86_compare_op0 = operands[0];
546 ix86_compare_op1 = operands[1];
550 (define_expand "cmpqi"
551 [(set (reg:CC FLAGS_REG)
552 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
553 (match_operand:QI 1 "general_operand" "")))]
556 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
557 operands[0] = force_reg (QImode, operands[0]);
558 ix86_compare_op0 = operands[0];
559 ix86_compare_op1 = operands[1];
563 (define_insn "cmpdi_ccno_1_rex64"
564 [(set (reg FLAGS_REG)
565 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
566 (match_operand:DI 1 "const0_operand" "n,n")))]
567 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
569 test{q}\t{%0, %0|%0, %0}
570 cmp{q}\t{%1, %0|%0, %1}"
571 [(set_attr "type" "test,icmp")
572 (set_attr "length_immediate" "0,1")
573 (set_attr "mode" "DI")])
575 (define_insn "*cmpdi_minus_1_rex64"
576 [(set (reg FLAGS_REG)
577 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
578 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
580 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
581 "cmp{q}\t{%1, %0|%0, %1}"
582 [(set_attr "type" "icmp")
583 (set_attr "mode" "DI")])
585 (define_expand "cmpdi_1_rex64"
586 [(set (reg:CC FLAGS_REG)
587 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
588 (match_operand:DI 1 "general_operand" "")))]
592 (define_insn "cmpdi_1_insn_rex64"
593 [(set (reg FLAGS_REG)
594 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
595 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
596 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
597 "cmp{q}\t{%1, %0|%0, %1}"
598 [(set_attr "type" "icmp")
599 (set_attr "mode" "DI")])
602 (define_insn "*cmpsi_ccno_1"
603 [(set (reg FLAGS_REG)
604 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
605 (match_operand:SI 1 "const0_operand" "n,n")))]
606 "ix86_match_ccmode (insn, CCNOmode)"
608 test{l}\t{%0, %0|%0, %0}
609 cmp{l}\t{%1, %0|%0, %1}"
610 [(set_attr "type" "test,icmp")
611 (set_attr "length_immediate" "0,1")
612 (set_attr "mode" "SI")])
614 (define_insn "*cmpsi_minus_1"
615 [(set (reg FLAGS_REG)
616 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
617 (match_operand:SI 1 "general_operand" "ri,mr"))
619 "ix86_match_ccmode (insn, CCGOCmode)"
620 "cmp{l}\t{%1, %0|%0, %1}"
621 [(set_attr "type" "icmp")
622 (set_attr "mode" "SI")])
624 (define_expand "cmpsi_1"
625 [(set (reg:CC FLAGS_REG)
626 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
627 (match_operand:SI 1 "general_operand" "ri,mr")))]
631 (define_insn "*cmpsi_1_insn"
632 [(set (reg FLAGS_REG)
633 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
634 (match_operand:SI 1 "general_operand" "ri,mr")))]
635 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
636 && ix86_match_ccmode (insn, CCmode)"
637 "cmp{l}\t{%1, %0|%0, %1}"
638 [(set_attr "type" "icmp")
639 (set_attr "mode" "SI")])
641 (define_insn "*cmphi_ccno_1"
642 [(set (reg FLAGS_REG)
643 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
644 (match_operand:HI 1 "const0_operand" "n,n")))]
645 "ix86_match_ccmode (insn, CCNOmode)"
647 test{w}\t{%0, %0|%0, %0}
648 cmp{w}\t{%1, %0|%0, %1}"
649 [(set_attr "type" "test,icmp")
650 (set_attr "length_immediate" "0,1")
651 (set_attr "mode" "HI")])
653 (define_insn "*cmphi_minus_1"
654 [(set (reg FLAGS_REG)
655 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
656 (match_operand:HI 1 "general_operand" "ri,mr"))
658 "ix86_match_ccmode (insn, CCGOCmode)"
659 "cmp{w}\t{%1, %0|%0, %1}"
660 [(set_attr "type" "icmp")
661 (set_attr "mode" "HI")])
663 (define_insn "*cmphi_1"
664 [(set (reg FLAGS_REG)
665 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
666 (match_operand:HI 1 "general_operand" "ri,mr")))]
667 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
668 && ix86_match_ccmode (insn, CCmode)"
669 "cmp{w}\t{%1, %0|%0, %1}"
670 [(set_attr "type" "icmp")
671 (set_attr "mode" "HI")])
673 (define_insn "*cmpqi_ccno_1"
674 [(set (reg FLAGS_REG)
675 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
676 (match_operand:QI 1 "const0_operand" "n,n")))]
677 "ix86_match_ccmode (insn, CCNOmode)"
679 test{b}\t{%0, %0|%0, %0}
680 cmp{b}\t{$0, %0|%0, 0}"
681 [(set_attr "type" "test,icmp")
682 (set_attr "length_immediate" "0,1")
683 (set_attr "mode" "QI")])
685 (define_insn "*cmpqi_1"
686 [(set (reg FLAGS_REG)
687 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
688 (match_operand:QI 1 "general_operand" "qi,mq")))]
689 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
690 && ix86_match_ccmode (insn, CCmode)"
691 "cmp{b}\t{%1, %0|%0, %1}"
692 [(set_attr "type" "icmp")
693 (set_attr "mode" "QI")])
695 (define_insn "*cmpqi_minus_1"
696 [(set (reg FLAGS_REG)
697 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
698 (match_operand:QI 1 "general_operand" "qi,mq"))
700 "ix86_match_ccmode (insn, CCGOCmode)"
701 "cmp{b}\t{%1, %0|%0, %1}"
702 [(set_attr "type" "icmp")
703 (set_attr "mode" "QI")])
705 (define_insn "*cmpqi_ext_1"
706 [(set (reg FLAGS_REG)
708 (match_operand:QI 0 "general_operand" "Qm")
711 (match_operand 1 "ext_register_operand" "Q")
714 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
715 "cmp{b}\t{%h1, %0|%0, %h1}"
716 [(set_attr "type" "icmp")
717 (set_attr "mode" "QI")])
719 (define_insn "*cmpqi_ext_1_rex64"
720 [(set (reg FLAGS_REG)
722 (match_operand:QI 0 "register_operand" "Q")
725 (match_operand 1 "ext_register_operand" "Q")
728 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
729 "cmp{b}\t{%h1, %0|%0, %h1}"
730 [(set_attr "type" "icmp")
731 (set_attr "mode" "QI")])
733 (define_insn "*cmpqi_ext_2"
734 [(set (reg FLAGS_REG)
738 (match_operand 0 "ext_register_operand" "Q")
741 (match_operand:QI 1 "const0_operand" "n")))]
742 "ix86_match_ccmode (insn, CCNOmode)"
744 [(set_attr "type" "test")
745 (set_attr "length_immediate" "0")
746 (set_attr "mode" "QI")])
748 (define_expand "cmpqi_ext_3"
749 [(set (reg:CC FLAGS_REG)
753 (match_operand 0 "ext_register_operand" "")
756 (match_operand:QI 1 "general_operand" "")))]
760 (define_insn "cmpqi_ext_3_insn"
761 [(set (reg FLAGS_REG)
765 (match_operand 0 "ext_register_operand" "Q")
768 (match_operand:QI 1 "general_operand" "Qmn")))]
769 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
770 "cmp{b}\t{%1, %h0|%h0, %1}"
771 [(set_attr "type" "icmp")
772 (set_attr "mode" "QI")])
774 (define_insn "cmpqi_ext_3_insn_rex64"
775 [(set (reg FLAGS_REG)
779 (match_operand 0 "ext_register_operand" "Q")
782 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
783 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
784 "cmp{b}\t{%1, %h0|%h0, %1}"
785 [(set_attr "type" "icmp")
786 (set_attr "mode" "QI")])
788 (define_insn "*cmpqi_ext_4"
789 [(set (reg FLAGS_REG)
793 (match_operand 0 "ext_register_operand" "Q")
798 (match_operand 1 "ext_register_operand" "Q")
801 "ix86_match_ccmode (insn, CCmode)"
802 "cmp{b}\t{%h1, %h0|%h0, %h1}"
803 [(set_attr "type" "icmp")
804 (set_attr "mode" "QI")])
806 ;; These implement float point compares.
807 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
808 ;; which would allow mix and match FP modes on the compares. Which is what
809 ;; the old patterns did, but with many more of them.
811 (define_expand "cmpxf"
812 [(set (reg:CC FLAGS_REG)
813 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
814 (match_operand:XF 1 "nonmemory_operand" "")))]
817 ix86_compare_op0 = operands[0];
818 ix86_compare_op1 = operands[1];
822 (define_expand "cmpdf"
823 [(set (reg:CC FLAGS_REG)
824 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
825 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
826 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
828 ix86_compare_op0 = operands[0];
829 ix86_compare_op1 = operands[1];
833 (define_expand "cmpsf"
834 [(set (reg:CC FLAGS_REG)
835 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
836 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
837 "TARGET_80387 || TARGET_SSE_MATH"
839 ix86_compare_op0 = operands[0];
840 ix86_compare_op1 = operands[1];
844 ;; FP compares, step 1:
845 ;; Set the FP condition codes.
847 ;; CCFPmode compare with exceptions
848 ;; CCFPUmode compare with no exceptions
850 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
851 ;; used to manage the reg stack popping would not be preserved.
853 (define_insn "*cmpfp_0"
854 [(set (match_operand:HI 0 "register_operand" "=a")
857 (match_operand 1 "register_operand" "f")
858 (match_operand 2 "const0_operand" "X"))]
861 && FLOAT_MODE_P (GET_MODE (operands[1]))
862 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
863 "* return output_fp_compare (insn, operands, 0, 0);"
864 [(set_attr "type" "multi")
865 (set_attr "unit" "i387")
867 (cond [(match_operand:SF 1 "" "")
869 (match_operand:DF 1 "" "")
872 (const_string "XF")))])
874 (define_insn "*cmpfp_sf"
875 [(set (match_operand:HI 0 "register_operand" "=a")
878 (match_operand:SF 1 "register_operand" "f")
879 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
882 "* return output_fp_compare (insn, operands, 0, 0);"
883 [(set_attr "type" "multi")
884 (set_attr "unit" "i387")
885 (set_attr "mode" "SF")])
887 (define_insn "*cmpfp_df"
888 [(set (match_operand:HI 0 "register_operand" "=a")
891 (match_operand:DF 1 "register_operand" "f")
892 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
895 "* return output_fp_compare (insn, operands, 0, 0);"
896 [(set_attr "type" "multi")
897 (set_attr "unit" "i387")
898 (set_attr "mode" "DF")])
900 (define_insn "*cmpfp_xf"
901 [(set (match_operand:HI 0 "register_operand" "=a")
904 (match_operand:XF 1 "register_operand" "f")
905 (match_operand:XF 2 "register_operand" "f"))]
908 "* return output_fp_compare (insn, operands, 0, 0);"
909 [(set_attr "type" "multi")
910 (set_attr "unit" "i387")
911 (set_attr "mode" "XF")])
913 (define_insn "*cmpfp_u"
914 [(set (match_operand:HI 0 "register_operand" "=a")
917 (match_operand 1 "register_operand" "f")
918 (match_operand 2 "register_operand" "f"))]
921 && FLOAT_MODE_P (GET_MODE (operands[1]))
922 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
923 "* return output_fp_compare (insn, operands, 0, 1);"
924 [(set_attr "type" "multi")
925 (set_attr "unit" "i387")
927 (cond [(match_operand:SF 1 "" "")
929 (match_operand:DF 1 "" "")
932 (const_string "XF")))])
934 (define_insn "*cmpfp_<mode>"
935 [(set (match_operand:HI 0 "register_operand" "=a")
938 (match_operand 1 "register_operand" "f")
939 (match_operator 3 "float_operator"
940 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
942 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
943 && FLOAT_MODE_P (GET_MODE (operands[1]))
944 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
945 "* return output_fp_compare (insn, operands, 0, 0);"
946 [(set_attr "type" "multi")
947 (set_attr "unit" "i387")
948 (set_attr "fp_int_src" "true")
949 (set_attr "mode" "<MODE>")])
951 ;; FP compares, step 2
952 ;; Move the fpsw to ax.
954 (define_insn "x86_fnstsw_1"
955 [(set (match_operand:HI 0 "register_operand" "=a")
956 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
959 [(set_attr "length" "2")
960 (set_attr "mode" "SI")
961 (set_attr "unit" "i387")])
963 ;; FP compares, step 3
964 ;; Get ax into flags, general case.
966 (define_insn "x86_sahf_1"
967 [(set (reg:CC FLAGS_REG)
968 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
971 [(set_attr "length" "1")
972 (set_attr "athlon_decode" "vector")
973 (set_attr "mode" "SI")])
975 ;; Pentium Pro can do steps 1 through 3 in one go.
977 (define_insn "*cmpfp_i_mixed"
978 [(set (reg:CCFP FLAGS_REG)
979 (compare:CCFP (match_operand 0 "register_operand" "f,x")
980 (match_operand 1 "nonimmediate_operand" "f,xm")))]
982 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
983 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
984 "* return output_fp_compare (insn, operands, 1, 0);"
985 [(set_attr "type" "fcmp,ssecomi")
987 (if_then_else (match_operand:SF 1 "" "")
989 (const_string "DF")))
990 (set_attr "athlon_decode" "vector")])
992 (define_insn "*cmpfp_i_sse"
993 [(set (reg:CCFP FLAGS_REG)
994 (compare:CCFP (match_operand 0 "register_operand" "x")
995 (match_operand 1 "nonimmediate_operand" "xm")))]
997 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
998 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
999 "* return output_fp_compare (insn, operands, 1, 0);"
1000 [(set_attr "type" "ssecomi")
1002 (if_then_else (match_operand:SF 1 "" "")
1004 (const_string "DF")))
1005 (set_attr "athlon_decode" "vector")])
1007 (define_insn "*cmpfp_i_i387"
1008 [(set (reg:CCFP FLAGS_REG)
1009 (compare:CCFP (match_operand 0 "register_operand" "f")
1010 (match_operand 1 "register_operand" "f")))]
1011 "TARGET_80387 && TARGET_CMOVE
1012 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1013 && FLOAT_MODE_P (GET_MODE (operands[0]))
1014 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1015 "* return output_fp_compare (insn, operands, 1, 0);"
1016 [(set_attr "type" "fcmp")
1018 (cond [(match_operand:SF 1 "" "")
1020 (match_operand:DF 1 "" "")
1023 (const_string "XF")))
1024 (set_attr "athlon_decode" "vector")])
1026 (define_insn "*cmpfp_iu_mixed"
1027 [(set (reg:CCFPU FLAGS_REG)
1028 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1029 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1030 "TARGET_MIX_SSE_I387
1031 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1032 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033 "* return output_fp_compare (insn, operands, 1, 1);"
1034 [(set_attr "type" "fcmp,ssecomi")
1036 (if_then_else (match_operand:SF 1 "" "")
1038 (const_string "DF")))
1039 (set_attr "athlon_decode" "vector")])
1041 (define_insn "*cmpfp_iu_sse"
1042 [(set (reg:CCFPU FLAGS_REG)
1043 (compare:CCFPU (match_operand 0 "register_operand" "x")
1044 (match_operand 1 "nonimmediate_operand" "xm")))]
1046 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1047 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1048 "* return output_fp_compare (insn, operands, 1, 1);"
1049 [(set_attr "type" "ssecomi")
1051 (if_then_else (match_operand:SF 1 "" "")
1053 (const_string "DF")))
1054 (set_attr "athlon_decode" "vector")])
1056 (define_insn "*cmpfp_iu_387"
1057 [(set (reg:CCFPU FLAGS_REG)
1058 (compare:CCFPU (match_operand 0 "register_operand" "f")
1059 (match_operand 1 "register_operand" "f")))]
1060 "TARGET_80387 && TARGET_CMOVE
1061 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1062 && FLOAT_MODE_P (GET_MODE (operands[0]))
1063 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1064 "* return output_fp_compare (insn, operands, 1, 1);"
1065 [(set_attr "type" "fcmp")
1067 (cond [(match_operand:SF 1 "" "")
1069 (match_operand:DF 1 "" "")
1072 (const_string "XF")))
1073 (set_attr "athlon_decode" "vector")])
1075 ;; Move instructions.
1077 ;; General case of fullword move.
1079 (define_expand "movsi"
1080 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1081 (match_operand:SI 1 "general_operand" ""))]
1083 "ix86_expand_move (SImode, operands); DONE;")
1085 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1088 ;; %%% We don't use a post-inc memory reference because x86 is not a
1089 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1090 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1091 ;; targets without our curiosities, and it is just as easy to represent
1092 ;; this differently.
1094 (define_insn "*pushsi2"
1095 [(set (match_operand:SI 0 "push_operand" "=<")
1096 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1099 [(set_attr "type" "push")
1100 (set_attr "mode" "SI")])
1102 ;; For 64BIT abi we always round up to 8 bytes.
1103 (define_insn "*pushsi2_rex64"
1104 [(set (match_operand:SI 0 "push_operand" "=X")
1105 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1108 [(set_attr "type" "push")
1109 (set_attr "mode" "SI")])
1111 (define_insn "*pushsi2_prologue"
1112 [(set (match_operand:SI 0 "push_operand" "=<")
1113 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1114 (clobber (mem:BLK (scratch)))]
1117 [(set_attr "type" "push")
1118 (set_attr "mode" "SI")])
1120 (define_insn "*popsi1_epilogue"
1121 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1122 (mem:SI (reg:SI SP_REG)))
1123 (set (reg:SI SP_REG)
1124 (plus:SI (reg:SI SP_REG) (const_int 4)))
1125 (clobber (mem:BLK (scratch)))]
1128 [(set_attr "type" "pop")
1129 (set_attr "mode" "SI")])
1131 (define_insn "popsi1"
1132 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1133 (mem:SI (reg:SI SP_REG)))
1134 (set (reg:SI SP_REG)
1135 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1138 [(set_attr "type" "pop")
1139 (set_attr "mode" "SI")])
1141 (define_insn "*movsi_xor"
1142 [(set (match_operand:SI 0 "register_operand" "=r")
1143 (match_operand:SI 1 "const0_operand" "i"))
1144 (clobber (reg:CC FLAGS_REG))]
1145 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1146 "xor{l}\t{%0, %0|%0, %0}"
1147 [(set_attr "type" "alu1")
1148 (set_attr "mode" "SI")
1149 (set_attr "length_immediate" "0")])
1151 (define_insn "*movsi_or"
1152 [(set (match_operand:SI 0 "register_operand" "=r")
1153 (match_operand:SI 1 "immediate_operand" "i"))
1154 (clobber (reg:CC FLAGS_REG))]
1156 && operands[1] == constm1_rtx
1157 && (TARGET_PENTIUM || optimize_size)"
1159 operands[1] = constm1_rtx;
1160 return "or{l}\t{%1, %0|%0, %1}";
1162 [(set_attr "type" "alu1")
1163 (set_attr "mode" "SI")
1164 (set_attr "length_immediate" "1")])
1166 (define_insn "*movsi_1"
1167 [(set (match_operand:SI 0 "nonimmediate_operand"
1168 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1169 (match_operand:SI 1 "general_operand"
1170 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1171 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1173 switch (get_attr_type (insn))
1176 if (get_attr_mode (insn) == MODE_TI)
1177 return "pxor\t%0, %0";
1178 return "xorps\t%0, %0";
1181 switch (get_attr_mode (insn))
1184 return "movdqa\t{%1, %0|%0, %1}";
1186 return "movaps\t{%1, %0|%0, %1}";
1188 return "movd\t{%1, %0|%0, %1}";
1190 return "movss\t{%1, %0|%0, %1}";
1196 return "pxor\t%0, %0";
1199 if (get_attr_mode (insn) == MODE_DI)
1200 return "movq\t{%1, %0|%0, %1}";
1201 return "movd\t{%1, %0|%0, %1}";
1204 return "lea{l}\t{%1, %0|%0, %1}";
1207 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1208 return "mov{l}\t{%1, %0|%0, %1}";
1212 (cond [(eq_attr "alternative" "2")
1213 (const_string "mmxadd")
1214 (eq_attr "alternative" "3,4,5")
1215 (const_string "mmxmov")
1216 (eq_attr "alternative" "6")
1217 (const_string "sselog1")
1218 (eq_attr "alternative" "7,8,9,10,11")
1219 (const_string "ssemov")
1220 (match_operand:DI 1 "pic_32bit_operand" "")
1221 (const_string "lea")
1223 (const_string "imov")))
1225 (cond [(eq_attr "alternative" "2,3")
1227 (eq_attr "alternative" "6,7")
1229 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1230 (const_string "V4SF")
1231 (const_string "TI"))
1232 (and (eq_attr "alternative" "8,9,10,11")
1233 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1236 (const_string "SI")))])
1238 ;; Stores and loads of ax to arbitrary constant address.
1239 ;; We fake an second form of instruction to force reload to load address
1240 ;; into register when rax is not available
1241 (define_insn "*movabssi_1_rex64"
1242 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1243 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1244 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1246 movabs{l}\t{%1, %P0|%P0, %1}
1247 mov{l}\t{%1, %a0|%a0, %1}"
1248 [(set_attr "type" "imov")
1249 (set_attr "modrm" "0,*")
1250 (set_attr "length_address" "8,0")
1251 (set_attr "length_immediate" "0,*")
1252 (set_attr "memory" "store")
1253 (set_attr "mode" "SI")])
1255 (define_insn "*movabssi_2_rex64"
1256 [(set (match_operand:SI 0 "register_operand" "=a,r")
1257 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1258 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1260 movabs{l}\t{%P1, %0|%0, %P1}
1261 mov{l}\t{%a1, %0|%0, %a1}"
1262 [(set_attr "type" "imov")
1263 (set_attr "modrm" "0,*")
1264 (set_attr "length_address" "8,0")
1265 (set_attr "length_immediate" "0")
1266 (set_attr "memory" "load")
1267 (set_attr "mode" "SI")])
1269 (define_insn "*swapsi"
1270 [(set (match_operand:SI 0 "register_operand" "+r")
1271 (match_operand:SI 1 "register_operand" "+r"))
1276 [(set_attr "type" "imov")
1277 (set_attr "mode" "SI")
1278 (set_attr "pent_pair" "np")
1279 (set_attr "athlon_decode" "vector")])
1281 (define_expand "movhi"
1282 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1283 (match_operand:HI 1 "general_operand" ""))]
1285 "ix86_expand_move (HImode, operands); DONE;")
1287 (define_insn "*pushhi2"
1288 [(set (match_operand:HI 0 "push_operand" "=X")
1289 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1292 [(set_attr "type" "push")
1293 (set_attr "mode" "SI")])
1295 ;; For 64BIT abi we always round up to 8 bytes.
1296 (define_insn "*pushhi2_rex64"
1297 [(set (match_operand:HI 0 "push_operand" "=X")
1298 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1301 [(set_attr "type" "push")
1302 (set_attr "mode" "DI")])
1304 (define_insn "*movhi_1"
1305 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1306 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1307 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1309 switch (get_attr_type (insn))
1312 /* movzwl is faster than movw on p2 due to partial word stalls,
1313 though not as fast as an aligned movl. */
1314 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1316 if (get_attr_mode (insn) == MODE_SI)
1317 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1319 return "mov{w}\t{%1, %0|%0, %1}";
1323 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1324 (const_string "imov")
1325 (and (eq_attr "alternative" "0")
1326 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1328 (eq (symbol_ref "TARGET_HIMODE_MATH")
1330 (const_string "imov")
1331 (and (eq_attr "alternative" "1,2")
1332 (match_operand:HI 1 "aligned_operand" ""))
1333 (const_string "imov")
1334 (and (ne (symbol_ref "TARGET_MOVX")
1336 (eq_attr "alternative" "0,2"))
1337 (const_string "imovx")
1339 (const_string "imov")))
1341 (cond [(eq_attr "type" "imovx")
1343 (and (eq_attr "alternative" "1,2")
1344 (match_operand:HI 1 "aligned_operand" ""))
1346 (and (eq_attr "alternative" "0")
1347 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1349 (eq (symbol_ref "TARGET_HIMODE_MATH")
1353 (const_string "HI")))])
1355 ;; Stores and loads of ax to arbitrary constant address.
1356 ;; We fake an second form of instruction to force reload to load address
1357 ;; into register when rax is not available
1358 (define_insn "*movabshi_1_rex64"
1359 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1360 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1361 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1363 movabs{w}\t{%1, %P0|%P0, %1}
1364 mov{w}\t{%1, %a0|%a0, %1}"
1365 [(set_attr "type" "imov")
1366 (set_attr "modrm" "0,*")
1367 (set_attr "length_address" "8,0")
1368 (set_attr "length_immediate" "0,*")
1369 (set_attr "memory" "store")
1370 (set_attr "mode" "HI")])
1372 (define_insn "*movabshi_2_rex64"
1373 [(set (match_operand:HI 0 "register_operand" "=a,r")
1374 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1375 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1377 movabs{w}\t{%P1, %0|%0, %P1}
1378 mov{w}\t{%a1, %0|%0, %a1}"
1379 [(set_attr "type" "imov")
1380 (set_attr "modrm" "0,*")
1381 (set_attr "length_address" "8,0")
1382 (set_attr "length_immediate" "0")
1383 (set_attr "memory" "load")
1384 (set_attr "mode" "HI")])
1386 (define_insn "*swaphi_1"
1387 [(set (match_operand:HI 0 "register_operand" "+r")
1388 (match_operand:HI 1 "register_operand" "+r"))
1391 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1393 [(set_attr "type" "imov")
1394 (set_attr "mode" "SI")
1395 (set_attr "pent_pair" "np")
1396 (set_attr "athlon_decode" "vector")])
1398 (define_insn "*swaphi_2"
1399 [(set (match_operand:HI 0 "register_operand" "+r")
1400 (match_operand:HI 1 "register_operand" "+r"))
1403 "TARGET_PARTIAL_REG_STALL"
1405 [(set_attr "type" "imov")
1406 (set_attr "mode" "HI")
1407 (set_attr "pent_pair" "np")
1408 (set_attr "athlon_decode" "vector")])
1410 (define_expand "movstricthi"
1411 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1412 (match_operand:HI 1 "general_operand" ""))]
1413 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1415 /* Don't generate memory->memory moves, go through a register */
1416 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1417 operands[1] = force_reg (HImode, operands[1]);
1420 (define_insn "*movstricthi_1"
1421 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1422 (match_operand:HI 1 "general_operand" "rn,m"))]
1423 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1424 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1425 "mov{w}\t{%1, %0|%0, %1}"
1426 [(set_attr "type" "imov")
1427 (set_attr "mode" "HI")])
1429 (define_insn "*movstricthi_xor"
1430 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1431 (match_operand:HI 1 "const0_operand" "i"))
1432 (clobber (reg:CC FLAGS_REG))]
1434 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1435 "xor{w}\t{%0, %0|%0, %0}"
1436 [(set_attr "type" "alu1")
1437 (set_attr "mode" "HI")
1438 (set_attr "length_immediate" "0")])
1440 (define_expand "movqi"
1441 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1442 (match_operand:QI 1 "general_operand" ""))]
1444 "ix86_expand_move (QImode, operands); DONE;")
1446 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1447 ;; "push a byte". But actually we use pushl, which has the effect
1448 ;; of rounding the amount pushed up to a word.
1450 (define_insn "*pushqi2"
1451 [(set (match_operand:QI 0 "push_operand" "=X")
1452 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1455 [(set_attr "type" "push")
1456 (set_attr "mode" "SI")])
1458 ;; For 64BIT abi we always round up to 8 bytes.
1459 (define_insn "*pushqi2_rex64"
1460 [(set (match_operand:QI 0 "push_operand" "=X")
1461 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1464 [(set_attr "type" "push")
1465 (set_attr "mode" "DI")])
1467 ;; Situation is quite tricky about when to choose full sized (SImode) move
1468 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1469 ;; partial register dependency machines (such as AMD Athlon), where QImode
1470 ;; moves issue extra dependency and for partial register stalls machines
1471 ;; that don't use QImode patterns (and QImode move cause stall on the next
1474 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1475 ;; register stall machines with, where we use QImode instructions, since
1476 ;; partial register stall can be caused there. Then we use movzx.
1477 (define_insn "*movqi_1"
1478 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1479 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1480 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1482 switch (get_attr_type (insn))
1485 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1486 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1488 if (get_attr_mode (insn) == MODE_SI)
1489 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1491 return "mov{b}\t{%1, %0|%0, %1}";
1495 (cond [(and (eq_attr "alternative" "5")
1496 (not (match_operand:QI 1 "aligned_operand" "")))
1497 (const_string "imovx")
1498 (ne (symbol_ref "optimize_size") (const_int 0))
1499 (const_string "imov")
1500 (and (eq_attr "alternative" "3")
1501 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1503 (eq (symbol_ref "TARGET_QIMODE_MATH")
1505 (const_string "imov")
1506 (eq_attr "alternative" "3,5")
1507 (const_string "imovx")
1508 (and (ne (symbol_ref "TARGET_MOVX")
1510 (eq_attr "alternative" "2"))
1511 (const_string "imovx")
1513 (const_string "imov")))
1515 (cond [(eq_attr "alternative" "3,4,5")
1517 (eq_attr "alternative" "6")
1519 (eq_attr "type" "imovx")
1521 (and (eq_attr "type" "imov")
1522 (and (eq_attr "alternative" "0,1")
1523 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1525 (and (eq (symbol_ref "optimize_size")
1527 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1530 ;; Avoid partial register stalls when not using QImode arithmetic
1531 (and (eq_attr "type" "imov")
1532 (and (eq_attr "alternative" "0,1")
1533 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1535 (eq (symbol_ref "TARGET_QIMODE_MATH")
1539 (const_string "QI")))])
1541 (define_expand "reload_outqi"
1542 [(parallel [(match_operand:QI 0 "" "=m")
1543 (match_operand:QI 1 "register_operand" "r")
1544 (match_operand:QI 2 "register_operand" "=&q")])]
1548 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1550 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1551 if (! q_regs_operand (op1, QImode))
1553 emit_insn (gen_movqi (op2, op1));
1556 emit_insn (gen_movqi (op0, op1));
1560 (define_insn "*swapqi_1"
1561 [(set (match_operand:QI 0 "register_operand" "+r")
1562 (match_operand:QI 1 "register_operand" "+r"))
1565 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1567 [(set_attr "type" "imov")
1568 (set_attr "mode" "SI")
1569 (set_attr "pent_pair" "np")
1570 (set_attr "athlon_decode" "vector")])
1572 (define_insn "*swapqi_2"
1573 [(set (match_operand:QI 0 "register_operand" "+q")
1574 (match_operand:QI 1 "register_operand" "+q"))
1577 "TARGET_PARTIAL_REG_STALL"
1579 [(set_attr "type" "imov")
1580 (set_attr "mode" "QI")
1581 (set_attr "pent_pair" "np")
1582 (set_attr "athlon_decode" "vector")])
1584 (define_expand "movstrictqi"
1585 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1586 (match_operand:QI 1 "general_operand" ""))]
1587 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1589 /* Don't generate memory->memory moves, go through a register. */
1590 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1591 operands[1] = force_reg (QImode, operands[1]);
1594 (define_insn "*movstrictqi_1"
1595 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1596 (match_operand:QI 1 "general_operand" "*qn,m"))]
1597 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1598 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1599 "mov{b}\t{%1, %0|%0, %1}"
1600 [(set_attr "type" "imov")
1601 (set_attr "mode" "QI")])
1603 (define_insn "*movstrictqi_xor"
1604 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1605 (match_operand:QI 1 "const0_operand" "i"))
1606 (clobber (reg:CC FLAGS_REG))]
1607 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1608 "xor{b}\t{%0, %0|%0, %0}"
1609 [(set_attr "type" "alu1")
1610 (set_attr "mode" "QI")
1611 (set_attr "length_immediate" "0")])
1613 (define_insn "*movsi_extv_1"
1614 [(set (match_operand:SI 0 "register_operand" "=R")
1615 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1619 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1620 [(set_attr "type" "imovx")
1621 (set_attr "mode" "SI")])
1623 (define_insn "*movhi_extv_1"
1624 [(set (match_operand:HI 0 "register_operand" "=R")
1625 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1629 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1630 [(set_attr "type" "imovx")
1631 (set_attr "mode" "SI")])
1633 (define_insn "*movqi_extv_1"
1634 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1635 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1640 switch (get_attr_type (insn))
1643 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1645 return "mov{b}\t{%h1, %0|%0, %h1}";
1649 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1650 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1651 (ne (symbol_ref "TARGET_MOVX")
1653 (const_string "imovx")
1654 (const_string "imov")))
1656 (if_then_else (eq_attr "type" "imovx")
1658 (const_string "QI")))])
1660 (define_insn "*movqi_extv_1_rex64"
1661 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1662 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1667 switch (get_attr_type (insn))
1670 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1672 return "mov{b}\t{%h1, %0|%0, %h1}";
1676 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1677 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1678 (ne (symbol_ref "TARGET_MOVX")
1680 (const_string "imovx")
1681 (const_string "imov")))
1683 (if_then_else (eq_attr "type" "imovx")
1685 (const_string "QI")))])
1687 ;; Stores and loads of ax to arbitrary constant address.
1688 ;; We fake an second form of instruction to force reload to load address
1689 ;; into register when rax is not available
1690 (define_insn "*movabsqi_1_rex64"
1691 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1692 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1693 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1695 movabs{b}\t{%1, %P0|%P0, %1}
1696 mov{b}\t{%1, %a0|%a0, %1}"
1697 [(set_attr "type" "imov")
1698 (set_attr "modrm" "0,*")
1699 (set_attr "length_address" "8,0")
1700 (set_attr "length_immediate" "0,*")
1701 (set_attr "memory" "store")
1702 (set_attr "mode" "QI")])
1704 (define_insn "*movabsqi_2_rex64"
1705 [(set (match_operand:QI 0 "register_operand" "=a,r")
1706 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1707 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1709 movabs{b}\t{%P1, %0|%0, %P1}
1710 mov{b}\t{%a1, %0|%0, %a1}"
1711 [(set_attr "type" "imov")
1712 (set_attr "modrm" "0,*")
1713 (set_attr "length_address" "8,0")
1714 (set_attr "length_immediate" "0")
1715 (set_attr "memory" "load")
1716 (set_attr "mode" "QI")])
1718 (define_insn "*movdi_extzv_1"
1719 [(set (match_operand:DI 0 "register_operand" "=R")
1720 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1724 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1725 [(set_attr "type" "imovx")
1726 (set_attr "mode" "DI")])
1728 (define_insn "*movsi_extzv_1"
1729 [(set (match_operand:SI 0 "register_operand" "=R")
1730 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1734 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1735 [(set_attr "type" "imovx")
1736 (set_attr "mode" "SI")])
1738 (define_insn "*movqi_extzv_2"
1739 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1740 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1745 switch (get_attr_type (insn))
1748 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1750 return "mov{b}\t{%h1, %0|%0, %h1}";
1754 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1755 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1756 (ne (symbol_ref "TARGET_MOVX")
1758 (const_string "imovx")
1759 (const_string "imov")))
1761 (if_then_else (eq_attr "type" "imovx")
1763 (const_string "QI")))])
1765 (define_insn "*movqi_extzv_2_rex64"
1766 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1767 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1772 switch (get_attr_type (insn))
1775 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1777 return "mov{b}\t{%h1, %0|%0, %h1}";
1781 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1782 (ne (symbol_ref "TARGET_MOVX")
1784 (const_string "imovx")
1785 (const_string "imov")))
1787 (if_then_else (eq_attr "type" "imovx")
1789 (const_string "QI")))])
1791 (define_insn "movsi_insv_1"
1792 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1795 (match_operand:SI 1 "general_operand" "Qmn"))]
1797 "mov{b}\t{%b1, %h0|%h0, %b1}"
1798 [(set_attr "type" "imov")
1799 (set_attr "mode" "QI")])
1801 (define_insn "movdi_insv_1_rex64"
1802 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1805 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1807 "mov{b}\t{%b1, %h0|%h0, %b1}"
1808 [(set_attr "type" "imov")
1809 (set_attr "mode" "QI")])
1811 (define_insn "*movqi_insv_2"
1812 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1815 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1818 "mov{b}\t{%h1, %h0|%h0, %h1}"
1819 [(set_attr "type" "imov")
1820 (set_attr "mode" "QI")])
1822 (define_expand "movdi"
1823 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1824 (match_operand:DI 1 "general_operand" ""))]
1826 "ix86_expand_move (DImode, operands); DONE;")
1828 (define_insn "*pushdi"
1829 [(set (match_operand:DI 0 "push_operand" "=<")
1830 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1834 (define_insn "*pushdi2_rex64"
1835 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1836 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1841 [(set_attr "type" "push,multi")
1842 (set_attr "mode" "DI")])
1844 ;; Convert impossible pushes of immediate to existing instructions.
1845 ;; First try to get scratch register and go through it. In case this
1846 ;; fails, push sign extended lower part first and then overwrite
1847 ;; upper part by 32bit move.
1849 [(match_scratch:DI 2 "r")
1850 (set (match_operand:DI 0 "push_operand" "")
1851 (match_operand:DI 1 "immediate_operand" ""))]
1852 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1853 && !x86_64_immediate_operand (operands[1], DImode)"
1854 [(set (match_dup 2) (match_dup 1))
1855 (set (match_dup 0) (match_dup 2))]
1858 ;; We need to define this as both peepholer and splitter for case
1859 ;; peephole2 pass is not run.
1860 ;; "&& 1" is needed to keep it from matching the previous pattern.
1862 [(set (match_operand:DI 0 "push_operand" "")
1863 (match_operand:DI 1 "immediate_operand" ""))]
1864 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1865 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1866 [(set (match_dup 0) (match_dup 1))
1867 (set (match_dup 2) (match_dup 3))]
1868 "split_di (operands + 1, 1, operands + 2, operands + 3);
1869 operands[1] = gen_lowpart (DImode, operands[2]);
1870 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1875 [(set (match_operand:DI 0 "push_operand" "")
1876 (match_operand:DI 1 "immediate_operand" ""))]
1877 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1878 ? flow2_completed : reload_completed)
1879 && !symbolic_operand (operands[1], DImode)
1880 && !x86_64_immediate_operand (operands[1], DImode)"
1881 [(set (match_dup 0) (match_dup 1))
1882 (set (match_dup 2) (match_dup 3))]
1883 "split_di (operands + 1, 1, operands + 2, operands + 3);
1884 operands[1] = gen_lowpart (DImode, operands[2]);
1885 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1889 (define_insn "*pushdi2_prologue_rex64"
1890 [(set (match_operand:DI 0 "push_operand" "=<")
1891 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1892 (clobber (mem:BLK (scratch)))]
1895 [(set_attr "type" "push")
1896 (set_attr "mode" "DI")])
1898 (define_insn "*popdi1_epilogue_rex64"
1899 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1900 (mem:DI (reg:DI SP_REG)))
1901 (set (reg:DI SP_REG)
1902 (plus:DI (reg:DI SP_REG) (const_int 8)))
1903 (clobber (mem:BLK (scratch)))]
1906 [(set_attr "type" "pop")
1907 (set_attr "mode" "DI")])
1909 (define_insn "popdi1"
1910 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1911 (mem:DI (reg:DI SP_REG)))
1912 (set (reg:DI SP_REG)
1913 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1916 [(set_attr "type" "pop")
1917 (set_attr "mode" "DI")])
1919 (define_insn "*movdi_xor_rex64"
1920 [(set (match_operand:DI 0 "register_operand" "=r")
1921 (match_operand:DI 1 "const0_operand" "i"))
1922 (clobber (reg:CC FLAGS_REG))]
1923 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1924 && reload_completed"
1925 "xor{l}\t{%k0, %k0|%k0, %k0}"
1926 [(set_attr "type" "alu1")
1927 (set_attr "mode" "SI")
1928 (set_attr "length_immediate" "0")])
1930 (define_insn "*movdi_or_rex64"
1931 [(set (match_operand:DI 0 "register_operand" "=r")
1932 (match_operand:DI 1 "const_int_operand" "i"))
1933 (clobber (reg:CC FLAGS_REG))]
1934 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1936 && operands[1] == constm1_rtx"
1938 operands[1] = constm1_rtx;
1939 return "or{q}\t{%1, %0|%0, %1}";
1941 [(set_attr "type" "alu1")
1942 (set_attr "mode" "DI")
1943 (set_attr "length_immediate" "1")])
1945 (define_insn "*movdi_2"
1946 [(set (match_operand:DI 0 "nonimmediate_operand"
1947 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1948 (match_operand:DI 1 "general_operand"
1949 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1950 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1955 movq\t{%1, %0|%0, %1}
1956 movq\t{%1, %0|%0, %1}
1958 movq\t{%1, %0|%0, %1}
1959 movdqa\t{%1, %0|%0, %1}
1960 movq\t{%1, %0|%0, %1}
1962 movlps\t{%1, %0|%0, %1}
1963 movaps\t{%1, %0|%0, %1}
1964 movlps\t{%1, %0|%0, %1}"
1965 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1966 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1969 [(set (match_operand:DI 0 "push_operand" "")
1970 (match_operand:DI 1 "general_operand" ""))]
1971 "!TARGET_64BIT && reload_completed
1972 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1974 "ix86_split_long_move (operands); DONE;")
1976 ;; %%% This multiword shite has got to go.
1978 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1979 (match_operand:DI 1 "general_operand" ""))]
1980 "!TARGET_64BIT && reload_completed
1981 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1982 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1984 "ix86_split_long_move (operands); DONE;")
1986 (define_insn "*movdi_1_rex64"
1987 [(set (match_operand:DI 0 "nonimmediate_operand"
1988 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1989 (match_operand:DI 1 "general_operand"
1990 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1991 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1993 switch (get_attr_type (insn))
1996 if (which_alternative == 13)
1997 return "movq2dq\t{%1, %0|%0, %1}";
1999 return "movdq2q\t{%1, %0|%0, %1}";
2001 if (get_attr_mode (insn) == MODE_TI)
2002 return "movdqa\t{%1, %0|%0, %1}";
2005 /* Moves from and into integer register is done using movd opcode with
2007 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2008 return "movd\t{%1, %0|%0, %1}";
2009 return "movq\t{%1, %0|%0, %1}";
2012 return "pxor\t%0, %0";
2016 return "lea{q}\t{%a1, %0|%0, %a1}";
2018 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2019 if (get_attr_mode (insn) == MODE_SI)
2020 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2021 else if (which_alternative == 2)
2022 return "movabs{q}\t{%1, %0|%0, %1}";
2024 return "mov{q}\t{%1, %0|%0, %1}";
2028 (cond [(eq_attr "alternative" "5")
2029 (const_string "mmxadd")
2030 (eq_attr "alternative" "6,7,8")
2031 (const_string "mmxmov")
2032 (eq_attr "alternative" "9")
2033 (const_string "sselog1")
2034 (eq_attr "alternative" "10,11,12")
2035 (const_string "ssemov")
2036 (eq_attr "alternative" "13,14")
2037 (const_string "ssecvt")
2038 (eq_attr "alternative" "4")
2039 (const_string "multi")
2040 (match_operand:DI 1 "pic_32bit_operand" "")
2041 (const_string "lea")
2043 (const_string "imov")))
2044 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2045 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2046 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2048 ;; Stores and loads of ax to arbitrary constant address.
2049 ;; We fake an second form of instruction to force reload to load address
2050 ;; into register when rax is not available
2051 (define_insn "*movabsdi_1_rex64"
2052 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2053 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2054 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2056 movabs{q}\t{%1, %P0|%P0, %1}
2057 mov{q}\t{%1, %a0|%a0, %1}"
2058 [(set_attr "type" "imov")
2059 (set_attr "modrm" "0,*")
2060 (set_attr "length_address" "8,0")
2061 (set_attr "length_immediate" "0,*")
2062 (set_attr "memory" "store")
2063 (set_attr "mode" "DI")])
2065 (define_insn "*movabsdi_2_rex64"
2066 [(set (match_operand:DI 0 "register_operand" "=a,r")
2067 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2068 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2070 movabs{q}\t{%P1, %0|%0, %P1}
2071 mov{q}\t{%a1, %0|%0, %a1}"
2072 [(set_attr "type" "imov")
2073 (set_attr "modrm" "0,*")
2074 (set_attr "length_address" "8,0")
2075 (set_attr "length_immediate" "0")
2076 (set_attr "memory" "load")
2077 (set_attr "mode" "DI")])
2079 ;; Convert impossible stores of immediate to existing instructions.
2080 ;; First try to get scratch register and go through it. In case this
2081 ;; fails, move by 32bit parts.
2083 [(match_scratch:DI 2 "r")
2084 (set (match_operand:DI 0 "memory_operand" "")
2085 (match_operand:DI 1 "immediate_operand" ""))]
2086 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2087 && !x86_64_immediate_operand (operands[1], DImode)"
2088 [(set (match_dup 2) (match_dup 1))
2089 (set (match_dup 0) (match_dup 2))]
2092 ;; We need to define this as both peepholer and splitter for case
2093 ;; peephole2 pass is not run.
2094 ;; "&& 1" is needed to keep it from matching the previous pattern.
2096 [(set (match_operand:DI 0 "memory_operand" "")
2097 (match_operand:DI 1 "immediate_operand" ""))]
2098 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2099 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2100 [(set (match_dup 2) (match_dup 3))
2101 (set (match_dup 4) (match_dup 5))]
2102 "split_di (operands, 2, operands + 2, operands + 4);")
2105 [(set (match_operand:DI 0 "memory_operand" "")
2106 (match_operand:DI 1 "immediate_operand" ""))]
2107 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2108 ? flow2_completed : reload_completed)
2109 && !symbolic_operand (operands[1], DImode)
2110 && !x86_64_immediate_operand (operands[1], DImode)"
2111 [(set (match_dup 2) (match_dup 3))
2112 (set (match_dup 4) (match_dup 5))]
2113 "split_di (operands, 2, operands + 2, operands + 4);")
2115 (define_insn "*swapdi_rex64"
2116 [(set (match_operand:DI 0 "register_operand" "+r")
2117 (match_operand:DI 1 "register_operand" "+r"))
2122 [(set_attr "type" "imov")
2123 (set_attr "mode" "DI")
2124 (set_attr "pent_pair" "np")
2125 (set_attr "athlon_decode" "vector")])
2127 (define_expand "movti"
2128 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2129 (match_operand:TI 1 "nonimmediate_operand" ""))]
2130 "TARGET_SSE || TARGET_64BIT"
2133 ix86_expand_move (TImode, operands);
2135 ix86_expand_vector_move (TImode, operands);
2139 (define_insn "*movti_internal"
2140 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2141 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2142 "TARGET_SSE && !TARGET_64BIT
2143 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2145 switch (which_alternative)
2148 if (get_attr_mode (insn) == MODE_V4SF)
2149 return "xorps\t%0, %0";
2151 return "pxor\t%0, %0";
2154 if (get_attr_mode (insn) == MODE_V4SF)
2155 return "movaps\t{%1, %0|%0, %1}";
2157 return "movdqa\t{%1, %0|%0, %1}";
2162 [(set_attr "type" "sselog1,ssemov,ssemov")
2164 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2165 (ne (symbol_ref "optimize_size") (const_int 0)))
2166 (const_string "V4SF")
2167 (and (eq_attr "alternative" "2")
2168 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2170 (const_string "V4SF")]
2171 (const_string "TI")))])
2173 (define_insn "*movti_rex64"
2174 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2175 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2177 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2179 switch (which_alternative)
2185 if (get_attr_mode (insn) == MODE_V4SF)
2186 return "xorps\t%0, %0";
2188 return "pxor\t%0, %0";
2191 if (get_attr_mode (insn) == MODE_V4SF)
2192 return "movaps\t{%1, %0|%0, %1}";
2194 return "movdqa\t{%1, %0|%0, %1}";
2199 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2201 (cond [(eq_attr "alternative" "2,3")
2203 (ne (symbol_ref "optimize_size")
2205 (const_string "V4SF")
2206 (const_string "TI"))
2207 (eq_attr "alternative" "4")
2209 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2211 (ne (symbol_ref "optimize_size")
2213 (const_string "V4SF")
2214 (const_string "TI"))]
2215 (const_string "DI")))])
2218 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2219 (match_operand:TI 1 "general_operand" ""))]
2220 "reload_completed && !SSE_REG_P (operands[0])
2221 && !SSE_REG_P (operands[1])"
2223 "ix86_split_long_move (operands); DONE;")
2225 (define_expand "movsf"
2226 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2227 (match_operand:SF 1 "general_operand" ""))]
2229 "ix86_expand_move (SFmode, operands); DONE;")
2231 (define_insn "*pushsf"
2232 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2233 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2236 /* Anything else should be already split before reg-stack. */
2237 gcc_assert (which_alternative == 1);
2238 return "push{l}\t%1";
2240 [(set_attr "type" "multi,push,multi")
2241 (set_attr "unit" "i387,*,*")
2242 (set_attr "mode" "SF,SI,SF")])
2244 (define_insn "*pushsf_rex64"
2245 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2246 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2249 /* Anything else should be already split before reg-stack. */
2250 gcc_assert (which_alternative == 1);
2251 return "push{q}\t%q1";
2253 [(set_attr "type" "multi,push,multi")
2254 (set_attr "unit" "i387,*,*")
2255 (set_attr "mode" "SF,DI,SF")])
2258 [(set (match_operand:SF 0 "push_operand" "")
2259 (match_operand:SF 1 "memory_operand" ""))]
2261 && GET_CODE (operands[1]) == MEM
2262 && constant_pool_reference_p (operands[1])"
2265 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2268 ;; %%% Kill this when call knows how to work this out.
2270 [(set (match_operand:SF 0 "push_operand" "")
2271 (match_operand:SF 1 "any_fp_register_operand" ""))]
2273 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2274 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2277 [(set (match_operand:SF 0 "push_operand" "")
2278 (match_operand:SF 1 "any_fp_register_operand" ""))]
2280 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2281 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2283 (define_insn "*movsf_1"
2284 [(set (match_operand:SF 0 "nonimmediate_operand"
2285 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2286 (match_operand:SF 1 "general_operand"
2287 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2288 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2289 && (reload_in_progress || reload_completed
2290 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2291 || GET_CODE (operands[1]) != CONST_DOUBLE
2292 || memory_operand (operands[0], SFmode))"
2294 switch (which_alternative)
2297 return output_387_reg_move (insn, operands);
2300 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2301 return "fstp%z0\t%y0";
2303 return "fst%z0\t%y0";
2306 return standard_80387_constant_opcode (operands[1]);
2310 return "mov{l}\t{%1, %0|%0, %1}";
2312 if (get_attr_mode (insn) == MODE_TI)
2313 return "pxor\t%0, %0";
2315 return "xorps\t%0, %0";
2317 if (get_attr_mode (insn) == MODE_V4SF)
2318 return "movaps\t{%1, %0|%0, %1}";
2320 return "movss\t{%1, %0|%0, %1}";
2323 return "movss\t{%1, %0|%0, %1}";
2327 return "movd\t{%1, %0|%0, %1}";
2330 return "movq\t{%1, %0|%0, %1}";
2336 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2338 (cond [(eq_attr "alternative" "3,4,9,10")
2340 (eq_attr "alternative" "5")
2342 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2344 (ne (symbol_ref "TARGET_SSE2")
2346 (eq (symbol_ref "optimize_size")
2349 (const_string "V4SF"))
2350 /* For architectures resolving dependencies on
2351 whole SSE registers use APS move to break dependency
2352 chains, otherwise use short move to avoid extra work.
2354 Do the same for architectures resolving dependencies on
2355 the parts. While in DF mode it is better to always handle
2356 just register parts, the SF mode is different due to lack
2357 of instructions to load just part of the register. It is
2358 better to maintain the whole registers in single format
2359 to avoid problems on using packed logical operations. */
2360 (eq_attr "alternative" "6")
2362 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2364 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2366 (const_string "V4SF")
2367 (const_string "SF"))
2368 (eq_attr "alternative" "11")
2369 (const_string "DI")]
2370 (const_string "SF")))])
2372 (define_insn "*swapsf"
2373 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2374 (match_operand:SF 1 "fp_register_operand" "+f"))
2377 "reload_completed || TARGET_80387"
2379 if (STACK_TOP_P (operands[0]))
2384 [(set_attr "type" "fxch")
2385 (set_attr "mode" "SF")])
2387 (define_expand "movdf"
2388 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2389 (match_operand:DF 1 "general_operand" ""))]
2391 "ix86_expand_move (DFmode, operands); DONE;")
2393 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2394 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2395 ;; On the average, pushdf using integers can be still shorter. Allow this
2396 ;; pattern for optimize_size too.
2398 (define_insn "*pushdf_nointeger"
2399 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2400 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2401 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2403 /* This insn should be already split before reg-stack. */
2406 [(set_attr "type" "multi")
2407 (set_attr "unit" "i387,*,*,*")
2408 (set_attr "mode" "DF,SI,SI,DF")])
2410 (define_insn "*pushdf_integer"
2411 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2412 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2413 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2415 /* This insn should be already split before reg-stack. */
2418 [(set_attr "type" "multi")
2419 (set_attr "unit" "i387,*,*")
2420 (set_attr "mode" "DF,SI,DF")])
2422 ;; %%% Kill this when call knows how to work this out.
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:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2428 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2432 [(set (match_operand:DF 0 "push_operand" "")
2433 (match_operand:DF 1 "any_fp_register_operand" ""))]
2434 "TARGET_64BIT && reload_completed"
2435 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2436 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2440 [(set (match_operand:DF 0 "push_operand" "")
2441 (match_operand:DF 1 "general_operand" ""))]
2444 "ix86_split_long_move (operands); DONE;")
2446 ;; Moving is usually shorter when only FP registers are used. This separate
2447 ;; movdf pattern avoids the use of integer registers for FP operations
2448 ;; when optimizing for size.
2450 (define_insn "*movdf_nointeger"
2451 [(set (match_operand:DF 0 "nonimmediate_operand"
2452 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2453 (match_operand:DF 1 "general_operand"
2454 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2455 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2456 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2457 && (reload_in_progress || reload_completed
2458 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2459 || GET_CODE (operands[1]) != CONST_DOUBLE
2460 || memory_operand (operands[0], DFmode))"
2462 switch (which_alternative)
2465 return output_387_reg_move (insn, operands);
2468 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2469 return "fstp%z0\t%y0";
2471 return "fst%z0\t%y0";
2474 return standard_80387_constant_opcode (operands[1]);
2480 switch (get_attr_mode (insn))
2483 return "xorps\t%0, %0";
2485 return "xorpd\t%0, %0";
2487 return "pxor\t%0, %0";
2494 switch (get_attr_mode (insn))
2497 return "movaps\t{%1, %0|%0, %1}";
2499 return "movapd\t{%1, %0|%0, %1}";
2501 return "movdqa\t{%1, %0|%0, %1}";
2503 return "movq\t{%1, %0|%0, %1}";
2505 return "movsd\t{%1, %0|%0, %1}";
2507 return "movlpd\t{%1, %0|%0, %1}";
2509 return "movlps\t{%1, %0|%0, %1}";
2518 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2520 (cond [(eq_attr "alternative" "0,1,2")
2522 (eq_attr "alternative" "3,4")
2525 /* For SSE1, we have many fewer alternatives. */
2526 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2527 (cond [(eq_attr "alternative" "5,6")
2528 (const_string "V4SF")
2530 (const_string "V2SF"))
2532 /* xorps is one byte shorter. */
2533 (eq_attr "alternative" "5")
2534 (cond [(ne (symbol_ref "optimize_size")
2536 (const_string "V4SF")
2537 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2541 (const_string "V2DF"))
2543 /* For architectures resolving dependencies on
2544 whole SSE registers use APD move to break dependency
2545 chains, otherwise use short move to avoid extra work.
2547 movaps encodes one byte shorter. */
2548 (eq_attr "alternative" "6")
2550 [(ne (symbol_ref "optimize_size")
2552 (const_string "V4SF")
2553 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2555 (const_string "V2DF")
2557 (const_string "DF"))
2558 /* For architectures resolving dependencies on register
2559 parts we may avoid extra work to zero out upper part
2561 (eq_attr "alternative" "7")
2563 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2565 (const_string "V1DF")
2566 (const_string "DF"))
2568 (const_string "DF")))])
2570 (define_insn "*movdf_integer"
2571 [(set (match_operand:DF 0 "nonimmediate_operand"
2572 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2573 (match_operand:DF 1 "general_operand"
2574 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2575 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2576 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2577 && (reload_in_progress || reload_completed
2578 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2579 || GET_CODE (operands[1]) != CONST_DOUBLE
2580 || memory_operand (operands[0], DFmode))"
2582 switch (which_alternative)
2585 return output_387_reg_move (insn, operands);
2588 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2589 return "fstp%z0\t%y0";
2591 return "fst%z0\t%y0";
2594 return standard_80387_constant_opcode (operands[1]);
2601 switch (get_attr_mode (insn))
2604 return "xorps\t%0, %0";
2606 return "xorpd\t%0, %0";
2608 return "pxor\t%0, %0";
2615 switch (get_attr_mode (insn))
2618 return "movaps\t{%1, %0|%0, %1}";
2620 return "movapd\t{%1, %0|%0, %1}";
2622 return "movdqa\t{%1, %0|%0, %1}";
2624 return "movq\t{%1, %0|%0, %1}";
2626 return "movsd\t{%1, %0|%0, %1}";
2628 return "movlpd\t{%1, %0|%0, %1}";
2630 return "movlps\t{%1, %0|%0, %1}";
2639 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2641 (cond [(eq_attr "alternative" "0,1,2")
2643 (eq_attr "alternative" "3,4")
2646 /* For SSE1, we have many fewer alternatives. */
2647 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2648 (cond [(eq_attr "alternative" "5,6")
2649 (const_string "V4SF")
2651 (const_string "V2SF"))
2653 /* xorps is one byte shorter. */
2654 (eq_attr "alternative" "5")
2655 (cond [(ne (symbol_ref "optimize_size")
2657 (const_string "V4SF")
2658 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2662 (const_string "V2DF"))
2664 /* For architectures resolving dependencies on
2665 whole SSE registers use APD move to break dependency
2666 chains, otherwise use short move to avoid extra work.
2668 movaps encodes one byte shorter. */
2669 (eq_attr "alternative" "6")
2671 [(ne (symbol_ref "optimize_size")
2673 (const_string "V4SF")
2674 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2676 (const_string "V2DF")
2678 (const_string "DF"))
2679 /* For architectures resolving dependencies on register
2680 parts we may avoid extra work to zero out upper part
2682 (eq_attr "alternative" "7")
2684 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2686 (const_string "V1DF")
2687 (const_string "DF"))
2689 (const_string "DF")))])
2692 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2693 (match_operand:DF 1 "general_operand" ""))]
2695 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2696 && ! (ANY_FP_REG_P (operands[0]) ||
2697 (GET_CODE (operands[0]) == SUBREG
2698 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2699 && ! (ANY_FP_REG_P (operands[1]) ||
2700 (GET_CODE (operands[1]) == SUBREG
2701 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2703 "ix86_split_long_move (operands); DONE;")
2705 (define_insn "*swapdf"
2706 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2707 (match_operand:DF 1 "fp_register_operand" "+f"))
2710 "reload_completed || TARGET_80387"
2712 if (STACK_TOP_P (operands[0]))
2717 [(set_attr "type" "fxch")
2718 (set_attr "mode" "DF")])
2720 (define_expand "movxf"
2721 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2722 (match_operand:XF 1 "general_operand" ""))]
2724 "ix86_expand_move (XFmode, operands); DONE;")
2726 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2727 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2728 ;; Pushing using integer instructions is longer except for constants
2729 ;; and direct memory references.
2730 ;; (assuming that any given constant is pushed only once, but this ought to be
2731 ;; handled elsewhere).
2733 (define_insn "*pushxf_nointeger"
2734 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2735 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2738 /* This insn should be already split before reg-stack. */
2741 [(set_attr "type" "multi")
2742 (set_attr "unit" "i387,*,*")
2743 (set_attr "mode" "XF,SI,SI")])
2745 (define_insn "*pushxf_integer"
2746 [(set (match_operand:XF 0 "push_operand" "=<,<")
2747 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2750 /* This insn should be already split before reg-stack. */
2753 [(set_attr "type" "multi")
2754 (set_attr "unit" "i387,*")
2755 (set_attr "mode" "XF,SI")])
2758 [(set (match_operand 0 "push_operand" "")
2759 (match_operand 1 "general_operand" ""))]
2761 && (GET_MODE (operands[0]) == XFmode
2762 || GET_MODE (operands[0]) == DFmode)
2763 && !ANY_FP_REG_P (operands[1])"
2765 "ix86_split_long_move (operands); DONE;")
2768 [(set (match_operand:XF 0 "push_operand" "")
2769 (match_operand:XF 1 "any_fp_register_operand" ""))]
2771 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2772 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2773 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2776 [(set (match_operand:XF 0 "push_operand" "")
2777 (match_operand:XF 1 "any_fp_register_operand" ""))]
2779 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2780 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2781 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2783 ;; Do not use integer registers when optimizing for size
2784 (define_insn "*movxf_nointeger"
2785 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2786 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2788 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2789 && (reload_in_progress || reload_completed
2790 || standard_80387_constant_p (operands[1])
2791 || GET_CODE (operands[1]) != CONST_DOUBLE
2792 || memory_operand (operands[0], XFmode))"
2794 switch (which_alternative)
2797 return output_387_reg_move (insn, operands);
2800 /* There is no non-popping store to memory for XFmode. So if
2801 we need one, follow the store with a load. */
2802 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2803 return "fstp%z0\t%y0\;fld%z0\t%y0";
2805 return "fstp%z0\t%y0";
2808 return standard_80387_constant_opcode (operands[1]);
2816 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2817 (set_attr "mode" "XF,XF,XF,SI,SI")])
2819 (define_insn "*movxf_integer"
2820 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2821 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2823 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2824 && (reload_in_progress || reload_completed
2825 || standard_80387_constant_p (operands[1])
2826 || GET_CODE (operands[1]) != CONST_DOUBLE
2827 || memory_operand (operands[0], XFmode))"
2829 switch (which_alternative)
2832 return output_387_reg_move (insn, operands);
2835 /* There is no non-popping store to memory for XFmode. So if
2836 we need one, follow the store with a load. */
2837 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2838 return "fstp%z0\t%y0\;fld%z0\t%y0";
2840 return "fstp%z0\t%y0";
2843 return standard_80387_constant_opcode (operands[1]);
2852 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2853 (set_attr "mode" "XF,XF,XF,SI,SI")])
2856 [(set (match_operand 0 "nonimmediate_operand" "")
2857 (match_operand 1 "general_operand" ""))]
2859 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2860 && GET_MODE (operands[0]) == XFmode
2861 && ! (ANY_FP_REG_P (operands[0]) ||
2862 (GET_CODE (operands[0]) == SUBREG
2863 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2864 && ! (ANY_FP_REG_P (operands[1]) ||
2865 (GET_CODE (operands[1]) == SUBREG
2866 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2868 "ix86_split_long_move (operands); DONE;")
2871 [(set (match_operand 0 "register_operand" "")
2872 (match_operand 1 "memory_operand" ""))]
2874 && GET_CODE (operands[1]) == MEM
2875 && (GET_MODE (operands[0]) == XFmode
2876 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2877 && constant_pool_reference_p (operands[1])"
2878 [(set (match_dup 0) (match_dup 1))]
2880 rtx c = avoid_constant_pool_reference (operands[1]);
2881 rtx r = operands[0];
2883 if (GET_CODE (r) == SUBREG)
2888 if (!standard_sse_constant_p (c))
2891 else if (FP_REG_P (r))
2893 if (!standard_80387_constant_p (c))
2896 else if (MMX_REG_P (r))
2902 (define_insn "swapxf"
2903 [(set (match_operand:XF 0 "register_operand" "+f")
2904 (match_operand:XF 1 "register_operand" "+f"))
2909 if (STACK_TOP_P (operands[0]))
2914 [(set_attr "type" "fxch")
2915 (set_attr "mode" "XF")])
2917 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2919 [(set (match_operand:X87MODEF 0 "register_operand" "")
2920 (match_operand:X87MODEF 1 "immediate_operand" ""))]
2921 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2922 && (standard_80387_constant_p (operands[1]) == 8
2923 || standard_80387_constant_p (operands[1]) == 9)"
2924 [(set (match_dup 0)(match_dup 1))
2926 (neg:X87MODEF (match_dup 0)))]
2930 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2931 if (real_isnegzero (&r))
2932 operands[1] = CONST0_RTX (<MODE>mode);
2934 operands[1] = CONST1_RTX (<MODE>mode);
2937 (define_expand "movtf"
2938 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2939 (match_operand:TF 1 "nonimmediate_operand" ""))]
2942 ix86_expand_move (TFmode, operands);
2946 (define_insn "*movtf_internal"
2947 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2948 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2950 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2952 switch (which_alternative)
2958 if (get_attr_mode (insn) == MODE_V4SF)
2959 return "xorps\t%0, %0";
2961 return "pxor\t%0, %0";
2964 if (get_attr_mode (insn) == MODE_V4SF)
2965 return "movaps\t{%1, %0|%0, %1}";
2967 return "movdqa\t{%1, %0|%0, %1}";
2972 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2974 (cond [(eq_attr "alternative" "2,3")
2976 (ne (symbol_ref "optimize_size")
2978 (const_string "V4SF")
2979 (const_string "TI"))
2980 (eq_attr "alternative" "4")
2982 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2984 (ne (symbol_ref "optimize_size")
2986 (const_string "V4SF")
2987 (const_string "TI"))]
2988 (const_string "DI")))])
2991 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2992 (match_operand:TF 1 "general_operand" ""))]
2993 "reload_completed && !SSE_REG_P (operands[0])
2994 && !SSE_REG_P (operands[1])"
2996 "ix86_split_long_move (operands); DONE;")
2998 ;; Zero extension instructions
3000 (define_expand "zero_extendhisi2"
3001 [(set (match_operand:SI 0 "register_operand" "")
3002 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3005 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3007 operands[1] = force_reg (HImode, operands[1]);
3008 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3013 (define_insn "zero_extendhisi2_and"
3014 [(set (match_operand:SI 0 "register_operand" "=r")
3015 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3016 (clobber (reg:CC FLAGS_REG))]
3017 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3019 [(set_attr "type" "alu1")
3020 (set_attr "mode" "SI")])
3023 [(set (match_operand:SI 0 "register_operand" "")
3024 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3025 (clobber (reg:CC FLAGS_REG))]
3026 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3027 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3028 (clobber (reg:CC FLAGS_REG))])]
3031 (define_insn "*zero_extendhisi2_movzwl"
3032 [(set (match_operand:SI 0 "register_operand" "=r")
3033 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3034 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3035 "movz{wl|x}\t{%1, %0|%0, %1}"
3036 [(set_attr "type" "imovx")
3037 (set_attr "mode" "SI")])
3039 (define_expand "zero_extendqihi2"
3041 [(set (match_operand:HI 0 "register_operand" "")
3042 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3043 (clobber (reg:CC FLAGS_REG))])]
3047 (define_insn "*zero_extendqihi2_and"
3048 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3049 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3050 (clobber (reg:CC FLAGS_REG))]
3051 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3053 [(set_attr "type" "alu1")
3054 (set_attr "mode" "HI")])
3056 (define_insn "*zero_extendqihi2_movzbw_and"
3057 [(set (match_operand:HI 0 "register_operand" "=r,r")
3058 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3059 (clobber (reg:CC FLAGS_REG))]
3060 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3062 [(set_attr "type" "imovx,alu1")
3063 (set_attr "mode" "HI")])
3065 ; zero extend to SImode here to avoid partial register stalls
3066 (define_insn "*zero_extendqihi2_movzbl"
3067 [(set (match_operand:HI 0 "register_operand" "=r")
3068 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3069 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3070 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3071 [(set_attr "type" "imovx")
3072 (set_attr "mode" "SI")])
3074 ;; For the movzbw case strip only the clobber
3076 [(set (match_operand:HI 0 "register_operand" "")
3077 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3078 (clobber (reg:CC FLAGS_REG))]
3080 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3081 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3082 [(set (match_operand:HI 0 "register_operand" "")
3083 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3085 ;; When source and destination does not overlap, clear destination
3086 ;; first and then do the movb
3088 [(set (match_operand:HI 0 "register_operand" "")
3089 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3090 (clobber (reg:CC FLAGS_REG))]
3092 && ANY_QI_REG_P (operands[0])
3093 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3094 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3095 [(set (match_dup 0) (const_int 0))
3096 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3097 "operands[2] = gen_lowpart (QImode, operands[0]);")
3099 ;; Rest is handled by single and.
3101 [(set (match_operand:HI 0 "register_operand" "")
3102 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3103 (clobber (reg:CC FLAGS_REG))]
3105 && true_regnum (operands[0]) == true_regnum (operands[1])"
3106 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3107 (clobber (reg:CC FLAGS_REG))])]
3110 (define_expand "zero_extendqisi2"
3112 [(set (match_operand:SI 0 "register_operand" "")
3113 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3114 (clobber (reg:CC FLAGS_REG))])]
3118 (define_insn "*zero_extendqisi2_and"
3119 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3120 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3121 (clobber (reg:CC FLAGS_REG))]
3122 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3124 [(set_attr "type" "alu1")
3125 (set_attr "mode" "SI")])
3127 (define_insn "*zero_extendqisi2_movzbw_and"
3128 [(set (match_operand:SI 0 "register_operand" "=r,r")
3129 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3130 (clobber (reg:CC FLAGS_REG))]
3131 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3133 [(set_attr "type" "imovx,alu1")
3134 (set_attr "mode" "SI")])
3136 (define_insn "*zero_extendqisi2_movzbw"
3137 [(set (match_operand:SI 0 "register_operand" "=r")
3138 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3139 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3140 "movz{bl|x}\t{%1, %0|%0, %1}"
3141 [(set_attr "type" "imovx")
3142 (set_attr "mode" "SI")])
3144 ;; For the movzbl case strip only the clobber
3146 [(set (match_operand:SI 0 "register_operand" "")
3147 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3148 (clobber (reg:CC FLAGS_REG))]
3150 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3151 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3153 (zero_extend:SI (match_dup 1)))])
3155 ;; When source and destination does not overlap, clear destination
3156 ;; first and then do the movb
3158 [(set (match_operand:SI 0 "register_operand" "")
3159 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3160 (clobber (reg:CC FLAGS_REG))]
3162 && ANY_QI_REG_P (operands[0])
3163 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3164 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3165 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3166 [(set (match_dup 0) (const_int 0))
3167 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3168 "operands[2] = gen_lowpart (QImode, operands[0]);")
3170 ;; Rest is handled by single and.
3172 [(set (match_operand:SI 0 "register_operand" "")
3173 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3174 (clobber (reg:CC FLAGS_REG))]
3176 && true_regnum (operands[0]) == true_regnum (operands[1])"
3177 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3178 (clobber (reg:CC FLAGS_REG))])]
3181 ;; %%% Kill me once multi-word ops are sane.
3182 (define_expand "zero_extendsidi2"
3183 [(set (match_operand:DI 0 "register_operand" "=r")
3184 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3188 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3193 (define_insn "zero_extendsidi2_32"
3194 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3195 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3196 (clobber (reg:CC FLAGS_REG))]
3202 movd\t{%1, %0|%0, %1}
3203 movd\t{%1, %0|%0, %1}"
3204 [(set_attr "mode" "SI,SI,SI,DI,TI")
3205 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3207 (define_insn "zero_extendsidi2_rex64"
3208 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3209 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3212 mov\t{%k1, %k0|%k0, %k1}
3214 movd\t{%1, %0|%0, %1}
3215 movd\t{%1, %0|%0, %1}"
3216 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3217 (set_attr "mode" "SI,DI,SI,SI")])
3220 [(set (match_operand:DI 0 "memory_operand" "")
3221 (zero_extend:DI (match_dup 0)))]
3223 [(set (match_dup 4) (const_int 0))]
3224 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3227 [(set (match_operand:DI 0 "register_operand" "")
3228 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3229 (clobber (reg:CC FLAGS_REG))]
3230 "!TARGET_64BIT && reload_completed
3231 && true_regnum (operands[0]) == true_regnum (operands[1])"
3232 [(set (match_dup 4) (const_int 0))]
3233 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3236 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3237 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3238 (clobber (reg:CC FLAGS_REG))]
3239 "!TARGET_64BIT && reload_completed
3240 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3241 [(set (match_dup 3) (match_dup 1))
3242 (set (match_dup 4) (const_int 0))]
3243 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3245 (define_insn "zero_extendhidi2"
3246 [(set (match_operand:DI 0 "register_operand" "=r")
3247 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3249 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3250 [(set_attr "type" "imovx")
3251 (set_attr "mode" "DI")])
3253 (define_insn "zero_extendqidi2"
3254 [(set (match_operand:DI 0 "register_operand" "=r")
3255 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3257 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3258 [(set_attr "type" "imovx")
3259 (set_attr "mode" "DI")])
3261 ;; Sign extension instructions
3263 (define_expand "extendsidi2"
3264 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3265 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3266 (clobber (reg:CC FLAGS_REG))
3267 (clobber (match_scratch:SI 2 ""))])]
3272 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3277 (define_insn "*extendsidi2_1"
3278 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3279 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3280 (clobber (reg:CC FLAGS_REG))
3281 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3285 (define_insn "extendsidi2_rex64"
3286 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3287 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3291 movs{lq|x}\t{%1,%0|%0, %1}"
3292 [(set_attr "type" "imovx")
3293 (set_attr "mode" "DI")
3294 (set_attr "prefix_0f" "0")
3295 (set_attr "modrm" "0,1")])
3297 (define_insn "extendhidi2"
3298 [(set (match_operand:DI 0 "register_operand" "=r")
3299 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3301 "movs{wq|x}\t{%1,%0|%0, %1}"
3302 [(set_attr "type" "imovx")
3303 (set_attr "mode" "DI")])
3305 (define_insn "extendqidi2"
3306 [(set (match_operand:DI 0 "register_operand" "=r")
3307 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3309 "movs{bq|x}\t{%1,%0|%0, %1}"
3310 [(set_attr "type" "imovx")
3311 (set_attr "mode" "DI")])
3313 ;; Extend to memory case when source register does die.
3315 [(set (match_operand:DI 0 "memory_operand" "")
3316 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3317 (clobber (reg:CC FLAGS_REG))
3318 (clobber (match_operand:SI 2 "register_operand" ""))]
3320 && dead_or_set_p (insn, operands[1])
3321 && !reg_mentioned_p (operands[1], operands[0]))"
3322 [(set (match_dup 3) (match_dup 1))
3323 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3324 (clobber (reg:CC FLAGS_REG))])
3325 (set (match_dup 4) (match_dup 1))]
3326 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3328 ;; Extend to memory case when source register does not die.
3330 [(set (match_operand:DI 0 "memory_operand" "")
3331 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3332 (clobber (reg:CC FLAGS_REG))
3333 (clobber (match_operand:SI 2 "register_operand" ""))]
3337 split_di (&operands[0], 1, &operands[3], &operands[4]);
3339 emit_move_insn (operands[3], operands[1]);
3341 /* Generate a cltd if possible and doing so it profitable. */
3342 if (true_regnum (operands[1]) == 0
3343 && true_regnum (operands[2]) == 1
3344 && (optimize_size || TARGET_USE_CLTD))
3346 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3350 emit_move_insn (operands[2], operands[1]);
3351 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3353 emit_move_insn (operands[4], operands[2]);
3357 ;; Extend to register case. Optimize case where source and destination
3358 ;; registers match and cases where we can use cltd.
3360 [(set (match_operand:DI 0 "register_operand" "")
3361 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3362 (clobber (reg:CC FLAGS_REG))
3363 (clobber (match_scratch:SI 2 ""))]
3367 split_di (&operands[0], 1, &operands[3], &operands[4]);
3369 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3370 emit_move_insn (operands[3], operands[1]);
3372 /* Generate a cltd if possible and doing so it profitable. */
3373 if (true_regnum (operands[3]) == 0
3374 && (optimize_size || TARGET_USE_CLTD))
3376 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3380 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3381 emit_move_insn (operands[4], operands[1]);
3383 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3387 (define_insn "extendhisi2"
3388 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3389 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3392 switch (get_attr_prefix_0f (insn))
3395 return "{cwtl|cwde}";
3397 return "movs{wl|x}\t{%1,%0|%0, %1}";
3400 [(set_attr "type" "imovx")
3401 (set_attr "mode" "SI")
3402 (set (attr "prefix_0f")
3403 ;; movsx is short decodable while cwtl is vector decoded.
3404 (if_then_else (and (eq_attr "cpu" "!k6")
3405 (eq_attr "alternative" "0"))
3407 (const_string "1")))
3409 (if_then_else (eq_attr "prefix_0f" "0")
3411 (const_string "1")))])
3413 (define_insn "*extendhisi2_zext"
3414 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3416 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3419 switch (get_attr_prefix_0f (insn))
3422 return "{cwtl|cwde}";
3424 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3427 [(set_attr "type" "imovx")
3428 (set_attr "mode" "SI")
3429 (set (attr "prefix_0f")
3430 ;; movsx is short decodable while cwtl is vector decoded.
3431 (if_then_else (and (eq_attr "cpu" "!k6")
3432 (eq_attr "alternative" "0"))
3434 (const_string "1")))
3436 (if_then_else (eq_attr "prefix_0f" "0")
3438 (const_string "1")))])
3440 (define_insn "extendqihi2"
3441 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3442 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3445 switch (get_attr_prefix_0f (insn))
3448 return "{cbtw|cbw}";
3450 return "movs{bw|x}\t{%1,%0|%0, %1}";
3453 [(set_attr "type" "imovx")
3454 (set_attr "mode" "HI")
3455 (set (attr "prefix_0f")
3456 ;; movsx is short decodable while cwtl is vector decoded.
3457 (if_then_else (and (eq_attr "cpu" "!k6")
3458 (eq_attr "alternative" "0"))
3460 (const_string "1")))
3462 (if_then_else (eq_attr "prefix_0f" "0")
3464 (const_string "1")))])
3466 (define_insn "extendqisi2"
3467 [(set (match_operand:SI 0 "register_operand" "=r")
3468 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3470 "movs{bl|x}\t{%1,%0|%0, %1}"
3471 [(set_attr "type" "imovx")
3472 (set_attr "mode" "SI")])
3474 (define_insn "*extendqisi2_zext"
3475 [(set (match_operand:DI 0 "register_operand" "=r")
3477 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3479 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3480 [(set_attr "type" "imovx")
3481 (set_attr "mode" "SI")])
3483 ;; Conversions between float and double.
3485 ;; These are all no-ops in the model used for the 80387. So just
3488 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3489 (define_insn "*dummy_extendsfdf2"
3490 [(set (match_operand:DF 0 "push_operand" "=<")
3491 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3496 [(set (match_operand:DF 0 "push_operand" "")
3497 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3499 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3500 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3503 [(set (match_operand:DF 0 "push_operand" "")
3504 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3506 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3507 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3509 (define_insn "*dummy_extendsfxf2"
3510 [(set (match_operand:XF 0 "push_operand" "=<")
3511 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3516 [(set (match_operand:XF 0 "push_operand" "")
3517 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3519 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3520 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3521 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3524 [(set (match_operand:XF 0 "push_operand" "")
3525 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3527 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3528 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3529 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3532 [(set (match_operand:XF 0 "push_operand" "")
3533 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3535 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3536 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3537 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3540 [(set (match_operand:XF 0 "push_operand" "")
3541 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3543 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3544 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3545 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3547 (define_expand "extendsfdf2"
3548 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3549 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3550 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3552 /* ??? Needed for compress_float_constant since all fp constants
3553 are LEGITIMATE_CONSTANT_P. */
3554 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3556 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3557 && standard_80387_constant_p (operands[1]) > 0)
3559 operands[1] = simplify_const_unary_operation
3560 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3561 emit_move_insn_1 (operands[0], operands[1]);
3564 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3568 (define_insn "*extendsfdf2_mixed"
3569 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3570 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3571 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3573 switch (which_alternative)
3576 return output_387_reg_move (insn, operands);
3579 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3580 return "fstp%z0\t%y0";
3582 return "fst%z0\t%y0";
3585 return "cvtss2sd\t{%1, %0|%0, %1}";
3591 [(set_attr "type" "fmov,fmov,ssecvt")
3592 (set_attr "mode" "SF,XF,DF")])
3594 (define_insn "*extendsfdf2_sse"
3595 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3596 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3597 "TARGET_SSE2 && TARGET_SSE_MATH"
3598 "cvtss2sd\t{%1, %0|%0, %1}"
3599 [(set_attr "type" "ssecvt")
3600 (set_attr "mode" "DF")])
3602 (define_insn "*extendsfdf2_i387"
3603 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3604 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3607 switch (which_alternative)
3610 return output_387_reg_move (insn, operands);
3613 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3614 return "fstp%z0\t%y0";
3616 return "fst%z0\t%y0";
3622 [(set_attr "type" "fmov")
3623 (set_attr "mode" "SF,XF")])
3625 (define_expand "extendsfxf2"
3626 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3627 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3630 /* ??? Needed for compress_float_constant since all fp constants
3631 are LEGITIMATE_CONSTANT_P. */
3632 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3634 if (standard_80387_constant_p (operands[1]) > 0)
3636 operands[1] = simplify_const_unary_operation
3637 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3638 emit_move_insn_1 (operands[0], operands[1]);
3641 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3645 (define_insn "*extendsfxf2_i387"
3646 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3647 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3650 switch (which_alternative)
3653 return output_387_reg_move (insn, operands);
3656 /* There is no non-popping store to memory for XFmode. So if
3657 we need one, follow the store with a load. */
3658 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3659 return "fstp%z0\t%y0";
3661 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3667 [(set_attr "type" "fmov")
3668 (set_attr "mode" "SF,XF")])
3670 (define_expand "extenddfxf2"
3671 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3672 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3675 /* ??? Needed for compress_float_constant since all fp constants
3676 are LEGITIMATE_CONSTANT_P. */
3677 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3679 if (standard_80387_constant_p (operands[1]) > 0)
3681 operands[1] = simplify_const_unary_operation
3682 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3683 emit_move_insn_1 (operands[0], operands[1]);
3686 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3690 (define_insn "*extenddfxf2_i387"
3691 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3692 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3695 switch (which_alternative)
3698 return output_387_reg_move (insn, operands);
3701 /* There is no non-popping store to memory for XFmode. So if
3702 we need one, follow the store with a load. */
3703 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3704 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3706 return "fstp%z0\t%y0";
3712 [(set_attr "type" "fmov")
3713 (set_attr "mode" "DF,XF")])
3715 ;; %%% This seems bad bad news.
3716 ;; This cannot output into an f-reg because there is no way to be sure
3717 ;; of truncating in that case. Otherwise this is just like a simple move
3718 ;; insn. So we pretend we can output to a reg in order to get better
3719 ;; register preferencing, but we really use a stack slot.
3721 ;; Conversion from DFmode to SFmode.
3723 (define_expand "truncdfsf2"
3724 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3726 (match_operand:DF 1 "nonimmediate_operand" "")))]
3727 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3729 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3731 else if (flag_unsafe_math_optimizations)
3735 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3736 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3741 (define_expand "truncdfsf2_with_temp"
3742 [(parallel [(set (match_operand:SF 0 "" "")
3743 (float_truncate:SF (match_operand:DF 1 "" "")))
3744 (clobber (match_operand:SF 2 "" ""))])]
3747 (define_insn "*truncdfsf_fast_mixed"
3748 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3750 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3751 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3753 switch (which_alternative)
3756 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3757 return "fstp%z0\t%y0";
3759 return "fst%z0\t%y0";
3761 return output_387_reg_move (insn, operands);
3763 return "cvtsd2ss\t{%1, %0|%0, %1}";
3768 [(set_attr "type" "fmov,fmov,ssecvt")
3769 (set_attr "mode" "SF")])
3771 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3772 ;; because nothing we do here is unsafe.
3773 (define_insn "*truncdfsf_fast_sse"
3774 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3776 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3777 "TARGET_SSE2 && TARGET_SSE_MATH"
3778 "cvtsd2ss\t{%1, %0|%0, %1}"
3779 [(set_attr "type" "ssecvt")
3780 (set_attr "mode" "SF")])
3782 (define_insn "*truncdfsf_fast_i387"
3783 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3785 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3786 "TARGET_80387 && flag_unsafe_math_optimizations"
3787 "* return output_387_reg_move (insn, operands);"
3788 [(set_attr "type" "fmov")
3789 (set_attr "mode" "SF")])
3791 (define_insn "*truncdfsf_mixed"
3792 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3794 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3795 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3796 "TARGET_MIX_SSE_I387"
3798 switch (which_alternative)
3801 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3802 return "fstp%z0\t%y0";
3804 return "fst%z0\t%y0";
3808 return "cvtsd2ss\t{%1, %0|%0, %1}";
3813 [(set_attr "type" "fmov,multi,ssecvt")
3814 (set_attr "unit" "*,i387,*")
3815 (set_attr "mode" "SF")])
3817 (define_insn "*truncdfsf_i387"
3818 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3820 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3821 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3824 switch (which_alternative)
3827 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3828 return "fstp%z0\t%y0";
3830 return "fst%z0\t%y0";
3837 [(set_attr "type" "fmov,multi")
3838 (set_attr "unit" "*,i387")
3839 (set_attr "mode" "SF")])
3841 (define_insn "*truncdfsf2_i387_1"
3842 [(set (match_operand:SF 0 "memory_operand" "=m")
3844 (match_operand:DF 1 "register_operand" "f")))]
3846 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3847 && !TARGET_MIX_SSE_I387"
3849 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850 return "fstp%z0\t%y0";
3852 return "fst%z0\t%y0";
3854 [(set_attr "type" "fmov")
3855 (set_attr "mode" "SF")])
3858 [(set (match_operand:SF 0 "register_operand" "")
3860 (match_operand:DF 1 "fp_register_operand" "")))
3861 (clobber (match_operand 2 "" ""))]
3863 [(set (match_dup 2) (match_dup 1))
3864 (set (match_dup 0) (match_dup 2))]
3866 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3869 ;; Conversion from XFmode to SFmode.
3871 (define_expand "truncxfsf2"
3872 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3874 (match_operand:XF 1 "register_operand" "")))
3875 (clobber (match_dup 2))])]
3878 if (flag_unsafe_math_optimizations)
3880 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3881 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3882 if (reg != operands[0])
3883 emit_move_insn (operands[0], reg);
3887 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3890 (define_insn "*truncxfsf2_mixed"
3891 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3893 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3894 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3895 "TARGET_MIX_SSE_I387"
3897 gcc_assert (!which_alternative);
3898 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3899 return "fstp%z0\t%y0";
3901 return "fst%z0\t%y0";
3903 [(set_attr "type" "fmov,multi,multi,multi")
3904 (set_attr "unit" "*,i387,i387,i387")
3905 (set_attr "mode" "SF")])
3907 (define_insn "truncxfsf2_i387_noop"
3908 [(set (match_operand:SF 0 "register_operand" "=f")
3909 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3910 "TARGET_80387 && flag_unsafe_math_optimizations"
3912 return output_387_reg_move (insn, operands);
3914 [(set_attr "type" "fmov")
3915 (set_attr "mode" "SF")])
3917 (define_insn "*truncxfsf2_i387"
3918 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3920 (match_operand:XF 1 "register_operand" "f,f,f")))
3921 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3924 gcc_assert (!which_alternative);
3925 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3926 return "fstp%z0\t%y0";
3928 return "fst%z0\t%y0";
3930 [(set_attr "type" "fmov,multi,multi")
3931 (set_attr "unit" "*,i387,i387")
3932 (set_attr "mode" "SF")])
3934 (define_insn "*truncxfsf2_i387_1"
3935 [(set (match_operand:SF 0 "memory_operand" "=m")
3937 (match_operand:XF 1 "register_operand" "f")))]
3940 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3941 return "fstp%z0\t%y0";
3943 return "fst%z0\t%y0";
3945 [(set_attr "type" "fmov")
3946 (set_attr "mode" "SF")])
3949 [(set (match_operand:SF 0 "register_operand" "")
3951 (match_operand:XF 1 "register_operand" "")))
3952 (clobber (match_operand:SF 2 "memory_operand" ""))]
3953 "TARGET_80387 && reload_completed"
3954 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3955 (set (match_dup 0) (match_dup 2))]
3959 [(set (match_operand:SF 0 "memory_operand" "")
3961 (match_operand:XF 1 "register_operand" "")))
3962 (clobber (match_operand:SF 2 "memory_operand" ""))]
3964 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3967 ;; Conversion from XFmode to DFmode.
3969 (define_expand "truncxfdf2"
3970 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3972 (match_operand:XF 1 "register_operand" "")))
3973 (clobber (match_dup 2))])]
3976 if (flag_unsafe_math_optimizations)
3978 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3979 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3980 if (reg != operands[0])
3981 emit_move_insn (operands[0], reg);
3985 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3988 (define_insn "*truncxfdf2_mixed"
3989 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3991 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3992 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3993 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3995 gcc_assert (!which_alternative);
3996 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3997 return "fstp%z0\t%y0";
3999 return "fst%z0\t%y0";
4001 [(set_attr "type" "fmov,multi,multi,multi")
4002 (set_attr "unit" "*,i387,i387,i387")
4003 (set_attr "mode" "DF")])
4005 (define_insn "truncxfdf2_i387_noop"
4006 [(set (match_operand:DF 0 "register_operand" "=f")
4007 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4008 "TARGET_80387 && flag_unsafe_math_optimizations"
4010 return output_387_reg_move (insn, operands);
4012 [(set_attr "type" "fmov")
4013 (set_attr "mode" "DF")])
4015 (define_insn "*truncxfdf2_i387"
4016 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4018 (match_operand:XF 1 "register_operand" "f,f,f")))
4019 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4022 gcc_assert (!which_alternative);
4023 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4024 return "fstp%z0\t%y0";
4026 return "fst%z0\t%y0";
4028 [(set_attr "type" "fmov,multi,multi")
4029 (set_attr "unit" "*,i387,i387")
4030 (set_attr "mode" "DF")])
4032 (define_insn "*truncxfdf2_i387_1"
4033 [(set (match_operand:DF 0 "memory_operand" "=m")
4035 (match_operand:XF 1 "register_operand" "f")))]
4038 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4039 return "fstp%z0\t%y0";
4041 return "fst%z0\t%y0";
4043 [(set_attr "type" "fmov")
4044 (set_attr "mode" "DF")])
4047 [(set (match_operand:DF 0 "register_operand" "")
4049 (match_operand:XF 1 "register_operand" "")))
4050 (clobber (match_operand:DF 2 "memory_operand" ""))]
4051 "TARGET_80387 && reload_completed"
4052 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4053 (set (match_dup 0) (match_dup 2))]
4057 [(set (match_operand:DF 0 "memory_operand" "")
4059 (match_operand:XF 1 "register_operand" "")))
4060 (clobber (match_operand:DF 2 "memory_operand" ""))]
4062 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4065 ;; Signed conversion to DImode.
4067 (define_expand "fix_truncxfdi2"
4068 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4069 (fix:DI (match_operand:XF 1 "register_operand" "")))
4070 (clobber (reg:CC FLAGS_REG))])]
4075 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4080 (define_expand "fix_trunc<mode>di2"
4081 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4082 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4083 (clobber (reg:CC FLAGS_REG))])]
4084 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4087 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4089 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4092 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4094 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4095 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4096 if (out != operands[0])
4097 emit_move_insn (operands[0], out);
4102 ;; Signed conversion to SImode.
4104 (define_expand "fix_truncxfsi2"
4105 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4106 (fix:SI (match_operand:XF 1 "register_operand" "")))
4107 (clobber (reg:CC FLAGS_REG))])]
4112 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4117 (define_expand "fix_trunc<mode>si2"
4118 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4119 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4120 (clobber (reg:CC FLAGS_REG))])]
4121 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4124 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4126 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4129 if (SSE_FLOAT_MODE_P (<MODE>mode))
4131 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4132 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4133 if (out != operands[0])
4134 emit_move_insn (operands[0], out);
4139 ;; Signed conversion to HImode.
4141 (define_expand "fix_trunc<mode>hi2"
4142 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4143 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4144 (clobber (reg:CC FLAGS_REG))])]
4146 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4150 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4155 ;; When SSE is available, it is always faster to use it!
4156 (define_insn "fix_truncsfdi_sse"
4157 [(set (match_operand:DI 0 "register_operand" "=r,r")
4158 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4159 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4160 "cvttss2si{q}\t{%1, %0|%0, %1}"
4161 [(set_attr "type" "sseicvt")
4162 (set_attr "mode" "SF")
4163 (set_attr "athlon_decode" "double,vector")])
4165 (define_insn "fix_truncdfdi_sse"
4166 [(set (match_operand:DI 0 "register_operand" "=r,r")
4167 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4168 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4169 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4170 [(set_attr "type" "sseicvt")
4171 (set_attr "mode" "DF")
4172 (set_attr "athlon_decode" "double,vector")])
4174 (define_insn "fix_truncsfsi_sse"
4175 [(set (match_operand:SI 0 "register_operand" "=r,r")
4176 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4177 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4178 "cvttss2si\t{%1, %0|%0, %1}"
4179 [(set_attr "type" "sseicvt")
4180 (set_attr "mode" "DF")
4181 (set_attr "athlon_decode" "double,vector")])
4183 (define_insn "fix_truncdfsi_sse"
4184 [(set (match_operand:SI 0 "register_operand" "=r,r")
4185 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4186 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4187 "cvttsd2si\t{%1, %0|%0, %1}"
4188 [(set_attr "type" "sseicvt")
4189 (set_attr "mode" "DF")
4190 (set_attr "athlon_decode" "double,vector")])
4192 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4194 [(set (match_operand:DF 0 "register_operand" "")
4195 (match_operand:DF 1 "memory_operand" ""))
4196 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4197 (fix:SSEMODEI24 (match_dup 0)))]
4199 && peep2_reg_dead_p (2, operands[0])"
4200 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4204 [(set (match_operand:SF 0 "register_operand" "")
4205 (match_operand:SF 1 "memory_operand" ""))
4206 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4207 (fix:SSEMODEI24 (match_dup 0)))]
4209 && peep2_reg_dead_p (2, operands[0])"
4210 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4213 ;; Avoid vector decoded forms of the instruction.
4215 [(match_scratch:DF 2 "Y")
4216 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4217 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4218 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4219 [(set (match_dup 2) (match_dup 1))
4220 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4224 [(match_scratch:SF 2 "x")
4225 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4226 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4227 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4228 [(set (match_dup 2) (match_dup 1))
4229 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4232 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4233 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4234 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4236 && FLOAT_MODE_P (GET_MODE (operands[1]))
4237 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4238 && (TARGET_64BIT || <MODE>mode != DImode))
4240 && !(reload_completed || reload_in_progress)"
4245 if (memory_operand (operands[0], VOIDmode))
4246 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4249 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4250 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4256 [(set_attr "type" "fisttp")
4257 (set_attr "mode" "<MODE>")])
4259 (define_insn "fix_trunc<mode>_i387_fisttp"
4260 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4261 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4262 (clobber (match_scratch:XF 2 "=&1f"))]
4264 && FLOAT_MODE_P (GET_MODE (operands[1]))
4265 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4266 && (TARGET_64BIT || <MODE>mode != DImode))
4267 && TARGET_SSE_MATH)"
4268 "* return output_fix_trunc (insn, operands, 1);"
4269 [(set_attr "type" "fisttp")
4270 (set_attr "mode" "<MODE>")])
4272 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4273 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4274 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4275 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4276 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4278 && FLOAT_MODE_P (GET_MODE (operands[1]))
4279 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4280 && (TARGET_64BIT || <MODE>mode != DImode))
4281 && TARGET_SSE_MATH)"
4283 [(set_attr "type" "fisttp")
4284 (set_attr "mode" "<MODE>")])
4287 [(set (match_operand:X87MODEI 0 "register_operand" "")
4288 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4289 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4290 (clobber (match_scratch 3 ""))]
4292 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4293 (clobber (match_dup 3))])
4294 (set (match_dup 0) (match_dup 2))]
4298 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4299 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4300 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4301 (clobber (match_scratch 3 ""))]
4303 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4304 (clobber (match_dup 3))])]
4307 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4308 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4309 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4310 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4311 ;; function in i386.c.
4312 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4313 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4314 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4315 (clobber (reg:CC FLAGS_REG))]
4316 "TARGET_80387 && !TARGET_FISTTP
4317 && FLOAT_MODE_P (GET_MODE (operands[1]))
4318 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4319 && (TARGET_64BIT || <MODE>mode != DImode))
4320 && !(reload_completed || reload_in_progress)"
4325 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4327 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4328 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4329 if (memory_operand (operands[0], VOIDmode))
4330 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4331 operands[2], operands[3]));
4334 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4335 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4336 operands[2], operands[3],
4341 [(set_attr "type" "fistp")
4342 (set_attr "i387_cw" "trunc")
4343 (set_attr "mode" "<MODE>")])
4345 (define_insn "fix_truncdi_i387"
4346 [(set (match_operand:DI 0 "memory_operand" "=m")
4347 (fix:DI (match_operand 1 "register_operand" "f")))
4348 (use (match_operand:HI 2 "memory_operand" "m"))
4349 (use (match_operand:HI 3 "memory_operand" "m"))
4350 (clobber (match_scratch:XF 4 "=&1f"))]
4351 "TARGET_80387 && !TARGET_FISTTP
4352 && FLOAT_MODE_P (GET_MODE (operands[1]))
4353 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4354 "* return output_fix_trunc (insn, operands, 0);"
4355 [(set_attr "type" "fistp")
4356 (set_attr "i387_cw" "trunc")
4357 (set_attr "mode" "DI")])
4359 (define_insn "fix_truncdi_i387_with_temp"
4360 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4361 (fix:DI (match_operand 1 "register_operand" "f,f")))
4362 (use (match_operand:HI 2 "memory_operand" "m,m"))
4363 (use (match_operand:HI 3 "memory_operand" "m,m"))
4364 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4365 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4366 "TARGET_80387 && !TARGET_FISTTP
4367 && FLOAT_MODE_P (GET_MODE (operands[1]))
4368 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4370 [(set_attr "type" "fistp")
4371 (set_attr "i387_cw" "trunc")
4372 (set_attr "mode" "DI")])
4375 [(set (match_operand:DI 0 "register_operand" "")
4376 (fix:DI (match_operand 1 "register_operand" "")))
4377 (use (match_operand:HI 2 "memory_operand" ""))
4378 (use (match_operand:HI 3 "memory_operand" ""))
4379 (clobber (match_operand:DI 4 "memory_operand" ""))
4380 (clobber (match_scratch 5 ""))]
4382 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4385 (clobber (match_dup 5))])
4386 (set (match_dup 0) (match_dup 4))]
4390 [(set (match_operand:DI 0 "memory_operand" "")
4391 (fix:DI (match_operand 1 "register_operand" "")))
4392 (use (match_operand:HI 2 "memory_operand" ""))
4393 (use (match_operand:HI 3 "memory_operand" ""))
4394 (clobber (match_operand:DI 4 "memory_operand" ""))
4395 (clobber (match_scratch 5 ""))]
4397 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4400 (clobber (match_dup 5))])]
4403 (define_insn "fix_trunc<mode>_i387"
4404 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4405 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4406 (use (match_operand:HI 2 "memory_operand" "m"))
4407 (use (match_operand:HI 3 "memory_operand" "m"))]
4408 "TARGET_80387 && !TARGET_FISTTP
4409 && FLOAT_MODE_P (GET_MODE (operands[1]))
4410 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4411 "* return output_fix_trunc (insn, operands, 0);"
4412 [(set_attr "type" "fistp")
4413 (set_attr "i387_cw" "trunc")
4414 (set_attr "mode" "<MODE>")])
4416 (define_insn "fix_trunc<mode>_i387_with_temp"
4417 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4418 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4419 (use (match_operand:HI 2 "memory_operand" "m,m"))
4420 (use (match_operand:HI 3 "memory_operand" "m,m"))
4421 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4422 "TARGET_80387 && !TARGET_FISTTP
4423 && FLOAT_MODE_P (GET_MODE (operands[1]))
4424 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4426 [(set_attr "type" "fistp")
4427 (set_attr "i387_cw" "trunc")
4428 (set_attr "mode" "<MODE>")])
4431 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4432 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4433 (use (match_operand:HI 2 "memory_operand" ""))
4434 (use (match_operand:HI 3 "memory_operand" ""))
4435 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4437 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4439 (use (match_dup 3))])
4440 (set (match_dup 0) (match_dup 4))]
4444 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4445 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4446 (use (match_operand:HI 2 "memory_operand" ""))
4447 (use (match_operand:HI 3 "memory_operand" ""))
4448 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4450 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4452 (use (match_dup 3))])]
4455 (define_insn "x86_fnstcw_1"
4456 [(set (match_operand:HI 0 "memory_operand" "=m")
4457 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4460 [(set_attr "length" "2")
4461 (set_attr "mode" "HI")
4462 (set_attr "unit" "i387")])
4464 (define_insn "x86_fldcw_1"
4465 [(set (reg:HI FPCR_REG)
4466 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4469 [(set_attr "length" "2")
4470 (set_attr "mode" "HI")
4471 (set_attr "unit" "i387")
4472 (set_attr "athlon_decode" "vector")])
4474 ;; Conversion between fixed point and floating point.
4476 ;; Even though we only accept memory inputs, the backend _really_
4477 ;; wants to be able to do this between registers.
4479 (define_expand "floathisf2"
4480 [(set (match_operand:SF 0 "register_operand" "")
4481 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4482 "TARGET_80387 || TARGET_SSE_MATH"
4484 if (TARGET_SSE_MATH)
4486 emit_insn (gen_floatsisf2 (operands[0],
4487 convert_to_mode (SImode, operands[1], 0)));
4492 (define_insn "*floathisf2_i387"
4493 [(set (match_operand:SF 0 "register_operand" "=f,f")
4494 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4495 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4499 [(set_attr "type" "fmov,multi")
4500 (set_attr "mode" "SF")
4501 (set_attr "unit" "*,i387")
4502 (set_attr "fp_int_src" "true")])
4504 (define_expand "floatsisf2"
4505 [(set (match_operand:SF 0 "register_operand" "")
4506 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4507 "TARGET_80387 || TARGET_SSE_MATH"
4510 (define_insn "*floatsisf2_mixed"
4511 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4512 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4513 "TARGET_MIX_SSE_I387"
4517 cvtsi2ss\t{%1, %0|%0, %1}
4518 cvtsi2ss\t{%1, %0|%0, %1}"
4519 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4520 (set_attr "mode" "SF")
4521 (set_attr "unit" "*,i387,*,*")
4522 (set_attr "athlon_decode" "*,*,vector,double")
4523 (set_attr "fp_int_src" "true")])
4525 (define_insn "*floatsisf2_sse"
4526 [(set (match_operand:SF 0 "register_operand" "=x,x")
4527 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4529 "cvtsi2ss\t{%1, %0|%0, %1}"
4530 [(set_attr "type" "sseicvt")
4531 (set_attr "mode" "SF")
4532 (set_attr "athlon_decode" "vector,double")
4533 (set_attr "fp_int_src" "true")])
4535 (define_insn "*floatsisf2_i387"
4536 [(set (match_operand:SF 0 "register_operand" "=f,f")
4537 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4542 [(set_attr "type" "fmov,multi")
4543 (set_attr "mode" "SF")
4544 (set_attr "unit" "*,i387")
4545 (set_attr "fp_int_src" "true")])
4547 (define_expand "floatdisf2"
4548 [(set (match_operand:SF 0 "register_operand" "")
4549 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4550 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4553 (define_insn "*floatdisf2_mixed"
4554 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4555 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4556 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4560 cvtsi2ss{q}\t{%1, %0|%0, %1}
4561 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4562 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4563 (set_attr "mode" "SF")
4564 (set_attr "unit" "*,i387,*,*")
4565 (set_attr "athlon_decode" "*,*,vector,double")
4566 (set_attr "fp_int_src" "true")])
4568 (define_insn "*floatdisf2_sse"
4569 [(set (match_operand:SF 0 "register_operand" "=x,x")
4570 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4571 "TARGET_64BIT && TARGET_SSE_MATH"
4572 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4573 [(set_attr "type" "sseicvt")
4574 (set_attr "mode" "SF")
4575 (set_attr "athlon_decode" "vector,double")
4576 (set_attr "fp_int_src" "true")])
4578 (define_insn "*floatdisf2_i387"
4579 [(set (match_operand:SF 0 "register_operand" "=f,f")
4580 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4585 [(set_attr "type" "fmov,multi")
4586 (set_attr "mode" "SF")
4587 (set_attr "unit" "*,i387")
4588 (set_attr "fp_int_src" "true")])
4590 (define_expand "floathidf2"
4591 [(set (match_operand:DF 0 "register_operand" "")
4592 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4593 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4595 if (TARGET_SSE2 && TARGET_SSE_MATH)
4597 emit_insn (gen_floatsidf2 (operands[0],
4598 convert_to_mode (SImode, operands[1], 0)));
4603 (define_insn "*floathidf2_i387"
4604 [(set (match_operand:DF 0 "register_operand" "=f,f")
4605 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4606 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4610 [(set_attr "type" "fmov,multi")
4611 (set_attr "mode" "DF")
4612 (set_attr "unit" "*,i387")
4613 (set_attr "fp_int_src" "true")])
4615 (define_expand "floatsidf2"
4616 [(set (match_operand:DF 0 "register_operand" "")
4617 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4618 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4621 (define_insn "*floatsidf2_mixed"
4622 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4623 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4624 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4628 cvtsi2sd\t{%1, %0|%0, %1}
4629 cvtsi2sd\t{%1, %0|%0, %1}"
4630 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4631 (set_attr "mode" "DF")
4632 (set_attr "unit" "*,i387,*,*")
4633 (set_attr "athlon_decode" "*,*,double,direct")
4634 (set_attr "fp_int_src" "true")])
4636 (define_insn "*floatsidf2_sse"
4637 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4638 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4639 "TARGET_SSE2 && TARGET_SSE_MATH"
4640 "cvtsi2sd\t{%1, %0|%0, %1}"
4641 [(set_attr "type" "sseicvt")
4642 (set_attr "mode" "DF")
4643 (set_attr "athlon_decode" "double,direct")
4644 (set_attr "fp_int_src" "true")])
4646 (define_insn "*floatsidf2_i387"
4647 [(set (match_operand:DF 0 "register_operand" "=f,f")
4648 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4653 [(set_attr "type" "fmov,multi")
4654 (set_attr "mode" "DF")
4655 (set_attr "unit" "*,i387")
4656 (set_attr "fp_int_src" "true")])
4658 (define_expand "floatdidf2"
4659 [(set (match_operand:DF 0 "register_operand" "")
4660 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4661 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4664 (define_insn "*floatdidf2_mixed"
4665 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4666 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4667 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4671 cvtsi2sd{q}\t{%1, %0|%0, %1}
4672 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4673 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4674 (set_attr "mode" "DF")
4675 (set_attr "unit" "*,i387,*,*")
4676 (set_attr "athlon_decode" "*,*,double,direct")
4677 (set_attr "fp_int_src" "true")])
4679 (define_insn "*floatdidf2_sse"
4680 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4681 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4682 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4683 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4684 [(set_attr "type" "sseicvt")
4685 (set_attr "mode" "DF")
4686 (set_attr "athlon_decode" "double,direct")
4687 (set_attr "fp_int_src" "true")])
4689 (define_insn "*floatdidf2_i387"
4690 [(set (match_operand:DF 0 "register_operand" "=f,f")
4691 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4696 [(set_attr "type" "fmov,multi")
4697 (set_attr "mode" "DF")
4698 (set_attr "unit" "*,i387")
4699 (set_attr "fp_int_src" "true")])
4701 (define_insn "floathixf2"
4702 [(set (match_operand:XF 0 "register_operand" "=f,f")
4703 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4708 [(set_attr "type" "fmov,multi")
4709 (set_attr "mode" "XF")
4710 (set_attr "unit" "*,i387")
4711 (set_attr "fp_int_src" "true")])
4713 (define_insn "floatsixf2"
4714 [(set (match_operand:XF 0 "register_operand" "=f,f")
4715 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4720 [(set_attr "type" "fmov,multi")
4721 (set_attr "mode" "XF")
4722 (set_attr "unit" "*,i387")
4723 (set_attr "fp_int_src" "true")])
4725 (define_insn "floatdixf2"
4726 [(set (match_operand:XF 0 "register_operand" "=f,f")
4727 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4732 [(set_attr "type" "fmov,multi")
4733 (set_attr "mode" "XF")
4734 (set_attr "unit" "*,i387")
4735 (set_attr "fp_int_src" "true")])
4737 ;; %%% Kill these when reload knows how to do it.
4739 [(set (match_operand 0 "fp_register_operand" "")
4740 (float (match_operand 1 "register_operand" "")))]
4743 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4746 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4747 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4748 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4749 ix86_free_from_memory (GET_MODE (operands[1]));
4753 (define_expand "floatunssisf2"
4754 [(use (match_operand:SF 0 "register_operand" ""))
4755 (use (match_operand:SI 1 "register_operand" ""))]
4756 "!TARGET_64BIT && TARGET_SSE_MATH"
4757 "x86_emit_floatuns (operands); DONE;")
4759 (define_expand "floatunsdisf2"
4760 [(use (match_operand:SF 0 "register_operand" ""))
4761 (use (match_operand:DI 1 "register_operand" ""))]
4762 "TARGET_64BIT && TARGET_SSE_MATH"
4763 "x86_emit_floatuns (operands); DONE;")
4765 (define_expand "floatunsdidf2"
4766 [(use (match_operand:DF 0 "register_operand" ""))
4767 (use (match_operand:DI 1 "register_operand" ""))]
4768 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4769 "x86_emit_floatuns (operands); DONE;")
4771 ;; SSE extract/set expanders
4776 ;; %%% splits for addditi3
4778 (define_expand "addti3"
4779 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4780 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4781 (match_operand:TI 2 "x86_64_general_operand" "")))
4782 (clobber (reg:CC FLAGS_REG))]
4784 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4786 (define_insn "*addti3_1"
4787 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4788 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4789 (match_operand:TI 2 "general_operand" "roiF,riF")))
4790 (clobber (reg:CC FLAGS_REG))]
4791 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4795 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4796 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4797 (match_operand:TI 2 "general_operand" "")))
4798 (clobber (reg:CC FLAGS_REG))]
4799 "TARGET_64BIT && reload_completed"
4800 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4802 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4803 (parallel [(set (match_dup 3)
4804 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4807 (clobber (reg:CC FLAGS_REG))])]
4808 "split_ti (operands+0, 1, operands+0, operands+3);
4809 split_ti (operands+1, 1, operands+1, operands+4);
4810 split_ti (operands+2, 1, operands+2, operands+5);")
4812 ;; %%% splits for addsidi3
4813 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4814 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4815 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4817 (define_expand "adddi3"
4818 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4819 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4820 (match_operand:DI 2 "x86_64_general_operand" "")))
4821 (clobber (reg:CC FLAGS_REG))]
4823 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4825 (define_insn "*adddi3_1"
4826 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4827 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4828 (match_operand:DI 2 "general_operand" "roiF,riF")))
4829 (clobber (reg:CC FLAGS_REG))]
4830 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4834 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4835 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4836 (match_operand:DI 2 "general_operand" "")))
4837 (clobber (reg:CC FLAGS_REG))]
4838 "!TARGET_64BIT && reload_completed"
4839 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4841 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4842 (parallel [(set (match_dup 3)
4843 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4846 (clobber (reg:CC FLAGS_REG))])]
4847 "split_di (operands+0, 1, operands+0, operands+3);
4848 split_di (operands+1, 1, operands+1, operands+4);
4849 split_di (operands+2, 1, operands+2, operands+5);")
4851 (define_insn "adddi3_carry_rex64"
4852 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4853 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4854 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4855 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4856 (clobber (reg:CC FLAGS_REG))]
4857 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4858 "adc{q}\t{%2, %0|%0, %2}"
4859 [(set_attr "type" "alu")
4860 (set_attr "pent_pair" "pu")
4861 (set_attr "mode" "DI")])
4863 (define_insn "*adddi3_cc_rex64"
4864 [(set (reg:CC FLAGS_REG)
4865 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4866 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4868 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4869 (plus:DI (match_dup 1) (match_dup 2)))]
4870 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4871 "add{q}\t{%2, %0|%0, %2}"
4872 [(set_attr "type" "alu")
4873 (set_attr "mode" "DI")])
4875 (define_insn "addqi3_carry"
4876 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4877 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4878 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4879 (match_operand:QI 2 "general_operand" "qi,qm")))
4880 (clobber (reg:CC FLAGS_REG))]
4881 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4882 "adc{b}\t{%2, %0|%0, %2}"
4883 [(set_attr "type" "alu")
4884 (set_attr "pent_pair" "pu")
4885 (set_attr "mode" "QI")])
4887 (define_insn "addhi3_carry"
4888 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4889 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4890 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4891 (match_operand:HI 2 "general_operand" "ri,rm")))
4892 (clobber (reg:CC FLAGS_REG))]
4893 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4894 "adc{w}\t{%2, %0|%0, %2}"
4895 [(set_attr "type" "alu")
4896 (set_attr "pent_pair" "pu")
4897 (set_attr "mode" "HI")])
4899 (define_insn "addsi3_carry"
4900 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4901 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4902 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4903 (match_operand:SI 2 "general_operand" "ri,rm")))
4904 (clobber (reg:CC FLAGS_REG))]
4905 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4906 "adc{l}\t{%2, %0|%0, %2}"
4907 [(set_attr "type" "alu")
4908 (set_attr "pent_pair" "pu")
4909 (set_attr "mode" "SI")])
4911 (define_insn "*addsi3_carry_zext"
4912 [(set (match_operand:DI 0 "register_operand" "=r")
4914 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4915 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4916 (match_operand:SI 2 "general_operand" "rim"))))
4917 (clobber (reg:CC FLAGS_REG))]
4918 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4919 "adc{l}\t{%2, %k0|%k0, %2}"
4920 [(set_attr "type" "alu")
4921 (set_attr "pent_pair" "pu")
4922 (set_attr "mode" "SI")])
4924 (define_insn "*addsi3_cc"
4925 [(set (reg:CC FLAGS_REG)
4926 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4927 (match_operand:SI 2 "general_operand" "ri,rm")]
4929 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4930 (plus:SI (match_dup 1) (match_dup 2)))]
4931 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4932 "add{l}\t{%2, %0|%0, %2}"
4933 [(set_attr "type" "alu")
4934 (set_attr "mode" "SI")])
4936 (define_insn "addqi3_cc"
4937 [(set (reg:CC FLAGS_REG)
4938 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4939 (match_operand:QI 2 "general_operand" "qi,qm")]
4941 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4942 (plus:QI (match_dup 1) (match_dup 2)))]
4943 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4944 "add{b}\t{%2, %0|%0, %2}"
4945 [(set_attr "type" "alu")
4946 (set_attr "mode" "QI")])
4948 (define_expand "addsi3"
4949 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4950 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4951 (match_operand:SI 2 "general_operand" "")))
4952 (clobber (reg:CC FLAGS_REG))])]
4954 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4956 (define_insn "*lea_1"
4957 [(set (match_operand:SI 0 "register_operand" "=r")
4958 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4960 "lea{l}\t{%a1, %0|%0, %a1}"
4961 [(set_attr "type" "lea")
4962 (set_attr "mode" "SI")])
4964 (define_insn "*lea_1_rex64"
4965 [(set (match_operand:SI 0 "register_operand" "=r")
4966 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4968 "lea{l}\t{%a1, %0|%0, %a1}"
4969 [(set_attr "type" "lea")
4970 (set_attr "mode" "SI")])
4972 (define_insn "*lea_1_zext"
4973 [(set (match_operand:DI 0 "register_operand" "=r")
4975 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4977 "lea{l}\t{%a1, %k0|%k0, %a1}"
4978 [(set_attr "type" "lea")
4979 (set_attr "mode" "SI")])
4981 (define_insn "*lea_2_rex64"
4982 [(set (match_operand:DI 0 "register_operand" "=r")
4983 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4985 "lea{q}\t{%a1, %0|%0, %a1}"
4986 [(set_attr "type" "lea")
4987 (set_attr "mode" "DI")])
4989 ;; The lea patterns for non-Pmodes needs to be matched by several
4990 ;; insns converted to real lea by splitters.
4992 (define_insn_and_split "*lea_general_1"
4993 [(set (match_operand 0 "register_operand" "=r")
4994 (plus (plus (match_operand 1 "index_register_operand" "l")
4995 (match_operand 2 "register_operand" "r"))
4996 (match_operand 3 "immediate_operand" "i")))]
4997 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4998 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4999 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5000 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5001 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5002 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5003 || GET_MODE (operands[3]) == VOIDmode)"
5005 "&& reload_completed"
5009 operands[0] = gen_lowpart (SImode, operands[0]);
5010 operands[1] = gen_lowpart (Pmode, operands[1]);
5011 operands[2] = gen_lowpart (Pmode, operands[2]);
5012 operands[3] = gen_lowpart (Pmode, operands[3]);
5013 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5015 if (Pmode != SImode)
5016 pat = gen_rtx_SUBREG (SImode, pat, 0);
5017 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5020 [(set_attr "type" "lea")
5021 (set_attr "mode" "SI")])
5023 (define_insn_and_split "*lea_general_1_zext"
5024 [(set (match_operand:DI 0 "register_operand" "=r")
5026 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5027 (match_operand:SI 2 "register_operand" "r"))
5028 (match_operand:SI 3 "immediate_operand" "i"))))]
5031 "&& reload_completed"
5033 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5035 (match_dup 3)) 0)))]
5037 operands[1] = gen_lowpart (Pmode, operands[1]);
5038 operands[2] = gen_lowpart (Pmode, operands[2]);
5039 operands[3] = gen_lowpart (Pmode, operands[3]);
5041 [(set_attr "type" "lea")
5042 (set_attr "mode" "SI")])
5044 (define_insn_and_split "*lea_general_2"
5045 [(set (match_operand 0 "register_operand" "=r")
5046 (plus (mult (match_operand 1 "index_register_operand" "l")
5047 (match_operand 2 "const248_operand" "i"))
5048 (match_operand 3 "nonmemory_operand" "ri")))]
5049 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5050 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5051 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5052 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5053 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5054 || GET_MODE (operands[3]) == VOIDmode)"
5056 "&& reload_completed"
5060 operands[0] = gen_lowpart (SImode, operands[0]);
5061 operands[1] = gen_lowpart (Pmode, operands[1]);
5062 operands[3] = gen_lowpart (Pmode, operands[3]);
5063 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5065 if (Pmode != SImode)
5066 pat = gen_rtx_SUBREG (SImode, pat, 0);
5067 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5070 [(set_attr "type" "lea")
5071 (set_attr "mode" "SI")])
5073 (define_insn_and_split "*lea_general_2_zext"
5074 [(set (match_operand:DI 0 "register_operand" "=r")
5076 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5077 (match_operand:SI 2 "const248_operand" "n"))
5078 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5081 "&& reload_completed"
5083 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5085 (match_dup 3)) 0)))]
5087 operands[1] = gen_lowpart (Pmode, operands[1]);
5088 operands[3] = gen_lowpart (Pmode, operands[3]);
5090 [(set_attr "type" "lea")
5091 (set_attr "mode" "SI")])
5093 (define_insn_and_split "*lea_general_3"
5094 [(set (match_operand 0 "register_operand" "=r")
5095 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5096 (match_operand 2 "const248_operand" "i"))
5097 (match_operand 3 "register_operand" "r"))
5098 (match_operand 4 "immediate_operand" "i")))]
5099 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5100 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5101 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5102 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5103 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5105 "&& reload_completed"
5109 operands[0] = gen_lowpart (SImode, operands[0]);
5110 operands[1] = gen_lowpart (Pmode, operands[1]);
5111 operands[3] = gen_lowpart (Pmode, operands[3]);
5112 operands[4] = gen_lowpart (Pmode, operands[4]);
5113 pat = gen_rtx_PLUS (Pmode,
5114 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5118 if (Pmode != SImode)
5119 pat = gen_rtx_SUBREG (SImode, pat, 0);
5120 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5123 [(set_attr "type" "lea")
5124 (set_attr "mode" "SI")])
5126 (define_insn_and_split "*lea_general_3_zext"
5127 [(set (match_operand:DI 0 "register_operand" "=r")
5129 (plus:SI (plus:SI (mult:SI
5130 (match_operand:SI 1 "index_register_operand" "l")
5131 (match_operand:SI 2 "const248_operand" "n"))
5132 (match_operand:SI 3 "register_operand" "r"))
5133 (match_operand:SI 4 "immediate_operand" "i"))))]
5136 "&& reload_completed"
5138 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5141 (match_dup 4)) 0)))]
5143 operands[1] = gen_lowpart (Pmode, operands[1]);
5144 operands[3] = gen_lowpart (Pmode, operands[3]);
5145 operands[4] = gen_lowpart (Pmode, operands[4]);
5147 [(set_attr "type" "lea")
5148 (set_attr "mode" "SI")])
5150 (define_insn "*adddi_1_rex64"
5151 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5152 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5153 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5154 (clobber (reg:CC FLAGS_REG))]
5155 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5157 switch (get_attr_type (insn))
5160 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5161 return "lea{q}\t{%a2, %0|%0, %a2}";
5164 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5165 if (operands[2] == const1_rtx)
5166 return "inc{q}\t%0";
5169 gcc_assert (operands[2] == constm1_rtx);
5170 return "dec{q}\t%0";
5174 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5176 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5177 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5178 if (GET_CODE (operands[2]) == CONST_INT
5179 /* Avoid overflows. */
5180 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5181 && (INTVAL (operands[2]) == 128
5182 || (INTVAL (operands[2]) < 0
5183 && INTVAL (operands[2]) != -128)))
5185 operands[2] = GEN_INT (-INTVAL (operands[2]));
5186 return "sub{q}\t{%2, %0|%0, %2}";
5188 return "add{q}\t{%2, %0|%0, %2}";
5192 (cond [(eq_attr "alternative" "2")
5193 (const_string "lea")
5194 ; Current assemblers are broken and do not allow @GOTOFF in
5195 ; ought but a memory context.
5196 (match_operand:DI 2 "pic_symbolic_operand" "")
5197 (const_string "lea")
5198 (match_operand:DI 2 "incdec_operand" "")
5199 (const_string "incdec")
5201 (const_string "alu")))
5202 (set_attr "mode" "DI")])
5204 ;; Convert lea to the lea pattern to avoid flags dependency.
5206 [(set (match_operand:DI 0 "register_operand" "")
5207 (plus:DI (match_operand:DI 1 "register_operand" "")
5208 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5209 (clobber (reg:CC FLAGS_REG))]
5210 "TARGET_64BIT && reload_completed
5211 && true_regnum (operands[0]) != true_regnum (operands[1])"
5213 (plus:DI (match_dup 1)
5217 (define_insn "*adddi_2_rex64"
5218 [(set (reg FLAGS_REG)
5220 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5221 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5223 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5224 (plus:DI (match_dup 1) (match_dup 2)))]
5225 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5226 && ix86_binary_operator_ok (PLUS, DImode, operands)
5227 /* Current assemblers are broken and do not allow @GOTOFF in
5228 ought but a memory context. */
5229 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5231 switch (get_attr_type (insn))
5234 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5235 if (operands[2] == const1_rtx)
5236 return "inc{q}\t%0";
5239 gcc_assert (operands[2] == constm1_rtx);
5240 return "dec{q}\t%0";
5244 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5245 /* ???? We ought to handle there the 32bit case too
5246 - do we need new constraint? */
5247 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5248 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5249 if (GET_CODE (operands[2]) == CONST_INT
5250 /* Avoid overflows. */
5251 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5252 && (INTVAL (operands[2]) == 128
5253 || (INTVAL (operands[2]) < 0
5254 && INTVAL (operands[2]) != -128)))
5256 operands[2] = GEN_INT (-INTVAL (operands[2]));
5257 return "sub{q}\t{%2, %0|%0, %2}";
5259 return "add{q}\t{%2, %0|%0, %2}";
5263 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5264 (const_string "incdec")
5265 (const_string "alu")))
5266 (set_attr "mode" "DI")])
5268 (define_insn "*adddi_3_rex64"
5269 [(set (reg FLAGS_REG)
5270 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5271 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5272 (clobber (match_scratch:DI 0 "=r"))]
5274 && ix86_match_ccmode (insn, CCZmode)
5275 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5276 /* Current assemblers are broken and do not allow @GOTOFF in
5277 ought but a memory context. */
5278 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5280 switch (get_attr_type (insn))
5283 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5284 if (operands[2] == const1_rtx)
5285 return "inc{q}\t%0";
5288 gcc_assert (operands[2] == constm1_rtx);
5289 return "dec{q}\t%0";
5293 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5294 /* ???? We ought to handle there the 32bit case too
5295 - do we need new constraint? */
5296 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5297 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5298 if (GET_CODE (operands[2]) == CONST_INT
5299 /* Avoid overflows. */
5300 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5301 && (INTVAL (operands[2]) == 128
5302 || (INTVAL (operands[2]) < 0
5303 && INTVAL (operands[2]) != -128)))
5305 operands[2] = GEN_INT (-INTVAL (operands[2]));
5306 return "sub{q}\t{%2, %0|%0, %2}";
5308 return "add{q}\t{%2, %0|%0, %2}";
5312 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5313 (const_string "incdec")
5314 (const_string "alu")))
5315 (set_attr "mode" "DI")])
5317 ; For comparisons against 1, -1 and 128, we may generate better code
5318 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5319 ; is matched then. We can't accept general immediate, because for
5320 ; case of overflows, the result is messed up.
5321 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5323 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5324 ; only for comparisons not depending on it.
5325 (define_insn "*adddi_4_rex64"
5326 [(set (reg FLAGS_REG)
5327 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5328 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5329 (clobber (match_scratch:DI 0 "=rm"))]
5331 && ix86_match_ccmode (insn, CCGCmode)"
5333 switch (get_attr_type (insn))
5336 if (operands[2] == constm1_rtx)
5337 return "inc{q}\t%0";
5340 gcc_assert (operands[2] == const1_rtx);
5341 return "dec{q}\t%0";
5345 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5346 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5347 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5348 if ((INTVAL (operands[2]) == -128
5349 || (INTVAL (operands[2]) > 0
5350 && INTVAL (operands[2]) != 128))
5351 /* Avoid overflows. */
5352 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5353 return "sub{q}\t{%2, %0|%0, %2}";
5354 operands[2] = GEN_INT (-INTVAL (operands[2]));
5355 return "add{q}\t{%2, %0|%0, %2}";
5359 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5360 (const_string "incdec")
5361 (const_string "alu")))
5362 (set_attr "mode" "DI")])
5364 (define_insn "*adddi_5_rex64"
5365 [(set (reg FLAGS_REG)
5367 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5368 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5370 (clobber (match_scratch:DI 0 "=r"))]
5372 && ix86_match_ccmode (insn, CCGOCmode)
5373 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5374 /* Current assemblers are broken and do not allow @GOTOFF in
5375 ought but a memory context. */
5376 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5378 switch (get_attr_type (insn))
5381 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5382 if (operands[2] == const1_rtx)
5383 return "inc{q}\t%0";
5386 gcc_assert (operands[2] == constm1_rtx);
5387 return "dec{q}\t%0";
5391 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5392 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5393 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5394 if (GET_CODE (operands[2]) == CONST_INT
5395 /* Avoid overflows. */
5396 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5397 && (INTVAL (operands[2]) == 128
5398 || (INTVAL (operands[2]) < 0
5399 && INTVAL (operands[2]) != -128)))
5401 operands[2] = GEN_INT (-INTVAL (operands[2]));
5402 return "sub{q}\t{%2, %0|%0, %2}";
5404 return "add{q}\t{%2, %0|%0, %2}";
5408 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5409 (const_string "incdec")
5410 (const_string "alu")))
5411 (set_attr "mode" "DI")])
5414 (define_insn "*addsi_1"
5415 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5416 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5417 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5418 (clobber (reg:CC FLAGS_REG))]
5419 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5421 switch (get_attr_type (insn))
5424 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5425 return "lea{l}\t{%a2, %0|%0, %a2}";
5428 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5429 if (operands[2] == const1_rtx)
5430 return "inc{l}\t%0";
5433 gcc_assert (operands[2] == constm1_rtx);
5434 return "dec{l}\t%0";
5438 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5440 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5441 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5442 if (GET_CODE (operands[2]) == CONST_INT
5443 && (INTVAL (operands[2]) == 128
5444 || (INTVAL (operands[2]) < 0
5445 && INTVAL (operands[2]) != -128)))
5447 operands[2] = GEN_INT (-INTVAL (operands[2]));
5448 return "sub{l}\t{%2, %0|%0, %2}";
5450 return "add{l}\t{%2, %0|%0, %2}";
5454 (cond [(eq_attr "alternative" "2")
5455 (const_string "lea")
5456 ; Current assemblers are broken and do not allow @GOTOFF in
5457 ; ought but a memory context.
5458 (match_operand:SI 2 "pic_symbolic_operand" "")
5459 (const_string "lea")
5460 (match_operand:SI 2 "incdec_operand" "")
5461 (const_string "incdec")
5463 (const_string "alu")))
5464 (set_attr "mode" "SI")])
5466 ;; Convert lea to the lea pattern to avoid flags dependency.
5468 [(set (match_operand 0 "register_operand" "")
5469 (plus (match_operand 1 "register_operand" "")
5470 (match_operand 2 "nonmemory_operand" "")))
5471 (clobber (reg:CC FLAGS_REG))]
5473 && true_regnum (operands[0]) != true_regnum (operands[1])"
5477 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5478 may confuse gen_lowpart. */
5479 if (GET_MODE (operands[0]) != Pmode)
5481 operands[1] = gen_lowpart (Pmode, operands[1]);
5482 operands[2] = gen_lowpart (Pmode, operands[2]);
5484 operands[0] = gen_lowpart (SImode, operands[0]);
5485 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5486 if (Pmode != SImode)
5487 pat = gen_rtx_SUBREG (SImode, pat, 0);
5488 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5492 ;; It may seem that nonimmediate operand is proper one for operand 1.
5493 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5494 ;; we take care in ix86_binary_operator_ok to not allow two memory
5495 ;; operands so proper swapping will be done in reload. This allow
5496 ;; patterns constructed from addsi_1 to match.
5497 (define_insn "addsi_1_zext"
5498 [(set (match_operand:DI 0 "register_operand" "=r,r")
5500 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5501 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5502 (clobber (reg:CC FLAGS_REG))]
5503 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5505 switch (get_attr_type (insn))
5508 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5509 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5512 if (operands[2] == const1_rtx)
5513 return "inc{l}\t%k0";
5516 gcc_assert (operands[2] == constm1_rtx);
5517 return "dec{l}\t%k0";
5521 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5522 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5523 if (GET_CODE (operands[2]) == CONST_INT
5524 && (INTVAL (operands[2]) == 128
5525 || (INTVAL (operands[2]) < 0
5526 && INTVAL (operands[2]) != -128)))
5528 operands[2] = GEN_INT (-INTVAL (operands[2]));
5529 return "sub{l}\t{%2, %k0|%k0, %2}";
5531 return "add{l}\t{%2, %k0|%k0, %2}";
5535 (cond [(eq_attr "alternative" "1")
5536 (const_string "lea")
5537 ; Current assemblers are broken and do not allow @GOTOFF in
5538 ; ought but a memory context.
5539 (match_operand:SI 2 "pic_symbolic_operand" "")
5540 (const_string "lea")
5541 (match_operand:SI 2 "incdec_operand" "")
5542 (const_string "incdec")
5544 (const_string "alu")))
5545 (set_attr "mode" "SI")])
5547 ;; Convert lea to the lea pattern to avoid flags dependency.
5549 [(set (match_operand:DI 0 "register_operand" "")
5551 (plus:SI (match_operand:SI 1 "register_operand" "")
5552 (match_operand:SI 2 "nonmemory_operand" ""))))
5553 (clobber (reg:CC FLAGS_REG))]
5554 "TARGET_64BIT && reload_completed
5555 && true_regnum (operands[0]) != true_regnum (operands[1])"
5557 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5559 operands[1] = gen_lowpart (Pmode, operands[1]);
5560 operands[2] = gen_lowpart (Pmode, operands[2]);
5563 (define_insn "*addsi_2"
5564 [(set (reg FLAGS_REG)
5566 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5567 (match_operand:SI 2 "general_operand" "rmni,rni"))
5569 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5570 (plus:SI (match_dup 1) (match_dup 2)))]
5571 "ix86_match_ccmode (insn, CCGOCmode)
5572 && ix86_binary_operator_ok (PLUS, SImode, operands)
5573 /* Current assemblers are broken and do not allow @GOTOFF in
5574 ought but a memory context. */
5575 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5577 switch (get_attr_type (insn))
5580 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5581 if (operands[2] == const1_rtx)
5582 return "inc{l}\t%0";
5585 gcc_assert (operands[2] == constm1_rtx);
5586 return "dec{l}\t%0";
5590 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5591 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5592 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5593 if (GET_CODE (operands[2]) == CONST_INT
5594 && (INTVAL (operands[2]) == 128
5595 || (INTVAL (operands[2]) < 0
5596 && INTVAL (operands[2]) != -128)))
5598 operands[2] = GEN_INT (-INTVAL (operands[2]));
5599 return "sub{l}\t{%2, %0|%0, %2}";
5601 return "add{l}\t{%2, %0|%0, %2}";
5605 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5606 (const_string "incdec")
5607 (const_string "alu")))
5608 (set_attr "mode" "SI")])
5610 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5611 (define_insn "*addsi_2_zext"
5612 [(set (reg FLAGS_REG)
5614 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5615 (match_operand:SI 2 "general_operand" "rmni"))
5617 (set (match_operand:DI 0 "register_operand" "=r")
5618 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5619 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5620 && ix86_binary_operator_ok (PLUS, SImode, operands)
5621 /* Current assemblers are broken and do not allow @GOTOFF in
5622 ought but a memory context. */
5623 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5625 switch (get_attr_type (insn))
5628 if (operands[2] == const1_rtx)
5629 return "inc{l}\t%k0";
5632 gcc_assert (operands[2] == constm1_rtx);
5633 return "dec{l}\t%k0";
5637 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5638 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5639 if (GET_CODE (operands[2]) == CONST_INT
5640 && (INTVAL (operands[2]) == 128
5641 || (INTVAL (operands[2]) < 0
5642 && INTVAL (operands[2]) != -128)))
5644 operands[2] = GEN_INT (-INTVAL (operands[2]));
5645 return "sub{l}\t{%2, %k0|%k0, %2}";
5647 return "add{l}\t{%2, %k0|%k0, %2}";
5651 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5652 (const_string "incdec")
5653 (const_string "alu")))
5654 (set_attr "mode" "SI")])
5656 (define_insn "*addsi_3"
5657 [(set (reg FLAGS_REG)
5658 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5659 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5660 (clobber (match_scratch:SI 0 "=r"))]
5661 "ix86_match_ccmode (insn, CCZmode)
5662 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5663 /* Current assemblers are broken and do not allow @GOTOFF in
5664 ought but a memory context. */
5665 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5667 switch (get_attr_type (insn))
5670 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5671 if (operands[2] == const1_rtx)
5672 return "inc{l}\t%0";
5675 gcc_assert (operands[2] == constm1_rtx);
5676 return "dec{l}\t%0";
5680 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5681 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5682 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5683 if (GET_CODE (operands[2]) == CONST_INT
5684 && (INTVAL (operands[2]) == 128
5685 || (INTVAL (operands[2]) < 0
5686 && INTVAL (operands[2]) != -128)))
5688 operands[2] = GEN_INT (-INTVAL (operands[2]));
5689 return "sub{l}\t{%2, %0|%0, %2}";
5691 return "add{l}\t{%2, %0|%0, %2}";
5695 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5696 (const_string "incdec")
5697 (const_string "alu")))
5698 (set_attr "mode" "SI")])
5700 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5701 (define_insn "*addsi_3_zext"
5702 [(set (reg FLAGS_REG)
5703 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5704 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5705 (set (match_operand:DI 0 "register_operand" "=r")
5706 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5707 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5708 && ix86_binary_operator_ok (PLUS, SImode, operands)
5709 /* Current assemblers are broken and do not allow @GOTOFF in
5710 ought but a memory context. */
5711 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5713 switch (get_attr_type (insn))
5716 if (operands[2] == const1_rtx)
5717 return "inc{l}\t%k0";
5720 gcc_assert (operands[2] == constm1_rtx);
5721 return "dec{l}\t%k0";
5725 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5726 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5727 if (GET_CODE (operands[2]) == CONST_INT
5728 && (INTVAL (operands[2]) == 128
5729 || (INTVAL (operands[2]) < 0
5730 && INTVAL (operands[2]) != -128)))
5732 operands[2] = GEN_INT (-INTVAL (operands[2]));
5733 return "sub{l}\t{%2, %k0|%k0, %2}";
5735 return "add{l}\t{%2, %k0|%k0, %2}";
5739 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5740 (const_string "incdec")
5741 (const_string "alu")))
5742 (set_attr "mode" "SI")])
5744 ; For comparisons against 1, -1 and 128, we may generate better code
5745 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5746 ; is matched then. We can't accept general immediate, because for
5747 ; case of overflows, the result is messed up.
5748 ; This pattern also don't hold of 0x80000000, since the value overflows
5750 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5751 ; only for comparisons not depending on it.
5752 (define_insn "*addsi_4"
5753 [(set (reg FLAGS_REG)
5754 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5755 (match_operand:SI 2 "const_int_operand" "n")))
5756 (clobber (match_scratch:SI 0 "=rm"))]
5757 "ix86_match_ccmode (insn, CCGCmode)
5758 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5760 switch (get_attr_type (insn))
5763 if (operands[2] == constm1_rtx)
5764 return "inc{l}\t%0";
5767 gcc_assert (operands[2] == const1_rtx);
5768 return "dec{l}\t%0";
5772 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5773 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5774 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5775 if ((INTVAL (operands[2]) == -128
5776 || (INTVAL (operands[2]) > 0
5777 && INTVAL (operands[2]) != 128)))
5778 return "sub{l}\t{%2, %0|%0, %2}";
5779 operands[2] = GEN_INT (-INTVAL (operands[2]));
5780 return "add{l}\t{%2, %0|%0, %2}";
5784 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5785 (const_string "incdec")
5786 (const_string "alu")))
5787 (set_attr "mode" "SI")])
5789 (define_insn "*addsi_5"
5790 [(set (reg FLAGS_REG)
5792 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5793 (match_operand:SI 2 "general_operand" "rmni"))
5795 (clobber (match_scratch:SI 0 "=r"))]
5796 "ix86_match_ccmode (insn, CCGOCmode)
5797 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5798 /* Current assemblers are broken and do not allow @GOTOFF in
5799 ought but a memory context. */
5800 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5802 switch (get_attr_type (insn))
5805 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5806 if (operands[2] == const1_rtx)
5807 return "inc{l}\t%0";
5810 gcc_assert (operands[2] == constm1_rtx);
5811 return "dec{l}\t%0";
5815 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5816 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5817 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5818 if (GET_CODE (operands[2]) == CONST_INT
5819 && (INTVAL (operands[2]) == 128
5820 || (INTVAL (operands[2]) < 0
5821 && INTVAL (operands[2]) != -128)))
5823 operands[2] = GEN_INT (-INTVAL (operands[2]));
5824 return "sub{l}\t{%2, %0|%0, %2}";
5826 return "add{l}\t{%2, %0|%0, %2}";
5830 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5831 (const_string "incdec")
5832 (const_string "alu")))
5833 (set_attr "mode" "SI")])
5835 (define_expand "addhi3"
5836 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5837 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5838 (match_operand:HI 2 "general_operand" "")))
5839 (clobber (reg:CC FLAGS_REG))])]
5840 "TARGET_HIMODE_MATH"
5841 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5843 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5844 ;; type optimizations enabled by define-splits. This is not important
5845 ;; for PII, and in fact harmful because of partial register stalls.
5847 (define_insn "*addhi_1_lea"
5848 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5849 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5850 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5851 (clobber (reg:CC FLAGS_REG))]
5852 "!TARGET_PARTIAL_REG_STALL
5853 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5855 switch (get_attr_type (insn))
5860 if (operands[2] == const1_rtx)
5861 return "inc{w}\t%0";
5864 gcc_assert (operands[2] == constm1_rtx);
5865 return "dec{w}\t%0";
5869 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5870 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5871 if (GET_CODE (operands[2]) == CONST_INT
5872 && (INTVAL (operands[2]) == 128
5873 || (INTVAL (operands[2]) < 0
5874 && INTVAL (operands[2]) != -128)))
5876 operands[2] = GEN_INT (-INTVAL (operands[2]));
5877 return "sub{w}\t{%2, %0|%0, %2}";
5879 return "add{w}\t{%2, %0|%0, %2}";
5883 (if_then_else (eq_attr "alternative" "2")
5884 (const_string "lea")
5885 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5886 (const_string "incdec")
5887 (const_string "alu"))))
5888 (set_attr "mode" "HI,HI,SI")])
5890 (define_insn "*addhi_1"
5891 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5892 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5893 (match_operand:HI 2 "general_operand" "ri,rm")))
5894 (clobber (reg:CC FLAGS_REG))]
5895 "TARGET_PARTIAL_REG_STALL
5896 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5898 switch (get_attr_type (insn))
5901 if (operands[2] == const1_rtx)
5902 return "inc{w}\t%0";
5905 gcc_assert (operands[2] == constm1_rtx);
5906 return "dec{w}\t%0";
5910 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5911 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5912 if (GET_CODE (operands[2]) == CONST_INT
5913 && (INTVAL (operands[2]) == 128
5914 || (INTVAL (operands[2]) < 0
5915 && INTVAL (operands[2]) != -128)))
5917 operands[2] = GEN_INT (-INTVAL (operands[2]));
5918 return "sub{w}\t{%2, %0|%0, %2}";
5920 return "add{w}\t{%2, %0|%0, %2}";
5924 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5925 (const_string "incdec")
5926 (const_string "alu")))
5927 (set_attr "mode" "HI")])
5929 (define_insn "*addhi_2"
5930 [(set (reg FLAGS_REG)
5932 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5933 (match_operand:HI 2 "general_operand" "rmni,rni"))
5935 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5936 (plus:HI (match_dup 1) (match_dup 2)))]
5937 "ix86_match_ccmode (insn, CCGOCmode)
5938 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5940 switch (get_attr_type (insn))
5943 if (operands[2] == const1_rtx)
5944 return "inc{w}\t%0";
5947 gcc_assert (operands[2] == constm1_rtx);
5948 return "dec{w}\t%0";
5952 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5953 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5954 if (GET_CODE (operands[2]) == CONST_INT
5955 && (INTVAL (operands[2]) == 128
5956 || (INTVAL (operands[2]) < 0
5957 && INTVAL (operands[2]) != -128)))
5959 operands[2] = GEN_INT (-INTVAL (operands[2]));
5960 return "sub{w}\t{%2, %0|%0, %2}";
5962 return "add{w}\t{%2, %0|%0, %2}";
5966 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5967 (const_string "incdec")
5968 (const_string "alu")))
5969 (set_attr "mode" "HI")])
5971 (define_insn "*addhi_3"
5972 [(set (reg FLAGS_REG)
5973 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5974 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5975 (clobber (match_scratch:HI 0 "=r"))]
5976 "ix86_match_ccmode (insn, CCZmode)
5977 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5979 switch (get_attr_type (insn))
5982 if (operands[2] == const1_rtx)
5983 return "inc{w}\t%0";
5986 gcc_assert (operands[2] == constm1_rtx);
5987 return "dec{w}\t%0";
5991 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5992 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5993 if (GET_CODE (operands[2]) == CONST_INT
5994 && (INTVAL (operands[2]) == 128
5995 || (INTVAL (operands[2]) < 0
5996 && INTVAL (operands[2]) != -128)))
5998 operands[2] = GEN_INT (-INTVAL (operands[2]));
5999 return "sub{w}\t{%2, %0|%0, %2}";
6001 return "add{w}\t{%2, %0|%0, %2}";
6005 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6006 (const_string "incdec")
6007 (const_string "alu")))
6008 (set_attr "mode" "HI")])
6010 ; See comments above addsi_4 for details.
6011 (define_insn "*addhi_4"
6012 [(set (reg FLAGS_REG)
6013 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6014 (match_operand:HI 2 "const_int_operand" "n")))
6015 (clobber (match_scratch:HI 0 "=rm"))]
6016 "ix86_match_ccmode (insn, CCGCmode)
6017 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6019 switch (get_attr_type (insn))
6022 if (operands[2] == constm1_rtx)
6023 return "inc{w}\t%0";
6026 gcc_assert (operands[2] == const1_rtx);
6027 return "dec{w}\t%0";
6031 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6032 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6033 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6034 if ((INTVAL (operands[2]) == -128
6035 || (INTVAL (operands[2]) > 0
6036 && INTVAL (operands[2]) != 128)))
6037 return "sub{w}\t{%2, %0|%0, %2}";
6038 operands[2] = GEN_INT (-INTVAL (operands[2]));
6039 return "add{w}\t{%2, %0|%0, %2}";
6043 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6044 (const_string "incdec")
6045 (const_string "alu")))
6046 (set_attr "mode" "SI")])
6049 (define_insn "*addhi_5"
6050 [(set (reg FLAGS_REG)
6052 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6053 (match_operand:HI 2 "general_operand" "rmni"))
6055 (clobber (match_scratch:HI 0 "=r"))]
6056 "ix86_match_ccmode (insn, CCGOCmode)
6057 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6059 switch (get_attr_type (insn))
6062 if (operands[2] == const1_rtx)
6063 return "inc{w}\t%0";
6066 gcc_assert (operands[2] == constm1_rtx);
6067 return "dec{w}\t%0";
6071 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6072 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6073 if (GET_CODE (operands[2]) == CONST_INT
6074 && (INTVAL (operands[2]) == 128
6075 || (INTVAL (operands[2]) < 0
6076 && INTVAL (operands[2]) != -128)))
6078 operands[2] = GEN_INT (-INTVAL (operands[2]));
6079 return "sub{w}\t{%2, %0|%0, %2}";
6081 return "add{w}\t{%2, %0|%0, %2}";
6085 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6086 (const_string "incdec")
6087 (const_string "alu")))
6088 (set_attr "mode" "HI")])
6090 (define_expand "addqi3"
6091 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6092 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6093 (match_operand:QI 2 "general_operand" "")))
6094 (clobber (reg:CC FLAGS_REG))])]
6095 "TARGET_QIMODE_MATH"
6096 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6098 ;; %%% Potential partial reg stall on alternative 2. What to do?
6099 (define_insn "*addqi_1_lea"
6100 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6101 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6102 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6103 (clobber (reg:CC FLAGS_REG))]
6104 "!TARGET_PARTIAL_REG_STALL
6105 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6107 int widen = (which_alternative == 2);
6108 switch (get_attr_type (insn))
6113 if (operands[2] == const1_rtx)
6114 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6117 gcc_assert (operands[2] == constm1_rtx);
6118 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6122 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6123 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6124 if (GET_CODE (operands[2]) == CONST_INT
6125 && (INTVAL (operands[2]) == 128
6126 || (INTVAL (operands[2]) < 0
6127 && INTVAL (operands[2]) != -128)))
6129 operands[2] = GEN_INT (-INTVAL (operands[2]));
6131 return "sub{l}\t{%2, %k0|%k0, %2}";
6133 return "sub{b}\t{%2, %0|%0, %2}";
6136 return "add{l}\t{%k2, %k0|%k0, %k2}";
6138 return "add{b}\t{%2, %0|%0, %2}";
6142 (if_then_else (eq_attr "alternative" "3")
6143 (const_string "lea")
6144 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6145 (const_string "incdec")
6146 (const_string "alu"))))
6147 (set_attr "mode" "QI,QI,SI,SI")])
6149 (define_insn "*addqi_1"
6150 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6151 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6152 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6153 (clobber (reg:CC FLAGS_REG))]
6154 "TARGET_PARTIAL_REG_STALL
6155 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6157 int widen = (which_alternative == 2);
6158 switch (get_attr_type (insn))
6161 if (operands[2] == const1_rtx)
6162 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6165 gcc_assert (operands[2] == constm1_rtx);
6166 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6170 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6171 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6172 if (GET_CODE (operands[2]) == CONST_INT
6173 && (INTVAL (operands[2]) == 128
6174 || (INTVAL (operands[2]) < 0
6175 && INTVAL (operands[2]) != -128)))
6177 operands[2] = GEN_INT (-INTVAL (operands[2]));
6179 return "sub{l}\t{%2, %k0|%k0, %2}";
6181 return "sub{b}\t{%2, %0|%0, %2}";
6184 return "add{l}\t{%k2, %k0|%k0, %k2}";
6186 return "add{b}\t{%2, %0|%0, %2}";
6190 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6191 (const_string "incdec")
6192 (const_string "alu")))
6193 (set_attr "mode" "QI,QI,SI")])
6195 (define_insn "*addqi_1_slp"
6196 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6197 (plus:QI (match_dup 0)
6198 (match_operand:QI 1 "general_operand" "qn,qnm")))
6199 (clobber (reg:CC FLAGS_REG))]
6200 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6201 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6203 switch (get_attr_type (insn))
6206 if (operands[1] == const1_rtx)
6207 return "inc{b}\t%0";
6210 gcc_assert (operands[1] == constm1_rtx);
6211 return "dec{b}\t%0";
6215 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6216 if (GET_CODE (operands[1]) == CONST_INT
6217 && INTVAL (operands[1]) < 0)
6219 operands[1] = GEN_INT (-INTVAL (operands[1]));
6220 return "sub{b}\t{%1, %0|%0, %1}";
6222 return "add{b}\t{%1, %0|%0, %1}";
6226 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6227 (const_string "incdec")
6228 (const_string "alu1")))
6229 (set (attr "memory")
6230 (if_then_else (match_operand 1 "memory_operand" "")
6231 (const_string "load")
6232 (const_string "none")))
6233 (set_attr "mode" "QI")])
6235 (define_insn "*addqi_2"
6236 [(set (reg FLAGS_REG)
6238 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6239 (match_operand:QI 2 "general_operand" "qmni,qni"))
6241 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6242 (plus:QI (match_dup 1) (match_dup 2)))]
6243 "ix86_match_ccmode (insn, CCGOCmode)
6244 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6246 switch (get_attr_type (insn))
6249 if (operands[2] == const1_rtx)
6250 return "inc{b}\t%0";
6253 gcc_assert (operands[2] == constm1_rtx
6254 || (GET_CODE (operands[2]) == CONST_INT
6255 && INTVAL (operands[2]) == 255));
6256 return "dec{b}\t%0";
6260 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6261 if (GET_CODE (operands[2]) == CONST_INT
6262 && INTVAL (operands[2]) < 0)
6264 operands[2] = GEN_INT (-INTVAL (operands[2]));
6265 return "sub{b}\t{%2, %0|%0, %2}";
6267 return "add{b}\t{%2, %0|%0, %2}";
6271 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6272 (const_string "incdec")
6273 (const_string "alu")))
6274 (set_attr "mode" "QI")])
6276 (define_insn "*addqi_3"
6277 [(set (reg FLAGS_REG)
6278 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6279 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6280 (clobber (match_scratch:QI 0 "=q"))]
6281 "ix86_match_ccmode (insn, CCZmode)
6282 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6284 switch (get_attr_type (insn))
6287 if (operands[2] == const1_rtx)
6288 return "inc{b}\t%0";
6291 gcc_assert (operands[2] == constm1_rtx
6292 || (GET_CODE (operands[2]) == CONST_INT
6293 && INTVAL (operands[2]) == 255));
6294 return "dec{b}\t%0";
6298 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6299 if (GET_CODE (operands[2]) == CONST_INT
6300 && INTVAL (operands[2]) < 0)
6302 operands[2] = GEN_INT (-INTVAL (operands[2]));
6303 return "sub{b}\t{%2, %0|%0, %2}";
6305 return "add{b}\t{%2, %0|%0, %2}";
6309 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6310 (const_string "incdec")
6311 (const_string "alu")))
6312 (set_attr "mode" "QI")])
6314 ; See comments above addsi_4 for details.
6315 (define_insn "*addqi_4"
6316 [(set (reg FLAGS_REG)
6317 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6318 (match_operand:QI 2 "const_int_operand" "n")))
6319 (clobber (match_scratch:QI 0 "=qm"))]
6320 "ix86_match_ccmode (insn, CCGCmode)
6321 && (INTVAL (operands[2]) & 0xff) != 0x80"
6323 switch (get_attr_type (insn))
6326 if (operands[2] == constm1_rtx
6327 || (GET_CODE (operands[2]) == CONST_INT
6328 && INTVAL (operands[2]) == 255))
6329 return "inc{b}\t%0";
6332 gcc_assert (operands[2] == const1_rtx);
6333 return "dec{b}\t%0";
6337 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6338 if (INTVAL (operands[2]) < 0)
6340 operands[2] = GEN_INT (-INTVAL (operands[2]));
6341 return "add{b}\t{%2, %0|%0, %2}";
6343 return "sub{b}\t{%2, %0|%0, %2}";
6347 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6348 (const_string "incdec")
6349 (const_string "alu")))
6350 (set_attr "mode" "QI")])
6353 (define_insn "*addqi_5"
6354 [(set (reg FLAGS_REG)
6356 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6357 (match_operand:QI 2 "general_operand" "qmni"))
6359 (clobber (match_scratch:QI 0 "=q"))]
6360 "ix86_match_ccmode (insn, CCGOCmode)
6361 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6363 switch (get_attr_type (insn))
6366 if (operands[2] == const1_rtx)
6367 return "inc{b}\t%0";
6370 gcc_assert (operands[2] == constm1_rtx
6371 || (GET_CODE (operands[2]) == CONST_INT
6372 && INTVAL (operands[2]) == 255));
6373 return "dec{b}\t%0";
6377 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6378 if (GET_CODE (operands[2]) == CONST_INT
6379 && INTVAL (operands[2]) < 0)
6381 operands[2] = GEN_INT (-INTVAL (operands[2]));
6382 return "sub{b}\t{%2, %0|%0, %2}";
6384 return "add{b}\t{%2, %0|%0, %2}";
6388 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6389 (const_string "incdec")
6390 (const_string "alu")))
6391 (set_attr "mode" "QI")])
6394 (define_insn "addqi_ext_1"
6395 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6400 (match_operand 1 "ext_register_operand" "0")
6403 (match_operand:QI 2 "general_operand" "Qmn")))
6404 (clobber (reg:CC FLAGS_REG))]
6407 switch (get_attr_type (insn))
6410 if (operands[2] == const1_rtx)
6411 return "inc{b}\t%h0";
6414 gcc_assert (operands[2] == constm1_rtx
6415 || (GET_CODE (operands[2]) == CONST_INT
6416 && INTVAL (operands[2]) == 255));
6417 return "dec{b}\t%h0";
6421 return "add{b}\t{%2, %h0|%h0, %2}";
6425 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6426 (const_string "incdec")
6427 (const_string "alu")))
6428 (set_attr "mode" "QI")])
6430 (define_insn "*addqi_ext_1_rex64"
6431 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6436 (match_operand 1 "ext_register_operand" "0")
6439 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6440 (clobber (reg:CC FLAGS_REG))]
6443 switch (get_attr_type (insn))
6446 if (operands[2] == const1_rtx)
6447 return "inc{b}\t%h0";
6450 gcc_assert (operands[2] == constm1_rtx
6451 || (GET_CODE (operands[2]) == CONST_INT
6452 && INTVAL (operands[2]) == 255));
6453 return "dec{b}\t%h0";
6457 return "add{b}\t{%2, %h0|%h0, %2}";
6461 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6462 (const_string "incdec")
6463 (const_string "alu")))
6464 (set_attr "mode" "QI")])
6466 (define_insn "*addqi_ext_2"
6467 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6472 (match_operand 1 "ext_register_operand" "%0")
6476 (match_operand 2 "ext_register_operand" "Q")
6479 (clobber (reg:CC FLAGS_REG))]
6481 "add{b}\t{%h2, %h0|%h0, %h2}"
6482 [(set_attr "type" "alu")
6483 (set_attr "mode" "QI")])
6485 ;; The patterns that match these are at the end of this file.
6487 (define_expand "addxf3"
6488 [(set (match_operand:XF 0 "register_operand" "")
6489 (plus:XF (match_operand:XF 1 "register_operand" "")
6490 (match_operand:XF 2 "register_operand" "")))]
6494 (define_expand "adddf3"
6495 [(set (match_operand:DF 0 "register_operand" "")
6496 (plus:DF (match_operand:DF 1 "register_operand" "")
6497 (match_operand:DF 2 "nonimmediate_operand" "")))]
6498 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6501 (define_expand "addsf3"
6502 [(set (match_operand:SF 0 "register_operand" "")
6503 (plus:SF (match_operand:SF 1 "register_operand" "")
6504 (match_operand:SF 2 "nonimmediate_operand" "")))]
6505 "TARGET_80387 || TARGET_SSE_MATH"
6508 ;; Subtract instructions
6510 ;; %%% splits for subditi3
6512 (define_expand "subti3"
6513 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6514 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6515 (match_operand:TI 2 "x86_64_general_operand" "")))
6516 (clobber (reg:CC FLAGS_REG))])]
6518 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6520 (define_insn "*subti3_1"
6521 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6522 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6523 (match_operand:TI 2 "general_operand" "roiF,riF")))
6524 (clobber (reg:CC FLAGS_REG))]
6525 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6529 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6530 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6531 (match_operand:TI 2 "general_operand" "")))
6532 (clobber (reg:CC FLAGS_REG))]
6533 "TARGET_64BIT && reload_completed"
6534 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6535 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6536 (parallel [(set (match_dup 3)
6537 (minus:DI (match_dup 4)
6538 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6540 (clobber (reg:CC FLAGS_REG))])]
6541 "split_ti (operands+0, 1, operands+0, operands+3);
6542 split_ti (operands+1, 1, operands+1, operands+4);
6543 split_ti (operands+2, 1, operands+2, operands+5);")
6545 ;; %%% splits for subsidi3
6547 (define_expand "subdi3"
6548 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6549 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6550 (match_operand:DI 2 "x86_64_general_operand" "")))
6551 (clobber (reg:CC FLAGS_REG))])]
6553 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6555 (define_insn "*subdi3_1"
6556 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6557 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6558 (match_operand:DI 2 "general_operand" "roiF,riF")))
6559 (clobber (reg:CC FLAGS_REG))]
6560 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6564 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6565 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6566 (match_operand:DI 2 "general_operand" "")))
6567 (clobber (reg:CC FLAGS_REG))]
6568 "!TARGET_64BIT && reload_completed"
6569 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6570 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6571 (parallel [(set (match_dup 3)
6572 (minus:SI (match_dup 4)
6573 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6575 (clobber (reg:CC FLAGS_REG))])]
6576 "split_di (operands+0, 1, operands+0, operands+3);
6577 split_di (operands+1, 1, operands+1, operands+4);
6578 split_di (operands+2, 1, operands+2, operands+5);")
6580 (define_insn "subdi3_carry_rex64"
6581 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6582 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6583 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6584 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6585 (clobber (reg:CC FLAGS_REG))]
6586 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6587 "sbb{q}\t{%2, %0|%0, %2}"
6588 [(set_attr "type" "alu")
6589 (set_attr "pent_pair" "pu")
6590 (set_attr "mode" "DI")])
6592 (define_insn "*subdi_1_rex64"
6593 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6594 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6595 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6596 (clobber (reg:CC FLAGS_REG))]
6597 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6598 "sub{q}\t{%2, %0|%0, %2}"
6599 [(set_attr "type" "alu")
6600 (set_attr "mode" "DI")])
6602 (define_insn "*subdi_2_rex64"
6603 [(set (reg FLAGS_REG)
6605 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6606 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6608 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6609 (minus:DI (match_dup 1) (match_dup 2)))]
6610 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6611 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6612 "sub{q}\t{%2, %0|%0, %2}"
6613 [(set_attr "type" "alu")
6614 (set_attr "mode" "DI")])
6616 (define_insn "*subdi_3_rex63"
6617 [(set (reg FLAGS_REG)
6618 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6619 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6620 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6621 (minus:DI (match_dup 1) (match_dup 2)))]
6622 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6623 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6624 "sub{q}\t{%2, %0|%0, %2}"
6625 [(set_attr "type" "alu")
6626 (set_attr "mode" "DI")])
6628 (define_insn "subqi3_carry"
6629 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6630 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6631 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6632 (match_operand:QI 2 "general_operand" "qi,qm"))))
6633 (clobber (reg:CC FLAGS_REG))]
6634 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6635 "sbb{b}\t{%2, %0|%0, %2}"
6636 [(set_attr "type" "alu")
6637 (set_attr "pent_pair" "pu")
6638 (set_attr "mode" "QI")])
6640 (define_insn "subhi3_carry"
6641 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6642 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6643 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6644 (match_operand:HI 2 "general_operand" "ri,rm"))))
6645 (clobber (reg:CC FLAGS_REG))]
6646 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6647 "sbb{w}\t{%2, %0|%0, %2}"
6648 [(set_attr "type" "alu")
6649 (set_attr "pent_pair" "pu")
6650 (set_attr "mode" "HI")])
6652 (define_insn "subsi3_carry"
6653 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6654 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6655 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6656 (match_operand:SI 2 "general_operand" "ri,rm"))))
6657 (clobber (reg:CC FLAGS_REG))]
6658 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6659 "sbb{l}\t{%2, %0|%0, %2}"
6660 [(set_attr "type" "alu")
6661 (set_attr "pent_pair" "pu")
6662 (set_attr "mode" "SI")])
6664 (define_insn "subsi3_carry_zext"
6665 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6667 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6668 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6669 (match_operand:SI 2 "general_operand" "ri,rm")))))
6670 (clobber (reg:CC FLAGS_REG))]
6671 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6672 "sbb{l}\t{%2, %k0|%k0, %2}"
6673 [(set_attr "type" "alu")
6674 (set_attr "pent_pair" "pu")
6675 (set_attr "mode" "SI")])
6677 (define_expand "subsi3"
6678 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6679 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6680 (match_operand:SI 2 "general_operand" "")))
6681 (clobber (reg:CC FLAGS_REG))])]
6683 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6685 (define_insn "*subsi_1"
6686 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6687 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6688 (match_operand:SI 2 "general_operand" "ri,rm")))
6689 (clobber (reg:CC FLAGS_REG))]
6690 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6691 "sub{l}\t{%2, %0|%0, %2}"
6692 [(set_attr "type" "alu")
6693 (set_attr "mode" "SI")])
6695 (define_insn "*subsi_1_zext"
6696 [(set (match_operand:DI 0 "register_operand" "=r")
6698 (minus:SI (match_operand:SI 1 "register_operand" "0")
6699 (match_operand:SI 2 "general_operand" "rim"))))
6700 (clobber (reg:CC FLAGS_REG))]
6701 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6702 "sub{l}\t{%2, %k0|%k0, %2}"
6703 [(set_attr "type" "alu")
6704 (set_attr "mode" "SI")])
6706 (define_insn "*subsi_2"
6707 [(set (reg FLAGS_REG)
6709 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6710 (match_operand:SI 2 "general_operand" "ri,rm"))
6712 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6713 (minus:SI (match_dup 1) (match_dup 2)))]
6714 "ix86_match_ccmode (insn, CCGOCmode)
6715 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6716 "sub{l}\t{%2, %0|%0, %2}"
6717 [(set_attr "type" "alu")
6718 (set_attr "mode" "SI")])
6720 (define_insn "*subsi_2_zext"
6721 [(set (reg FLAGS_REG)
6723 (minus:SI (match_operand:SI 1 "register_operand" "0")
6724 (match_operand:SI 2 "general_operand" "rim"))
6726 (set (match_operand:DI 0 "register_operand" "=r")
6728 (minus:SI (match_dup 1)
6730 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6731 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6732 "sub{l}\t{%2, %k0|%k0, %2}"
6733 [(set_attr "type" "alu")
6734 (set_attr "mode" "SI")])
6736 (define_insn "*subsi_3"
6737 [(set (reg FLAGS_REG)
6738 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6739 (match_operand:SI 2 "general_operand" "ri,rm")))
6740 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6741 (minus:SI (match_dup 1) (match_dup 2)))]
6742 "ix86_match_ccmode (insn, CCmode)
6743 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6744 "sub{l}\t{%2, %0|%0, %2}"
6745 [(set_attr "type" "alu")
6746 (set_attr "mode" "SI")])
6748 (define_insn "*subsi_3_zext"
6749 [(set (reg FLAGS_REG)
6750 (compare (match_operand:SI 1 "register_operand" "0")
6751 (match_operand:SI 2 "general_operand" "rim")))
6752 (set (match_operand:DI 0 "register_operand" "=r")
6754 (minus:SI (match_dup 1)
6756 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6757 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6758 "sub{l}\t{%2, %1|%1, %2}"
6759 [(set_attr "type" "alu")
6760 (set_attr "mode" "DI")])
6762 (define_expand "subhi3"
6763 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6764 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6765 (match_operand:HI 2 "general_operand" "")))
6766 (clobber (reg:CC FLAGS_REG))])]
6767 "TARGET_HIMODE_MATH"
6768 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6770 (define_insn "*subhi_1"
6771 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6772 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6773 (match_operand:HI 2 "general_operand" "ri,rm")))
6774 (clobber (reg:CC FLAGS_REG))]
6775 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6776 "sub{w}\t{%2, %0|%0, %2}"
6777 [(set_attr "type" "alu")
6778 (set_attr "mode" "HI")])
6780 (define_insn "*subhi_2"
6781 [(set (reg FLAGS_REG)
6783 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6784 (match_operand:HI 2 "general_operand" "ri,rm"))
6786 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6787 (minus:HI (match_dup 1) (match_dup 2)))]
6788 "ix86_match_ccmode (insn, CCGOCmode)
6789 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6790 "sub{w}\t{%2, %0|%0, %2}"
6791 [(set_attr "type" "alu")
6792 (set_attr "mode" "HI")])
6794 (define_insn "*subhi_3"
6795 [(set (reg FLAGS_REG)
6796 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6797 (match_operand:HI 2 "general_operand" "ri,rm")))
6798 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6799 (minus:HI (match_dup 1) (match_dup 2)))]
6800 "ix86_match_ccmode (insn, CCmode)
6801 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6802 "sub{w}\t{%2, %0|%0, %2}"
6803 [(set_attr "type" "alu")
6804 (set_attr "mode" "HI")])
6806 (define_expand "subqi3"
6807 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6808 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6809 (match_operand:QI 2 "general_operand" "")))
6810 (clobber (reg:CC FLAGS_REG))])]
6811 "TARGET_QIMODE_MATH"
6812 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6814 (define_insn "*subqi_1"
6815 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6816 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6817 (match_operand:QI 2 "general_operand" "qn,qmn")))
6818 (clobber (reg:CC FLAGS_REG))]
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 (define_insn "*subqi_1_slp"
6825 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6826 (minus:QI (match_dup 0)
6827 (match_operand:QI 1 "general_operand" "qn,qmn")))
6828 (clobber (reg:CC FLAGS_REG))]
6829 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6830 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6831 "sub{b}\t{%1, %0|%0, %1}"
6832 [(set_attr "type" "alu1")
6833 (set_attr "mode" "QI")])
6835 (define_insn "*subqi_2"
6836 [(set (reg FLAGS_REG)
6838 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6839 (match_operand:QI 2 "general_operand" "qi,qm"))
6841 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6842 (minus:HI (match_dup 1) (match_dup 2)))]
6843 "ix86_match_ccmode (insn, CCGOCmode)
6844 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6845 "sub{b}\t{%2, %0|%0, %2}"
6846 [(set_attr "type" "alu")
6847 (set_attr "mode" "QI")])
6849 (define_insn "*subqi_3"
6850 [(set (reg FLAGS_REG)
6851 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6852 (match_operand:QI 2 "general_operand" "qi,qm")))
6853 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6854 (minus:HI (match_dup 1) (match_dup 2)))]
6855 "ix86_match_ccmode (insn, CCmode)
6856 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6857 "sub{b}\t{%2, %0|%0, %2}"
6858 [(set_attr "type" "alu")
6859 (set_attr "mode" "QI")])
6861 ;; The patterns that match these are at the end of this file.
6863 (define_expand "subxf3"
6864 [(set (match_operand:XF 0 "register_operand" "")
6865 (minus:XF (match_operand:XF 1 "register_operand" "")
6866 (match_operand:XF 2 "register_operand" "")))]
6870 (define_expand "subdf3"
6871 [(set (match_operand:DF 0 "register_operand" "")
6872 (minus:DF (match_operand:DF 1 "register_operand" "")
6873 (match_operand:DF 2 "nonimmediate_operand" "")))]
6874 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6877 (define_expand "subsf3"
6878 [(set (match_operand:SF 0 "register_operand" "")
6879 (minus:SF (match_operand:SF 1 "register_operand" "")
6880 (match_operand:SF 2 "nonimmediate_operand" "")))]
6881 "TARGET_80387 || TARGET_SSE_MATH"
6884 ;; Multiply instructions
6886 (define_expand "muldi3"
6887 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6888 (mult:DI (match_operand:DI 1 "register_operand" "")
6889 (match_operand:DI 2 "x86_64_general_operand" "")))
6890 (clobber (reg:CC FLAGS_REG))])]
6894 (define_insn "*muldi3_1_rex64"
6895 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6896 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6897 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6898 (clobber (reg:CC FLAGS_REG))]
6900 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6902 imul{q}\t{%2, %1, %0|%0, %1, %2}
6903 imul{q}\t{%2, %1, %0|%0, %1, %2}
6904 imul{q}\t{%2, %0|%0, %2}"
6905 [(set_attr "type" "imul")
6906 (set_attr "prefix_0f" "0,0,1")
6907 (set (attr "athlon_decode")
6908 (cond [(eq_attr "cpu" "athlon")
6909 (const_string "vector")
6910 (eq_attr "alternative" "1")
6911 (const_string "vector")
6912 (and (eq_attr "alternative" "2")
6913 (match_operand 1 "memory_operand" ""))
6914 (const_string "vector")]
6915 (const_string "direct")))
6916 (set_attr "mode" "DI")])
6918 (define_expand "mulsi3"
6919 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6920 (mult:SI (match_operand:SI 1 "register_operand" "")
6921 (match_operand:SI 2 "general_operand" "")))
6922 (clobber (reg:CC FLAGS_REG))])]
6926 (define_insn "*mulsi3_1"
6927 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6928 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6929 (match_operand:SI 2 "general_operand" "K,i,mr")))
6930 (clobber (reg:CC FLAGS_REG))]
6931 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6933 imul{l}\t{%2, %1, %0|%0, %1, %2}
6934 imul{l}\t{%2, %1, %0|%0, %1, %2}
6935 imul{l}\t{%2, %0|%0, %2}"
6936 [(set_attr "type" "imul")
6937 (set_attr "prefix_0f" "0,0,1")
6938 (set (attr "athlon_decode")
6939 (cond [(eq_attr "cpu" "athlon")
6940 (const_string "vector")
6941 (eq_attr "alternative" "1")
6942 (const_string "vector")
6943 (and (eq_attr "alternative" "2")
6944 (match_operand 1 "memory_operand" ""))
6945 (const_string "vector")]
6946 (const_string "direct")))
6947 (set_attr "mode" "SI")])
6949 (define_insn "*mulsi3_1_zext"
6950 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6952 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6953 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6954 (clobber (reg:CC FLAGS_REG))]
6956 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6958 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6959 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6960 imul{l}\t{%2, %k0|%k0, %2}"
6961 [(set_attr "type" "imul")
6962 (set_attr "prefix_0f" "0,0,1")
6963 (set (attr "athlon_decode")
6964 (cond [(eq_attr "cpu" "athlon")
6965 (const_string "vector")
6966 (eq_attr "alternative" "1")
6967 (const_string "vector")
6968 (and (eq_attr "alternative" "2")
6969 (match_operand 1 "memory_operand" ""))
6970 (const_string "vector")]
6971 (const_string "direct")))
6972 (set_attr "mode" "SI")])
6974 (define_expand "mulhi3"
6975 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6976 (mult:HI (match_operand:HI 1 "register_operand" "")
6977 (match_operand:HI 2 "general_operand" "")))
6978 (clobber (reg:CC FLAGS_REG))])]
6979 "TARGET_HIMODE_MATH"
6982 (define_insn "*mulhi3_1"
6983 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6984 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6985 (match_operand:HI 2 "general_operand" "K,i,mr")))
6986 (clobber (reg:CC FLAGS_REG))]
6987 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6989 imul{w}\t{%2, %1, %0|%0, %1, %2}
6990 imul{w}\t{%2, %1, %0|%0, %1, %2}
6991 imul{w}\t{%2, %0|%0, %2}"
6992 [(set_attr "type" "imul")
6993 (set_attr "prefix_0f" "0,0,1")
6994 (set (attr "athlon_decode")
6995 (cond [(eq_attr "cpu" "athlon")
6996 (const_string "vector")
6997 (eq_attr "alternative" "1,2")
6998 (const_string "vector")]
6999 (const_string "direct")))
7000 (set_attr "mode" "HI")])
7002 (define_expand "mulqi3"
7003 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7004 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7005 (match_operand:QI 2 "register_operand" "")))
7006 (clobber (reg:CC FLAGS_REG))])]
7007 "TARGET_QIMODE_MATH"
7010 (define_insn "*mulqi3_1"
7011 [(set (match_operand:QI 0 "register_operand" "=a")
7012 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7013 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7014 (clobber (reg:CC FLAGS_REG))]
7016 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7018 [(set_attr "type" "imul")
7019 (set_attr "length_immediate" "0")
7020 (set (attr "athlon_decode")
7021 (if_then_else (eq_attr "cpu" "athlon")
7022 (const_string "vector")
7023 (const_string "direct")))
7024 (set_attr "mode" "QI")])
7026 (define_expand "umulqihi3"
7027 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7028 (mult:HI (zero_extend:HI
7029 (match_operand:QI 1 "nonimmediate_operand" ""))
7031 (match_operand:QI 2 "register_operand" ""))))
7032 (clobber (reg:CC FLAGS_REG))])]
7033 "TARGET_QIMODE_MATH"
7036 (define_insn "*umulqihi3_1"
7037 [(set (match_operand:HI 0 "register_operand" "=a")
7038 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7039 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7040 (clobber (reg:CC FLAGS_REG))]
7042 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7044 [(set_attr "type" "imul")
7045 (set_attr "length_immediate" "0")
7046 (set (attr "athlon_decode")
7047 (if_then_else (eq_attr "cpu" "athlon")
7048 (const_string "vector")
7049 (const_string "direct")))
7050 (set_attr "mode" "QI")])
7052 (define_expand "mulqihi3"
7053 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7054 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7055 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7056 (clobber (reg:CC FLAGS_REG))])]
7057 "TARGET_QIMODE_MATH"
7060 (define_insn "*mulqihi3_insn"
7061 [(set (match_operand:HI 0 "register_operand" "=a")
7062 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7063 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7064 (clobber (reg:CC FLAGS_REG))]
7066 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7068 [(set_attr "type" "imul")
7069 (set_attr "length_immediate" "0")
7070 (set (attr "athlon_decode")
7071 (if_then_else (eq_attr "cpu" "athlon")
7072 (const_string "vector")
7073 (const_string "direct")))
7074 (set_attr "mode" "QI")])
7076 (define_expand "umulditi3"
7077 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7078 (mult:TI (zero_extend:TI
7079 (match_operand:DI 1 "nonimmediate_operand" ""))
7081 (match_operand:DI 2 "register_operand" ""))))
7082 (clobber (reg:CC FLAGS_REG))])]
7086 (define_insn "*umulditi3_insn"
7087 [(set (match_operand:TI 0 "register_operand" "=A")
7088 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7089 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7090 (clobber (reg:CC FLAGS_REG))]
7092 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7094 [(set_attr "type" "imul")
7095 (set_attr "length_immediate" "0")
7096 (set (attr "athlon_decode")
7097 (if_then_else (eq_attr "cpu" "athlon")
7098 (const_string "vector")
7099 (const_string "double")))
7100 (set_attr "mode" "DI")])
7102 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7103 (define_expand "umulsidi3"
7104 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7105 (mult:DI (zero_extend:DI
7106 (match_operand:SI 1 "nonimmediate_operand" ""))
7108 (match_operand:SI 2 "register_operand" ""))))
7109 (clobber (reg:CC FLAGS_REG))])]
7113 (define_insn "*umulsidi3_insn"
7114 [(set (match_operand:DI 0 "register_operand" "=A")
7115 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7116 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7117 (clobber (reg:CC FLAGS_REG))]
7119 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7121 [(set_attr "type" "imul")
7122 (set_attr "length_immediate" "0")
7123 (set (attr "athlon_decode")
7124 (if_then_else (eq_attr "cpu" "athlon")
7125 (const_string "vector")
7126 (const_string "double")))
7127 (set_attr "mode" "SI")])
7129 (define_expand "mulditi3"
7130 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7131 (mult:TI (sign_extend:TI
7132 (match_operand:DI 1 "nonimmediate_operand" ""))
7134 (match_operand:DI 2 "register_operand" ""))))
7135 (clobber (reg:CC FLAGS_REG))])]
7139 (define_insn "*mulditi3_insn"
7140 [(set (match_operand:TI 0 "register_operand" "=A")
7141 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7142 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7143 (clobber (reg:CC FLAGS_REG))]
7145 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7147 [(set_attr "type" "imul")
7148 (set_attr "length_immediate" "0")
7149 (set (attr "athlon_decode")
7150 (if_then_else (eq_attr "cpu" "athlon")
7151 (const_string "vector")
7152 (const_string "double")))
7153 (set_attr "mode" "DI")])
7155 (define_expand "mulsidi3"
7156 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7157 (mult:DI (sign_extend:DI
7158 (match_operand:SI 1 "nonimmediate_operand" ""))
7160 (match_operand:SI 2 "register_operand" ""))))
7161 (clobber (reg:CC FLAGS_REG))])]
7165 (define_insn "*mulsidi3_insn"
7166 [(set (match_operand:DI 0 "register_operand" "=A")
7167 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7168 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7169 (clobber (reg:CC FLAGS_REG))]
7171 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7173 [(set_attr "type" "imul")
7174 (set_attr "length_immediate" "0")
7175 (set (attr "athlon_decode")
7176 (if_then_else (eq_attr "cpu" "athlon")
7177 (const_string "vector")
7178 (const_string "double")))
7179 (set_attr "mode" "SI")])
7181 (define_expand "umuldi3_highpart"
7182 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7185 (mult:TI (zero_extend:TI
7186 (match_operand:DI 1 "nonimmediate_operand" ""))
7188 (match_operand:DI 2 "register_operand" "")))
7190 (clobber (match_scratch:DI 3 ""))
7191 (clobber (reg:CC FLAGS_REG))])]
7195 (define_insn "*umuldi3_highpart_rex64"
7196 [(set (match_operand:DI 0 "register_operand" "=d")
7199 (mult:TI (zero_extend:TI
7200 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7202 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7204 (clobber (match_scratch:DI 3 "=1"))
7205 (clobber (reg:CC FLAGS_REG))]
7207 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7209 [(set_attr "type" "imul")
7210 (set_attr "length_immediate" "0")
7211 (set (attr "athlon_decode")
7212 (if_then_else (eq_attr "cpu" "athlon")
7213 (const_string "vector")
7214 (const_string "double")))
7215 (set_attr "mode" "DI")])
7217 (define_expand "umulsi3_highpart"
7218 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7221 (mult:DI (zero_extend:DI
7222 (match_operand:SI 1 "nonimmediate_operand" ""))
7224 (match_operand:SI 2 "register_operand" "")))
7226 (clobber (match_scratch:SI 3 ""))
7227 (clobber (reg:CC FLAGS_REG))])]
7231 (define_insn "*umulsi3_highpart_insn"
7232 [(set (match_operand:SI 0 "register_operand" "=d")
7235 (mult:DI (zero_extend:DI
7236 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7238 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7240 (clobber (match_scratch:SI 3 "=1"))
7241 (clobber (reg:CC FLAGS_REG))]
7242 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7244 [(set_attr "type" "imul")
7245 (set_attr "length_immediate" "0")
7246 (set (attr "athlon_decode")
7247 (if_then_else (eq_attr "cpu" "athlon")
7248 (const_string "vector")
7249 (const_string "double")))
7250 (set_attr "mode" "SI")])
7252 (define_insn "*umulsi3_highpart_zext"
7253 [(set (match_operand:DI 0 "register_operand" "=d")
7254 (zero_extend:DI (truncate:SI
7256 (mult:DI (zero_extend:DI
7257 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7259 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7261 (clobber (match_scratch:SI 3 "=1"))
7262 (clobber (reg:CC FLAGS_REG))]
7264 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7266 [(set_attr "type" "imul")
7267 (set_attr "length_immediate" "0")
7268 (set (attr "athlon_decode")
7269 (if_then_else (eq_attr "cpu" "athlon")
7270 (const_string "vector")
7271 (const_string "double")))
7272 (set_attr "mode" "SI")])
7274 (define_expand "smuldi3_highpart"
7275 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7278 (mult:TI (sign_extend:TI
7279 (match_operand:DI 1 "nonimmediate_operand" ""))
7281 (match_operand:DI 2 "register_operand" "")))
7283 (clobber (match_scratch:DI 3 ""))
7284 (clobber (reg:CC FLAGS_REG))])]
7288 (define_insn "*smuldi3_highpart_rex64"
7289 [(set (match_operand:DI 0 "register_operand" "=d")
7292 (mult:TI (sign_extend:TI
7293 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7295 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7297 (clobber (match_scratch:DI 3 "=1"))
7298 (clobber (reg:CC FLAGS_REG))]
7300 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7302 [(set_attr "type" "imul")
7303 (set (attr "athlon_decode")
7304 (if_then_else (eq_attr "cpu" "athlon")
7305 (const_string "vector")
7306 (const_string "double")))
7307 (set_attr "mode" "DI")])
7309 (define_expand "smulsi3_highpart"
7310 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7313 (mult:DI (sign_extend:DI
7314 (match_operand:SI 1 "nonimmediate_operand" ""))
7316 (match_operand:SI 2 "register_operand" "")))
7318 (clobber (match_scratch:SI 3 ""))
7319 (clobber (reg:CC FLAGS_REG))])]
7323 (define_insn "*smulsi3_highpart_insn"
7324 [(set (match_operand:SI 0 "register_operand" "=d")
7327 (mult:DI (sign_extend:DI
7328 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7330 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7332 (clobber (match_scratch:SI 3 "=1"))
7333 (clobber (reg:CC FLAGS_REG))]
7334 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7336 [(set_attr "type" "imul")
7337 (set (attr "athlon_decode")
7338 (if_then_else (eq_attr "cpu" "athlon")
7339 (const_string "vector")
7340 (const_string "double")))
7341 (set_attr "mode" "SI")])
7343 (define_insn "*smulsi3_highpart_zext"
7344 [(set (match_operand:DI 0 "register_operand" "=d")
7345 (zero_extend:DI (truncate:SI
7347 (mult:DI (sign_extend:DI
7348 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7350 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7352 (clobber (match_scratch:SI 3 "=1"))
7353 (clobber (reg:CC FLAGS_REG))]
7355 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7357 [(set_attr "type" "imul")
7358 (set (attr "athlon_decode")
7359 (if_then_else (eq_attr "cpu" "athlon")
7360 (const_string "vector")
7361 (const_string "double")))
7362 (set_attr "mode" "SI")])
7364 ;; The patterns that match these are at the end of this file.
7366 (define_expand "mulxf3"
7367 [(set (match_operand:XF 0 "register_operand" "")
7368 (mult:XF (match_operand:XF 1 "register_operand" "")
7369 (match_operand:XF 2 "register_operand" "")))]
7373 (define_expand "muldf3"
7374 [(set (match_operand:DF 0 "register_operand" "")
7375 (mult:DF (match_operand:DF 1 "register_operand" "")
7376 (match_operand:DF 2 "nonimmediate_operand" "")))]
7377 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7380 (define_expand "mulsf3"
7381 [(set (match_operand:SF 0 "register_operand" "")
7382 (mult:SF (match_operand:SF 1 "register_operand" "")
7383 (match_operand:SF 2 "nonimmediate_operand" "")))]
7384 "TARGET_80387 || TARGET_SSE_MATH"
7387 ;; Divide instructions
7389 (define_insn "divqi3"
7390 [(set (match_operand:QI 0 "register_operand" "=a")
7391 (div:QI (match_operand:HI 1 "register_operand" "0")
7392 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7393 (clobber (reg:CC FLAGS_REG))]
7394 "TARGET_QIMODE_MATH"
7396 [(set_attr "type" "idiv")
7397 (set_attr "mode" "QI")])
7399 (define_insn "udivqi3"
7400 [(set (match_operand:QI 0 "register_operand" "=a")
7401 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7402 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7403 (clobber (reg:CC FLAGS_REG))]
7404 "TARGET_QIMODE_MATH"
7406 [(set_attr "type" "idiv")
7407 (set_attr "mode" "QI")])
7409 ;; The patterns that match these are at the end of this file.
7411 (define_expand "divxf3"
7412 [(set (match_operand:XF 0 "register_operand" "")
7413 (div:XF (match_operand:XF 1 "register_operand" "")
7414 (match_operand:XF 2 "register_operand" "")))]
7418 (define_expand "divdf3"
7419 [(set (match_operand:DF 0 "register_operand" "")
7420 (div:DF (match_operand:DF 1 "register_operand" "")
7421 (match_operand:DF 2 "nonimmediate_operand" "")))]
7422 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7425 (define_expand "divsf3"
7426 [(set (match_operand:SF 0 "register_operand" "")
7427 (div:SF (match_operand:SF 1 "register_operand" "")
7428 (match_operand:SF 2 "nonimmediate_operand" "")))]
7429 "TARGET_80387 || TARGET_SSE_MATH"
7432 ;; Remainder instructions.
7434 (define_expand "divmoddi4"
7435 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7436 (div:DI (match_operand:DI 1 "register_operand" "")
7437 (match_operand:DI 2 "nonimmediate_operand" "")))
7438 (set (match_operand:DI 3 "register_operand" "")
7439 (mod:DI (match_dup 1) (match_dup 2)))
7440 (clobber (reg:CC FLAGS_REG))])]
7444 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7445 ;; Penalize eax case slightly because it results in worse scheduling
7447 (define_insn "*divmoddi4_nocltd_rex64"
7448 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7449 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7450 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7451 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7452 (mod:DI (match_dup 2) (match_dup 3)))
7453 (clobber (reg:CC FLAGS_REG))]
7454 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7456 [(set_attr "type" "multi")])
7458 (define_insn "*divmoddi4_cltd_rex64"
7459 [(set (match_operand:DI 0 "register_operand" "=a")
7460 (div:DI (match_operand:DI 2 "register_operand" "a")
7461 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7462 (set (match_operand:DI 1 "register_operand" "=&d")
7463 (mod:DI (match_dup 2) (match_dup 3)))
7464 (clobber (reg:CC FLAGS_REG))]
7465 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7467 [(set_attr "type" "multi")])
7469 (define_insn "*divmoddi_noext_rex64"
7470 [(set (match_operand:DI 0 "register_operand" "=a")
7471 (div:DI (match_operand:DI 1 "register_operand" "0")
7472 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7473 (set (match_operand:DI 3 "register_operand" "=d")
7474 (mod:DI (match_dup 1) (match_dup 2)))
7475 (use (match_operand:DI 4 "register_operand" "3"))
7476 (clobber (reg:CC FLAGS_REG))]
7479 [(set_attr "type" "idiv")
7480 (set_attr "mode" "DI")])
7483 [(set (match_operand:DI 0 "register_operand" "")
7484 (div:DI (match_operand:DI 1 "register_operand" "")
7485 (match_operand:DI 2 "nonimmediate_operand" "")))
7486 (set (match_operand:DI 3 "register_operand" "")
7487 (mod:DI (match_dup 1) (match_dup 2)))
7488 (clobber (reg:CC FLAGS_REG))]
7489 "TARGET_64BIT && reload_completed"
7490 [(parallel [(set (match_dup 3)
7491 (ashiftrt:DI (match_dup 4) (const_int 63)))
7492 (clobber (reg:CC FLAGS_REG))])
7493 (parallel [(set (match_dup 0)
7494 (div:DI (reg:DI 0) (match_dup 2)))
7496 (mod:DI (reg:DI 0) (match_dup 2)))
7498 (clobber (reg:CC FLAGS_REG))])]
7500 /* Avoid use of cltd in favor of a mov+shift. */
7501 if (!TARGET_USE_CLTD && !optimize_size)
7503 if (true_regnum (operands[1]))
7504 emit_move_insn (operands[0], operands[1]);
7506 emit_move_insn (operands[3], operands[1]);
7507 operands[4] = operands[3];
7511 gcc_assert (!true_regnum (operands[1]));
7512 operands[4] = operands[1];
7517 (define_expand "divmodsi4"
7518 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7519 (div:SI (match_operand:SI 1 "register_operand" "")
7520 (match_operand:SI 2 "nonimmediate_operand" "")))
7521 (set (match_operand:SI 3 "register_operand" "")
7522 (mod:SI (match_dup 1) (match_dup 2)))
7523 (clobber (reg:CC FLAGS_REG))])]
7527 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7528 ;; Penalize eax case slightly because it results in worse scheduling
7530 (define_insn "*divmodsi4_nocltd"
7531 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7532 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7533 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7534 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7535 (mod:SI (match_dup 2) (match_dup 3)))
7536 (clobber (reg:CC FLAGS_REG))]
7537 "!optimize_size && !TARGET_USE_CLTD"
7539 [(set_attr "type" "multi")])
7541 (define_insn "*divmodsi4_cltd"
7542 [(set (match_operand:SI 0 "register_operand" "=a")
7543 (div:SI (match_operand:SI 2 "register_operand" "a")
7544 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7545 (set (match_operand:SI 1 "register_operand" "=&d")
7546 (mod:SI (match_dup 2) (match_dup 3)))
7547 (clobber (reg:CC FLAGS_REG))]
7548 "optimize_size || TARGET_USE_CLTD"
7550 [(set_attr "type" "multi")])
7552 (define_insn "*divmodsi_noext"
7553 [(set (match_operand:SI 0 "register_operand" "=a")
7554 (div:SI (match_operand:SI 1 "register_operand" "0")
7555 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7556 (set (match_operand:SI 3 "register_operand" "=d")
7557 (mod:SI (match_dup 1) (match_dup 2)))
7558 (use (match_operand:SI 4 "register_operand" "3"))
7559 (clobber (reg:CC FLAGS_REG))]
7562 [(set_attr "type" "idiv")
7563 (set_attr "mode" "SI")])
7566 [(set (match_operand:SI 0 "register_operand" "")
7567 (div:SI (match_operand:SI 1 "register_operand" "")
7568 (match_operand:SI 2 "nonimmediate_operand" "")))
7569 (set (match_operand:SI 3 "register_operand" "")
7570 (mod:SI (match_dup 1) (match_dup 2)))
7571 (clobber (reg:CC FLAGS_REG))]
7573 [(parallel [(set (match_dup 3)
7574 (ashiftrt:SI (match_dup 4) (const_int 31)))
7575 (clobber (reg:CC FLAGS_REG))])
7576 (parallel [(set (match_dup 0)
7577 (div:SI (reg:SI 0) (match_dup 2)))
7579 (mod:SI (reg:SI 0) (match_dup 2)))
7581 (clobber (reg:CC FLAGS_REG))])]
7583 /* Avoid use of cltd in favor of a mov+shift. */
7584 if (!TARGET_USE_CLTD && !optimize_size)
7586 if (true_regnum (operands[1]))
7587 emit_move_insn (operands[0], operands[1]);
7589 emit_move_insn (operands[3], operands[1]);
7590 operands[4] = operands[3];
7594 gcc_assert (!true_regnum (operands[1]));
7595 operands[4] = operands[1];
7599 (define_insn "divmodhi4"
7600 [(set (match_operand:HI 0 "register_operand" "=a")
7601 (div:HI (match_operand:HI 1 "register_operand" "0")
7602 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7603 (set (match_operand:HI 3 "register_operand" "=&d")
7604 (mod:HI (match_dup 1) (match_dup 2)))
7605 (clobber (reg:CC FLAGS_REG))]
7606 "TARGET_HIMODE_MATH"
7608 [(set_attr "type" "multi")
7609 (set_attr "length_immediate" "0")
7610 (set_attr "mode" "SI")])
7612 (define_insn "udivmoddi4"
7613 [(set (match_operand:DI 0 "register_operand" "=a")
7614 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7615 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7616 (set (match_operand:DI 3 "register_operand" "=&d")
7617 (umod:DI (match_dup 1) (match_dup 2)))
7618 (clobber (reg:CC FLAGS_REG))]
7620 "xor{q}\t%3, %3\;div{q}\t%2"
7621 [(set_attr "type" "multi")
7622 (set_attr "length_immediate" "0")
7623 (set_attr "mode" "DI")])
7625 (define_insn "*udivmoddi4_noext"
7626 [(set (match_operand:DI 0 "register_operand" "=a")
7627 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7628 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7629 (set (match_operand:DI 3 "register_operand" "=d")
7630 (umod:DI (match_dup 1) (match_dup 2)))
7632 (clobber (reg:CC FLAGS_REG))]
7635 [(set_attr "type" "idiv")
7636 (set_attr "mode" "DI")])
7639 [(set (match_operand:DI 0 "register_operand" "")
7640 (udiv:DI (match_operand:DI 1 "register_operand" "")
7641 (match_operand:DI 2 "nonimmediate_operand" "")))
7642 (set (match_operand:DI 3 "register_operand" "")
7643 (umod:DI (match_dup 1) (match_dup 2)))
7644 (clobber (reg:CC FLAGS_REG))]
7645 "TARGET_64BIT && reload_completed"
7646 [(set (match_dup 3) (const_int 0))
7647 (parallel [(set (match_dup 0)
7648 (udiv:DI (match_dup 1) (match_dup 2)))
7650 (umod:DI (match_dup 1) (match_dup 2)))
7652 (clobber (reg:CC FLAGS_REG))])]
7655 (define_insn "udivmodsi4"
7656 [(set (match_operand:SI 0 "register_operand" "=a")
7657 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7658 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7659 (set (match_operand:SI 3 "register_operand" "=&d")
7660 (umod:SI (match_dup 1) (match_dup 2)))
7661 (clobber (reg:CC FLAGS_REG))]
7663 "xor{l}\t%3, %3\;div{l}\t%2"
7664 [(set_attr "type" "multi")
7665 (set_attr "length_immediate" "0")
7666 (set_attr "mode" "SI")])
7668 (define_insn "*udivmodsi4_noext"
7669 [(set (match_operand:SI 0 "register_operand" "=a")
7670 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7671 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7672 (set (match_operand:SI 3 "register_operand" "=d")
7673 (umod:SI (match_dup 1) (match_dup 2)))
7675 (clobber (reg:CC FLAGS_REG))]
7678 [(set_attr "type" "idiv")
7679 (set_attr "mode" "SI")])
7682 [(set (match_operand:SI 0 "register_operand" "")
7683 (udiv:SI (match_operand:SI 1 "register_operand" "")
7684 (match_operand:SI 2 "nonimmediate_operand" "")))
7685 (set (match_operand:SI 3 "register_operand" "")
7686 (umod:SI (match_dup 1) (match_dup 2)))
7687 (clobber (reg:CC FLAGS_REG))]
7689 [(set (match_dup 3) (const_int 0))
7690 (parallel [(set (match_dup 0)
7691 (udiv:SI (match_dup 1) (match_dup 2)))
7693 (umod:SI (match_dup 1) (match_dup 2)))
7695 (clobber (reg:CC FLAGS_REG))])]
7698 (define_expand "udivmodhi4"
7699 [(set (match_dup 4) (const_int 0))
7700 (parallel [(set (match_operand:HI 0 "register_operand" "")
7701 (udiv:HI (match_operand:HI 1 "register_operand" "")
7702 (match_operand:HI 2 "nonimmediate_operand" "")))
7703 (set (match_operand:HI 3 "register_operand" "")
7704 (umod:HI (match_dup 1) (match_dup 2)))
7706 (clobber (reg:CC FLAGS_REG))])]
7707 "TARGET_HIMODE_MATH"
7708 "operands[4] = gen_reg_rtx (HImode);")
7710 (define_insn "*udivmodhi_noext"
7711 [(set (match_operand:HI 0 "register_operand" "=a")
7712 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7713 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7714 (set (match_operand:HI 3 "register_operand" "=d")
7715 (umod:HI (match_dup 1) (match_dup 2)))
7716 (use (match_operand:HI 4 "register_operand" "3"))
7717 (clobber (reg:CC FLAGS_REG))]
7720 [(set_attr "type" "idiv")
7721 (set_attr "mode" "HI")])
7723 ;; We cannot use div/idiv for double division, because it causes
7724 ;; "division by zero" on the overflow and that's not what we expect
7725 ;; from truncate. Because true (non truncating) double division is
7726 ;; never generated, we can't create this insn anyway.
7729 ; [(set (match_operand:SI 0 "register_operand" "=a")
7731 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7733 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7734 ; (set (match_operand:SI 3 "register_operand" "=d")
7736 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7737 ; (clobber (reg:CC FLAGS_REG))]
7739 ; "div{l}\t{%2, %0|%0, %2}"
7740 ; [(set_attr "type" "idiv")])
7742 ;;- Logical AND instructions
7744 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7745 ;; Note that this excludes ah.
7747 (define_insn "*testdi_1_rex64"
7748 [(set (reg FLAGS_REG)
7750 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7751 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7753 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7754 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7756 test{l}\t{%k1, %k0|%k0, %k1}
7757 test{l}\t{%k1, %k0|%k0, %k1}
7758 test{q}\t{%1, %0|%0, %1}
7759 test{q}\t{%1, %0|%0, %1}
7760 test{q}\t{%1, %0|%0, %1}"
7761 [(set_attr "type" "test")
7762 (set_attr "modrm" "0,1,0,1,1")
7763 (set_attr "mode" "SI,SI,DI,DI,DI")
7764 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7766 (define_insn "testsi_1"
7767 [(set (reg FLAGS_REG)
7769 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7770 (match_operand:SI 1 "general_operand" "in,in,rin"))
7772 "ix86_match_ccmode (insn, CCNOmode)
7773 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7774 "test{l}\t{%1, %0|%0, %1}"
7775 [(set_attr "type" "test")
7776 (set_attr "modrm" "0,1,1")
7777 (set_attr "mode" "SI")
7778 (set_attr "pent_pair" "uv,np,uv")])
7780 (define_expand "testsi_ccno_1"
7781 [(set (reg:CCNO FLAGS_REG)
7783 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7784 (match_operand:SI 1 "nonmemory_operand" ""))
7789 (define_insn "*testhi_1"
7790 [(set (reg FLAGS_REG)
7791 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7792 (match_operand:HI 1 "general_operand" "n,n,rn"))
7794 "ix86_match_ccmode (insn, CCNOmode)
7795 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7796 "test{w}\t{%1, %0|%0, %1}"
7797 [(set_attr "type" "test")
7798 (set_attr "modrm" "0,1,1")
7799 (set_attr "mode" "HI")
7800 (set_attr "pent_pair" "uv,np,uv")])
7802 (define_expand "testqi_ccz_1"
7803 [(set (reg:CCZ FLAGS_REG)
7804 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7805 (match_operand:QI 1 "nonmemory_operand" ""))
7810 (define_insn "*testqi_1_maybe_si"
7811 [(set (reg FLAGS_REG)
7814 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7815 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7817 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7818 && ix86_match_ccmode (insn,
7819 GET_CODE (operands[1]) == CONST_INT
7820 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7822 if (which_alternative == 3)
7824 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7825 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7826 return "test{l}\t{%1, %k0|%k0, %1}";
7828 return "test{b}\t{%1, %0|%0, %1}";
7830 [(set_attr "type" "test")
7831 (set_attr "modrm" "0,1,1,1")
7832 (set_attr "mode" "QI,QI,QI,SI")
7833 (set_attr "pent_pair" "uv,np,uv,np")])
7835 (define_insn "*testqi_1"
7836 [(set (reg FLAGS_REG)
7839 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7840 (match_operand:QI 1 "general_operand" "n,n,qn"))
7842 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7843 && ix86_match_ccmode (insn, CCNOmode)"
7844 "test{b}\t{%1, %0|%0, %1}"
7845 [(set_attr "type" "test")
7846 (set_attr "modrm" "0,1,1")
7847 (set_attr "mode" "QI")
7848 (set_attr "pent_pair" "uv,np,uv")])
7850 (define_expand "testqi_ext_ccno_0"
7851 [(set (reg:CCNO FLAGS_REG)
7855 (match_operand 0 "ext_register_operand" "")
7858 (match_operand 1 "const_int_operand" ""))
7863 (define_insn "*testqi_ext_0"
7864 [(set (reg FLAGS_REG)
7868 (match_operand 0 "ext_register_operand" "Q")
7871 (match_operand 1 "const_int_operand" "n"))
7873 "ix86_match_ccmode (insn, CCNOmode)"
7874 "test{b}\t{%1, %h0|%h0, %1}"
7875 [(set_attr "type" "test")
7876 (set_attr "mode" "QI")
7877 (set_attr "length_immediate" "1")
7878 (set_attr "pent_pair" "np")])
7880 (define_insn "*testqi_ext_1"
7881 [(set (reg FLAGS_REG)
7885 (match_operand 0 "ext_register_operand" "Q")
7889 (match_operand:QI 1 "general_operand" "Qm")))
7891 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7892 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7893 "test{b}\t{%1, %h0|%h0, %1}"
7894 [(set_attr "type" "test")
7895 (set_attr "mode" "QI")])
7897 (define_insn "*testqi_ext_1_rex64"
7898 [(set (reg FLAGS_REG)
7902 (match_operand 0 "ext_register_operand" "Q")
7906 (match_operand:QI 1 "register_operand" "Q")))
7908 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7909 "test{b}\t{%1, %h0|%h0, %1}"
7910 [(set_attr "type" "test")
7911 (set_attr "mode" "QI")])
7913 (define_insn "*testqi_ext_2"
7914 [(set (reg FLAGS_REG)
7918 (match_operand 0 "ext_register_operand" "Q")
7922 (match_operand 1 "ext_register_operand" "Q")
7926 "ix86_match_ccmode (insn, CCNOmode)"
7927 "test{b}\t{%h1, %h0|%h0, %h1}"
7928 [(set_attr "type" "test")
7929 (set_attr "mode" "QI")])
7931 ;; Combine likes to form bit extractions for some tests. Humor it.
7932 (define_insn "*testqi_ext_3"
7933 [(set (reg FLAGS_REG)
7934 (compare (zero_extract:SI
7935 (match_operand 0 "nonimmediate_operand" "rm")
7936 (match_operand:SI 1 "const_int_operand" "")
7937 (match_operand:SI 2 "const_int_operand" ""))
7939 "ix86_match_ccmode (insn, CCNOmode)
7940 && INTVAL (operands[1]) > 0
7941 && INTVAL (operands[2]) >= 0
7942 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7943 && (GET_MODE (operands[0]) == SImode
7944 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7945 || GET_MODE (operands[0]) == HImode
7946 || GET_MODE (operands[0]) == QImode)"
7949 (define_insn "*testqi_ext_3_rex64"
7950 [(set (reg FLAGS_REG)
7951 (compare (zero_extract:DI
7952 (match_operand 0 "nonimmediate_operand" "rm")
7953 (match_operand:DI 1 "const_int_operand" "")
7954 (match_operand:DI 2 "const_int_operand" ""))
7957 && ix86_match_ccmode (insn, CCNOmode)
7958 && INTVAL (operands[1]) > 0
7959 && INTVAL (operands[2]) >= 0
7960 /* Ensure that resulting mask is zero or sign extended operand. */
7961 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7962 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7963 && INTVAL (operands[1]) > 32))
7964 && (GET_MODE (operands[0]) == SImode
7965 || GET_MODE (operands[0]) == DImode
7966 || GET_MODE (operands[0]) == HImode
7967 || GET_MODE (operands[0]) == QImode)"
7971 [(set (match_operand 0 "flags_reg_operand" "")
7972 (match_operator 1 "compare_operator"
7974 (match_operand 2 "nonimmediate_operand" "")
7975 (match_operand 3 "const_int_operand" "")
7976 (match_operand 4 "const_int_operand" ""))
7978 "ix86_match_ccmode (insn, CCNOmode)"
7979 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7981 rtx val = operands[2];
7982 HOST_WIDE_INT len = INTVAL (operands[3]);
7983 HOST_WIDE_INT pos = INTVAL (operands[4]);
7985 enum machine_mode mode, submode;
7987 mode = GET_MODE (val);
7988 if (GET_CODE (val) == MEM)
7990 /* ??? Combine likes to put non-volatile mem extractions in QImode
7991 no matter the size of the test. So find a mode that works. */
7992 if (! MEM_VOLATILE_P (val))
7994 mode = smallest_mode_for_size (pos + len, MODE_INT);
7995 val = adjust_address (val, mode, 0);
7998 else if (GET_CODE (val) == SUBREG
7999 && (submode = GET_MODE (SUBREG_REG (val)),
8000 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8001 && pos + len <= GET_MODE_BITSIZE (submode))
8003 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8005 val = SUBREG_REG (val);
8007 else if (mode == HImode && pos + len <= 8)
8009 /* Small HImode tests can be converted to QImode. */
8011 val = gen_lowpart (QImode, val);
8014 if (len == HOST_BITS_PER_WIDE_INT)
8017 mask = ((HOST_WIDE_INT)1 << len) - 1;
8020 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8023 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8024 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8025 ;; this is relatively important trick.
8026 ;; Do the conversion only post-reload to avoid limiting of the register class
8029 [(set (match_operand 0 "flags_reg_operand" "")
8030 (match_operator 1 "compare_operator"
8031 [(and (match_operand 2 "register_operand" "")
8032 (match_operand 3 "const_int_operand" ""))
8035 && QI_REG_P (operands[2])
8036 && GET_MODE (operands[2]) != QImode
8037 && ((ix86_match_ccmode (insn, CCZmode)
8038 && !(INTVAL (operands[3]) & ~(255 << 8)))
8039 || (ix86_match_ccmode (insn, CCNOmode)
8040 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8043 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8046 "operands[2] = gen_lowpart (SImode, operands[2]);
8047 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8050 [(set (match_operand 0 "flags_reg_operand" "")
8051 (match_operator 1 "compare_operator"
8052 [(and (match_operand 2 "nonimmediate_operand" "")
8053 (match_operand 3 "const_int_operand" ""))
8056 && GET_MODE (operands[2]) != QImode
8057 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8058 && ((ix86_match_ccmode (insn, CCZmode)
8059 && !(INTVAL (operands[3]) & ~255))
8060 || (ix86_match_ccmode (insn, CCNOmode)
8061 && !(INTVAL (operands[3]) & ~127)))"
8063 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8065 "operands[2] = gen_lowpart (QImode, operands[2]);
8066 operands[3] = gen_lowpart (QImode, operands[3]);")
8069 ;; %%% This used to optimize known byte-wide and operations to memory,
8070 ;; and sometimes to QImode registers. If this is considered useful,
8071 ;; it should be done with splitters.
8073 (define_expand "anddi3"
8074 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8075 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8076 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8077 (clobber (reg:CC FLAGS_REG))]
8079 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8081 (define_insn "*anddi_1_rex64"
8082 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8083 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8084 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8085 (clobber (reg:CC FLAGS_REG))]
8086 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8088 switch (get_attr_type (insn))
8092 enum machine_mode mode;
8094 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8095 if (INTVAL (operands[2]) == 0xff)
8099 gcc_assert (INTVAL (operands[2]) == 0xffff);
8103 operands[1] = gen_lowpart (mode, operands[1]);
8105 return "movz{bq|x}\t{%1,%0|%0, %1}";
8107 return "movz{wq|x}\t{%1,%0|%0, %1}";
8111 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8112 if (get_attr_mode (insn) == MODE_SI)
8113 return "and{l}\t{%k2, %k0|%k0, %k2}";
8115 return "and{q}\t{%2, %0|%0, %2}";
8118 [(set_attr "type" "alu,alu,alu,imovx")
8119 (set_attr "length_immediate" "*,*,*,0")
8120 (set_attr "mode" "SI,DI,DI,DI")])
8122 (define_insn "*anddi_2"
8123 [(set (reg FLAGS_REG)
8124 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8125 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8127 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8128 (and:DI (match_dup 1) (match_dup 2)))]
8129 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8130 && ix86_binary_operator_ok (AND, DImode, operands)"
8132 and{l}\t{%k2, %k0|%k0, %k2}
8133 and{q}\t{%2, %0|%0, %2}
8134 and{q}\t{%2, %0|%0, %2}"
8135 [(set_attr "type" "alu")
8136 (set_attr "mode" "SI,DI,DI")])
8138 (define_expand "andsi3"
8139 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8140 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8141 (match_operand:SI 2 "general_operand" "")))
8142 (clobber (reg:CC FLAGS_REG))]
8144 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8146 (define_insn "*andsi_1"
8147 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8148 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8149 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8150 (clobber (reg:CC FLAGS_REG))]
8151 "ix86_binary_operator_ok (AND, SImode, operands)"
8153 switch (get_attr_type (insn))
8157 enum machine_mode mode;
8159 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8160 if (INTVAL (operands[2]) == 0xff)
8164 gcc_assert (INTVAL (operands[2]) == 0xffff);
8168 operands[1] = gen_lowpart (mode, operands[1]);
8170 return "movz{bl|x}\t{%1,%0|%0, %1}";
8172 return "movz{wl|x}\t{%1,%0|%0, %1}";
8176 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8177 return "and{l}\t{%2, %0|%0, %2}";
8180 [(set_attr "type" "alu,alu,imovx")
8181 (set_attr "length_immediate" "*,*,0")
8182 (set_attr "mode" "SI")])
8185 [(set (match_operand 0 "register_operand" "")
8187 (const_int -65536)))
8188 (clobber (reg:CC FLAGS_REG))]
8189 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8190 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8191 "operands[1] = gen_lowpart (HImode, operands[0]);")
8194 [(set (match_operand 0 "ext_register_operand" "")
8197 (clobber (reg:CC FLAGS_REG))]
8198 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8199 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8200 "operands[1] = gen_lowpart (QImode, operands[0]);")
8203 [(set (match_operand 0 "ext_register_operand" "")
8205 (const_int -65281)))
8206 (clobber (reg:CC FLAGS_REG))]
8207 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8208 [(parallel [(set (zero_extract:SI (match_dup 0)
8212 (zero_extract:SI (match_dup 0)
8215 (zero_extract:SI (match_dup 0)
8218 (clobber (reg:CC FLAGS_REG))])]
8219 "operands[0] = gen_lowpart (SImode, operands[0]);")
8221 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8222 (define_insn "*andsi_1_zext"
8223 [(set (match_operand:DI 0 "register_operand" "=r")
8225 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8226 (match_operand:SI 2 "general_operand" "rim"))))
8227 (clobber (reg:CC FLAGS_REG))]
8228 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8229 "and{l}\t{%2, %k0|%k0, %2}"
8230 [(set_attr "type" "alu")
8231 (set_attr "mode" "SI")])
8233 (define_insn "*andsi_2"
8234 [(set (reg FLAGS_REG)
8235 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8236 (match_operand:SI 2 "general_operand" "rim,ri"))
8238 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8239 (and:SI (match_dup 1) (match_dup 2)))]
8240 "ix86_match_ccmode (insn, CCNOmode)
8241 && ix86_binary_operator_ok (AND, SImode, operands)"
8242 "and{l}\t{%2, %0|%0, %2}"
8243 [(set_attr "type" "alu")
8244 (set_attr "mode" "SI")])
8246 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8247 (define_insn "*andsi_2_zext"
8248 [(set (reg FLAGS_REG)
8249 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8250 (match_operand:SI 2 "general_operand" "rim"))
8252 (set (match_operand:DI 0 "register_operand" "=r")
8253 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8254 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8255 && ix86_binary_operator_ok (AND, SImode, operands)"
8256 "and{l}\t{%2, %k0|%k0, %2}"
8257 [(set_attr "type" "alu")
8258 (set_attr "mode" "SI")])
8260 (define_expand "andhi3"
8261 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8262 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8263 (match_operand:HI 2 "general_operand" "")))
8264 (clobber (reg:CC FLAGS_REG))]
8265 "TARGET_HIMODE_MATH"
8266 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8268 (define_insn "*andhi_1"
8269 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8270 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8271 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8272 (clobber (reg:CC FLAGS_REG))]
8273 "ix86_binary_operator_ok (AND, HImode, operands)"
8275 switch (get_attr_type (insn))
8278 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8279 gcc_assert (INTVAL (operands[2]) == 0xff);
8280 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8283 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8285 return "and{w}\t{%2, %0|%0, %2}";
8288 [(set_attr "type" "alu,alu,imovx")
8289 (set_attr "length_immediate" "*,*,0")
8290 (set_attr "mode" "HI,HI,SI")])
8292 (define_insn "*andhi_2"
8293 [(set (reg FLAGS_REG)
8294 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8295 (match_operand:HI 2 "general_operand" "rim,ri"))
8297 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8298 (and:HI (match_dup 1) (match_dup 2)))]
8299 "ix86_match_ccmode (insn, CCNOmode)
8300 && ix86_binary_operator_ok (AND, HImode, operands)"
8301 "and{w}\t{%2, %0|%0, %2}"
8302 [(set_attr "type" "alu")
8303 (set_attr "mode" "HI")])
8305 (define_expand "andqi3"
8306 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8307 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8308 (match_operand:QI 2 "general_operand" "")))
8309 (clobber (reg:CC FLAGS_REG))]
8310 "TARGET_QIMODE_MATH"
8311 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8313 ;; %%% Potential partial reg stall on alternative 2. What to do?
8314 (define_insn "*andqi_1"
8315 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8316 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8317 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8318 (clobber (reg:CC FLAGS_REG))]
8319 "ix86_binary_operator_ok (AND, QImode, operands)"
8321 and{b}\t{%2, %0|%0, %2}
8322 and{b}\t{%2, %0|%0, %2}
8323 and{l}\t{%k2, %k0|%k0, %k2}"
8324 [(set_attr "type" "alu")
8325 (set_attr "mode" "QI,QI,SI")])
8327 (define_insn "*andqi_1_slp"
8328 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8329 (and:QI (match_dup 0)
8330 (match_operand:QI 1 "general_operand" "qi,qmi")))
8331 (clobber (reg:CC FLAGS_REG))]
8332 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8333 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8334 "and{b}\t{%1, %0|%0, %1}"
8335 [(set_attr "type" "alu1")
8336 (set_attr "mode" "QI")])
8338 (define_insn "*andqi_2_maybe_si"
8339 [(set (reg FLAGS_REG)
8341 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8342 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8344 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8345 (and:QI (match_dup 1) (match_dup 2)))]
8346 "ix86_binary_operator_ok (AND, QImode, operands)
8347 && ix86_match_ccmode (insn,
8348 GET_CODE (operands[2]) == CONST_INT
8349 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8351 if (which_alternative == 2)
8353 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8354 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8355 return "and{l}\t{%2, %k0|%k0, %2}";
8357 return "and{b}\t{%2, %0|%0, %2}";
8359 [(set_attr "type" "alu")
8360 (set_attr "mode" "QI,QI,SI")])
8362 (define_insn "*andqi_2"
8363 [(set (reg FLAGS_REG)
8365 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8366 (match_operand:QI 2 "general_operand" "qim,qi"))
8368 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8369 (and:QI (match_dup 1) (match_dup 2)))]
8370 "ix86_match_ccmode (insn, CCNOmode)
8371 && ix86_binary_operator_ok (AND, QImode, operands)"
8372 "and{b}\t{%2, %0|%0, %2}"
8373 [(set_attr "type" "alu")
8374 (set_attr "mode" "QI")])
8376 (define_insn "*andqi_2_slp"
8377 [(set (reg FLAGS_REG)
8379 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8380 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8382 (set (strict_low_part (match_dup 0))
8383 (and:QI (match_dup 0) (match_dup 1)))]
8384 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8385 && ix86_match_ccmode (insn, CCNOmode)
8386 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8387 "and{b}\t{%1, %0|%0, %1}"
8388 [(set_attr "type" "alu1")
8389 (set_attr "mode" "QI")])
8391 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8392 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8393 ;; for a QImode operand, which of course failed.
8395 (define_insn "andqi_ext_0"
8396 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8401 (match_operand 1 "ext_register_operand" "0")
8404 (match_operand 2 "const_int_operand" "n")))
8405 (clobber (reg:CC FLAGS_REG))]
8407 "and{b}\t{%2, %h0|%h0, %2}"
8408 [(set_attr "type" "alu")
8409 (set_attr "length_immediate" "1")
8410 (set_attr "mode" "QI")])
8412 ;; Generated by peephole translating test to and. This shows up
8413 ;; often in fp comparisons.
8415 (define_insn "*andqi_ext_0_cc"
8416 [(set (reg FLAGS_REG)
8420 (match_operand 1 "ext_register_operand" "0")
8423 (match_operand 2 "const_int_operand" "n"))
8425 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8434 "ix86_match_ccmode (insn, CCNOmode)"
8435 "and{b}\t{%2, %h0|%h0, %2}"
8436 [(set_attr "type" "alu")
8437 (set_attr "length_immediate" "1")
8438 (set_attr "mode" "QI")])
8440 (define_insn "*andqi_ext_1"
8441 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8446 (match_operand 1 "ext_register_operand" "0")
8450 (match_operand:QI 2 "general_operand" "Qm"))))
8451 (clobber (reg:CC FLAGS_REG))]
8453 "and{b}\t{%2, %h0|%h0, %2}"
8454 [(set_attr "type" "alu")
8455 (set_attr "length_immediate" "0")
8456 (set_attr "mode" "QI")])
8458 (define_insn "*andqi_ext_1_rex64"
8459 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8464 (match_operand 1 "ext_register_operand" "0")
8468 (match_operand 2 "ext_register_operand" "Q"))))
8469 (clobber (reg:CC FLAGS_REG))]
8471 "and{b}\t{%2, %h0|%h0, %2}"
8472 [(set_attr "type" "alu")
8473 (set_attr "length_immediate" "0")
8474 (set_attr "mode" "QI")])
8476 (define_insn "*andqi_ext_2"
8477 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8482 (match_operand 1 "ext_register_operand" "%0")
8486 (match_operand 2 "ext_register_operand" "Q")
8489 (clobber (reg:CC FLAGS_REG))]
8491 "and{b}\t{%h2, %h0|%h0, %h2}"
8492 [(set_attr "type" "alu")
8493 (set_attr "length_immediate" "0")
8494 (set_attr "mode" "QI")])
8496 ;; Convert wide AND instructions with immediate operand to shorter QImode
8497 ;; equivalents when possible.
8498 ;; Don't do the splitting with memory operands, since it introduces risk
8499 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8500 ;; for size, but that can (should?) be handled by generic code instead.
8502 [(set (match_operand 0 "register_operand" "")
8503 (and (match_operand 1 "register_operand" "")
8504 (match_operand 2 "const_int_operand" "")))
8505 (clobber (reg:CC FLAGS_REG))]
8507 && QI_REG_P (operands[0])
8508 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8509 && !(~INTVAL (operands[2]) & ~(255 << 8))
8510 && GET_MODE (operands[0]) != QImode"
8511 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8512 (and:SI (zero_extract:SI (match_dup 1)
8513 (const_int 8) (const_int 8))
8515 (clobber (reg:CC FLAGS_REG))])]
8516 "operands[0] = gen_lowpart (SImode, operands[0]);
8517 operands[1] = gen_lowpart (SImode, operands[1]);
8518 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8520 ;; Since AND can be encoded with sign extended immediate, this is only
8521 ;; profitable when 7th bit is not set.
8523 [(set (match_operand 0 "register_operand" "")
8524 (and (match_operand 1 "general_operand" "")
8525 (match_operand 2 "const_int_operand" "")))
8526 (clobber (reg:CC FLAGS_REG))]
8528 && ANY_QI_REG_P (operands[0])
8529 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8530 && !(~INTVAL (operands[2]) & ~255)
8531 && !(INTVAL (operands[2]) & 128)
8532 && GET_MODE (operands[0]) != QImode"
8533 [(parallel [(set (strict_low_part (match_dup 0))
8534 (and:QI (match_dup 1)
8536 (clobber (reg:CC FLAGS_REG))])]
8537 "operands[0] = gen_lowpart (QImode, operands[0]);
8538 operands[1] = gen_lowpart (QImode, operands[1]);
8539 operands[2] = gen_lowpart (QImode, operands[2]);")
8541 ;; Logical inclusive OR instructions
8543 ;; %%% This used to optimize known byte-wide and operations to memory.
8544 ;; If this is considered useful, it should be done with splitters.
8546 (define_expand "iordi3"
8547 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8548 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8549 (match_operand:DI 2 "x86_64_general_operand" "")))
8550 (clobber (reg:CC FLAGS_REG))]
8552 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8554 (define_insn "*iordi_1_rex64"
8555 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8556 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8557 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8558 (clobber (reg:CC FLAGS_REG))]
8560 && ix86_binary_operator_ok (IOR, DImode, operands)"
8561 "or{q}\t{%2, %0|%0, %2}"
8562 [(set_attr "type" "alu")
8563 (set_attr "mode" "DI")])
8565 (define_insn "*iordi_2_rex64"
8566 [(set (reg FLAGS_REG)
8567 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8568 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8570 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8571 (ior:DI (match_dup 1) (match_dup 2)))]
8573 && ix86_match_ccmode (insn, CCNOmode)
8574 && ix86_binary_operator_ok (IOR, DImode, operands)"
8575 "or{q}\t{%2, %0|%0, %2}"
8576 [(set_attr "type" "alu")
8577 (set_attr "mode" "DI")])
8579 (define_insn "*iordi_3_rex64"
8580 [(set (reg FLAGS_REG)
8581 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8582 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8584 (clobber (match_scratch:DI 0 "=r"))]
8586 && ix86_match_ccmode (insn, CCNOmode)
8587 && ix86_binary_operator_ok (IOR, DImode, operands)"
8588 "or{q}\t{%2, %0|%0, %2}"
8589 [(set_attr "type" "alu")
8590 (set_attr "mode" "DI")])
8593 (define_expand "iorsi3"
8594 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8595 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8596 (match_operand:SI 2 "general_operand" "")))
8597 (clobber (reg:CC FLAGS_REG))]
8599 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8601 (define_insn "*iorsi_1"
8602 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8603 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8604 (match_operand:SI 2 "general_operand" "ri,rmi")))
8605 (clobber (reg:CC FLAGS_REG))]
8606 "ix86_binary_operator_ok (IOR, SImode, operands)"
8607 "or{l}\t{%2, %0|%0, %2}"
8608 [(set_attr "type" "alu")
8609 (set_attr "mode" "SI")])
8611 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8612 (define_insn "*iorsi_1_zext"
8613 [(set (match_operand:DI 0 "register_operand" "=rm")
8615 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8616 (match_operand:SI 2 "general_operand" "rim"))))
8617 (clobber (reg:CC FLAGS_REG))]
8618 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8619 "or{l}\t{%2, %k0|%k0, %2}"
8620 [(set_attr "type" "alu")
8621 (set_attr "mode" "SI")])
8623 (define_insn "*iorsi_1_zext_imm"
8624 [(set (match_operand:DI 0 "register_operand" "=rm")
8625 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8626 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8627 (clobber (reg:CC FLAGS_REG))]
8629 "or{l}\t{%2, %k0|%k0, %2}"
8630 [(set_attr "type" "alu")
8631 (set_attr "mode" "SI")])
8633 (define_insn "*iorsi_2"
8634 [(set (reg FLAGS_REG)
8635 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8636 (match_operand:SI 2 "general_operand" "rim,ri"))
8638 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8639 (ior:SI (match_dup 1) (match_dup 2)))]
8640 "ix86_match_ccmode (insn, CCNOmode)
8641 && ix86_binary_operator_ok (IOR, SImode, operands)"
8642 "or{l}\t{%2, %0|%0, %2}"
8643 [(set_attr "type" "alu")
8644 (set_attr "mode" "SI")])
8646 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8647 ;; ??? Special case for immediate operand is missing - it is tricky.
8648 (define_insn "*iorsi_2_zext"
8649 [(set (reg FLAGS_REG)
8650 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8651 (match_operand:SI 2 "general_operand" "rim"))
8653 (set (match_operand:DI 0 "register_operand" "=r")
8654 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8655 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8656 && ix86_binary_operator_ok (IOR, SImode, operands)"
8657 "or{l}\t{%2, %k0|%k0, %2}"
8658 [(set_attr "type" "alu")
8659 (set_attr "mode" "SI")])
8661 (define_insn "*iorsi_2_zext_imm"
8662 [(set (reg FLAGS_REG)
8663 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8664 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8666 (set (match_operand:DI 0 "register_operand" "=r")
8667 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8668 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8669 && ix86_binary_operator_ok (IOR, SImode, operands)"
8670 "or{l}\t{%2, %k0|%k0, %2}"
8671 [(set_attr "type" "alu")
8672 (set_attr "mode" "SI")])
8674 (define_insn "*iorsi_3"
8675 [(set (reg FLAGS_REG)
8676 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8677 (match_operand:SI 2 "general_operand" "rim"))
8679 (clobber (match_scratch:SI 0 "=r"))]
8680 "ix86_match_ccmode (insn, CCNOmode)
8681 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8682 "or{l}\t{%2, %0|%0, %2}"
8683 [(set_attr "type" "alu")
8684 (set_attr "mode" "SI")])
8686 (define_expand "iorhi3"
8687 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8688 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8689 (match_operand:HI 2 "general_operand" "")))
8690 (clobber (reg:CC FLAGS_REG))]
8691 "TARGET_HIMODE_MATH"
8692 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8694 (define_insn "*iorhi_1"
8695 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8696 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8697 (match_operand:HI 2 "general_operand" "rmi,ri")))
8698 (clobber (reg:CC FLAGS_REG))]
8699 "ix86_binary_operator_ok (IOR, HImode, operands)"
8700 "or{w}\t{%2, %0|%0, %2}"
8701 [(set_attr "type" "alu")
8702 (set_attr "mode" "HI")])
8704 (define_insn "*iorhi_2"
8705 [(set (reg FLAGS_REG)
8706 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8707 (match_operand:HI 2 "general_operand" "rim,ri"))
8709 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8710 (ior:HI (match_dup 1) (match_dup 2)))]
8711 "ix86_match_ccmode (insn, CCNOmode)
8712 && ix86_binary_operator_ok (IOR, HImode, operands)"
8713 "or{w}\t{%2, %0|%0, %2}"
8714 [(set_attr "type" "alu")
8715 (set_attr "mode" "HI")])
8717 (define_insn "*iorhi_3"
8718 [(set (reg FLAGS_REG)
8719 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8720 (match_operand:HI 2 "general_operand" "rim"))
8722 (clobber (match_scratch:HI 0 "=r"))]
8723 "ix86_match_ccmode (insn, CCNOmode)
8724 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8725 "or{w}\t{%2, %0|%0, %2}"
8726 [(set_attr "type" "alu")
8727 (set_attr "mode" "HI")])
8729 (define_expand "iorqi3"
8730 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8731 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8732 (match_operand:QI 2 "general_operand" "")))
8733 (clobber (reg:CC FLAGS_REG))]
8734 "TARGET_QIMODE_MATH"
8735 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8737 ;; %%% Potential partial reg stall on alternative 2. What to do?
8738 (define_insn "*iorqi_1"
8739 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8740 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8741 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8742 (clobber (reg:CC FLAGS_REG))]
8743 "ix86_binary_operator_ok (IOR, QImode, operands)"
8745 or{b}\t{%2, %0|%0, %2}
8746 or{b}\t{%2, %0|%0, %2}
8747 or{l}\t{%k2, %k0|%k0, %k2}"
8748 [(set_attr "type" "alu")
8749 (set_attr "mode" "QI,QI,SI")])
8751 (define_insn "*iorqi_1_slp"
8752 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8753 (ior:QI (match_dup 0)
8754 (match_operand:QI 1 "general_operand" "qmi,qi")))
8755 (clobber (reg:CC FLAGS_REG))]
8756 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8757 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8758 "or{b}\t{%1, %0|%0, %1}"
8759 [(set_attr "type" "alu1")
8760 (set_attr "mode" "QI")])
8762 (define_insn "*iorqi_2"
8763 [(set (reg FLAGS_REG)
8764 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8765 (match_operand:QI 2 "general_operand" "qim,qi"))
8767 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8768 (ior:QI (match_dup 1) (match_dup 2)))]
8769 "ix86_match_ccmode (insn, CCNOmode)
8770 && ix86_binary_operator_ok (IOR, QImode, operands)"
8771 "or{b}\t{%2, %0|%0, %2}"
8772 [(set_attr "type" "alu")
8773 (set_attr "mode" "QI")])
8775 (define_insn "*iorqi_2_slp"
8776 [(set (reg FLAGS_REG)
8777 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8778 (match_operand:QI 1 "general_operand" "qim,qi"))
8780 (set (strict_low_part (match_dup 0))
8781 (ior:QI (match_dup 0) (match_dup 1)))]
8782 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8783 && ix86_match_ccmode (insn, CCNOmode)
8784 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8785 "or{b}\t{%1, %0|%0, %1}"
8786 [(set_attr "type" "alu1")
8787 (set_attr "mode" "QI")])
8789 (define_insn "*iorqi_3"
8790 [(set (reg FLAGS_REG)
8791 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8792 (match_operand:QI 2 "general_operand" "qim"))
8794 (clobber (match_scratch:QI 0 "=q"))]
8795 "ix86_match_ccmode (insn, CCNOmode)
8796 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8797 "or{b}\t{%2, %0|%0, %2}"
8798 [(set_attr "type" "alu")
8799 (set_attr "mode" "QI")])
8801 (define_insn "iorqi_ext_0"
8802 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8807 (match_operand 1 "ext_register_operand" "0")
8810 (match_operand 2 "const_int_operand" "n")))
8811 (clobber (reg:CC FLAGS_REG))]
8812 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8813 "or{b}\t{%2, %h0|%h0, %2}"
8814 [(set_attr "type" "alu")
8815 (set_attr "length_immediate" "1")
8816 (set_attr "mode" "QI")])
8818 (define_insn "*iorqi_ext_1"
8819 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8824 (match_operand 1 "ext_register_operand" "0")
8828 (match_operand:QI 2 "general_operand" "Qm"))))
8829 (clobber (reg:CC FLAGS_REG))]
8831 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8832 "or{b}\t{%2, %h0|%h0, %2}"
8833 [(set_attr "type" "alu")
8834 (set_attr "length_immediate" "0")
8835 (set_attr "mode" "QI")])
8837 (define_insn "*iorqi_ext_1_rex64"
8838 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8843 (match_operand 1 "ext_register_operand" "0")
8847 (match_operand 2 "ext_register_operand" "Q"))))
8848 (clobber (reg:CC FLAGS_REG))]
8850 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8851 "or{b}\t{%2, %h0|%h0, %2}"
8852 [(set_attr "type" "alu")
8853 (set_attr "length_immediate" "0")
8854 (set_attr "mode" "QI")])
8856 (define_insn "*iorqi_ext_2"
8857 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8861 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8864 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8867 (clobber (reg:CC FLAGS_REG))]
8868 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8869 "ior{b}\t{%h2, %h0|%h0, %h2}"
8870 [(set_attr "type" "alu")
8871 (set_attr "length_immediate" "0")
8872 (set_attr "mode" "QI")])
8875 [(set (match_operand 0 "register_operand" "")
8876 (ior (match_operand 1 "register_operand" "")
8877 (match_operand 2 "const_int_operand" "")))
8878 (clobber (reg:CC FLAGS_REG))]
8880 && QI_REG_P (operands[0])
8881 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8882 && !(INTVAL (operands[2]) & ~(255 << 8))
8883 && GET_MODE (operands[0]) != QImode"
8884 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8885 (ior:SI (zero_extract:SI (match_dup 1)
8886 (const_int 8) (const_int 8))
8888 (clobber (reg:CC FLAGS_REG))])]
8889 "operands[0] = gen_lowpart (SImode, operands[0]);
8890 operands[1] = gen_lowpart (SImode, operands[1]);
8891 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8893 ;; Since OR can be encoded with sign extended immediate, this is only
8894 ;; profitable when 7th bit is set.
8896 [(set (match_operand 0 "register_operand" "")
8897 (ior (match_operand 1 "general_operand" "")
8898 (match_operand 2 "const_int_operand" "")))
8899 (clobber (reg:CC FLAGS_REG))]
8901 && ANY_QI_REG_P (operands[0])
8902 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8903 && !(INTVAL (operands[2]) & ~255)
8904 && (INTVAL (operands[2]) & 128)
8905 && GET_MODE (operands[0]) != QImode"
8906 [(parallel [(set (strict_low_part (match_dup 0))
8907 (ior:QI (match_dup 1)
8909 (clobber (reg:CC FLAGS_REG))])]
8910 "operands[0] = gen_lowpart (QImode, operands[0]);
8911 operands[1] = gen_lowpart (QImode, operands[1]);
8912 operands[2] = gen_lowpart (QImode, operands[2]);")
8914 ;; Logical XOR instructions
8916 ;; %%% This used to optimize known byte-wide and operations to memory.
8917 ;; If this is considered useful, it should be done with splitters.
8919 (define_expand "xordi3"
8920 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8921 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8922 (match_operand:DI 2 "x86_64_general_operand" "")))
8923 (clobber (reg:CC FLAGS_REG))]
8925 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8927 (define_insn "*xordi_1_rex64"
8928 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8929 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8930 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8931 (clobber (reg:CC FLAGS_REG))]
8933 && ix86_binary_operator_ok (XOR, DImode, operands)"
8935 xor{q}\t{%2, %0|%0, %2}
8936 xor{q}\t{%2, %0|%0, %2}"
8937 [(set_attr "type" "alu")
8938 (set_attr "mode" "DI,DI")])
8940 (define_insn "*xordi_2_rex64"
8941 [(set (reg FLAGS_REG)
8942 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8943 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8945 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8946 (xor:DI (match_dup 1) (match_dup 2)))]
8948 && ix86_match_ccmode (insn, CCNOmode)
8949 && ix86_binary_operator_ok (XOR, DImode, operands)"
8951 xor{q}\t{%2, %0|%0, %2}
8952 xor{q}\t{%2, %0|%0, %2}"
8953 [(set_attr "type" "alu")
8954 (set_attr "mode" "DI,DI")])
8956 (define_insn "*xordi_3_rex64"
8957 [(set (reg FLAGS_REG)
8958 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8959 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8961 (clobber (match_scratch:DI 0 "=r"))]
8963 && ix86_match_ccmode (insn, CCNOmode)
8964 && ix86_binary_operator_ok (XOR, DImode, operands)"
8965 "xor{q}\t{%2, %0|%0, %2}"
8966 [(set_attr "type" "alu")
8967 (set_attr "mode" "DI")])
8969 (define_expand "xorsi3"
8970 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8971 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8972 (match_operand:SI 2 "general_operand" "")))
8973 (clobber (reg:CC FLAGS_REG))]
8975 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8977 (define_insn "*xorsi_1"
8978 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8979 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8980 (match_operand:SI 2 "general_operand" "ri,rm")))
8981 (clobber (reg:CC FLAGS_REG))]
8982 "ix86_binary_operator_ok (XOR, SImode, operands)"
8983 "xor{l}\t{%2, %0|%0, %2}"
8984 [(set_attr "type" "alu")
8985 (set_attr "mode" "SI")])
8987 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8988 ;; Add speccase for immediates
8989 (define_insn "*xorsi_1_zext"
8990 [(set (match_operand:DI 0 "register_operand" "=r")
8992 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8993 (match_operand:SI 2 "general_operand" "rim"))))
8994 (clobber (reg:CC FLAGS_REG))]
8995 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8996 "xor{l}\t{%2, %k0|%k0, %2}"
8997 [(set_attr "type" "alu")
8998 (set_attr "mode" "SI")])
9000 (define_insn "*xorsi_1_zext_imm"
9001 [(set (match_operand:DI 0 "register_operand" "=r")
9002 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9003 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9004 (clobber (reg:CC FLAGS_REG))]
9005 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9006 "xor{l}\t{%2, %k0|%k0, %2}"
9007 [(set_attr "type" "alu")
9008 (set_attr "mode" "SI")])
9010 (define_insn "*xorsi_2"
9011 [(set (reg FLAGS_REG)
9012 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9013 (match_operand:SI 2 "general_operand" "rim,ri"))
9015 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9016 (xor:SI (match_dup 1) (match_dup 2)))]
9017 "ix86_match_ccmode (insn, CCNOmode)
9018 && ix86_binary_operator_ok (XOR, SImode, operands)"
9019 "xor{l}\t{%2, %0|%0, %2}"
9020 [(set_attr "type" "alu")
9021 (set_attr "mode" "SI")])
9023 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9024 ;; ??? Special case for immediate operand is missing - it is tricky.
9025 (define_insn "*xorsi_2_zext"
9026 [(set (reg FLAGS_REG)
9027 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9028 (match_operand:SI 2 "general_operand" "rim"))
9030 (set (match_operand:DI 0 "register_operand" "=r")
9031 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9032 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9033 && ix86_binary_operator_ok (XOR, SImode, operands)"
9034 "xor{l}\t{%2, %k0|%k0, %2}"
9035 [(set_attr "type" "alu")
9036 (set_attr "mode" "SI")])
9038 (define_insn "*xorsi_2_zext_imm"
9039 [(set (reg FLAGS_REG)
9040 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9041 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9043 (set (match_operand:DI 0 "register_operand" "=r")
9044 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9045 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9046 && ix86_binary_operator_ok (XOR, SImode, operands)"
9047 "xor{l}\t{%2, %k0|%k0, %2}"
9048 [(set_attr "type" "alu")
9049 (set_attr "mode" "SI")])
9051 (define_insn "*xorsi_3"
9052 [(set (reg FLAGS_REG)
9053 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9054 (match_operand:SI 2 "general_operand" "rim"))
9056 (clobber (match_scratch:SI 0 "=r"))]
9057 "ix86_match_ccmode (insn, CCNOmode)
9058 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9059 "xor{l}\t{%2, %0|%0, %2}"
9060 [(set_attr "type" "alu")
9061 (set_attr "mode" "SI")])
9063 (define_expand "xorhi3"
9064 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9065 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9066 (match_operand:HI 2 "general_operand" "")))
9067 (clobber (reg:CC FLAGS_REG))]
9068 "TARGET_HIMODE_MATH"
9069 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9071 (define_insn "*xorhi_1"
9072 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9073 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9074 (match_operand:HI 2 "general_operand" "rmi,ri")))
9075 (clobber (reg:CC FLAGS_REG))]
9076 "ix86_binary_operator_ok (XOR, HImode, operands)"
9077 "xor{w}\t{%2, %0|%0, %2}"
9078 [(set_attr "type" "alu")
9079 (set_attr "mode" "HI")])
9081 (define_insn "*xorhi_2"
9082 [(set (reg FLAGS_REG)
9083 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9084 (match_operand:HI 2 "general_operand" "rim,ri"))
9086 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9087 (xor:HI (match_dup 1) (match_dup 2)))]
9088 "ix86_match_ccmode (insn, CCNOmode)
9089 && ix86_binary_operator_ok (XOR, HImode, operands)"
9090 "xor{w}\t{%2, %0|%0, %2}"
9091 [(set_attr "type" "alu")
9092 (set_attr "mode" "HI")])
9094 (define_insn "*xorhi_3"
9095 [(set (reg FLAGS_REG)
9096 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9097 (match_operand:HI 2 "general_operand" "rim"))
9099 (clobber (match_scratch:HI 0 "=r"))]
9100 "ix86_match_ccmode (insn, CCNOmode)
9101 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9102 "xor{w}\t{%2, %0|%0, %2}"
9103 [(set_attr "type" "alu")
9104 (set_attr "mode" "HI")])
9106 (define_expand "xorqi3"
9107 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9108 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9109 (match_operand:QI 2 "general_operand" "")))
9110 (clobber (reg:CC FLAGS_REG))]
9111 "TARGET_QIMODE_MATH"
9112 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9114 ;; %%% Potential partial reg stall on alternative 2. What to do?
9115 (define_insn "*xorqi_1"
9116 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9117 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9118 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "ix86_binary_operator_ok (XOR, QImode, operands)"
9122 xor{b}\t{%2, %0|%0, %2}
9123 xor{b}\t{%2, %0|%0, %2}
9124 xor{l}\t{%k2, %k0|%k0, %k2}"
9125 [(set_attr "type" "alu")
9126 (set_attr "mode" "QI,QI,SI")])
9128 (define_insn "*xorqi_1_slp"
9129 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9130 (xor:QI (match_dup 0)
9131 (match_operand:QI 1 "general_operand" "qi,qmi")))
9132 (clobber (reg:CC FLAGS_REG))]
9133 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9134 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9135 "xor{b}\t{%1, %0|%0, %1}"
9136 [(set_attr "type" "alu1")
9137 (set_attr "mode" "QI")])
9139 (define_insn "xorqi_ext_0"
9140 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9145 (match_operand 1 "ext_register_operand" "0")
9148 (match_operand 2 "const_int_operand" "n")))
9149 (clobber (reg:CC FLAGS_REG))]
9150 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9151 "xor{b}\t{%2, %h0|%h0, %2}"
9152 [(set_attr "type" "alu")
9153 (set_attr "length_immediate" "1")
9154 (set_attr "mode" "QI")])
9156 (define_insn "*xorqi_ext_1"
9157 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9162 (match_operand 1 "ext_register_operand" "0")
9166 (match_operand:QI 2 "general_operand" "Qm"))))
9167 (clobber (reg:CC FLAGS_REG))]
9169 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9170 "xor{b}\t{%2, %h0|%h0, %2}"
9171 [(set_attr "type" "alu")
9172 (set_attr "length_immediate" "0")
9173 (set_attr "mode" "QI")])
9175 (define_insn "*xorqi_ext_1_rex64"
9176 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9181 (match_operand 1 "ext_register_operand" "0")
9185 (match_operand 2 "ext_register_operand" "Q"))))
9186 (clobber (reg:CC FLAGS_REG))]
9188 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9189 "xor{b}\t{%2, %h0|%h0, %2}"
9190 [(set_attr "type" "alu")
9191 (set_attr "length_immediate" "0")
9192 (set_attr "mode" "QI")])
9194 (define_insn "*xorqi_ext_2"
9195 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9199 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9202 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9205 (clobber (reg:CC FLAGS_REG))]
9206 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9207 "xor{b}\t{%h2, %h0|%h0, %h2}"
9208 [(set_attr "type" "alu")
9209 (set_attr "length_immediate" "0")
9210 (set_attr "mode" "QI")])
9212 (define_insn "*xorqi_cc_1"
9213 [(set (reg FLAGS_REG)
9215 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9216 (match_operand:QI 2 "general_operand" "qim,qi"))
9218 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9219 (xor:QI (match_dup 1) (match_dup 2)))]
9220 "ix86_match_ccmode (insn, CCNOmode)
9221 && ix86_binary_operator_ok (XOR, QImode, operands)"
9222 "xor{b}\t{%2, %0|%0, %2}"
9223 [(set_attr "type" "alu")
9224 (set_attr "mode" "QI")])
9226 (define_insn "*xorqi_2_slp"
9227 [(set (reg FLAGS_REG)
9228 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9229 (match_operand:QI 1 "general_operand" "qim,qi"))
9231 (set (strict_low_part (match_dup 0))
9232 (xor:QI (match_dup 0) (match_dup 1)))]
9233 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9234 && ix86_match_ccmode (insn, CCNOmode)
9235 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9236 "xor{b}\t{%1, %0|%0, %1}"
9237 [(set_attr "type" "alu1")
9238 (set_attr "mode" "QI")])
9240 (define_insn "*xorqi_cc_2"
9241 [(set (reg FLAGS_REG)
9243 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9244 (match_operand:QI 2 "general_operand" "qim"))
9246 (clobber (match_scratch:QI 0 "=q"))]
9247 "ix86_match_ccmode (insn, CCNOmode)
9248 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9249 "xor{b}\t{%2, %0|%0, %2}"
9250 [(set_attr "type" "alu")
9251 (set_attr "mode" "QI")])
9253 (define_insn "*xorqi_cc_ext_1"
9254 [(set (reg FLAGS_REG)
9258 (match_operand 1 "ext_register_operand" "0")
9261 (match_operand:QI 2 "general_operand" "qmn"))
9263 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9267 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9269 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9270 "xor{b}\t{%2, %h0|%h0, %2}"
9271 [(set_attr "type" "alu")
9272 (set_attr "mode" "QI")])
9274 (define_insn "*xorqi_cc_ext_1_rex64"
9275 [(set (reg FLAGS_REG)
9279 (match_operand 1 "ext_register_operand" "0")
9282 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9284 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9288 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9290 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9291 "xor{b}\t{%2, %h0|%h0, %2}"
9292 [(set_attr "type" "alu")
9293 (set_attr "mode" "QI")])
9295 (define_expand "xorqi_cc_ext_1"
9297 (set (reg:CCNO FLAGS_REG)
9301 (match_operand 1 "ext_register_operand" "")
9304 (match_operand:QI 2 "general_operand" ""))
9306 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9310 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9316 [(set (match_operand 0 "register_operand" "")
9317 (xor (match_operand 1 "register_operand" "")
9318 (match_operand 2 "const_int_operand" "")))
9319 (clobber (reg:CC FLAGS_REG))]
9321 && QI_REG_P (operands[0])
9322 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9323 && !(INTVAL (operands[2]) & ~(255 << 8))
9324 && GET_MODE (operands[0]) != QImode"
9325 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9326 (xor:SI (zero_extract:SI (match_dup 1)
9327 (const_int 8) (const_int 8))
9329 (clobber (reg:CC FLAGS_REG))])]
9330 "operands[0] = gen_lowpart (SImode, operands[0]);
9331 operands[1] = gen_lowpart (SImode, operands[1]);
9332 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9334 ;; Since XOR can be encoded with sign extended immediate, this is only
9335 ;; profitable when 7th bit is set.
9337 [(set (match_operand 0 "register_operand" "")
9338 (xor (match_operand 1 "general_operand" "")
9339 (match_operand 2 "const_int_operand" "")))
9340 (clobber (reg:CC FLAGS_REG))]
9342 && ANY_QI_REG_P (operands[0])
9343 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9344 && !(INTVAL (operands[2]) & ~255)
9345 && (INTVAL (operands[2]) & 128)
9346 && GET_MODE (operands[0]) != QImode"
9347 [(parallel [(set (strict_low_part (match_dup 0))
9348 (xor:QI (match_dup 1)
9350 (clobber (reg:CC FLAGS_REG))])]
9351 "operands[0] = gen_lowpart (QImode, operands[0]);
9352 operands[1] = gen_lowpart (QImode, operands[1]);
9353 operands[2] = gen_lowpart (QImode, operands[2]);")
9355 ;; Negation instructions
9357 (define_expand "negti2"
9358 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9359 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9360 (clobber (reg:CC FLAGS_REG))])]
9362 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9364 (define_insn "*negti2_1"
9365 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9366 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9367 (clobber (reg:CC FLAGS_REG))]
9369 && ix86_unary_operator_ok (NEG, TImode, operands)"
9373 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9374 (neg:TI (match_operand:TI 1 "general_operand" "")))
9375 (clobber (reg:CC FLAGS_REG))]
9376 "TARGET_64BIT && reload_completed"
9378 [(set (reg:CCZ FLAGS_REG)
9379 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9380 (set (match_dup 0) (neg:DI (match_dup 2)))])
9383 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9386 (clobber (reg:CC FLAGS_REG))])
9389 (neg:DI (match_dup 1)))
9390 (clobber (reg:CC FLAGS_REG))])]
9391 "split_ti (operands+1, 1, operands+2, operands+3);
9392 split_ti (operands+0, 1, operands+0, operands+1);")
9394 (define_expand "negdi2"
9395 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9396 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9397 (clobber (reg:CC FLAGS_REG))])]
9399 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9401 (define_insn "*negdi2_1"
9402 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9403 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9404 (clobber (reg:CC FLAGS_REG))]
9406 && ix86_unary_operator_ok (NEG, DImode, operands)"
9410 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9411 (neg:DI (match_operand:DI 1 "general_operand" "")))
9412 (clobber (reg:CC FLAGS_REG))]
9413 "!TARGET_64BIT && reload_completed"
9415 [(set (reg:CCZ FLAGS_REG)
9416 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9417 (set (match_dup 0) (neg:SI (match_dup 2)))])
9420 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9423 (clobber (reg:CC FLAGS_REG))])
9426 (neg:SI (match_dup 1)))
9427 (clobber (reg:CC FLAGS_REG))])]
9428 "split_di (operands+1, 1, operands+2, operands+3);
9429 split_di (operands+0, 1, operands+0, operands+1);")
9431 (define_insn "*negdi2_1_rex64"
9432 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9433 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9434 (clobber (reg:CC FLAGS_REG))]
9435 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9437 [(set_attr "type" "negnot")
9438 (set_attr "mode" "DI")])
9440 ;; The problem with neg is that it does not perform (compare x 0),
9441 ;; it really performs (compare 0 x), which leaves us with the zero
9442 ;; flag being the only useful item.
9444 (define_insn "*negdi2_cmpz_rex64"
9445 [(set (reg:CCZ FLAGS_REG)
9446 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9448 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9449 (neg:DI (match_dup 1)))]
9450 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9452 [(set_attr "type" "negnot")
9453 (set_attr "mode" "DI")])
9456 (define_expand "negsi2"
9457 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9458 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9459 (clobber (reg:CC FLAGS_REG))])]
9461 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9463 (define_insn "*negsi2_1"
9464 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9465 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9466 (clobber (reg:CC FLAGS_REG))]
9467 "ix86_unary_operator_ok (NEG, SImode, operands)"
9469 [(set_attr "type" "negnot")
9470 (set_attr "mode" "SI")])
9472 ;; Combine is quite creative about this pattern.
9473 (define_insn "*negsi2_1_zext"
9474 [(set (match_operand:DI 0 "register_operand" "=r")
9475 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9478 (clobber (reg:CC FLAGS_REG))]
9479 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9481 [(set_attr "type" "negnot")
9482 (set_attr "mode" "SI")])
9484 ;; The problem with neg is that it does not perform (compare x 0),
9485 ;; it really performs (compare 0 x), which leaves us with the zero
9486 ;; flag being the only useful item.
9488 (define_insn "*negsi2_cmpz"
9489 [(set (reg:CCZ FLAGS_REG)
9490 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9492 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9493 (neg:SI (match_dup 1)))]
9494 "ix86_unary_operator_ok (NEG, SImode, operands)"
9496 [(set_attr "type" "negnot")
9497 (set_attr "mode" "SI")])
9499 (define_insn "*negsi2_cmpz_zext"
9500 [(set (reg:CCZ FLAGS_REG)
9501 (compare:CCZ (lshiftrt:DI
9503 (match_operand:DI 1 "register_operand" "0")
9507 (set (match_operand:DI 0 "register_operand" "=r")
9508 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9511 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9513 [(set_attr "type" "negnot")
9514 (set_attr "mode" "SI")])
9516 (define_expand "neghi2"
9517 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9518 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9519 (clobber (reg:CC FLAGS_REG))])]
9520 "TARGET_HIMODE_MATH"
9521 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9523 (define_insn "*neghi2_1"
9524 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9525 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9526 (clobber (reg:CC FLAGS_REG))]
9527 "ix86_unary_operator_ok (NEG, HImode, operands)"
9529 [(set_attr "type" "negnot")
9530 (set_attr "mode" "HI")])
9532 (define_insn "*neghi2_cmpz"
9533 [(set (reg:CCZ FLAGS_REG)
9534 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9536 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9537 (neg:HI (match_dup 1)))]
9538 "ix86_unary_operator_ok (NEG, HImode, operands)"
9540 [(set_attr "type" "negnot")
9541 (set_attr "mode" "HI")])
9543 (define_expand "negqi2"
9544 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9545 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9546 (clobber (reg:CC FLAGS_REG))])]
9547 "TARGET_QIMODE_MATH"
9548 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9550 (define_insn "*negqi2_1"
9551 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9552 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9553 (clobber (reg:CC FLAGS_REG))]
9554 "ix86_unary_operator_ok (NEG, QImode, operands)"
9556 [(set_attr "type" "negnot")
9557 (set_attr "mode" "QI")])
9559 (define_insn "*negqi2_cmpz"
9560 [(set (reg:CCZ FLAGS_REG)
9561 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9563 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9564 (neg:QI (match_dup 1)))]
9565 "ix86_unary_operator_ok (NEG, QImode, operands)"
9567 [(set_attr "type" "negnot")
9568 (set_attr "mode" "QI")])
9570 ;; Changing of sign for FP values is doable using integer unit too.
9572 (define_expand "negsf2"
9573 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9574 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9575 "TARGET_80387 || TARGET_SSE_MATH"
9576 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9578 (define_expand "abssf2"
9579 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9580 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9581 "TARGET_80387 || TARGET_SSE_MATH"
9582 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9584 (define_insn "*absnegsf2_mixed"
9585 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9586 (match_operator:SF 3 "absneg_operator"
9587 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9588 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9589 (clobber (reg:CC FLAGS_REG))]
9590 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9591 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9594 (define_insn "*absnegsf2_sse"
9595 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9596 (match_operator:SF 3 "absneg_operator"
9597 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9598 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9599 (clobber (reg:CC FLAGS_REG))]
9601 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9604 (define_insn "*absnegsf2_i387"
9605 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9606 (match_operator:SF 3 "absneg_operator"
9607 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9608 (use (match_operand 2 "" ""))
9609 (clobber (reg:CC FLAGS_REG))]
9610 "TARGET_80387 && !TARGET_SSE_MATH
9611 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9614 (define_expand "copysignsf3"
9615 [(match_operand:SF 0 "register_operand" "")
9616 (match_operand:SF 1 "nonmemory_operand" "")
9617 (match_operand:SF 2 "register_operand" "")]
9620 ix86_expand_copysign (operands);
9624 (define_insn_and_split "copysignsf3_const"
9625 [(set (match_operand:SF 0 "register_operand" "=x")
9627 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9628 (match_operand:SF 2 "register_operand" "0")
9629 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9633 "&& reload_completed"
9636 ix86_split_copysign_const (operands);
9640 (define_insn "copysignsf3_var"
9641 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9643 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9644 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9645 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9646 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9648 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9653 [(set (match_operand:SF 0 "register_operand" "")
9655 [(match_operand:SF 2 "register_operand" "")
9656 (match_operand:SF 3 "register_operand" "")
9657 (match_operand:V4SF 4 "" "")
9658 (match_operand:V4SF 5 "" "")]
9660 (clobber (match_scratch:V4SF 1 ""))]
9661 "TARGET_SSE_MATH && reload_completed"
9664 ix86_split_copysign_var (operands);
9668 (define_expand "negdf2"
9669 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9670 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9671 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9672 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9674 (define_expand "absdf2"
9675 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9676 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9677 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9678 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9680 (define_insn "*absnegdf2_mixed"
9681 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9682 (match_operator:DF 3 "absneg_operator"
9683 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9684 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9685 (clobber (reg:CC FLAGS_REG))]
9686 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9687 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9690 (define_insn "*absnegdf2_sse"
9691 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9692 (match_operator:DF 3 "absneg_operator"
9693 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9694 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9695 (clobber (reg:CC FLAGS_REG))]
9696 "TARGET_SSE2 && TARGET_SSE_MATH
9697 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9700 (define_insn "*absnegdf2_i387"
9701 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9702 (match_operator:DF 3 "absneg_operator"
9703 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9704 (use (match_operand 2 "" ""))
9705 (clobber (reg:CC FLAGS_REG))]
9706 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9707 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9710 (define_expand "copysigndf3"
9711 [(match_operand:DF 0 "register_operand" "")
9712 (match_operand:DF 1 "nonmemory_operand" "")
9713 (match_operand:DF 2 "register_operand" "")]
9714 "TARGET_SSE2 && TARGET_SSE_MATH"
9716 ix86_expand_copysign (operands);
9720 (define_insn_and_split "copysigndf3_const"
9721 [(set (match_operand:DF 0 "register_operand" "=x")
9723 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9724 (match_operand:DF 2 "register_operand" "0")
9725 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9727 "TARGET_SSE2 && TARGET_SSE_MATH"
9729 "&& reload_completed"
9732 ix86_split_copysign_const (operands);
9736 (define_insn "copysigndf3_var"
9737 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9739 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9740 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9741 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9742 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9744 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9745 "TARGET_SSE2 && TARGET_SSE_MATH"
9749 [(set (match_operand:DF 0 "register_operand" "")
9751 [(match_operand:DF 2 "register_operand" "")
9752 (match_operand:DF 3 "register_operand" "")
9753 (match_operand:V2DF 4 "" "")
9754 (match_operand:V2DF 5 "" "")]
9756 (clobber (match_scratch:V2DF 1 ""))]
9757 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9760 ix86_split_copysign_var (operands);
9764 (define_expand "negxf2"
9765 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9766 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9768 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9770 (define_expand "absxf2"
9771 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9772 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9774 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9776 (define_insn "*absnegxf2_i387"
9777 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9778 (match_operator:XF 3 "absneg_operator"
9779 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9780 (use (match_operand 2 "" ""))
9781 (clobber (reg:CC FLAGS_REG))]
9783 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9786 ;; Splitters for fp abs and neg.
9789 [(set (match_operand 0 "fp_register_operand" "")
9790 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9791 (use (match_operand 2 "" ""))
9792 (clobber (reg:CC FLAGS_REG))]
9794 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9797 [(set (match_operand 0 "register_operand" "")
9798 (match_operator 3 "absneg_operator"
9799 [(match_operand 1 "register_operand" "")]))
9800 (use (match_operand 2 "nonimmediate_operand" ""))
9801 (clobber (reg:CC FLAGS_REG))]
9802 "reload_completed && SSE_REG_P (operands[0])"
9803 [(set (match_dup 0) (match_dup 3))]
9805 enum machine_mode mode = GET_MODE (operands[0]);
9806 enum machine_mode vmode = GET_MODE (operands[2]);
9809 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9810 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9811 if (operands_match_p (operands[0], operands[2]))
9814 operands[1] = operands[2];
9817 if (GET_CODE (operands[3]) == ABS)
9818 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9820 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9825 [(set (match_operand:SF 0 "register_operand" "")
9826 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9827 (use (match_operand:V4SF 2 "" ""))
9828 (clobber (reg:CC FLAGS_REG))]
9830 [(parallel [(set (match_dup 0) (match_dup 1))
9831 (clobber (reg:CC FLAGS_REG))])]
9834 operands[0] = gen_lowpart (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);
9849 [(set (match_operand:DF 0 "register_operand" "")
9850 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9851 (use (match_operand 2 "" ""))
9852 (clobber (reg:CC FLAGS_REG))]
9854 [(parallel [(set (match_dup 0) (match_dup 1))
9855 (clobber (reg:CC FLAGS_REG))])]
9860 tmp = gen_lowpart (DImode, operands[0]);
9861 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9864 if (GET_CODE (operands[1]) == ABS)
9867 tmp = gen_rtx_NOT (DImode, tmp);
9871 operands[0] = gen_highpart (SImode, operands[0]);
9872 if (GET_CODE (operands[1]) == ABS)
9874 tmp = gen_int_mode (0x7fffffff, SImode);
9875 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9879 tmp = gen_int_mode (0x80000000, SImode);
9880 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9887 [(set (match_operand:XF 0 "register_operand" "")
9888 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9889 (use (match_operand 2 "" ""))
9890 (clobber (reg:CC FLAGS_REG))]
9892 [(parallel [(set (match_dup 0) (match_dup 1))
9893 (clobber (reg:CC FLAGS_REG))])]
9896 operands[0] = gen_rtx_REG (SImode,
9897 true_regnum (operands[0])
9898 + (TARGET_64BIT ? 1 : 2));
9899 if (GET_CODE (operands[1]) == ABS)
9901 tmp = GEN_INT (0x7fff);
9902 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9906 tmp = GEN_INT (0x8000);
9907 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9913 [(set (match_operand 0 "memory_operand" "")
9914 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9915 (use (match_operand 2 "" ""))
9916 (clobber (reg:CC FLAGS_REG))]
9918 [(parallel [(set (match_dup 0) (match_dup 1))
9919 (clobber (reg:CC FLAGS_REG))])]
9921 enum machine_mode mode = GET_MODE (operands[0]);
9922 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9925 operands[0] = adjust_address (operands[0], QImode, size - 1);
9926 if (GET_CODE (operands[1]) == ABS)
9928 tmp = gen_int_mode (0x7f, QImode);
9929 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9933 tmp = gen_int_mode (0x80, QImode);
9934 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9939 ;; Conditionalize these after reload. If they match before reload, we
9940 ;; lose the clobber and ability to use integer instructions.
9942 (define_insn "*negsf2_1"
9943 [(set (match_operand:SF 0 "register_operand" "=f")
9944 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9945 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9947 [(set_attr "type" "fsgn")
9948 (set_attr "mode" "SF")])
9950 (define_insn "*negdf2_1"
9951 [(set (match_operand:DF 0 "register_operand" "=f")
9952 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9953 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9955 [(set_attr "type" "fsgn")
9956 (set_attr "mode" "DF")])
9958 (define_insn "*negxf2_1"
9959 [(set (match_operand:XF 0 "register_operand" "=f")
9960 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9963 [(set_attr "type" "fsgn")
9964 (set_attr "mode" "XF")])
9966 (define_insn "*abssf2_1"
9967 [(set (match_operand:SF 0 "register_operand" "=f")
9968 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9969 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9971 [(set_attr "type" "fsgn")
9972 (set_attr "mode" "SF")])
9974 (define_insn "*absdf2_1"
9975 [(set (match_operand:DF 0 "register_operand" "=f")
9976 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9977 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9979 [(set_attr "type" "fsgn")
9980 (set_attr "mode" "DF")])
9982 (define_insn "*absxf2_1"
9983 [(set (match_operand:XF 0 "register_operand" "=f")
9984 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9987 [(set_attr "type" "fsgn")
9988 (set_attr "mode" "DF")])
9990 (define_insn "*negextendsfdf2"
9991 [(set (match_operand:DF 0 "register_operand" "=f")
9992 (neg:DF (float_extend:DF
9993 (match_operand:SF 1 "register_operand" "0"))))]
9994 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9996 [(set_attr "type" "fsgn")
9997 (set_attr "mode" "DF")])
9999 (define_insn "*negextenddfxf2"
10000 [(set (match_operand:XF 0 "register_operand" "=f")
10001 (neg:XF (float_extend:XF
10002 (match_operand:DF 1 "register_operand" "0"))))]
10005 [(set_attr "type" "fsgn")
10006 (set_attr "mode" "XF")])
10008 (define_insn "*negextendsfxf2"
10009 [(set (match_operand:XF 0 "register_operand" "=f")
10010 (neg:XF (float_extend:XF
10011 (match_operand:SF 1 "register_operand" "0"))))]
10014 [(set_attr "type" "fsgn")
10015 (set_attr "mode" "XF")])
10017 (define_insn "*absextendsfdf2"
10018 [(set (match_operand:DF 0 "register_operand" "=f")
10019 (abs:DF (float_extend:DF
10020 (match_operand:SF 1 "register_operand" "0"))))]
10021 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10023 [(set_attr "type" "fsgn")
10024 (set_attr "mode" "DF")])
10026 (define_insn "*absextenddfxf2"
10027 [(set (match_operand:XF 0 "register_operand" "=f")
10028 (abs:XF (float_extend:XF
10029 (match_operand:DF 1 "register_operand" "0"))))]
10032 [(set_attr "type" "fsgn")
10033 (set_attr "mode" "XF")])
10035 (define_insn "*absextendsfxf2"
10036 [(set (match_operand:XF 0 "register_operand" "=f")
10037 (abs:XF (float_extend:XF
10038 (match_operand:SF 1 "register_operand" "0"))))]
10041 [(set_attr "type" "fsgn")
10042 (set_attr "mode" "XF")])
10044 ;; One complement instructions
10046 (define_expand "one_cmpldi2"
10047 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10048 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10050 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10052 (define_insn "*one_cmpldi2_1_rex64"
10053 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10054 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10055 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10057 [(set_attr "type" "negnot")
10058 (set_attr "mode" "DI")])
10060 (define_insn "*one_cmpldi2_2_rex64"
10061 [(set (reg FLAGS_REG)
10062 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10064 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10065 (not:DI (match_dup 1)))]
10066 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10067 && ix86_unary_operator_ok (NOT, DImode, operands)"
10069 [(set_attr "type" "alu1")
10070 (set_attr "mode" "DI")])
10073 [(set (match_operand 0 "flags_reg_operand" "")
10074 (match_operator 2 "compare_operator"
10075 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10077 (set (match_operand:DI 1 "nonimmediate_operand" "")
10078 (not:DI (match_dup 3)))]
10079 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10080 [(parallel [(set (match_dup 0)
10082 [(xor:DI (match_dup 3) (const_int -1))
10085 (xor:DI (match_dup 3) (const_int -1)))])]
10088 (define_expand "one_cmplsi2"
10089 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10090 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10092 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10094 (define_insn "*one_cmplsi2_1"
10095 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10096 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10097 "ix86_unary_operator_ok (NOT, SImode, operands)"
10099 [(set_attr "type" "negnot")
10100 (set_attr "mode" "SI")])
10102 ;; ??? Currently never generated - xor is used instead.
10103 (define_insn "*one_cmplsi2_1_zext"
10104 [(set (match_operand:DI 0 "register_operand" "=r")
10105 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10106 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10108 [(set_attr "type" "negnot")
10109 (set_attr "mode" "SI")])
10111 (define_insn "*one_cmplsi2_2"
10112 [(set (reg FLAGS_REG)
10113 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10115 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10116 (not:SI (match_dup 1)))]
10117 "ix86_match_ccmode (insn, CCNOmode)
10118 && ix86_unary_operator_ok (NOT, SImode, operands)"
10120 [(set_attr "type" "alu1")
10121 (set_attr "mode" "SI")])
10124 [(set (match_operand 0 "flags_reg_operand" "")
10125 (match_operator 2 "compare_operator"
10126 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10128 (set (match_operand:SI 1 "nonimmediate_operand" "")
10129 (not:SI (match_dup 3)))]
10130 "ix86_match_ccmode (insn, CCNOmode)"
10131 [(parallel [(set (match_dup 0)
10132 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10135 (xor:SI (match_dup 3) (const_int -1)))])]
10138 ;; ??? Currently never generated - xor is used instead.
10139 (define_insn "*one_cmplsi2_2_zext"
10140 [(set (reg FLAGS_REG)
10141 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10143 (set (match_operand:DI 0 "register_operand" "=r")
10144 (zero_extend:DI (not:SI (match_dup 1))))]
10145 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10146 && ix86_unary_operator_ok (NOT, SImode, operands)"
10148 [(set_attr "type" "alu1")
10149 (set_attr "mode" "SI")])
10152 [(set (match_operand 0 "flags_reg_operand" "")
10153 (match_operator 2 "compare_operator"
10154 [(not:SI (match_operand:SI 3 "register_operand" ""))
10156 (set (match_operand:DI 1 "register_operand" "")
10157 (zero_extend:DI (not:SI (match_dup 3))))]
10158 "ix86_match_ccmode (insn, CCNOmode)"
10159 [(parallel [(set (match_dup 0)
10160 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10163 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10166 (define_expand "one_cmplhi2"
10167 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10168 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10169 "TARGET_HIMODE_MATH"
10170 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10172 (define_insn "*one_cmplhi2_1"
10173 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10174 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10175 "ix86_unary_operator_ok (NOT, HImode, operands)"
10177 [(set_attr "type" "negnot")
10178 (set_attr "mode" "HI")])
10180 (define_insn "*one_cmplhi2_2"
10181 [(set (reg FLAGS_REG)
10182 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10184 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10185 (not:HI (match_dup 1)))]
10186 "ix86_match_ccmode (insn, CCNOmode)
10187 && ix86_unary_operator_ok (NEG, HImode, operands)"
10189 [(set_attr "type" "alu1")
10190 (set_attr "mode" "HI")])
10193 [(set (match_operand 0 "flags_reg_operand" "")
10194 (match_operator 2 "compare_operator"
10195 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10197 (set (match_operand:HI 1 "nonimmediate_operand" "")
10198 (not:HI (match_dup 3)))]
10199 "ix86_match_ccmode (insn, CCNOmode)"
10200 [(parallel [(set (match_dup 0)
10201 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10204 (xor:HI (match_dup 3) (const_int -1)))])]
10207 ;; %%% Potential partial reg stall on alternative 1. What to do?
10208 (define_expand "one_cmplqi2"
10209 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10210 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10211 "TARGET_QIMODE_MATH"
10212 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10214 (define_insn "*one_cmplqi2_1"
10215 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10216 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10217 "ix86_unary_operator_ok (NOT, QImode, operands)"
10221 [(set_attr "type" "negnot")
10222 (set_attr "mode" "QI,SI")])
10224 (define_insn "*one_cmplqi2_2"
10225 [(set (reg FLAGS_REG)
10226 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10228 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10229 (not:QI (match_dup 1)))]
10230 "ix86_match_ccmode (insn, CCNOmode)
10231 && ix86_unary_operator_ok (NOT, QImode, operands)"
10233 [(set_attr "type" "alu1")
10234 (set_attr "mode" "QI")])
10237 [(set (match_operand 0 "flags_reg_operand" "")
10238 (match_operator 2 "compare_operator"
10239 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10241 (set (match_operand:QI 1 "nonimmediate_operand" "")
10242 (not:QI (match_dup 3)))]
10243 "ix86_match_ccmode (insn, CCNOmode)"
10244 [(parallel [(set (match_dup 0)
10245 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10248 (xor:QI (match_dup 3) (const_int -1)))])]
10251 ;; Arithmetic shift instructions
10253 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10254 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10255 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10256 ;; from the assembler input.
10258 ;; This instruction shifts the target reg/mem as usual, but instead of
10259 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10260 ;; is a left shift double, bits are taken from the high order bits of
10261 ;; reg, else if the insn is a shift right double, bits are taken from the
10262 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10263 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10265 ;; Since sh[lr]d does not change the `reg' operand, that is done
10266 ;; separately, making all shifts emit pairs of shift double and normal
10267 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10268 ;; support a 63 bit shift, each shift where the count is in a reg expands
10269 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10271 ;; If the shift count is a constant, we need never emit more than one
10272 ;; shift pair, instead using moves and sign extension for counts greater
10275 (define_expand "ashlti3"
10276 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10277 (ashift:TI (match_operand:TI 1 "register_operand" "")
10278 (match_operand:QI 2 "nonmemory_operand" "")))
10279 (clobber (reg:CC FLAGS_REG))])]
10282 if (! immediate_operand (operands[2], QImode))
10284 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10287 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10291 (define_insn "ashlti3_1"
10292 [(set (match_operand:TI 0 "register_operand" "=r")
10293 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10294 (match_operand:QI 2 "register_operand" "c")))
10295 (clobber (match_scratch:DI 3 "=&r"))
10296 (clobber (reg:CC FLAGS_REG))]
10299 [(set_attr "type" "multi")])
10301 (define_insn "*ashlti3_2"
10302 [(set (match_operand:TI 0 "register_operand" "=r")
10303 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10304 (match_operand:QI 2 "immediate_operand" "O")))
10305 (clobber (reg:CC FLAGS_REG))]
10308 [(set_attr "type" "multi")])
10311 [(set (match_operand:TI 0 "register_operand" "")
10312 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10313 (match_operand:QI 2 "register_operand" "")))
10314 (clobber (match_scratch:DI 3 ""))
10315 (clobber (reg:CC FLAGS_REG))]
10316 "TARGET_64BIT && reload_completed"
10318 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10321 [(set (match_operand:TI 0 "register_operand" "")
10322 (ashift:TI (match_operand:TI 1 "register_operand" "")
10323 (match_operand:QI 2 "immediate_operand" "")))
10324 (clobber (reg:CC FLAGS_REG))]
10325 "TARGET_64BIT && reload_completed"
10327 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10329 (define_insn "x86_64_shld"
10330 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10331 (ior:DI (ashift:DI (match_dup 0)
10332 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10333 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10334 (minus:QI (const_int 64) (match_dup 2)))))
10335 (clobber (reg:CC FLAGS_REG))]
10338 shld{q}\t{%2, %1, %0|%0, %1, %2}
10339 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10340 [(set_attr "type" "ishift")
10341 (set_attr "prefix_0f" "1")
10342 (set_attr "mode" "DI")
10343 (set_attr "athlon_decode" "vector")])
10345 (define_expand "x86_64_shift_adj"
10346 [(set (reg:CCZ FLAGS_REG)
10347 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10350 (set (match_operand:DI 0 "register_operand" "")
10351 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10352 (match_operand:DI 1 "register_operand" "")
10355 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10356 (match_operand:DI 3 "register_operand" "r")
10361 (define_expand "ashldi3"
10362 [(set (match_operand:DI 0 "shiftdi_operand" "")
10363 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10364 (match_operand:QI 2 "nonmemory_operand" "")))]
10366 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10368 (define_insn "*ashldi3_1_rex64"
10369 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10370 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10371 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10372 (clobber (reg:CC FLAGS_REG))]
10373 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10375 switch (get_attr_type (insn))
10378 gcc_assert (operands[2] == const1_rtx);
10379 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10380 return "add{q}\t{%0, %0|%0, %0}";
10383 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10384 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10385 operands[1] = gen_rtx_MULT (DImode, operands[1],
10386 GEN_INT (1 << INTVAL (operands[2])));
10387 return "lea{q}\t{%a1, %0|%0, %a1}";
10390 if (REG_P (operands[2]))
10391 return "sal{q}\t{%b2, %0|%0, %b2}";
10392 else if (operands[2] == const1_rtx
10393 && (TARGET_SHIFT1 || optimize_size))
10394 return "sal{q}\t%0";
10396 return "sal{q}\t{%2, %0|%0, %2}";
10399 [(set (attr "type")
10400 (cond [(eq_attr "alternative" "1")
10401 (const_string "lea")
10402 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10404 (match_operand 0 "register_operand" ""))
10405 (match_operand 2 "const1_operand" ""))
10406 (const_string "alu")
10408 (const_string "ishift")))
10409 (set_attr "mode" "DI")])
10411 ;; Convert lea to the lea pattern to avoid flags dependency.
10413 [(set (match_operand:DI 0 "register_operand" "")
10414 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10415 (match_operand:QI 2 "immediate_operand" "")))
10416 (clobber (reg:CC FLAGS_REG))]
10417 "TARGET_64BIT && reload_completed
10418 && true_regnum (operands[0]) != true_regnum (operands[1])"
10419 [(set (match_dup 0)
10420 (mult:DI (match_dup 1)
10422 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10424 ;; This pattern can't accept a variable shift count, since shifts by
10425 ;; zero don't affect the flags. We assume that shifts by constant
10426 ;; zero are optimized away.
10427 (define_insn "*ashldi3_cmp_rex64"
10428 [(set (reg FLAGS_REG)
10430 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10431 (match_operand:QI 2 "immediate_operand" "e"))
10433 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10434 (ashift:DI (match_dup 1) (match_dup 2)))]
10435 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10436 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10438 || !TARGET_PARTIAL_FLAG_REG_STALL
10439 || (operands[2] == const1_rtx
10441 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10443 switch (get_attr_type (insn))
10446 gcc_assert (operands[2] == const1_rtx);
10447 return "add{q}\t{%0, %0|%0, %0}";
10450 if (REG_P (operands[2]))
10451 return "sal{q}\t{%b2, %0|%0, %b2}";
10452 else if (operands[2] == const1_rtx
10453 && (TARGET_SHIFT1 || optimize_size))
10454 return "sal{q}\t%0";
10456 return "sal{q}\t{%2, %0|%0, %2}";
10459 [(set (attr "type")
10460 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10462 (match_operand 0 "register_operand" ""))
10463 (match_operand 2 "const1_operand" ""))
10464 (const_string "alu")
10466 (const_string "ishift")))
10467 (set_attr "mode" "DI")])
10469 (define_insn "*ashldi3_cconly_rex64"
10470 [(set (reg FLAGS_REG)
10472 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10473 (match_operand:QI 2 "immediate_operand" "e"))
10475 (clobber (match_scratch:DI 0 "=r"))]
10476 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10477 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10479 || !TARGET_PARTIAL_FLAG_REG_STALL
10480 || (operands[2] == const1_rtx
10482 || TARGET_DOUBLE_WITH_ADD)))"
10484 switch (get_attr_type (insn))
10487 gcc_assert (operands[2] == const1_rtx);
10488 return "add{q}\t{%0, %0|%0, %0}";
10491 if (REG_P (operands[2]))
10492 return "sal{q}\t{%b2, %0|%0, %b2}";
10493 else if (operands[2] == const1_rtx
10494 && (TARGET_SHIFT1 || optimize_size))
10495 return "sal{q}\t%0";
10497 return "sal{q}\t{%2, %0|%0, %2}";
10500 [(set (attr "type")
10501 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10503 (match_operand 0 "register_operand" ""))
10504 (match_operand 2 "const1_operand" ""))
10505 (const_string "alu")
10507 (const_string "ishift")))
10508 (set_attr "mode" "DI")])
10510 (define_insn "*ashldi3_1"
10511 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10512 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10513 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10514 (clobber (reg:CC FLAGS_REG))]
10517 [(set_attr "type" "multi")])
10519 ;; By default we don't ask for a scratch register, because when DImode
10520 ;; values are manipulated, registers are already at a premium. But if
10521 ;; we have one handy, we won't turn it away.
10523 [(match_scratch:SI 3 "r")
10524 (parallel [(set (match_operand:DI 0 "register_operand" "")
10525 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10526 (match_operand:QI 2 "nonmemory_operand" "")))
10527 (clobber (reg:CC FLAGS_REG))])
10529 "!TARGET_64BIT && TARGET_CMOVE"
10531 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10534 [(set (match_operand:DI 0 "register_operand" "")
10535 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10536 (match_operand:QI 2 "nonmemory_operand" "")))
10537 (clobber (reg:CC FLAGS_REG))]
10538 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10539 ? flow2_completed : reload_completed)"
10541 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10543 (define_insn "x86_shld_1"
10544 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10545 (ior:SI (ashift:SI (match_dup 0)
10546 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10547 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10548 (minus:QI (const_int 32) (match_dup 2)))))
10549 (clobber (reg:CC FLAGS_REG))]
10552 shld{l}\t{%2, %1, %0|%0, %1, %2}
10553 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10554 [(set_attr "type" "ishift")
10555 (set_attr "prefix_0f" "1")
10556 (set_attr "mode" "SI")
10557 (set_attr "pent_pair" "np")
10558 (set_attr "athlon_decode" "vector")])
10560 (define_expand "x86_shift_adj_1"
10561 [(set (reg:CCZ FLAGS_REG)
10562 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10565 (set (match_operand:SI 0 "register_operand" "")
10566 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10567 (match_operand:SI 1 "register_operand" "")
10570 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10571 (match_operand:SI 3 "register_operand" "r")
10576 (define_expand "x86_shift_adj_2"
10577 [(use (match_operand:SI 0 "register_operand" ""))
10578 (use (match_operand:SI 1 "register_operand" ""))
10579 (use (match_operand:QI 2 "register_operand" ""))]
10582 rtx label = gen_label_rtx ();
10585 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10587 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10588 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10589 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10590 gen_rtx_LABEL_REF (VOIDmode, label),
10592 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10593 JUMP_LABEL (tmp) = label;
10595 emit_move_insn (operands[0], operands[1]);
10596 ix86_expand_clear (operands[1]);
10598 emit_label (label);
10599 LABEL_NUSES (label) = 1;
10604 (define_expand "ashlsi3"
10605 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10606 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10607 (match_operand:QI 2 "nonmemory_operand" "")))
10608 (clobber (reg:CC FLAGS_REG))]
10610 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10612 (define_insn "*ashlsi3_1"
10613 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10614 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10615 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10616 (clobber (reg:CC FLAGS_REG))]
10617 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10619 switch (get_attr_type (insn))
10622 gcc_assert (operands[2] == const1_rtx);
10623 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10624 return "add{l}\t{%0, %0|%0, %0}";
10630 if (REG_P (operands[2]))
10631 return "sal{l}\t{%b2, %0|%0, %b2}";
10632 else if (operands[2] == const1_rtx
10633 && (TARGET_SHIFT1 || optimize_size))
10634 return "sal{l}\t%0";
10636 return "sal{l}\t{%2, %0|%0, %2}";
10639 [(set (attr "type")
10640 (cond [(eq_attr "alternative" "1")
10641 (const_string "lea")
10642 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10644 (match_operand 0 "register_operand" ""))
10645 (match_operand 2 "const1_operand" ""))
10646 (const_string "alu")
10648 (const_string "ishift")))
10649 (set_attr "mode" "SI")])
10651 ;; Convert lea to the lea pattern to avoid flags dependency.
10653 [(set (match_operand 0 "register_operand" "")
10654 (ashift (match_operand 1 "index_register_operand" "")
10655 (match_operand:QI 2 "const_int_operand" "")))
10656 (clobber (reg:CC FLAGS_REG))]
10658 && true_regnum (operands[0]) != true_regnum (operands[1])
10659 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10663 enum machine_mode mode = GET_MODE (operands[0]);
10665 if (GET_MODE_SIZE (mode) < 4)
10666 operands[0] = gen_lowpart (SImode, operands[0]);
10668 operands[1] = gen_lowpart (Pmode, operands[1]);
10669 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10671 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10672 if (Pmode != SImode)
10673 pat = gen_rtx_SUBREG (SImode, pat, 0);
10674 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10678 ;; Rare case of shifting RSP is handled by generating move and shift
10680 [(set (match_operand 0 "register_operand" "")
10681 (ashift (match_operand 1 "register_operand" "")
10682 (match_operand:QI 2 "const_int_operand" "")))
10683 (clobber (reg:CC FLAGS_REG))]
10685 && true_regnum (operands[0]) != true_regnum (operands[1])"
10689 emit_move_insn (operands[0], operands[1]);
10690 pat = gen_rtx_SET (VOIDmode, operands[0],
10691 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10692 operands[0], operands[2]));
10693 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10694 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10698 (define_insn "*ashlsi3_1_zext"
10699 [(set (match_operand:DI 0 "register_operand" "=r,r")
10700 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10701 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10702 (clobber (reg:CC FLAGS_REG))]
10703 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10705 switch (get_attr_type (insn))
10708 gcc_assert (operands[2] == const1_rtx);
10709 return "add{l}\t{%k0, %k0|%k0, %k0}";
10715 if (REG_P (operands[2]))
10716 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10717 else if (operands[2] == const1_rtx
10718 && (TARGET_SHIFT1 || optimize_size))
10719 return "sal{l}\t%k0";
10721 return "sal{l}\t{%2, %k0|%k0, %2}";
10724 [(set (attr "type")
10725 (cond [(eq_attr "alternative" "1")
10726 (const_string "lea")
10727 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10729 (match_operand 2 "const1_operand" ""))
10730 (const_string "alu")
10732 (const_string "ishift")))
10733 (set_attr "mode" "SI")])
10735 ;; Convert lea to the lea pattern to avoid flags dependency.
10737 [(set (match_operand:DI 0 "register_operand" "")
10738 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10739 (match_operand:QI 2 "const_int_operand" ""))))
10740 (clobber (reg:CC FLAGS_REG))]
10741 "TARGET_64BIT && reload_completed
10742 && true_regnum (operands[0]) != true_regnum (operands[1])"
10743 [(set (match_dup 0) (zero_extend:DI
10744 (subreg:SI (mult:SI (match_dup 1)
10745 (match_dup 2)) 0)))]
10747 operands[1] = gen_lowpart (Pmode, operands[1]);
10748 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10751 ;; This pattern can't accept a variable shift count, since shifts by
10752 ;; zero don't affect the flags. We assume that shifts by constant
10753 ;; zero are optimized away.
10754 (define_insn "*ashlsi3_cmp"
10755 [(set (reg FLAGS_REG)
10757 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10758 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10760 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10761 (ashift:SI (match_dup 1) (match_dup 2)))]
10762 "ix86_match_ccmode (insn, CCGOCmode)
10763 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10765 || !TARGET_PARTIAL_FLAG_REG_STALL
10766 || (operands[2] == const1_rtx
10768 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10770 switch (get_attr_type (insn))
10773 gcc_assert (operands[2] == const1_rtx);
10774 return "add{l}\t{%0, %0|%0, %0}";
10777 if (REG_P (operands[2]))
10778 return "sal{l}\t{%b2, %0|%0, %b2}";
10779 else if (operands[2] == const1_rtx
10780 && (TARGET_SHIFT1 || optimize_size))
10781 return "sal{l}\t%0";
10783 return "sal{l}\t{%2, %0|%0, %2}";
10786 [(set (attr "type")
10787 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10789 (match_operand 0 "register_operand" ""))
10790 (match_operand 2 "const1_operand" ""))
10791 (const_string "alu")
10793 (const_string "ishift")))
10794 (set_attr "mode" "SI")])
10796 (define_insn "*ashlsi3_cconly"
10797 [(set (reg FLAGS_REG)
10799 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10800 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10802 (clobber (match_scratch:SI 0 "=r"))]
10803 "ix86_match_ccmode (insn, CCGOCmode)
10804 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10806 || !TARGET_PARTIAL_FLAG_REG_STALL
10807 || (operands[2] == const1_rtx
10809 || TARGET_DOUBLE_WITH_ADD)))"
10811 switch (get_attr_type (insn))
10814 gcc_assert (operands[2] == const1_rtx);
10815 return "add{l}\t{%0, %0|%0, %0}";
10818 if (REG_P (operands[2]))
10819 return "sal{l}\t{%b2, %0|%0, %b2}";
10820 else if (operands[2] == const1_rtx
10821 && (TARGET_SHIFT1 || optimize_size))
10822 return "sal{l}\t%0";
10824 return "sal{l}\t{%2, %0|%0, %2}";
10827 [(set (attr "type")
10828 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10830 (match_operand 0 "register_operand" ""))
10831 (match_operand 2 "const1_operand" ""))
10832 (const_string "alu")
10834 (const_string "ishift")))
10835 (set_attr "mode" "SI")])
10837 (define_insn "*ashlsi3_cmp_zext"
10838 [(set (reg FLAGS_REG)
10840 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10841 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10843 (set (match_operand:DI 0 "register_operand" "=r")
10844 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10845 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10846 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10848 || !TARGET_PARTIAL_FLAG_REG_STALL
10849 || (operands[2] == const1_rtx
10851 || TARGET_DOUBLE_WITH_ADD)))"
10853 switch (get_attr_type (insn))
10856 gcc_assert (operands[2] == const1_rtx);
10857 return "add{l}\t{%k0, %k0|%k0, %k0}";
10860 if (REG_P (operands[2]))
10861 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10862 else if (operands[2] == const1_rtx
10863 && (TARGET_SHIFT1 || optimize_size))
10864 return "sal{l}\t%k0";
10866 return "sal{l}\t{%2, %k0|%k0, %2}";
10869 [(set (attr "type")
10870 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10872 (match_operand 2 "const1_operand" ""))
10873 (const_string "alu")
10875 (const_string "ishift")))
10876 (set_attr "mode" "SI")])
10878 (define_expand "ashlhi3"
10879 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10880 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10881 (match_operand:QI 2 "nonmemory_operand" "")))
10882 (clobber (reg:CC FLAGS_REG))]
10883 "TARGET_HIMODE_MATH"
10884 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10886 (define_insn "*ashlhi3_1_lea"
10887 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10888 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10889 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10890 (clobber (reg:CC FLAGS_REG))]
10891 "!TARGET_PARTIAL_REG_STALL
10892 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10894 switch (get_attr_type (insn))
10899 gcc_assert (operands[2] == const1_rtx);
10900 return "add{w}\t{%0, %0|%0, %0}";
10903 if (REG_P (operands[2]))
10904 return "sal{w}\t{%b2, %0|%0, %b2}";
10905 else if (operands[2] == const1_rtx
10906 && (TARGET_SHIFT1 || optimize_size))
10907 return "sal{w}\t%0";
10909 return "sal{w}\t{%2, %0|%0, %2}";
10912 [(set (attr "type")
10913 (cond [(eq_attr "alternative" "1")
10914 (const_string "lea")
10915 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10917 (match_operand 0 "register_operand" ""))
10918 (match_operand 2 "const1_operand" ""))
10919 (const_string "alu")
10921 (const_string "ishift")))
10922 (set_attr "mode" "HI,SI")])
10924 (define_insn "*ashlhi3_1"
10925 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10926 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10927 (match_operand:QI 2 "nonmemory_operand" "cI")))
10928 (clobber (reg:CC FLAGS_REG))]
10929 "TARGET_PARTIAL_REG_STALL
10930 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10932 switch (get_attr_type (insn))
10935 gcc_assert (operands[2] == const1_rtx);
10936 return "add{w}\t{%0, %0|%0, %0}";
10939 if (REG_P (operands[2]))
10940 return "sal{w}\t{%b2, %0|%0, %b2}";
10941 else if (operands[2] == const1_rtx
10942 && (TARGET_SHIFT1 || optimize_size))
10943 return "sal{w}\t%0";
10945 return "sal{w}\t{%2, %0|%0, %2}";
10948 [(set (attr "type")
10949 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10951 (match_operand 0 "register_operand" ""))
10952 (match_operand 2 "const1_operand" ""))
10953 (const_string "alu")
10955 (const_string "ishift")))
10956 (set_attr "mode" "HI")])
10958 ;; This pattern can't accept a variable shift count, since shifts by
10959 ;; zero don't affect the flags. We assume that shifts by constant
10960 ;; zero are optimized away.
10961 (define_insn "*ashlhi3_cmp"
10962 [(set (reg FLAGS_REG)
10964 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10965 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10967 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10968 (ashift:HI (match_dup 1) (match_dup 2)))]
10969 "ix86_match_ccmode (insn, CCGOCmode)
10970 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10972 || !TARGET_PARTIAL_FLAG_REG_STALL
10973 || (operands[2] == const1_rtx
10975 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10977 switch (get_attr_type (insn))
10980 gcc_assert (operands[2] == const1_rtx);
10981 return "add{w}\t{%0, %0|%0, %0}";
10984 if (REG_P (operands[2]))
10985 return "sal{w}\t{%b2, %0|%0, %b2}";
10986 else if (operands[2] == const1_rtx
10987 && (TARGET_SHIFT1 || optimize_size))
10988 return "sal{w}\t%0";
10990 return "sal{w}\t{%2, %0|%0, %2}";
10993 [(set (attr "type")
10994 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10996 (match_operand 0 "register_operand" ""))
10997 (match_operand 2 "const1_operand" ""))
10998 (const_string "alu")
11000 (const_string "ishift")))
11001 (set_attr "mode" "HI")])
11003 (define_insn "*ashlhi3_cconly"
11004 [(set (reg FLAGS_REG)
11006 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11007 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11009 (clobber (match_scratch:HI 0 "=r"))]
11010 "ix86_match_ccmode (insn, CCGOCmode)
11011 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11013 || !TARGET_PARTIAL_FLAG_REG_STALL
11014 || (operands[2] == const1_rtx
11016 || TARGET_DOUBLE_WITH_ADD)))"
11018 switch (get_attr_type (insn))
11021 gcc_assert (operands[2] == const1_rtx);
11022 return "add{w}\t{%0, %0|%0, %0}";
11025 if (REG_P (operands[2]))
11026 return "sal{w}\t{%b2, %0|%0, %b2}";
11027 else if (operands[2] == const1_rtx
11028 && (TARGET_SHIFT1 || optimize_size))
11029 return "sal{w}\t%0";
11031 return "sal{w}\t{%2, %0|%0, %2}";
11034 [(set (attr "type")
11035 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11037 (match_operand 0 "register_operand" ""))
11038 (match_operand 2 "const1_operand" ""))
11039 (const_string "alu")
11041 (const_string "ishift")))
11042 (set_attr "mode" "HI")])
11044 (define_expand "ashlqi3"
11045 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11046 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11047 (match_operand:QI 2 "nonmemory_operand" "")))
11048 (clobber (reg:CC FLAGS_REG))]
11049 "TARGET_QIMODE_MATH"
11050 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11052 ;; %%% Potential partial reg stall on alternative 2. What to do?
11054 (define_insn "*ashlqi3_1_lea"
11055 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11056 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11057 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11058 (clobber (reg:CC FLAGS_REG))]
11059 "!TARGET_PARTIAL_REG_STALL
11060 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11062 switch (get_attr_type (insn))
11067 gcc_assert (operands[2] == const1_rtx);
11068 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11069 return "add{l}\t{%k0, %k0|%k0, %k0}";
11071 return "add{b}\t{%0, %0|%0, %0}";
11074 if (REG_P (operands[2]))
11076 if (get_attr_mode (insn) == MODE_SI)
11077 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11079 return "sal{b}\t{%b2, %0|%0, %b2}";
11081 else if (operands[2] == const1_rtx
11082 && (TARGET_SHIFT1 || optimize_size))
11084 if (get_attr_mode (insn) == MODE_SI)
11085 return "sal{l}\t%0";
11087 return "sal{b}\t%0";
11091 if (get_attr_mode (insn) == MODE_SI)
11092 return "sal{l}\t{%2, %k0|%k0, %2}";
11094 return "sal{b}\t{%2, %0|%0, %2}";
11098 [(set (attr "type")
11099 (cond [(eq_attr "alternative" "2")
11100 (const_string "lea")
11101 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11103 (match_operand 0 "register_operand" ""))
11104 (match_operand 2 "const1_operand" ""))
11105 (const_string "alu")
11107 (const_string "ishift")))
11108 (set_attr "mode" "QI,SI,SI")])
11110 (define_insn "*ashlqi3_1"
11111 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11112 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11113 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11114 (clobber (reg:CC FLAGS_REG))]
11115 "TARGET_PARTIAL_REG_STALL
11116 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11118 switch (get_attr_type (insn))
11121 gcc_assert (operands[2] == const1_rtx);
11122 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11123 return "add{l}\t{%k0, %k0|%k0, %k0}";
11125 return "add{b}\t{%0, %0|%0, %0}";
11128 if (REG_P (operands[2]))
11130 if (get_attr_mode (insn) == MODE_SI)
11131 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11133 return "sal{b}\t{%b2, %0|%0, %b2}";
11135 else if (operands[2] == const1_rtx
11136 && (TARGET_SHIFT1 || optimize_size))
11138 if (get_attr_mode (insn) == MODE_SI)
11139 return "sal{l}\t%0";
11141 return "sal{b}\t%0";
11145 if (get_attr_mode (insn) == MODE_SI)
11146 return "sal{l}\t{%2, %k0|%k0, %2}";
11148 return "sal{b}\t{%2, %0|%0, %2}";
11152 [(set (attr "type")
11153 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11155 (match_operand 0 "register_operand" ""))
11156 (match_operand 2 "const1_operand" ""))
11157 (const_string "alu")
11159 (const_string "ishift")))
11160 (set_attr "mode" "QI,SI")])
11162 ;; This pattern can't accept a variable shift count, since shifts by
11163 ;; zero don't affect the flags. We assume that shifts by constant
11164 ;; zero are optimized away.
11165 (define_insn "*ashlqi3_cmp"
11166 [(set (reg FLAGS_REG)
11168 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11169 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11171 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11172 (ashift:QI (match_dup 1) (match_dup 2)))]
11173 "ix86_match_ccmode (insn, CCGOCmode)
11174 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11176 || !TARGET_PARTIAL_FLAG_REG_STALL
11177 || (operands[2] == const1_rtx
11179 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11181 switch (get_attr_type (insn))
11184 gcc_assert (operands[2] == const1_rtx);
11185 return "add{b}\t{%0, %0|%0, %0}";
11188 if (REG_P (operands[2]))
11189 return "sal{b}\t{%b2, %0|%0, %b2}";
11190 else if (operands[2] == const1_rtx
11191 && (TARGET_SHIFT1 || optimize_size))
11192 return "sal{b}\t%0";
11194 return "sal{b}\t{%2, %0|%0, %2}";
11197 [(set (attr "type")
11198 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11200 (match_operand 0 "register_operand" ""))
11201 (match_operand 2 "const1_operand" ""))
11202 (const_string "alu")
11204 (const_string "ishift")))
11205 (set_attr "mode" "QI")])
11207 (define_insn "*ashlqi3_cconly"
11208 [(set (reg FLAGS_REG)
11210 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11211 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11213 (clobber (match_scratch:QI 0 "=q"))]
11214 "ix86_match_ccmode (insn, CCGOCmode)
11215 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11217 || !TARGET_PARTIAL_FLAG_REG_STALL
11218 || (operands[2] == const1_rtx
11220 || TARGET_DOUBLE_WITH_ADD)))"
11222 switch (get_attr_type (insn))
11225 gcc_assert (operands[2] == const1_rtx);
11226 return "add{b}\t{%0, %0|%0, %0}";
11229 if (REG_P (operands[2]))
11230 return "sal{b}\t{%b2, %0|%0, %b2}";
11231 else if (operands[2] == const1_rtx
11232 && (TARGET_SHIFT1 || optimize_size))
11233 return "sal{b}\t%0";
11235 return "sal{b}\t{%2, %0|%0, %2}";
11238 [(set (attr "type")
11239 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11241 (match_operand 0 "register_operand" ""))
11242 (match_operand 2 "const1_operand" ""))
11243 (const_string "alu")
11245 (const_string "ishift")))
11246 (set_attr "mode" "QI")])
11248 ;; See comment above `ashldi3' about how this works.
11250 (define_expand "ashrti3"
11251 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11252 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11253 (match_operand:QI 2 "nonmemory_operand" "")))
11254 (clobber (reg:CC FLAGS_REG))])]
11257 if (! immediate_operand (operands[2], QImode))
11259 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11262 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11266 (define_insn "ashrti3_1"
11267 [(set (match_operand:TI 0 "register_operand" "=r")
11268 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11269 (match_operand:QI 2 "register_operand" "c")))
11270 (clobber (match_scratch:DI 3 "=&r"))
11271 (clobber (reg:CC FLAGS_REG))]
11274 [(set_attr "type" "multi")])
11276 (define_insn "*ashrti3_2"
11277 [(set (match_operand:TI 0 "register_operand" "=r")
11278 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11279 (match_operand:QI 2 "immediate_operand" "O")))
11280 (clobber (reg:CC FLAGS_REG))]
11283 [(set_attr "type" "multi")])
11286 [(set (match_operand:TI 0 "register_operand" "")
11287 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11288 (match_operand:QI 2 "register_operand" "")))
11289 (clobber (match_scratch:DI 3 ""))
11290 (clobber (reg:CC FLAGS_REG))]
11291 "TARGET_64BIT && reload_completed"
11293 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11296 [(set (match_operand:TI 0 "register_operand" "")
11297 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11298 (match_operand:QI 2 "immediate_operand" "")))
11299 (clobber (reg:CC FLAGS_REG))]
11300 "TARGET_64BIT && reload_completed"
11302 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11304 (define_insn "x86_64_shrd"
11305 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11306 (ior:DI (ashiftrt:DI (match_dup 0)
11307 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11308 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11309 (minus:QI (const_int 64) (match_dup 2)))))
11310 (clobber (reg:CC FLAGS_REG))]
11313 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11314 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11315 [(set_attr "type" "ishift")
11316 (set_attr "prefix_0f" "1")
11317 (set_attr "mode" "DI")
11318 (set_attr "athlon_decode" "vector")])
11320 (define_expand "ashrdi3"
11321 [(set (match_operand:DI 0 "shiftdi_operand" "")
11322 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11323 (match_operand:QI 2 "nonmemory_operand" "")))]
11325 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11327 (define_insn "*ashrdi3_63_rex64"
11328 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11329 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11330 (match_operand:DI 2 "const_int_operand" "i,i")))
11331 (clobber (reg:CC FLAGS_REG))]
11332 "TARGET_64BIT && INTVAL (operands[2]) == 63
11333 && (TARGET_USE_CLTD || optimize_size)
11334 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11337 sar{q}\t{%2, %0|%0, %2}"
11338 [(set_attr "type" "imovx,ishift")
11339 (set_attr "prefix_0f" "0,*")
11340 (set_attr "length_immediate" "0,*")
11341 (set_attr "modrm" "0,1")
11342 (set_attr "mode" "DI")])
11344 (define_insn "*ashrdi3_1_one_bit_rex64"
11345 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11346 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11347 (match_operand:QI 2 "const1_operand" "")))
11348 (clobber (reg:CC FLAGS_REG))]
11349 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11350 && (TARGET_SHIFT1 || optimize_size)"
11352 [(set_attr "type" "ishift")
11353 (set (attr "length")
11354 (if_then_else (match_operand:DI 0 "register_operand" "")
11356 (const_string "*")))])
11358 (define_insn "*ashrdi3_1_rex64"
11359 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11360 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11361 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11362 (clobber (reg:CC FLAGS_REG))]
11363 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11365 sar{q}\t{%2, %0|%0, %2}
11366 sar{q}\t{%b2, %0|%0, %b2}"
11367 [(set_attr "type" "ishift")
11368 (set_attr "mode" "DI")])
11370 ;; This pattern can't accept a variable shift count, since shifts by
11371 ;; zero don't affect the flags. We assume that shifts by constant
11372 ;; zero are optimized away.
11373 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11374 [(set (reg FLAGS_REG)
11376 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11377 (match_operand:QI 2 "const1_operand" ""))
11379 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11380 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11381 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11382 && (TARGET_SHIFT1 || optimize_size)
11383 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11385 [(set_attr "type" "ishift")
11386 (set (attr "length")
11387 (if_then_else (match_operand:DI 0 "register_operand" "")
11389 (const_string "*")))])
11391 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11392 [(set (reg FLAGS_REG)
11394 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11395 (match_operand:QI 2 "const1_operand" ""))
11397 (clobber (match_scratch:DI 0 "=r"))]
11398 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11399 && (TARGET_SHIFT1 || optimize_size)
11400 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11402 [(set_attr "type" "ishift")
11403 (set_attr "length" "2")])
11405 ;; This pattern can't accept a variable shift count, since shifts by
11406 ;; zero don't affect the flags. We assume that shifts by constant
11407 ;; zero are optimized away.
11408 (define_insn "*ashrdi3_cmp_rex64"
11409 [(set (reg FLAGS_REG)
11411 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11412 (match_operand:QI 2 "const_int_operand" "n"))
11414 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11415 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11416 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11417 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11419 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11420 "sar{q}\t{%2, %0|%0, %2}"
11421 [(set_attr "type" "ishift")
11422 (set_attr "mode" "DI")])
11424 (define_insn "*ashrdi3_cconly_rex64"
11425 [(set (reg FLAGS_REG)
11427 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11428 (match_operand:QI 2 "const_int_operand" "n"))
11430 (clobber (match_scratch:DI 0 "=r"))]
11431 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11432 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11434 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11435 "sar{q}\t{%2, %0|%0, %2}"
11436 [(set_attr "type" "ishift")
11437 (set_attr "mode" "DI")])
11439 (define_insn "*ashrdi3_1"
11440 [(set (match_operand:DI 0 "register_operand" "=r")
11441 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11442 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11443 (clobber (reg:CC FLAGS_REG))]
11446 [(set_attr "type" "multi")])
11448 ;; By default we don't ask for a scratch register, because when DImode
11449 ;; values are manipulated, registers are already at a premium. But if
11450 ;; we have one handy, we won't turn it away.
11452 [(match_scratch:SI 3 "r")
11453 (parallel [(set (match_operand:DI 0 "register_operand" "")
11454 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11455 (match_operand:QI 2 "nonmemory_operand" "")))
11456 (clobber (reg:CC FLAGS_REG))])
11458 "!TARGET_64BIT && TARGET_CMOVE"
11460 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11463 [(set (match_operand:DI 0 "register_operand" "")
11464 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11465 (match_operand:QI 2 "nonmemory_operand" "")))
11466 (clobber (reg:CC FLAGS_REG))]
11467 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11468 ? flow2_completed : reload_completed)"
11470 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11472 (define_insn "x86_shrd_1"
11473 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11474 (ior:SI (ashiftrt:SI (match_dup 0)
11475 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11476 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11477 (minus:QI (const_int 32) (match_dup 2)))))
11478 (clobber (reg:CC FLAGS_REG))]
11481 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11482 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11483 [(set_attr "type" "ishift")
11484 (set_attr "prefix_0f" "1")
11485 (set_attr "pent_pair" "np")
11486 (set_attr "mode" "SI")])
11488 (define_expand "x86_shift_adj_3"
11489 [(use (match_operand:SI 0 "register_operand" ""))
11490 (use (match_operand:SI 1 "register_operand" ""))
11491 (use (match_operand:QI 2 "register_operand" ""))]
11494 rtx label = gen_label_rtx ();
11497 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11499 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11500 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11501 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11502 gen_rtx_LABEL_REF (VOIDmode, label),
11504 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11505 JUMP_LABEL (tmp) = label;
11507 emit_move_insn (operands[0], operands[1]);
11508 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11510 emit_label (label);
11511 LABEL_NUSES (label) = 1;
11516 (define_insn "ashrsi3_31"
11517 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11518 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11519 (match_operand:SI 2 "const_int_operand" "i,i")))
11520 (clobber (reg:CC FLAGS_REG))]
11521 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11522 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11525 sar{l}\t{%2, %0|%0, %2}"
11526 [(set_attr "type" "imovx,ishift")
11527 (set_attr "prefix_0f" "0,*")
11528 (set_attr "length_immediate" "0,*")
11529 (set_attr "modrm" "0,1")
11530 (set_attr "mode" "SI")])
11532 (define_insn "*ashrsi3_31_zext"
11533 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11534 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11535 (match_operand:SI 2 "const_int_operand" "i,i"))))
11536 (clobber (reg:CC FLAGS_REG))]
11537 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11538 && INTVAL (operands[2]) == 31
11539 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11542 sar{l}\t{%2, %k0|%k0, %2}"
11543 [(set_attr "type" "imovx,ishift")
11544 (set_attr "prefix_0f" "0,*")
11545 (set_attr "length_immediate" "0,*")
11546 (set_attr "modrm" "0,1")
11547 (set_attr "mode" "SI")])
11549 (define_expand "ashrsi3"
11550 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11551 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11552 (match_operand:QI 2 "nonmemory_operand" "")))
11553 (clobber (reg:CC FLAGS_REG))]
11555 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11557 (define_insn "*ashrsi3_1_one_bit"
11558 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11559 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11560 (match_operand:QI 2 "const1_operand" "")))
11561 (clobber (reg:CC FLAGS_REG))]
11562 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11563 && (TARGET_SHIFT1 || optimize_size)"
11565 [(set_attr "type" "ishift")
11566 (set (attr "length")
11567 (if_then_else (match_operand:SI 0 "register_operand" "")
11569 (const_string "*")))])
11571 (define_insn "*ashrsi3_1_one_bit_zext"
11572 [(set (match_operand:DI 0 "register_operand" "=r")
11573 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11574 (match_operand:QI 2 "const1_operand" ""))))
11575 (clobber (reg:CC FLAGS_REG))]
11576 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11577 && (TARGET_SHIFT1 || optimize_size)"
11579 [(set_attr "type" "ishift")
11580 (set_attr "length" "2")])
11582 (define_insn "*ashrsi3_1"
11583 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11584 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11585 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11586 (clobber (reg:CC FLAGS_REG))]
11587 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11589 sar{l}\t{%2, %0|%0, %2}
11590 sar{l}\t{%b2, %0|%0, %b2}"
11591 [(set_attr "type" "ishift")
11592 (set_attr "mode" "SI")])
11594 (define_insn "*ashrsi3_1_zext"
11595 [(set (match_operand:DI 0 "register_operand" "=r,r")
11596 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11597 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11598 (clobber (reg:CC FLAGS_REG))]
11599 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11601 sar{l}\t{%2, %k0|%k0, %2}
11602 sar{l}\t{%b2, %k0|%k0, %b2}"
11603 [(set_attr "type" "ishift")
11604 (set_attr "mode" "SI")])
11606 ;; This pattern can't accept a variable shift count, since shifts by
11607 ;; zero don't affect the flags. We assume that shifts by constant
11608 ;; zero are optimized away.
11609 (define_insn "*ashrsi3_one_bit_cmp"
11610 [(set (reg FLAGS_REG)
11612 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11613 (match_operand:QI 2 "const1_operand" ""))
11615 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11616 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11617 "ix86_match_ccmode (insn, CCGOCmode)
11618 && (TARGET_SHIFT1 || optimize_size)
11619 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11621 [(set_attr "type" "ishift")
11622 (set (attr "length")
11623 (if_then_else (match_operand:SI 0 "register_operand" "")
11625 (const_string "*")))])
11627 (define_insn "*ashrsi3_one_bit_cconly"
11628 [(set (reg FLAGS_REG)
11630 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11631 (match_operand:QI 2 "const1_operand" ""))
11633 (clobber (match_scratch:SI 0 "=r"))]
11634 "ix86_match_ccmode (insn, CCGOCmode)
11635 && (TARGET_SHIFT1 || optimize_size)
11636 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11638 [(set_attr "type" "ishift")
11639 (set_attr "length" "2")])
11641 (define_insn "*ashrsi3_one_bit_cmp_zext"
11642 [(set (reg FLAGS_REG)
11644 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11645 (match_operand:QI 2 "const1_operand" ""))
11647 (set (match_operand:DI 0 "register_operand" "=r")
11648 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11649 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11650 && (TARGET_SHIFT1 || optimize_size)
11651 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11653 [(set_attr "type" "ishift")
11654 (set_attr "length" "2")])
11656 ;; This pattern can't accept a variable shift count, since shifts by
11657 ;; zero don't affect the flags. We assume that shifts by constant
11658 ;; zero are optimized away.
11659 (define_insn "*ashrsi3_cmp"
11660 [(set (reg FLAGS_REG)
11662 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11663 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11665 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11666 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11667 "ix86_match_ccmode (insn, CCGOCmode)
11668 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11670 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11671 "sar{l}\t{%2, %0|%0, %2}"
11672 [(set_attr "type" "ishift")
11673 (set_attr "mode" "SI")])
11675 (define_insn "*ashrsi3_cconly"
11676 [(set (reg FLAGS_REG)
11678 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11679 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11681 (clobber (match_scratch:SI 0 "=r"))]
11682 "ix86_match_ccmode (insn, CCGOCmode)
11683 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11685 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11686 "sar{l}\t{%2, %0|%0, %2}"
11687 [(set_attr "type" "ishift")
11688 (set_attr "mode" "SI")])
11690 (define_insn "*ashrsi3_cmp_zext"
11691 [(set (reg FLAGS_REG)
11693 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11694 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11696 (set (match_operand:DI 0 "register_operand" "=r")
11697 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11698 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11699 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11701 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11702 "sar{l}\t{%2, %k0|%k0, %2}"
11703 [(set_attr "type" "ishift")
11704 (set_attr "mode" "SI")])
11706 (define_expand "ashrhi3"
11707 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11708 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11709 (match_operand:QI 2 "nonmemory_operand" "")))
11710 (clobber (reg:CC FLAGS_REG))]
11711 "TARGET_HIMODE_MATH"
11712 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11714 (define_insn "*ashrhi3_1_one_bit"
11715 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11716 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11717 (match_operand:QI 2 "const1_operand" "")))
11718 (clobber (reg:CC FLAGS_REG))]
11719 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11720 && (TARGET_SHIFT1 || optimize_size)"
11722 [(set_attr "type" "ishift")
11723 (set (attr "length")
11724 (if_then_else (match_operand 0 "register_operand" "")
11726 (const_string "*")))])
11728 (define_insn "*ashrhi3_1"
11729 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11730 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11731 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11732 (clobber (reg:CC FLAGS_REG))]
11733 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11735 sar{w}\t{%2, %0|%0, %2}
11736 sar{w}\t{%b2, %0|%0, %b2}"
11737 [(set_attr "type" "ishift")
11738 (set_attr "mode" "HI")])
11740 ;; This pattern can't accept a variable shift count, since shifts by
11741 ;; zero don't affect the flags. We assume that shifts by constant
11742 ;; zero are optimized away.
11743 (define_insn "*ashrhi3_one_bit_cmp"
11744 [(set (reg FLAGS_REG)
11746 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11747 (match_operand:QI 2 "const1_operand" ""))
11749 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11750 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11751 "ix86_match_ccmode (insn, CCGOCmode)
11752 && (TARGET_SHIFT1 || optimize_size)
11753 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11755 [(set_attr "type" "ishift")
11756 (set (attr "length")
11757 (if_then_else (match_operand 0 "register_operand" "")
11759 (const_string "*")))])
11761 (define_insn "*ashrhi3_one_bit_cconly"
11762 [(set (reg FLAGS_REG)
11764 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11765 (match_operand:QI 2 "const1_operand" ""))
11767 (clobber (match_scratch:HI 0 "=r"))]
11768 "ix86_match_ccmode (insn, CCGOCmode)
11769 && (TARGET_SHIFT1 || optimize_size)
11770 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11772 [(set_attr "type" "ishift")
11773 (set_attr "length" "2")])
11775 ;; This pattern can't accept a variable shift count, since shifts by
11776 ;; zero don't affect the flags. We assume that shifts by constant
11777 ;; zero are optimized away.
11778 (define_insn "*ashrhi3_cmp"
11779 [(set (reg FLAGS_REG)
11781 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11782 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11784 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11785 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11786 "ix86_match_ccmode (insn, CCGOCmode)
11787 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11789 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11790 "sar{w}\t{%2, %0|%0, %2}"
11791 [(set_attr "type" "ishift")
11792 (set_attr "mode" "HI")])
11794 (define_insn "*ashrhi3_cconly"
11795 [(set (reg FLAGS_REG)
11797 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11798 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11800 (clobber (match_scratch:HI 0 "=r"))]
11801 "ix86_match_ccmode (insn, CCGOCmode)
11802 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11804 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11805 "sar{w}\t{%2, %0|%0, %2}"
11806 [(set_attr "type" "ishift")
11807 (set_attr "mode" "HI")])
11809 (define_expand "ashrqi3"
11810 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11811 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11812 (match_operand:QI 2 "nonmemory_operand" "")))
11813 (clobber (reg:CC FLAGS_REG))]
11814 "TARGET_QIMODE_MATH"
11815 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11817 (define_insn "*ashrqi3_1_one_bit"
11818 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11819 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11820 (match_operand:QI 2 "const1_operand" "")))
11821 (clobber (reg:CC FLAGS_REG))]
11822 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11823 && (TARGET_SHIFT1 || optimize_size)"
11825 [(set_attr "type" "ishift")
11826 (set (attr "length")
11827 (if_then_else (match_operand 0 "register_operand" "")
11829 (const_string "*")))])
11831 (define_insn "*ashrqi3_1_one_bit_slp"
11832 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11833 (ashiftrt:QI (match_dup 0)
11834 (match_operand:QI 1 "const1_operand" "")))
11835 (clobber (reg:CC FLAGS_REG))]
11836 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11837 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11838 && (TARGET_SHIFT1 || optimize_size)"
11840 [(set_attr "type" "ishift1")
11841 (set (attr "length")
11842 (if_then_else (match_operand 0 "register_operand" "")
11844 (const_string "*")))])
11846 (define_insn "*ashrqi3_1"
11847 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11848 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11849 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11850 (clobber (reg:CC FLAGS_REG))]
11851 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11853 sar{b}\t{%2, %0|%0, %2}
11854 sar{b}\t{%b2, %0|%0, %b2}"
11855 [(set_attr "type" "ishift")
11856 (set_attr "mode" "QI")])
11858 (define_insn "*ashrqi3_1_slp"
11859 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11860 (ashiftrt:QI (match_dup 0)
11861 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11862 (clobber (reg:CC FLAGS_REG))]
11863 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11864 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11866 sar{b}\t{%1, %0|%0, %1}
11867 sar{b}\t{%b1, %0|%0, %b1}"
11868 [(set_attr "type" "ishift1")
11869 (set_attr "mode" "QI")])
11871 ;; This pattern can't accept a variable shift count, since shifts by
11872 ;; zero don't affect the flags. We assume that shifts by constant
11873 ;; zero are optimized away.
11874 (define_insn "*ashrqi3_one_bit_cmp"
11875 [(set (reg FLAGS_REG)
11877 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11878 (match_operand:QI 2 "const1_operand" "I"))
11880 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11881 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11882 "ix86_match_ccmode (insn, CCGOCmode)
11883 && (TARGET_SHIFT1 || optimize_size)
11884 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11886 [(set_attr "type" "ishift")
11887 (set (attr "length")
11888 (if_then_else (match_operand 0 "register_operand" "")
11890 (const_string "*")))])
11892 (define_insn "*ashrqi3_one_bit_cconly"
11893 [(set (reg FLAGS_REG)
11895 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11896 (match_operand:QI 2 "const1_operand" "I"))
11898 (clobber (match_scratch:QI 0 "=q"))]
11899 "ix86_match_ccmode (insn, CCGOCmode)
11900 && (TARGET_SHIFT1 || optimize_size)
11901 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11903 [(set_attr "type" "ishift")
11904 (set_attr "length" "2")])
11906 ;; This pattern can't accept a variable shift count, since shifts by
11907 ;; zero don't affect the flags. We assume that shifts by constant
11908 ;; zero are optimized away.
11909 (define_insn "*ashrqi3_cmp"
11910 [(set (reg FLAGS_REG)
11912 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11913 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11915 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11916 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11917 "ix86_match_ccmode (insn, CCGOCmode)
11918 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11920 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11921 "sar{b}\t{%2, %0|%0, %2}"
11922 [(set_attr "type" "ishift")
11923 (set_attr "mode" "QI")])
11925 (define_insn "*ashrqi3_cconly"
11926 [(set (reg FLAGS_REG)
11928 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11929 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11931 (clobber (match_scratch:QI 0 "=q"))]
11932 "ix86_match_ccmode (insn, CCGOCmode)
11933 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11935 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11936 "sar{b}\t{%2, %0|%0, %2}"
11937 [(set_attr "type" "ishift")
11938 (set_attr "mode" "QI")])
11941 ;; Logical shift instructions
11943 ;; See comment above `ashldi3' about how this works.
11945 (define_expand "lshrti3"
11946 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11947 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11948 (match_operand:QI 2 "nonmemory_operand" "")))
11949 (clobber (reg:CC FLAGS_REG))])]
11952 if (! immediate_operand (operands[2], QImode))
11954 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11957 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11961 (define_insn "lshrti3_1"
11962 [(set (match_operand:TI 0 "register_operand" "=r")
11963 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11964 (match_operand:QI 2 "register_operand" "c")))
11965 (clobber (match_scratch:DI 3 "=&r"))
11966 (clobber (reg:CC FLAGS_REG))]
11969 [(set_attr "type" "multi")])
11971 (define_insn "*lshrti3_2"
11972 [(set (match_operand:TI 0 "register_operand" "=r")
11973 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11974 (match_operand:QI 2 "immediate_operand" "O")))
11975 (clobber (reg:CC FLAGS_REG))]
11978 [(set_attr "type" "multi")])
11981 [(set (match_operand:TI 0 "register_operand" "")
11982 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11983 (match_operand:QI 2 "register_operand" "")))
11984 (clobber (match_scratch:DI 3 ""))
11985 (clobber (reg:CC FLAGS_REG))]
11986 "TARGET_64BIT && reload_completed"
11988 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11991 [(set (match_operand:TI 0 "register_operand" "")
11992 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11993 (match_operand:QI 2 "immediate_operand" "")))
11994 (clobber (reg:CC FLAGS_REG))]
11995 "TARGET_64BIT && reload_completed"
11997 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11999 (define_expand "lshrdi3"
12000 [(set (match_operand:DI 0 "shiftdi_operand" "")
12001 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12002 (match_operand:QI 2 "nonmemory_operand" "")))]
12004 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12006 (define_insn "*lshrdi3_1_one_bit_rex64"
12007 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12008 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12009 (match_operand:QI 2 "const1_operand" "")))
12010 (clobber (reg:CC FLAGS_REG))]
12011 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12012 && (TARGET_SHIFT1 || optimize_size)"
12014 [(set_attr "type" "ishift")
12015 (set (attr "length")
12016 (if_then_else (match_operand:DI 0 "register_operand" "")
12018 (const_string "*")))])
12020 (define_insn "*lshrdi3_1_rex64"
12021 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12022 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12023 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12024 (clobber (reg:CC FLAGS_REG))]
12025 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12027 shr{q}\t{%2, %0|%0, %2}
12028 shr{q}\t{%b2, %0|%0, %b2}"
12029 [(set_attr "type" "ishift")
12030 (set_attr "mode" "DI")])
12032 ;; This pattern can't accept a variable shift count, since shifts by
12033 ;; zero don't affect the flags. We assume that shifts by constant
12034 ;; zero are optimized away.
12035 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12036 [(set (reg FLAGS_REG)
12038 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12039 (match_operand:QI 2 "const1_operand" ""))
12041 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12042 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12043 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12044 && (TARGET_SHIFT1 || optimize_size)
12045 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12047 [(set_attr "type" "ishift")
12048 (set (attr "length")
12049 (if_then_else (match_operand:DI 0 "register_operand" "")
12051 (const_string "*")))])
12053 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12054 [(set (reg FLAGS_REG)
12056 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12057 (match_operand:QI 2 "const1_operand" ""))
12059 (clobber (match_scratch:DI 0 "=r"))]
12060 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12061 && (TARGET_SHIFT1 || optimize_size)
12062 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12064 [(set_attr "type" "ishift")
12065 (set_attr "length" "2")])
12067 ;; This pattern can't accept a variable shift count, since shifts by
12068 ;; zero don't affect the flags. We assume that shifts by constant
12069 ;; zero are optimized away.
12070 (define_insn "*lshrdi3_cmp_rex64"
12071 [(set (reg FLAGS_REG)
12073 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12074 (match_operand:QI 2 "const_int_operand" "e"))
12076 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12077 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12078 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12079 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12081 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12082 "shr{q}\t{%2, %0|%0, %2}"
12083 [(set_attr "type" "ishift")
12084 (set_attr "mode" "DI")])
12086 (define_insn "*lshrdi3_cconly_rex64"
12087 [(set (reg FLAGS_REG)
12089 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12090 (match_operand:QI 2 "const_int_operand" "e"))
12092 (clobber (match_scratch:DI 0 "=r"))]
12093 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12094 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12096 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12097 "shr{q}\t{%2, %0|%0, %2}"
12098 [(set_attr "type" "ishift")
12099 (set_attr "mode" "DI")])
12101 (define_insn "*lshrdi3_1"
12102 [(set (match_operand:DI 0 "register_operand" "=r")
12103 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12104 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12105 (clobber (reg:CC FLAGS_REG))]
12108 [(set_attr "type" "multi")])
12110 ;; By default we don't ask for a scratch register, because when DImode
12111 ;; values are manipulated, registers are already at a premium. But if
12112 ;; we have one handy, we won't turn it away.
12114 [(match_scratch:SI 3 "r")
12115 (parallel [(set (match_operand:DI 0 "register_operand" "")
12116 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12117 (match_operand:QI 2 "nonmemory_operand" "")))
12118 (clobber (reg:CC FLAGS_REG))])
12120 "!TARGET_64BIT && TARGET_CMOVE"
12122 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12125 [(set (match_operand:DI 0 "register_operand" "")
12126 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12127 (match_operand:QI 2 "nonmemory_operand" "")))
12128 (clobber (reg:CC FLAGS_REG))]
12129 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12130 ? flow2_completed : reload_completed)"
12132 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12134 (define_expand "lshrsi3"
12135 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12136 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12137 (match_operand:QI 2 "nonmemory_operand" "")))
12138 (clobber (reg:CC FLAGS_REG))]
12140 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12142 (define_insn "*lshrsi3_1_one_bit"
12143 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12144 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12145 (match_operand:QI 2 "const1_operand" "")))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12148 && (TARGET_SHIFT1 || optimize_size)"
12150 [(set_attr "type" "ishift")
12151 (set (attr "length")
12152 (if_then_else (match_operand:SI 0 "register_operand" "")
12154 (const_string "*")))])
12156 (define_insn "*lshrsi3_1_one_bit_zext"
12157 [(set (match_operand:DI 0 "register_operand" "=r")
12158 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12159 (match_operand:QI 2 "const1_operand" "")))
12160 (clobber (reg:CC FLAGS_REG))]
12161 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12162 && (TARGET_SHIFT1 || optimize_size)"
12164 [(set_attr "type" "ishift")
12165 (set_attr "length" "2")])
12167 (define_insn "*lshrsi3_1"
12168 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12169 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12170 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12171 (clobber (reg:CC FLAGS_REG))]
12172 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12174 shr{l}\t{%2, %0|%0, %2}
12175 shr{l}\t{%b2, %0|%0, %b2}"
12176 [(set_attr "type" "ishift")
12177 (set_attr "mode" "SI")])
12179 (define_insn "*lshrsi3_1_zext"
12180 [(set (match_operand:DI 0 "register_operand" "=r,r")
12182 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12183 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12184 (clobber (reg:CC FLAGS_REG))]
12185 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12187 shr{l}\t{%2, %k0|%k0, %2}
12188 shr{l}\t{%b2, %k0|%k0, %b2}"
12189 [(set_attr "type" "ishift")
12190 (set_attr "mode" "SI")])
12192 ;; This pattern can't accept a variable shift count, since shifts by
12193 ;; zero don't affect the flags. We assume that shifts by constant
12194 ;; zero are optimized away.
12195 (define_insn "*lshrsi3_one_bit_cmp"
12196 [(set (reg FLAGS_REG)
12198 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12199 (match_operand:QI 2 "const1_operand" ""))
12201 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12202 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12203 "ix86_match_ccmode (insn, CCGOCmode)
12204 && (TARGET_SHIFT1 || optimize_size)
12205 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12207 [(set_attr "type" "ishift")
12208 (set (attr "length")
12209 (if_then_else (match_operand:SI 0 "register_operand" "")
12211 (const_string "*")))])
12213 (define_insn "*lshrsi3_one_bit_cconly"
12214 [(set (reg FLAGS_REG)
12216 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12217 (match_operand:QI 2 "const1_operand" ""))
12219 (clobber (match_scratch:SI 0 "=r"))]
12220 "ix86_match_ccmode (insn, CCGOCmode)
12221 && (TARGET_SHIFT1 || optimize_size)
12222 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12224 [(set_attr "type" "ishift")
12225 (set_attr "length" "2")])
12227 (define_insn "*lshrsi3_cmp_one_bit_zext"
12228 [(set (reg FLAGS_REG)
12230 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12231 (match_operand:QI 2 "const1_operand" ""))
12233 (set (match_operand:DI 0 "register_operand" "=r")
12234 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12235 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12236 && (TARGET_SHIFT1 || optimize_size)
12237 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12239 [(set_attr "type" "ishift")
12240 (set_attr "length" "2")])
12242 ;; This pattern can't accept a variable shift count, since shifts by
12243 ;; zero don't affect the flags. We assume that shifts by constant
12244 ;; zero are optimized away.
12245 (define_insn "*lshrsi3_cmp"
12246 [(set (reg FLAGS_REG)
12248 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12249 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12251 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12252 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12253 "ix86_match_ccmode (insn, CCGOCmode)
12254 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12256 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12257 "shr{l}\t{%2, %0|%0, %2}"
12258 [(set_attr "type" "ishift")
12259 (set_attr "mode" "SI")])
12261 (define_insn "*lshrsi3_cconly"
12262 [(set (reg FLAGS_REG)
12264 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12265 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12267 (clobber (match_scratch:SI 0 "=r"))]
12268 "ix86_match_ccmode (insn, CCGOCmode)
12269 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12271 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12272 "shr{l}\t{%2, %0|%0, %2}"
12273 [(set_attr "type" "ishift")
12274 (set_attr "mode" "SI")])
12276 (define_insn "*lshrsi3_cmp_zext"
12277 [(set (reg FLAGS_REG)
12279 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12280 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12282 (set (match_operand:DI 0 "register_operand" "=r")
12283 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12284 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12285 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12287 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12288 "shr{l}\t{%2, %k0|%k0, %2}"
12289 [(set_attr "type" "ishift")
12290 (set_attr "mode" "SI")])
12292 (define_expand "lshrhi3"
12293 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12294 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12295 (match_operand:QI 2 "nonmemory_operand" "")))
12296 (clobber (reg:CC FLAGS_REG))]
12297 "TARGET_HIMODE_MATH"
12298 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12300 (define_insn "*lshrhi3_1_one_bit"
12301 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12302 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12303 (match_operand:QI 2 "const1_operand" "")))
12304 (clobber (reg:CC FLAGS_REG))]
12305 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12306 && (TARGET_SHIFT1 || optimize_size)"
12308 [(set_attr "type" "ishift")
12309 (set (attr "length")
12310 (if_then_else (match_operand 0 "register_operand" "")
12312 (const_string "*")))])
12314 (define_insn "*lshrhi3_1"
12315 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12316 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12317 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12318 (clobber (reg:CC FLAGS_REG))]
12319 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12321 shr{w}\t{%2, %0|%0, %2}
12322 shr{w}\t{%b2, %0|%0, %b2}"
12323 [(set_attr "type" "ishift")
12324 (set_attr "mode" "HI")])
12326 ;; This pattern can't accept a variable shift count, since shifts by
12327 ;; zero don't affect the flags. We assume that shifts by constant
12328 ;; zero are optimized away.
12329 (define_insn "*lshrhi3_one_bit_cmp"
12330 [(set (reg FLAGS_REG)
12332 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12333 (match_operand:QI 2 "const1_operand" ""))
12335 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12336 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12337 "ix86_match_ccmode (insn, CCGOCmode)
12338 && (TARGET_SHIFT1 || optimize_size)
12339 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12341 [(set_attr "type" "ishift")
12342 (set (attr "length")
12343 (if_then_else (match_operand:SI 0 "register_operand" "")
12345 (const_string "*")))])
12347 (define_insn "*lshrhi3_one_bit_cconly"
12348 [(set (reg FLAGS_REG)
12350 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12351 (match_operand:QI 2 "const1_operand" ""))
12353 (clobber (match_scratch:HI 0 "=r"))]
12354 "ix86_match_ccmode (insn, CCGOCmode)
12355 && (TARGET_SHIFT1 || optimize_size)
12356 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12358 [(set_attr "type" "ishift")
12359 (set_attr "length" "2")])
12361 ;; This pattern can't accept a variable shift count, since shifts by
12362 ;; zero don't affect the flags. We assume that shifts by constant
12363 ;; zero are optimized away.
12364 (define_insn "*lshrhi3_cmp"
12365 [(set (reg FLAGS_REG)
12367 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12370 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12371 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12372 "ix86_match_ccmode (insn, CCGOCmode)
12373 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12375 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12376 "shr{w}\t{%2, %0|%0, %2}"
12377 [(set_attr "type" "ishift")
12378 (set_attr "mode" "HI")])
12380 (define_insn "*lshrhi3_cconly"
12381 [(set (reg FLAGS_REG)
12383 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12384 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12386 (clobber (match_scratch:HI 0 "=r"))]
12387 "ix86_match_ccmode (insn, CCGOCmode)
12388 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12390 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12391 "shr{w}\t{%2, %0|%0, %2}"
12392 [(set_attr "type" "ishift")
12393 (set_attr "mode" "HI")])
12395 (define_expand "lshrqi3"
12396 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12397 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12398 (match_operand:QI 2 "nonmemory_operand" "")))
12399 (clobber (reg:CC FLAGS_REG))]
12400 "TARGET_QIMODE_MATH"
12401 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12403 (define_insn "*lshrqi3_1_one_bit"
12404 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12405 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12406 (match_operand:QI 2 "const1_operand" "")))
12407 (clobber (reg:CC FLAGS_REG))]
12408 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12409 && (TARGET_SHIFT1 || optimize_size)"
12411 [(set_attr "type" "ishift")
12412 (set (attr "length")
12413 (if_then_else (match_operand 0 "register_operand" "")
12415 (const_string "*")))])
12417 (define_insn "*lshrqi3_1_one_bit_slp"
12418 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12419 (lshiftrt:QI (match_dup 0)
12420 (match_operand:QI 1 "const1_operand" "")))
12421 (clobber (reg:CC FLAGS_REG))]
12422 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12423 && (TARGET_SHIFT1 || optimize_size)"
12425 [(set_attr "type" "ishift1")
12426 (set (attr "length")
12427 (if_then_else (match_operand 0 "register_operand" "")
12429 (const_string "*")))])
12431 (define_insn "*lshrqi3_1"
12432 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12433 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12434 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12435 (clobber (reg:CC FLAGS_REG))]
12436 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12438 shr{b}\t{%2, %0|%0, %2}
12439 shr{b}\t{%b2, %0|%0, %b2}"
12440 [(set_attr "type" "ishift")
12441 (set_attr "mode" "QI")])
12443 (define_insn "*lshrqi3_1_slp"
12444 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12445 (lshiftrt:QI (match_dup 0)
12446 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12447 (clobber (reg:CC FLAGS_REG))]
12448 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12449 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12451 shr{b}\t{%1, %0|%0, %1}
12452 shr{b}\t{%b1, %0|%0, %b1}"
12453 [(set_attr "type" "ishift1")
12454 (set_attr "mode" "QI")])
12456 ;; This pattern can't accept a variable shift count, since shifts by
12457 ;; zero don't affect the flags. We assume that shifts by constant
12458 ;; zero are optimized away.
12459 (define_insn "*lshrqi2_one_bit_cmp"
12460 [(set (reg FLAGS_REG)
12462 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12463 (match_operand:QI 2 "const1_operand" ""))
12465 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12466 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12467 "ix86_match_ccmode (insn, CCGOCmode)
12468 && (TARGET_SHIFT1 || optimize_size)
12469 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12471 [(set_attr "type" "ishift")
12472 (set (attr "length")
12473 (if_then_else (match_operand:SI 0 "register_operand" "")
12475 (const_string "*")))])
12477 (define_insn "*lshrqi2_one_bit_cconly"
12478 [(set (reg FLAGS_REG)
12480 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12481 (match_operand:QI 2 "const1_operand" ""))
12483 (clobber (match_scratch:QI 0 "=q"))]
12484 "ix86_match_ccmode (insn, CCGOCmode)
12485 && (TARGET_SHIFT1 || optimize_size)
12486 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12488 [(set_attr "type" "ishift")
12489 (set_attr "length" "2")])
12491 ;; This pattern can't accept a variable shift count, since shifts by
12492 ;; zero don't affect the flags. We assume that shifts by constant
12493 ;; zero are optimized away.
12494 (define_insn "*lshrqi2_cmp"
12495 [(set (reg FLAGS_REG)
12497 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12498 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12500 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12501 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12502 "ix86_match_ccmode (insn, CCGOCmode)
12503 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12505 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12506 "shr{b}\t{%2, %0|%0, %2}"
12507 [(set_attr "type" "ishift")
12508 (set_attr "mode" "QI")])
12510 (define_insn "*lshrqi2_cconly"
12511 [(set (reg FLAGS_REG)
12513 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12514 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12516 (clobber (match_scratch:QI 0 "=q"))]
12517 "ix86_match_ccmode (insn, CCGOCmode)
12518 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12520 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12521 "shr{b}\t{%2, %0|%0, %2}"
12522 [(set_attr "type" "ishift")
12523 (set_attr "mode" "QI")])
12525 ;; Rotate instructions
12527 (define_expand "rotldi3"
12528 [(set (match_operand:DI 0 "shiftdi_operand" "")
12529 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12530 (match_operand:QI 2 "nonmemory_operand" "")))
12531 (clobber (reg:CC FLAGS_REG))]
12536 ix86_expand_binary_operator (ROTATE, DImode, operands);
12539 if (!const_1_to_31_operand (operands[2], VOIDmode))
12541 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12545 ;; Implement rotation using two double-precision shift instructions
12546 ;; and a scratch register.
12547 (define_insn_and_split "ix86_rotldi3"
12548 [(set (match_operand:DI 0 "register_operand" "=r")
12549 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12550 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12551 (clobber (reg:CC FLAGS_REG))
12552 (clobber (match_scratch:SI 3 "=&r"))]
12555 "&& reload_completed"
12556 [(set (match_dup 3) (match_dup 4))
12558 [(set (match_dup 4)
12559 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12560 (lshiftrt:SI (match_dup 5)
12561 (minus:QI (const_int 32) (match_dup 2)))))
12562 (clobber (reg:CC FLAGS_REG))])
12564 [(set (match_dup 5)
12565 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12566 (lshiftrt:SI (match_dup 3)
12567 (minus:QI (const_int 32) (match_dup 2)))))
12568 (clobber (reg:CC FLAGS_REG))])]
12569 "split_di (operands, 1, operands + 4, operands + 5);")
12571 (define_insn "*rotlsi3_1_one_bit_rex64"
12572 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12573 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12574 (match_operand:QI 2 "const1_operand" "")))
12575 (clobber (reg:CC FLAGS_REG))]
12576 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12577 && (TARGET_SHIFT1 || optimize_size)"
12579 [(set_attr "type" "rotate")
12580 (set (attr "length")
12581 (if_then_else (match_operand:DI 0 "register_operand" "")
12583 (const_string "*")))])
12585 (define_insn "*rotldi3_1_rex64"
12586 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12587 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12588 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12589 (clobber (reg:CC FLAGS_REG))]
12590 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12592 rol{q}\t{%2, %0|%0, %2}
12593 rol{q}\t{%b2, %0|%0, %b2}"
12594 [(set_attr "type" "rotate")
12595 (set_attr "mode" "DI")])
12597 (define_expand "rotlsi3"
12598 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12599 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12600 (match_operand:QI 2 "nonmemory_operand" "")))
12601 (clobber (reg:CC FLAGS_REG))]
12603 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12605 (define_insn "*rotlsi3_1_one_bit"
12606 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12607 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12608 (match_operand:QI 2 "const1_operand" "")))
12609 (clobber (reg:CC FLAGS_REG))]
12610 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12611 && (TARGET_SHIFT1 || optimize_size)"
12613 [(set_attr "type" "rotate")
12614 (set (attr "length")
12615 (if_then_else (match_operand:SI 0 "register_operand" "")
12617 (const_string "*")))])
12619 (define_insn "*rotlsi3_1_one_bit_zext"
12620 [(set (match_operand:DI 0 "register_operand" "=r")
12622 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12623 (match_operand:QI 2 "const1_operand" ""))))
12624 (clobber (reg:CC FLAGS_REG))]
12625 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12626 && (TARGET_SHIFT1 || optimize_size)"
12628 [(set_attr "type" "rotate")
12629 (set_attr "length" "2")])
12631 (define_insn "*rotlsi3_1"
12632 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12633 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12634 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12635 (clobber (reg:CC FLAGS_REG))]
12636 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12638 rol{l}\t{%2, %0|%0, %2}
12639 rol{l}\t{%b2, %0|%0, %b2}"
12640 [(set_attr "type" "rotate")
12641 (set_attr "mode" "SI")])
12643 (define_insn "*rotlsi3_1_zext"
12644 [(set (match_operand:DI 0 "register_operand" "=r,r")
12646 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12647 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12648 (clobber (reg:CC FLAGS_REG))]
12649 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12651 rol{l}\t{%2, %k0|%k0, %2}
12652 rol{l}\t{%b2, %k0|%k0, %b2}"
12653 [(set_attr "type" "rotate")
12654 (set_attr "mode" "SI")])
12656 (define_expand "rotlhi3"
12657 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12658 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12659 (match_operand:QI 2 "nonmemory_operand" "")))
12660 (clobber (reg:CC FLAGS_REG))]
12661 "TARGET_HIMODE_MATH"
12662 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12664 (define_insn "*rotlhi3_1_one_bit"
12665 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12666 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12667 (match_operand:QI 2 "const1_operand" "")))
12668 (clobber (reg:CC FLAGS_REG))]
12669 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12670 && (TARGET_SHIFT1 || optimize_size)"
12672 [(set_attr "type" "rotate")
12673 (set (attr "length")
12674 (if_then_else (match_operand 0 "register_operand" "")
12676 (const_string "*")))])
12678 (define_insn "*rotlhi3_1"
12679 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12680 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12681 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12682 (clobber (reg:CC FLAGS_REG))]
12683 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12685 rol{w}\t{%2, %0|%0, %2}
12686 rol{w}\t{%b2, %0|%0, %b2}"
12687 [(set_attr "type" "rotate")
12688 (set_attr "mode" "HI")])
12690 (define_expand "rotlqi3"
12691 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12692 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12693 (match_operand:QI 2 "nonmemory_operand" "")))
12694 (clobber (reg:CC FLAGS_REG))]
12695 "TARGET_QIMODE_MATH"
12696 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12698 (define_insn "*rotlqi3_1_one_bit_slp"
12699 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12700 (rotate:QI (match_dup 0)
12701 (match_operand:QI 1 "const1_operand" "")))
12702 (clobber (reg:CC FLAGS_REG))]
12703 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12704 && (TARGET_SHIFT1 || optimize_size)"
12706 [(set_attr "type" "rotate1")
12707 (set (attr "length")
12708 (if_then_else (match_operand 0 "register_operand" "")
12710 (const_string "*")))])
12712 (define_insn "*rotlqi3_1_one_bit"
12713 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12714 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12715 (match_operand:QI 2 "const1_operand" "")))
12716 (clobber (reg:CC FLAGS_REG))]
12717 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12718 && (TARGET_SHIFT1 || optimize_size)"
12720 [(set_attr "type" "rotate")
12721 (set (attr "length")
12722 (if_then_else (match_operand 0 "register_operand" "")
12724 (const_string "*")))])
12726 (define_insn "*rotlqi3_1_slp"
12727 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12728 (rotate:QI (match_dup 0)
12729 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12730 (clobber (reg:CC FLAGS_REG))]
12731 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12732 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12734 rol{b}\t{%1, %0|%0, %1}
12735 rol{b}\t{%b1, %0|%0, %b1}"
12736 [(set_attr "type" "rotate1")
12737 (set_attr "mode" "QI")])
12739 (define_insn "*rotlqi3_1"
12740 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12741 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12742 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12743 (clobber (reg:CC FLAGS_REG))]
12744 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12746 rol{b}\t{%2, %0|%0, %2}
12747 rol{b}\t{%b2, %0|%0, %b2}"
12748 [(set_attr "type" "rotate")
12749 (set_attr "mode" "QI")])
12751 (define_expand "rotrdi3"
12752 [(set (match_operand:DI 0 "shiftdi_operand" "")
12753 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12754 (match_operand:QI 2 "nonmemory_operand" "")))
12755 (clobber (reg:CC FLAGS_REG))]
12760 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12763 if (!const_1_to_31_operand (operands[2], VOIDmode))
12765 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12769 ;; Implement rotation using two double-precision shift instructions
12770 ;; and a scratch register.
12771 (define_insn_and_split "ix86_rotrdi3"
12772 [(set (match_operand:DI 0 "register_operand" "=r")
12773 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12774 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12775 (clobber (reg:CC FLAGS_REG))
12776 (clobber (match_scratch:SI 3 "=&r"))]
12779 "&& reload_completed"
12780 [(set (match_dup 3) (match_dup 4))
12782 [(set (match_dup 4)
12783 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12784 (ashift:SI (match_dup 5)
12785 (minus:QI (const_int 32) (match_dup 2)))))
12786 (clobber (reg:CC FLAGS_REG))])
12788 [(set (match_dup 5)
12789 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12790 (ashift:SI (match_dup 3)
12791 (minus:QI (const_int 32) (match_dup 2)))))
12792 (clobber (reg:CC FLAGS_REG))])]
12793 "split_di (operands, 1, operands + 4, operands + 5);")
12795 (define_insn "*rotrdi3_1_one_bit_rex64"
12796 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12797 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12798 (match_operand:QI 2 "const1_operand" "")))
12799 (clobber (reg:CC FLAGS_REG))]
12800 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12801 && (TARGET_SHIFT1 || optimize_size)"
12803 [(set_attr "type" "rotate")
12804 (set (attr "length")
12805 (if_then_else (match_operand:DI 0 "register_operand" "")
12807 (const_string "*")))])
12809 (define_insn "*rotrdi3_1_rex64"
12810 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12811 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12812 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12813 (clobber (reg:CC FLAGS_REG))]
12814 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12816 ror{q}\t{%2, %0|%0, %2}
12817 ror{q}\t{%b2, %0|%0, %b2}"
12818 [(set_attr "type" "rotate")
12819 (set_attr "mode" "DI")])
12821 (define_expand "rotrsi3"
12822 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12823 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12824 (match_operand:QI 2 "nonmemory_operand" "")))
12825 (clobber (reg:CC FLAGS_REG))]
12827 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12829 (define_insn "*rotrsi3_1_one_bit"
12830 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12831 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12832 (match_operand:QI 2 "const1_operand" "")))
12833 (clobber (reg:CC FLAGS_REG))]
12834 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12835 && (TARGET_SHIFT1 || optimize_size)"
12837 [(set_attr "type" "rotate")
12838 (set (attr "length")
12839 (if_then_else (match_operand:SI 0 "register_operand" "")
12841 (const_string "*")))])
12843 (define_insn "*rotrsi3_1_one_bit_zext"
12844 [(set (match_operand:DI 0 "register_operand" "=r")
12846 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12847 (match_operand:QI 2 "const1_operand" ""))))
12848 (clobber (reg:CC FLAGS_REG))]
12849 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12850 && (TARGET_SHIFT1 || optimize_size)"
12852 [(set_attr "type" "rotate")
12853 (set (attr "length")
12854 (if_then_else (match_operand:SI 0 "register_operand" "")
12856 (const_string "*")))])
12858 (define_insn "*rotrsi3_1"
12859 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12860 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12861 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12862 (clobber (reg:CC FLAGS_REG))]
12863 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12865 ror{l}\t{%2, %0|%0, %2}
12866 ror{l}\t{%b2, %0|%0, %b2}"
12867 [(set_attr "type" "rotate")
12868 (set_attr "mode" "SI")])
12870 (define_insn "*rotrsi3_1_zext"
12871 [(set (match_operand:DI 0 "register_operand" "=r,r")
12873 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12874 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12875 (clobber (reg:CC FLAGS_REG))]
12876 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12878 ror{l}\t{%2, %k0|%k0, %2}
12879 ror{l}\t{%b2, %k0|%k0, %b2}"
12880 [(set_attr "type" "rotate")
12881 (set_attr "mode" "SI")])
12883 (define_expand "rotrhi3"
12884 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12885 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12886 (match_operand:QI 2 "nonmemory_operand" "")))
12887 (clobber (reg:CC FLAGS_REG))]
12888 "TARGET_HIMODE_MATH"
12889 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12891 (define_insn "*rotrhi3_one_bit"
12892 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12893 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12894 (match_operand:QI 2 "const1_operand" "")))
12895 (clobber (reg:CC FLAGS_REG))]
12896 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12897 && (TARGET_SHIFT1 || optimize_size)"
12899 [(set_attr "type" "rotate")
12900 (set (attr "length")
12901 (if_then_else (match_operand 0 "register_operand" "")
12903 (const_string "*")))])
12905 (define_insn "*rotrhi3"
12906 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12907 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12908 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12909 (clobber (reg:CC FLAGS_REG))]
12910 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12912 ror{w}\t{%2, %0|%0, %2}
12913 ror{w}\t{%b2, %0|%0, %b2}"
12914 [(set_attr "type" "rotate")
12915 (set_attr "mode" "HI")])
12917 (define_expand "rotrqi3"
12918 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12919 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12920 (match_operand:QI 2 "nonmemory_operand" "")))
12921 (clobber (reg:CC FLAGS_REG))]
12922 "TARGET_QIMODE_MATH"
12923 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12925 (define_insn "*rotrqi3_1_one_bit"
12926 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12927 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12928 (match_operand:QI 2 "const1_operand" "")))
12929 (clobber (reg:CC FLAGS_REG))]
12930 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12931 && (TARGET_SHIFT1 || optimize_size)"
12933 [(set_attr "type" "rotate")
12934 (set (attr "length")
12935 (if_then_else (match_operand 0 "register_operand" "")
12937 (const_string "*")))])
12939 (define_insn "*rotrqi3_1_one_bit_slp"
12940 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12941 (rotatert:QI (match_dup 0)
12942 (match_operand:QI 1 "const1_operand" "")))
12943 (clobber (reg:CC FLAGS_REG))]
12944 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12945 && (TARGET_SHIFT1 || optimize_size)"
12947 [(set_attr "type" "rotate1")
12948 (set (attr "length")
12949 (if_then_else (match_operand 0 "register_operand" "")
12951 (const_string "*")))])
12953 (define_insn "*rotrqi3_1"
12954 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12955 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12956 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12957 (clobber (reg:CC FLAGS_REG))]
12958 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12960 ror{b}\t{%2, %0|%0, %2}
12961 ror{b}\t{%b2, %0|%0, %b2}"
12962 [(set_attr "type" "rotate")
12963 (set_attr "mode" "QI")])
12965 (define_insn "*rotrqi3_1_slp"
12966 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12967 (rotatert:QI (match_dup 0)
12968 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12969 (clobber (reg:CC FLAGS_REG))]
12970 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12971 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12973 ror{b}\t{%1, %0|%0, %1}
12974 ror{b}\t{%b1, %0|%0, %b1}"
12975 [(set_attr "type" "rotate1")
12976 (set_attr "mode" "QI")])
12978 ;; Bit set / bit test instructions
12980 (define_expand "extv"
12981 [(set (match_operand:SI 0 "register_operand" "")
12982 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12983 (match_operand:SI 2 "const8_operand" "")
12984 (match_operand:SI 3 "const8_operand" "")))]
12987 /* Handle extractions from %ah et al. */
12988 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12991 /* From mips.md: extract_bit_field doesn't verify that our source
12992 matches the predicate, so check it again here. */
12993 if (! ext_register_operand (operands[1], VOIDmode))
12997 (define_expand "extzv"
12998 [(set (match_operand:SI 0 "register_operand" "")
12999 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13000 (match_operand:SI 2 "const8_operand" "")
13001 (match_operand:SI 3 "const8_operand" "")))]
13004 /* Handle extractions from %ah et al. */
13005 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13008 /* From mips.md: extract_bit_field doesn't verify that our source
13009 matches the predicate, so check it again here. */
13010 if (! ext_register_operand (operands[1], VOIDmode))
13014 (define_expand "insv"
13015 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13016 (match_operand 1 "const8_operand" "")
13017 (match_operand 2 "const8_operand" ""))
13018 (match_operand 3 "register_operand" ""))]
13021 /* Handle insertions to %ah et al. */
13022 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13025 /* From mips.md: insert_bit_field doesn't verify that our source
13026 matches the predicate, so check it again here. */
13027 if (! ext_register_operand (operands[0], VOIDmode))
13031 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13033 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13038 ;; %%% bts, btr, btc, bt.
13039 ;; In general these instructions are *slow* when applied to memory,
13040 ;; since they enforce atomic operation. When applied to registers,
13041 ;; it depends on the cpu implementation. They're never faster than
13042 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13043 ;; no point. But in 64-bit, we can't hold the relevant immediates
13044 ;; within the instruction itself, so operating on bits in the high
13045 ;; 32-bits of a register becomes easier.
13047 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13048 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13049 ;; negdf respectively, so they can never be disabled entirely.
13051 (define_insn "*btsq"
13052 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13054 (match_operand:DI 1 "const_0_to_63_operand" ""))
13056 (clobber (reg:CC FLAGS_REG))]
13057 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13059 [(set_attr "type" "alu1")])
13061 (define_insn "*btrq"
13062 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13064 (match_operand:DI 1 "const_0_to_63_operand" ""))
13066 (clobber (reg:CC FLAGS_REG))]
13067 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13069 [(set_attr "type" "alu1")])
13071 (define_insn "*btcq"
13072 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13074 (match_operand:DI 1 "const_0_to_63_operand" ""))
13075 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13076 (clobber (reg:CC FLAGS_REG))]
13077 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13079 [(set_attr "type" "alu1")])
13081 ;; Allow Nocona to avoid these instructions if a register is available.
13084 [(match_scratch:DI 2 "r")
13085 (parallel [(set (zero_extract:DI
13086 (match_operand:DI 0 "register_operand" "")
13088 (match_operand:DI 1 "const_0_to_63_operand" ""))
13090 (clobber (reg:CC FLAGS_REG))])]
13091 "TARGET_64BIT && !TARGET_USE_BT"
13094 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13097 if (HOST_BITS_PER_WIDE_INT >= 64)
13098 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13099 else if (i < HOST_BITS_PER_WIDE_INT)
13100 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13102 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13104 op1 = immed_double_const (lo, hi, DImode);
13107 emit_move_insn (operands[2], op1);
13111 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13116 [(match_scratch:DI 2 "r")
13117 (parallel [(set (zero_extract:DI
13118 (match_operand:DI 0 "register_operand" "")
13120 (match_operand:DI 1 "const_0_to_63_operand" ""))
13122 (clobber (reg:CC FLAGS_REG))])]
13123 "TARGET_64BIT && !TARGET_USE_BT"
13126 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13129 if (HOST_BITS_PER_WIDE_INT >= 64)
13130 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13131 else if (i < HOST_BITS_PER_WIDE_INT)
13132 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13134 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13136 op1 = immed_double_const (~lo, ~hi, DImode);
13139 emit_move_insn (operands[2], op1);
13143 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13148 [(match_scratch:DI 2 "r")
13149 (parallel [(set (zero_extract:DI
13150 (match_operand:DI 0 "register_operand" "")
13152 (match_operand:DI 1 "const_0_to_63_operand" ""))
13153 (not:DI (zero_extract:DI
13154 (match_dup 0) (const_int 1) (match_dup 1))))
13155 (clobber (reg:CC FLAGS_REG))])]
13156 "TARGET_64BIT && !TARGET_USE_BT"
13159 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13162 if (HOST_BITS_PER_WIDE_INT >= 64)
13163 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13164 else if (i < HOST_BITS_PER_WIDE_INT)
13165 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13167 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13169 op1 = immed_double_const (lo, hi, DImode);
13172 emit_move_insn (operands[2], op1);
13176 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13180 ;; Store-flag instructions.
13182 ;; For all sCOND expanders, also expand the compare or test insn that
13183 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13185 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13186 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13187 ;; way, which can later delete the movzx if only QImode is needed.
13189 (define_expand "seq"
13190 [(set (match_operand:QI 0 "register_operand" "")
13191 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13193 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13195 (define_expand "sne"
13196 [(set (match_operand:QI 0 "register_operand" "")
13197 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13199 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13201 (define_expand "sgt"
13202 [(set (match_operand:QI 0 "register_operand" "")
13203 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13205 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13207 (define_expand "sgtu"
13208 [(set (match_operand:QI 0 "register_operand" "")
13209 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13211 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13213 (define_expand "slt"
13214 [(set (match_operand:QI 0 "register_operand" "")
13215 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13217 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13219 (define_expand "sltu"
13220 [(set (match_operand:QI 0 "register_operand" "")
13221 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13223 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13225 (define_expand "sge"
13226 [(set (match_operand:QI 0 "register_operand" "")
13227 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13229 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13231 (define_expand "sgeu"
13232 [(set (match_operand:QI 0 "register_operand" "")
13233 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13235 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13237 (define_expand "sle"
13238 [(set (match_operand:QI 0 "register_operand" "")
13239 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13241 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13243 (define_expand "sleu"
13244 [(set (match_operand:QI 0 "register_operand" "")
13245 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13247 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13249 (define_expand "sunordered"
13250 [(set (match_operand:QI 0 "register_operand" "")
13251 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13252 "TARGET_80387 || TARGET_SSE"
13253 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13255 (define_expand "sordered"
13256 [(set (match_operand:QI 0 "register_operand" "")
13257 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13259 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13261 (define_expand "suneq"
13262 [(set (match_operand:QI 0 "register_operand" "")
13263 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13264 "TARGET_80387 || TARGET_SSE"
13265 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13267 (define_expand "sunge"
13268 [(set (match_operand:QI 0 "register_operand" "")
13269 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13270 "TARGET_80387 || TARGET_SSE"
13271 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13273 (define_expand "sungt"
13274 [(set (match_operand:QI 0 "register_operand" "")
13275 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13276 "TARGET_80387 || TARGET_SSE"
13277 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13279 (define_expand "sunle"
13280 [(set (match_operand:QI 0 "register_operand" "")
13281 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13282 "TARGET_80387 || TARGET_SSE"
13283 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13285 (define_expand "sunlt"
13286 [(set (match_operand:QI 0 "register_operand" "")
13287 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13288 "TARGET_80387 || TARGET_SSE"
13289 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13291 (define_expand "sltgt"
13292 [(set (match_operand:QI 0 "register_operand" "")
13293 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13294 "TARGET_80387 || TARGET_SSE"
13295 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13297 (define_insn "*setcc_1"
13298 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13299 (match_operator:QI 1 "ix86_comparison_operator"
13300 [(reg FLAGS_REG) (const_int 0)]))]
13303 [(set_attr "type" "setcc")
13304 (set_attr "mode" "QI")])
13306 (define_insn "*setcc_2"
13307 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13308 (match_operator:QI 1 "ix86_comparison_operator"
13309 [(reg FLAGS_REG) (const_int 0)]))]
13312 [(set_attr "type" "setcc")
13313 (set_attr "mode" "QI")])
13315 ;; In general it is not safe to assume too much about CCmode registers,
13316 ;; so simplify-rtx stops when it sees a second one. Under certain
13317 ;; conditions this is safe on x86, so help combine not create
13324 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13325 (ne:QI (match_operator 1 "ix86_comparison_operator"
13326 [(reg FLAGS_REG) (const_int 0)])
13329 [(set (match_dup 0) (match_dup 1))]
13331 PUT_MODE (operands[1], QImode);
13335 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13336 (ne:QI (match_operator 1 "ix86_comparison_operator"
13337 [(reg FLAGS_REG) (const_int 0)])
13340 [(set (match_dup 0) (match_dup 1))]
13342 PUT_MODE (operands[1], QImode);
13346 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13347 (eq:QI (match_operator 1 "ix86_comparison_operator"
13348 [(reg FLAGS_REG) (const_int 0)])
13351 [(set (match_dup 0) (match_dup 1))]
13353 rtx new_op1 = copy_rtx (operands[1]);
13354 operands[1] = new_op1;
13355 PUT_MODE (new_op1, QImode);
13356 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13357 GET_MODE (XEXP (new_op1, 0))));
13359 /* Make sure that (a) the CCmode we have for the flags is strong
13360 enough for the reversed compare or (b) we have a valid FP compare. */
13361 if (! ix86_comparison_operator (new_op1, VOIDmode))
13366 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13367 (eq:QI (match_operator 1 "ix86_comparison_operator"
13368 [(reg FLAGS_REG) (const_int 0)])
13371 [(set (match_dup 0) (match_dup 1))]
13373 rtx new_op1 = copy_rtx (operands[1]);
13374 operands[1] = new_op1;
13375 PUT_MODE (new_op1, QImode);
13376 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13377 GET_MODE (XEXP (new_op1, 0))));
13379 /* Make sure that (a) the CCmode we have for the flags is strong
13380 enough for the reversed compare or (b) we have a valid FP compare. */
13381 if (! ix86_comparison_operator (new_op1, VOIDmode))
13385 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13386 ;; subsequent logical operations are used to imitate conditional moves.
13387 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13390 (define_insn "*sse_setccsf"
13391 [(set (match_operand:SF 0 "register_operand" "=x")
13392 (match_operator:SF 1 "sse_comparison_operator"
13393 [(match_operand:SF 2 "register_operand" "0")
13394 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13396 "cmp%D1ss\t{%3, %0|%0, %3}"
13397 [(set_attr "type" "ssecmp")
13398 (set_attr "mode" "SF")])
13400 (define_insn "*sse_setccdf"
13401 [(set (match_operand:DF 0 "register_operand" "=Y")
13402 (match_operator:DF 1 "sse_comparison_operator"
13403 [(match_operand:DF 2 "register_operand" "0")
13404 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13406 "cmp%D1sd\t{%3, %0|%0, %3}"
13407 [(set_attr "type" "ssecmp")
13408 (set_attr "mode" "DF")])
13410 ;; Basic conditional jump instructions.
13411 ;; We ignore the overflow flag for signed branch instructions.
13413 ;; For all bCOND expanders, also expand the compare or test insn that
13414 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13416 (define_expand "beq"
13418 (if_then_else (match_dup 1)
13419 (label_ref (match_operand 0 "" ""))
13422 "ix86_expand_branch (EQ, operands[0]); DONE;")
13424 (define_expand "bne"
13426 (if_then_else (match_dup 1)
13427 (label_ref (match_operand 0 "" ""))
13430 "ix86_expand_branch (NE, operands[0]); DONE;")
13432 (define_expand "bgt"
13434 (if_then_else (match_dup 1)
13435 (label_ref (match_operand 0 "" ""))
13438 "ix86_expand_branch (GT, operands[0]); DONE;")
13440 (define_expand "bgtu"
13442 (if_then_else (match_dup 1)
13443 (label_ref (match_operand 0 "" ""))
13446 "ix86_expand_branch (GTU, operands[0]); DONE;")
13448 (define_expand "blt"
13450 (if_then_else (match_dup 1)
13451 (label_ref (match_operand 0 "" ""))
13454 "ix86_expand_branch (LT, operands[0]); DONE;")
13456 (define_expand "bltu"
13458 (if_then_else (match_dup 1)
13459 (label_ref (match_operand 0 "" ""))
13462 "ix86_expand_branch (LTU, operands[0]); DONE;")
13464 (define_expand "bge"
13466 (if_then_else (match_dup 1)
13467 (label_ref (match_operand 0 "" ""))
13470 "ix86_expand_branch (GE, operands[0]); DONE;")
13472 (define_expand "bgeu"
13474 (if_then_else (match_dup 1)
13475 (label_ref (match_operand 0 "" ""))
13478 "ix86_expand_branch (GEU, operands[0]); DONE;")
13480 (define_expand "ble"
13482 (if_then_else (match_dup 1)
13483 (label_ref (match_operand 0 "" ""))
13486 "ix86_expand_branch (LE, operands[0]); DONE;")
13488 (define_expand "bleu"
13490 (if_then_else (match_dup 1)
13491 (label_ref (match_operand 0 "" ""))
13494 "ix86_expand_branch (LEU, operands[0]); DONE;")
13496 (define_expand "bunordered"
13498 (if_then_else (match_dup 1)
13499 (label_ref (match_operand 0 "" ""))
13501 "TARGET_80387 || TARGET_SSE_MATH"
13502 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13504 (define_expand "bordered"
13506 (if_then_else (match_dup 1)
13507 (label_ref (match_operand 0 "" ""))
13509 "TARGET_80387 || TARGET_SSE_MATH"
13510 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13512 (define_expand "buneq"
13514 (if_then_else (match_dup 1)
13515 (label_ref (match_operand 0 "" ""))
13517 "TARGET_80387 || TARGET_SSE_MATH"
13518 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13520 (define_expand "bunge"
13522 (if_then_else (match_dup 1)
13523 (label_ref (match_operand 0 "" ""))
13525 "TARGET_80387 || TARGET_SSE_MATH"
13526 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13528 (define_expand "bungt"
13530 (if_then_else (match_dup 1)
13531 (label_ref (match_operand 0 "" ""))
13533 "TARGET_80387 || TARGET_SSE_MATH"
13534 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13536 (define_expand "bunle"
13538 (if_then_else (match_dup 1)
13539 (label_ref (match_operand 0 "" ""))
13541 "TARGET_80387 || TARGET_SSE_MATH"
13542 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13544 (define_expand "bunlt"
13546 (if_then_else (match_dup 1)
13547 (label_ref (match_operand 0 "" ""))
13549 "TARGET_80387 || TARGET_SSE_MATH"
13550 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13552 (define_expand "bltgt"
13554 (if_then_else (match_dup 1)
13555 (label_ref (match_operand 0 "" ""))
13557 "TARGET_80387 || TARGET_SSE_MATH"
13558 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13560 (define_insn "*jcc_1"
13562 (if_then_else (match_operator 1 "ix86_comparison_operator"
13563 [(reg FLAGS_REG) (const_int 0)])
13564 (label_ref (match_operand 0 "" ""))
13568 [(set_attr "type" "ibr")
13569 (set_attr "modrm" "0")
13570 (set (attr "length")
13571 (if_then_else (and (ge (minus (match_dup 0) (pc))
13573 (lt (minus (match_dup 0) (pc))
13578 (define_insn "*jcc_2"
13580 (if_then_else (match_operator 1 "ix86_comparison_operator"
13581 [(reg FLAGS_REG) (const_int 0)])
13583 (label_ref (match_operand 0 "" ""))))]
13586 [(set_attr "type" "ibr")
13587 (set_attr "modrm" "0")
13588 (set (attr "length")
13589 (if_then_else (and (ge (minus (match_dup 0) (pc))
13591 (lt (minus (match_dup 0) (pc))
13596 ;; In general it is not safe to assume too much about CCmode registers,
13597 ;; so simplify-rtx stops when it sees a second one. Under certain
13598 ;; conditions this is safe on x86, so help combine not create
13606 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13607 [(reg FLAGS_REG) (const_int 0)])
13609 (label_ref (match_operand 1 "" ""))
13613 (if_then_else (match_dup 0)
13614 (label_ref (match_dup 1))
13617 PUT_MODE (operands[0], VOIDmode);
13622 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13623 [(reg FLAGS_REG) (const_int 0)])
13625 (label_ref (match_operand 1 "" ""))
13629 (if_then_else (match_dup 0)
13630 (label_ref (match_dup 1))
13633 rtx new_op0 = copy_rtx (operands[0]);
13634 operands[0] = new_op0;
13635 PUT_MODE (new_op0, VOIDmode);
13636 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13637 GET_MODE (XEXP (new_op0, 0))));
13639 /* Make sure that (a) the CCmode we have for the flags is strong
13640 enough for the reversed compare or (b) we have a valid FP compare. */
13641 if (! ix86_comparison_operator (new_op0, VOIDmode))
13645 ;; Define combination compare-and-branch fp compare instructions to use
13646 ;; during early optimization. Splitting the operation apart early makes
13647 ;; for bad code when we want to reverse the operation.
13649 (define_insn "*fp_jcc_1_mixed"
13651 (if_then_else (match_operator 0 "comparison_operator"
13652 [(match_operand 1 "register_operand" "f,x")
13653 (match_operand 2 "nonimmediate_operand" "f,xm")])
13654 (label_ref (match_operand 3 "" ""))
13656 (clobber (reg:CCFP FPSR_REG))
13657 (clobber (reg:CCFP FLAGS_REG))]
13658 "TARGET_MIX_SSE_I387
13659 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13660 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13661 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13664 (define_insn "*fp_jcc_1_sse"
13666 (if_then_else (match_operator 0 "comparison_operator"
13667 [(match_operand 1 "register_operand" "x")
13668 (match_operand 2 "nonimmediate_operand" "xm")])
13669 (label_ref (match_operand 3 "" ""))
13671 (clobber (reg:CCFP FPSR_REG))
13672 (clobber (reg:CCFP FLAGS_REG))]
13674 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13675 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13676 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13679 (define_insn "*fp_jcc_1_387"
13681 (if_then_else (match_operator 0 "comparison_operator"
13682 [(match_operand 1 "register_operand" "f")
13683 (match_operand 2 "register_operand" "f")])
13684 (label_ref (match_operand 3 "" ""))
13686 (clobber (reg:CCFP FPSR_REG))
13687 (clobber (reg:CCFP FLAGS_REG))]
13688 "TARGET_CMOVE && TARGET_80387
13689 && FLOAT_MODE_P (GET_MODE (operands[1]))
13690 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13691 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13694 (define_insn "*fp_jcc_2_mixed"
13696 (if_then_else (match_operator 0 "comparison_operator"
13697 [(match_operand 1 "register_operand" "f,x")
13698 (match_operand 2 "nonimmediate_operand" "f,xm")])
13700 (label_ref (match_operand 3 "" ""))))
13701 (clobber (reg:CCFP FPSR_REG))
13702 (clobber (reg:CCFP FLAGS_REG))]
13703 "TARGET_MIX_SSE_I387
13704 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13705 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13706 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13709 (define_insn "*fp_jcc_2_sse"
13711 (if_then_else (match_operator 0 "comparison_operator"
13712 [(match_operand 1 "register_operand" "x")
13713 (match_operand 2 "nonimmediate_operand" "xm")])
13715 (label_ref (match_operand 3 "" ""))))
13716 (clobber (reg:CCFP FPSR_REG))
13717 (clobber (reg:CCFP FLAGS_REG))]
13719 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13720 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13721 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13724 (define_insn "*fp_jcc_2_387"
13726 (if_then_else (match_operator 0 "comparison_operator"
13727 [(match_operand 1 "register_operand" "f")
13728 (match_operand 2 "register_operand" "f")])
13730 (label_ref (match_operand 3 "" ""))))
13731 (clobber (reg:CCFP FPSR_REG))
13732 (clobber (reg:CCFP FLAGS_REG))]
13733 "TARGET_CMOVE && TARGET_80387
13734 && FLOAT_MODE_P (GET_MODE (operands[1]))
13735 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13736 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13739 (define_insn "*fp_jcc_3_387"
13741 (if_then_else (match_operator 0 "comparison_operator"
13742 [(match_operand 1 "register_operand" "f")
13743 (match_operand 2 "nonimmediate_operand" "fm")])
13744 (label_ref (match_operand 3 "" ""))
13746 (clobber (reg:CCFP FPSR_REG))
13747 (clobber (reg:CCFP FLAGS_REG))
13748 (clobber (match_scratch:HI 4 "=a"))]
13750 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13751 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13752 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13753 && SELECT_CC_MODE (GET_CODE (operands[0]),
13754 operands[1], operands[2]) == CCFPmode
13755 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13758 (define_insn "*fp_jcc_4_387"
13760 (if_then_else (match_operator 0 "comparison_operator"
13761 [(match_operand 1 "register_operand" "f")
13762 (match_operand 2 "nonimmediate_operand" "fm")])
13764 (label_ref (match_operand 3 "" ""))))
13765 (clobber (reg:CCFP FPSR_REG))
13766 (clobber (reg:CCFP FLAGS_REG))
13767 (clobber (match_scratch:HI 4 "=a"))]
13769 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13770 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13771 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13772 && SELECT_CC_MODE (GET_CODE (operands[0]),
13773 operands[1], operands[2]) == CCFPmode
13774 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13777 (define_insn "*fp_jcc_5_387"
13779 (if_then_else (match_operator 0 "comparison_operator"
13780 [(match_operand 1 "register_operand" "f")
13781 (match_operand 2 "register_operand" "f")])
13782 (label_ref (match_operand 3 "" ""))
13784 (clobber (reg:CCFP FPSR_REG))
13785 (clobber (reg:CCFP FLAGS_REG))
13786 (clobber (match_scratch:HI 4 "=a"))]
13788 && FLOAT_MODE_P (GET_MODE (operands[1]))
13789 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13790 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13793 (define_insn "*fp_jcc_6_387"
13795 (if_then_else (match_operator 0 "comparison_operator"
13796 [(match_operand 1 "register_operand" "f")
13797 (match_operand 2 "register_operand" "f")])
13799 (label_ref (match_operand 3 "" ""))))
13800 (clobber (reg:CCFP FPSR_REG))
13801 (clobber (reg:CCFP FLAGS_REG))
13802 (clobber (match_scratch:HI 4 "=a"))]
13804 && FLOAT_MODE_P (GET_MODE (operands[1]))
13805 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13806 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13809 (define_insn "*fp_jcc_7_387"
13811 (if_then_else (match_operator 0 "comparison_operator"
13812 [(match_operand 1 "register_operand" "f")
13813 (match_operand 2 "const0_operand" "X")])
13814 (label_ref (match_operand 3 "" ""))
13816 (clobber (reg:CCFP FPSR_REG))
13817 (clobber (reg:CCFP FLAGS_REG))
13818 (clobber (match_scratch:HI 4 "=a"))]
13820 && FLOAT_MODE_P (GET_MODE (operands[1]))
13821 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13822 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13823 && SELECT_CC_MODE (GET_CODE (operands[0]),
13824 operands[1], operands[2]) == CCFPmode
13825 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13828 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13829 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13830 ;; with a precedence over other operators and is always put in the first
13831 ;; place. Swap condition and operands to match ficom instruction.
13833 (define_insn "*fp_jcc_8<mode>_387"
13835 (if_then_else (match_operator 0 "comparison_operator"
13836 [(match_operator 1 "float_operator"
13837 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13838 (match_operand 3 "register_operand" "f,f")])
13839 (label_ref (match_operand 4 "" ""))
13841 (clobber (reg:CCFP FPSR_REG))
13842 (clobber (reg:CCFP FLAGS_REG))
13843 (clobber (match_scratch:HI 5 "=a,a"))]
13844 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13845 && FLOAT_MODE_P (GET_MODE (operands[3]))
13846 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13847 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13848 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13849 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13854 (if_then_else (match_operator 0 "comparison_operator"
13855 [(match_operand 1 "register_operand" "")
13856 (match_operand 2 "nonimmediate_operand" "")])
13857 (match_operand 3 "" "")
13858 (match_operand 4 "" "")))
13859 (clobber (reg:CCFP FPSR_REG))
13860 (clobber (reg:CCFP FLAGS_REG))]
13864 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13865 operands[3], operands[4], NULL_RTX, NULL_RTX);
13871 (if_then_else (match_operator 0 "comparison_operator"
13872 [(match_operand 1 "register_operand" "")
13873 (match_operand 2 "general_operand" "")])
13874 (match_operand 3 "" "")
13875 (match_operand 4 "" "")))
13876 (clobber (reg:CCFP FPSR_REG))
13877 (clobber (reg:CCFP FLAGS_REG))
13878 (clobber (match_scratch:HI 5 "=a"))]
13882 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13883 operands[3], operands[4], operands[5], NULL_RTX);
13889 (if_then_else (match_operator 0 "comparison_operator"
13890 [(match_operator 1 "float_operator"
13891 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13892 (match_operand 3 "register_operand" "")])
13893 (match_operand 4 "" "")
13894 (match_operand 5 "" "")))
13895 (clobber (reg:CCFP FPSR_REG))
13896 (clobber (reg:CCFP FLAGS_REG))
13897 (clobber (match_scratch:HI 6 "=a"))]
13901 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13902 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13903 operands[3], operands[7],
13904 operands[4], operands[5], operands[6], NULL_RTX);
13908 ;; %%% Kill this when reload knows how to do it.
13911 (if_then_else (match_operator 0 "comparison_operator"
13912 [(match_operator 1 "float_operator"
13913 [(match_operand:X87MODEI12 2 "register_operand" "")])
13914 (match_operand 3 "register_operand" "")])
13915 (match_operand 4 "" "")
13916 (match_operand 5 "" "")))
13917 (clobber (reg:CCFP FPSR_REG))
13918 (clobber (reg:CCFP FLAGS_REG))
13919 (clobber (match_scratch:HI 6 "=a"))]
13923 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13924 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13925 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13926 operands[3], operands[7],
13927 operands[4], operands[5], operands[6], operands[2]);
13931 ;; Unconditional and other jump instructions
13933 (define_insn "jump"
13935 (label_ref (match_operand 0 "" "")))]
13938 [(set_attr "type" "ibr")
13939 (set (attr "length")
13940 (if_then_else (and (ge (minus (match_dup 0) (pc))
13942 (lt (minus (match_dup 0) (pc))
13946 (set_attr "modrm" "0")])
13948 (define_expand "indirect_jump"
13949 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13953 (define_insn "*indirect_jump"
13954 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13957 [(set_attr "type" "ibr")
13958 (set_attr "length_immediate" "0")])
13960 (define_insn "*indirect_jump_rtx64"
13961 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13964 [(set_attr "type" "ibr")
13965 (set_attr "length_immediate" "0")])
13967 (define_expand "tablejump"
13968 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13969 (use (label_ref (match_operand 1 "" "")))])]
13972 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13973 relative. Convert the relative address to an absolute address. */
13977 enum rtx_code code;
13983 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13985 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13989 op1 = pic_offset_table_rtx;
13994 op0 = pic_offset_table_rtx;
13998 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14003 (define_insn "*tablejump_1"
14004 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14005 (use (label_ref (match_operand 1 "" "")))]
14008 [(set_attr "type" "ibr")
14009 (set_attr "length_immediate" "0")])
14011 (define_insn "*tablejump_1_rtx64"
14012 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14013 (use (label_ref (match_operand 1 "" "")))]
14016 [(set_attr "type" "ibr")
14017 (set_attr "length_immediate" "0")])
14019 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14022 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14023 (set (match_operand:QI 1 "register_operand" "")
14024 (match_operator:QI 2 "ix86_comparison_operator"
14025 [(reg FLAGS_REG) (const_int 0)]))
14026 (set (match_operand 3 "q_regs_operand" "")
14027 (zero_extend (match_dup 1)))]
14028 "(peep2_reg_dead_p (3, operands[1])
14029 || operands_match_p (operands[1], operands[3]))
14030 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14031 [(set (match_dup 4) (match_dup 0))
14032 (set (strict_low_part (match_dup 5))
14035 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14036 operands[5] = gen_lowpart (QImode, operands[3]);
14037 ix86_expand_clear (operands[3]);
14040 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14043 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14044 (set (match_operand:QI 1 "register_operand" "")
14045 (match_operator:QI 2 "ix86_comparison_operator"
14046 [(reg FLAGS_REG) (const_int 0)]))
14047 (parallel [(set (match_operand 3 "q_regs_operand" "")
14048 (zero_extend (match_dup 1)))
14049 (clobber (reg:CC FLAGS_REG))])]
14050 "(peep2_reg_dead_p (3, operands[1])
14051 || operands_match_p (operands[1], operands[3]))
14052 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14053 [(set (match_dup 4) (match_dup 0))
14054 (set (strict_low_part (match_dup 5))
14057 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14058 operands[5] = gen_lowpart (QImode, operands[3]);
14059 ix86_expand_clear (operands[3]);
14062 ;; Call instructions.
14064 ;; The predicates normally associated with named expanders are not properly
14065 ;; checked for calls. This is a bug in the generic code, but it isn't that
14066 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14068 ;; Call subroutine returning no value.
14070 (define_expand "call_pop"
14071 [(parallel [(call (match_operand:QI 0 "" "")
14072 (match_operand:SI 1 "" ""))
14073 (set (reg:SI SP_REG)
14074 (plus:SI (reg:SI SP_REG)
14075 (match_operand:SI 3 "" "")))])]
14078 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14082 (define_insn "*call_pop_0"
14083 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14084 (match_operand:SI 1 "" ""))
14085 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14086 (match_operand:SI 2 "immediate_operand" "")))]
14089 if (SIBLING_CALL_P (insn))
14092 return "call\t%P0";
14094 [(set_attr "type" "call")])
14096 (define_insn "*call_pop_1"
14097 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14098 (match_operand:SI 1 "" ""))
14099 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14100 (match_operand:SI 2 "immediate_operand" "i")))]
14103 if (constant_call_address_operand (operands[0], Pmode))
14105 if (SIBLING_CALL_P (insn))
14108 return "call\t%P0";
14110 if (SIBLING_CALL_P (insn))
14113 return "call\t%A0";
14115 [(set_attr "type" "call")])
14117 (define_expand "call"
14118 [(call (match_operand:QI 0 "" "")
14119 (match_operand 1 "" ""))
14120 (use (match_operand 2 "" ""))]
14123 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14127 (define_expand "sibcall"
14128 [(call (match_operand:QI 0 "" "")
14129 (match_operand 1 "" ""))
14130 (use (match_operand 2 "" ""))]
14133 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14137 (define_insn "*call_0"
14138 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14139 (match_operand 1 "" ""))]
14142 if (SIBLING_CALL_P (insn))
14145 return "call\t%P0";
14147 [(set_attr "type" "call")])
14149 (define_insn "*call_1"
14150 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14151 (match_operand 1 "" ""))]
14152 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14154 if (constant_call_address_operand (operands[0], Pmode))
14155 return "call\t%P0";
14156 return "call\t%A0";
14158 [(set_attr "type" "call")])
14160 (define_insn "*sibcall_1"
14161 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14162 (match_operand 1 "" ""))]
14163 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14165 if (constant_call_address_operand (operands[0], Pmode))
14169 [(set_attr "type" "call")])
14171 (define_insn "*call_1_rex64"
14172 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14173 (match_operand 1 "" ""))]
14174 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14176 if (constant_call_address_operand (operands[0], Pmode))
14177 return "call\t%P0";
14178 return "call\t%A0";
14180 [(set_attr "type" "call")])
14182 (define_insn "*sibcall_1_rex64"
14183 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14184 (match_operand 1 "" ""))]
14185 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14187 [(set_attr "type" "call")])
14189 (define_insn "*sibcall_1_rex64_v"
14190 [(call (mem:QI (reg:DI R11_REG))
14191 (match_operand 0 "" ""))]
14192 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14194 [(set_attr "type" "call")])
14197 ;; Call subroutine, returning value in operand 0
14199 (define_expand "call_value_pop"
14200 [(parallel [(set (match_operand 0 "" "")
14201 (call (match_operand:QI 1 "" "")
14202 (match_operand:SI 2 "" "")))
14203 (set (reg:SI SP_REG)
14204 (plus:SI (reg:SI SP_REG)
14205 (match_operand:SI 4 "" "")))])]
14208 ix86_expand_call (operands[0], operands[1], operands[2],
14209 operands[3], operands[4], 0);
14213 (define_expand "call_value"
14214 [(set (match_operand 0 "" "")
14215 (call (match_operand:QI 1 "" "")
14216 (match_operand:SI 2 "" "")))
14217 (use (match_operand:SI 3 "" ""))]
14218 ;; Operand 2 not used on the i386.
14221 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14225 (define_expand "sibcall_value"
14226 [(set (match_operand 0 "" "")
14227 (call (match_operand:QI 1 "" "")
14228 (match_operand:SI 2 "" "")))
14229 (use (match_operand:SI 3 "" ""))]
14230 ;; Operand 2 not used on the i386.
14233 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14237 ;; Call subroutine returning any type.
14239 (define_expand "untyped_call"
14240 [(parallel [(call (match_operand 0 "" "")
14242 (match_operand 1 "" "")
14243 (match_operand 2 "" "")])]
14248 /* In order to give reg-stack an easier job in validating two
14249 coprocessor registers as containing a possible return value,
14250 simply pretend the untyped call returns a complex long double
14253 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14254 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14255 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14258 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14260 rtx set = XVECEXP (operands[2], 0, i);
14261 emit_move_insn (SET_DEST (set), SET_SRC (set));
14264 /* The optimizer does not know that the call sets the function value
14265 registers we stored in the result block. We avoid problems by
14266 claiming that all hard registers are used and clobbered at this
14268 emit_insn (gen_blockage (const0_rtx));
14273 ;; Prologue and epilogue instructions
14275 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14276 ;; all of memory. This blocks insns from being moved across this point.
14278 (define_insn "blockage"
14279 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14282 [(set_attr "length" "0")])
14284 ;; Insn emitted into the body of a function to return from a function.
14285 ;; This is only done if the function's epilogue is known to be simple.
14286 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14288 (define_expand "return"
14290 "ix86_can_use_return_insn_p ()"
14292 if (current_function_pops_args)
14294 rtx popc = GEN_INT (current_function_pops_args);
14295 emit_jump_insn (gen_return_pop_internal (popc));
14300 (define_insn "return_internal"
14304 [(set_attr "length" "1")
14305 (set_attr "length_immediate" "0")
14306 (set_attr "modrm" "0")])
14308 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14309 ;; instruction Athlon and K8 have.
14311 (define_insn "return_internal_long"
14313 (unspec [(const_int 0)] UNSPEC_REP)]
14316 [(set_attr "length" "1")
14317 (set_attr "length_immediate" "0")
14318 (set_attr "prefix_rep" "1")
14319 (set_attr "modrm" "0")])
14321 (define_insn "return_pop_internal"
14323 (use (match_operand:SI 0 "const_int_operand" ""))]
14326 [(set_attr "length" "3")
14327 (set_attr "length_immediate" "2")
14328 (set_attr "modrm" "0")])
14330 (define_insn "return_indirect_internal"
14332 (use (match_operand:SI 0 "register_operand" "r"))]
14335 [(set_attr "type" "ibr")
14336 (set_attr "length_immediate" "0")])
14342 [(set_attr "length" "1")
14343 (set_attr "length_immediate" "0")
14344 (set_attr "modrm" "0")])
14346 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14347 ;; branch prediction penalty for the third jump in a 16-byte
14350 (define_insn "align"
14351 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14354 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14355 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14357 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14358 The align insn is used to avoid 3 jump instructions in the row to improve
14359 branch prediction and the benefits hardly outweigh the cost of extra 8
14360 nops on the average inserted by full alignment pseudo operation. */
14364 [(set_attr "length" "16")])
14366 (define_expand "prologue"
14369 "ix86_expand_prologue (); DONE;")
14371 (define_insn "set_got"
14372 [(set (match_operand:SI 0 "register_operand" "=r")
14373 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14374 (clobber (reg:CC FLAGS_REG))]
14376 { return output_set_got (operands[0], NULL_RTX); }
14377 [(set_attr "type" "multi")
14378 (set_attr "length" "12")])
14380 (define_insn "set_got_labelled"
14381 [(set (match_operand:SI 0 "register_operand" "=r")
14382 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14384 (clobber (reg:CC FLAGS_REG))]
14386 { return output_set_got (operands[0], operands[1]); }
14387 [(set_attr "type" "multi")
14388 (set_attr "length" "12")])
14390 (define_insn "set_got_rex64"
14391 [(set (match_operand:DI 0 "register_operand" "=r")
14392 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14394 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14395 [(set_attr "type" "lea")
14396 (set_attr "length" "6")])
14398 (define_expand "epilogue"
14401 "ix86_expand_epilogue (1); DONE;")
14403 (define_expand "sibcall_epilogue"
14406 "ix86_expand_epilogue (0); DONE;")
14408 (define_expand "eh_return"
14409 [(use (match_operand 0 "register_operand" ""))]
14412 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14414 /* Tricky bit: we write the address of the handler to which we will
14415 be returning into someone else's stack frame, one word below the
14416 stack address we wish to restore. */
14417 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14418 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14419 tmp = gen_rtx_MEM (Pmode, tmp);
14420 emit_move_insn (tmp, ra);
14422 if (Pmode == SImode)
14423 emit_jump_insn (gen_eh_return_si (sa));
14425 emit_jump_insn (gen_eh_return_di (sa));
14430 (define_insn_and_split "eh_return_si"
14432 (unspec [(match_operand:SI 0 "register_operand" "c")]
14433 UNSPEC_EH_RETURN))]
14438 "ix86_expand_epilogue (2); DONE;")
14440 (define_insn_and_split "eh_return_di"
14442 (unspec [(match_operand:DI 0 "register_operand" "c")]
14443 UNSPEC_EH_RETURN))]
14448 "ix86_expand_epilogue (2); DONE;")
14450 (define_insn "leave"
14451 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14452 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14453 (clobber (mem:BLK (scratch)))]
14456 [(set_attr "type" "leave")])
14458 (define_insn "leave_rex64"
14459 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14460 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14461 (clobber (mem:BLK (scratch)))]
14464 [(set_attr "type" "leave")])
14466 (define_expand "ffssi2"
14468 [(set (match_operand:SI 0 "register_operand" "")
14469 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14470 (clobber (match_scratch:SI 2 ""))
14471 (clobber (reg:CC FLAGS_REG))])]
14475 (define_insn_and_split "*ffs_cmove"
14476 [(set (match_operand:SI 0 "register_operand" "=r")
14477 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14478 (clobber (match_scratch:SI 2 "=&r"))
14479 (clobber (reg:CC FLAGS_REG))]
14482 "&& reload_completed"
14483 [(set (match_dup 2) (const_int -1))
14484 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14485 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14486 (set (match_dup 0) (if_then_else:SI
14487 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14490 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14491 (clobber (reg:CC FLAGS_REG))])]
14494 (define_insn_and_split "*ffs_no_cmove"
14495 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14496 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14497 (clobber (match_scratch:SI 2 "=&q"))
14498 (clobber (reg:CC FLAGS_REG))]
14502 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14503 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14504 (set (strict_low_part (match_dup 3))
14505 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14506 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14507 (clobber (reg:CC FLAGS_REG))])
14508 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14509 (clobber (reg:CC FLAGS_REG))])
14510 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14511 (clobber (reg:CC FLAGS_REG))])]
14513 operands[3] = gen_lowpart (QImode, operands[2]);
14514 ix86_expand_clear (operands[2]);
14517 (define_insn "*ffssi_1"
14518 [(set (reg:CCZ FLAGS_REG)
14519 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14521 (set (match_operand:SI 0 "register_operand" "=r")
14522 (ctz:SI (match_dup 1)))]
14524 "bsf{l}\t{%1, %0|%0, %1}"
14525 [(set_attr "prefix_0f" "1")])
14527 (define_expand "ffsdi2"
14529 [(set (match_operand:DI 0 "register_operand" "")
14530 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14531 (clobber (match_scratch:DI 2 ""))
14532 (clobber (reg:CC FLAGS_REG))])]
14533 "TARGET_64BIT && TARGET_CMOVE"
14536 (define_insn_and_split "*ffs_rex64"
14537 [(set (match_operand:DI 0 "register_operand" "=r")
14538 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14539 (clobber (match_scratch:DI 2 "=&r"))
14540 (clobber (reg:CC FLAGS_REG))]
14541 "TARGET_64BIT && TARGET_CMOVE"
14543 "&& reload_completed"
14544 [(set (match_dup 2) (const_int -1))
14545 (parallel [(set (reg:CCZ FLAGS_REG)
14546 (compare:CCZ (match_dup 1) (const_int 0)))
14547 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14548 (set (match_dup 0) (if_then_else:DI
14549 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14552 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14553 (clobber (reg:CC FLAGS_REG))])]
14556 (define_insn "*ffsdi_1"
14557 [(set (reg:CCZ FLAGS_REG)
14558 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14560 (set (match_operand:DI 0 "register_operand" "=r")
14561 (ctz:DI (match_dup 1)))]
14563 "bsf{q}\t{%1, %0|%0, %1}"
14564 [(set_attr "prefix_0f" "1")])
14566 (define_insn "ctzsi2"
14567 [(set (match_operand:SI 0 "register_operand" "=r")
14568 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14569 (clobber (reg:CC FLAGS_REG))]
14571 "bsf{l}\t{%1, %0|%0, %1}"
14572 [(set_attr "prefix_0f" "1")])
14574 (define_insn "ctzdi2"
14575 [(set (match_operand:DI 0 "register_operand" "=r")
14576 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14577 (clobber (reg:CC FLAGS_REG))]
14579 "bsf{q}\t{%1, %0|%0, %1}"
14580 [(set_attr "prefix_0f" "1")])
14582 (define_expand "clzsi2"
14584 [(set (match_operand:SI 0 "register_operand" "")
14585 (minus:SI (const_int 31)
14586 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14587 (clobber (reg:CC FLAGS_REG))])
14589 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14590 (clobber (reg:CC FLAGS_REG))])]
14594 (define_insn "*bsr"
14595 [(set (match_operand:SI 0 "register_operand" "=r")
14596 (minus:SI (const_int 31)
14597 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14598 (clobber (reg:CC FLAGS_REG))]
14600 "bsr{l}\t{%1, %0|%0, %1}"
14601 [(set_attr "prefix_0f" "1")])
14603 (define_insn "bswapsi2"
14604 [(set (match_operand:SI 0 "register_operand" "=r")
14605 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14606 (clobber (reg:CC FLAGS_REG))]
14609 [(set_attr "prefix_0f" "1")
14610 (set_attr "length" "2")])
14612 (define_insn "bswapdi2"
14613 [(set (match_operand:DI 0 "register_operand" "=r")
14614 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14615 (clobber (reg:CC FLAGS_REG))]
14616 "TARGET_64BIT && TARGET_BSWAP"
14618 [(set_attr "prefix_0f" "1")
14619 (set_attr "length" "3")])
14621 (define_expand "clzdi2"
14623 [(set (match_operand:DI 0 "register_operand" "")
14624 (minus:DI (const_int 63)
14625 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14626 (clobber (reg:CC FLAGS_REG))])
14628 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14629 (clobber (reg:CC FLAGS_REG))])]
14633 (define_insn "*bsr_rex64"
14634 [(set (match_operand:DI 0 "register_operand" "=r")
14635 (minus:DI (const_int 63)
14636 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14637 (clobber (reg:CC FLAGS_REG))]
14639 "bsr{q}\t{%1, %0|%0, %1}"
14640 [(set_attr "prefix_0f" "1")])
14642 ;; Thread-local storage patterns for ELF.
14644 ;; Note that these code sequences must appear exactly as shown
14645 ;; in order to allow linker relaxation.
14647 (define_insn "*tls_global_dynamic_32_gnu"
14648 [(set (match_operand:SI 0 "register_operand" "=a")
14649 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14650 (match_operand:SI 2 "tls_symbolic_operand" "")
14651 (match_operand:SI 3 "call_insn_operand" "")]
14653 (clobber (match_scratch:SI 4 "=d"))
14654 (clobber (match_scratch:SI 5 "=c"))
14655 (clobber (reg:CC FLAGS_REG))]
14656 "!TARGET_64BIT && TARGET_GNU_TLS"
14657 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14658 [(set_attr "type" "multi")
14659 (set_attr "length" "12")])
14661 (define_insn "*tls_global_dynamic_32_sun"
14662 [(set (match_operand:SI 0 "register_operand" "=a")
14663 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14664 (match_operand:SI 2 "tls_symbolic_operand" "")
14665 (match_operand:SI 3 "call_insn_operand" "")]
14667 (clobber (match_scratch:SI 4 "=d"))
14668 (clobber (match_scratch:SI 5 "=c"))
14669 (clobber (reg:CC FLAGS_REG))]
14670 "!TARGET_64BIT && TARGET_SUN_TLS"
14671 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14672 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14673 [(set_attr "type" "multi")
14674 (set_attr "length" "14")])
14676 (define_expand "tls_global_dynamic_32"
14677 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14680 (match_operand:SI 1 "tls_symbolic_operand" "")
14683 (clobber (match_scratch:SI 4 ""))
14684 (clobber (match_scratch:SI 5 ""))
14685 (clobber (reg:CC FLAGS_REG))])]
14689 operands[2] = pic_offset_table_rtx;
14692 operands[2] = gen_reg_rtx (Pmode);
14693 emit_insn (gen_set_got (operands[2]));
14695 if (TARGET_GNU2_TLS)
14697 emit_insn (gen_tls_dynamic_gnu2_32
14698 (operands[0], operands[1], operands[2]));
14701 operands[3] = ix86_tls_get_addr ();
14704 (define_insn "*tls_global_dynamic_64"
14705 [(set (match_operand:DI 0 "register_operand" "=a")
14706 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14707 (match_operand:DI 3 "" "")))
14708 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14711 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14712 [(set_attr "type" "multi")
14713 (set_attr "length" "16")])
14715 (define_expand "tls_global_dynamic_64"
14716 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14717 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14718 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14722 if (TARGET_GNU2_TLS)
14724 emit_insn (gen_tls_dynamic_gnu2_64
14725 (operands[0], operands[1]));
14728 operands[2] = ix86_tls_get_addr ();
14731 (define_insn "*tls_local_dynamic_base_32_gnu"
14732 [(set (match_operand:SI 0 "register_operand" "=a")
14733 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14734 (match_operand:SI 2 "call_insn_operand" "")]
14735 UNSPEC_TLS_LD_BASE))
14736 (clobber (match_scratch:SI 3 "=d"))
14737 (clobber (match_scratch:SI 4 "=c"))
14738 (clobber (reg:CC FLAGS_REG))]
14739 "!TARGET_64BIT && TARGET_GNU_TLS"
14740 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14741 [(set_attr "type" "multi")
14742 (set_attr "length" "11")])
14744 (define_insn "*tls_local_dynamic_base_32_sun"
14745 [(set (match_operand:SI 0 "register_operand" "=a")
14746 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14747 (match_operand:SI 2 "call_insn_operand" "")]
14748 UNSPEC_TLS_LD_BASE))
14749 (clobber (match_scratch:SI 3 "=d"))
14750 (clobber (match_scratch:SI 4 "=c"))
14751 (clobber (reg:CC FLAGS_REG))]
14752 "!TARGET_64BIT && TARGET_SUN_TLS"
14753 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14754 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14755 [(set_attr "type" "multi")
14756 (set_attr "length" "13")])
14758 (define_expand "tls_local_dynamic_base_32"
14759 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14760 (unspec:SI [(match_dup 1) (match_dup 2)]
14761 UNSPEC_TLS_LD_BASE))
14762 (clobber (match_scratch:SI 3 ""))
14763 (clobber (match_scratch:SI 4 ""))
14764 (clobber (reg:CC FLAGS_REG))])]
14768 operands[1] = pic_offset_table_rtx;
14771 operands[1] = gen_reg_rtx (Pmode);
14772 emit_insn (gen_set_got (operands[1]));
14774 if (TARGET_GNU2_TLS)
14776 emit_insn (gen_tls_dynamic_gnu2_32
14777 (operands[0], ix86_tls_module_base (), operands[1]));
14780 operands[2] = ix86_tls_get_addr ();
14783 (define_insn "*tls_local_dynamic_base_64"
14784 [(set (match_operand:DI 0 "register_operand" "=a")
14785 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14786 (match_operand:DI 2 "" "")))
14787 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14789 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14790 [(set_attr "type" "multi")
14791 (set_attr "length" "12")])
14793 (define_expand "tls_local_dynamic_base_64"
14794 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14795 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14796 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14799 if (TARGET_GNU2_TLS)
14801 emit_insn (gen_tls_dynamic_gnu2_64
14802 (operands[0], ix86_tls_module_base ()));
14805 operands[1] = ix86_tls_get_addr ();
14808 ;; Local dynamic of a single variable is a lose. Show combine how
14809 ;; to convert that back to global dynamic.
14811 (define_insn_and_split "*tls_local_dynamic_32_once"
14812 [(set (match_operand:SI 0 "register_operand" "=a")
14813 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14814 (match_operand:SI 2 "call_insn_operand" "")]
14815 UNSPEC_TLS_LD_BASE)
14816 (const:SI (unspec:SI
14817 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14819 (clobber (match_scratch:SI 4 "=d"))
14820 (clobber (match_scratch:SI 5 "=c"))
14821 (clobber (reg:CC FLAGS_REG))]
14825 [(parallel [(set (match_dup 0)
14826 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14828 (clobber (match_dup 4))
14829 (clobber (match_dup 5))
14830 (clobber (reg:CC FLAGS_REG))])]
14833 ;; Load and add the thread base pointer from %gs:0.
14835 (define_insn "*load_tp_si"
14836 [(set (match_operand:SI 0 "register_operand" "=r")
14837 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14839 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14840 [(set_attr "type" "imov")
14841 (set_attr "modrm" "0")
14842 (set_attr "length" "7")
14843 (set_attr "memory" "load")
14844 (set_attr "imm_disp" "false")])
14846 (define_insn "*add_tp_si"
14847 [(set (match_operand:SI 0 "register_operand" "=r")
14848 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14849 (match_operand:SI 1 "register_operand" "0")))
14850 (clobber (reg:CC FLAGS_REG))]
14852 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14853 [(set_attr "type" "alu")
14854 (set_attr "modrm" "0")
14855 (set_attr "length" "7")
14856 (set_attr "memory" "load")
14857 (set_attr "imm_disp" "false")])
14859 (define_insn "*load_tp_di"
14860 [(set (match_operand:DI 0 "register_operand" "=r")
14861 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14863 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14864 [(set_attr "type" "imov")
14865 (set_attr "modrm" "0")
14866 (set_attr "length" "7")
14867 (set_attr "memory" "load")
14868 (set_attr "imm_disp" "false")])
14870 (define_insn "*add_tp_di"
14871 [(set (match_operand:DI 0 "register_operand" "=r")
14872 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14873 (match_operand:DI 1 "register_operand" "0")))
14874 (clobber (reg:CC FLAGS_REG))]
14876 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14877 [(set_attr "type" "alu")
14878 (set_attr "modrm" "0")
14879 (set_attr "length" "7")
14880 (set_attr "memory" "load")
14881 (set_attr "imm_disp" "false")])
14883 ;; GNU2 TLS patterns can be split.
14885 (define_expand "tls_dynamic_gnu2_32"
14886 [(set (match_dup 3)
14887 (plus:SI (match_operand:SI 2 "register_operand" "")
14889 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14892 [(set (match_operand:SI 0 "register_operand" "")
14893 (unspec:SI [(match_dup 1) (match_dup 3)
14894 (match_dup 2) (reg:SI SP_REG)]
14896 (clobber (reg:CC FLAGS_REG))])]
14897 "!TARGET_64BIT && TARGET_GNU2_TLS"
14899 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14900 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14903 (define_insn "*tls_dynamic_lea_32"
14904 [(set (match_operand:SI 0 "register_operand" "=r")
14905 (plus:SI (match_operand:SI 1 "register_operand" "b")
14907 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14908 UNSPEC_TLSDESC))))]
14909 "!TARGET_64BIT && TARGET_GNU2_TLS"
14910 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14911 [(set_attr "type" "lea")
14912 (set_attr "mode" "SI")
14913 (set_attr "length" "6")
14914 (set_attr "length_address" "4")])
14916 (define_insn "*tls_dynamic_call_32"
14917 [(set (match_operand:SI 0 "register_operand" "=a")
14918 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14919 (match_operand:SI 2 "register_operand" "0")
14920 ;; we have to make sure %ebx still points to the GOT
14921 (match_operand:SI 3 "register_operand" "b")
14924 (clobber (reg:CC FLAGS_REG))]
14925 "!TARGET_64BIT && TARGET_GNU2_TLS"
14926 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14927 [(set_attr "type" "call")
14928 (set_attr "length" "2")
14929 (set_attr "length_address" "0")])
14931 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14932 [(set (match_operand:SI 0 "register_operand" "=&a")
14934 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14935 (match_operand:SI 4 "" "")
14936 (match_operand:SI 2 "register_operand" "b")
14939 (const:SI (unspec:SI
14940 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14942 (clobber (reg:CC FLAGS_REG))]
14943 "!TARGET_64BIT && TARGET_GNU2_TLS"
14946 [(set (match_dup 0) (match_dup 5))]
14948 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14949 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14952 (define_expand "tls_dynamic_gnu2_64"
14953 [(set (match_dup 2)
14954 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14957 [(set (match_operand:DI 0 "register_operand" "")
14958 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14960 (clobber (reg:CC FLAGS_REG))])]
14961 "TARGET_64BIT && TARGET_GNU2_TLS"
14963 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14964 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14967 (define_insn "*tls_dynamic_lea_64"
14968 [(set (match_operand:DI 0 "register_operand" "=r")
14969 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14971 "TARGET_64BIT && TARGET_GNU2_TLS"
14972 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14973 [(set_attr "type" "lea")
14974 (set_attr "mode" "DI")
14975 (set_attr "length" "7")
14976 (set_attr "length_address" "4")])
14978 (define_insn "*tls_dynamic_call_64"
14979 [(set (match_operand:DI 0 "register_operand" "=a")
14980 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14981 (match_operand:DI 2 "register_operand" "0")
14984 (clobber (reg:CC FLAGS_REG))]
14985 "TARGET_64BIT && TARGET_GNU2_TLS"
14986 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14987 [(set_attr "type" "call")
14988 (set_attr "length" "2")
14989 (set_attr "length_address" "0")])
14991 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14992 [(set (match_operand:DI 0 "register_operand" "=&a")
14994 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14995 (match_operand:DI 3 "" "")
14998 (const:DI (unspec:DI
14999 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15001 (clobber (reg:CC FLAGS_REG))]
15002 "TARGET_64BIT && TARGET_GNU2_TLS"
15005 [(set (match_dup 0) (match_dup 4))]
15007 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15008 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15013 ;; These patterns match the binary 387 instructions for addM3, subM3,
15014 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15015 ;; SFmode. The first is the normal insn, the second the same insn but
15016 ;; with one operand a conversion, and the third the same insn but with
15017 ;; the other operand a conversion. The conversion may be SFmode or
15018 ;; SImode if the target mode DFmode, but only SImode if the target mode
15021 ;; Gcc is slightly more smart about handling normal two address instructions
15022 ;; so use special patterns for add and mull.
15024 (define_insn "*fop_sf_comm_mixed"
15025 [(set (match_operand:SF 0 "register_operand" "=f,x")
15026 (match_operator:SF 3 "binary_fp_operator"
15027 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15028 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15029 "TARGET_MIX_SSE_I387
15030 && COMMUTATIVE_ARITH_P (operands[3])
15031 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15032 "* return output_387_binary_op (insn, operands);"
15033 [(set (attr "type")
15034 (if_then_else (eq_attr "alternative" "1")
15035 (if_then_else (match_operand:SF 3 "mult_operator" "")
15036 (const_string "ssemul")
15037 (const_string "sseadd"))
15038 (if_then_else (match_operand:SF 3 "mult_operator" "")
15039 (const_string "fmul")
15040 (const_string "fop"))))
15041 (set_attr "mode" "SF")])
15043 (define_insn "*fop_sf_comm_sse"
15044 [(set (match_operand:SF 0 "register_operand" "=x")
15045 (match_operator:SF 3 "binary_fp_operator"
15046 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15047 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15049 && COMMUTATIVE_ARITH_P (operands[3])
15050 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15051 "* return output_387_binary_op (insn, operands);"
15052 [(set (attr "type")
15053 (if_then_else (match_operand:SF 3 "mult_operator" "")
15054 (const_string "ssemul")
15055 (const_string "sseadd")))
15056 (set_attr "mode" "SF")])
15058 (define_insn "*fop_sf_comm_i387"
15059 [(set (match_operand:SF 0 "register_operand" "=f")
15060 (match_operator:SF 3 "binary_fp_operator"
15061 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15062 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15064 && COMMUTATIVE_ARITH_P (operands[3])
15065 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15066 "* return output_387_binary_op (insn, operands);"
15067 [(set (attr "type")
15068 (if_then_else (match_operand:SF 3 "mult_operator" "")
15069 (const_string "fmul")
15070 (const_string "fop")))
15071 (set_attr "mode" "SF")])
15073 (define_insn "*fop_sf_1_mixed"
15074 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15075 (match_operator:SF 3 "binary_fp_operator"
15076 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15077 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15078 "TARGET_MIX_SSE_I387
15079 && !COMMUTATIVE_ARITH_P (operands[3])
15080 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15081 "* return output_387_binary_op (insn, operands);"
15082 [(set (attr "type")
15083 (cond [(and (eq_attr "alternative" "2")
15084 (match_operand:SF 3 "mult_operator" ""))
15085 (const_string "ssemul")
15086 (and (eq_attr "alternative" "2")
15087 (match_operand:SF 3 "div_operator" ""))
15088 (const_string "ssediv")
15089 (eq_attr "alternative" "2")
15090 (const_string "sseadd")
15091 (match_operand:SF 3 "mult_operator" "")
15092 (const_string "fmul")
15093 (match_operand:SF 3 "div_operator" "")
15094 (const_string "fdiv")
15096 (const_string "fop")))
15097 (set_attr "mode" "SF")])
15099 (define_insn "*fop_sf_1_sse"
15100 [(set (match_operand:SF 0 "register_operand" "=x")
15101 (match_operator:SF 3 "binary_fp_operator"
15102 [(match_operand:SF 1 "register_operand" "0")
15103 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15105 && !COMMUTATIVE_ARITH_P (operands[3])"
15106 "* return output_387_binary_op (insn, operands);"
15107 [(set (attr "type")
15108 (cond [(match_operand:SF 3 "mult_operator" "")
15109 (const_string "ssemul")
15110 (match_operand:SF 3 "div_operator" "")
15111 (const_string "ssediv")
15113 (const_string "sseadd")))
15114 (set_attr "mode" "SF")])
15116 ;; This pattern is not fully shadowed by the pattern above.
15117 (define_insn "*fop_sf_1_i387"
15118 [(set (match_operand:SF 0 "register_operand" "=f,f")
15119 (match_operator:SF 3 "binary_fp_operator"
15120 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15121 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15122 "TARGET_80387 && !TARGET_SSE_MATH
15123 && !COMMUTATIVE_ARITH_P (operands[3])
15124 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15125 "* return output_387_binary_op (insn, operands);"
15126 [(set (attr "type")
15127 (cond [(match_operand:SF 3 "mult_operator" "")
15128 (const_string "fmul")
15129 (match_operand:SF 3 "div_operator" "")
15130 (const_string "fdiv")
15132 (const_string "fop")))
15133 (set_attr "mode" "SF")])
15135 ;; ??? Add SSE splitters for these!
15136 (define_insn "*fop_sf_2<mode>_i387"
15137 [(set (match_operand:SF 0 "register_operand" "=f,f")
15138 (match_operator:SF 3 "binary_fp_operator"
15139 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15140 (match_operand:SF 2 "register_operand" "0,0")]))]
15141 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15142 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15143 [(set (attr "type")
15144 (cond [(match_operand:SF 3 "mult_operator" "")
15145 (const_string "fmul")
15146 (match_operand:SF 3 "div_operator" "")
15147 (const_string "fdiv")
15149 (const_string "fop")))
15150 (set_attr "fp_int_src" "true")
15151 (set_attr "mode" "<MODE>")])
15153 (define_insn "*fop_sf_3<mode>_i387"
15154 [(set (match_operand:SF 0 "register_operand" "=f,f")
15155 (match_operator:SF 3 "binary_fp_operator"
15156 [(match_operand:SF 1 "register_operand" "0,0")
15157 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15158 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15159 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15160 [(set (attr "type")
15161 (cond [(match_operand:SF 3 "mult_operator" "")
15162 (const_string "fmul")
15163 (match_operand:SF 3 "div_operator" "")
15164 (const_string "fdiv")
15166 (const_string "fop")))
15167 (set_attr "fp_int_src" "true")
15168 (set_attr "mode" "<MODE>")])
15170 (define_insn "*fop_df_comm_mixed"
15171 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15172 (match_operator:DF 3 "binary_fp_operator"
15173 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15174 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15175 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15176 && COMMUTATIVE_ARITH_P (operands[3])
15177 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15178 "* return output_387_binary_op (insn, operands);"
15179 [(set (attr "type")
15180 (if_then_else (eq_attr "alternative" "1")
15181 (if_then_else (match_operand:DF 3 "mult_operator" "")
15182 (const_string "ssemul")
15183 (const_string "sseadd"))
15184 (if_then_else (match_operand:DF 3 "mult_operator" "")
15185 (const_string "fmul")
15186 (const_string "fop"))))
15187 (set_attr "mode" "DF")])
15189 (define_insn "*fop_df_comm_sse"
15190 [(set (match_operand:DF 0 "register_operand" "=Y")
15191 (match_operator:DF 3 "binary_fp_operator"
15192 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15193 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15194 "TARGET_SSE2 && TARGET_SSE_MATH
15195 && COMMUTATIVE_ARITH_P (operands[3])
15196 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15197 "* return output_387_binary_op (insn, operands);"
15198 [(set (attr "type")
15199 (if_then_else (match_operand:DF 3 "mult_operator" "")
15200 (const_string "ssemul")
15201 (const_string "sseadd")))
15202 (set_attr "mode" "DF")])
15204 (define_insn "*fop_df_comm_i387"
15205 [(set (match_operand:DF 0 "register_operand" "=f")
15206 (match_operator:DF 3 "binary_fp_operator"
15207 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15208 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15210 && COMMUTATIVE_ARITH_P (operands[3])
15211 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15212 "* return output_387_binary_op (insn, operands);"
15213 [(set (attr "type")
15214 (if_then_else (match_operand:DF 3 "mult_operator" "")
15215 (const_string "fmul")
15216 (const_string "fop")))
15217 (set_attr "mode" "DF")])
15219 (define_insn "*fop_df_1_mixed"
15220 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15221 (match_operator:DF 3 "binary_fp_operator"
15222 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15223 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15224 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15225 && !COMMUTATIVE_ARITH_P (operands[3])
15226 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15227 "* return output_387_binary_op (insn, operands);"
15228 [(set (attr "type")
15229 (cond [(and (eq_attr "alternative" "2")
15230 (match_operand:DF 3 "mult_operator" ""))
15231 (const_string "ssemul")
15232 (and (eq_attr "alternative" "2")
15233 (match_operand:DF 3 "div_operator" ""))
15234 (const_string "ssediv")
15235 (eq_attr "alternative" "2")
15236 (const_string "sseadd")
15237 (match_operand:DF 3 "mult_operator" "")
15238 (const_string "fmul")
15239 (match_operand:DF 3 "div_operator" "")
15240 (const_string "fdiv")
15242 (const_string "fop")))
15243 (set_attr "mode" "DF")])
15245 (define_insn "*fop_df_1_sse"
15246 [(set (match_operand:DF 0 "register_operand" "=Y")
15247 (match_operator:DF 3 "binary_fp_operator"
15248 [(match_operand:DF 1 "register_operand" "0")
15249 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15250 "TARGET_SSE2 && TARGET_SSE_MATH
15251 && !COMMUTATIVE_ARITH_P (operands[3])"
15252 "* return output_387_binary_op (insn, operands);"
15253 [(set_attr "mode" "DF")
15255 (cond [(match_operand:DF 3 "mult_operator" "")
15256 (const_string "ssemul")
15257 (match_operand:DF 3 "div_operator" "")
15258 (const_string "ssediv")
15260 (const_string "sseadd")))])
15262 ;; This pattern is not fully shadowed by the pattern above.
15263 (define_insn "*fop_df_1_i387"
15264 [(set (match_operand:DF 0 "register_operand" "=f,f")
15265 (match_operator:DF 3 "binary_fp_operator"
15266 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15267 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15268 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15269 && !COMMUTATIVE_ARITH_P (operands[3])
15270 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15271 "* return output_387_binary_op (insn, operands);"
15272 [(set (attr "type")
15273 (cond [(match_operand:DF 3 "mult_operator" "")
15274 (const_string "fmul")
15275 (match_operand:DF 3 "div_operator" "")
15276 (const_string "fdiv")
15278 (const_string "fop")))
15279 (set_attr "mode" "DF")])
15281 ;; ??? Add SSE splitters for these!
15282 (define_insn "*fop_df_2<mode>_i387"
15283 [(set (match_operand:DF 0 "register_operand" "=f,f")
15284 (match_operator:DF 3 "binary_fp_operator"
15285 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15286 (match_operand:DF 2 "register_operand" "0,0")]))]
15287 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15288 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15289 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15290 [(set (attr "type")
15291 (cond [(match_operand:DF 3 "mult_operator" "")
15292 (const_string "fmul")
15293 (match_operand:DF 3 "div_operator" "")
15294 (const_string "fdiv")
15296 (const_string "fop")))
15297 (set_attr "fp_int_src" "true")
15298 (set_attr "mode" "<MODE>")])
15300 (define_insn "*fop_df_3<mode>_i387"
15301 [(set (match_operand:DF 0 "register_operand" "=f,f")
15302 (match_operator:DF 3 "binary_fp_operator"
15303 [(match_operand:DF 1 "register_operand" "0,0")
15304 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15305 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15306 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15307 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15308 [(set (attr "type")
15309 (cond [(match_operand:DF 3 "mult_operator" "")
15310 (const_string "fmul")
15311 (match_operand:DF 3 "div_operator" "")
15312 (const_string "fdiv")
15314 (const_string "fop")))
15315 (set_attr "fp_int_src" "true")
15316 (set_attr "mode" "<MODE>")])
15318 (define_insn "*fop_df_4_i387"
15319 [(set (match_operand:DF 0 "register_operand" "=f,f")
15320 (match_operator:DF 3 "binary_fp_operator"
15321 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15322 (match_operand:DF 2 "register_operand" "0,f")]))]
15323 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15324 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15325 "* return output_387_binary_op (insn, operands);"
15326 [(set (attr "type")
15327 (cond [(match_operand:DF 3 "mult_operator" "")
15328 (const_string "fmul")
15329 (match_operand:DF 3 "div_operator" "")
15330 (const_string "fdiv")
15332 (const_string "fop")))
15333 (set_attr "mode" "SF")])
15335 (define_insn "*fop_df_5_i387"
15336 [(set (match_operand:DF 0 "register_operand" "=f,f")
15337 (match_operator:DF 3 "binary_fp_operator"
15338 [(match_operand:DF 1 "register_operand" "0,f")
15340 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15341 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15342 "* return output_387_binary_op (insn, operands);"
15343 [(set (attr "type")
15344 (cond [(match_operand:DF 3 "mult_operator" "")
15345 (const_string "fmul")
15346 (match_operand:DF 3 "div_operator" "")
15347 (const_string "fdiv")
15349 (const_string "fop")))
15350 (set_attr "mode" "SF")])
15352 (define_insn "*fop_df_6_i387"
15353 [(set (match_operand:DF 0 "register_operand" "=f,f")
15354 (match_operator:DF 3 "binary_fp_operator"
15356 (match_operand:SF 1 "register_operand" "0,f"))
15358 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15359 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15360 "* return output_387_binary_op (insn, operands);"
15361 [(set (attr "type")
15362 (cond [(match_operand:DF 3 "mult_operator" "")
15363 (const_string "fmul")
15364 (match_operand:DF 3 "div_operator" "")
15365 (const_string "fdiv")
15367 (const_string "fop")))
15368 (set_attr "mode" "SF")])
15370 (define_insn "*fop_xf_comm_i387"
15371 [(set (match_operand:XF 0 "register_operand" "=f")
15372 (match_operator:XF 3 "binary_fp_operator"
15373 [(match_operand:XF 1 "register_operand" "%0")
15374 (match_operand:XF 2 "register_operand" "f")]))]
15376 && COMMUTATIVE_ARITH_P (operands[3])"
15377 "* return output_387_binary_op (insn, operands);"
15378 [(set (attr "type")
15379 (if_then_else (match_operand:XF 3 "mult_operator" "")
15380 (const_string "fmul")
15381 (const_string "fop")))
15382 (set_attr "mode" "XF")])
15384 (define_insn "*fop_xf_1_i387"
15385 [(set (match_operand:XF 0 "register_operand" "=f,f")
15386 (match_operator:XF 3 "binary_fp_operator"
15387 [(match_operand:XF 1 "register_operand" "0,f")
15388 (match_operand:XF 2 "register_operand" "f,0")]))]
15390 && !COMMUTATIVE_ARITH_P (operands[3])"
15391 "* return output_387_binary_op (insn, operands);"
15392 [(set (attr "type")
15393 (cond [(match_operand:XF 3 "mult_operator" "")
15394 (const_string "fmul")
15395 (match_operand:XF 3 "div_operator" "")
15396 (const_string "fdiv")
15398 (const_string "fop")))
15399 (set_attr "mode" "XF")])
15401 (define_insn "*fop_xf_2<mode>_i387"
15402 [(set (match_operand:XF 0 "register_operand" "=f,f")
15403 (match_operator:XF 3 "binary_fp_operator"
15404 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15405 (match_operand:XF 2 "register_operand" "0,0")]))]
15406 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15407 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15408 [(set (attr "type")
15409 (cond [(match_operand:XF 3 "mult_operator" "")
15410 (const_string "fmul")
15411 (match_operand:XF 3 "div_operator" "")
15412 (const_string "fdiv")
15414 (const_string "fop")))
15415 (set_attr "fp_int_src" "true")
15416 (set_attr "mode" "<MODE>")])
15418 (define_insn "*fop_xf_3<mode>_i387"
15419 [(set (match_operand:XF 0 "register_operand" "=f,f")
15420 (match_operator:XF 3 "binary_fp_operator"
15421 [(match_operand:XF 1 "register_operand" "0,0")
15422 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15423 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15424 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15425 [(set (attr "type")
15426 (cond [(match_operand:XF 3 "mult_operator" "")
15427 (const_string "fmul")
15428 (match_operand:XF 3 "div_operator" "")
15429 (const_string "fdiv")
15431 (const_string "fop")))
15432 (set_attr "fp_int_src" "true")
15433 (set_attr "mode" "<MODE>")])
15435 (define_insn "*fop_xf_4_i387"
15436 [(set (match_operand:XF 0 "register_operand" "=f,f")
15437 (match_operator:XF 3 "binary_fp_operator"
15438 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15439 (match_operand:XF 2 "register_operand" "0,f")]))]
15441 "* return output_387_binary_op (insn, operands);"
15442 [(set (attr "type")
15443 (cond [(match_operand:XF 3 "mult_operator" "")
15444 (const_string "fmul")
15445 (match_operand:XF 3 "div_operator" "")
15446 (const_string "fdiv")
15448 (const_string "fop")))
15449 (set_attr "mode" "SF")])
15451 (define_insn "*fop_xf_5_i387"
15452 [(set (match_operand:XF 0 "register_operand" "=f,f")
15453 (match_operator:XF 3 "binary_fp_operator"
15454 [(match_operand:XF 1 "register_operand" "0,f")
15456 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15458 "* return output_387_binary_op (insn, operands);"
15459 [(set (attr "type")
15460 (cond [(match_operand:XF 3 "mult_operator" "")
15461 (const_string "fmul")
15462 (match_operand:XF 3 "div_operator" "")
15463 (const_string "fdiv")
15465 (const_string "fop")))
15466 (set_attr "mode" "SF")])
15468 (define_insn "*fop_xf_6_i387"
15469 [(set (match_operand:XF 0 "register_operand" "=f,f")
15470 (match_operator:XF 3 "binary_fp_operator"
15472 (match_operand 1 "register_operand" "0,f"))
15474 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15476 "* return output_387_binary_op (insn, operands);"
15477 [(set (attr "type")
15478 (cond [(match_operand:XF 3 "mult_operator" "")
15479 (const_string "fmul")
15480 (match_operand:XF 3 "div_operator" "")
15481 (const_string "fdiv")
15483 (const_string "fop")))
15484 (set_attr "mode" "SF")])
15487 [(set (match_operand 0 "register_operand" "")
15488 (match_operator 3 "binary_fp_operator"
15489 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15490 (match_operand 2 "register_operand" "")]))]
15491 "TARGET_80387 && reload_completed
15492 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15495 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15496 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15497 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15498 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15499 GET_MODE (operands[3]),
15502 ix86_free_from_memory (GET_MODE (operands[1]));
15507 [(set (match_operand 0 "register_operand" "")
15508 (match_operator 3 "binary_fp_operator"
15509 [(match_operand 1 "register_operand" "")
15510 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15511 "TARGET_80387 && reload_completed
15512 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15515 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15516 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15517 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15518 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15519 GET_MODE (operands[3]),
15522 ix86_free_from_memory (GET_MODE (operands[2]));
15526 ;; FPU special functions.
15528 (define_expand "sqrtsf2"
15529 [(set (match_operand:SF 0 "register_operand" "")
15530 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15531 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15533 if (!TARGET_SSE_MATH)
15534 operands[1] = force_reg (SFmode, operands[1]);
15537 (define_insn "*sqrtsf2_mixed"
15538 [(set (match_operand:SF 0 "register_operand" "=f,x")
15539 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15540 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15543 sqrtss\t{%1, %0|%0, %1}"
15544 [(set_attr "type" "fpspc,sse")
15545 (set_attr "mode" "SF,SF")
15546 (set_attr "athlon_decode" "direct,*")])
15548 (define_insn "*sqrtsf2_sse"
15549 [(set (match_operand:SF 0 "register_operand" "=x")
15550 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15552 "sqrtss\t{%1, %0|%0, %1}"
15553 [(set_attr "type" "sse")
15554 (set_attr "mode" "SF")
15555 (set_attr "athlon_decode" "*")])
15557 (define_insn "*sqrtsf2_i387"
15558 [(set (match_operand:SF 0 "register_operand" "=f")
15559 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15560 "TARGET_USE_FANCY_MATH_387"
15562 [(set_attr "type" "fpspc")
15563 (set_attr "mode" "SF")
15564 (set_attr "athlon_decode" "direct")])
15566 (define_expand "sqrtdf2"
15567 [(set (match_operand:DF 0 "register_operand" "")
15568 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15569 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15571 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15572 operands[1] = force_reg (DFmode, operands[1]);
15575 (define_insn "*sqrtdf2_mixed"
15576 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15577 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15578 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15581 sqrtsd\t{%1, %0|%0, %1}"
15582 [(set_attr "type" "fpspc,sse")
15583 (set_attr "mode" "DF,DF")
15584 (set_attr "athlon_decode" "direct,*")])
15586 (define_insn "*sqrtdf2_sse"
15587 [(set (match_operand:DF 0 "register_operand" "=Y")
15588 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15589 "TARGET_SSE2 && TARGET_SSE_MATH"
15590 "sqrtsd\t{%1, %0|%0, %1}"
15591 [(set_attr "type" "sse")
15592 (set_attr "mode" "DF")
15593 (set_attr "athlon_decode" "*")])
15595 (define_insn "*sqrtdf2_i387"
15596 [(set (match_operand:DF 0 "register_operand" "=f")
15597 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15598 "TARGET_USE_FANCY_MATH_387"
15600 [(set_attr "type" "fpspc")
15601 (set_attr "mode" "DF")
15602 (set_attr "athlon_decode" "direct")])
15604 (define_insn "*sqrtextendsfdf2_i387"
15605 [(set (match_operand:DF 0 "register_operand" "=f")
15606 (sqrt:DF (float_extend:DF
15607 (match_operand:SF 1 "register_operand" "0"))))]
15608 "TARGET_USE_FANCY_MATH_387
15609 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15611 [(set_attr "type" "fpspc")
15612 (set_attr "mode" "DF")
15613 (set_attr "athlon_decode" "direct")])
15615 (define_insn "sqrtxf2"
15616 [(set (match_operand:XF 0 "register_operand" "=f")
15617 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15618 "TARGET_USE_FANCY_MATH_387"
15620 [(set_attr "type" "fpspc")
15621 (set_attr "mode" "XF")
15622 (set_attr "athlon_decode" "direct")])
15624 (define_insn "*sqrtextendsfxf2_i387"
15625 [(set (match_operand:XF 0 "register_operand" "=f")
15626 (sqrt:XF (float_extend:XF
15627 (match_operand:SF 1 "register_operand" "0"))))]
15628 "TARGET_USE_FANCY_MATH_387"
15630 [(set_attr "type" "fpspc")
15631 (set_attr "mode" "XF")
15632 (set_attr "athlon_decode" "direct")])
15634 (define_insn "*sqrtextenddfxf2_i387"
15635 [(set (match_operand:XF 0 "register_operand" "=f")
15636 (sqrt:XF (float_extend:XF
15637 (match_operand:DF 1 "register_operand" "0"))))]
15638 "TARGET_USE_FANCY_MATH_387"
15640 [(set_attr "type" "fpspc")
15641 (set_attr "mode" "XF")
15642 (set_attr "athlon_decode" "direct")])
15644 (define_insn "fpremxf4"
15645 [(set (match_operand:XF 0 "register_operand" "=f")
15646 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15647 (match_operand:XF 3 "register_operand" "1")]
15649 (set (match_operand:XF 1 "register_operand" "=u")
15650 (unspec:XF [(match_dup 2) (match_dup 3)]
15652 (set (reg:CCFP FPSR_REG)
15653 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15654 "TARGET_USE_FANCY_MATH_387"
15656 [(set_attr "type" "fpspc")
15657 (set_attr "mode" "XF")])
15659 (define_expand "fmodsf3"
15660 [(use (match_operand:SF 0 "register_operand" ""))
15661 (use (match_operand:SF 1 "register_operand" ""))
15662 (use (match_operand:SF 2 "register_operand" ""))]
15663 "TARGET_USE_FANCY_MATH_387
15664 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15666 rtx label = gen_label_rtx ();
15668 rtx op1 = gen_reg_rtx (XFmode);
15669 rtx op2 = gen_reg_rtx (XFmode);
15671 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15672 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15674 emit_label (label);
15676 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15677 ix86_emit_fp_unordered_jump (label);
15679 emit_insn (gen_truncxfsf2 (operands[0], op1));
15683 (define_expand "fmoddf3"
15684 [(use (match_operand:DF 0 "register_operand" ""))
15685 (use (match_operand:DF 1 "register_operand" ""))
15686 (use (match_operand:DF 2 "register_operand" ""))]
15687 "TARGET_USE_FANCY_MATH_387
15688 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15690 rtx label = gen_label_rtx ();
15692 rtx op1 = gen_reg_rtx (XFmode);
15693 rtx op2 = gen_reg_rtx (XFmode);
15695 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15696 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15698 emit_label (label);
15700 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15701 ix86_emit_fp_unordered_jump (label);
15703 emit_insn (gen_truncxfdf2 (operands[0], op1));
15707 (define_expand "fmodxf3"
15708 [(use (match_operand:XF 0 "register_operand" ""))
15709 (use (match_operand:XF 1 "register_operand" ""))
15710 (use (match_operand:XF 2 "register_operand" ""))]
15711 "TARGET_USE_FANCY_MATH_387"
15713 rtx label = gen_label_rtx ();
15715 emit_label (label);
15717 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15718 operands[1], operands[2]));
15719 ix86_emit_fp_unordered_jump (label);
15721 emit_move_insn (operands[0], operands[1]);
15725 (define_insn "fprem1xf4"
15726 [(set (match_operand:XF 0 "register_operand" "=f")
15727 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15728 (match_operand:XF 3 "register_operand" "1")]
15730 (set (match_operand:XF 1 "register_operand" "=u")
15731 (unspec:XF [(match_dup 2) (match_dup 3)]
15733 (set (reg:CCFP FPSR_REG)
15734 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15735 "TARGET_USE_FANCY_MATH_387"
15737 [(set_attr "type" "fpspc")
15738 (set_attr "mode" "XF")])
15740 (define_expand "remaindersf3"
15741 [(use (match_operand:SF 0 "register_operand" ""))
15742 (use (match_operand:SF 1 "register_operand" ""))
15743 (use (match_operand:SF 2 "register_operand" ""))]
15744 "TARGET_USE_FANCY_MATH_387
15745 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15747 rtx label = gen_label_rtx ();
15749 rtx op1 = gen_reg_rtx (XFmode);
15750 rtx op2 = gen_reg_rtx (XFmode);
15752 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15753 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15755 emit_label (label);
15757 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15758 ix86_emit_fp_unordered_jump (label);
15760 emit_insn (gen_truncxfsf2 (operands[0], op1));
15764 (define_expand "remainderdf3"
15765 [(use (match_operand:DF 0 "register_operand" ""))
15766 (use (match_operand:DF 1 "register_operand" ""))
15767 (use (match_operand:DF 2 "register_operand" ""))]
15768 "TARGET_USE_FANCY_MATH_387
15769 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15771 rtx label = gen_label_rtx ();
15773 rtx op1 = gen_reg_rtx (XFmode);
15774 rtx op2 = gen_reg_rtx (XFmode);
15776 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15777 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15779 emit_label (label);
15781 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15782 ix86_emit_fp_unordered_jump (label);
15784 emit_insn (gen_truncxfdf2 (operands[0], op1));
15788 (define_expand "remainderxf3"
15789 [(use (match_operand:XF 0 "register_operand" ""))
15790 (use (match_operand:XF 1 "register_operand" ""))
15791 (use (match_operand:XF 2 "register_operand" ""))]
15792 "TARGET_USE_FANCY_MATH_387"
15794 rtx label = gen_label_rtx ();
15796 emit_label (label);
15798 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15799 operands[1], operands[2]));
15800 ix86_emit_fp_unordered_jump (label);
15802 emit_move_insn (operands[0], operands[1]);
15806 (define_insn "*sindf2"
15807 [(set (match_operand:DF 0 "register_operand" "=f")
15808 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15809 "TARGET_USE_FANCY_MATH_387
15810 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15811 && flag_unsafe_math_optimizations"
15813 [(set_attr "type" "fpspc")
15814 (set_attr "mode" "DF")])
15816 (define_insn "*sinsf2"
15817 [(set (match_operand:SF 0 "register_operand" "=f")
15818 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15819 "TARGET_USE_FANCY_MATH_387
15820 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15821 && flag_unsafe_math_optimizations"
15823 [(set_attr "type" "fpspc")
15824 (set_attr "mode" "SF")])
15826 (define_insn "*sinextendsfdf2"
15827 [(set (match_operand:DF 0 "register_operand" "=f")
15828 (unspec:DF [(float_extend:DF
15829 (match_operand:SF 1 "register_operand" "0"))]
15831 "TARGET_USE_FANCY_MATH_387
15832 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15833 && flag_unsafe_math_optimizations"
15835 [(set_attr "type" "fpspc")
15836 (set_attr "mode" "DF")])
15838 (define_insn "*sinxf2"
15839 [(set (match_operand:XF 0 "register_operand" "=f")
15840 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15841 "TARGET_USE_FANCY_MATH_387
15842 && flag_unsafe_math_optimizations"
15844 [(set_attr "type" "fpspc")
15845 (set_attr "mode" "XF")])
15847 (define_insn "*cosdf2"
15848 [(set (match_operand:DF 0 "register_operand" "=f")
15849 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15850 "TARGET_USE_FANCY_MATH_387
15851 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15852 && flag_unsafe_math_optimizations"
15854 [(set_attr "type" "fpspc")
15855 (set_attr "mode" "DF")])
15857 (define_insn "*cossf2"
15858 [(set (match_operand:SF 0 "register_operand" "=f")
15859 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15860 "TARGET_USE_FANCY_MATH_387
15861 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15862 && flag_unsafe_math_optimizations"
15864 [(set_attr "type" "fpspc")
15865 (set_attr "mode" "SF")])
15867 (define_insn "*cosextendsfdf2"
15868 [(set (match_operand:DF 0 "register_operand" "=f")
15869 (unspec:DF [(float_extend:DF
15870 (match_operand:SF 1 "register_operand" "0"))]
15872 "TARGET_USE_FANCY_MATH_387
15873 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15874 && flag_unsafe_math_optimizations"
15876 [(set_attr "type" "fpspc")
15877 (set_attr "mode" "DF")])
15879 (define_insn "*cosxf2"
15880 [(set (match_operand:XF 0 "register_operand" "=f")
15881 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15882 "TARGET_USE_FANCY_MATH_387
15883 && flag_unsafe_math_optimizations"
15885 [(set_attr "type" "fpspc")
15886 (set_attr "mode" "XF")])
15888 ;; With sincos pattern defined, sin and cos builtin function will be
15889 ;; expanded to sincos pattern with one of its outputs left unused.
15890 ;; Cse pass will detected, if two sincos patterns can be combined,
15891 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15892 ;; depending on the unused output.
15894 (define_insn "sincosdf3"
15895 [(set (match_operand:DF 0 "register_operand" "=f")
15896 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15897 UNSPEC_SINCOS_COS))
15898 (set (match_operand:DF 1 "register_operand" "=u")
15899 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15900 "TARGET_USE_FANCY_MATH_387
15901 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15902 && flag_unsafe_math_optimizations"
15904 [(set_attr "type" "fpspc")
15905 (set_attr "mode" "DF")])
15908 [(set (match_operand:DF 0 "register_operand" "")
15909 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15910 UNSPEC_SINCOS_COS))
15911 (set (match_operand:DF 1 "register_operand" "")
15912 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15913 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15914 && !reload_completed && !reload_in_progress"
15915 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15919 [(set (match_operand:DF 0 "register_operand" "")
15920 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15921 UNSPEC_SINCOS_COS))
15922 (set (match_operand:DF 1 "register_operand" "")
15923 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15924 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15925 && !reload_completed && !reload_in_progress"
15926 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15929 (define_insn "sincossf3"
15930 [(set (match_operand:SF 0 "register_operand" "=f")
15931 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15932 UNSPEC_SINCOS_COS))
15933 (set (match_operand:SF 1 "register_operand" "=u")
15934 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15935 "TARGET_USE_FANCY_MATH_387
15936 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15937 && flag_unsafe_math_optimizations"
15939 [(set_attr "type" "fpspc")
15940 (set_attr "mode" "SF")])
15943 [(set (match_operand:SF 0 "register_operand" "")
15944 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15945 UNSPEC_SINCOS_COS))
15946 (set (match_operand:SF 1 "register_operand" "")
15947 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15948 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15949 && !reload_completed && !reload_in_progress"
15950 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15954 [(set (match_operand:SF 0 "register_operand" "")
15955 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15956 UNSPEC_SINCOS_COS))
15957 (set (match_operand:SF 1 "register_operand" "")
15958 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15959 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15960 && !reload_completed && !reload_in_progress"
15961 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15964 (define_insn "*sincosextendsfdf3"
15965 [(set (match_operand:DF 0 "register_operand" "=f")
15966 (unspec:DF [(float_extend:DF
15967 (match_operand:SF 2 "register_operand" "0"))]
15968 UNSPEC_SINCOS_COS))
15969 (set (match_operand:DF 1 "register_operand" "=u")
15970 (unspec:DF [(float_extend:DF
15971 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15972 "TARGET_USE_FANCY_MATH_387
15973 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15974 && flag_unsafe_math_optimizations"
15976 [(set_attr "type" "fpspc")
15977 (set_attr "mode" "DF")])
15980 [(set (match_operand:DF 0 "register_operand" "")
15981 (unspec:DF [(float_extend:DF
15982 (match_operand:SF 2 "register_operand" ""))]
15983 UNSPEC_SINCOS_COS))
15984 (set (match_operand:DF 1 "register_operand" "")
15985 (unspec:DF [(float_extend:DF
15986 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15987 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15988 && !reload_completed && !reload_in_progress"
15989 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15990 (match_dup 2))] UNSPEC_SIN))]
15994 [(set (match_operand:DF 0 "register_operand" "")
15995 (unspec:DF [(float_extend:DF
15996 (match_operand:SF 2 "register_operand" ""))]
15997 UNSPEC_SINCOS_COS))
15998 (set (match_operand:DF 1 "register_operand" "")
15999 (unspec:DF [(float_extend:DF
16000 (match_dup 2))] UNSPEC_SINCOS_SIN))]
16001 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16002 && !reload_completed && !reload_in_progress"
16003 [(set (match_dup 0) (unspec:DF [(float_extend:DF
16004 (match_dup 2))] UNSPEC_COS))]
16007 (define_insn "sincosxf3"
16008 [(set (match_operand:XF 0 "register_operand" "=f")
16009 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16010 UNSPEC_SINCOS_COS))
16011 (set (match_operand:XF 1 "register_operand" "=u")
16012 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16013 "TARGET_USE_FANCY_MATH_387
16014 && flag_unsafe_math_optimizations"
16016 [(set_attr "type" "fpspc")
16017 (set_attr "mode" "XF")])
16020 [(set (match_operand:XF 0 "register_operand" "")
16021 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16022 UNSPEC_SINCOS_COS))
16023 (set (match_operand:XF 1 "register_operand" "")
16024 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16025 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16026 && !reload_completed && !reload_in_progress"
16027 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16031 [(set (match_operand:XF 0 "register_operand" "")
16032 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16033 UNSPEC_SINCOS_COS))
16034 (set (match_operand:XF 1 "register_operand" "")
16035 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16036 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16037 && !reload_completed && !reload_in_progress"
16038 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16041 (define_insn "*tandf3_1"
16042 [(set (match_operand:DF 0 "register_operand" "=f")
16043 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16045 (set (match_operand:DF 1 "register_operand" "=u")
16046 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16047 "TARGET_USE_FANCY_MATH_387
16048 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16049 && flag_unsafe_math_optimizations"
16051 [(set_attr "type" "fpspc")
16052 (set_attr "mode" "DF")])
16054 ;; optimize sequence: fptan
16057 ;; into fptan insn.
16060 [(parallel[(set (match_operand:DF 0 "register_operand" "")
16061 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16063 (set (match_operand:DF 1 "register_operand" "")
16064 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16066 (match_operand:DF 3 "immediate_operand" ""))]
16067 "standard_80387_constant_p (operands[3]) == 2"
16068 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16069 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16072 (define_expand "tandf2"
16073 [(parallel [(set (match_dup 2)
16074 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16076 (set (match_operand:DF 0 "register_operand" "")
16077 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16078 "TARGET_USE_FANCY_MATH_387
16079 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16080 && flag_unsafe_math_optimizations"
16082 operands[2] = gen_reg_rtx (DFmode);
16085 (define_insn "*tansf3_1"
16086 [(set (match_operand:SF 0 "register_operand" "=f")
16087 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16089 (set (match_operand:SF 1 "register_operand" "=u")
16090 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16091 "TARGET_USE_FANCY_MATH_387
16092 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16093 && flag_unsafe_math_optimizations"
16095 [(set_attr "type" "fpspc")
16096 (set_attr "mode" "SF")])
16098 ;; optimize sequence: fptan
16101 ;; into fptan insn.
16104 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16105 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16107 (set (match_operand:SF 1 "register_operand" "")
16108 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16110 (match_operand:SF 3 "immediate_operand" ""))]
16111 "standard_80387_constant_p (operands[3]) == 2"
16112 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16113 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16116 (define_expand "tansf2"
16117 [(parallel [(set (match_dup 2)
16118 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16120 (set (match_operand:SF 0 "register_operand" "")
16121 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16122 "TARGET_USE_FANCY_MATH_387
16123 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16124 && flag_unsafe_math_optimizations"
16126 operands[2] = gen_reg_rtx (SFmode);
16129 (define_insn "*tanxf3_1"
16130 [(set (match_operand:XF 0 "register_operand" "=f")
16131 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16133 (set (match_operand:XF 1 "register_operand" "=u")
16134 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16135 "TARGET_USE_FANCY_MATH_387
16136 && flag_unsafe_math_optimizations"
16138 [(set_attr "type" "fpspc")
16139 (set_attr "mode" "XF")])
16141 ;; optimize sequence: fptan
16144 ;; into fptan insn.
16147 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16148 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16150 (set (match_operand:XF 1 "register_operand" "")
16151 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16153 (match_operand:XF 3 "immediate_operand" ""))]
16154 "standard_80387_constant_p (operands[3]) == 2"
16155 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16156 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16159 (define_expand "tanxf2"
16160 [(parallel [(set (match_dup 2)
16161 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16163 (set (match_operand:XF 0 "register_operand" "")
16164 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16165 "TARGET_USE_FANCY_MATH_387
16166 && flag_unsafe_math_optimizations"
16168 operands[2] = gen_reg_rtx (XFmode);
16171 (define_insn "atan2df3_1"
16172 [(set (match_operand:DF 0 "register_operand" "=f")
16173 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16174 (match_operand:DF 1 "register_operand" "u")]
16176 (clobber (match_scratch:DF 3 "=1"))]
16177 "TARGET_USE_FANCY_MATH_387
16178 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16179 && flag_unsafe_math_optimizations"
16181 [(set_attr "type" "fpspc")
16182 (set_attr "mode" "DF")])
16184 (define_expand "atan2df3"
16185 [(use (match_operand:DF 0 "register_operand" ""))
16186 (use (match_operand:DF 2 "register_operand" ""))
16187 (use (match_operand:DF 1 "register_operand" ""))]
16188 "TARGET_USE_FANCY_MATH_387
16189 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16190 && flag_unsafe_math_optimizations"
16192 rtx copy = gen_reg_rtx (DFmode);
16193 emit_move_insn (copy, operands[1]);
16194 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16198 (define_expand "atandf2"
16199 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16200 (unspec:DF [(match_dup 2)
16201 (match_operand:DF 1 "register_operand" "")]
16203 (clobber (match_scratch:DF 3 ""))])]
16204 "TARGET_USE_FANCY_MATH_387
16205 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16206 && flag_unsafe_math_optimizations"
16208 operands[2] = gen_reg_rtx (DFmode);
16209 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16212 (define_insn "atan2sf3_1"
16213 [(set (match_operand:SF 0 "register_operand" "=f")
16214 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16215 (match_operand:SF 1 "register_operand" "u")]
16217 (clobber (match_scratch:SF 3 "=1"))]
16218 "TARGET_USE_FANCY_MATH_387
16219 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16220 && flag_unsafe_math_optimizations"
16222 [(set_attr "type" "fpspc")
16223 (set_attr "mode" "SF")])
16225 (define_expand "atan2sf3"
16226 [(use (match_operand:SF 0 "register_operand" ""))
16227 (use (match_operand:SF 2 "register_operand" ""))
16228 (use (match_operand:SF 1 "register_operand" ""))]
16229 "TARGET_USE_FANCY_MATH_387
16230 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16231 && flag_unsafe_math_optimizations"
16233 rtx copy = gen_reg_rtx (SFmode);
16234 emit_move_insn (copy, operands[1]);
16235 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16239 (define_expand "atansf2"
16240 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16241 (unspec:SF [(match_dup 2)
16242 (match_operand:SF 1 "register_operand" "")]
16244 (clobber (match_scratch:SF 3 ""))])]
16245 "TARGET_USE_FANCY_MATH_387
16246 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16247 && flag_unsafe_math_optimizations"
16249 operands[2] = gen_reg_rtx (SFmode);
16250 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16253 (define_insn "atan2xf3_1"
16254 [(set (match_operand:XF 0 "register_operand" "=f")
16255 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16256 (match_operand:XF 1 "register_operand" "u")]
16258 (clobber (match_scratch:XF 3 "=1"))]
16259 "TARGET_USE_FANCY_MATH_387
16260 && flag_unsafe_math_optimizations"
16262 [(set_attr "type" "fpspc")
16263 (set_attr "mode" "XF")])
16265 (define_expand "atan2xf3"
16266 [(use (match_operand:XF 0 "register_operand" ""))
16267 (use (match_operand:XF 2 "register_operand" ""))
16268 (use (match_operand:XF 1 "register_operand" ""))]
16269 "TARGET_USE_FANCY_MATH_387
16270 && flag_unsafe_math_optimizations"
16272 rtx copy = gen_reg_rtx (XFmode);
16273 emit_move_insn (copy, operands[1]);
16274 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16278 (define_expand "atanxf2"
16279 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16280 (unspec:XF [(match_dup 2)
16281 (match_operand:XF 1 "register_operand" "")]
16283 (clobber (match_scratch:XF 3 ""))])]
16284 "TARGET_USE_FANCY_MATH_387
16285 && flag_unsafe_math_optimizations"
16287 operands[2] = gen_reg_rtx (XFmode);
16288 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16291 (define_expand "asindf2"
16292 [(set (match_dup 2)
16293 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16294 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16295 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16296 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16297 (parallel [(set (match_dup 7)
16298 (unspec:XF [(match_dup 6) (match_dup 2)]
16300 (clobber (match_scratch:XF 8 ""))])
16301 (set (match_operand:DF 0 "register_operand" "")
16302 (float_truncate:DF (match_dup 7)))]
16303 "TARGET_USE_FANCY_MATH_387
16304 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16305 && flag_unsafe_math_optimizations && !optimize_size"
16309 for (i=2; i<8; i++)
16310 operands[i] = gen_reg_rtx (XFmode);
16312 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16315 (define_expand "asinsf2"
16316 [(set (match_dup 2)
16317 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16318 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16319 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16320 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16321 (parallel [(set (match_dup 7)
16322 (unspec:XF [(match_dup 6) (match_dup 2)]
16324 (clobber (match_scratch:XF 8 ""))])
16325 (set (match_operand:SF 0 "register_operand" "")
16326 (float_truncate:SF (match_dup 7)))]
16327 "TARGET_USE_FANCY_MATH_387
16328 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16329 && flag_unsafe_math_optimizations && !optimize_size"
16333 for (i=2; i<8; i++)
16334 operands[i] = gen_reg_rtx (XFmode);
16336 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16339 (define_expand "asinxf2"
16340 [(set (match_dup 2)
16341 (mult:XF (match_operand:XF 1 "register_operand" "")
16343 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16344 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16345 (parallel [(set (match_operand:XF 0 "register_operand" "")
16346 (unspec:XF [(match_dup 5) (match_dup 1)]
16348 (clobber (match_scratch:XF 6 ""))])]
16349 "TARGET_USE_FANCY_MATH_387
16350 && flag_unsafe_math_optimizations && !optimize_size"
16354 for (i=2; i<6; i++)
16355 operands[i] = gen_reg_rtx (XFmode);
16357 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16360 (define_expand "acosdf2"
16361 [(set (match_dup 2)
16362 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16363 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16364 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16365 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16366 (parallel [(set (match_dup 7)
16367 (unspec:XF [(match_dup 2) (match_dup 6)]
16369 (clobber (match_scratch:XF 8 ""))])
16370 (set (match_operand:DF 0 "register_operand" "")
16371 (float_truncate:DF (match_dup 7)))]
16372 "TARGET_USE_FANCY_MATH_387
16373 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16374 && flag_unsafe_math_optimizations && !optimize_size"
16378 for (i=2; i<8; i++)
16379 operands[i] = gen_reg_rtx (XFmode);
16381 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16384 (define_expand "acossf2"
16385 [(set (match_dup 2)
16386 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16387 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16388 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16389 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16390 (parallel [(set (match_dup 7)
16391 (unspec:XF [(match_dup 2) (match_dup 6)]
16393 (clobber (match_scratch:XF 8 ""))])
16394 (set (match_operand:SF 0 "register_operand" "")
16395 (float_truncate:SF (match_dup 7)))]
16396 "TARGET_USE_FANCY_MATH_387
16397 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16398 && flag_unsafe_math_optimizations && !optimize_size"
16402 for (i=2; i<8; i++)
16403 operands[i] = gen_reg_rtx (XFmode);
16405 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16408 (define_expand "acosxf2"
16409 [(set (match_dup 2)
16410 (mult:XF (match_operand:XF 1 "register_operand" "")
16412 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16413 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16414 (parallel [(set (match_operand:XF 0 "register_operand" "")
16415 (unspec:XF [(match_dup 1) (match_dup 5)]
16417 (clobber (match_scratch:XF 6 ""))])]
16418 "TARGET_USE_FANCY_MATH_387
16419 && flag_unsafe_math_optimizations && !optimize_size"
16423 for (i=2; i<6; i++)
16424 operands[i] = gen_reg_rtx (XFmode);
16426 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16429 (define_insn "fyl2x_xf3"
16430 [(set (match_operand:XF 0 "register_operand" "=f")
16431 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16432 (match_operand:XF 1 "register_operand" "u")]
16434 (clobber (match_scratch:XF 3 "=1"))]
16435 "TARGET_USE_FANCY_MATH_387
16436 && flag_unsafe_math_optimizations"
16438 [(set_attr "type" "fpspc")
16439 (set_attr "mode" "XF")])
16441 (define_expand "logsf2"
16442 [(set (match_dup 2)
16443 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16444 (parallel [(set (match_dup 4)
16445 (unspec:XF [(match_dup 2)
16446 (match_dup 3)] UNSPEC_FYL2X))
16447 (clobber (match_scratch:XF 5 ""))])
16448 (set (match_operand:SF 0 "register_operand" "")
16449 (float_truncate:SF (match_dup 4)))]
16450 "TARGET_USE_FANCY_MATH_387
16451 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16452 && flag_unsafe_math_optimizations"
16456 operands[2] = gen_reg_rtx (XFmode);
16457 operands[3] = gen_reg_rtx (XFmode);
16458 operands[4] = gen_reg_rtx (XFmode);
16460 temp = standard_80387_constant_rtx (4); /* fldln2 */
16461 emit_move_insn (operands[3], temp);
16464 (define_expand "logdf2"
16465 [(set (match_dup 2)
16466 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16467 (parallel [(set (match_dup 4)
16468 (unspec:XF [(match_dup 2)
16469 (match_dup 3)] UNSPEC_FYL2X))
16470 (clobber (match_scratch:XF 5 ""))])
16471 (set (match_operand:DF 0 "register_operand" "")
16472 (float_truncate:DF (match_dup 4)))]
16473 "TARGET_USE_FANCY_MATH_387
16474 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16475 && flag_unsafe_math_optimizations"
16479 operands[2] = gen_reg_rtx (XFmode);
16480 operands[3] = gen_reg_rtx (XFmode);
16481 operands[4] = gen_reg_rtx (XFmode);
16483 temp = standard_80387_constant_rtx (4); /* fldln2 */
16484 emit_move_insn (operands[3], temp);
16487 (define_expand "logxf2"
16488 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16489 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16490 (match_dup 2)] UNSPEC_FYL2X))
16491 (clobber (match_scratch:XF 3 ""))])]
16492 "TARGET_USE_FANCY_MATH_387
16493 && flag_unsafe_math_optimizations"
16497 operands[2] = gen_reg_rtx (XFmode);
16498 temp = standard_80387_constant_rtx (4); /* fldln2 */
16499 emit_move_insn (operands[2], temp);
16502 (define_expand "log10sf2"
16503 [(set (match_dup 2)
16504 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16505 (parallel [(set (match_dup 4)
16506 (unspec:XF [(match_dup 2)
16507 (match_dup 3)] UNSPEC_FYL2X))
16508 (clobber (match_scratch:XF 5 ""))])
16509 (set (match_operand:SF 0 "register_operand" "")
16510 (float_truncate:SF (match_dup 4)))]
16511 "TARGET_USE_FANCY_MATH_387
16512 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16513 && flag_unsafe_math_optimizations"
16517 operands[2] = gen_reg_rtx (XFmode);
16518 operands[3] = gen_reg_rtx (XFmode);
16519 operands[4] = gen_reg_rtx (XFmode);
16521 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16522 emit_move_insn (operands[3], temp);
16525 (define_expand "log10df2"
16526 [(set (match_dup 2)
16527 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16528 (parallel [(set (match_dup 4)
16529 (unspec:XF [(match_dup 2)
16530 (match_dup 3)] UNSPEC_FYL2X))
16531 (clobber (match_scratch:XF 5 ""))])
16532 (set (match_operand:DF 0 "register_operand" "")
16533 (float_truncate:DF (match_dup 4)))]
16534 "TARGET_USE_FANCY_MATH_387
16535 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16536 && flag_unsafe_math_optimizations"
16540 operands[2] = gen_reg_rtx (XFmode);
16541 operands[3] = gen_reg_rtx (XFmode);
16542 operands[4] = gen_reg_rtx (XFmode);
16544 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16545 emit_move_insn (operands[3], temp);
16548 (define_expand "log10xf2"
16549 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16550 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16551 (match_dup 2)] UNSPEC_FYL2X))
16552 (clobber (match_scratch:XF 3 ""))])]
16553 "TARGET_USE_FANCY_MATH_387
16554 && flag_unsafe_math_optimizations"
16558 operands[2] = gen_reg_rtx (XFmode);
16559 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16560 emit_move_insn (operands[2], temp);
16563 (define_expand "log2sf2"
16564 [(set (match_dup 2)
16565 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16566 (parallel [(set (match_dup 4)
16567 (unspec:XF [(match_dup 2)
16568 (match_dup 3)] UNSPEC_FYL2X))
16569 (clobber (match_scratch:XF 5 ""))])
16570 (set (match_operand:SF 0 "register_operand" "")
16571 (float_truncate:SF (match_dup 4)))]
16572 "TARGET_USE_FANCY_MATH_387
16573 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16574 && flag_unsafe_math_optimizations"
16576 operands[2] = gen_reg_rtx (XFmode);
16577 operands[3] = gen_reg_rtx (XFmode);
16578 operands[4] = gen_reg_rtx (XFmode);
16580 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16583 (define_expand "log2df2"
16584 [(set (match_dup 2)
16585 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16586 (parallel [(set (match_dup 4)
16587 (unspec:XF [(match_dup 2)
16588 (match_dup 3)] UNSPEC_FYL2X))
16589 (clobber (match_scratch:XF 5 ""))])
16590 (set (match_operand:DF 0 "register_operand" "")
16591 (float_truncate:DF (match_dup 4)))]
16592 "TARGET_USE_FANCY_MATH_387
16593 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16594 && flag_unsafe_math_optimizations"
16596 operands[2] = gen_reg_rtx (XFmode);
16597 operands[3] = gen_reg_rtx (XFmode);
16598 operands[4] = gen_reg_rtx (XFmode);
16600 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16603 (define_expand "log2xf2"
16604 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16605 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16606 (match_dup 2)] UNSPEC_FYL2X))
16607 (clobber (match_scratch:XF 3 ""))])]
16608 "TARGET_USE_FANCY_MATH_387
16609 && flag_unsafe_math_optimizations"
16611 operands[2] = gen_reg_rtx (XFmode);
16612 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16615 (define_insn "fyl2xp1_xf3"
16616 [(set (match_operand:XF 0 "register_operand" "=f")
16617 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16618 (match_operand:XF 1 "register_operand" "u")]
16620 (clobber (match_scratch:XF 3 "=1"))]
16621 "TARGET_USE_FANCY_MATH_387
16622 && flag_unsafe_math_optimizations"
16624 [(set_attr "type" "fpspc")
16625 (set_attr "mode" "XF")])
16627 (define_expand "log1psf2"
16628 [(use (match_operand:SF 0 "register_operand" ""))
16629 (use (match_operand:SF 1 "register_operand" ""))]
16630 "TARGET_USE_FANCY_MATH_387
16631 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16632 && flag_unsafe_math_optimizations && !optimize_size"
16634 rtx op0 = gen_reg_rtx (XFmode);
16635 rtx op1 = gen_reg_rtx (XFmode);
16637 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16638 ix86_emit_i387_log1p (op0, op1);
16639 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16643 (define_expand "log1pdf2"
16644 [(use (match_operand:DF 0 "register_operand" ""))
16645 (use (match_operand:DF 1 "register_operand" ""))]
16646 "TARGET_USE_FANCY_MATH_387
16647 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16648 && flag_unsafe_math_optimizations && !optimize_size"
16650 rtx op0 = gen_reg_rtx (XFmode);
16651 rtx op1 = gen_reg_rtx (XFmode);
16653 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16654 ix86_emit_i387_log1p (op0, op1);
16655 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16659 (define_expand "log1pxf2"
16660 [(use (match_operand:XF 0 "register_operand" ""))
16661 (use (match_operand:XF 1 "register_operand" ""))]
16662 "TARGET_USE_FANCY_MATH_387
16663 && flag_unsafe_math_optimizations && !optimize_size"
16665 ix86_emit_i387_log1p (operands[0], operands[1]);
16669 (define_insn "*fxtractxf3"
16670 [(set (match_operand:XF 0 "register_operand" "=f")
16671 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16672 UNSPEC_XTRACT_FRACT))
16673 (set (match_operand:XF 1 "register_operand" "=u")
16674 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16675 "TARGET_USE_FANCY_MATH_387
16676 && flag_unsafe_math_optimizations"
16678 [(set_attr "type" "fpspc")
16679 (set_attr "mode" "XF")])
16681 (define_expand "logbsf2"
16682 [(set (match_dup 2)
16683 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16684 (parallel [(set (match_dup 3)
16685 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16687 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16688 (set (match_operand:SF 0 "register_operand" "")
16689 (float_truncate:SF (match_dup 4)))]
16690 "TARGET_USE_FANCY_MATH_387
16691 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16692 && flag_unsafe_math_optimizations"
16694 operands[2] = gen_reg_rtx (XFmode);
16695 operands[3] = gen_reg_rtx (XFmode);
16696 operands[4] = gen_reg_rtx (XFmode);
16699 (define_expand "logbdf2"
16700 [(set (match_dup 2)
16701 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16702 (parallel [(set (match_dup 3)
16703 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16705 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16706 (set (match_operand:DF 0 "register_operand" "")
16707 (float_truncate:DF (match_dup 4)))]
16708 "TARGET_USE_FANCY_MATH_387
16709 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16710 && flag_unsafe_math_optimizations"
16712 operands[2] = gen_reg_rtx (XFmode);
16713 operands[3] = gen_reg_rtx (XFmode);
16714 operands[4] = gen_reg_rtx (XFmode);
16717 (define_expand "logbxf2"
16718 [(parallel [(set (match_dup 2)
16719 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16720 UNSPEC_XTRACT_FRACT))
16721 (set (match_operand:XF 0 "register_operand" "")
16722 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16723 "TARGET_USE_FANCY_MATH_387
16724 && flag_unsafe_math_optimizations"
16726 operands[2] = gen_reg_rtx (XFmode);
16729 (define_expand "ilogbsi2"
16730 [(parallel [(set (match_dup 2)
16731 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16732 UNSPEC_XTRACT_FRACT))
16733 (set (match_operand:XF 3 "register_operand" "")
16734 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16735 (parallel [(set (match_operand:SI 0 "register_operand" "")
16736 (fix:SI (match_dup 3)))
16737 (clobber (reg:CC FLAGS_REG))])]
16738 "TARGET_USE_FANCY_MATH_387
16739 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16740 && flag_unsafe_math_optimizations && !optimize_size"
16742 operands[2] = gen_reg_rtx (XFmode);
16743 operands[3] = gen_reg_rtx (XFmode);
16746 (define_insn "*f2xm1xf2"
16747 [(set (match_operand:XF 0 "register_operand" "=f")
16748 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16750 "TARGET_USE_FANCY_MATH_387
16751 && flag_unsafe_math_optimizations"
16753 [(set_attr "type" "fpspc")
16754 (set_attr "mode" "XF")])
16756 (define_insn "*fscalexf4"
16757 [(set (match_operand:XF 0 "register_operand" "=f")
16758 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16759 (match_operand:XF 3 "register_operand" "1")]
16760 UNSPEC_FSCALE_FRACT))
16761 (set (match_operand:XF 1 "register_operand" "=u")
16762 (unspec:XF [(match_dup 2) (match_dup 3)]
16763 UNSPEC_FSCALE_EXP))]
16764 "TARGET_USE_FANCY_MATH_387
16765 && flag_unsafe_math_optimizations"
16767 [(set_attr "type" "fpspc")
16768 (set_attr "mode" "XF")])
16770 (define_expand "expsf2"
16771 [(set (match_dup 2)
16772 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16773 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16774 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16775 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16776 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16777 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16778 (parallel [(set (match_dup 10)
16779 (unspec:XF [(match_dup 9) (match_dup 5)]
16780 UNSPEC_FSCALE_FRACT))
16781 (set (match_dup 11)
16782 (unspec:XF [(match_dup 9) (match_dup 5)]
16783 UNSPEC_FSCALE_EXP))])
16784 (set (match_operand:SF 0 "register_operand" "")
16785 (float_truncate:SF (match_dup 10)))]
16786 "TARGET_USE_FANCY_MATH_387
16787 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16788 && flag_unsafe_math_optimizations && !optimize_size"
16793 for (i=2; i<12; i++)
16794 operands[i] = gen_reg_rtx (XFmode);
16795 temp = standard_80387_constant_rtx (5); /* fldl2e */
16796 emit_move_insn (operands[3], temp);
16797 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16800 (define_expand "expdf2"
16801 [(set (match_dup 2)
16802 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16803 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16804 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16805 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16806 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16807 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16808 (parallel [(set (match_dup 10)
16809 (unspec:XF [(match_dup 9) (match_dup 5)]
16810 UNSPEC_FSCALE_FRACT))
16811 (set (match_dup 11)
16812 (unspec:XF [(match_dup 9) (match_dup 5)]
16813 UNSPEC_FSCALE_EXP))])
16814 (set (match_operand:DF 0 "register_operand" "")
16815 (float_truncate:DF (match_dup 10)))]
16816 "TARGET_USE_FANCY_MATH_387
16817 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16818 && flag_unsafe_math_optimizations && !optimize_size"
16823 for (i=2; i<12; i++)
16824 operands[i] = gen_reg_rtx (XFmode);
16825 temp = standard_80387_constant_rtx (5); /* fldl2e */
16826 emit_move_insn (operands[3], temp);
16827 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16830 (define_expand "expxf2"
16831 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16833 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16834 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16835 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16836 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16837 (parallel [(set (match_operand:XF 0 "register_operand" "")
16838 (unspec:XF [(match_dup 8) (match_dup 4)]
16839 UNSPEC_FSCALE_FRACT))
16841 (unspec:XF [(match_dup 8) (match_dup 4)]
16842 UNSPEC_FSCALE_EXP))])]
16843 "TARGET_USE_FANCY_MATH_387
16844 && flag_unsafe_math_optimizations && !optimize_size"
16849 for (i=2; i<10; i++)
16850 operands[i] = gen_reg_rtx (XFmode);
16851 temp = standard_80387_constant_rtx (5); /* fldl2e */
16852 emit_move_insn (operands[2], temp);
16853 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16856 (define_expand "exp10sf2"
16857 [(set (match_dup 2)
16858 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16859 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16860 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16861 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16862 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16863 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16864 (parallel [(set (match_dup 10)
16865 (unspec:XF [(match_dup 9) (match_dup 5)]
16866 UNSPEC_FSCALE_FRACT))
16867 (set (match_dup 11)
16868 (unspec:XF [(match_dup 9) (match_dup 5)]
16869 UNSPEC_FSCALE_EXP))])
16870 (set (match_operand:SF 0 "register_operand" "")
16871 (float_truncate:SF (match_dup 10)))]
16872 "TARGET_USE_FANCY_MATH_387
16873 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16874 && flag_unsafe_math_optimizations && !optimize_size"
16879 for (i=2; i<12; i++)
16880 operands[i] = gen_reg_rtx (XFmode);
16881 temp = standard_80387_constant_rtx (6); /* fldl2t */
16882 emit_move_insn (operands[3], temp);
16883 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16886 (define_expand "exp10df2"
16887 [(set (match_dup 2)
16888 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16889 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16890 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16891 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16892 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16893 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16894 (parallel [(set (match_dup 10)
16895 (unspec:XF [(match_dup 9) (match_dup 5)]
16896 UNSPEC_FSCALE_FRACT))
16897 (set (match_dup 11)
16898 (unspec:XF [(match_dup 9) (match_dup 5)]
16899 UNSPEC_FSCALE_EXP))])
16900 (set (match_operand:DF 0 "register_operand" "")
16901 (float_truncate:DF (match_dup 10)))]
16902 "TARGET_USE_FANCY_MATH_387
16903 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16904 && flag_unsafe_math_optimizations && !optimize_size"
16909 for (i=2; i<12; i++)
16910 operands[i] = gen_reg_rtx (XFmode);
16911 temp = standard_80387_constant_rtx (6); /* fldl2t */
16912 emit_move_insn (operands[3], temp);
16913 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16916 (define_expand "exp10xf2"
16917 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16919 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16920 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16921 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16922 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16923 (parallel [(set (match_operand:XF 0 "register_operand" "")
16924 (unspec:XF [(match_dup 8) (match_dup 4)]
16925 UNSPEC_FSCALE_FRACT))
16927 (unspec:XF [(match_dup 8) (match_dup 4)]
16928 UNSPEC_FSCALE_EXP))])]
16929 "TARGET_USE_FANCY_MATH_387
16930 && flag_unsafe_math_optimizations && !optimize_size"
16935 for (i=2; i<10; i++)
16936 operands[i] = gen_reg_rtx (XFmode);
16937 temp = standard_80387_constant_rtx (6); /* fldl2t */
16938 emit_move_insn (operands[2], temp);
16939 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16942 (define_expand "exp2sf2"
16943 [(set (match_dup 2)
16944 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16945 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16946 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16947 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16948 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16949 (parallel [(set (match_dup 8)
16950 (unspec:XF [(match_dup 7) (match_dup 3)]
16951 UNSPEC_FSCALE_FRACT))
16953 (unspec:XF [(match_dup 7) (match_dup 3)]
16954 UNSPEC_FSCALE_EXP))])
16955 (set (match_operand:SF 0 "register_operand" "")
16956 (float_truncate:SF (match_dup 8)))]
16957 "TARGET_USE_FANCY_MATH_387
16958 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16959 && flag_unsafe_math_optimizations && !optimize_size"
16963 for (i=2; i<10; i++)
16964 operands[i] = gen_reg_rtx (XFmode);
16965 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16968 (define_expand "exp2df2"
16969 [(set (match_dup 2)
16970 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16971 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16972 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16973 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16974 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16975 (parallel [(set (match_dup 8)
16976 (unspec:XF [(match_dup 7) (match_dup 3)]
16977 UNSPEC_FSCALE_FRACT))
16979 (unspec:XF [(match_dup 7) (match_dup 3)]
16980 UNSPEC_FSCALE_EXP))])
16981 (set (match_operand:DF 0 "register_operand" "")
16982 (float_truncate:DF (match_dup 8)))]
16983 "TARGET_USE_FANCY_MATH_387
16984 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16985 && flag_unsafe_math_optimizations && !optimize_size"
16989 for (i=2; i<10; i++)
16990 operands[i] = gen_reg_rtx (XFmode);
16991 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16994 (define_expand "exp2xf2"
16995 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16996 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16997 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16998 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16999 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17000 (parallel [(set (match_operand:XF 0 "register_operand" "")
17001 (unspec:XF [(match_dup 7) (match_dup 3)]
17002 UNSPEC_FSCALE_FRACT))
17004 (unspec:XF [(match_dup 7) (match_dup 3)]
17005 UNSPEC_FSCALE_EXP))])]
17006 "TARGET_USE_FANCY_MATH_387
17007 && flag_unsafe_math_optimizations && !optimize_size"
17011 for (i=2; i<9; i++)
17012 operands[i] = gen_reg_rtx (XFmode);
17013 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
17016 (define_expand "expm1df2"
17017 [(set (match_dup 2)
17018 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17019 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17020 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17021 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17022 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17023 (parallel [(set (match_dup 8)
17024 (unspec:XF [(match_dup 7) (match_dup 5)]
17025 UNSPEC_FSCALE_FRACT))
17027 (unspec:XF [(match_dup 7) (match_dup 5)]
17028 UNSPEC_FSCALE_EXP))])
17029 (parallel [(set (match_dup 11)
17030 (unspec:XF [(match_dup 10) (match_dup 9)]
17031 UNSPEC_FSCALE_FRACT))
17032 (set (match_dup 12)
17033 (unspec:XF [(match_dup 10) (match_dup 9)]
17034 UNSPEC_FSCALE_EXP))])
17035 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17036 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17037 (set (match_operand:DF 0 "register_operand" "")
17038 (float_truncate:DF (match_dup 14)))]
17039 "TARGET_USE_FANCY_MATH_387
17040 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17041 && flag_unsafe_math_optimizations && !optimize_size"
17046 for (i=2; i<15; i++)
17047 operands[i] = gen_reg_rtx (XFmode);
17048 temp = standard_80387_constant_rtx (5); /* fldl2e */
17049 emit_move_insn (operands[3], temp);
17050 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17053 (define_expand "expm1sf2"
17054 [(set (match_dup 2)
17055 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17056 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17057 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17058 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17059 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17060 (parallel [(set (match_dup 8)
17061 (unspec:XF [(match_dup 7) (match_dup 5)]
17062 UNSPEC_FSCALE_FRACT))
17064 (unspec:XF [(match_dup 7) (match_dup 5)]
17065 UNSPEC_FSCALE_EXP))])
17066 (parallel [(set (match_dup 11)
17067 (unspec:XF [(match_dup 10) (match_dup 9)]
17068 UNSPEC_FSCALE_FRACT))
17069 (set (match_dup 12)
17070 (unspec:XF [(match_dup 10) (match_dup 9)]
17071 UNSPEC_FSCALE_EXP))])
17072 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17073 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17074 (set (match_operand:SF 0 "register_operand" "")
17075 (float_truncate:SF (match_dup 14)))]
17076 "TARGET_USE_FANCY_MATH_387
17077 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17078 && flag_unsafe_math_optimizations && !optimize_size"
17083 for (i=2; i<15; i++)
17084 operands[i] = gen_reg_rtx (XFmode);
17085 temp = standard_80387_constant_rtx (5); /* fldl2e */
17086 emit_move_insn (operands[3], temp);
17087 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17090 (define_expand "expm1xf2"
17091 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17093 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17094 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17095 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17096 (parallel [(set (match_dup 7)
17097 (unspec:XF [(match_dup 6) (match_dup 4)]
17098 UNSPEC_FSCALE_FRACT))
17100 (unspec:XF [(match_dup 6) (match_dup 4)]
17101 UNSPEC_FSCALE_EXP))])
17102 (parallel [(set (match_dup 10)
17103 (unspec:XF [(match_dup 9) (match_dup 8)]
17104 UNSPEC_FSCALE_FRACT))
17105 (set (match_dup 11)
17106 (unspec:XF [(match_dup 9) (match_dup 8)]
17107 UNSPEC_FSCALE_EXP))])
17108 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17109 (set (match_operand:XF 0 "register_operand" "")
17110 (plus:XF (match_dup 12) (match_dup 7)))]
17111 "TARGET_USE_FANCY_MATH_387
17112 && flag_unsafe_math_optimizations && !optimize_size"
17117 for (i=2; i<13; i++)
17118 operands[i] = gen_reg_rtx (XFmode);
17119 temp = standard_80387_constant_rtx (5); /* fldl2e */
17120 emit_move_insn (operands[2], temp);
17121 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17124 (define_expand "ldexpdf3"
17125 [(set (match_dup 3)
17126 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17128 (float:XF (match_operand:SI 2 "register_operand" "")))
17129 (parallel [(set (match_dup 5)
17130 (unspec:XF [(match_dup 3) (match_dup 4)]
17131 UNSPEC_FSCALE_FRACT))
17133 (unspec:XF [(match_dup 3) (match_dup 4)]
17134 UNSPEC_FSCALE_EXP))])
17135 (set (match_operand:DF 0 "register_operand" "")
17136 (float_truncate:DF (match_dup 5)))]
17137 "TARGET_USE_FANCY_MATH_387
17138 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17139 && flag_unsafe_math_optimizations && !optimize_size"
17143 for (i=3; i<7; i++)
17144 operands[i] = gen_reg_rtx (XFmode);
17147 (define_expand "ldexpsf3"
17148 [(set (match_dup 3)
17149 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17151 (float:XF (match_operand:SI 2 "register_operand" "")))
17152 (parallel [(set (match_dup 5)
17153 (unspec:XF [(match_dup 3) (match_dup 4)]
17154 UNSPEC_FSCALE_FRACT))
17156 (unspec:XF [(match_dup 3) (match_dup 4)]
17157 UNSPEC_FSCALE_EXP))])
17158 (set (match_operand:SF 0 "register_operand" "")
17159 (float_truncate:SF (match_dup 5)))]
17160 "TARGET_USE_FANCY_MATH_387
17161 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17162 && flag_unsafe_math_optimizations && !optimize_size"
17166 for (i=3; i<7; i++)
17167 operands[i] = gen_reg_rtx (XFmode);
17170 (define_expand "ldexpxf3"
17171 [(set (match_dup 3)
17172 (float:XF (match_operand:SI 2 "register_operand" "")))
17173 (parallel [(set (match_operand:XF 0 " register_operand" "")
17174 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17176 UNSPEC_FSCALE_FRACT))
17178 (unspec:XF [(match_dup 1) (match_dup 3)]
17179 UNSPEC_FSCALE_EXP))])]
17180 "TARGET_USE_FANCY_MATH_387
17181 && flag_unsafe_math_optimizations && !optimize_size"
17185 for (i=3; i<5; i++)
17186 operands[i] = gen_reg_rtx (XFmode);
17190 (define_insn "frndintxf2"
17191 [(set (match_operand:XF 0 "register_operand" "=f")
17192 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17194 "TARGET_USE_FANCY_MATH_387
17195 && flag_unsafe_math_optimizations"
17197 [(set_attr "type" "fpspc")
17198 (set_attr "mode" "XF")])
17200 (define_expand "rintdf2"
17201 [(use (match_operand:DF 0 "register_operand" ""))
17202 (use (match_operand:DF 1 "register_operand" ""))]
17203 "(TARGET_USE_FANCY_MATH_387
17204 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17205 && flag_unsafe_math_optimizations)
17206 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17207 && !flag_trapping_math
17208 && !optimize_size)"
17210 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17211 && !flag_trapping_math
17213 ix86_expand_rint (operand0, operand1);
17216 rtx op0 = gen_reg_rtx (XFmode);
17217 rtx op1 = gen_reg_rtx (XFmode);
17219 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17220 emit_insn (gen_frndintxf2 (op0, op1));
17222 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17227 (define_expand "rintsf2"
17228 [(use (match_operand:SF 0 "register_operand" ""))
17229 (use (match_operand:SF 1 "register_operand" ""))]
17230 "(TARGET_USE_FANCY_MATH_387
17231 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17232 && flag_unsafe_math_optimizations)
17233 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17234 && !flag_trapping_math
17235 && !optimize_size)"
17237 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17238 && !flag_trapping_math
17240 ix86_expand_rint (operand0, operand1);
17243 rtx op0 = gen_reg_rtx (XFmode);
17244 rtx op1 = gen_reg_rtx (XFmode);
17246 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17247 emit_insn (gen_frndintxf2 (op0, op1));
17249 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17254 (define_expand "rintxf2"
17255 [(use (match_operand:XF 0 "register_operand" ""))
17256 (use (match_operand:XF 1 "register_operand" ""))]
17257 "TARGET_USE_FANCY_MATH_387
17258 && flag_unsafe_math_optimizations && !optimize_size"
17260 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17264 (define_expand "roundsf2"
17265 [(match_operand:SF 0 "register_operand" "")
17266 (match_operand:SF 1 "nonimmediate_operand" "")]
17267 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17268 && !flag_trapping_math && !flag_rounding_math
17271 ix86_expand_round (operand0, operand1);
17275 (define_expand "rounddf2"
17276 [(match_operand:DF 0 "register_operand" "")
17277 (match_operand:DF 1 "nonimmediate_operand" "")]
17278 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17279 && !flag_trapping_math && !flag_rounding_math
17283 ix86_expand_round (operand0, operand1);
17285 ix86_expand_rounddf_32 (operand0, operand1);
17289 (define_insn_and_split "*fistdi2_1"
17290 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17291 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17293 "TARGET_USE_FANCY_MATH_387
17294 && !(reload_completed || reload_in_progress)"
17299 if (memory_operand (operands[0], VOIDmode))
17300 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17303 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17304 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17309 [(set_attr "type" "fpspc")
17310 (set_attr "mode" "DI")])
17312 (define_insn "fistdi2"
17313 [(set (match_operand:DI 0 "memory_operand" "=m")
17314 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17316 (clobber (match_scratch:XF 2 "=&1f"))]
17317 "TARGET_USE_FANCY_MATH_387"
17318 "* return output_fix_trunc (insn, operands, 0);"
17319 [(set_attr "type" "fpspc")
17320 (set_attr "mode" "DI")])
17322 (define_insn "fistdi2_with_temp"
17323 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17324 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17326 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17327 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17328 "TARGET_USE_FANCY_MATH_387"
17330 [(set_attr "type" "fpspc")
17331 (set_attr "mode" "DI")])
17334 [(set (match_operand:DI 0 "register_operand" "")
17335 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17337 (clobber (match_operand:DI 2 "memory_operand" ""))
17338 (clobber (match_scratch 3 ""))]
17340 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17341 (clobber (match_dup 3))])
17342 (set (match_dup 0) (match_dup 2))]
17346 [(set (match_operand:DI 0 "memory_operand" "")
17347 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17349 (clobber (match_operand:DI 2 "memory_operand" ""))
17350 (clobber (match_scratch 3 ""))]
17352 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17353 (clobber (match_dup 3))])]
17356 (define_insn_and_split "*fist<mode>2_1"
17357 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17358 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17360 "TARGET_USE_FANCY_MATH_387
17361 && !(reload_completed || reload_in_progress)"
17366 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17367 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17371 [(set_attr "type" "fpspc")
17372 (set_attr "mode" "<MODE>")])
17374 (define_insn "fist<mode>2"
17375 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17376 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17378 "TARGET_USE_FANCY_MATH_387"
17379 "* return output_fix_trunc (insn, operands, 0);"
17380 [(set_attr "type" "fpspc")
17381 (set_attr "mode" "<MODE>")])
17383 (define_insn "fist<mode>2_with_temp"
17384 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17385 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17387 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17388 "TARGET_USE_FANCY_MATH_387"
17390 [(set_attr "type" "fpspc")
17391 (set_attr "mode" "<MODE>")])
17394 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17395 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17397 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17399 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17401 (set (match_dup 0) (match_dup 2))]
17405 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17406 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17408 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17410 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17414 (define_expand "lrintxf<mode>2"
17415 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17416 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17418 "TARGET_USE_FANCY_MATH_387"
17421 (define_expand "lrint<mode>di2"
17422 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17423 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17424 UNSPEC_FIX_NOTRUNC))]
17425 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17428 (define_expand "lrint<mode>si2"
17429 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17430 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17431 UNSPEC_FIX_NOTRUNC))]
17432 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17435 (define_expand "lround<mode>di2"
17436 [(match_operand:DI 0 "nonimmediate_operand" "")
17437 (match_operand:SSEMODEF 1 "register_operand" "")]
17438 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17439 && !flag_trapping_math && !flag_rounding_math
17442 ix86_expand_lround (operand0, operand1);
17446 (define_expand "lround<mode>si2"
17447 [(match_operand:SI 0 "nonimmediate_operand" "")
17448 (match_operand:SSEMODEF 1 "register_operand" "")]
17449 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17450 && !flag_trapping_math && !flag_rounding_math
17453 ix86_expand_lround (operand0, operand1);
17457 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17458 (define_insn_and_split "frndintxf2_floor"
17459 [(set (match_operand:XF 0 "register_operand" "=f")
17460 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17461 UNSPEC_FRNDINT_FLOOR))
17462 (clobber (reg:CC FLAGS_REG))]
17463 "TARGET_USE_FANCY_MATH_387
17464 && flag_unsafe_math_optimizations
17465 && !(reload_completed || reload_in_progress)"
17470 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17472 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17473 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17475 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17476 operands[2], operands[3]));
17479 [(set_attr "type" "frndint")
17480 (set_attr "i387_cw" "floor")
17481 (set_attr "mode" "XF")])
17483 (define_insn "frndintxf2_floor_i387"
17484 [(set (match_operand:XF 0 "register_operand" "=f")
17485 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17486 UNSPEC_FRNDINT_FLOOR))
17487 (use (match_operand:HI 2 "memory_operand" "m"))
17488 (use (match_operand:HI 3 "memory_operand" "m"))]
17489 "TARGET_USE_FANCY_MATH_387
17490 && flag_unsafe_math_optimizations"
17491 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17492 [(set_attr "type" "frndint")
17493 (set_attr "i387_cw" "floor")
17494 (set_attr "mode" "XF")])
17496 (define_expand "floorxf2"
17497 [(use (match_operand:XF 0 "register_operand" ""))
17498 (use (match_operand:XF 1 "register_operand" ""))]
17499 "TARGET_USE_FANCY_MATH_387
17500 && flag_unsafe_math_optimizations && !optimize_size"
17502 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17506 (define_expand "floordf2"
17507 [(use (match_operand:DF 0 "register_operand" ""))
17508 (use (match_operand:DF 1 "register_operand" ""))]
17509 "((TARGET_USE_FANCY_MATH_387
17510 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17511 && flag_unsafe_math_optimizations)
17512 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17513 && !flag_trapping_math))
17516 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17517 && !flag_trapping_math)
17520 ix86_expand_floorceil (operand0, operand1, true);
17522 ix86_expand_floorceildf_32 (operand0, operand1, true);
17526 rtx op0 = gen_reg_rtx (XFmode);
17527 rtx op1 = gen_reg_rtx (XFmode);
17529 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17530 emit_insn (gen_frndintxf2_floor (op0, op1));
17532 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17537 (define_expand "floorsf2"
17538 [(use (match_operand:SF 0 "register_operand" ""))
17539 (use (match_operand:SF 1 "register_operand" ""))]
17540 "((TARGET_USE_FANCY_MATH_387
17541 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17542 && flag_unsafe_math_optimizations)
17543 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17544 && !flag_trapping_math))
17547 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17548 && !flag_trapping_math)
17549 ix86_expand_floorceil (operand0, operand1, true);
17552 rtx op0 = gen_reg_rtx (XFmode);
17553 rtx op1 = gen_reg_rtx (XFmode);
17555 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17556 emit_insn (gen_frndintxf2_floor (op0, op1));
17558 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17563 (define_insn_and_split "*fist<mode>2_floor_1"
17564 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17565 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17566 UNSPEC_FIST_FLOOR))
17567 (clobber (reg:CC FLAGS_REG))]
17568 "TARGET_USE_FANCY_MATH_387
17569 && flag_unsafe_math_optimizations
17570 && !(reload_completed || reload_in_progress)"
17575 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17577 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17578 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17579 if (memory_operand (operands[0], VOIDmode))
17580 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17581 operands[2], operands[3]));
17584 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17585 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17586 operands[2], operands[3],
17591 [(set_attr "type" "fistp")
17592 (set_attr "i387_cw" "floor")
17593 (set_attr "mode" "<MODE>")])
17595 (define_insn "fistdi2_floor"
17596 [(set (match_operand:DI 0 "memory_operand" "=m")
17597 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17598 UNSPEC_FIST_FLOOR))
17599 (use (match_operand:HI 2 "memory_operand" "m"))
17600 (use (match_operand:HI 3 "memory_operand" "m"))
17601 (clobber (match_scratch:XF 4 "=&1f"))]
17602 "TARGET_USE_FANCY_MATH_387
17603 && flag_unsafe_math_optimizations"
17604 "* return output_fix_trunc (insn, operands, 0);"
17605 [(set_attr "type" "fistp")
17606 (set_attr "i387_cw" "floor")
17607 (set_attr "mode" "DI")])
17609 (define_insn "fistdi2_floor_with_temp"
17610 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17611 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17612 UNSPEC_FIST_FLOOR))
17613 (use (match_operand:HI 2 "memory_operand" "m,m"))
17614 (use (match_operand:HI 3 "memory_operand" "m,m"))
17615 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17616 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17617 "TARGET_USE_FANCY_MATH_387
17618 && flag_unsafe_math_optimizations"
17620 [(set_attr "type" "fistp")
17621 (set_attr "i387_cw" "floor")
17622 (set_attr "mode" "DI")])
17625 [(set (match_operand:DI 0 "register_operand" "")
17626 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17627 UNSPEC_FIST_FLOOR))
17628 (use (match_operand:HI 2 "memory_operand" ""))
17629 (use (match_operand:HI 3 "memory_operand" ""))
17630 (clobber (match_operand:DI 4 "memory_operand" ""))
17631 (clobber (match_scratch 5 ""))]
17633 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17634 (use (match_dup 2))
17635 (use (match_dup 3))
17636 (clobber (match_dup 5))])
17637 (set (match_dup 0) (match_dup 4))]
17641 [(set (match_operand:DI 0 "memory_operand" "")
17642 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17643 UNSPEC_FIST_FLOOR))
17644 (use (match_operand:HI 2 "memory_operand" ""))
17645 (use (match_operand:HI 3 "memory_operand" ""))
17646 (clobber (match_operand:DI 4 "memory_operand" ""))
17647 (clobber (match_scratch 5 ""))]
17649 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17650 (use (match_dup 2))
17651 (use (match_dup 3))
17652 (clobber (match_dup 5))])]
17655 (define_insn "fist<mode>2_floor"
17656 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17657 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17658 UNSPEC_FIST_FLOOR))
17659 (use (match_operand:HI 2 "memory_operand" "m"))
17660 (use (match_operand:HI 3 "memory_operand" "m"))]
17661 "TARGET_USE_FANCY_MATH_387
17662 && flag_unsafe_math_optimizations"
17663 "* return output_fix_trunc (insn, operands, 0);"
17664 [(set_attr "type" "fistp")
17665 (set_attr "i387_cw" "floor")
17666 (set_attr "mode" "<MODE>")])
17668 (define_insn "fist<mode>2_floor_with_temp"
17669 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17670 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17671 UNSPEC_FIST_FLOOR))
17672 (use (match_operand:HI 2 "memory_operand" "m,m"))
17673 (use (match_operand:HI 3 "memory_operand" "m,m"))
17674 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17675 "TARGET_USE_FANCY_MATH_387
17676 && flag_unsafe_math_optimizations"
17678 [(set_attr "type" "fistp")
17679 (set_attr "i387_cw" "floor")
17680 (set_attr "mode" "<MODE>")])
17683 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17684 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17685 UNSPEC_FIST_FLOOR))
17686 (use (match_operand:HI 2 "memory_operand" ""))
17687 (use (match_operand:HI 3 "memory_operand" ""))
17688 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17690 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17691 UNSPEC_FIST_FLOOR))
17692 (use (match_dup 2))
17693 (use (match_dup 3))])
17694 (set (match_dup 0) (match_dup 4))]
17698 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17699 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17700 UNSPEC_FIST_FLOOR))
17701 (use (match_operand:HI 2 "memory_operand" ""))
17702 (use (match_operand:HI 3 "memory_operand" ""))
17703 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17705 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17706 UNSPEC_FIST_FLOOR))
17707 (use (match_dup 2))
17708 (use (match_dup 3))])]
17711 (define_expand "lfloorxf<mode>2"
17712 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17713 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17714 UNSPEC_FIST_FLOOR))
17715 (clobber (reg:CC FLAGS_REG))])]
17716 "TARGET_USE_FANCY_MATH_387
17717 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17718 && flag_unsafe_math_optimizations"
17721 (define_expand "lfloor<mode>di2"
17722 [(match_operand:DI 0 "nonimmediate_operand" "")
17723 (match_operand:SSEMODEF 1 "register_operand" "")]
17724 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17725 && !flag_trapping_math
17728 ix86_expand_lfloorceil (operand0, operand1, true);
17732 (define_expand "lfloor<mode>si2"
17733 [(match_operand:SI 0 "nonimmediate_operand" "")
17734 (match_operand:SSEMODEF 1 "register_operand" "")]
17735 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17736 && !flag_trapping_math
17737 && (!optimize_size || !TARGET_64BIT)"
17739 ix86_expand_lfloorceil (operand0, operand1, true);
17743 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17744 (define_insn_and_split "frndintxf2_ceil"
17745 [(set (match_operand:XF 0 "register_operand" "=f")
17746 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17747 UNSPEC_FRNDINT_CEIL))
17748 (clobber (reg:CC FLAGS_REG))]
17749 "TARGET_USE_FANCY_MATH_387
17750 && flag_unsafe_math_optimizations
17751 && !(reload_completed || reload_in_progress)"
17756 ix86_optimize_mode_switching[I387_CEIL] = 1;
17758 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17759 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17761 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17762 operands[2], operands[3]));
17765 [(set_attr "type" "frndint")
17766 (set_attr "i387_cw" "ceil")
17767 (set_attr "mode" "XF")])
17769 (define_insn "frndintxf2_ceil_i387"
17770 [(set (match_operand:XF 0 "register_operand" "=f")
17771 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17772 UNSPEC_FRNDINT_CEIL))
17773 (use (match_operand:HI 2 "memory_operand" "m"))
17774 (use (match_operand:HI 3 "memory_operand" "m"))]
17775 "TARGET_USE_FANCY_MATH_387
17776 && flag_unsafe_math_optimizations"
17777 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17778 [(set_attr "type" "frndint")
17779 (set_attr "i387_cw" "ceil")
17780 (set_attr "mode" "XF")])
17782 (define_expand "ceilxf2"
17783 [(use (match_operand:XF 0 "register_operand" ""))
17784 (use (match_operand:XF 1 "register_operand" ""))]
17785 "TARGET_USE_FANCY_MATH_387
17786 && flag_unsafe_math_optimizations && !optimize_size"
17788 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17792 (define_expand "ceildf2"
17793 [(use (match_operand:DF 0 "register_operand" ""))
17794 (use (match_operand:DF 1 "register_operand" ""))]
17795 "((TARGET_USE_FANCY_MATH_387
17796 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17797 && flag_unsafe_math_optimizations)
17798 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17799 && !flag_trapping_math))
17802 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17803 && !flag_trapping_math)
17806 ix86_expand_floorceil (operand0, operand1, false);
17808 ix86_expand_floorceildf_32 (operand0, operand1, false);
17812 rtx op0 = gen_reg_rtx (XFmode);
17813 rtx op1 = gen_reg_rtx (XFmode);
17815 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17816 emit_insn (gen_frndintxf2_ceil (op0, op1));
17818 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17823 (define_expand "ceilsf2"
17824 [(use (match_operand:SF 0 "register_operand" ""))
17825 (use (match_operand:SF 1 "register_operand" ""))]
17826 "((TARGET_USE_FANCY_MATH_387
17827 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17828 && flag_unsafe_math_optimizations)
17829 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17830 && !flag_trapping_math))
17833 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17834 && !flag_trapping_math)
17835 ix86_expand_floorceil (operand0, operand1, false);
17838 rtx op0 = gen_reg_rtx (XFmode);
17839 rtx op1 = gen_reg_rtx (XFmode);
17841 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17842 emit_insn (gen_frndintxf2_ceil (op0, op1));
17844 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17849 (define_insn_and_split "*fist<mode>2_ceil_1"
17850 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17851 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17853 (clobber (reg:CC FLAGS_REG))]
17854 "TARGET_USE_FANCY_MATH_387
17855 && flag_unsafe_math_optimizations
17856 && !(reload_completed || reload_in_progress)"
17861 ix86_optimize_mode_switching[I387_CEIL] = 1;
17863 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17864 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17865 if (memory_operand (operands[0], VOIDmode))
17866 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17867 operands[2], operands[3]));
17870 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17871 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17872 operands[2], operands[3],
17877 [(set_attr "type" "fistp")
17878 (set_attr "i387_cw" "ceil")
17879 (set_attr "mode" "<MODE>")])
17881 (define_insn "fistdi2_ceil"
17882 [(set (match_operand:DI 0 "memory_operand" "=m")
17883 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17885 (use (match_operand:HI 2 "memory_operand" "m"))
17886 (use (match_operand:HI 3 "memory_operand" "m"))
17887 (clobber (match_scratch:XF 4 "=&1f"))]
17888 "TARGET_USE_FANCY_MATH_387
17889 && flag_unsafe_math_optimizations"
17890 "* return output_fix_trunc (insn, operands, 0);"
17891 [(set_attr "type" "fistp")
17892 (set_attr "i387_cw" "ceil")
17893 (set_attr "mode" "DI")])
17895 (define_insn "fistdi2_ceil_with_temp"
17896 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17897 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17899 (use (match_operand:HI 2 "memory_operand" "m,m"))
17900 (use (match_operand:HI 3 "memory_operand" "m,m"))
17901 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17902 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17903 "TARGET_USE_FANCY_MATH_387
17904 && flag_unsafe_math_optimizations"
17906 [(set_attr "type" "fistp")
17907 (set_attr "i387_cw" "ceil")
17908 (set_attr "mode" "DI")])
17911 [(set (match_operand:DI 0 "register_operand" "")
17912 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17914 (use (match_operand:HI 2 "memory_operand" ""))
17915 (use (match_operand:HI 3 "memory_operand" ""))
17916 (clobber (match_operand:DI 4 "memory_operand" ""))
17917 (clobber (match_scratch 5 ""))]
17919 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17920 (use (match_dup 2))
17921 (use (match_dup 3))
17922 (clobber (match_dup 5))])
17923 (set (match_dup 0) (match_dup 4))]
17927 [(set (match_operand:DI 0 "memory_operand" "")
17928 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17930 (use (match_operand:HI 2 "memory_operand" ""))
17931 (use (match_operand:HI 3 "memory_operand" ""))
17932 (clobber (match_operand:DI 4 "memory_operand" ""))
17933 (clobber (match_scratch 5 ""))]
17935 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17936 (use (match_dup 2))
17937 (use (match_dup 3))
17938 (clobber (match_dup 5))])]
17941 (define_insn "fist<mode>2_ceil"
17942 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17943 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17945 (use (match_operand:HI 2 "memory_operand" "m"))
17946 (use (match_operand:HI 3 "memory_operand" "m"))]
17947 "TARGET_USE_FANCY_MATH_387
17948 && flag_unsafe_math_optimizations"
17949 "* return output_fix_trunc (insn, operands, 0);"
17950 [(set_attr "type" "fistp")
17951 (set_attr "i387_cw" "ceil")
17952 (set_attr "mode" "<MODE>")])
17954 (define_insn "fist<mode>2_ceil_with_temp"
17955 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17956 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17958 (use (match_operand:HI 2 "memory_operand" "m,m"))
17959 (use (match_operand:HI 3 "memory_operand" "m,m"))
17960 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17961 "TARGET_USE_FANCY_MATH_387
17962 && flag_unsafe_math_optimizations"
17964 [(set_attr "type" "fistp")
17965 (set_attr "i387_cw" "ceil")
17966 (set_attr "mode" "<MODE>")])
17969 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17970 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17972 (use (match_operand:HI 2 "memory_operand" ""))
17973 (use (match_operand:HI 3 "memory_operand" ""))
17974 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17976 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17978 (use (match_dup 2))
17979 (use (match_dup 3))])
17980 (set (match_dup 0) (match_dup 4))]
17984 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17985 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17987 (use (match_operand:HI 2 "memory_operand" ""))
17988 (use (match_operand:HI 3 "memory_operand" ""))
17989 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17991 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17993 (use (match_dup 2))
17994 (use (match_dup 3))])]
17997 (define_expand "lceilxf<mode>2"
17998 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17999 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18001 (clobber (reg:CC FLAGS_REG))])]
18002 "TARGET_USE_FANCY_MATH_387
18003 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18004 && flag_unsafe_math_optimizations"
18007 (define_expand "lceil<mode>di2"
18008 [(match_operand:DI 0 "nonimmediate_operand" "")
18009 (match_operand:SSEMODEF 1 "register_operand" "")]
18010 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18011 && !flag_trapping_math"
18013 ix86_expand_lfloorceil (operand0, operand1, false);
18017 (define_expand "lceil<mode>si2"
18018 [(match_operand:SI 0 "nonimmediate_operand" "")
18019 (match_operand:SSEMODEF 1 "register_operand" "")]
18020 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18021 && !flag_trapping_math"
18023 ix86_expand_lfloorceil (operand0, operand1, false);
18027 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18028 (define_insn_and_split "frndintxf2_trunc"
18029 [(set (match_operand:XF 0 "register_operand" "=f")
18030 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18031 UNSPEC_FRNDINT_TRUNC))
18032 (clobber (reg:CC FLAGS_REG))]
18033 "TARGET_USE_FANCY_MATH_387
18034 && flag_unsafe_math_optimizations
18035 && !(reload_completed || reload_in_progress)"
18040 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18042 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18043 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18045 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18046 operands[2], operands[3]));
18049 [(set_attr "type" "frndint")
18050 (set_attr "i387_cw" "trunc")
18051 (set_attr "mode" "XF")])
18053 (define_insn "frndintxf2_trunc_i387"
18054 [(set (match_operand:XF 0 "register_operand" "=f")
18055 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18056 UNSPEC_FRNDINT_TRUNC))
18057 (use (match_operand:HI 2 "memory_operand" "m"))
18058 (use (match_operand:HI 3 "memory_operand" "m"))]
18059 "TARGET_USE_FANCY_MATH_387
18060 && flag_unsafe_math_optimizations"
18061 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18062 [(set_attr "type" "frndint")
18063 (set_attr "i387_cw" "trunc")
18064 (set_attr "mode" "XF")])
18066 (define_expand "btruncxf2"
18067 [(use (match_operand:XF 0 "register_operand" ""))
18068 (use (match_operand:XF 1 "register_operand" ""))]
18069 "TARGET_USE_FANCY_MATH_387
18070 && flag_unsafe_math_optimizations && !optimize_size"
18072 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18076 (define_expand "btruncdf2"
18077 [(use (match_operand:DF 0 "register_operand" ""))
18078 (use (match_operand:DF 1 "register_operand" ""))]
18079 "((TARGET_USE_FANCY_MATH_387
18080 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18081 && flag_unsafe_math_optimizations)
18082 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18083 && !flag_trapping_math))
18086 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18087 && !flag_trapping_math)
18090 ix86_expand_trunc (operand0, operand1);
18092 ix86_expand_truncdf_32 (operand0, operand1);
18096 rtx op0 = gen_reg_rtx (XFmode);
18097 rtx op1 = gen_reg_rtx (XFmode);
18099 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18100 emit_insn (gen_frndintxf2_trunc (op0, op1));
18102 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18107 (define_expand "btruncsf2"
18108 [(use (match_operand:SF 0 "register_operand" ""))
18109 (use (match_operand:SF 1 "register_operand" ""))]
18110 "((TARGET_USE_FANCY_MATH_387
18111 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18112 && flag_unsafe_math_optimizations)
18113 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18114 && !flag_trapping_math))
18117 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18118 && !flag_trapping_math)
18119 ix86_expand_trunc (operand0, operand1);
18122 rtx op0 = gen_reg_rtx (XFmode);
18123 rtx op1 = gen_reg_rtx (XFmode);
18125 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18126 emit_insn (gen_frndintxf2_trunc (op0, op1));
18128 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18133 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18134 (define_insn_and_split "frndintxf2_mask_pm"
18135 [(set (match_operand:XF 0 "register_operand" "=f")
18136 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18137 UNSPEC_FRNDINT_MASK_PM))
18138 (clobber (reg:CC FLAGS_REG))]
18139 "TARGET_USE_FANCY_MATH_387
18140 && flag_unsafe_math_optimizations
18141 && !(reload_completed || reload_in_progress)"
18146 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18148 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18149 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18151 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18152 operands[2], operands[3]));
18155 [(set_attr "type" "frndint")
18156 (set_attr "i387_cw" "mask_pm")
18157 (set_attr "mode" "XF")])
18159 (define_insn "frndintxf2_mask_pm_i387"
18160 [(set (match_operand:XF 0 "register_operand" "=f")
18161 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18162 UNSPEC_FRNDINT_MASK_PM))
18163 (use (match_operand:HI 2 "memory_operand" "m"))
18164 (use (match_operand:HI 3 "memory_operand" "m"))]
18165 "TARGET_USE_FANCY_MATH_387
18166 && flag_unsafe_math_optimizations"
18167 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18168 [(set_attr "type" "frndint")
18169 (set_attr "i387_cw" "mask_pm")
18170 (set_attr "mode" "XF")])
18172 (define_expand "nearbyintxf2"
18173 [(use (match_operand:XF 0 "register_operand" ""))
18174 (use (match_operand:XF 1 "register_operand" ""))]
18175 "TARGET_USE_FANCY_MATH_387
18176 && flag_unsafe_math_optimizations"
18178 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18183 (define_expand "nearbyintdf2"
18184 [(use (match_operand:DF 0 "register_operand" ""))
18185 (use (match_operand:DF 1 "register_operand" ""))]
18186 "TARGET_USE_FANCY_MATH_387
18187 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18188 && flag_unsafe_math_optimizations"
18190 rtx op0 = gen_reg_rtx (XFmode);
18191 rtx op1 = gen_reg_rtx (XFmode);
18193 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18194 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18196 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18200 (define_expand "nearbyintsf2"
18201 [(use (match_operand:SF 0 "register_operand" ""))
18202 (use (match_operand:SF 1 "register_operand" ""))]
18203 "TARGET_USE_FANCY_MATH_387
18204 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18205 && flag_unsafe_math_optimizations"
18207 rtx op0 = gen_reg_rtx (XFmode);
18208 rtx op1 = gen_reg_rtx (XFmode);
18210 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18211 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18213 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18218 ;; Block operation instructions
18221 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18224 [(set_attr "type" "cld")])
18226 (define_expand "movmemsi"
18227 [(use (match_operand:BLK 0 "memory_operand" ""))
18228 (use (match_operand:BLK 1 "memory_operand" ""))
18229 (use (match_operand:SI 2 "nonmemory_operand" ""))
18230 (use (match_operand:SI 3 "const_int_operand" ""))]
18231 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18233 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18239 (define_expand "movmemdi"
18240 [(use (match_operand:BLK 0 "memory_operand" ""))
18241 (use (match_operand:BLK 1 "memory_operand" ""))
18242 (use (match_operand:DI 2 "nonmemory_operand" ""))
18243 (use (match_operand:DI 3 "const_int_operand" ""))]
18246 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18252 ;; Most CPUs don't like single string operations
18253 ;; Handle this case here to simplify previous expander.
18255 (define_expand "strmov"
18256 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18257 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18258 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18259 (clobber (reg:CC FLAGS_REG))])
18260 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18261 (clobber (reg:CC FLAGS_REG))])]
18264 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18266 /* If .md ever supports :P for Pmode, these can be directly
18267 in the pattern above. */
18268 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18269 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18271 if (TARGET_SINGLE_STRINGOP || optimize_size)
18273 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18274 operands[2], operands[3],
18275 operands[5], operands[6]));
18279 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18282 (define_expand "strmov_singleop"
18283 [(parallel [(set (match_operand 1 "memory_operand" "")
18284 (match_operand 3 "memory_operand" ""))
18285 (set (match_operand 0 "register_operand" "")
18286 (match_operand 4 "" ""))
18287 (set (match_operand 2 "register_operand" "")
18288 (match_operand 5 "" ""))
18289 (use (reg:SI DIRFLAG_REG))])]
18290 "TARGET_SINGLE_STRINGOP || optimize_size"
18293 (define_insn "*strmovdi_rex_1"
18294 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18295 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18296 (set (match_operand:DI 0 "register_operand" "=D")
18297 (plus:DI (match_dup 2)
18299 (set (match_operand:DI 1 "register_operand" "=S")
18300 (plus:DI (match_dup 3)
18302 (use (reg:SI DIRFLAG_REG))]
18303 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18305 [(set_attr "type" "str")
18306 (set_attr "mode" "DI")
18307 (set_attr "memory" "both")])
18309 (define_insn "*strmovsi_1"
18310 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18311 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18312 (set (match_operand:SI 0 "register_operand" "=D")
18313 (plus:SI (match_dup 2)
18315 (set (match_operand:SI 1 "register_operand" "=S")
18316 (plus:SI (match_dup 3)
18318 (use (reg:SI DIRFLAG_REG))]
18319 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18321 [(set_attr "type" "str")
18322 (set_attr "mode" "SI")
18323 (set_attr "memory" "both")])
18325 (define_insn "*strmovsi_rex_1"
18326 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18327 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18328 (set (match_operand:DI 0 "register_operand" "=D")
18329 (plus:DI (match_dup 2)
18331 (set (match_operand:DI 1 "register_operand" "=S")
18332 (plus:DI (match_dup 3)
18334 (use (reg:SI DIRFLAG_REG))]
18335 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18337 [(set_attr "type" "str")
18338 (set_attr "mode" "SI")
18339 (set_attr "memory" "both")])
18341 (define_insn "*strmovhi_1"
18342 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18343 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18344 (set (match_operand:SI 0 "register_operand" "=D")
18345 (plus:SI (match_dup 2)
18347 (set (match_operand:SI 1 "register_operand" "=S")
18348 (plus:SI (match_dup 3)
18350 (use (reg:SI DIRFLAG_REG))]
18351 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18353 [(set_attr "type" "str")
18354 (set_attr "memory" "both")
18355 (set_attr "mode" "HI")])
18357 (define_insn "*strmovhi_rex_1"
18358 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18359 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18360 (set (match_operand:DI 0 "register_operand" "=D")
18361 (plus:DI (match_dup 2)
18363 (set (match_operand:DI 1 "register_operand" "=S")
18364 (plus:DI (match_dup 3)
18366 (use (reg:SI DIRFLAG_REG))]
18367 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18369 [(set_attr "type" "str")
18370 (set_attr "memory" "both")
18371 (set_attr "mode" "HI")])
18373 (define_insn "*strmovqi_1"
18374 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18375 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18376 (set (match_operand:SI 0 "register_operand" "=D")
18377 (plus:SI (match_dup 2)
18379 (set (match_operand:SI 1 "register_operand" "=S")
18380 (plus:SI (match_dup 3)
18382 (use (reg:SI DIRFLAG_REG))]
18383 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18385 [(set_attr "type" "str")
18386 (set_attr "memory" "both")
18387 (set_attr "mode" "QI")])
18389 (define_insn "*strmovqi_rex_1"
18390 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18391 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18392 (set (match_operand:DI 0 "register_operand" "=D")
18393 (plus:DI (match_dup 2)
18395 (set (match_operand:DI 1 "register_operand" "=S")
18396 (plus:DI (match_dup 3)
18398 (use (reg:SI DIRFLAG_REG))]
18399 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18401 [(set_attr "type" "str")
18402 (set_attr "memory" "both")
18403 (set_attr "mode" "QI")])
18405 (define_expand "rep_mov"
18406 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18407 (set (match_operand 0 "register_operand" "")
18408 (match_operand 5 "" ""))
18409 (set (match_operand 2 "register_operand" "")
18410 (match_operand 6 "" ""))
18411 (set (match_operand 1 "memory_operand" "")
18412 (match_operand 3 "memory_operand" ""))
18413 (use (match_dup 4))
18414 (use (reg:SI DIRFLAG_REG))])]
18418 (define_insn "*rep_movdi_rex64"
18419 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18420 (set (match_operand:DI 0 "register_operand" "=D")
18421 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18423 (match_operand:DI 3 "register_operand" "0")))
18424 (set (match_operand:DI 1 "register_operand" "=S")
18425 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18426 (match_operand:DI 4 "register_operand" "1")))
18427 (set (mem:BLK (match_dup 3))
18428 (mem:BLK (match_dup 4)))
18429 (use (match_dup 5))
18430 (use (reg:SI DIRFLAG_REG))]
18432 "{rep\;movsq|rep movsq}"
18433 [(set_attr "type" "str")
18434 (set_attr "prefix_rep" "1")
18435 (set_attr "memory" "both")
18436 (set_attr "mode" "DI")])
18438 (define_insn "*rep_movsi"
18439 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18440 (set (match_operand:SI 0 "register_operand" "=D")
18441 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18443 (match_operand:SI 3 "register_operand" "0")))
18444 (set (match_operand:SI 1 "register_operand" "=S")
18445 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18446 (match_operand:SI 4 "register_operand" "1")))
18447 (set (mem:BLK (match_dup 3))
18448 (mem:BLK (match_dup 4)))
18449 (use (match_dup 5))
18450 (use (reg:SI DIRFLAG_REG))]
18452 "{rep\;movsl|rep movsd}"
18453 [(set_attr "type" "str")
18454 (set_attr "prefix_rep" "1")
18455 (set_attr "memory" "both")
18456 (set_attr "mode" "SI")])
18458 (define_insn "*rep_movsi_rex64"
18459 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18460 (set (match_operand:DI 0 "register_operand" "=D")
18461 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18463 (match_operand:DI 3 "register_operand" "0")))
18464 (set (match_operand:DI 1 "register_operand" "=S")
18465 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18466 (match_operand:DI 4 "register_operand" "1")))
18467 (set (mem:BLK (match_dup 3))
18468 (mem:BLK (match_dup 4)))
18469 (use (match_dup 5))
18470 (use (reg:SI DIRFLAG_REG))]
18472 "{rep\;movsl|rep movsd}"
18473 [(set_attr "type" "str")
18474 (set_attr "prefix_rep" "1")
18475 (set_attr "memory" "both")
18476 (set_attr "mode" "SI")])
18478 (define_insn "*rep_movqi"
18479 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18480 (set (match_operand:SI 0 "register_operand" "=D")
18481 (plus:SI (match_operand:SI 3 "register_operand" "0")
18482 (match_operand:SI 5 "register_operand" "2")))
18483 (set (match_operand:SI 1 "register_operand" "=S")
18484 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18485 (set (mem:BLK (match_dup 3))
18486 (mem:BLK (match_dup 4)))
18487 (use (match_dup 5))
18488 (use (reg:SI DIRFLAG_REG))]
18490 "{rep\;movsb|rep movsb}"
18491 [(set_attr "type" "str")
18492 (set_attr "prefix_rep" "1")
18493 (set_attr "memory" "both")
18494 (set_attr "mode" "SI")])
18496 (define_insn "*rep_movqi_rex64"
18497 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18498 (set (match_operand:DI 0 "register_operand" "=D")
18499 (plus:DI (match_operand:DI 3 "register_operand" "0")
18500 (match_operand:DI 5 "register_operand" "2")))
18501 (set (match_operand:DI 1 "register_operand" "=S")
18502 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18503 (set (mem:BLK (match_dup 3))
18504 (mem:BLK (match_dup 4)))
18505 (use (match_dup 5))
18506 (use (reg:SI DIRFLAG_REG))]
18508 "{rep\;movsb|rep movsb}"
18509 [(set_attr "type" "str")
18510 (set_attr "prefix_rep" "1")
18511 (set_attr "memory" "both")
18512 (set_attr "mode" "SI")])
18514 (define_expand "setmemsi"
18515 [(use (match_operand:BLK 0 "memory_operand" ""))
18516 (use (match_operand:SI 1 "nonmemory_operand" ""))
18517 (use (match_operand 2 "const_int_operand" ""))
18518 (use (match_operand 3 "const_int_operand" ""))]
18521 /* If value to set is not zero, use the library routine. */
18522 if (operands[2] != const0_rtx)
18525 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18531 (define_expand "setmemdi"
18532 [(use (match_operand:BLK 0 "memory_operand" ""))
18533 (use (match_operand:DI 1 "nonmemory_operand" ""))
18534 (use (match_operand 2 "const_int_operand" ""))
18535 (use (match_operand 3 "const_int_operand" ""))]
18538 /* If value to set is not zero, use the library routine. */
18539 if (operands[2] != const0_rtx)
18542 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18548 ;; Most CPUs don't like single string operations
18549 ;; Handle this case here to simplify previous expander.
18551 (define_expand "strset"
18552 [(set (match_operand 1 "memory_operand" "")
18553 (match_operand 2 "register_operand" ""))
18554 (parallel [(set (match_operand 0 "register_operand" "")
18556 (clobber (reg:CC FLAGS_REG))])]
18559 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18560 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18562 /* If .md ever supports :P for Pmode, this can be directly
18563 in the pattern above. */
18564 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18565 GEN_INT (GET_MODE_SIZE (GET_MODE
18567 if (TARGET_SINGLE_STRINGOP || optimize_size)
18569 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18575 (define_expand "strset_singleop"
18576 [(parallel [(set (match_operand 1 "memory_operand" "")
18577 (match_operand 2 "register_operand" ""))
18578 (set (match_operand 0 "register_operand" "")
18579 (match_operand 3 "" ""))
18580 (use (reg:SI DIRFLAG_REG))])]
18581 "TARGET_SINGLE_STRINGOP || optimize_size"
18584 (define_insn "*strsetdi_rex_1"
18585 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18586 (match_operand:DI 2 "register_operand" "a"))
18587 (set (match_operand:DI 0 "register_operand" "=D")
18588 (plus:DI (match_dup 1)
18590 (use (reg:SI DIRFLAG_REG))]
18591 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18593 [(set_attr "type" "str")
18594 (set_attr "memory" "store")
18595 (set_attr "mode" "DI")])
18597 (define_insn "*strsetsi_1"
18598 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18599 (match_operand:SI 2 "register_operand" "a"))
18600 (set (match_operand:SI 0 "register_operand" "=D")
18601 (plus:SI (match_dup 1)
18603 (use (reg:SI DIRFLAG_REG))]
18604 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18606 [(set_attr "type" "str")
18607 (set_attr "memory" "store")
18608 (set_attr "mode" "SI")])
18610 (define_insn "*strsetsi_rex_1"
18611 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18612 (match_operand:SI 2 "register_operand" "a"))
18613 (set (match_operand:DI 0 "register_operand" "=D")
18614 (plus:DI (match_dup 1)
18616 (use (reg:SI DIRFLAG_REG))]
18617 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18619 [(set_attr "type" "str")
18620 (set_attr "memory" "store")
18621 (set_attr "mode" "SI")])
18623 (define_insn "*strsethi_1"
18624 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18625 (match_operand:HI 2 "register_operand" "a"))
18626 (set (match_operand:SI 0 "register_operand" "=D")
18627 (plus:SI (match_dup 1)
18629 (use (reg:SI DIRFLAG_REG))]
18630 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18632 [(set_attr "type" "str")
18633 (set_attr "memory" "store")
18634 (set_attr "mode" "HI")])
18636 (define_insn "*strsethi_rex_1"
18637 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18638 (match_operand:HI 2 "register_operand" "a"))
18639 (set (match_operand:DI 0 "register_operand" "=D")
18640 (plus:DI (match_dup 1)
18642 (use (reg:SI DIRFLAG_REG))]
18643 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18645 [(set_attr "type" "str")
18646 (set_attr "memory" "store")
18647 (set_attr "mode" "HI")])
18649 (define_insn "*strsetqi_1"
18650 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18651 (match_operand:QI 2 "register_operand" "a"))
18652 (set (match_operand:SI 0 "register_operand" "=D")
18653 (plus:SI (match_dup 1)
18655 (use (reg:SI DIRFLAG_REG))]
18656 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18658 [(set_attr "type" "str")
18659 (set_attr "memory" "store")
18660 (set_attr "mode" "QI")])
18662 (define_insn "*strsetqi_rex_1"
18663 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18664 (match_operand:QI 2 "register_operand" "a"))
18665 (set (match_operand:DI 0 "register_operand" "=D")
18666 (plus:DI (match_dup 1)
18668 (use (reg:SI DIRFLAG_REG))]
18669 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18671 [(set_attr "type" "str")
18672 (set_attr "memory" "store")
18673 (set_attr "mode" "QI")])
18675 (define_expand "rep_stos"
18676 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18677 (set (match_operand 0 "register_operand" "")
18678 (match_operand 4 "" ""))
18679 (set (match_operand 2 "memory_operand" "") (const_int 0))
18680 (use (match_operand 3 "register_operand" ""))
18681 (use (match_dup 1))
18682 (use (reg:SI DIRFLAG_REG))])]
18686 (define_insn "*rep_stosdi_rex64"
18687 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18688 (set (match_operand:DI 0 "register_operand" "=D")
18689 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18691 (match_operand:DI 3 "register_operand" "0")))
18692 (set (mem:BLK (match_dup 3))
18694 (use (match_operand:DI 2 "register_operand" "a"))
18695 (use (match_dup 4))
18696 (use (reg:SI DIRFLAG_REG))]
18698 "{rep\;stosq|rep stosq}"
18699 [(set_attr "type" "str")
18700 (set_attr "prefix_rep" "1")
18701 (set_attr "memory" "store")
18702 (set_attr "mode" "DI")])
18704 (define_insn "*rep_stossi"
18705 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18706 (set (match_operand:SI 0 "register_operand" "=D")
18707 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18709 (match_operand:SI 3 "register_operand" "0")))
18710 (set (mem:BLK (match_dup 3))
18712 (use (match_operand:SI 2 "register_operand" "a"))
18713 (use (match_dup 4))
18714 (use (reg:SI DIRFLAG_REG))]
18716 "{rep\;stosl|rep stosd}"
18717 [(set_attr "type" "str")
18718 (set_attr "prefix_rep" "1")
18719 (set_attr "memory" "store")
18720 (set_attr "mode" "SI")])
18722 (define_insn "*rep_stossi_rex64"
18723 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18724 (set (match_operand:DI 0 "register_operand" "=D")
18725 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18727 (match_operand:DI 3 "register_operand" "0")))
18728 (set (mem:BLK (match_dup 3))
18730 (use (match_operand:SI 2 "register_operand" "a"))
18731 (use (match_dup 4))
18732 (use (reg:SI DIRFLAG_REG))]
18734 "{rep\;stosl|rep stosd}"
18735 [(set_attr "type" "str")
18736 (set_attr "prefix_rep" "1")
18737 (set_attr "memory" "store")
18738 (set_attr "mode" "SI")])
18740 (define_insn "*rep_stosqi"
18741 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18742 (set (match_operand:SI 0 "register_operand" "=D")
18743 (plus:SI (match_operand:SI 3 "register_operand" "0")
18744 (match_operand:SI 4 "register_operand" "1")))
18745 (set (mem:BLK (match_dup 3))
18747 (use (match_operand:QI 2 "register_operand" "a"))
18748 (use (match_dup 4))
18749 (use (reg:SI DIRFLAG_REG))]
18751 "{rep\;stosb|rep stosb}"
18752 [(set_attr "type" "str")
18753 (set_attr "prefix_rep" "1")
18754 (set_attr "memory" "store")
18755 (set_attr "mode" "QI")])
18757 (define_insn "*rep_stosqi_rex64"
18758 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18759 (set (match_operand:DI 0 "register_operand" "=D")
18760 (plus:DI (match_operand:DI 3 "register_operand" "0")
18761 (match_operand:DI 4 "register_operand" "1")))
18762 (set (mem:BLK (match_dup 3))
18764 (use (match_operand:QI 2 "register_operand" "a"))
18765 (use (match_dup 4))
18766 (use (reg:SI DIRFLAG_REG))]
18768 "{rep\;stosb|rep stosb}"
18769 [(set_attr "type" "str")
18770 (set_attr "prefix_rep" "1")
18771 (set_attr "memory" "store")
18772 (set_attr "mode" "QI")])
18774 (define_expand "cmpstrnsi"
18775 [(set (match_operand:SI 0 "register_operand" "")
18776 (compare:SI (match_operand:BLK 1 "general_operand" "")
18777 (match_operand:BLK 2 "general_operand" "")))
18778 (use (match_operand 3 "general_operand" ""))
18779 (use (match_operand 4 "immediate_operand" ""))]
18780 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18782 rtx addr1, addr2, out, outlow, count, countreg, align;
18784 /* Can't use this if the user has appropriated esi or edi. */
18785 if (global_regs[4] || global_regs[5])
18789 if (GET_CODE (out) != REG)
18790 out = gen_reg_rtx (SImode);
18792 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18793 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18794 if (addr1 != XEXP (operands[1], 0))
18795 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18796 if (addr2 != XEXP (operands[2], 0))
18797 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18799 count = operands[3];
18800 countreg = ix86_zero_extend_to_Pmode (count);
18802 /* %%% Iff we are testing strict equality, we can use known alignment
18803 to good advantage. This may be possible with combine, particularly
18804 once cc0 is dead. */
18805 align = operands[4];
18807 emit_insn (gen_cld ());
18808 if (GET_CODE (count) == CONST_INT)
18810 if (INTVAL (count) == 0)
18812 emit_move_insn (operands[0], const0_rtx);
18815 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18816 operands[1], operands[2]));
18821 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18823 emit_insn (gen_cmpsi_1 (countreg, countreg));
18824 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18825 operands[1], operands[2]));
18828 outlow = gen_lowpart (QImode, out);
18829 emit_insn (gen_cmpintqi (outlow));
18830 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18832 if (operands[0] != out)
18833 emit_move_insn (operands[0], out);
18838 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18840 (define_expand "cmpintqi"
18841 [(set (match_dup 1)
18842 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18844 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18845 (parallel [(set (match_operand:QI 0 "register_operand" "")
18846 (minus:QI (match_dup 1)
18848 (clobber (reg:CC FLAGS_REG))])]
18850 "operands[1] = gen_reg_rtx (QImode);
18851 operands[2] = gen_reg_rtx (QImode);")
18853 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18854 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18856 (define_expand "cmpstrnqi_nz_1"
18857 [(parallel [(set (reg:CC FLAGS_REG)
18858 (compare:CC (match_operand 4 "memory_operand" "")
18859 (match_operand 5 "memory_operand" "")))
18860 (use (match_operand 2 "register_operand" ""))
18861 (use (match_operand:SI 3 "immediate_operand" ""))
18862 (use (reg:SI DIRFLAG_REG))
18863 (clobber (match_operand 0 "register_operand" ""))
18864 (clobber (match_operand 1 "register_operand" ""))
18865 (clobber (match_dup 2))])]
18869 (define_insn "*cmpstrnqi_nz_1"
18870 [(set (reg:CC FLAGS_REG)
18871 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18872 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18873 (use (match_operand:SI 6 "register_operand" "2"))
18874 (use (match_operand:SI 3 "immediate_operand" "i"))
18875 (use (reg:SI DIRFLAG_REG))
18876 (clobber (match_operand:SI 0 "register_operand" "=S"))
18877 (clobber (match_operand:SI 1 "register_operand" "=D"))
18878 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18881 [(set_attr "type" "str")
18882 (set_attr "mode" "QI")
18883 (set_attr "prefix_rep" "1")])
18885 (define_insn "*cmpstrnqi_nz_rex_1"
18886 [(set (reg:CC FLAGS_REG)
18887 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18888 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18889 (use (match_operand:DI 6 "register_operand" "2"))
18890 (use (match_operand:SI 3 "immediate_operand" "i"))
18891 (use (reg:SI DIRFLAG_REG))
18892 (clobber (match_operand:DI 0 "register_operand" "=S"))
18893 (clobber (match_operand:DI 1 "register_operand" "=D"))
18894 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18897 [(set_attr "type" "str")
18898 (set_attr "mode" "QI")
18899 (set_attr "prefix_rep" "1")])
18901 ;; The same, but the count is not known to not be zero.
18903 (define_expand "cmpstrnqi_1"
18904 [(parallel [(set (reg:CC FLAGS_REG)
18905 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18907 (compare:CC (match_operand 4 "memory_operand" "")
18908 (match_operand 5 "memory_operand" ""))
18910 (use (match_operand:SI 3 "immediate_operand" ""))
18911 (use (reg:CC FLAGS_REG))
18912 (use (reg:SI DIRFLAG_REG))
18913 (clobber (match_operand 0 "register_operand" ""))
18914 (clobber (match_operand 1 "register_operand" ""))
18915 (clobber (match_dup 2))])]
18919 (define_insn "*cmpstrnqi_1"
18920 [(set (reg:CC FLAGS_REG)
18921 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18923 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18924 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18926 (use (match_operand:SI 3 "immediate_operand" "i"))
18927 (use (reg:CC FLAGS_REG))
18928 (use (reg:SI DIRFLAG_REG))
18929 (clobber (match_operand:SI 0 "register_operand" "=S"))
18930 (clobber (match_operand:SI 1 "register_operand" "=D"))
18931 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18934 [(set_attr "type" "str")
18935 (set_attr "mode" "QI")
18936 (set_attr "prefix_rep" "1")])
18938 (define_insn "*cmpstrnqi_rex_1"
18939 [(set (reg:CC FLAGS_REG)
18940 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18942 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18943 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18945 (use (match_operand:SI 3 "immediate_operand" "i"))
18946 (use (reg:CC FLAGS_REG))
18947 (use (reg:SI DIRFLAG_REG))
18948 (clobber (match_operand:DI 0 "register_operand" "=S"))
18949 (clobber (match_operand:DI 1 "register_operand" "=D"))
18950 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18953 [(set_attr "type" "str")
18954 (set_attr "mode" "QI")
18955 (set_attr "prefix_rep" "1")])
18957 (define_expand "strlensi"
18958 [(set (match_operand:SI 0 "register_operand" "")
18959 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18960 (match_operand:QI 2 "immediate_operand" "")
18961 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18964 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18970 (define_expand "strlendi"
18971 [(set (match_operand:DI 0 "register_operand" "")
18972 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18973 (match_operand:QI 2 "immediate_operand" "")
18974 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18977 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18983 (define_expand "strlenqi_1"
18984 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18985 (use (reg:SI DIRFLAG_REG))
18986 (clobber (match_operand 1 "register_operand" ""))
18987 (clobber (reg:CC FLAGS_REG))])]
18991 (define_insn "*strlenqi_1"
18992 [(set (match_operand:SI 0 "register_operand" "=&c")
18993 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18994 (match_operand:QI 2 "register_operand" "a")
18995 (match_operand:SI 3 "immediate_operand" "i")
18996 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18997 (use (reg:SI DIRFLAG_REG))
18998 (clobber (match_operand:SI 1 "register_operand" "=D"))
18999 (clobber (reg:CC FLAGS_REG))]
19002 [(set_attr "type" "str")
19003 (set_attr "mode" "QI")
19004 (set_attr "prefix_rep" "1")])
19006 (define_insn "*strlenqi_rex_1"
19007 [(set (match_operand:DI 0 "register_operand" "=&c")
19008 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19009 (match_operand:QI 2 "register_operand" "a")
19010 (match_operand:DI 3 "immediate_operand" "i")
19011 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19012 (use (reg:SI DIRFLAG_REG))
19013 (clobber (match_operand:DI 1 "register_operand" "=D"))
19014 (clobber (reg:CC FLAGS_REG))]
19017 [(set_attr "type" "str")
19018 (set_attr "mode" "QI")
19019 (set_attr "prefix_rep" "1")])
19021 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19022 ;; handled in combine, but it is not currently up to the task.
19023 ;; When used for their truth value, the cmpstrn* expanders generate
19032 ;; The intermediate three instructions are unnecessary.
19034 ;; This one handles cmpstrn*_nz_1...
19037 (set (reg:CC FLAGS_REG)
19038 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19039 (mem:BLK (match_operand 5 "register_operand" ""))))
19040 (use (match_operand 6 "register_operand" ""))
19041 (use (match_operand:SI 3 "immediate_operand" ""))
19042 (use (reg:SI DIRFLAG_REG))
19043 (clobber (match_operand 0 "register_operand" ""))
19044 (clobber (match_operand 1 "register_operand" ""))
19045 (clobber (match_operand 2 "register_operand" ""))])
19046 (set (match_operand:QI 7 "register_operand" "")
19047 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19048 (set (match_operand:QI 8 "register_operand" "")
19049 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19050 (set (reg FLAGS_REG)
19051 (compare (match_dup 7) (match_dup 8)))
19053 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19055 (set (reg:CC FLAGS_REG)
19056 (compare:CC (mem:BLK (match_dup 4))
19057 (mem:BLK (match_dup 5))))
19058 (use (match_dup 6))
19059 (use (match_dup 3))
19060 (use (reg:SI DIRFLAG_REG))
19061 (clobber (match_dup 0))
19062 (clobber (match_dup 1))
19063 (clobber (match_dup 2))])]
19066 ;; ...and this one handles cmpstrn*_1.
19069 (set (reg:CC FLAGS_REG)
19070 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19072 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19073 (mem:BLK (match_operand 5 "register_operand" "")))
19075 (use (match_operand:SI 3 "immediate_operand" ""))
19076 (use (reg:CC FLAGS_REG))
19077 (use (reg:SI DIRFLAG_REG))
19078 (clobber (match_operand 0 "register_operand" ""))
19079 (clobber (match_operand 1 "register_operand" ""))
19080 (clobber (match_operand 2 "register_operand" ""))])
19081 (set (match_operand:QI 7 "register_operand" "")
19082 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19083 (set (match_operand:QI 8 "register_operand" "")
19084 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19085 (set (reg FLAGS_REG)
19086 (compare (match_dup 7) (match_dup 8)))
19088 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19090 (set (reg:CC FLAGS_REG)
19091 (if_then_else:CC (ne (match_dup 6)
19093 (compare:CC (mem:BLK (match_dup 4))
19094 (mem:BLK (match_dup 5)))
19096 (use (match_dup 3))
19097 (use (reg:CC FLAGS_REG))
19098 (use (reg:SI DIRFLAG_REG))
19099 (clobber (match_dup 0))
19100 (clobber (match_dup 1))
19101 (clobber (match_dup 2))])]
19106 ;; Conditional move instructions.
19108 (define_expand "movdicc"
19109 [(set (match_operand:DI 0 "register_operand" "")
19110 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19111 (match_operand:DI 2 "general_operand" "")
19112 (match_operand:DI 3 "general_operand" "")))]
19114 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19116 (define_insn "x86_movdicc_0_m1_rex64"
19117 [(set (match_operand:DI 0 "register_operand" "=r")
19118 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19121 (clobber (reg:CC FLAGS_REG))]
19124 ; Since we don't have the proper number of operands for an alu insn,
19125 ; fill in all the blanks.
19126 [(set_attr "type" "alu")
19127 (set_attr "pent_pair" "pu")
19128 (set_attr "memory" "none")
19129 (set_attr "imm_disp" "false")
19130 (set_attr "mode" "DI")
19131 (set_attr "length_immediate" "0")])
19133 (define_insn "*movdicc_c_rex64"
19134 [(set (match_operand:DI 0 "register_operand" "=r,r")
19135 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19136 [(reg FLAGS_REG) (const_int 0)])
19137 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19138 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19139 "TARGET_64BIT && TARGET_CMOVE
19140 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19142 cmov%O2%C1\t{%2, %0|%0, %2}
19143 cmov%O2%c1\t{%3, %0|%0, %3}"
19144 [(set_attr "type" "icmov")
19145 (set_attr "mode" "DI")])
19147 (define_expand "movsicc"
19148 [(set (match_operand:SI 0 "register_operand" "")
19149 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19150 (match_operand:SI 2 "general_operand" "")
19151 (match_operand:SI 3 "general_operand" "")))]
19153 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19155 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19156 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19157 ;; So just document what we're doing explicitly.
19159 (define_insn "x86_movsicc_0_m1"
19160 [(set (match_operand:SI 0 "register_operand" "=r")
19161 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19164 (clobber (reg:CC FLAGS_REG))]
19167 ; Since we don't have the proper number of operands for an alu insn,
19168 ; fill in all the blanks.
19169 [(set_attr "type" "alu")
19170 (set_attr "pent_pair" "pu")
19171 (set_attr "memory" "none")
19172 (set_attr "imm_disp" "false")
19173 (set_attr "mode" "SI")
19174 (set_attr "length_immediate" "0")])
19176 (define_insn "*movsicc_noc"
19177 [(set (match_operand:SI 0 "register_operand" "=r,r")
19178 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19179 [(reg FLAGS_REG) (const_int 0)])
19180 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19181 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19183 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19185 cmov%O2%C1\t{%2, %0|%0, %2}
19186 cmov%O2%c1\t{%3, %0|%0, %3}"
19187 [(set_attr "type" "icmov")
19188 (set_attr "mode" "SI")])
19190 (define_expand "movhicc"
19191 [(set (match_operand:HI 0 "register_operand" "")
19192 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19193 (match_operand:HI 2 "general_operand" "")
19194 (match_operand:HI 3 "general_operand" "")))]
19195 "TARGET_HIMODE_MATH"
19196 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19198 (define_insn "*movhicc_noc"
19199 [(set (match_operand:HI 0 "register_operand" "=r,r")
19200 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19201 [(reg FLAGS_REG) (const_int 0)])
19202 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19203 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19205 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19207 cmov%O2%C1\t{%2, %0|%0, %2}
19208 cmov%O2%c1\t{%3, %0|%0, %3}"
19209 [(set_attr "type" "icmov")
19210 (set_attr "mode" "HI")])
19212 (define_expand "movqicc"
19213 [(set (match_operand:QI 0 "register_operand" "")
19214 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19215 (match_operand:QI 2 "general_operand" "")
19216 (match_operand:QI 3 "general_operand" "")))]
19217 "TARGET_QIMODE_MATH"
19218 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19220 (define_insn_and_split "*movqicc_noc"
19221 [(set (match_operand:QI 0 "register_operand" "=r,r")
19222 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19223 [(match_operand 4 "flags_reg_operand" "")
19225 (match_operand:QI 2 "register_operand" "r,0")
19226 (match_operand:QI 3 "register_operand" "0,r")))]
19227 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19229 "&& reload_completed"
19230 [(set (match_dup 0)
19231 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19234 "operands[0] = gen_lowpart (SImode, operands[0]);
19235 operands[2] = gen_lowpart (SImode, operands[2]);
19236 operands[3] = gen_lowpart (SImode, operands[3]);"
19237 [(set_attr "type" "icmov")
19238 (set_attr "mode" "SI")])
19240 (define_expand "movsfcc"
19241 [(set (match_operand:SF 0 "register_operand" "")
19242 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19243 (match_operand:SF 2 "register_operand" "")
19244 (match_operand:SF 3 "register_operand" "")))]
19245 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19246 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19248 (define_insn "*movsfcc_1_387"
19249 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19250 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19251 [(reg FLAGS_REG) (const_int 0)])
19252 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19253 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19254 "TARGET_80387 && TARGET_CMOVE
19255 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19257 fcmov%F1\t{%2, %0|%0, %2}
19258 fcmov%f1\t{%3, %0|%0, %3}
19259 cmov%O2%C1\t{%2, %0|%0, %2}
19260 cmov%O2%c1\t{%3, %0|%0, %3}"
19261 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19262 (set_attr "mode" "SF,SF,SI,SI")])
19264 (define_expand "movdfcc"
19265 [(set (match_operand:DF 0 "register_operand" "")
19266 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19267 (match_operand:DF 2 "register_operand" "")
19268 (match_operand:DF 3 "register_operand" "")))]
19269 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19270 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19272 (define_insn "*movdfcc_1"
19273 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19274 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19275 [(reg FLAGS_REG) (const_int 0)])
19276 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19277 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19278 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19279 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19281 fcmov%F1\t{%2, %0|%0, %2}
19282 fcmov%f1\t{%3, %0|%0, %3}
19285 [(set_attr "type" "fcmov,fcmov,multi,multi")
19286 (set_attr "mode" "DF")])
19288 (define_insn "*movdfcc_1_rex64"
19289 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19290 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19291 [(reg FLAGS_REG) (const_int 0)])
19292 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19293 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19294 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19295 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19297 fcmov%F1\t{%2, %0|%0, %2}
19298 fcmov%f1\t{%3, %0|%0, %3}
19299 cmov%O2%C1\t{%2, %0|%0, %2}
19300 cmov%O2%c1\t{%3, %0|%0, %3}"
19301 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19302 (set_attr "mode" "DF")])
19305 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19306 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19307 [(match_operand 4 "flags_reg_operand" "")
19309 (match_operand:DF 2 "nonimmediate_operand" "")
19310 (match_operand:DF 3 "nonimmediate_operand" "")))]
19311 "!TARGET_64BIT && reload_completed"
19312 [(set (match_dup 2)
19313 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19317 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19320 "split_di (operands+2, 1, operands+5, operands+6);
19321 split_di (operands+3, 1, operands+7, operands+8);
19322 split_di (operands, 1, operands+2, operands+3);")
19324 (define_expand "movxfcc"
19325 [(set (match_operand:XF 0 "register_operand" "")
19326 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19327 (match_operand:XF 2 "register_operand" "")
19328 (match_operand:XF 3 "register_operand" "")))]
19329 "TARGET_80387 && TARGET_CMOVE"
19330 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19332 (define_insn "*movxfcc_1"
19333 [(set (match_operand:XF 0 "register_operand" "=f,f")
19334 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19335 [(reg FLAGS_REG) (const_int 0)])
19336 (match_operand:XF 2 "register_operand" "f,0")
19337 (match_operand:XF 3 "register_operand" "0,f")))]
19338 "TARGET_80387 && TARGET_CMOVE"
19340 fcmov%F1\t{%2, %0|%0, %2}
19341 fcmov%f1\t{%3, %0|%0, %3}"
19342 [(set_attr "type" "fcmov")
19343 (set_attr "mode" "XF")])
19345 ;; These versions of the min/max patterns are intentionally ignorant of
19346 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19347 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19348 ;; are undefined in this condition, we're certain this is correct.
19350 (define_insn "sminsf3"
19351 [(set (match_operand:SF 0 "register_operand" "=x")
19352 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19353 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19355 "minss\t{%2, %0|%0, %2}"
19356 [(set_attr "type" "sseadd")
19357 (set_attr "mode" "SF")])
19359 (define_insn "smaxsf3"
19360 [(set (match_operand:SF 0 "register_operand" "=x")
19361 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19362 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19364 "maxss\t{%2, %0|%0, %2}"
19365 [(set_attr "type" "sseadd")
19366 (set_attr "mode" "SF")])
19368 (define_insn "smindf3"
19369 [(set (match_operand:DF 0 "register_operand" "=x")
19370 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19371 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19372 "TARGET_SSE2 && TARGET_SSE_MATH"
19373 "minsd\t{%2, %0|%0, %2}"
19374 [(set_attr "type" "sseadd")
19375 (set_attr "mode" "DF")])
19377 (define_insn "smaxdf3"
19378 [(set (match_operand:DF 0 "register_operand" "=x")
19379 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19380 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19381 "TARGET_SSE2 && TARGET_SSE_MATH"
19382 "maxsd\t{%2, %0|%0, %2}"
19383 [(set_attr "type" "sseadd")
19384 (set_attr "mode" "DF")])
19386 ;; These versions of the min/max patterns implement exactly the operations
19387 ;; min = (op1 < op2 ? op1 : op2)
19388 ;; max = (!(op1 < op2) ? op1 : op2)
19389 ;; Their operands are not commutative, and thus they may be used in the
19390 ;; presence of -0.0 and NaN.
19392 (define_insn "*ieee_sminsf3"
19393 [(set (match_operand:SF 0 "register_operand" "=x")
19394 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19395 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19398 "minss\t{%2, %0|%0, %2}"
19399 [(set_attr "type" "sseadd")
19400 (set_attr "mode" "SF")])
19402 (define_insn "*ieee_smaxsf3"
19403 [(set (match_operand:SF 0 "register_operand" "=x")
19404 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19405 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19408 "maxss\t{%2, %0|%0, %2}"
19409 [(set_attr "type" "sseadd")
19410 (set_attr "mode" "SF")])
19412 (define_insn "*ieee_smindf3"
19413 [(set (match_operand:DF 0 "register_operand" "=x")
19414 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19415 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19417 "TARGET_SSE2 && TARGET_SSE_MATH"
19418 "minsd\t{%2, %0|%0, %2}"
19419 [(set_attr "type" "sseadd")
19420 (set_attr "mode" "DF")])
19422 (define_insn "*ieee_smaxdf3"
19423 [(set (match_operand:DF 0 "register_operand" "=x")
19424 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19425 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19427 "TARGET_SSE2 && TARGET_SSE_MATH"
19428 "maxsd\t{%2, %0|%0, %2}"
19429 [(set_attr "type" "sseadd")
19430 (set_attr "mode" "DF")])
19432 ;; Make two stack loads independent:
19434 ;; fld %st(0) -> fld bb
19435 ;; fmul bb fmul %st(1), %st
19437 ;; Actually we only match the last two instructions for simplicity.
19439 [(set (match_operand 0 "fp_register_operand" "")
19440 (match_operand 1 "fp_register_operand" ""))
19442 (match_operator 2 "binary_fp_operator"
19444 (match_operand 3 "memory_operand" "")]))]
19445 "REGNO (operands[0]) != REGNO (operands[1])"
19446 [(set (match_dup 0) (match_dup 3))
19447 (set (match_dup 0) (match_dup 4))]
19449 ;; The % modifier is not operational anymore in peephole2's, so we have to
19450 ;; swap the operands manually in the case of addition and multiplication.
19451 "if (COMMUTATIVE_ARITH_P (operands[2]))
19452 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19453 operands[0], operands[1]);
19455 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19456 operands[1], operands[0]);")
19458 ;; Conditional addition patterns
19459 (define_expand "addqicc"
19460 [(match_operand:QI 0 "register_operand" "")
19461 (match_operand 1 "comparison_operator" "")
19462 (match_operand:QI 2 "register_operand" "")
19463 (match_operand:QI 3 "const_int_operand" "")]
19465 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19467 (define_expand "addhicc"
19468 [(match_operand:HI 0 "register_operand" "")
19469 (match_operand 1 "comparison_operator" "")
19470 (match_operand:HI 2 "register_operand" "")
19471 (match_operand:HI 3 "const_int_operand" "")]
19473 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19475 (define_expand "addsicc"
19476 [(match_operand:SI 0 "register_operand" "")
19477 (match_operand 1 "comparison_operator" "")
19478 (match_operand:SI 2 "register_operand" "")
19479 (match_operand:SI 3 "const_int_operand" "")]
19481 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19483 (define_expand "adddicc"
19484 [(match_operand:DI 0 "register_operand" "")
19485 (match_operand 1 "comparison_operator" "")
19486 (match_operand:DI 2 "register_operand" "")
19487 (match_operand:DI 3 "const_int_operand" "")]
19489 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19492 ;; Misc patterns (?)
19494 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19495 ;; Otherwise there will be nothing to keep
19497 ;; [(set (reg ebp) (reg esp))]
19498 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19499 ;; (clobber (eflags)]
19500 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19502 ;; in proper program order.
19503 (define_insn "pro_epilogue_adjust_stack_1"
19504 [(set (match_operand:SI 0 "register_operand" "=r,r")
19505 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19506 (match_operand:SI 2 "immediate_operand" "i,i")))
19507 (clobber (reg:CC FLAGS_REG))
19508 (clobber (mem:BLK (scratch)))]
19511 switch (get_attr_type (insn))
19514 return "mov{l}\t{%1, %0|%0, %1}";
19517 if (GET_CODE (operands[2]) == CONST_INT
19518 && (INTVAL (operands[2]) == 128
19519 || (INTVAL (operands[2]) < 0
19520 && INTVAL (operands[2]) != -128)))
19522 operands[2] = GEN_INT (-INTVAL (operands[2]));
19523 return "sub{l}\t{%2, %0|%0, %2}";
19525 return "add{l}\t{%2, %0|%0, %2}";
19528 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19529 return "lea{l}\t{%a2, %0|%0, %a2}";
19532 gcc_unreachable ();
19535 [(set (attr "type")
19536 (cond [(eq_attr "alternative" "0")
19537 (const_string "alu")
19538 (match_operand:SI 2 "const0_operand" "")
19539 (const_string "imov")
19541 (const_string "lea")))
19542 (set_attr "mode" "SI")])
19544 (define_insn "pro_epilogue_adjust_stack_rex64"
19545 [(set (match_operand:DI 0 "register_operand" "=r,r")
19546 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19547 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19548 (clobber (reg:CC FLAGS_REG))
19549 (clobber (mem:BLK (scratch)))]
19552 switch (get_attr_type (insn))
19555 return "mov{q}\t{%1, %0|%0, %1}";
19558 if (GET_CODE (operands[2]) == CONST_INT
19559 /* Avoid overflows. */
19560 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19561 && (INTVAL (operands[2]) == 128
19562 || (INTVAL (operands[2]) < 0
19563 && INTVAL (operands[2]) != -128)))
19565 operands[2] = GEN_INT (-INTVAL (operands[2]));
19566 return "sub{q}\t{%2, %0|%0, %2}";
19568 return "add{q}\t{%2, %0|%0, %2}";
19571 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19572 return "lea{q}\t{%a2, %0|%0, %a2}";
19575 gcc_unreachable ();
19578 [(set (attr "type")
19579 (cond [(eq_attr "alternative" "0")
19580 (const_string "alu")
19581 (match_operand:DI 2 "const0_operand" "")
19582 (const_string "imov")
19584 (const_string "lea")))
19585 (set_attr "mode" "DI")])
19587 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19588 [(set (match_operand:DI 0 "register_operand" "=r,r")
19589 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19590 (match_operand:DI 3 "immediate_operand" "i,i")))
19591 (use (match_operand:DI 2 "register_operand" "r,r"))
19592 (clobber (reg:CC FLAGS_REG))
19593 (clobber (mem:BLK (scratch)))]
19596 switch (get_attr_type (insn))
19599 return "add{q}\t{%2, %0|%0, %2}";
19602 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19603 return "lea{q}\t{%a2, %0|%0, %a2}";
19606 gcc_unreachable ();
19609 [(set_attr "type" "alu,lea")
19610 (set_attr "mode" "DI")])
19612 (define_expand "allocate_stack_worker"
19613 [(match_operand:SI 0 "register_operand" "")]
19614 "TARGET_STACK_PROBE"
19616 if (reload_completed)
19619 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19621 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19626 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19628 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19633 (define_insn "allocate_stack_worker_1"
19634 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19635 UNSPECV_STACK_PROBE)
19636 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19637 (clobber (match_scratch:SI 1 "=0"))
19638 (clobber (reg:CC FLAGS_REG))]
19639 "!TARGET_64BIT && TARGET_STACK_PROBE"
19641 [(set_attr "type" "multi")
19642 (set_attr "length" "5")])
19644 (define_expand "allocate_stack_worker_postreload"
19645 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19646 UNSPECV_STACK_PROBE)
19647 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19648 (clobber (match_dup 0))
19649 (clobber (reg:CC FLAGS_REG))])]
19653 (define_insn "allocate_stack_worker_rex64"
19654 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19655 UNSPECV_STACK_PROBE)
19656 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19657 (clobber (match_scratch:DI 1 "=0"))
19658 (clobber (reg:CC FLAGS_REG))]
19659 "TARGET_64BIT && TARGET_STACK_PROBE"
19661 [(set_attr "type" "multi")
19662 (set_attr "length" "5")])
19664 (define_expand "allocate_stack_worker_rex64_postreload"
19665 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19666 UNSPECV_STACK_PROBE)
19667 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19668 (clobber (match_dup 0))
19669 (clobber (reg:CC FLAGS_REG))])]
19673 (define_expand "allocate_stack"
19674 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19675 (minus:SI (reg:SI SP_REG)
19676 (match_operand:SI 1 "general_operand" "")))
19677 (clobber (reg:CC FLAGS_REG))])
19678 (parallel [(set (reg:SI SP_REG)
19679 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19680 (clobber (reg:CC FLAGS_REG))])]
19681 "TARGET_STACK_PROBE"
19683 #ifdef CHECK_STACK_LIMIT
19684 if (GET_CODE (operands[1]) == CONST_INT
19685 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19686 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19690 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19693 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19697 (define_expand "builtin_setjmp_receiver"
19698 [(label_ref (match_operand 0 "" ""))]
19699 "!TARGET_64BIT && flag_pic"
19704 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19705 rtx label_rtx = gen_label_rtx ();
19706 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19707 xops[0] = xops[1] = picreg;
19708 xops[2] = gen_rtx_CONST (SImode,
19709 gen_rtx_MINUS (SImode,
19710 gen_rtx_LABEL_REF (SImode, label_rtx),
19711 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19712 ix86_expand_binary_operator (MINUS, SImode, xops);
19715 emit_insn (gen_set_got (pic_offset_table_rtx));
19719 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19722 [(set (match_operand 0 "register_operand" "")
19723 (match_operator 3 "promotable_binary_operator"
19724 [(match_operand 1 "register_operand" "")
19725 (match_operand 2 "aligned_operand" "")]))
19726 (clobber (reg:CC FLAGS_REG))]
19727 "! TARGET_PARTIAL_REG_STALL && reload_completed
19728 && ((GET_MODE (operands[0]) == HImode
19729 && ((!optimize_size && !TARGET_FAST_PREFIX)
19730 /* ??? next two lines just !satisfies_constraint_K (...) */
19731 || GET_CODE (operands[2]) != CONST_INT
19732 || satisfies_constraint_K (operands[2])))
19733 || (GET_MODE (operands[0]) == QImode
19734 && (TARGET_PROMOTE_QImode || optimize_size)))"
19735 [(parallel [(set (match_dup 0)
19736 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19737 (clobber (reg:CC FLAGS_REG))])]
19738 "operands[0] = gen_lowpart (SImode, operands[0]);
19739 operands[1] = gen_lowpart (SImode, operands[1]);
19740 if (GET_CODE (operands[3]) != ASHIFT)
19741 operands[2] = gen_lowpart (SImode, operands[2]);
19742 PUT_MODE (operands[3], SImode);")
19744 ; Promote the QImode tests, as i386 has encoding of the AND
19745 ; instruction with 32-bit sign-extended immediate and thus the
19746 ; instruction size is unchanged, except in the %eax case for
19747 ; which it is increased by one byte, hence the ! optimize_size.
19749 [(set (match_operand 0 "flags_reg_operand" "")
19750 (match_operator 2 "compare_operator"
19751 [(and (match_operand 3 "aligned_operand" "")
19752 (match_operand 4 "const_int_operand" ""))
19754 (set (match_operand 1 "register_operand" "")
19755 (and (match_dup 3) (match_dup 4)))]
19756 "! TARGET_PARTIAL_REG_STALL && reload_completed
19757 /* Ensure that the operand will remain sign-extended immediate. */
19758 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19760 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19761 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19762 [(parallel [(set (match_dup 0)
19763 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19766 (and:SI (match_dup 3) (match_dup 4)))])]
19769 = gen_int_mode (INTVAL (operands[4])
19770 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19771 operands[1] = gen_lowpart (SImode, operands[1]);
19772 operands[3] = gen_lowpart (SImode, operands[3]);
19775 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19776 ; the TEST instruction with 32-bit sign-extended immediate and thus
19777 ; the instruction size would at least double, which is not what we
19778 ; want even with ! optimize_size.
19780 [(set (match_operand 0 "flags_reg_operand" "")
19781 (match_operator 1 "compare_operator"
19782 [(and (match_operand:HI 2 "aligned_operand" "")
19783 (match_operand:HI 3 "const_int_operand" ""))
19785 "! TARGET_PARTIAL_REG_STALL && reload_completed
19786 /* Ensure that the operand will remain sign-extended immediate. */
19787 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19788 && ! TARGET_FAST_PREFIX
19789 && ! optimize_size"
19790 [(set (match_dup 0)
19791 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19795 = gen_int_mode (INTVAL (operands[3])
19796 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19797 operands[2] = gen_lowpart (SImode, operands[2]);
19801 [(set (match_operand 0 "register_operand" "")
19802 (neg (match_operand 1 "register_operand" "")))
19803 (clobber (reg:CC FLAGS_REG))]
19804 "! TARGET_PARTIAL_REG_STALL && reload_completed
19805 && (GET_MODE (operands[0]) == HImode
19806 || (GET_MODE (operands[0]) == QImode
19807 && (TARGET_PROMOTE_QImode || optimize_size)))"
19808 [(parallel [(set (match_dup 0)
19809 (neg:SI (match_dup 1)))
19810 (clobber (reg:CC FLAGS_REG))])]
19811 "operands[0] = gen_lowpart (SImode, operands[0]);
19812 operands[1] = gen_lowpart (SImode, operands[1]);")
19815 [(set (match_operand 0 "register_operand" "")
19816 (not (match_operand 1 "register_operand" "")))]
19817 "! TARGET_PARTIAL_REG_STALL && reload_completed
19818 && (GET_MODE (operands[0]) == HImode
19819 || (GET_MODE (operands[0]) == QImode
19820 && (TARGET_PROMOTE_QImode || optimize_size)))"
19821 [(set (match_dup 0)
19822 (not:SI (match_dup 1)))]
19823 "operands[0] = gen_lowpart (SImode, operands[0]);
19824 operands[1] = gen_lowpart (SImode, operands[1]);")
19827 [(set (match_operand 0 "register_operand" "")
19828 (if_then_else (match_operator 1 "comparison_operator"
19829 [(reg FLAGS_REG) (const_int 0)])
19830 (match_operand 2 "register_operand" "")
19831 (match_operand 3 "register_operand" "")))]
19832 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19833 && (GET_MODE (operands[0]) == HImode
19834 || (GET_MODE (operands[0]) == QImode
19835 && (TARGET_PROMOTE_QImode || optimize_size)))"
19836 [(set (match_dup 0)
19837 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19838 "operands[0] = gen_lowpart (SImode, operands[0]);
19839 operands[2] = gen_lowpart (SImode, operands[2]);
19840 operands[3] = gen_lowpart (SImode, operands[3]);")
19843 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19844 ;; transform a complex memory operation into two memory to register operations.
19846 ;; Don't push memory operands
19848 [(set (match_operand:SI 0 "push_operand" "")
19849 (match_operand:SI 1 "memory_operand" ""))
19850 (match_scratch:SI 2 "r")]
19851 "!optimize_size && !TARGET_PUSH_MEMORY
19852 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19853 [(set (match_dup 2) (match_dup 1))
19854 (set (match_dup 0) (match_dup 2))]
19858 [(set (match_operand:DI 0 "push_operand" "")
19859 (match_operand:DI 1 "memory_operand" ""))
19860 (match_scratch:DI 2 "r")]
19861 "!optimize_size && !TARGET_PUSH_MEMORY
19862 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19863 [(set (match_dup 2) (match_dup 1))
19864 (set (match_dup 0) (match_dup 2))]
19867 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19870 [(set (match_operand:SF 0 "push_operand" "")
19871 (match_operand:SF 1 "memory_operand" ""))
19872 (match_scratch:SF 2 "r")]
19873 "!optimize_size && !TARGET_PUSH_MEMORY
19874 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19875 [(set (match_dup 2) (match_dup 1))
19876 (set (match_dup 0) (match_dup 2))]
19880 [(set (match_operand:HI 0 "push_operand" "")
19881 (match_operand:HI 1 "memory_operand" ""))
19882 (match_scratch:HI 2 "r")]
19883 "!optimize_size && !TARGET_PUSH_MEMORY
19884 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19885 [(set (match_dup 2) (match_dup 1))
19886 (set (match_dup 0) (match_dup 2))]
19890 [(set (match_operand:QI 0 "push_operand" "")
19891 (match_operand:QI 1 "memory_operand" ""))
19892 (match_scratch:QI 2 "q")]
19893 "!optimize_size && !TARGET_PUSH_MEMORY
19894 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19895 [(set (match_dup 2) (match_dup 1))
19896 (set (match_dup 0) (match_dup 2))]
19899 ;; Don't move an immediate directly to memory when the instruction
19902 [(match_scratch:SI 1 "r")
19903 (set (match_operand:SI 0 "memory_operand" "")
19906 && ! TARGET_USE_MOV0
19907 && TARGET_SPLIT_LONG_MOVES
19908 && get_attr_length (insn) >= ix86_cost->large_insn
19909 && peep2_regno_dead_p (0, FLAGS_REG)"
19910 [(parallel [(set (match_dup 1) (const_int 0))
19911 (clobber (reg:CC FLAGS_REG))])
19912 (set (match_dup 0) (match_dup 1))]
19916 [(match_scratch:HI 1 "r")
19917 (set (match_operand:HI 0 "memory_operand" "")
19920 && ! TARGET_USE_MOV0
19921 && TARGET_SPLIT_LONG_MOVES
19922 && get_attr_length (insn) >= ix86_cost->large_insn
19923 && peep2_regno_dead_p (0, FLAGS_REG)"
19924 [(parallel [(set (match_dup 2) (const_int 0))
19925 (clobber (reg:CC FLAGS_REG))])
19926 (set (match_dup 0) (match_dup 1))]
19927 "operands[2] = gen_lowpart (SImode, operands[1]);")
19930 [(match_scratch:QI 1 "q")
19931 (set (match_operand:QI 0 "memory_operand" "")
19934 && ! TARGET_USE_MOV0
19935 && TARGET_SPLIT_LONG_MOVES
19936 && get_attr_length (insn) >= ix86_cost->large_insn
19937 && peep2_regno_dead_p (0, FLAGS_REG)"
19938 [(parallel [(set (match_dup 2) (const_int 0))
19939 (clobber (reg:CC FLAGS_REG))])
19940 (set (match_dup 0) (match_dup 1))]
19941 "operands[2] = gen_lowpart (SImode, operands[1]);")
19944 [(match_scratch:SI 2 "r")
19945 (set (match_operand:SI 0 "memory_operand" "")
19946 (match_operand:SI 1 "immediate_operand" ""))]
19948 && get_attr_length (insn) >= ix86_cost->large_insn
19949 && TARGET_SPLIT_LONG_MOVES"
19950 [(set (match_dup 2) (match_dup 1))
19951 (set (match_dup 0) (match_dup 2))]
19955 [(match_scratch:HI 2 "r")
19956 (set (match_operand:HI 0 "memory_operand" "")
19957 (match_operand:HI 1 "immediate_operand" ""))]
19958 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19959 && TARGET_SPLIT_LONG_MOVES"
19960 [(set (match_dup 2) (match_dup 1))
19961 (set (match_dup 0) (match_dup 2))]
19965 [(match_scratch:QI 2 "q")
19966 (set (match_operand:QI 0 "memory_operand" "")
19967 (match_operand:QI 1 "immediate_operand" ""))]
19968 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19969 && TARGET_SPLIT_LONG_MOVES"
19970 [(set (match_dup 2) (match_dup 1))
19971 (set (match_dup 0) (match_dup 2))]
19974 ;; Don't compare memory with zero, load and use a test instead.
19976 [(set (match_operand 0 "flags_reg_operand" "")
19977 (match_operator 1 "compare_operator"
19978 [(match_operand:SI 2 "memory_operand" "")
19980 (match_scratch:SI 3 "r")]
19981 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19982 [(set (match_dup 3) (match_dup 2))
19983 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19986 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19987 ;; Don't split NOTs with a displacement operand, because resulting XOR
19988 ;; will not be pairable anyway.
19990 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19991 ;; represented using a modRM byte. The XOR replacement is long decoded,
19992 ;; so this split helps here as well.
19994 ;; Note: Can't do this as a regular split because we can't get proper
19995 ;; lifetime information then.
19998 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19999 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20001 && peep2_regno_dead_p (0, FLAGS_REG)
20002 && ((TARGET_PENTIUM
20003 && (GET_CODE (operands[0]) != MEM
20004 || !memory_displacement_operand (operands[0], SImode)))
20005 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20006 [(parallel [(set (match_dup 0)
20007 (xor:SI (match_dup 1) (const_int -1)))
20008 (clobber (reg:CC FLAGS_REG))])]
20012 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20013 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20015 && peep2_regno_dead_p (0, FLAGS_REG)
20016 && ((TARGET_PENTIUM
20017 && (GET_CODE (operands[0]) != MEM
20018 || !memory_displacement_operand (operands[0], HImode)))
20019 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20020 [(parallel [(set (match_dup 0)
20021 (xor:HI (match_dup 1) (const_int -1)))
20022 (clobber (reg:CC FLAGS_REG))])]
20026 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20027 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20029 && peep2_regno_dead_p (0, FLAGS_REG)
20030 && ((TARGET_PENTIUM
20031 && (GET_CODE (operands[0]) != MEM
20032 || !memory_displacement_operand (operands[0], QImode)))
20033 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20034 [(parallel [(set (match_dup 0)
20035 (xor:QI (match_dup 1) (const_int -1)))
20036 (clobber (reg:CC FLAGS_REG))])]
20039 ;; Non pairable "test imm, reg" instructions can be translated to
20040 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20041 ;; byte opcode instead of two, have a short form for byte operands),
20042 ;; so do it for other CPUs as well. Given that the value was dead,
20043 ;; this should not create any new dependencies. Pass on the sub-word
20044 ;; versions if we're concerned about partial register stalls.
20047 [(set (match_operand 0 "flags_reg_operand" "")
20048 (match_operator 1 "compare_operator"
20049 [(and:SI (match_operand:SI 2 "register_operand" "")
20050 (match_operand:SI 3 "immediate_operand" ""))
20052 "ix86_match_ccmode (insn, CCNOmode)
20053 && (true_regnum (operands[2]) != 0
20054 || satisfies_constraint_K (operands[3]))
20055 && peep2_reg_dead_p (1, operands[2])"
20057 [(set (match_dup 0)
20058 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20061 (and:SI (match_dup 2) (match_dup 3)))])]
20064 ;; We don't need to handle HImode case, because it will be promoted to SImode
20065 ;; on ! TARGET_PARTIAL_REG_STALL
20068 [(set (match_operand 0 "flags_reg_operand" "")
20069 (match_operator 1 "compare_operator"
20070 [(and:QI (match_operand:QI 2 "register_operand" "")
20071 (match_operand:QI 3 "immediate_operand" ""))
20073 "! TARGET_PARTIAL_REG_STALL
20074 && ix86_match_ccmode (insn, CCNOmode)
20075 && true_regnum (operands[2]) != 0
20076 && peep2_reg_dead_p (1, operands[2])"
20078 [(set (match_dup 0)
20079 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20082 (and:QI (match_dup 2) (match_dup 3)))])]
20086 [(set (match_operand 0 "flags_reg_operand" "")
20087 (match_operator 1 "compare_operator"
20090 (match_operand 2 "ext_register_operand" "")
20093 (match_operand 3 "const_int_operand" ""))
20095 "! TARGET_PARTIAL_REG_STALL
20096 && ix86_match_ccmode (insn, CCNOmode)
20097 && true_regnum (operands[2]) != 0
20098 && peep2_reg_dead_p (1, operands[2])"
20099 [(parallel [(set (match_dup 0)
20108 (set (zero_extract:SI (match_dup 2)
20119 ;; Don't do logical operations with memory inputs.
20121 [(match_scratch:SI 2 "r")
20122 (parallel [(set (match_operand:SI 0 "register_operand" "")
20123 (match_operator:SI 3 "arith_or_logical_operator"
20125 (match_operand:SI 1 "memory_operand" "")]))
20126 (clobber (reg:CC FLAGS_REG))])]
20127 "! optimize_size && ! TARGET_READ_MODIFY"
20128 [(set (match_dup 2) (match_dup 1))
20129 (parallel [(set (match_dup 0)
20130 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20131 (clobber (reg:CC FLAGS_REG))])]
20135 [(match_scratch:SI 2 "r")
20136 (parallel [(set (match_operand:SI 0 "register_operand" "")
20137 (match_operator:SI 3 "arith_or_logical_operator"
20138 [(match_operand:SI 1 "memory_operand" "")
20140 (clobber (reg:CC FLAGS_REG))])]
20141 "! optimize_size && ! TARGET_READ_MODIFY"
20142 [(set (match_dup 2) (match_dup 1))
20143 (parallel [(set (match_dup 0)
20144 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20145 (clobber (reg:CC FLAGS_REG))])]
20148 ; Don't do logical operations with memory outputs
20150 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20151 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20152 ; the same decoder scheduling characteristics as the original.
20155 [(match_scratch:SI 2 "r")
20156 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20157 (match_operator:SI 3 "arith_or_logical_operator"
20159 (match_operand:SI 1 "nonmemory_operand" "")]))
20160 (clobber (reg:CC FLAGS_REG))])]
20161 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20162 [(set (match_dup 2) (match_dup 0))
20163 (parallel [(set (match_dup 2)
20164 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20165 (clobber (reg:CC FLAGS_REG))])
20166 (set (match_dup 0) (match_dup 2))]
20170 [(match_scratch:SI 2 "r")
20171 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20172 (match_operator:SI 3 "arith_or_logical_operator"
20173 [(match_operand:SI 1 "nonmemory_operand" "")
20175 (clobber (reg:CC FLAGS_REG))])]
20176 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20177 [(set (match_dup 2) (match_dup 0))
20178 (parallel [(set (match_dup 2)
20179 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20180 (clobber (reg:CC FLAGS_REG))])
20181 (set (match_dup 0) (match_dup 2))]
20184 ;; Attempt to always use XOR for zeroing registers.
20186 [(set (match_operand 0 "register_operand" "")
20187 (match_operand 1 "const0_operand" ""))]
20188 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20189 && (! TARGET_USE_MOV0 || optimize_size)
20190 && GENERAL_REG_P (operands[0])
20191 && peep2_regno_dead_p (0, FLAGS_REG)"
20192 [(parallel [(set (match_dup 0) (const_int 0))
20193 (clobber (reg:CC FLAGS_REG))])]
20195 operands[0] = gen_lowpart (word_mode, operands[0]);
20199 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20201 "(GET_MODE (operands[0]) == QImode
20202 || GET_MODE (operands[0]) == HImode)
20203 && (! TARGET_USE_MOV0 || optimize_size)
20204 && peep2_regno_dead_p (0, FLAGS_REG)"
20205 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20206 (clobber (reg:CC FLAGS_REG))])])
20208 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20210 [(set (match_operand 0 "register_operand" "")
20212 "(GET_MODE (operands[0]) == HImode
20213 || GET_MODE (operands[0]) == SImode
20214 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20215 && (optimize_size || TARGET_PENTIUM)
20216 && peep2_regno_dead_p (0, FLAGS_REG)"
20217 [(parallel [(set (match_dup 0) (const_int -1))
20218 (clobber (reg:CC FLAGS_REG))])]
20219 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20222 ;; Attempt to convert simple leas to adds. These can be created by
20225 [(set (match_operand:SI 0 "register_operand" "")
20226 (plus:SI (match_dup 0)
20227 (match_operand:SI 1 "nonmemory_operand" "")))]
20228 "peep2_regno_dead_p (0, FLAGS_REG)"
20229 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20230 (clobber (reg:CC FLAGS_REG))])]
20234 [(set (match_operand:SI 0 "register_operand" "")
20235 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20236 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20237 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20238 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20239 (clobber (reg:CC FLAGS_REG))])]
20240 "operands[2] = gen_lowpart (SImode, operands[2]);")
20243 [(set (match_operand:DI 0 "register_operand" "")
20244 (plus:DI (match_dup 0)
20245 (match_operand:DI 1 "x86_64_general_operand" "")))]
20246 "peep2_regno_dead_p (0, FLAGS_REG)"
20247 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20248 (clobber (reg:CC FLAGS_REG))])]
20252 [(set (match_operand:SI 0 "register_operand" "")
20253 (mult:SI (match_dup 0)
20254 (match_operand:SI 1 "const_int_operand" "")))]
20255 "exact_log2 (INTVAL (operands[1])) >= 0
20256 && peep2_regno_dead_p (0, FLAGS_REG)"
20257 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20258 (clobber (reg:CC FLAGS_REG))])]
20259 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20262 [(set (match_operand:DI 0 "register_operand" "")
20263 (mult:DI (match_dup 0)
20264 (match_operand:DI 1 "const_int_operand" "")))]
20265 "exact_log2 (INTVAL (operands[1])) >= 0
20266 && peep2_regno_dead_p (0, FLAGS_REG)"
20267 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20268 (clobber (reg:CC FLAGS_REG))])]
20269 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20272 [(set (match_operand:SI 0 "register_operand" "")
20273 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20274 (match_operand:DI 2 "const_int_operand" "")) 0))]
20275 "exact_log2 (INTVAL (operands[2])) >= 0
20276 && REGNO (operands[0]) == REGNO (operands[1])
20277 && peep2_regno_dead_p (0, FLAGS_REG)"
20278 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20279 (clobber (reg:CC FLAGS_REG))])]
20280 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20282 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20283 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20284 ;; many CPUs it is also faster, since special hardware to avoid esp
20285 ;; dependencies is present.
20287 ;; While some of these conversions may be done using splitters, we use peepholes
20288 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20290 ;; Convert prologue esp subtractions to push.
20291 ;; We need register to push. In order to keep verify_flow_info happy we have
20293 ;; - use scratch and clobber it in order to avoid dependencies
20294 ;; - use already live register
20295 ;; We can't use the second way right now, since there is no reliable way how to
20296 ;; verify that given register is live. First choice will also most likely in
20297 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20298 ;; call clobbered registers are dead. We may want to use base pointer as an
20299 ;; alternative when no register is available later.
20302 [(match_scratch:SI 0 "r")
20303 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20304 (clobber (reg:CC FLAGS_REG))
20305 (clobber (mem:BLK (scratch)))])]
20306 "optimize_size || !TARGET_SUB_ESP_4"
20307 [(clobber (match_dup 0))
20308 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20309 (clobber (mem:BLK (scratch)))])])
20312 [(match_scratch:SI 0 "r")
20313 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20314 (clobber (reg:CC FLAGS_REG))
20315 (clobber (mem:BLK (scratch)))])]
20316 "optimize_size || !TARGET_SUB_ESP_8"
20317 [(clobber (match_dup 0))
20318 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20319 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20320 (clobber (mem:BLK (scratch)))])])
20322 ;; Convert esp subtractions to push.
20324 [(match_scratch:SI 0 "r")
20325 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20326 (clobber (reg:CC FLAGS_REG))])]
20327 "optimize_size || !TARGET_SUB_ESP_4"
20328 [(clobber (match_dup 0))
20329 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20332 [(match_scratch:SI 0 "r")
20333 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20334 (clobber (reg:CC FLAGS_REG))])]
20335 "optimize_size || !TARGET_SUB_ESP_8"
20336 [(clobber (match_dup 0))
20337 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20338 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20340 ;; Convert epilogue deallocator to pop.
20342 [(match_scratch:SI 0 "r")
20343 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20344 (clobber (reg:CC FLAGS_REG))
20345 (clobber (mem:BLK (scratch)))])]
20346 "optimize_size || !TARGET_ADD_ESP_4"
20347 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20348 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20349 (clobber (mem:BLK (scratch)))])]
20352 ;; Two pops case is tricky, since pop causes dependency on destination register.
20353 ;; We use two registers if available.
20355 [(match_scratch:SI 0 "r")
20356 (match_scratch:SI 1 "r")
20357 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20358 (clobber (reg:CC FLAGS_REG))
20359 (clobber (mem:BLK (scratch)))])]
20360 "optimize_size || !TARGET_ADD_ESP_8"
20361 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20362 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20363 (clobber (mem:BLK (scratch)))])
20364 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20365 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20369 [(match_scratch:SI 0 "r")
20370 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20371 (clobber (reg:CC FLAGS_REG))
20372 (clobber (mem:BLK (scratch)))])]
20374 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20375 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20376 (clobber (mem:BLK (scratch)))])
20377 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20378 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20381 ;; Convert esp additions to pop.
20383 [(match_scratch:SI 0 "r")
20384 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20385 (clobber (reg:CC FLAGS_REG))])]
20387 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20388 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20391 ;; Two pops case is tricky, since pop causes dependency on destination register.
20392 ;; We use two registers if available.
20394 [(match_scratch:SI 0 "r")
20395 (match_scratch:SI 1 "r")
20396 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20397 (clobber (reg:CC FLAGS_REG))])]
20399 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20400 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20401 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20402 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20406 [(match_scratch:SI 0 "r")
20407 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20408 (clobber (reg:CC FLAGS_REG))])]
20410 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20411 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20412 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20413 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20416 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20417 ;; required and register dies. Similarly for 128 to plus -128.
20419 [(set (match_operand 0 "flags_reg_operand" "")
20420 (match_operator 1 "compare_operator"
20421 [(match_operand 2 "register_operand" "")
20422 (match_operand 3 "const_int_operand" "")]))]
20423 "(INTVAL (operands[3]) == -1
20424 || INTVAL (operands[3]) == 1
20425 || INTVAL (operands[3]) == 128)
20426 && ix86_match_ccmode (insn, CCGCmode)
20427 && peep2_reg_dead_p (1, operands[2])"
20428 [(parallel [(set (match_dup 0)
20429 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20430 (clobber (match_dup 2))])]
20434 [(match_scratch:DI 0 "r")
20435 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20436 (clobber (reg:CC FLAGS_REG))
20437 (clobber (mem:BLK (scratch)))])]
20438 "optimize_size || !TARGET_SUB_ESP_4"
20439 [(clobber (match_dup 0))
20440 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20441 (clobber (mem:BLK (scratch)))])])
20444 [(match_scratch:DI 0 "r")
20445 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20446 (clobber (reg:CC FLAGS_REG))
20447 (clobber (mem:BLK (scratch)))])]
20448 "optimize_size || !TARGET_SUB_ESP_8"
20449 [(clobber (match_dup 0))
20450 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20451 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20452 (clobber (mem:BLK (scratch)))])])
20454 ;; Convert esp subtractions to push.
20456 [(match_scratch:DI 0 "r")
20457 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20458 (clobber (reg:CC FLAGS_REG))])]
20459 "optimize_size || !TARGET_SUB_ESP_4"
20460 [(clobber (match_dup 0))
20461 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20464 [(match_scratch:DI 0 "r")
20465 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20466 (clobber (reg:CC FLAGS_REG))])]
20467 "optimize_size || !TARGET_SUB_ESP_8"
20468 [(clobber (match_dup 0))
20469 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20470 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20472 ;; Convert epilogue deallocator to pop.
20474 [(match_scratch:DI 0 "r")
20475 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20476 (clobber (reg:CC FLAGS_REG))
20477 (clobber (mem:BLK (scratch)))])]
20478 "optimize_size || !TARGET_ADD_ESP_4"
20479 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20480 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20481 (clobber (mem:BLK (scratch)))])]
20484 ;; Two pops case is tricky, since pop causes dependency on destination register.
20485 ;; We use two registers if available.
20487 [(match_scratch:DI 0 "r")
20488 (match_scratch:DI 1 "r")
20489 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20490 (clobber (reg:CC FLAGS_REG))
20491 (clobber (mem:BLK (scratch)))])]
20492 "optimize_size || !TARGET_ADD_ESP_8"
20493 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20494 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20495 (clobber (mem:BLK (scratch)))])
20496 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20497 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20501 [(match_scratch:DI 0 "r")
20502 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20503 (clobber (reg:CC FLAGS_REG))
20504 (clobber (mem:BLK (scratch)))])]
20506 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20507 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20508 (clobber (mem:BLK (scratch)))])
20509 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20510 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20513 ;; Convert esp additions to pop.
20515 [(match_scratch:DI 0 "r")
20516 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20517 (clobber (reg:CC FLAGS_REG))])]
20519 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20520 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20523 ;; Two pops case is tricky, since pop causes dependency on destination register.
20524 ;; We use two registers if available.
20526 [(match_scratch:DI 0 "r")
20527 (match_scratch:DI 1 "r")
20528 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20529 (clobber (reg:CC FLAGS_REG))])]
20531 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20532 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20533 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20534 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20538 [(match_scratch:DI 0 "r")
20539 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20540 (clobber (reg:CC FLAGS_REG))])]
20542 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20543 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20544 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20545 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20548 ;; Convert imul by three, five and nine into lea
20551 [(set (match_operand:SI 0 "register_operand" "")
20552 (mult:SI (match_operand:SI 1 "register_operand" "")
20553 (match_operand:SI 2 "const_int_operand" "")))
20554 (clobber (reg:CC FLAGS_REG))])]
20555 "INTVAL (operands[2]) == 3
20556 || INTVAL (operands[2]) == 5
20557 || INTVAL (operands[2]) == 9"
20558 [(set (match_dup 0)
20559 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20561 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20565 [(set (match_operand:SI 0 "register_operand" "")
20566 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20567 (match_operand:SI 2 "const_int_operand" "")))
20568 (clobber (reg:CC FLAGS_REG))])]
20570 && (INTVAL (operands[2]) == 3
20571 || INTVAL (operands[2]) == 5
20572 || INTVAL (operands[2]) == 9)"
20573 [(set (match_dup 0) (match_dup 1))
20575 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20577 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20581 [(set (match_operand:DI 0 "register_operand" "")
20582 (mult:DI (match_operand:DI 1 "register_operand" "")
20583 (match_operand:DI 2 "const_int_operand" "")))
20584 (clobber (reg:CC FLAGS_REG))])]
20586 && (INTVAL (operands[2]) == 3
20587 || INTVAL (operands[2]) == 5
20588 || INTVAL (operands[2]) == 9)"
20589 [(set (match_dup 0)
20590 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20592 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20596 [(set (match_operand:DI 0 "register_operand" "")
20597 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20598 (match_operand:DI 2 "const_int_operand" "")))
20599 (clobber (reg:CC FLAGS_REG))])]
20602 && (INTVAL (operands[2]) == 3
20603 || INTVAL (operands[2]) == 5
20604 || INTVAL (operands[2]) == 9)"
20605 [(set (match_dup 0) (match_dup 1))
20607 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20609 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20611 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20612 ;; imul $32bit_imm, reg, reg is direct decoded.
20614 [(match_scratch:DI 3 "r")
20615 (parallel [(set (match_operand:DI 0 "register_operand" "")
20616 (mult:DI (match_operand:DI 1 "memory_operand" "")
20617 (match_operand:DI 2 "immediate_operand" "")))
20618 (clobber (reg:CC FLAGS_REG))])]
20619 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20620 && !satisfies_constraint_K (operands[2])"
20621 [(set (match_dup 3) (match_dup 1))
20622 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20623 (clobber (reg:CC FLAGS_REG))])]
20627 [(match_scratch:SI 3 "r")
20628 (parallel [(set (match_operand:SI 0 "register_operand" "")
20629 (mult:SI (match_operand:SI 1 "memory_operand" "")
20630 (match_operand:SI 2 "immediate_operand" "")))
20631 (clobber (reg:CC FLAGS_REG))])]
20632 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20633 && !satisfies_constraint_K (operands[2])"
20634 [(set (match_dup 3) (match_dup 1))
20635 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20636 (clobber (reg:CC FLAGS_REG))])]
20640 [(match_scratch:SI 3 "r")
20641 (parallel [(set (match_operand:DI 0 "register_operand" "")
20643 (mult:SI (match_operand:SI 1 "memory_operand" "")
20644 (match_operand:SI 2 "immediate_operand" ""))))
20645 (clobber (reg:CC FLAGS_REG))])]
20646 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20647 && !satisfies_constraint_K (operands[2])"
20648 [(set (match_dup 3) (match_dup 1))
20649 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20650 (clobber (reg:CC FLAGS_REG))])]
20653 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20654 ;; Convert it into imul reg, reg
20655 ;; It would be better to force assembler to encode instruction using long
20656 ;; immediate, but there is apparently no way to do so.
20658 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20659 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20660 (match_operand:DI 2 "const_int_operand" "")))
20661 (clobber (reg:CC FLAGS_REG))])
20662 (match_scratch:DI 3 "r")]
20663 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20664 && satisfies_constraint_K (operands[2])"
20665 [(set (match_dup 3) (match_dup 2))
20666 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20667 (clobber (reg:CC FLAGS_REG))])]
20669 if (!rtx_equal_p (operands[0], operands[1]))
20670 emit_move_insn (operands[0], operands[1]);
20674 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20675 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20676 (match_operand:SI 2 "const_int_operand" "")))
20677 (clobber (reg:CC FLAGS_REG))])
20678 (match_scratch:SI 3 "r")]
20679 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20680 && satisfies_constraint_K (operands[2])"
20681 [(set (match_dup 3) (match_dup 2))
20682 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20683 (clobber (reg:CC FLAGS_REG))])]
20685 if (!rtx_equal_p (operands[0], operands[1]))
20686 emit_move_insn (operands[0], operands[1]);
20690 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20691 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20692 (match_operand:HI 2 "immediate_operand" "")))
20693 (clobber (reg:CC FLAGS_REG))])
20694 (match_scratch:HI 3 "r")]
20695 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20696 [(set (match_dup 3) (match_dup 2))
20697 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20698 (clobber (reg:CC FLAGS_REG))])]
20700 if (!rtx_equal_p (operands[0], operands[1]))
20701 emit_move_insn (operands[0], operands[1]);
20704 ;; After splitting up read-modify operations, array accesses with memory
20705 ;; operands might end up in form:
20707 ;; movl 4(%esp), %edx
20709 ;; instead of pre-splitting:
20711 ;; addl 4(%esp), %eax
20713 ;; movl 4(%esp), %edx
20714 ;; leal (%edx,%eax,4), %eax
20717 [(parallel [(set (match_operand 0 "register_operand" "")
20718 (ashift (match_operand 1 "register_operand" "")
20719 (match_operand 2 "const_int_operand" "")))
20720 (clobber (reg:CC FLAGS_REG))])
20721 (set (match_operand 3 "register_operand")
20722 (match_operand 4 "x86_64_general_operand" ""))
20723 (parallel [(set (match_operand 5 "register_operand" "")
20724 (plus (match_operand 6 "register_operand" "")
20725 (match_operand 7 "register_operand" "")))
20726 (clobber (reg:CC FLAGS_REG))])]
20727 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20728 /* Validate MODE for lea. */
20729 && ((!TARGET_PARTIAL_REG_STALL
20730 && (GET_MODE (operands[0]) == QImode
20731 || GET_MODE (operands[0]) == HImode))
20732 || GET_MODE (operands[0]) == SImode
20733 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20734 /* We reorder load and the shift. */
20735 && !rtx_equal_p (operands[1], operands[3])
20736 && !reg_overlap_mentioned_p (operands[0], operands[4])
20737 /* Last PLUS must consist of operand 0 and 3. */
20738 && !rtx_equal_p (operands[0], operands[3])
20739 && (rtx_equal_p (operands[3], operands[6])
20740 || rtx_equal_p (operands[3], operands[7]))
20741 && (rtx_equal_p (operands[0], operands[6])
20742 || rtx_equal_p (operands[0], operands[7]))
20743 /* The intermediate operand 0 must die or be same as output. */
20744 && (rtx_equal_p (operands[0], operands[5])
20745 || peep2_reg_dead_p (3, operands[0]))"
20746 [(set (match_dup 3) (match_dup 4))
20747 (set (match_dup 0) (match_dup 1))]
20749 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20750 int scale = 1 << INTVAL (operands[2]);
20751 rtx index = gen_lowpart (Pmode, operands[1]);
20752 rtx base = gen_lowpart (Pmode, operands[3]);
20753 rtx dest = gen_lowpart (mode, operands[5]);
20755 operands[1] = gen_rtx_PLUS (Pmode, base,
20756 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20758 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20759 operands[0] = dest;
20762 ;; Call-value patterns last so that the wildcard operand does not
20763 ;; disrupt insn-recog's switch tables.
20765 (define_insn "*call_value_pop_0"
20766 [(set (match_operand 0 "" "")
20767 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20768 (match_operand:SI 2 "" "")))
20769 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20770 (match_operand:SI 3 "immediate_operand" "")))]
20773 if (SIBLING_CALL_P (insn))
20776 return "call\t%P1";
20778 [(set_attr "type" "callv")])
20780 (define_insn "*call_value_pop_1"
20781 [(set (match_operand 0 "" "")
20782 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20783 (match_operand:SI 2 "" "")))
20784 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20785 (match_operand:SI 3 "immediate_operand" "i")))]
20788 if (constant_call_address_operand (operands[1], Pmode))
20790 if (SIBLING_CALL_P (insn))
20793 return "call\t%P1";
20795 if (SIBLING_CALL_P (insn))
20798 return "call\t%A1";
20800 [(set_attr "type" "callv")])
20802 (define_insn "*call_value_0"
20803 [(set (match_operand 0 "" "")
20804 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20805 (match_operand:SI 2 "" "")))]
20808 if (SIBLING_CALL_P (insn))
20811 return "call\t%P1";
20813 [(set_attr "type" "callv")])
20815 (define_insn "*call_value_0_rex64"
20816 [(set (match_operand 0 "" "")
20817 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20818 (match_operand:DI 2 "const_int_operand" "")))]
20821 if (SIBLING_CALL_P (insn))
20824 return "call\t%P1";
20826 [(set_attr "type" "callv")])
20828 (define_insn "*call_value_1"
20829 [(set (match_operand 0 "" "")
20830 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20831 (match_operand:SI 2 "" "")))]
20832 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20834 if (constant_call_address_operand (operands[1], Pmode))
20835 return "call\t%P1";
20836 return "call\t%A1";
20838 [(set_attr "type" "callv")])
20840 (define_insn "*sibcall_value_1"
20841 [(set (match_operand 0 "" "")
20842 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20843 (match_operand:SI 2 "" "")))]
20844 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20846 if (constant_call_address_operand (operands[1], Pmode))
20850 [(set_attr "type" "callv")])
20852 (define_insn "*call_value_1_rex64"
20853 [(set (match_operand 0 "" "")
20854 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20855 (match_operand:DI 2 "" "")))]
20856 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20858 if (constant_call_address_operand (operands[1], Pmode))
20859 return "call\t%P1";
20860 return "call\t%A1";
20862 [(set_attr "type" "callv")])
20864 (define_insn "*sibcall_value_1_rex64"
20865 [(set (match_operand 0 "" "")
20866 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20867 (match_operand:DI 2 "" "")))]
20868 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20870 [(set_attr "type" "callv")])
20872 (define_insn "*sibcall_value_1_rex64_v"
20873 [(set (match_operand 0 "" "")
20874 (call (mem:QI (reg:DI R11_REG))
20875 (match_operand:DI 1 "" "")))]
20876 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20878 [(set_attr "type" "callv")])
20880 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20881 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20882 ;; caught for use by garbage collectors and the like. Using an insn that
20883 ;; maps to SIGILL makes it more likely the program will rightfully die.
20884 ;; Keeping with tradition, "6" is in honor of #UD.
20885 (define_insn "trap"
20886 [(trap_if (const_int 1) (const_int 6))]
20888 { return ASM_SHORT "0x0b0f"; }
20889 [(set_attr "length" "2")])
20891 (define_expand "sse_prologue_save"
20892 [(parallel [(set (match_operand:BLK 0 "" "")
20893 (unspec:BLK [(reg:DI 22)
20900 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20901 (use (match_operand:DI 1 "register_operand" ""))
20902 (use (match_operand:DI 2 "immediate_operand" ""))
20903 (use (label_ref:DI (match_operand 3 "" "")))])]
20907 (define_insn "*sse_prologue_save_insn"
20908 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20909 (match_operand:DI 4 "const_int_operand" "n")))
20910 (unspec:BLK [(reg:DI 22)
20917 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20918 (use (match_operand:DI 1 "register_operand" "r"))
20919 (use (match_operand:DI 2 "const_int_operand" "i"))
20920 (use (label_ref:DI (match_operand 3 "" "X")))]
20922 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20923 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20927 operands[0] = gen_rtx_MEM (Pmode,
20928 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20929 output_asm_insn (\"jmp\\t%A1\", operands);
20930 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20932 operands[4] = adjust_address (operands[0], DImode, i*16);
20933 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20934 PUT_MODE (operands[4], TImode);
20935 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20936 output_asm_insn (\"rex\", operands);
20937 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20939 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20940 CODE_LABEL_NUMBER (operands[3]));
20944 [(set_attr "type" "other")
20945 (set_attr "length_immediate" "0")
20946 (set_attr "length_address" "0")
20947 (set_attr "length" "135")
20948 (set_attr "memory" "store")
20949 (set_attr "modrm" "0")
20950 (set_attr "mode" "DI")])
20952 (define_expand "prefetch"
20953 [(prefetch (match_operand 0 "address_operand" "")
20954 (match_operand:SI 1 "const_int_operand" "")
20955 (match_operand:SI 2 "const_int_operand" ""))]
20956 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20958 int rw = INTVAL (operands[1]);
20959 int locality = INTVAL (operands[2]);
20961 gcc_assert (rw == 0 || rw == 1);
20962 gcc_assert (locality >= 0 && locality <= 3);
20963 gcc_assert (GET_MODE (operands[0]) == Pmode
20964 || GET_MODE (operands[0]) == VOIDmode);
20966 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20967 supported by SSE counterpart or the SSE prefetch is not available
20968 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20970 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20971 operands[2] = GEN_INT (3);
20973 operands[1] = const0_rtx;
20976 (define_insn "*prefetch_sse"
20977 [(prefetch (match_operand:SI 0 "address_operand" "p")
20979 (match_operand:SI 1 "const_int_operand" ""))]
20980 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20982 static const char * const patterns[4] = {
20983 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20986 int locality = INTVAL (operands[1]);
20987 gcc_assert (locality >= 0 && locality <= 3);
20989 return patterns[locality];
20991 [(set_attr "type" "sse")
20992 (set_attr "memory" "none")])
20994 (define_insn "*prefetch_sse_rex"
20995 [(prefetch (match_operand:DI 0 "address_operand" "p")
20997 (match_operand:SI 1 "const_int_operand" ""))]
20998 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21000 static const char * const patterns[4] = {
21001 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21004 int locality = INTVAL (operands[1]);
21005 gcc_assert (locality >= 0 && locality <= 3);
21007 return patterns[locality];
21009 [(set_attr "type" "sse")
21010 (set_attr "memory" "none")])
21012 (define_insn "*prefetch_3dnow"
21013 [(prefetch (match_operand:SI 0 "address_operand" "p")
21014 (match_operand:SI 1 "const_int_operand" "n")
21016 "TARGET_3DNOW && !TARGET_64BIT"
21018 if (INTVAL (operands[1]) == 0)
21019 return "prefetch\t%a0";
21021 return "prefetchw\t%a0";
21023 [(set_attr "type" "mmx")
21024 (set_attr "memory" "none")])
21026 (define_insn "*prefetch_3dnow_rex"
21027 [(prefetch (match_operand:DI 0 "address_operand" "p")
21028 (match_operand:SI 1 "const_int_operand" "n")
21030 "TARGET_3DNOW && TARGET_64BIT"
21032 if (INTVAL (operands[1]) == 0)
21033 return "prefetch\t%a0";
21035 return "prefetchw\t%a0";
21037 [(set_attr "type" "mmx")
21038 (set_attr "memory" "none")])
21040 (define_expand "stack_protect_set"
21041 [(match_operand 0 "memory_operand" "")
21042 (match_operand 1 "memory_operand" "")]
21045 #ifdef TARGET_THREAD_SSP_OFFSET
21047 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21048 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21050 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21051 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21054 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21056 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21061 (define_insn "stack_protect_set_si"
21062 [(set (match_operand:SI 0 "memory_operand" "=m")
21063 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21064 (set (match_scratch:SI 2 "=&r") (const_int 0))
21065 (clobber (reg:CC FLAGS_REG))]
21067 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21068 [(set_attr "type" "multi")])
21070 (define_insn "stack_protect_set_di"
21071 [(set (match_operand:DI 0 "memory_operand" "=m")
21072 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21073 (set (match_scratch:DI 2 "=&r") (const_int 0))
21074 (clobber (reg:CC FLAGS_REG))]
21076 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21077 [(set_attr "type" "multi")])
21079 (define_insn "stack_tls_protect_set_si"
21080 [(set (match_operand:SI 0 "memory_operand" "=m")
21081 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21082 (set (match_scratch:SI 2 "=&r") (const_int 0))
21083 (clobber (reg:CC FLAGS_REG))]
21085 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21086 [(set_attr "type" "multi")])
21088 (define_insn "stack_tls_protect_set_di"
21089 [(set (match_operand:DI 0 "memory_operand" "=m")
21090 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21091 (set (match_scratch:DI 2 "=&r") (const_int 0))
21092 (clobber (reg:CC FLAGS_REG))]
21095 /* The kernel uses a different segment register for performance reasons; a
21096 system call would not have to trash the userspace segment register,
21097 which would be expensive */
21098 if (ix86_cmodel != CM_KERNEL)
21099 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21101 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21103 [(set_attr "type" "multi")])
21105 (define_expand "stack_protect_test"
21106 [(match_operand 0 "memory_operand" "")
21107 (match_operand 1 "memory_operand" "")
21108 (match_operand 2 "" "")]
21111 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21112 ix86_compare_op0 = operands[0];
21113 ix86_compare_op1 = operands[1];
21114 ix86_compare_emitted = flags;
21116 #ifdef TARGET_THREAD_SSP_OFFSET
21118 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21119 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21121 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21122 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21125 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21127 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21129 emit_jump_insn (gen_beq (operands[2]));
21133 (define_insn "stack_protect_test_si"
21134 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21135 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21136 (match_operand:SI 2 "memory_operand" "m")]
21138 (clobber (match_scratch:SI 3 "=&r"))]
21140 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21141 [(set_attr "type" "multi")])
21143 (define_insn "stack_protect_test_di"
21144 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21145 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21146 (match_operand:DI 2 "memory_operand" "m")]
21148 (clobber (match_scratch:DI 3 "=&r"))]
21150 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21151 [(set_attr "type" "multi")])
21153 (define_insn "stack_tls_protect_test_si"
21154 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21155 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21156 (match_operand:SI 2 "const_int_operand" "i")]
21157 UNSPEC_SP_TLS_TEST))
21158 (clobber (match_scratch:SI 3 "=r"))]
21160 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21161 [(set_attr "type" "multi")])
21163 (define_insn "stack_tls_protect_test_di"
21164 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21165 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21166 (match_operand:DI 2 "const_int_operand" "i")]
21167 UNSPEC_SP_TLS_TEST))
21168 (clobber (match_scratch:DI 3 "=r"))]
21171 /* The kernel uses a different segment register for performance reasons; a
21172 system call would not have to trash the userspace segment register,
21173 which would be expensive */
21174 if (ix86_cmodel != CM_KERNEL)
21175 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21177 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21179 [(set_attr "type" "multi")])
21183 (include "sync.md")