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,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 || GET_CODE (operands[1]) != CONST_DOUBLE
2791 || memory_operand (operands[0], XFmode))"
2793 switch (which_alternative)
2796 return output_387_reg_move (insn, operands);
2799 /* There is no non-popping store to memory for XFmode. So if
2800 we need one, follow the store with a load. */
2801 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2802 return "fstp%z0\t%y0\;fld%z0\t%y0";
2804 return "fstp%z0\t%y0";
2807 return standard_80387_constant_opcode (operands[1]);
2815 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2816 (set_attr "mode" "XF,XF,XF,SI,SI")])
2818 (define_insn "*movxf_integer"
2819 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2820 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2822 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2823 && (reload_in_progress || reload_completed
2824 || GET_CODE (operands[1]) != CONST_DOUBLE
2825 || memory_operand (operands[0], XFmode))"
2827 switch (which_alternative)
2830 return output_387_reg_move (insn, operands);
2833 /* There is no non-popping store to memory for XFmode. So if
2834 we need one, follow the store with a load. */
2835 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2836 return "fstp%z0\t%y0\;fld%z0\t%y0";
2838 return "fstp%z0\t%y0";
2841 return standard_80387_constant_opcode (operands[1]);
2850 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2851 (set_attr "mode" "XF,XF,XF,SI,SI")])
2854 [(set (match_operand 0 "nonimmediate_operand" "")
2855 (match_operand 1 "general_operand" ""))]
2857 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2858 && GET_MODE (operands[0]) == XFmode
2859 && ! (ANY_FP_REG_P (operands[0]) ||
2860 (GET_CODE (operands[0]) == SUBREG
2861 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2862 && ! (ANY_FP_REG_P (operands[1]) ||
2863 (GET_CODE (operands[1]) == SUBREG
2864 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2866 "ix86_split_long_move (operands); DONE;")
2869 [(set (match_operand 0 "register_operand" "")
2870 (match_operand 1 "memory_operand" ""))]
2872 && GET_CODE (operands[1]) == MEM
2873 && (GET_MODE (operands[0]) == XFmode
2874 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2875 && constant_pool_reference_p (operands[1])"
2876 [(set (match_dup 0) (match_dup 1))]
2878 rtx c = avoid_constant_pool_reference (operands[1]);
2879 rtx r = operands[0];
2881 if (GET_CODE (r) == SUBREG)
2886 if (!standard_sse_constant_p (c))
2889 else if (FP_REG_P (r))
2891 if (!standard_80387_constant_p (c))
2894 else if (MMX_REG_P (r))
2900 (define_insn "swapxf"
2901 [(set (match_operand:XF 0 "register_operand" "+f")
2902 (match_operand:XF 1 "register_operand" "+f"))
2907 if (STACK_TOP_P (operands[0]))
2912 [(set_attr "type" "fxch")
2913 (set_attr "mode" "XF")])
2915 (define_expand "movtf"
2916 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2917 (match_operand:TF 1 "nonimmediate_operand" ""))]
2920 ix86_expand_move (TFmode, operands);
2924 (define_insn "*movtf_internal"
2925 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2926 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2928 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2930 switch (which_alternative)
2936 if (get_attr_mode (insn) == MODE_V4SF)
2937 return "xorps\t%0, %0";
2939 return "pxor\t%0, %0";
2942 if (get_attr_mode (insn) == MODE_V4SF)
2943 return "movaps\t{%1, %0|%0, %1}";
2945 return "movdqa\t{%1, %0|%0, %1}";
2950 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2952 (cond [(eq_attr "alternative" "2,3")
2954 (ne (symbol_ref "optimize_size")
2956 (const_string "V4SF")
2957 (const_string "TI"))
2958 (eq_attr "alternative" "4")
2960 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2962 (ne (symbol_ref "optimize_size")
2964 (const_string "V4SF")
2965 (const_string "TI"))]
2966 (const_string "DI")))])
2969 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2970 (match_operand:TF 1 "general_operand" ""))]
2971 "reload_completed && !SSE_REG_P (operands[0])
2972 && !SSE_REG_P (operands[1])"
2974 "ix86_split_long_move (operands); DONE;")
2976 ;; Zero extension instructions
2978 (define_expand "zero_extendhisi2"
2979 [(set (match_operand:SI 0 "register_operand" "")
2980 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2983 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2985 operands[1] = force_reg (HImode, operands[1]);
2986 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2991 (define_insn "zero_extendhisi2_and"
2992 [(set (match_operand:SI 0 "register_operand" "=r")
2993 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2994 (clobber (reg:CC FLAGS_REG))]
2995 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997 [(set_attr "type" "alu1")
2998 (set_attr "mode" "SI")])
3001 [(set (match_operand:SI 0 "register_operand" "")
3002 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3003 (clobber (reg:CC FLAGS_REG))]
3004 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3005 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3006 (clobber (reg:CC FLAGS_REG))])]
3009 (define_insn "*zero_extendhisi2_movzwl"
3010 [(set (match_operand:SI 0 "register_operand" "=r")
3011 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3012 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3013 "movz{wl|x}\t{%1, %0|%0, %1}"
3014 [(set_attr "type" "imovx")
3015 (set_attr "mode" "SI")])
3017 (define_expand "zero_extendqihi2"
3019 [(set (match_operand:HI 0 "register_operand" "")
3020 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3021 (clobber (reg:CC FLAGS_REG))])]
3025 (define_insn "*zero_extendqihi2_and"
3026 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3027 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3028 (clobber (reg:CC FLAGS_REG))]
3029 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3031 [(set_attr "type" "alu1")
3032 (set_attr "mode" "HI")])
3034 (define_insn "*zero_extendqihi2_movzbw_and"
3035 [(set (match_operand:HI 0 "register_operand" "=r,r")
3036 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3037 (clobber (reg:CC FLAGS_REG))]
3038 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3040 [(set_attr "type" "imovx,alu1")
3041 (set_attr "mode" "HI")])
3043 ; zero extend to SImode here to avoid partial register stalls
3044 (define_insn "*zero_extendqihi2_movzbl"
3045 [(set (match_operand:HI 0 "register_operand" "=r")
3046 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3047 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3048 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3049 [(set_attr "type" "imovx")
3050 (set_attr "mode" "SI")])
3052 ;; For the movzbw case strip only the clobber
3054 [(set (match_operand:HI 0 "register_operand" "")
3055 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3056 (clobber (reg:CC FLAGS_REG))]
3058 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3059 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3060 [(set (match_operand:HI 0 "register_operand" "")
3061 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3063 ;; When source and destination does not overlap, clear destination
3064 ;; first and then do the movb
3066 [(set (match_operand:HI 0 "register_operand" "")
3067 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3068 (clobber (reg:CC FLAGS_REG))]
3070 && ANY_QI_REG_P (operands[0])
3071 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3072 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3073 [(set (match_dup 0) (const_int 0))
3074 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3075 "operands[2] = gen_lowpart (QImode, operands[0]);")
3077 ;; Rest is handled by single and.
3079 [(set (match_operand:HI 0 "register_operand" "")
3080 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3081 (clobber (reg:CC FLAGS_REG))]
3083 && true_regnum (operands[0]) == true_regnum (operands[1])"
3084 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3085 (clobber (reg:CC FLAGS_REG))])]
3088 (define_expand "zero_extendqisi2"
3090 [(set (match_operand:SI 0 "register_operand" "")
3091 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3092 (clobber (reg:CC FLAGS_REG))])]
3096 (define_insn "*zero_extendqisi2_and"
3097 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3098 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3099 (clobber (reg:CC FLAGS_REG))]
3100 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3102 [(set_attr "type" "alu1")
3103 (set_attr "mode" "SI")])
3105 (define_insn "*zero_extendqisi2_movzbw_and"
3106 [(set (match_operand:SI 0 "register_operand" "=r,r")
3107 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3108 (clobber (reg:CC FLAGS_REG))]
3109 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3111 [(set_attr "type" "imovx,alu1")
3112 (set_attr "mode" "SI")])
3114 (define_insn "*zero_extendqisi2_movzbw"
3115 [(set (match_operand:SI 0 "register_operand" "=r")
3116 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3117 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3118 "movz{bl|x}\t{%1, %0|%0, %1}"
3119 [(set_attr "type" "imovx")
3120 (set_attr "mode" "SI")])
3122 ;; For the movzbl case strip only the clobber
3124 [(set (match_operand:SI 0 "register_operand" "")
3125 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3126 (clobber (reg:CC FLAGS_REG))]
3128 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3129 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3131 (zero_extend:SI (match_dup 1)))])
3133 ;; When source and destination does not overlap, clear destination
3134 ;; first and then do the movb
3136 [(set (match_operand:SI 0 "register_operand" "")
3137 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3138 (clobber (reg:CC FLAGS_REG))]
3140 && ANY_QI_REG_P (operands[0])
3141 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3142 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3143 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3144 [(set (match_dup 0) (const_int 0))
3145 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3146 "operands[2] = gen_lowpart (QImode, operands[0]);")
3148 ;; Rest is handled by single and.
3150 [(set (match_operand:SI 0 "register_operand" "")
3151 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3152 (clobber (reg:CC FLAGS_REG))]
3154 && true_regnum (operands[0]) == true_regnum (operands[1])"
3155 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3156 (clobber (reg:CC FLAGS_REG))])]
3159 ;; %%% Kill me once multi-word ops are sane.
3160 (define_expand "zero_extendsidi2"
3161 [(set (match_operand:DI 0 "register_operand" "=r")
3162 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3166 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3171 (define_insn "zero_extendsidi2_32"
3172 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3173 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3174 (clobber (reg:CC FLAGS_REG))]
3180 movd\t{%1, %0|%0, %1}
3181 movd\t{%1, %0|%0, %1}"
3182 [(set_attr "mode" "SI,SI,SI,DI,TI")
3183 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3185 (define_insn "zero_extendsidi2_rex64"
3186 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3187 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3190 mov\t{%k1, %k0|%k0, %k1}
3192 movd\t{%1, %0|%0, %1}
3193 movd\t{%1, %0|%0, %1}"
3194 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3195 (set_attr "mode" "SI,DI,SI,SI")])
3198 [(set (match_operand:DI 0 "memory_operand" "")
3199 (zero_extend:DI (match_dup 0)))]
3201 [(set (match_dup 4) (const_int 0))]
3202 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205 [(set (match_operand:DI 0 "register_operand" "")
3206 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3207 (clobber (reg:CC FLAGS_REG))]
3208 "!TARGET_64BIT && reload_completed
3209 && true_regnum (operands[0]) == true_regnum (operands[1])"
3210 [(set (match_dup 4) (const_int 0))]
3211 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3214 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3215 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3216 (clobber (reg:CC FLAGS_REG))]
3217 "!TARGET_64BIT && reload_completed
3218 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3219 [(set (match_dup 3) (match_dup 1))
3220 (set (match_dup 4) (const_int 0))]
3221 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3223 (define_insn "zero_extendhidi2"
3224 [(set (match_operand:DI 0 "register_operand" "=r")
3225 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3227 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3228 [(set_attr "type" "imovx")
3229 (set_attr "mode" "DI")])
3231 (define_insn "zero_extendqidi2"
3232 [(set (match_operand:DI 0 "register_operand" "=r")
3233 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3235 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3236 [(set_attr "type" "imovx")
3237 (set_attr "mode" "DI")])
3239 ;; Sign extension instructions
3241 (define_expand "extendsidi2"
3242 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3243 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3244 (clobber (reg:CC FLAGS_REG))
3245 (clobber (match_scratch:SI 2 ""))])]
3250 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3255 (define_insn "*extendsidi2_1"
3256 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3257 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3258 (clobber (reg:CC FLAGS_REG))
3259 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3263 (define_insn "extendsidi2_rex64"
3264 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3265 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3269 movs{lq|x}\t{%1,%0|%0, %1}"
3270 [(set_attr "type" "imovx")
3271 (set_attr "mode" "DI")
3272 (set_attr "prefix_0f" "0")
3273 (set_attr "modrm" "0,1")])
3275 (define_insn "extendhidi2"
3276 [(set (match_operand:DI 0 "register_operand" "=r")
3277 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3279 "movs{wq|x}\t{%1,%0|%0, %1}"
3280 [(set_attr "type" "imovx")
3281 (set_attr "mode" "DI")])
3283 (define_insn "extendqidi2"
3284 [(set (match_operand:DI 0 "register_operand" "=r")
3285 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3287 "movs{bq|x}\t{%1,%0|%0, %1}"
3288 [(set_attr "type" "imovx")
3289 (set_attr "mode" "DI")])
3291 ;; Extend to memory case when source register does die.
3293 [(set (match_operand:DI 0 "memory_operand" "")
3294 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3295 (clobber (reg:CC FLAGS_REG))
3296 (clobber (match_operand:SI 2 "register_operand" ""))]
3298 && dead_or_set_p (insn, operands[1])
3299 && !reg_mentioned_p (operands[1], operands[0]))"
3300 [(set (match_dup 3) (match_dup 1))
3301 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3302 (clobber (reg:CC FLAGS_REG))])
3303 (set (match_dup 4) (match_dup 1))]
3304 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3306 ;; Extend to memory case when source register does not die.
3308 [(set (match_operand:DI 0 "memory_operand" "")
3309 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3310 (clobber (reg:CC FLAGS_REG))
3311 (clobber (match_operand:SI 2 "register_operand" ""))]
3315 split_di (&operands[0], 1, &operands[3], &operands[4]);
3317 emit_move_insn (operands[3], operands[1]);
3319 /* Generate a cltd if possible and doing so it profitable. */
3320 if (true_regnum (operands[1]) == 0
3321 && true_regnum (operands[2]) == 1
3322 && (optimize_size || TARGET_USE_CLTD))
3324 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3328 emit_move_insn (operands[2], operands[1]);
3329 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3331 emit_move_insn (operands[4], operands[2]);
3335 ;; Extend to register case. Optimize case where source and destination
3336 ;; registers match and cases where we can use cltd.
3338 [(set (match_operand:DI 0 "register_operand" "")
3339 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3340 (clobber (reg:CC FLAGS_REG))
3341 (clobber (match_scratch:SI 2 ""))]
3345 split_di (&operands[0], 1, &operands[3], &operands[4]);
3347 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3348 emit_move_insn (operands[3], operands[1]);
3350 /* Generate a cltd if possible and doing so it profitable. */
3351 if (true_regnum (operands[3]) == 0
3352 && (optimize_size || TARGET_USE_CLTD))
3354 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3358 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3359 emit_move_insn (operands[4], operands[1]);
3361 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3365 (define_insn "extendhisi2"
3366 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3367 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3370 switch (get_attr_prefix_0f (insn))
3373 return "{cwtl|cwde}";
3375 return "movs{wl|x}\t{%1,%0|%0, %1}";
3378 [(set_attr "type" "imovx")
3379 (set_attr "mode" "SI")
3380 (set (attr "prefix_0f")
3381 ;; movsx is short decodable while cwtl is vector decoded.
3382 (if_then_else (and (eq_attr "cpu" "!k6")
3383 (eq_attr "alternative" "0"))
3385 (const_string "1")))
3387 (if_then_else (eq_attr "prefix_0f" "0")
3389 (const_string "1")))])
3391 (define_insn "*extendhisi2_zext"
3392 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3394 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3397 switch (get_attr_prefix_0f (insn))
3400 return "{cwtl|cwde}";
3402 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3405 [(set_attr "type" "imovx")
3406 (set_attr "mode" "SI")
3407 (set (attr "prefix_0f")
3408 ;; movsx is short decodable while cwtl is vector decoded.
3409 (if_then_else (and (eq_attr "cpu" "!k6")
3410 (eq_attr "alternative" "0"))
3412 (const_string "1")))
3414 (if_then_else (eq_attr "prefix_0f" "0")
3416 (const_string "1")))])
3418 (define_insn "extendqihi2"
3419 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3420 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3423 switch (get_attr_prefix_0f (insn))
3426 return "{cbtw|cbw}";
3428 return "movs{bw|x}\t{%1,%0|%0, %1}";
3431 [(set_attr "type" "imovx")
3432 (set_attr "mode" "HI")
3433 (set (attr "prefix_0f")
3434 ;; movsx is short decodable while cwtl is vector decoded.
3435 (if_then_else (and (eq_attr "cpu" "!k6")
3436 (eq_attr "alternative" "0"))
3438 (const_string "1")))
3440 (if_then_else (eq_attr "prefix_0f" "0")
3442 (const_string "1")))])
3444 (define_insn "extendqisi2"
3445 [(set (match_operand:SI 0 "register_operand" "=r")
3446 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3448 "movs{bl|x}\t{%1,%0|%0, %1}"
3449 [(set_attr "type" "imovx")
3450 (set_attr "mode" "SI")])
3452 (define_insn "*extendqisi2_zext"
3453 [(set (match_operand:DI 0 "register_operand" "=r")
3455 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3457 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3458 [(set_attr "type" "imovx")
3459 (set_attr "mode" "SI")])
3461 ;; Conversions between float and double.
3463 ;; These are all no-ops in the model used for the 80387. So just
3466 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3467 (define_insn "*dummy_extendsfdf2"
3468 [(set (match_operand:DF 0 "push_operand" "=<")
3469 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3474 [(set (match_operand:DF 0 "push_operand" "")
3475 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3477 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3478 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3481 [(set (match_operand:DF 0 "push_operand" "")
3482 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3484 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3485 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3487 (define_insn "*dummy_extendsfxf2"
3488 [(set (match_operand:XF 0 "push_operand" "=<")
3489 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3494 [(set (match_operand:XF 0 "push_operand" "")
3495 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3497 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3498 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3499 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3502 [(set (match_operand:XF 0 "push_operand" "")
3503 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3505 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3506 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3507 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3510 [(set (match_operand:XF 0 "push_operand" "")
3511 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3513 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3514 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3515 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3518 [(set (match_operand:XF 0 "push_operand" "")
3519 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3521 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3522 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3523 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3525 (define_expand "extendsfdf2"
3526 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3527 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3528 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3530 /* ??? Needed for compress_float_constant since all fp constants
3531 are LEGITIMATE_CONSTANT_P. */
3532 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3534 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3535 && standard_80387_constant_p (operands[1]) > 0)
3537 operands[1] = simplify_const_unary_operation
3538 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3539 emit_move_insn_1 (operands[0], operands[1]);
3542 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3546 (define_insn "*extendsfdf2_mixed"
3547 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3548 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3549 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3551 switch (which_alternative)
3554 return output_387_reg_move (insn, operands);
3557 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3558 return "fstp%z0\t%y0";
3560 return "fst%z0\t%y0";
3563 return "cvtss2sd\t{%1, %0|%0, %1}";
3569 [(set_attr "type" "fmov,fmov,ssecvt")
3570 (set_attr "mode" "SF,XF,DF")])
3572 (define_insn "*extendsfdf2_sse"
3573 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3574 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3575 "TARGET_SSE2 && TARGET_SSE_MATH"
3576 "cvtss2sd\t{%1, %0|%0, %1}"
3577 [(set_attr "type" "ssecvt")
3578 (set_attr "mode" "DF")])
3580 (define_insn "*extendsfdf2_i387"
3581 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3582 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3585 switch (which_alternative)
3588 return output_387_reg_move (insn, operands);
3591 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3592 return "fstp%z0\t%y0";
3594 return "fst%z0\t%y0";
3600 [(set_attr "type" "fmov")
3601 (set_attr "mode" "SF,XF")])
3603 (define_expand "extendsfxf2"
3604 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3605 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3608 /* ??? Needed for compress_float_constant since all fp constants
3609 are LEGITIMATE_CONSTANT_P. */
3610 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3612 if (standard_80387_constant_p (operands[1]) > 0)
3614 operands[1] = simplify_const_unary_operation
3615 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3616 emit_move_insn_1 (operands[0], operands[1]);
3619 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3623 (define_insn "*extendsfxf2_i387"
3624 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3625 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3628 switch (which_alternative)
3631 return output_387_reg_move (insn, operands);
3634 /* There is no non-popping store to memory for XFmode. So if
3635 we need one, follow the store with a load. */
3636 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3637 return "fstp%z0\t%y0";
3639 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3645 [(set_attr "type" "fmov")
3646 (set_attr "mode" "SF,XF")])
3648 (define_expand "extenddfxf2"
3649 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3650 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3653 /* ??? Needed for compress_float_constant since all fp constants
3654 are LEGITIMATE_CONSTANT_P. */
3655 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3657 if (standard_80387_constant_p (operands[1]) > 0)
3659 operands[1] = simplify_const_unary_operation
3660 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3661 emit_move_insn_1 (operands[0], operands[1]);
3664 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3668 (define_insn "*extenddfxf2_i387"
3669 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3670 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3673 switch (which_alternative)
3676 return output_387_reg_move (insn, operands);
3679 /* There is no non-popping store to memory for XFmode. So if
3680 we need one, follow the store with a load. */
3681 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3682 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3684 return "fstp%z0\t%y0";
3690 [(set_attr "type" "fmov")
3691 (set_attr "mode" "DF,XF")])
3693 ;; %%% This seems bad bad news.
3694 ;; This cannot output into an f-reg because there is no way to be sure
3695 ;; of truncating in that case. Otherwise this is just like a simple move
3696 ;; insn. So we pretend we can output to a reg in order to get better
3697 ;; register preferencing, but we really use a stack slot.
3699 ;; Conversion from DFmode to SFmode.
3701 (define_expand "truncdfsf2"
3702 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3704 (match_operand:DF 1 "nonimmediate_operand" "")))]
3705 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3707 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3709 else if (flag_unsafe_math_optimizations)
3713 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3714 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3719 (define_expand "truncdfsf2_with_temp"
3720 [(parallel [(set (match_operand:SF 0 "" "")
3721 (float_truncate:SF (match_operand:DF 1 "" "")))
3722 (clobber (match_operand:SF 2 "" ""))])]
3725 (define_insn "*truncdfsf_fast_mixed"
3726 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3728 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3729 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3731 switch (which_alternative)
3734 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3735 return "fstp%z0\t%y0";
3737 return "fst%z0\t%y0";
3739 return output_387_reg_move (insn, operands);
3741 return "cvtsd2ss\t{%1, %0|%0, %1}";
3746 [(set_attr "type" "fmov,fmov,ssecvt")
3747 (set_attr "mode" "SF")])
3749 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3750 ;; because nothing we do here is unsafe.
3751 (define_insn "*truncdfsf_fast_sse"
3752 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3754 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3755 "TARGET_SSE2 && TARGET_SSE_MATH"
3756 "cvtsd2ss\t{%1, %0|%0, %1}"
3757 [(set_attr "type" "ssecvt")
3758 (set_attr "mode" "SF")])
3760 (define_insn "*truncdfsf_fast_i387"
3761 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3763 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3764 "TARGET_80387 && flag_unsafe_math_optimizations"
3765 "* return output_387_reg_move (insn, operands);"
3766 [(set_attr "type" "fmov")
3767 (set_attr "mode" "SF")])
3769 (define_insn "*truncdfsf_mixed"
3770 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3772 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3773 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3774 "TARGET_MIX_SSE_I387"
3776 switch (which_alternative)
3779 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3780 return "fstp%z0\t%y0";
3782 return "fst%z0\t%y0";
3786 return "cvtsd2ss\t{%1, %0|%0, %1}";
3791 [(set_attr "type" "fmov,multi,ssecvt")
3792 (set_attr "unit" "*,i387,*")
3793 (set_attr "mode" "SF")])
3795 (define_insn "*truncdfsf_i387"
3796 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3798 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3799 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3802 switch (which_alternative)
3805 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3806 return "fstp%z0\t%y0";
3808 return "fst%z0\t%y0";
3815 [(set_attr "type" "fmov,multi")
3816 (set_attr "unit" "*,i387")
3817 (set_attr "mode" "SF")])
3819 (define_insn "*truncdfsf2_i387_1"
3820 [(set (match_operand:SF 0 "memory_operand" "=m")
3822 (match_operand:DF 1 "register_operand" "f")))]
3824 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3825 && !TARGET_MIX_SSE_I387"
3827 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3828 return "fstp%z0\t%y0";
3830 return "fst%z0\t%y0";
3832 [(set_attr "type" "fmov")
3833 (set_attr "mode" "SF")])
3836 [(set (match_operand:SF 0 "register_operand" "")
3838 (match_operand:DF 1 "fp_register_operand" "")))
3839 (clobber (match_operand 2 "" ""))]
3841 [(set (match_dup 2) (match_dup 1))
3842 (set (match_dup 0) (match_dup 2))]
3844 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3847 ;; Conversion from XFmode to SFmode.
3849 (define_expand "truncxfsf2"
3850 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3852 (match_operand:XF 1 "register_operand" "")))
3853 (clobber (match_dup 2))])]
3856 if (flag_unsafe_math_optimizations)
3858 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3859 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3860 if (reg != operands[0])
3861 emit_move_insn (operands[0], reg);
3865 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3868 (define_insn "*truncxfsf2_mixed"
3869 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3871 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3872 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3873 "TARGET_MIX_SSE_I387"
3875 gcc_assert (!which_alternative);
3876 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3877 return "fstp%z0\t%y0";
3879 return "fst%z0\t%y0";
3881 [(set_attr "type" "fmov,multi,multi,multi")
3882 (set_attr "unit" "*,i387,i387,i387")
3883 (set_attr "mode" "SF")])
3885 (define_insn "truncxfsf2_i387_noop"
3886 [(set (match_operand:SF 0 "register_operand" "=f")
3887 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3888 "TARGET_80387 && flag_unsafe_math_optimizations"
3890 return output_387_reg_move (insn, operands);
3892 [(set_attr "type" "fmov")
3893 (set_attr "mode" "SF")])
3895 (define_insn "*truncxfsf2_i387"
3896 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3898 (match_operand:XF 1 "register_operand" "f,f,f")))
3899 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3902 gcc_assert (!which_alternative);
3903 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3904 return "fstp%z0\t%y0";
3906 return "fst%z0\t%y0";
3908 [(set_attr "type" "fmov,multi,multi")
3909 (set_attr "unit" "*,i387,i387")
3910 (set_attr "mode" "SF")])
3912 (define_insn "*truncxfsf2_i387_1"
3913 [(set (match_operand:SF 0 "memory_operand" "=m")
3915 (match_operand:XF 1 "register_operand" "f")))]
3918 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3919 return "fstp%z0\t%y0";
3921 return "fst%z0\t%y0";
3923 [(set_attr "type" "fmov")
3924 (set_attr "mode" "SF")])
3927 [(set (match_operand:SF 0 "register_operand" "")
3929 (match_operand:XF 1 "register_operand" "")))
3930 (clobber (match_operand:SF 2 "memory_operand" ""))]
3931 "TARGET_80387 && reload_completed"
3932 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3933 (set (match_dup 0) (match_dup 2))]
3937 [(set (match_operand:SF 0 "memory_operand" "")
3939 (match_operand:XF 1 "register_operand" "")))
3940 (clobber (match_operand:SF 2 "memory_operand" ""))]
3942 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3945 ;; Conversion from XFmode to DFmode.
3947 (define_expand "truncxfdf2"
3948 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3950 (match_operand:XF 1 "register_operand" "")))
3951 (clobber (match_dup 2))])]
3954 if (flag_unsafe_math_optimizations)
3956 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3957 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3958 if (reg != operands[0])
3959 emit_move_insn (operands[0], reg);
3963 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3966 (define_insn "*truncxfdf2_mixed"
3967 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3969 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3970 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3971 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3973 gcc_assert (!which_alternative);
3974 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3975 return "fstp%z0\t%y0";
3977 return "fst%z0\t%y0";
3979 [(set_attr "type" "fmov,multi,multi,multi")
3980 (set_attr "unit" "*,i387,i387,i387")
3981 (set_attr "mode" "DF")])
3983 (define_insn "truncxfdf2_i387_noop"
3984 [(set (match_operand:DF 0 "register_operand" "=f")
3985 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3986 "TARGET_80387 && flag_unsafe_math_optimizations"
3988 return output_387_reg_move (insn, operands);
3990 [(set_attr "type" "fmov")
3991 (set_attr "mode" "DF")])
3993 (define_insn "*truncxfdf2_i387"
3994 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
3996 (match_operand:XF 1 "register_operand" "f,f,f")))
3997 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4000 gcc_assert (!which_alternative);
4001 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4002 return "fstp%z0\t%y0";
4004 return "fst%z0\t%y0";
4006 [(set_attr "type" "fmov,multi,multi")
4007 (set_attr "unit" "*,i387,i387")
4008 (set_attr "mode" "DF")])
4010 (define_insn "*truncxfdf2_i387_1"
4011 [(set (match_operand:DF 0 "memory_operand" "=m")
4013 (match_operand:XF 1 "register_operand" "f")))]
4016 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4017 return "fstp%z0\t%y0";
4019 return "fst%z0\t%y0";
4021 [(set_attr "type" "fmov")
4022 (set_attr "mode" "DF")])
4025 [(set (match_operand:DF 0 "register_operand" "")
4027 (match_operand:XF 1 "register_operand" "")))
4028 (clobber (match_operand:DF 2 "memory_operand" ""))]
4029 "TARGET_80387 && reload_completed"
4030 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4031 (set (match_dup 0) (match_dup 2))]
4035 [(set (match_operand:DF 0 "memory_operand" "")
4037 (match_operand:XF 1 "register_operand" "")))
4038 (clobber (match_operand:DF 2 "memory_operand" ""))]
4040 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4043 ;; Signed conversion to DImode.
4045 (define_expand "fix_truncxfdi2"
4046 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4047 (fix:DI (match_operand:XF 1 "register_operand" "")))
4048 (clobber (reg:CC FLAGS_REG))])]
4053 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4058 (define_expand "fix_trunc<mode>di2"
4059 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4060 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4061 (clobber (reg:CC FLAGS_REG))])]
4062 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4065 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4067 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4070 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4072 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4073 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4074 if (out != operands[0])
4075 emit_move_insn (operands[0], out);
4080 ;; Signed conversion to SImode.
4082 (define_expand "fix_truncxfsi2"
4083 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4084 (fix:SI (match_operand:XF 1 "register_operand" "")))
4085 (clobber (reg:CC FLAGS_REG))])]
4090 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4095 (define_expand "fix_trunc<mode>si2"
4096 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4097 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4098 (clobber (reg:CC FLAGS_REG))])]
4099 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4102 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4104 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4107 if (SSE_FLOAT_MODE_P (<MODE>mode))
4109 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4110 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4111 if (out != operands[0])
4112 emit_move_insn (operands[0], out);
4117 ;; Signed conversion to HImode.
4119 (define_expand "fix_trunc<mode>hi2"
4120 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4121 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4122 (clobber (reg:CC FLAGS_REG))])]
4124 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4128 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4133 ;; When SSE is available, it is always faster to use it!
4134 (define_insn "fix_truncsfdi_sse"
4135 [(set (match_operand:DI 0 "register_operand" "=r,r")
4136 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4137 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4138 "cvttss2si{q}\t{%1, %0|%0, %1}"
4139 [(set_attr "type" "sseicvt")
4140 (set_attr "mode" "SF")
4141 (set_attr "athlon_decode" "double,vector")])
4143 (define_insn "fix_truncdfdi_sse"
4144 [(set (match_operand:DI 0 "register_operand" "=r,r")
4145 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4146 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4147 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4148 [(set_attr "type" "sseicvt")
4149 (set_attr "mode" "DF")
4150 (set_attr "athlon_decode" "double,vector")])
4152 (define_insn "fix_truncsfsi_sse"
4153 [(set (match_operand:SI 0 "register_operand" "=r,r")
4154 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4155 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4156 "cvttss2si\t{%1, %0|%0, %1}"
4157 [(set_attr "type" "sseicvt")
4158 (set_attr "mode" "DF")
4159 (set_attr "athlon_decode" "double,vector")])
4161 (define_insn "fix_truncdfsi_sse"
4162 [(set (match_operand:SI 0 "register_operand" "=r,r")
4163 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4164 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4165 "cvttsd2si\t{%1, %0|%0, %1}"
4166 [(set_attr "type" "sseicvt")
4167 (set_attr "mode" "DF")
4168 (set_attr "athlon_decode" "double,vector")])
4170 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4172 [(set (match_operand:DF 0 "register_operand" "")
4173 (match_operand:DF 1 "memory_operand" ""))
4174 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4175 (fix:SSEMODEI24 (match_dup 0)))]
4177 && peep2_reg_dead_p (2, operands[0])"
4178 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4182 [(set (match_operand:SF 0 "register_operand" "")
4183 (match_operand:SF 1 "memory_operand" ""))
4184 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4185 (fix:SSEMODEI24 (match_dup 0)))]
4187 && peep2_reg_dead_p (2, operands[0])"
4188 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4191 ;; Avoid vector decoded forms of the instruction.
4193 [(match_scratch:DF 2 "Y")
4194 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4195 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4196 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4197 [(set (match_dup 2) (match_dup 1))
4198 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4202 [(match_scratch:SF 2 "x")
4203 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4204 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4205 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4206 [(set (match_dup 2) (match_dup 1))
4207 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4210 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4211 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4212 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4214 && FLOAT_MODE_P (GET_MODE (operands[1]))
4215 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4216 && (TARGET_64BIT || <MODE>mode != DImode))
4218 && !(reload_completed || reload_in_progress)"
4223 if (memory_operand (operands[0], VOIDmode))
4224 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4227 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4228 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4234 [(set_attr "type" "fisttp")
4235 (set_attr "mode" "<MODE>")])
4237 (define_insn "fix_trunc<mode>_i387_fisttp"
4238 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4239 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4240 (clobber (match_scratch:XF 2 "=&1f"))]
4242 && FLOAT_MODE_P (GET_MODE (operands[1]))
4243 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4244 && (TARGET_64BIT || <MODE>mode != DImode))
4245 && TARGET_SSE_MATH)"
4246 "* return output_fix_trunc (insn, operands, 1);"
4247 [(set_attr "type" "fisttp")
4248 (set_attr "mode" "<MODE>")])
4250 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4251 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4252 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4253 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4254 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4256 && FLOAT_MODE_P (GET_MODE (operands[1]))
4257 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4258 && (TARGET_64BIT || <MODE>mode != DImode))
4259 && TARGET_SSE_MATH)"
4261 [(set_attr "type" "fisttp")
4262 (set_attr "mode" "<MODE>")])
4265 [(set (match_operand:X87MODEI 0 "register_operand" "")
4266 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4267 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4268 (clobber (match_scratch 3 ""))]
4270 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4271 (clobber (match_dup 3))])
4272 (set (match_dup 0) (match_dup 2))]
4276 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4277 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4278 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4279 (clobber (match_scratch 3 ""))]
4281 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4282 (clobber (match_dup 3))])]
4285 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4286 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4287 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4288 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4289 ;; function in i386.c.
4290 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4291 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4292 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4293 (clobber (reg:CC FLAGS_REG))]
4294 "TARGET_80387 && !TARGET_FISTTP
4295 && FLOAT_MODE_P (GET_MODE (operands[1]))
4296 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4297 && (TARGET_64BIT || <MODE>mode != DImode))
4298 && !(reload_completed || reload_in_progress)"
4303 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4305 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4306 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4307 if (memory_operand (operands[0], VOIDmode))
4308 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4309 operands[2], operands[3]));
4312 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4313 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4314 operands[2], operands[3],
4319 [(set_attr "type" "fistp")
4320 (set_attr "i387_cw" "trunc")
4321 (set_attr "mode" "<MODE>")])
4323 (define_insn "fix_truncdi_i387"
4324 [(set (match_operand:DI 0 "memory_operand" "=m")
4325 (fix:DI (match_operand 1 "register_operand" "f")))
4326 (use (match_operand:HI 2 "memory_operand" "m"))
4327 (use (match_operand:HI 3 "memory_operand" "m"))
4328 (clobber (match_scratch:XF 4 "=&1f"))]
4329 "TARGET_80387 && !TARGET_FISTTP
4330 && FLOAT_MODE_P (GET_MODE (operands[1]))
4331 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4332 "* return output_fix_trunc (insn, operands, 0);"
4333 [(set_attr "type" "fistp")
4334 (set_attr "i387_cw" "trunc")
4335 (set_attr "mode" "DI")])
4337 (define_insn "fix_truncdi_i387_with_temp"
4338 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4339 (fix:DI (match_operand 1 "register_operand" "f,f")))
4340 (use (match_operand:HI 2 "memory_operand" "m,m"))
4341 (use (match_operand:HI 3 "memory_operand" "m,m"))
4342 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4343 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4344 "TARGET_80387 && !TARGET_FISTTP
4345 && FLOAT_MODE_P (GET_MODE (operands[1]))
4346 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4348 [(set_attr "type" "fistp")
4349 (set_attr "i387_cw" "trunc")
4350 (set_attr "mode" "DI")])
4353 [(set (match_operand:DI 0 "register_operand" "")
4354 (fix:DI (match_operand 1 "register_operand" "")))
4355 (use (match_operand:HI 2 "memory_operand" ""))
4356 (use (match_operand:HI 3 "memory_operand" ""))
4357 (clobber (match_operand:DI 4 "memory_operand" ""))
4358 (clobber (match_scratch 5 ""))]
4360 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4363 (clobber (match_dup 5))])
4364 (set (match_dup 0) (match_dup 4))]
4368 [(set (match_operand:DI 0 "memory_operand" "")
4369 (fix:DI (match_operand 1 "register_operand" "")))
4370 (use (match_operand:HI 2 "memory_operand" ""))
4371 (use (match_operand:HI 3 "memory_operand" ""))
4372 (clobber (match_operand:DI 4 "memory_operand" ""))
4373 (clobber (match_scratch 5 ""))]
4375 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4378 (clobber (match_dup 5))])]
4381 (define_insn "fix_trunc<mode>_i387"
4382 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4383 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4384 (use (match_operand:HI 2 "memory_operand" "m"))
4385 (use (match_operand:HI 3 "memory_operand" "m"))]
4386 "TARGET_80387 && !TARGET_FISTTP
4387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4388 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4389 "* return output_fix_trunc (insn, operands, 0);"
4390 [(set_attr "type" "fistp")
4391 (set_attr "i387_cw" "trunc")
4392 (set_attr "mode" "<MODE>")])
4394 (define_insn "fix_trunc<mode>_i387_with_temp"
4395 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4396 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4397 (use (match_operand:HI 2 "memory_operand" "m,m"))
4398 (use (match_operand:HI 3 "memory_operand" "m,m"))
4399 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4400 "TARGET_80387 && !TARGET_FISTTP
4401 && FLOAT_MODE_P (GET_MODE (operands[1]))
4402 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4404 [(set_attr "type" "fistp")
4405 (set_attr "i387_cw" "trunc")
4406 (set_attr "mode" "<MODE>")])
4409 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4410 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4411 (use (match_operand:HI 2 "memory_operand" ""))
4412 (use (match_operand:HI 3 "memory_operand" ""))
4413 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4415 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4417 (use (match_dup 3))])
4418 (set (match_dup 0) (match_dup 4))]
4422 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4423 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4424 (use (match_operand:HI 2 "memory_operand" ""))
4425 (use (match_operand:HI 3 "memory_operand" ""))
4426 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4428 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4430 (use (match_dup 3))])]
4433 (define_insn "x86_fnstcw_1"
4434 [(set (match_operand:HI 0 "memory_operand" "=m")
4435 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4438 [(set_attr "length" "2")
4439 (set_attr "mode" "HI")
4440 (set_attr "unit" "i387")])
4442 (define_insn "x86_fldcw_1"
4443 [(set (reg:HI FPCR_REG)
4444 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4447 [(set_attr "length" "2")
4448 (set_attr "mode" "HI")
4449 (set_attr "unit" "i387")
4450 (set_attr "athlon_decode" "vector")])
4452 ;; Conversion between fixed point and floating point.
4454 ;; Even though we only accept memory inputs, the backend _really_
4455 ;; wants to be able to do this between registers.
4457 (define_expand "floathisf2"
4458 [(set (match_operand:SF 0 "register_operand" "")
4459 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4460 "TARGET_80387 || TARGET_SSE_MATH"
4462 if (TARGET_SSE_MATH)
4464 emit_insn (gen_floatsisf2 (operands[0],
4465 convert_to_mode (SImode, operands[1], 0)));
4470 (define_insn "*floathisf2_i387"
4471 [(set (match_operand:SF 0 "register_operand" "=f,f")
4472 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4473 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4477 [(set_attr "type" "fmov,multi")
4478 (set_attr "mode" "SF")
4479 (set_attr "unit" "*,i387")
4480 (set_attr "fp_int_src" "true")])
4482 (define_expand "floatsisf2"
4483 [(set (match_operand:SF 0 "register_operand" "")
4484 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4485 "TARGET_80387 || TARGET_SSE_MATH"
4488 (define_insn "*floatsisf2_mixed"
4489 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4490 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4491 "TARGET_MIX_SSE_I387"
4495 cvtsi2ss\t{%1, %0|%0, %1}
4496 cvtsi2ss\t{%1, %0|%0, %1}"
4497 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4498 (set_attr "mode" "SF")
4499 (set_attr "unit" "*,i387,*,*")
4500 (set_attr "athlon_decode" "*,*,vector,double")
4501 (set_attr "fp_int_src" "true")])
4503 (define_insn "*floatsisf2_sse"
4504 [(set (match_operand:SF 0 "register_operand" "=x,x")
4505 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4507 "cvtsi2ss\t{%1, %0|%0, %1}"
4508 [(set_attr "type" "sseicvt")
4509 (set_attr "mode" "SF")
4510 (set_attr "athlon_decode" "vector,double")
4511 (set_attr "fp_int_src" "true")])
4513 (define_insn "*floatsisf2_i387"
4514 [(set (match_operand:SF 0 "register_operand" "=f,f")
4515 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4520 [(set_attr "type" "fmov,multi")
4521 (set_attr "mode" "SF")
4522 (set_attr "unit" "*,i387")
4523 (set_attr "fp_int_src" "true")])
4525 (define_expand "floatdisf2"
4526 [(set (match_operand:SF 0 "register_operand" "")
4527 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4528 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4531 (define_insn "*floatdisf2_mixed"
4532 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4533 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4534 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4538 cvtsi2ss{q}\t{%1, %0|%0, %1}
4539 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4540 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4541 (set_attr "mode" "SF")
4542 (set_attr "unit" "*,i387,*,*")
4543 (set_attr "athlon_decode" "*,*,vector,double")
4544 (set_attr "fp_int_src" "true")])
4546 (define_insn "*floatdisf2_sse"
4547 [(set (match_operand:SF 0 "register_operand" "=x,x")
4548 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4549 "TARGET_64BIT && TARGET_SSE_MATH"
4550 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4551 [(set_attr "type" "sseicvt")
4552 (set_attr "mode" "SF")
4553 (set_attr "athlon_decode" "vector,double")
4554 (set_attr "fp_int_src" "true")])
4556 (define_insn "*floatdisf2_i387"
4557 [(set (match_operand:SF 0 "register_operand" "=f,f")
4558 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4563 [(set_attr "type" "fmov,multi")
4564 (set_attr "mode" "SF")
4565 (set_attr "unit" "*,i387")
4566 (set_attr "fp_int_src" "true")])
4568 (define_expand "floathidf2"
4569 [(set (match_operand:DF 0 "register_operand" "")
4570 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4571 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4573 if (TARGET_SSE2 && TARGET_SSE_MATH)
4575 emit_insn (gen_floatsidf2 (operands[0],
4576 convert_to_mode (SImode, operands[1], 0)));
4581 (define_insn "*floathidf2_i387"
4582 [(set (match_operand:DF 0 "register_operand" "=f,f")
4583 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4584 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4588 [(set_attr "type" "fmov,multi")
4589 (set_attr "mode" "DF")
4590 (set_attr "unit" "*,i387")
4591 (set_attr "fp_int_src" "true")])
4593 (define_expand "floatsidf2"
4594 [(set (match_operand:DF 0 "register_operand" "")
4595 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4596 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4599 (define_insn "*floatsidf2_mixed"
4600 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4601 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4602 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4606 cvtsi2sd\t{%1, %0|%0, %1}
4607 cvtsi2sd\t{%1, %0|%0, %1}"
4608 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4609 (set_attr "mode" "DF")
4610 (set_attr "unit" "*,i387,*,*")
4611 (set_attr "athlon_decode" "*,*,double,direct")
4612 (set_attr "fp_int_src" "true")])
4614 (define_insn "*floatsidf2_sse"
4615 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4616 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4617 "TARGET_SSE2 && TARGET_SSE_MATH"
4618 "cvtsi2sd\t{%1, %0|%0, %1}"
4619 [(set_attr "type" "sseicvt")
4620 (set_attr "mode" "DF")
4621 (set_attr "athlon_decode" "double,direct")
4622 (set_attr "fp_int_src" "true")])
4624 (define_insn "*floatsidf2_i387"
4625 [(set (match_operand:DF 0 "register_operand" "=f,f")
4626 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4631 [(set_attr "type" "fmov,multi")
4632 (set_attr "mode" "DF")
4633 (set_attr "unit" "*,i387")
4634 (set_attr "fp_int_src" "true")])
4636 (define_expand "floatdidf2"
4637 [(set (match_operand:DF 0 "register_operand" "")
4638 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4639 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4642 (define_insn "*floatdidf2_mixed"
4643 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4644 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4645 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4649 cvtsi2sd{q}\t{%1, %0|%0, %1}
4650 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4651 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4652 (set_attr "mode" "DF")
4653 (set_attr "unit" "*,i387,*,*")
4654 (set_attr "athlon_decode" "*,*,double,direct")
4655 (set_attr "fp_int_src" "true")])
4657 (define_insn "*floatdidf2_sse"
4658 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4659 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4660 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4661 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4662 [(set_attr "type" "sseicvt")
4663 (set_attr "mode" "DF")
4664 (set_attr "athlon_decode" "double,direct")
4665 (set_attr "fp_int_src" "true")])
4667 (define_insn "*floatdidf2_i387"
4668 [(set (match_operand:DF 0 "register_operand" "=f,f")
4669 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4674 [(set_attr "type" "fmov,multi")
4675 (set_attr "mode" "DF")
4676 (set_attr "unit" "*,i387")
4677 (set_attr "fp_int_src" "true")])
4679 (define_insn "floathixf2"
4680 [(set (match_operand:XF 0 "register_operand" "=f,f")
4681 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4686 [(set_attr "type" "fmov,multi")
4687 (set_attr "mode" "XF")
4688 (set_attr "unit" "*,i387")
4689 (set_attr "fp_int_src" "true")])
4691 (define_insn "floatsixf2"
4692 [(set (match_operand:XF 0 "register_operand" "=f,f")
4693 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4698 [(set_attr "type" "fmov,multi")
4699 (set_attr "mode" "XF")
4700 (set_attr "unit" "*,i387")
4701 (set_attr "fp_int_src" "true")])
4703 (define_insn "floatdixf2"
4704 [(set (match_operand:XF 0 "register_operand" "=f,f")
4705 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4710 [(set_attr "type" "fmov,multi")
4711 (set_attr "mode" "XF")
4712 (set_attr "unit" "*,i387")
4713 (set_attr "fp_int_src" "true")])
4715 ;; %%% Kill these when reload knows how to do it.
4717 [(set (match_operand 0 "fp_register_operand" "")
4718 (float (match_operand 1 "register_operand" "")))]
4721 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4724 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4725 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4726 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4727 ix86_free_from_memory (GET_MODE (operands[1]));
4731 (define_expand "floatunssisf2"
4732 [(use (match_operand:SF 0 "register_operand" ""))
4733 (use (match_operand:SI 1 "register_operand" ""))]
4734 "!TARGET_64BIT && TARGET_SSE_MATH"
4735 "x86_emit_floatuns (operands); DONE;")
4737 (define_expand "floatunsdisf2"
4738 [(use (match_operand:SF 0 "register_operand" ""))
4739 (use (match_operand:DI 1 "register_operand" ""))]
4740 "TARGET_64BIT && TARGET_SSE_MATH"
4741 "x86_emit_floatuns (operands); DONE;")
4743 (define_expand "floatunsdidf2"
4744 [(use (match_operand:DF 0 "register_operand" ""))
4745 (use (match_operand:DI 1 "register_operand" ""))]
4746 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4747 "x86_emit_floatuns (operands); DONE;")
4749 ;; SSE extract/set expanders
4754 ;; %%% splits for addditi3
4756 (define_expand "addti3"
4757 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4758 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4759 (match_operand:TI 2 "x86_64_general_operand" "")))
4760 (clobber (reg:CC FLAGS_REG))]
4762 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4764 (define_insn "*addti3_1"
4765 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4766 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4767 (match_operand:TI 2 "general_operand" "roiF,riF")))
4768 (clobber (reg:CC FLAGS_REG))]
4769 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4773 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4774 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4775 (match_operand:TI 2 "general_operand" "")))
4776 (clobber (reg:CC FLAGS_REG))]
4777 "TARGET_64BIT && reload_completed"
4778 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4780 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4781 (parallel [(set (match_dup 3)
4782 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4785 (clobber (reg:CC FLAGS_REG))])]
4786 "split_ti (operands+0, 1, operands+0, operands+3);
4787 split_ti (operands+1, 1, operands+1, operands+4);
4788 split_ti (operands+2, 1, operands+2, operands+5);")
4790 ;; %%% splits for addsidi3
4791 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4792 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4793 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4795 (define_expand "adddi3"
4796 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4797 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4798 (match_operand:DI 2 "x86_64_general_operand" "")))
4799 (clobber (reg:CC FLAGS_REG))]
4801 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4803 (define_insn "*adddi3_1"
4804 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4805 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4806 (match_operand:DI 2 "general_operand" "roiF,riF")))
4807 (clobber (reg:CC FLAGS_REG))]
4808 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4812 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4813 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4814 (match_operand:DI 2 "general_operand" "")))
4815 (clobber (reg:CC FLAGS_REG))]
4816 "!TARGET_64BIT && reload_completed"
4817 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4819 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4820 (parallel [(set (match_dup 3)
4821 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4824 (clobber (reg:CC FLAGS_REG))])]
4825 "split_di (operands+0, 1, operands+0, operands+3);
4826 split_di (operands+1, 1, operands+1, operands+4);
4827 split_di (operands+2, 1, operands+2, operands+5);")
4829 (define_insn "adddi3_carry_rex64"
4830 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4831 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4832 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4833 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4834 (clobber (reg:CC FLAGS_REG))]
4835 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4836 "adc{q}\t{%2, %0|%0, %2}"
4837 [(set_attr "type" "alu")
4838 (set_attr "pent_pair" "pu")
4839 (set_attr "mode" "DI")])
4841 (define_insn "*adddi3_cc_rex64"
4842 [(set (reg:CC FLAGS_REG)
4843 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4844 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4846 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4847 (plus:DI (match_dup 1) (match_dup 2)))]
4848 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4849 "add{q}\t{%2, %0|%0, %2}"
4850 [(set_attr "type" "alu")
4851 (set_attr "mode" "DI")])
4853 (define_insn "addqi3_carry"
4854 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4855 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4856 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4857 (match_operand:QI 2 "general_operand" "qi,qm")))
4858 (clobber (reg:CC FLAGS_REG))]
4859 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4860 "adc{b}\t{%2, %0|%0, %2}"
4861 [(set_attr "type" "alu")
4862 (set_attr "pent_pair" "pu")
4863 (set_attr "mode" "QI")])
4865 (define_insn "addhi3_carry"
4866 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4867 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4868 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4869 (match_operand:HI 2 "general_operand" "ri,rm")))
4870 (clobber (reg:CC FLAGS_REG))]
4871 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4872 "adc{w}\t{%2, %0|%0, %2}"
4873 [(set_attr "type" "alu")
4874 (set_attr "pent_pair" "pu")
4875 (set_attr "mode" "HI")])
4877 (define_insn "addsi3_carry"
4878 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4879 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4880 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4881 (match_operand:SI 2 "general_operand" "ri,rm")))
4882 (clobber (reg:CC FLAGS_REG))]
4883 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4884 "adc{l}\t{%2, %0|%0, %2}"
4885 [(set_attr "type" "alu")
4886 (set_attr "pent_pair" "pu")
4887 (set_attr "mode" "SI")])
4889 (define_insn "*addsi3_carry_zext"
4890 [(set (match_operand:DI 0 "register_operand" "=r")
4892 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4893 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4894 (match_operand:SI 2 "general_operand" "rim"))))
4895 (clobber (reg:CC FLAGS_REG))]
4896 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4897 "adc{l}\t{%2, %k0|%k0, %2}"
4898 [(set_attr "type" "alu")
4899 (set_attr "pent_pair" "pu")
4900 (set_attr "mode" "SI")])
4902 (define_insn "*addsi3_cc"
4903 [(set (reg:CC FLAGS_REG)
4904 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4905 (match_operand:SI 2 "general_operand" "ri,rm")]
4907 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4908 (plus:SI (match_dup 1) (match_dup 2)))]
4909 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4910 "add{l}\t{%2, %0|%0, %2}"
4911 [(set_attr "type" "alu")
4912 (set_attr "mode" "SI")])
4914 (define_insn "addqi3_cc"
4915 [(set (reg:CC FLAGS_REG)
4916 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4917 (match_operand:QI 2 "general_operand" "qi,qm")]
4919 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4920 (plus:QI (match_dup 1) (match_dup 2)))]
4921 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4922 "add{b}\t{%2, %0|%0, %2}"
4923 [(set_attr "type" "alu")
4924 (set_attr "mode" "QI")])
4926 (define_expand "addsi3"
4927 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4928 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4929 (match_operand:SI 2 "general_operand" "")))
4930 (clobber (reg:CC FLAGS_REG))])]
4932 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4934 (define_insn "*lea_1"
4935 [(set (match_operand:SI 0 "register_operand" "=r")
4936 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4938 "lea{l}\t{%a1, %0|%0, %a1}"
4939 [(set_attr "type" "lea")
4940 (set_attr "mode" "SI")])
4942 (define_insn "*lea_1_rex64"
4943 [(set (match_operand:SI 0 "register_operand" "=r")
4944 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4946 "lea{l}\t{%a1, %0|%0, %a1}"
4947 [(set_attr "type" "lea")
4948 (set_attr "mode" "SI")])
4950 (define_insn "*lea_1_zext"
4951 [(set (match_operand:DI 0 "register_operand" "=r")
4953 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4955 "lea{l}\t{%a1, %k0|%k0, %a1}"
4956 [(set_attr "type" "lea")
4957 (set_attr "mode" "SI")])
4959 (define_insn "*lea_2_rex64"
4960 [(set (match_operand:DI 0 "register_operand" "=r")
4961 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4963 "lea{q}\t{%a1, %0|%0, %a1}"
4964 [(set_attr "type" "lea")
4965 (set_attr "mode" "DI")])
4967 ;; The lea patterns for non-Pmodes needs to be matched by several
4968 ;; insns converted to real lea by splitters.
4970 (define_insn_and_split "*lea_general_1"
4971 [(set (match_operand 0 "register_operand" "=r")
4972 (plus (plus (match_operand 1 "index_register_operand" "l")
4973 (match_operand 2 "register_operand" "r"))
4974 (match_operand 3 "immediate_operand" "i")))]
4975 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4976 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4977 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4978 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4979 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4980 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4981 || GET_MODE (operands[3]) == VOIDmode)"
4983 "&& reload_completed"
4987 operands[0] = gen_lowpart (SImode, operands[0]);
4988 operands[1] = gen_lowpart (Pmode, operands[1]);
4989 operands[2] = gen_lowpart (Pmode, operands[2]);
4990 operands[3] = gen_lowpart (Pmode, operands[3]);
4991 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4993 if (Pmode != SImode)
4994 pat = gen_rtx_SUBREG (SImode, pat, 0);
4995 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4998 [(set_attr "type" "lea")
4999 (set_attr "mode" "SI")])
5001 (define_insn_and_split "*lea_general_1_zext"
5002 [(set (match_operand:DI 0 "register_operand" "=r")
5004 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5005 (match_operand:SI 2 "register_operand" "r"))
5006 (match_operand:SI 3 "immediate_operand" "i"))))]
5009 "&& reload_completed"
5011 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5013 (match_dup 3)) 0)))]
5015 operands[1] = gen_lowpart (Pmode, operands[1]);
5016 operands[2] = gen_lowpart (Pmode, operands[2]);
5017 operands[3] = gen_lowpart (Pmode, operands[3]);
5019 [(set_attr "type" "lea")
5020 (set_attr "mode" "SI")])
5022 (define_insn_and_split "*lea_general_2"
5023 [(set (match_operand 0 "register_operand" "=r")
5024 (plus (mult (match_operand 1 "index_register_operand" "l")
5025 (match_operand 2 "const248_operand" "i"))
5026 (match_operand 3 "nonmemory_operand" "ri")))]
5027 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5028 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5029 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5030 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5031 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5032 || GET_MODE (operands[3]) == VOIDmode)"
5034 "&& reload_completed"
5038 operands[0] = gen_lowpart (SImode, operands[0]);
5039 operands[1] = gen_lowpart (Pmode, operands[1]);
5040 operands[3] = gen_lowpart (Pmode, operands[3]);
5041 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5043 if (Pmode != SImode)
5044 pat = gen_rtx_SUBREG (SImode, pat, 0);
5045 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5048 [(set_attr "type" "lea")
5049 (set_attr "mode" "SI")])
5051 (define_insn_and_split "*lea_general_2_zext"
5052 [(set (match_operand:DI 0 "register_operand" "=r")
5054 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5055 (match_operand:SI 2 "const248_operand" "n"))
5056 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5059 "&& reload_completed"
5061 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5063 (match_dup 3)) 0)))]
5065 operands[1] = gen_lowpart (Pmode, operands[1]);
5066 operands[3] = gen_lowpart (Pmode, operands[3]);
5068 [(set_attr "type" "lea")
5069 (set_attr "mode" "SI")])
5071 (define_insn_and_split "*lea_general_3"
5072 [(set (match_operand 0 "register_operand" "=r")
5073 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5074 (match_operand 2 "const248_operand" "i"))
5075 (match_operand 3 "register_operand" "r"))
5076 (match_operand 4 "immediate_operand" "i")))]
5077 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5078 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5079 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5080 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5081 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5083 "&& reload_completed"
5087 operands[0] = gen_lowpart (SImode, operands[0]);
5088 operands[1] = gen_lowpart (Pmode, operands[1]);
5089 operands[3] = gen_lowpart (Pmode, operands[3]);
5090 operands[4] = gen_lowpart (Pmode, operands[4]);
5091 pat = gen_rtx_PLUS (Pmode,
5092 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5096 if (Pmode != SImode)
5097 pat = gen_rtx_SUBREG (SImode, pat, 0);
5098 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5101 [(set_attr "type" "lea")
5102 (set_attr "mode" "SI")])
5104 (define_insn_and_split "*lea_general_3_zext"
5105 [(set (match_operand:DI 0 "register_operand" "=r")
5107 (plus:SI (plus:SI (mult:SI
5108 (match_operand:SI 1 "index_register_operand" "l")
5109 (match_operand:SI 2 "const248_operand" "n"))
5110 (match_operand:SI 3 "register_operand" "r"))
5111 (match_operand:SI 4 "immediate_operand" "i"))))]
5114 "&& reload_completed"
5116 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5119 (match_dup 4)) 0)))]
5121 operands[1] = gen_lowpart (Pmode, operands[1]);
5122 operands[3] = gen_lowpart (Pmode, operands[3]);
5123 operands[4] = gen_lowpart (Pmode, operands[4]);
5125 [(set_attr "type" "lea")
5126 (set_attr "mode" "SI")])
5128 (define_insn "*adddi_1_rex64"
5129 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5130 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5131 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5132 (clobber (reg:CC FLAGS_REG))]
5133 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5135 switch (get_attr_type (insn))
5138 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5139 return "lea{q}\t{%a2, %0|%0, %a2}";
5142 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5143 if (operands[2] == const1_rtx)
5144 return "inc{q}\t%0";
5147 gcc_assert (operands[2] == constm1_rtx);
5148 return "dec{q}\t%0";
5152 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5154 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5155 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5156 if (GET_CODE (operands[2]) == CONST_INT
5157 /* Avoid overflows. */
5158 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5159 && (INTVAL (operands[2]) == 128
5160 || (INTVAL (operands[2]) < 0
5161 && INTVAL (operands[2]) != -128)))
5163 operands[2] = GEN_INT (-INTVAL (operands[2]));
5164 return "sub{q}\t{%2, %0|%0, %2}";
5166 return "add{q}\t{%2, %0|%0, %2}";
5170 (cond [(eq_attr "alternative" "2")
5171 (const_string "lea")
5172 ; Current assemblers are broken and do not allow @GOTOFF in
5173 ; ought but a memory context.
5174 (match_operand:DI 2 "pic_symbolic_operand" "")
5175 (const_string "lea")
5176 (match_operand:DI 2 "incdec_operand" "")
5177 (const_string "incdec")
5179 (const_string "alu")))
5180 (set_attr "mode" "DI")])
5182 ;; Convert lea to the lea pattern to avoid flags dependency.
5184 [(set (match_operand:DI 0 "register_operand" "")
5185 (plus:DI (match_operand:DI 1 "register_operand" "")
5186 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5187 (clobber (reg:CC FLAGS_REG))]
5188 "TARGET_64BIT && reload_completed
5189 && true_regnum (operands[0]) != true_regnum (operands[1])"
5191 (plus:DI (match_dup 1)
5195 (define_insn "*adddi_2_rex64"
5196 [(set (reg FLAGS_REG)
5198 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5199 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5201 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5202 (plus:DI (match_dup 1) (match_dup 2)))]
5203 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5204 && ix86_binary_operator_ok (PLUS, DImode, operands)
5205 /* Current assemblers are broken and do not allow @GOTOFF in
5206 ought but a memory context. */
5207 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5209 switch (get_attr_type (insn))
5212 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5213 if (operands[2] == const1_rtx)
5214 return "inc{q}\t%0";
5217 gcc_assert (operands[2] == constm1_rtx);
5218 return "dec{q}\t%0";
5222 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5223 /* ???? We ought to handle there the 32bit case too
5224 - do we need new constraint? */
5225 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5226 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5227 if (GET_CODE (operands[2]) == CONST_INT
5228 /* Avoid overflows. */
5229 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5230 && (INTVAL (operands[2]) == 128
5231 || (INTVAL (operands[2]) < 0
5232 && INTVAL (operands[2]) != -128)))
5234 operands[2] = GEN_INT (-INTVAL (operands[2]));
5235 return "sub{q}\t{%2, %0|%0, %2}";
5237 return "add{q}\t{%2, %0|%0, %2}";
5241 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5242 (const_string "incdec")
5243 (const_string "alu")))
5244 (set_attr "mode" "DI")])
5246 (define_insn "*adddi_3_rex64"
5247 [(set (reg FLAGS_REG)
5248 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5249 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5250 (clobber (match_scratch:DI 0 "=r"))]
5252 && ix86_match_ccmode (insn, CCZmode)
5253 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5254 /* Current assemblers are broken and do not allow @GOTOFF in
5255 ought but a memory context. */
5256 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5258 switch (get_attr_type (insn))
5261 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5262 if (operands[2] == const1_rtx)
5263 return "inc{q}\t%0";
5266 gcc_assert (operands[2] == constm1_rtx);
5267 return "dec{q}\t%0";
5271 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5272 /* ???? We ought to handle there the 32bit case too
5273 - do we need new constraint? */
5274 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5275 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5276 if (GET_CODE (operands[2]) == CONST_INT
5277 /* Avoid overflows. */
5278 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5279 && (INTVAL (operands[2]) == 128
5280 || (INTVAL (operands[2]) < 0
5281 && INTVAL (operands[2]) != -128)))
5283 operands[2] = GEN_INT (-INTVAL (operands[2]));
5284 return "sub{q}\t{%2, %0|%0, %2}";
5286 return "add{q}\t{%2, %0|%0, %2}";
5290 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5291 (const_string "incdec")
5292 (const_string "alu")))
5293 (set_attr "mode" "DI")])
5295 ; For comparisons against 1, -1 and 128, we may generate better code
5296 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5297 ; is matched then. We can't accept general immediate, because for
5298 ; case of overflows, the result is messed up.
5299 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5301 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5302 ; only for comparisons not depending on it.
5303 (define_insn "*adddi_4_rex64"
5304 [(set (reg FLAGS_REG)
5305 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5306 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5307 (clobber (match_scratch:DI 0 "=rm"))]
5309 && ix86_match_ccmode (insn, CCGCmode)"
5311 switch (get_attr_type (insn))
5314 if (operands[2] == constm1_rtx)
5315 return "inc{q}\t%0";
5318 gcc_assert (operands[2] == const1_rtx);
5319 return "dec{q}\t%0";
5323 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5324 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5325 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5326 if ((INTVAL (operands[2]) == -128
5327 || (INTVAL (operands[2]) > 0
5328 && INTVAL (operands[2]) != 128))
5329 /* Avoid overflows. */
5330 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5331 return "sub{q}\t{%2, %0|%0, %2}";
5332 operands[2] = GEN_INT (-INTVAL (operands[2]));
5333 return "add{q}\t{%2, %0|%0, %2}";
5337 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5338 (const_string "incdec")
5339 (const_string "alu")))
5340 (set_attr "mode" "DI")])
5342 (define_insn "*adddi_5_rex64"
5343 [(set (reg FLAGS_REG)
5345 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5346 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5348 (clobber (match_scratch:DI 0 "=r"))]
5350 && ix86_match_ccmode (insn, CCGOCmode)
5351 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5352 /* Current assemblers are broken and do not allow @GOTOFF in
5353 ought but a memory context. */
5354 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5356 switch (get_attr_type (insn))
5359 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5360 if (operands[2] == const1_rtx)
5361 return "inc{q}\t%0";
5364 gcc_assert (operands[2] == constm1_rtx);
5365 return "dec{q}\t%0";
5369 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5370 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5371 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5372 if (GET_CODE (operands[2]) == CONST_INT
5373 /* Avoid overflows. */
5374 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5375 && (INTVAL (operands[2]) == 128
5376 || (INTVAL (operands[2]) < 0
5377 && INTVAL (operands[2]) != -128)))
5379 operands[2] = GEN_INT (-INTVAL (operands[2]));
5380 return "sub{q}\t{%2, %0|%0, %2}";
5382 return "add{q}\t{%2, %0|%0, %2}";
5386 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5387 (const_string "incdec")
5388 (const_string "alu")))
5389 (set_attr "mode" "DI")])
5392 (define_insn "*addsi_1"
5393 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5394 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5395 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5396 (clobber (reg:CC FLAGS_REG))]
5397 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5399 switch (get_attr_type (insn))
5402 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5403 return "lea{l}\t{%a2, %0|%0, %a2}";
5406 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5407 if (operands[2] == const1_rtx)
5408 return "inc{l}\t%0";
5411 gcc_assert (operands[2] == constm1_rtx);
5412 return "dec{l}\t%0";
5416 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5418 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5419 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5420 if (GET_CODE (operands[2]) == CONST_INT
5421 && (INTVAL (operands[2]) == 128
5422 || (INTVAL (operands[2]) < 0
5423 && INTVAL (operands[2]) != -128)))
5425 operands[2] = GEN_INT (-INTVAL (operands[2]));
5426 return "sub{l}\t{%2, %0|%0, %2}";
5428 return "add{l}\t{%2, %0|%0, %2}";
5432 (cond [(eq_attr "alternative" "2")
5433 (const_string "lea")
5434 ; Current assemblers are broken and do not allow @GOTOFF in
5435 ; ought but a memory context.
5436 (match_operand:SI 2 "pic_symbolic_operand" "")
5437 (const_string "lea")
5438 (match_operand:SI 2 "incdec_operand" "")
5439 (const_string "incdec")
5441 (const_string "alu")))
5442 (set_attr "mode" "SI")])
5444 ;; Convert lea to the lea pattern to avoid flags dependency.
5446 [(set (match_operand 0 "register_operand" "")
5447 (plus (match_operand 1 "register_operand" "")
5448 (match_operand 2 "nonmemory_operand" "")))
5449 (clobber (reg:CC FLAGS_REG))]
5451 && true_regnum (operands[0]) != true_regnum (operands[1])"
5455 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5456 may confuse gen_lowpart. */
5457 if (GET_MODE (operands[0]) != Pmode)
5459 operands[1] = gen_lowpart (Pmode, operands[1]);
5460 operands[2] = gen_lowpart (Pmode, operands[2]);
5462 operands[0] = gen_lowpart (SImode, operands[0]);
5463 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5464 if (Pmode != SImode)
5465 pat = gen_rtx_SUBREG (SImode, pat, 0);
5466 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5470 ;; It may seem that nonimmediate operand is proper one for operand 1.
5471 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5472 ;; we take care in ix86_binary_operator_ok to not allow two memory
5473 ;; operands so proper swapping will be done in reload. This allow
5474 ;; patterns constructed from addsi_1 to match.
5475 (define_insn "addsi_1_zext"
5476 [(set (match_operand:DI 0 "register_operand" "=r,r")
5478 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5479 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5480 (clobber (reg:CC FLAGS_REG))]
5481 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5483 switch (get_attr_type (insn))
5486 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5487 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5490 if (operands[2] == const1_rtx)
5491 return "inc{l}\t%k0";
5494 gcc_assert (operands[2] == constm1_rtx);
5495 return "dec{l}\t%k0";
5499 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5500 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5501 if (GET_CODE (operands[2]) == CONST_INT
5502 && (INTVAL (operands[2]) == 128
5503 || (INTVAL (operands[2]) < 0
5504 && INTVAL (operands[2]) != -128)))
5506 operands[2] = GEN_INT (-INTVAL (operands[2]));
5507 return "sub{l}\t{%2, %k0|%k0, %2}";
5509 return "add{l}\t{%2, %k0|%k0, %2}";
5513 (cond [(eq_attr "alternative" "1")
5514 (const_string "lea")
5515 ; Current assemblers are broken and do not allow @GOTOFF in
5516 ; ought but a memory context.
5517 (match_operand:SI 2 "pic_symbolic_operand" "")
5518 (const_string "lea")
5519 (match_operand:SI 2 "incdec_operand" "")
5520 (const_string "incdec")
5522 (const_string "alu")))
5523 (set_attr "mode" "SI")])
5525 ;; Convert lea to the lea pattern to avoid flags dependency.
5527 [(set (match_operand:DI 0 "register_operand" "")
5529 (plus:SI (match_operand:SI 1 "register_operand" "")
5530 (match_operand:SI 2 "nonmemory_operand" ""))))
5531 (clobber (reg:CC FLAGS_REG))]
5532 "TARGET_64BIT && reload_completed
5533 && true_regnum (operands[0]) != true_regnum (operands[1])"
5535 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5537 operands[1] = gen_lowpart (Pmode, operands[1]);
5538 operands[2] = gen_lowpart (Pmode, operands[2]);
5541 (define_insn "*addsi_2"
5542 [(set (reg FLAGS_REG)
5544 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5545 (match_operand:SI 2 "general_operand" "rmni,rni"))
5547 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5548 (plus:SI (match_dup 1) (match_dup 2)))]
5549 "ix86_match_ccmode (insn, CCGOCmode)
5550 && ix86_binary_operator_ok (PLUS, SImode, operands)
5551 /* Current assemblers are broken and do not allow @GOTOFF in
5552 ought but a memory context. */
5553 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5555 switch (get_attr_type (insn))
5558 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5559 if (operands[2] == const1_rtx)
5560 return "inc{l}\t%0";
5563 gcc_assert (operands[2] == constm1_rtx);
5564 return "dec{l}\t%0";
5568 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5569 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5570 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5571 if (GET_CODE (operands[2]) == CONST_INT
5572 && (INTVAL (operands[2]) == 128
5573 || (INTVAL (operands[2]) < 0
5574 && INTVAL (operands[2]) != -128)))
5576 operands[2] = GEN_INT (-INTVAL (operands[2]));
5577 return "sub{l}\t{%2, %0|%0, %2}";
5579 return "add{l}\t{%2, %0|%0, %2}";
5583 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5584 (const_string "incdec")
5585 (const_string "alu")))
5586 (set_attr "mode" "SI")])
5588 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5589 (define_insn "*addsi_2_zext"
5590 [(set (reg FLAGS_REG)
5592 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5593 (match_operand:SI 2 "general_operand" "rmni"))
5595 (set (match_operand:DI 0 "register_operand" "=r")
5596 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5597 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5598 && ix86_binary_operator_ok (PLUS, SImode, operands)
5599 /* Current assemblers are broken and do not allow @GOTOFF in
5600 ought but a memory context. */
5601 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5603 switch (get_attr_type (insn))
5606 if (operands[2] == const1_rtx)
5607 return "inc{l}\t%k0";
5610 gcc_assert (operands[2] == constm1_rtx);
5611 return "dec{l}\t%k0";
5615 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5616 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5617 if (GET_CODE (operands[2]) == CONST_INT
5618 && (INTVAL (operands[2]) == 128
5619 || (INTVAL (operands[2]) < 0
5620 && INTVAL (operands[2]) != -128)))
5622 operands[2] = GEN_INT (-INTVAL (operands[2]));
5623 return "sub{l}\t{%2, %k0|%k0, %2}";
5625 return "add{l}\t{%2, %k0|%k0, %2}";
5629 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5630 (const_string "incdec")
5631 (const_string "alu")))
5632 (set_attr "mode" "SI")])
5634 (define_insn "*addsi_3"
5635 [(set (reg FLAGS_REG)
5636 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5637 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5638 (clobber (match_scratch:SI 0 "=r"))]
5639 "ix86_match_ccmode (insn, CCZmode)
5640 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5641 /* Current assemblers are broken and do not allow @GOTOFF in
5642 ought but a memory context. */
5643 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5645 switch (get_attr_type (insn))
5648 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5649 if (operands[2] == const1_rtx)
5650 return "inc{l}\t%0";
5653 gcc_assert (operands[2] == constm1_rtx);
5654 return "dec{l}\t%0";
5658 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5659 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5660 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5661 if (GET_CODE (operands[2]) == CONST_INT
5662 && (INTVAL (operands[2]) == 128
5663 || (INTVAL (operands[2]) < 0
5664 && INTVAL (operands[2]) != -128)))
5666 operands[2] = GEN_INT (-INTVAL (operands[2]));
5667 return "sub{l}\t{%2, %0|%0, %2}";
5669 return "add{l}\t{%2, %0|%0, %2}";
5673 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5674 (const_string "incdec")
5675 (const_string "alu")))
5676 (set_attr "mode" "SI")])
5678 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5679 (define_insn "*addsi_3_zext"
5680 [(set (reg FLAGS_REG)
5681 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5682 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5683 (set (match_operand:DI 0 "register_operand" "=r")
5684 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5685 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5686 && ix86_binary_operator_ok (PLUS, SImode, operands)
5687 /* Current assemblers are broken and do not allow @GOTOFF in
5688 ought but a memory context. */
5689 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5691 switch (get_attr_type (insn))
5694 if (operands[2] == const1_rtx)
5695 return "inc{l}\t%k0";
5698 gcc_assert (operands[2] == constm1_rtx);
5699 return "dec{l}\t%k0";
5703 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5704 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5705 if (GET_CODE (operands[2]) == CONST_INT
5706 && (INTVAL (operands[2]) == 128
5707 || (INTVAL (operands[2]) < 0
5708 && INTVAL (operands[2]) != -128)))
5710 operands[2] = GEN_INT (-INTVAL (operands[2]));
5711 return "sub{l}\t{%2, %k0|%k0, %2}";
5713 return "add{l}\t{%2, %k0|%k0, %2}";
5717 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5718 (const_string "incdec")
5719 (const_string "alu")))
5720 (set_attr "mode" "SI")])
5722 ; For comparisons against 1, -1 and 128, we may generate better code
5723 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5724 ; is matched then. We can't accept general immediate, because for
5725 ; case of overflows, the result is messed up.
5726 ; This pattern also don't hold of 0x80000000, since the value overflows
5728 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5729 ; only for comparisons not depending on it.
5730 (define_insn "*addsi_4"
5731 [(set (reg FLAGS_REG)
5732 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5733 (match_operand:SI 2 "const_int_operand" "n")))
5734 (clobber (match_scratch:SI 0 "=rm"))]
5735 "ix86_match_ccmode (insn, CCGCmode)
5736 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5738 switch (get_attr_type (insn))
5741 if (operands[2] == constm1_rtx)
5742 return "inc{l}\t%0";
5745 gcc_assert (operands[2] == const1_rtx);
5746 return "dec{l}\t%0";
5750 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5751 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5752 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5753 if ((INTVAL (operands[2]) == -128
5754 || (INTVAL (operands[2]) > 0
5755 && INTVAL (operands[2]) != 128)))
5756 return "sub{l}\t{%2, %0|%0, %2}";
5757 operands[2] = GEN_INT (-INTVAL (operands[2]));
5758 return "add{l}\t{%2, %0|%0, %2}";
5762 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5763 (const_string "incdec")
5764 (const_string "alu")))
5765 (set_attr "mode" "SI")])
5767 (define_insn "*addsi_5"
5768 [(set (reg FLAGS_REG)
5770 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5771 (match_operand:SI 2 "general_operand" "rmni"))
5773 (clobber (match_scratch:SI 0 "=r"))]
5774 "ix86_match_ccmode (insn, CCGOCmode)
5775 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5776 /* Current assemblers are broken and do not allow @GOTOFF in
5777 ought but a memory context. */
5778 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5780 switch (get_attr_type (insn))
5783 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5784 if (operands[2] == const1_rtx)
5785 return "inc{l}\t%0";
5788 gcc_assert (operands[2] == constm1_rtx);
5789 return "dec{l}\t%0";
5793 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5794 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5795 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5796 if (GET_CODE (operands[2]) == CONST_INT
5797 && (INTVAL (operands[2]) == 128
5798 || (INTVAL (operands[2]) < 0
5799 && INTVAL (operands[2]) != -128)))
5801 operands[2] = GEN_INT (-INTVAL (operands[2]));
5802 return "sub{l}\t{%2, %0|%0, %2}";
5804 return "add{l}\t{%2, %0|%0, %2}";
5808 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5809 (const_string "incdec")
5810 (const_string "alu")))
5811 (set_attr "mode" "SI")])
5813 (define_expand "addhi3"
5814 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5815 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5816 (match_operand:HI 2 "general_operand" "")))
5817 (clobber (reg:CC FLAGS_REG))])]
5818 "TARGET_HIMODE_MATH"
5819 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5821 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5822 ;; type optimizations enabled by define-splits. This is not important
5823 ;; for PII, and in fact harmful because of partial register stalls.
5825 (define_insn "*addhi_1_lea"
5826 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5827 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5828 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5829 (clobber (reg:CC FLAGS_REG))]
5830 "!TARGET_PARTIAL_REG_STALL
5831 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5833 switch (get_attr_type (insn))
5838 if (operands[2] == const1_rtx)
5839 return "inc{w}\t%0";
5842 gcc_assert (operands[2] == constm1_rtx);
5843 return "dec{w}\t%0";
5847 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5848 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5849 if (GET_CODE (operands[2]) == CONST_INT
5850 && (INTVAL (operands[2]) == 128
5851 || (INTVAL (operands[2]) < 0
5852 && INTVAL (operands[2]) != -128)))
5854 operands[2] = GEN_INT (-INTVAL (operands[2]));
5855 return "sub{w}\t{%2, %0|%0, %2}";
5857 return "add{w}\t{%2, %0|%0, %2}";
5861 (if_then_else (eq_attr "alternative" "2")
5862 (const_string "lea")
5863 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5864 (const_string "incdec")
5865 (const_string "alu"))))
5866 (set_attr "mode" "HI,HI,SI")])
5868 (define_insn "*addhi_1"
5869 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5870 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5871 (match_operand:HI 2 "general_operand" "ri,rm")))
5872 (clobber (reg:CC FLAGS_REG))]
5873 "TARGET_PARTIAL_REG_STALL
5874 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5876 switch (get_attr_type (insn))
5879 if (operands[2] == const1_rtx)
5880 return "inc{w}\t%0";
5883 gcc_assert (operands[2] == constm1_rtx);
5884 return "dec{w}\t%0";
5888 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5889 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5890 if (GET_CODE (operands[2]) == CONST_INT
5891 && (INTVAL (operands[2]) == 128
5892 || (INTVAL (operands[2]) < 0
5893 && INTVAL (operands[2]) != -128)))
5895 operands[2] = GEN_INT (-INTVAL (operands[2]));
5896 return "sub{w}\t{%2, %0|%0, %2}";
5898 return "add{w}\t{%2, %0|%0, %2}";
5902 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5903 (const_string "incdec")
5904 (const_string "alu")))
5905 (set_attr "mode" "HI")])
5907 (define_insn "*addhi_2"
5908 [(set (reg FLAGS_REG)
5910 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5911 (match_operand:HI 2 "general_operand" "rmni,rni"))
5913 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5914 (plus:HI (match_dup 1) (match_dup 2)))]
5915 "ix86_match_ccmode (insn, CCGOCmode)
5916 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5918 switch (get_attr_type (insn))
5921 if (operands[2] == const1_rtx)
5922 return "inc{w}\t%0";
5925 gcc_assert (operands[2] == constm1_rtx);
5926 return "dec{w}\t%0";
5930 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5931 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5932 if (GET_CODE (operands[2]) == CONST_INT
5933 && (INTVAL (operands[2]) == 128
5934 || (INTVAL (operands[2]) < 0
5935 && INTVAL (operands[2]) != -128)))
5937 operands[2] = GEN_INT (-INTVAL (operands[2]));
5938 return "sub{w}\t{%2, %0|%0, %2}";
5940 return "add{w}\t{%2, %0|%0, %2}";
5944 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5945 (const_string "incdec")
5946 (const_string "alu")))
5947 (set_attr "mode" "HI")])
5949 (define_insn "*addhi_3"
5950 [(set (reg FLAGS_REG)
5951 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5952 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5953 (clobber (match_scratch:HI 0 "=r"))]
5954 "ix86_match_ccmode (insn, CCZmode)
5955 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5957 switch (get_attr_type (insn))
5960 if (operands[2] == const1_rtx)
5961 return "inc{w}\t%0";
5964 gcc_assert (operands[2] == constm1_rtx);
5965 return "dec{w}\t%0";
5969 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5970 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5971 if (GET_CODE (operands[2]) == CONST_INT
5972 && (INTVAL (operands[2]) == 128
5973 || (INTVAL (operands[2]) < 0
5974 && INTVAL (operands[2]) != -128)))
5976 operands[2] = GEN_INT (-INTVAL (operands[2]));
5977 return "sub{w}\t{%2, %0|%0, %2}";
5979 return "add{w}\t{%2, %0|%0, %2}";
5983 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5984 (const_string "incdec")
5985 (const_string "alu")))
5986 (set_attr "mode" "HI")])
5988 ; See comments above addsi_4 for details.
5989 (define_insn "*addhi_4"
5990 [(set (reg FLAGS_REG)
5991 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5992 (match_operand:HI 2 "const_int_operand" "n")))
5993 (clobber (match_scratch:HI 0 "=rm"))]
5994 "ix86_match_ccmode (insn, CCGCmode)
5995 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5997 switch (get_attr_type (insn))
6000 if (operands[2] == constm1_rtx)
6001 return "inc{w}\t%0";
6004 gcc_assert (operands[2] == const1_rtx);
6005 return "dec{w}\t%0";
6009 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6010 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6011 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6012 if ((INTVAL (operands[2]) == -128
6013 || (INTVAL (operands[2]) > 0
6014 && INTVAL (operands[2]) != 128)))
6015 return "sub{w}\t{%2, %0|%0, %2}";
6016 operands[2] = GEN_INT (-INTVAL (operands[2]));
6017 return "add{w}\t{%2, %0|%0, %2}";
6021 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6022 (const_string "incdec")
6023 (const_string "alu")))
6024 (set_attr "mode" "SI")])
6027 (define_insn "*addhi_5"
6028 [(set (reg FLAGS_REG)
6030 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6031 (match_operand:HI 2 "general_operand" "rmni"))
6033 (clobber (match_scratch:HI 0 "=r"))]
6034 "ix86_match_ccmode (insn, CCGOCmode)
6035 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6037 switch (get_attr_type (insn))
6040 if (operands[2] == const1_rtx)
6041 return "inc{w}\t%0";
6044 gcc_assert (operands[2] == constm1_rtx);
6045 return "dec{w}\t%0";
6049 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6050 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6051 if (GET_CODE (operands[2]) == CONST_INT
6052 && (INTVAL (operands[2]) == 128
6053 || (INTVAL (operands[2]) < 0
6054 && INTVAL (operands[2]) != -128)))
6056 operands[2] = GEN_INT (-INTVAL (operands[2]));
6057 return "sub{w}\t{%2, %0|%0, %2}";
6059 return "add{w}\t{%2, %0|%0, %2}";
6063 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6064 (const_string "incdec")
6065 (const_string "alu")))
6066 (set_attr "mode" "HI")])
6068 (define_expand "addqi3"
6069 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6070 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6071 (match_operand:QI 2 "general_operand" "")))
6072 (clobber (reg:CC FLAGS_REG))])]
6073 "TARGET_QIMODE_MATH"
6074 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6076 ;; %%% Potential partial reg stall on alternative 2. What to do?
6077 (define_insn "*addqi_1_lea"
6078 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6079 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6080 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6081 (clobber (reg:CC FLAGS_REG))]
6082 "!TARGET_PARTIAL_REG_STALL
6083 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6085 int widen = (which_alternative == 2);
6086 switch (get_attr_type (insn))
6091 if (operands[2] == const1_rtx)
6092 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6095 gcc_assert (operands[2] == constm1_rtx);
6096 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6100 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6102 if (GET_CODE (operands[2]) == CONST_INT
6103 && (INTVAL (operands[2]) == 128
6104 || (INTVAL (operands[2]) < 0
6105 && INTVAL (operands[2]) != -128)))
6107 operands[2] = GEN_INT (-INTVAL (operands[2]));
6109 return "sub{l}\t{%2, %k0|%k0, %2}";
6111 return "sub{b}\t{%2, %0|%0, %2}";
6114 return "add{l}\t{%k2, %k0|%k0, %k2}";
6116 return "add{b}\t{%2, %0|%0, %2}";
6120 (if_then_else (eq_attr "alternative" "3")
6121 (const_string "lea")
6122 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6123 (const_string "incdec")
6124 (const_string "alu"))))
6125 (set_attr "mode" "QI,QI,SI,SI")])
6127 (define_insn "*addqi_1"
6128 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6129 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6130 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6131 (clobber (reg:CC FLAGS_REG))]
6132 "TARGET_PARTIAL_REG_STALL
6133 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6135 int widen = (which_alternative == 2);
6136 switch (get_attr_type (insn))
6139 if (operands[2] == const1_rtx)
6140 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6143 gcc_assert (operands[2] == constm1_rtx);
6144 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6148 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6149 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6150 if (GET_CODE (operands[2]) == CONST_INT
6151 && (INTVAL (operands[2]) == 128
6152 || (INTVAL (operands[2]) < 0
6153 && INTVAL (operands[2]) != -128)))
6155 operands[2] = GEN_INT (-INTVAL (operands[2]));
6157 return "sub{l}\t{%2, %k0|%k0, %2}";
6159 return "sub{b}\t{%2, %0|%0, %2}";
6162 return "add{l}\t{%k2, %k0|%k0, %k2}";
6164 return "add{b}\t{%2, %0|%0, %2}";
6168 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6169 (const_string "incdec")
6170 (const_string "alu")))
6171 (set_attr "mode" "QI,QI,SI")])
6173 (define_insn "*addqi_1_slp"
6174 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6175 (plus:QI (match_dup 0)
6176 (match_operand:QI 1 "general_operand" "qn,qnm")))
6177 (clobber (reg:CC FLAGS_REG))]
6178 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6179 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6181 switch (get_attr_type (insn))
6184 if (operands[1] == const1_rtx)
6185 return "inc{b}\t%0";
6188 gcc_assert (operands[1] == constm1_rtx);
6189 return "dec{b}\t%0";
6193 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6194 if (GET_CODE (operands[1]) == CONST_INT
6195 && INTVAL (operands[1]) < 0)
6197 operands[1] = GEN_INT (-INTVAL (operands[1]));
6198 return "sub{b}\t{%1, %0|%0, %1}";
6200 return "add{b}\t{%1, %0|%0, %1}";
6204 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6205 (const_string "incdec")
6206 (const_string "alu1")))
6207 (set (attr "memory")
6208 (if_then_else (match_operand 1 "memory_operand" "")
6209 (const_string "load")
6210 (const_string "none")))
6211 (set_attr "mode" "QI")])
6213 (define_insn "*addqi_2"
6214 [(set (reg FLAGS_REG)
6216 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6217 (match_operand:QI 2 "general_operand" "qmni,qni"))
6219 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6220 (plus:QI (match_dup 1) (match_dup 2)))]
6221 "ix86_match_ccmode (insn, CCGOCmode)
6222 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6224 switch (get_attr_type (insn))
6227 if (operands[2] == const1_rtx)
6228 return "inc{b}\t%0";
6231 gcc_assert (operands[2] == constm1_rtx
6232 || (GET_CODE (operands[2]) == CONST_INT
6233 && INTVAL (operands[2]) == 255));
6234 return "dec{b}\t%0";
6238 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6239 if (GET_CODE (operands[2]) == CONST_INT
6240 && INTVAL (operands[2]) < 0)
6242 operands[2] = GEN_INT (-INTVAL (operands[2]));
6243 return "sub{b}\t{%2, %0|%0, %2}";
6245 return "add{b}\t{%2, %0|%0, %2}";
6249 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6250 (const_string "incdec")
6251 (const_string "alu")))
6252 (set_attr "mode" "QI")])
6254 (define_insn "*addqi_3"
6255 [(set (reg FLAGS_REG)
6256 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6257 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6258 (clobber (match_scratch:QI 0 "=q"))]
6259 "ix86_match_ccmode (insn, CCZmode)
6260 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6262 switch (get_attr_type (insn))
6265 if (operands[2] == const1_rtx)
6266 return "inc{b}\t%0";
6269 gcc_assert (operands[2] == constm1_rtx
6270 || (GET_CODE (operands[2]) == CONST_INT
6271 && INTVAL (operands[2]) == 255));
6272 return "dec{b}\t%0";
6276 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6277 if (GET_CODE (operands[2]) == CONST_INT
6278 && INTVAL (operands[2]) < 0)
6280 operands[2] = GEN_INT (-INTVAL (operands[2]));
6281 return "sub{b}\t{%2, %0|%0, %2}";
6283 return "add{b}\t{%2, %0|%0, %2}";
6287 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6288 (const_string "incdec")
6289 (const_string "alu")))
6290 (set_attr "mode" "QI")])
6292 ; See comments above addsi_4 for details.
6293 (define_insn "*addqi_4"
6294 [(set (reg FLAGS_REG)
6295 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6296 (match_operand:QI 2 "const_int_operand" "n")))
6297 (clobber (match_scratch:QI 0 "=qm"))]
6298 "ix86_match_ccmode (insn, CCGCmode)
6299 && (INTVAL (operands[2]) & 0xff) != 0x80"
6301 switch (get_attr_type (insn))
6304 if (operands[2] == constm1_rtx
6305 || (GET_CODE (operands[2]) == CONST_INT
6306 && INTVAL (operands[2]) == 255))
6307 return "inc{b}\t%0";
6310 gcc_assert (operands[2] == const1_rtx);
6311 return "dec{b}\t%0";
6315 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6316 if (INTVAL (operands[2]) < 0)
6318 operands[2] = GEN_INT (-INTVAL (operands[2]));
6319 return "add{b}\t{%2, %0|%0, %2}";
6321 return "sub{b}\t{%2, %0|%0, %2}";
6325 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6326 (const_string "incdec")
6327 (const_string "alu")))
6328 (set_attr "mode" "QI")])
6331 (define_insn "*addqi_5"
6332 [(set (reg FLAGS_REG)
6334 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6335 (match_operand:QI 2 "general_operand" "qmni"))
6337 (clobber (match_scratch:QI 0 "=q"))]
6338 "ix86_match_ccmode (insn, CCGOCmode)
6339 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6341 switch (get_attr_type (insn))
6344 if (operands[2] == const1_rtx)
6345 return "inc{b}\t%0";
6348 gcc_assert (operands[2] == constm1_rtx
6349 || (GET_CODE (operands[2]) == CONST_INT
6350 && INTVAL (operands[2]) == 255));
6351 return "dec{b}\t%0";
6355 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6356 if (GET_CODE (operands[2]) == CONST_INT
6357 && INTVAL (operands[2]) < 0)
6359 operands[2] = GEN_INT (-INTVAL (operands[2]));
6360 return "sub{b}\t{%2, %0|%0, %2}";
6362 return "add{b}\t{%2, %0|%0, %2}";
6366 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6367 (const_string "incdec")
6368 (const_string "alu")))
6369 (set_attr "mode" "QI")])
6372 (define_insn "addqi_ext_1"
6373 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6378 (match_operand 1 "ext_register_operand" "0")
6381 (match_operand:QI 2 "general_operand" "Qmn")))
6382 (clobber (reg:CC FLAGS_REG))]
6385 switch (get_attr_type (insn))
6388 if (operands[2] == const1_rtx)
6389 return "inc{b}\t%h0";
6392 gcc_assert (operands[2] == constm1_rtx
6393 || (GET_CODE (operands[2]) == CONST_INT
6394 && INTVAL (operands[2]) == 255));
6395 return "dec{b}\t%h0";
6399 return "add{b}\t{%2, %h0|%h0, %2}";
6403 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6404 (const_string "incdec")
6405 (const_string "alu")))
6406 (set_attr "mode" "QI")])
6408 (define_insn "*addqi_ext_1_rex64"
6409 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6414 (match_operand 1 "ext_register_operand" "0")
6417 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6418 (clobber (reg:CC FLAGS_REG))]
6421 switch (get_attr_type (insn))
6424 if (operands[2] == const1_rtx)
6425 return "inc{b}\t%h0";
6428 gcc_assert (operands[2] == constm1_rtx
6429 || (GET_CODE (operands[2]) == CONST_INT
6430 && INTVAL (operands[2]) == 255));
6431 return "dec{b}\t%h0";
6435 return "add{b}\t{%2, %h0|%h0, %2}";
6439 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6440 (const_string "incdec")
6441 (const_string "alu")))
6442 (set_attr "mode" "QI")])
6444 (define_insn "*addqi_ext_2"
6445 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6450 (match_operand 1 "ext_register_operand" "%0")
6454 (match_operand 2 "ext_register_operand" "Q")
6457 (clobber (reg:CC FLAGS_REG))]
6459 "add{b}\t{%h2, %h0|%h0, %h2}"
6460 [(set_attr "type" "alu")
6461 (set_attr "mode" "QI")])
6463 ;; The patterns that match these are at the end of this file.
6465 (define_expand "addxf3"
6466 [(set (match_operand:XF 0 "register_operand" "")
6467 (plus:XF (match_operand:XF 1 "register_operand" "")
6468 (match_operand:XF 2 "register_operand" "")))]
6472 (define_expand "adddf3"
6473 [(set (match_operand:DF 0 "register_operand" "")
6474 (plus:DF (match_operand:DF 1 "register_operand" "")
6475 (match_operand:DF 2 "nonimmediate_operand" "")))]
6476 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6479 (define_expand "addsf3"
6480 [(set (match_operand:SF 0 "register_operand" "")
6481 (plus:SF (match_operand:SF 1 "register_operand" "")
6482 (match_operand:SF 2 "nonimmediate_operand" "")))]
6483 "TARGET_80387 || TARGET_SSE_MATH"
6486 ;; Subtract instructions
6488 ;; %%% splits for subditi3
6490 (define_expand "subti3"
6491 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6492 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6493 (match_operand:TI 2 "x86_64_general_operand" "")))
6494 (clobber (reg:CC FLAGS_REG))])]
6496 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6498 (define_insn "*subti3_1"
6499 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6500 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6501 (match_operand:TI 2 "general_operand" "roiF,riF")))
6502 (clobber (reg:CC FLAGS_REG))]
6503 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6507 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6508 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6509 (match_operand:TI 2 "general_operand" "")))
6510 (clobber (reg:CC FLAGS_REG))]
6511 "TARGET_64BIT && reload_completed"
6512 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6513 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6514 (parallel [(set (match_dup 3)
6515 (minus:DI (match_dup 4)
6516 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6518 (clobber (reg:CC FLAGS_REG))])]
6519 "split_ti (operands+0, 1, operands+0, operands+3);
6520 split_ti (operands+1, 1, operands+1, operands+4);
6521 split_ti (operands+2, 1, operands+2, operands+5);")
6523 ;; %%% splits for subsidi3
6525 (define_expand "subdi3"
6526 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6527 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6528 (match_operand:DI 2 "x86_64_general_operand" "")))
6529 (clobber (reg:CC FLAGS_REG))])]
6531 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6533 (define_insn "*subdi3_1"
6534 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6535 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6536 (match_operand:DI 2 "general_operand" "roiF,riF")))
6537 (clobber (reg:CC FLAGS_REG))]
6538 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6542 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6543 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6544 (match_operand:DI 2 "general_operand" "")))
6545 (clobber (reg:CC FLAGS_REG))]
6546 "!TARGET_64BIT && reload_completed"
6547 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6548 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6549 (parallel [(set (match_dup 3)
6550 (minus:SI (match_dup 4)
6551 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6553 (clobber (reg:CC FLAGS_REG))])]
6554 "split_di (operands+0, 1, operands+0, operands+3);
6555 split_di (operands+1, 1, operands+1, operands+4);
6556 split_di (operands+2, 1, operands+2, operands+5);")
6558 (define_insn "subdi3_carry_rex64"
6559 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6560 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6561 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6562 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6563 (clobber (reg:CC FLAGS_REG))]
6564 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6565 "sbb{q}\t{%2, %0|%0, %2}"
6566 [(set_attr "type" "alu")
6567 (set_attr "pent_pair" "pu")
6568 (set_attr "mode" "DI")])
6570 (define_insn "*subdi_1_rex64"
6571 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6572 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6573 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6574 (clobber (reg:CC FLAGS_REG))]
6575 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6576 "sub{q}\t{%2, %0|%0, %2}"
6577 [(set_attr "type" "alu")
6578 (set_attr "mode" "DI")])
6580 (define_insn "*subdi_2_rex64"
6581 [(set (reg FLAGS_REG)
6583 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6584 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6586 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6587 (minus:DI (match_dup 1) (match_dup 2)))]
6588 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6589 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6590 "sub{q}\t{%2, %0|%0, %2}"
6591 [(set_attr "type" "alu")
6592 (set_attr "mode" "DI")])
6594 (define_insn "*subdi_3_rex63"
6595 [(set (reg FLAGS_REG)
6596 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6597 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6598 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6599 (minus:DI (match_dup 1) (match_dup 2)))]
6600 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6601 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6602 "sub{q}\t{%2, %0|%0, %2}"
6603 [(set_attr "type" "alu")
6604 (set_attr "mode" "DI")])
6606 (define_insn "subqi3_carry"
6607 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6608 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6609 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6610 (match_operand:QI 2 "general_operand" "qi,qm"))))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6613 "sbb{b}\t{%2, %0|%0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "pent_pair" "pu")
6616 (set_attr "mode" "QI")])
6618 (define_insn "subhi3_carry"
6619 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6620 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6621 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6622 (match_operand:HI 2 "general_operand" "ri,rm"))))
6623 (clobber (reg:CC FLAGS_REG))]
6624 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6625 "sbb{w}\t{%2, %0|%0, %2}"
6626 [(set_attr "type" "alu")
6627 (set_attr "pent_pair" "pu")
6628 (set_attr "mode" "HI")])
6630 (define_insn "subsi3_carry"
6631 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6632 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6633 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6634 (match_operand:SI 2 "general_operand" "ri,rm"))))
6635 (clobber (reg:CC FLAGS_REG))]
6636 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6637 "sbb{l}\t{%2, %0|%0, %2}"
6638 [(set_attr "type" "alu")
6639 (set_attr "pent_pair" "pu")
6640 (set_attr "mode" "SI")])
6642 (define_insn "subsi3_carry_zext"
6643 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6645 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6646 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6647 (match_operand:SI 2 "general_operand" "ri,rm")))))
6648 (clobber (reg:CC FLAGS_REG))]
6649 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650 "sbb{l}\t{%2, %k0|%k0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "pent_pair" "pu")
6653 (set_attr "mode" "SI")])
6655 (define_expand "subsi3"
6656 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6657 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6658 (match_operand:SI 2 "general_operand" "")))
6659 (clobber (reg:CC FLAGS_REG))])]
6661 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6663 (define_insn "*subsi_1"
6664 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6665 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6666 (match_operand:SI 2 "general_operand" "ri,rm")))
6667 (clobber (reg:CC FLAGS_REG))]
6668 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6669 "sub{l}\t{%2, %0|%0, %2}"
6670 [(set_attr "type" "alu")
6671 (set_attr "mode" "SI")])
6673 (define_insn "*subsi_1_zext"
6674 [(set (match_operand:DI 0 "register_operand" "=r")
6676 (minus:SI (match_operand:SI 1 "register_operand" "0")
6677 (match_operand:SI 2 "general_operand" "rim"))))
6678 (clobber (reg:CC FLAGS_REG))]
6679 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6680 "sub{l}\t{%2, %k0|%k0, %2}"
6681 [(set_attr "type" "alu")
6682 (set_attr "mode" "SI")])
6684 (define_insn "*subsi_2"
6685 [(set (reg FLAGS_REG)
6687 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6688 (match_operand:SI 2 "general_operand" "ri,rm"))
6690 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6691 (minus:SI (match_dup 1) (match_dup 2)))]
6692 "ix86_match_ccmode (insn, CCGOCmode)
6693 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6694 "sub{l}\t{%2, %0|%0, %2}"
6695 [(set_attr "type" "alu")
6696 (set_attr "mode" "SI")])
6698 (define_insn "*subsi_2_zext"
6699 [(set (reg FLAGS_REG)
6701 (minus:SI (match_operand:SI 1 "register_operand" "0")
6702 (match_operand:SI 2 "general_operand" "rim"))
6704 (set (match_operand:DI 0 "register_operand" "=r")
6706 (minus:SI (match_dup 1)
6708 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6709 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6710 "sub{l}\t{%2, %k0|%k0, %2}"
6711 [(set_attr "type" "alu")
6712 (set_attr "mode" "SI")])
6714 (define_insn "*subsi_3"
6715 [(set (reg FLAGS_REG)
6716 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6717 (match_operand:SI 2 "general_operand" "ri,rm")))
6718 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6719 (minus:SI (match_dup 1) (match_dup 2)))]
6720 "ix86_match_ccmode (insn, CCmode)
6721 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6722 "sub{l}\t{%2, %0|%0, %2}"
6723 [(set_attr "type" "alu")
6724 (set_attr "mode" "SI")])
6726 (define_insn "*subsi_3_zext"
6727 [(set (reg FLAGS_REG)
6728 (compare (match_operand:SI 1 "register_operand" "0")
6729 (match_operand:SI 2 "general_operand" "rim")))
6730 (set (match_operand:DI 0 "register_operand" "=r")
6732 (minus:SI (match_dup 1)
6734 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6735 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6736 "sub{l}\t{%2, %1|%1, %2}"
6737 [(set_attr "type" "alu")
6738 (set_attr "mode" "DI")])
6740 (define_expand "subhi3"
6741 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6742 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6743 (match_operand:HI 2 "general_operand" "")))
6744 (clobber (reg:CC FLAGS_REG))])]
6745 "TARGET_HIMODE_MATH"
6746 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6748 (define_insn "*subhi_1"
6749 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6750 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6751 (match_operand:HI 2 "general_operand" "ri,rm")))
6752 (clobber (reg:CC FLAGS_REG))]
6753 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6754 "sub{w}\t{%2, %0|%0, %2}"
6755 [(set_attr "type" "alu")
6756 (set_attr "mode" "HI")])
6758 (define_insn "*subhi_2"
6759 [(set (reg FLAGS_REG)
6761 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6762 (match_operand:HI 2 "general_operand" "ri,rm"))
6764 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6765 (minus:HI (match_dup 1) (match_dup 2)))]
6766 "ix86_match_ccmode (insn, CCGOCmode)
6767 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6768 "sub{w}\t{%2, %0|%0, %2}"
6769 [(set_attr "type" "alu")
6770 (set_attr "mode" "HI")])
6772 (define_insn "*subhi_3"
6773 [(set (reg FLAGS_REG)
6774 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6775 (match_operand:HI 2 "general_operand" "ri,rm")))
6776 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6777 (minus:HI (match_dup 1) (match_dup 2)))]
6778 "ix86_match_ccmode (insn, CCmode)
6779 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6780 "sub{w}\t{%2, %0|%0, %2}"
6781 [(set_attr "type" "alu")
6782 (set_attr "mode" "HI")])
6784 (define_expand "subqi3"
6785 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6786 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6787 (match_operand:QI 2 "general_operand" "")))
6788 (clobber (reg:CC FLAGS_REG))])]
6789 "TARGET_QIMODE_MATH"
6790 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6792 (define_insn "*subqi_1"
6793 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6794 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6795 (match_operand:QI 2 "general_operand" "qn,qmn")))
6796 (clobber (reg:CC FLAGS_REG))]
6797 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6798 "sub{b}\t{%2, %0|%0, %2}"
6799 [(set_attr "type" "alu")
6800 (set_attr "mode" "QI")])
6802 (define_insn "*subqi_1_slp"
6803 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6804 (minus:QI (match_dup 0)
6805 (match_operand:QI 1 "general_operand" "qn,qmn")))
6806 (clobber (reg:CC FLAGS_REG))]
6807 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6808 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6809 "sub{b}\t{%1, %0|%0, %1}"
6810 [(set_attr "type" "alu1")
6811 (set_attr "mode" "QI")])
6813 (define_insn "*subqi_2"
6814 [(set (reg FLAGS_REG)
6816 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6817 (match_operand:QI 2 "general_operand" "qi,qm"))
6819 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6820 (minus:HI (match_dup 1) (match_dup 2)))]
6821 "ix86_match_ccmode (insn, CCGOCmode)
6822 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6823 "sub{b}\t{%2, %0|%0, %2}"
6824 [(set_attr "type" "alu")
6825 (set_attr "mode" "QI")])
6827 (define_insn "*subqi_3"
6828 [(set (reg FLAGS_REG)
6829 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6830 (match_operand:QI 2 "general_operand" "qi,qm")))
6831 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6832 (minus:HI (match_dup 1) (match_dup 2)))]
6833 "ix86_match_ccmode (insn, CCmode)
6834 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6835 "sub{b}\t{%2, %0|%0, %2}"
6836 [(set_attr "type" "alu")
6837 (set_attr "mode" "QI")])
6839 ;; The patterns that match these are at the end of this file.
6841 (define_expand "subxf3"
6842 [(set (match_operand:XF 0 "register_operand" "")
6843 (minus:XF (match_operand:XF 1 "register_operand" "")
6844 (match_operand:XF 2 "register_operand" "")))]
6848 (define_expand "subdf3"
6849 [(set (match_operand:DF 0 "register_operand" "")
6850 (minus:DF (match_operand:DF 1 "register_operand" "")
6851 (match_operand:DF 2 "nonimmediate_operand" "")))]
6852 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6855 (define_expand "subsf3"
6856 [(set (match_operand:SF 0 "register_operand" "")
6857 (minus:SF (match_operand:SF 1 "register_operand" "")
6858 (match_operand:SF 2 "nonimmediate_operand" "")))]
6859 "TARGET_80387 || TARGET_SSE_MATH"
6862 ;; Multiply instructions
6864 (define_expand "muldi3"
6865 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6866 (mult:DI (match_operand:DI 1 "register_operand" "")
6867 (match_operand:DI 2 "x86_64_general_operand" "")))
6868 (clobber (reg:CC FLAGS_REG))])]
6872 (define_insn "*muldi3_1_rex64"
6873 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6874 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6875 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6876 (clobber (reg:CC FLAGS_REG))]
6878 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6880 imul{q}\t{%2, %1, %0|%0, %1, %2}
6881 imul{q}\t{%2, %1, %0|%0, %1, %2}
6882 imul{q}\t{%2, %0|%0, %2}"
6883 [(set_attr "type" "imul")
6884 (set_attr "prefix_0f" "0,0,1")
6885 (set (attr "athlon_decode")
6886 (cond [(eq_attr "cpu" "athlon")
6887 (const_string "vector")
6888 (eq_attr "alternative" "1")
6889 (const_string "vector")
6890 (and (eq_attr "alternative" "2")
6891 (match_operand 1 "memory_operand" ""))
6892 (const_string "vector")]
6893 (const_string "direct")))
6894 (set_attr "mode" "DI")])
6896 (define_expand "mulsi3"
6897 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6898 (mult:SI (match_operand:SI 1 "register_operand" "")
6899 (match_operand:SI 2 "general_operand" "")))
6900 (clobber (reg:CC FLAGS_REG))])]
6904 (define_insn "*mulsi3_1"
6905 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6906 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6907 (match_operand:SI 2 "general_operand" "K,i,mr")))
6908 (clobber (reg:CC FLAGS_REG))]
6909 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6911 imul{l}\t{%2, %1, %0|%0, %1, %2}
6912 imul{l}\t{%2, %1, %0|%0, %1, %2}
6913 imul{l}\t{%2, %0|%0, %2}"
6914 [(set_attr "type" "imul")
6915 (set_attr "prefix_0f" "0,0,1")
6916 (set (attr "athlon_decode")
6917 (cond [(eq_attr "cpu" "athlon")
6918 (const_string "vector")
6919 (eq_attr "alternative" "1")
6920 (const_string "vector")
6921 (and (eq_attr "alternative" "2")
6922 (match_operand 1 "memory_operand" ""))
6923 (const_string "vector")]
6924 (const_string "direct")))
6925 (set_attr "mode" "SI")])
6927 (define_insn "*mulsi3_1_zext"
6928 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6930 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6931 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6932 (clobber (reg:CC FLAGS_REG))]
6934 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6936 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6937 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6938 imul{l}\t{%2, %k0|%k0, %2}"
6939 [(set_attr "type" "imul")
6940 (set_attr "prefix_0f" "0,0,1")
6941 (set (attr "athlon_decode")
6942 (cond [(eq_attr "cpu" "athlon")
6943 (const_string "vector")
6944 (eq_attr "alternative" "1")
6945 (const_string "vector")
6946 (and (eq_attr "alternative" "2")
6947 (match_operand 1 "memory_operand" ""))
6948 (const_string "vector")]
6949 (const_string "direct")))
6950 (set_attr "mode" "SI")])
6952 (define_expand "mulhi3"
6953 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6954 (mult:HI (match_operand:HI 1 "register_operand" "")
6955 (match_operand:HI 2 "general_operand" "")))
6956 (clobber (reg:CC FLAGS_REG))])]
6957 "TARGET_HIMODE_MATH"
6960 (define_insn "*mulhi3_1"
6961 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6962 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6963 (match_operand:HI 2 "general_operand" "K,i,mr")))
6964 (clobber (reg:CC FLAGS_REG))]
6965 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6967 imul{w}\t{%2, %1, %0|%0, %1, %2}
6968 imul{w}\t{%2, %1, %0|%0, %1, %2}
6969 imul{w}\t{%2, %0|%0, %2}"
6970 [(set_attr "type" "imul")
6971 (set_attr "prefix_0f" "0,0,1")
6972 (set (attr "athlon_decode")
6973 (cond [(eq_attr "cpu" "athlon")
6974 (const_string "vector")
6975 (eq_attr "alternative" "1,2")
6976 (const_string "vector")]
6977 (const_string "direct")))
6978 (set_attr "mode" "HI")])
6980 (define_expand "mulqi3"
6981 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6982 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6983 (match_operand:QI 2 "register_operand" "")))
6984 (clobber (reg:CC FLAGS_REG))])]
6985 "TARGET_QIMODE_MATH"
6988 (define_insn "*mulqi3_1"
6989 [(set (match_operand:QI 0 "register_operand" "=a")
6990 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6991 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6992 (clobber (reg:CC FLAGS_REG))]
6994 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6996 [(set_attr "type" "imul")
6997 (set_attr "length_immediate" "0")
6998 (set (attr "athlon_decode")
6999 (if_then_else (eq_attr "cpu" "athlon")
7000 (const_string "vector")
7001 (const_string "direct")))
7002 (set_attr "mode" "QI")])
7004 (define_expand "umulqihi3"
7005 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7006 (mult:HI (zero_extend:HI
7007 (match_operand:QI 1 "nonimmediate_operand" ""))
7009 (match_operand:QI 2 "register_operand" ""))))
7010 (clobber (reg:CC FLAGS_REG))])]
7011 "TARGET_QIMODE_MATH"
7014 (define_insn "*umulqihi3_1"
7015 [(set (match_operand:HI 0 "register_operand" "=a")
7016 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7017 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7018 (clobber (reg:CC FLAGS_REG))]
7020 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7022 [(set_attr "type" "imul")
7023 (set_attr "length_immediate" "0")
7024 (set (attr "athlon_decode")
7025 (if_then_else (eq_attr "cpu" "athlon")
7026 (const_string "vector")
7027 (const_string "direct")))
7028 (set_attr "mode" "QI")])
7030 (define_expand "mulqihi3"
7031 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7032 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7033 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7034 (clobber (reg:CC FLAGS_REG))])]
7035 "TARGET_QIMODE_MATH"
7038 (define_insn "*mulqihi3_insn"
7039 [(set (match_operand:HI 0 "register_operand" "=a")
7040 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7041 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7042 (clobber (reg:CC FLAGS_REG))]
7044 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7046 [(set_attr "type" "imul")
7047 (set_attr "length_immediate" "0")
7048 (set (attr "athlon_decode")
7049 (if_then_else (eq_attr "cpu" "athlon")
7050 (const_string "vector")
7051 (const_string "direct")))
7052 (set_attr "mode" "QI")])
7054 (define_expand "umulditi3"
7055 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7056 (mult:TI (zero_extend:TI
7057 (match_operand:DI 1 "nonimmediate_operand" ""))
7059 (match_operand:DI 2 "register_operand" ""))))
7060 (clobber (reg:CC FLAGS_REG))])]
7064 (define_insn "*umulditi3_insn"
7065 [(set (match_operand:TI 0 "register_operand" "=A")
7066 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7067 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7068 (clobber (reg:CC FLAGS_REG))]
7070 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7072 [(set_attr "type" "imul")
7073 (set_attr "length_immediate" "0")
7074 (set (attr "athlon_decode")
7075 (if_then_else (eq_attr "cpu" "athlon")
7076 (const_string "vector")
7077 (const_string "double")))
7078 (set_attr "mode" "DI")])
7080 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7081 (define_expand "umulsidi3"
7082 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7083 (mult:DI (zero_extend:DI
7084 (match_operand:SI 1 "nonimmediate_operand" ""))
7086 (match_operand:SI 2 "register_operand" ""))))
7087 (clobber (reg:CC FLAGS_REG))])]
7091 (define_insn "*umulsidi3_insn"
7092 [(set (match_operand:DI 0 "register_operand" "=A")
7093 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7094 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7095 (clobber (reg:CC FLAGS_REG))]
7097 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7099 [(set_attr "type" "imul")
7100 (set_attr "length_immediate" "0")
7101 (set (attr "athlon_decode")
7102 (if_then_else (eq_attr "cpu" "athlon")
7103 (const_string "vector")
7104 (const_string "double")))
7105 (set_attr "mode" "SI")])
7107 (define_expand "mulditi3"
7108 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7109 (mult:TI (sign_extend:TI
7110 (match_operand:DI 1 "nonimmediate_operand" ""))
7112 (match_operand:DI 2 "register_operand" ""))))
7113 (clobber (reg:CC FLAGS_REG))])]
7117 (define_insn "*mulditi3_insn"
7118 [(set (match_operand:TI 0 "register_operand" "=A")
7119 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7120 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7121 (clobber (reg:CC FLAGS_REG))]
7123 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7125 [(set_attr "type" "imul")
7126 (set_attr "length_immediate" "0")
7127 (set (attr "athlon_decode")
7128 (if_then_else (eq_attr "cpu" "athlon")
7129 (const_string "vector")
7130 (const_string "double")))
7131 (set_attr "mode" "DI")])
7133 (define_expand "mulsidi3"
7134 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7135 (mult:DI (sign_extend:DI
7136 (match_operand:SI 1 "nonimmediate_operand" ""))
7138 (match_operand:SI 2 "register_operand" ""))))
7139 (clobber (reg:CC FLAGS_REG))])]
7143 (define_insn "*mulsidi3_insn"
7144 [(set (match_operand:DI 0 "register_operand" "=A")
7145 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7146 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7147 (clobber (reg:CC FLAGS_REG))]
7149 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7151 [(set_attr "type" "imul")
7152 (set_attr "length_immediate" "0")
7153 (set (attr "athlon_decode")
7154 (if_then_else (eq_attr "cpu" "athlon")
7155 (const_string "vector")
7156 (const_string "double")))
7157 (set_attr "mode" "SI")])
7159 (define_expand "umuldi3_highpart"
7160 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7163 (mult:TI (zero_extend:TI
7164 (match_operand:DI 1 "nonimmediate_operand" ""))
7166 (match_operand:DI 2 "register_operand" "")))
7168 (clobber (match_scratch:DI 3 ""))
7169 (clobber (reg:CC FLAGS_REG))])]
7173 (define_insn "*umuldi3_highpart_rex64"
7174 [(set (match_operand:DI 0 "register_operand" "=d")
7177 (mult:TI (zero_extend:TI
7178 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7180 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7182 (clobber (match_scratch:DI 3 "=1"))
7183 (clobber (reg:CC FLAGS_REG))]
7185 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7187 [(set_attr "type" "imul")
7188 (set_attr "length_immediate" "0")
7189 (set (attr "athlon_decode")
7190 (if_then_else (eq_attr "cpu" "athlon")
7191 (const_string "vector")
7192 (const_string "double")))
7193 (set_attr "mode" "DI")])
7195 (define_expand "umulsi3_highpart"
7196 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7199 (mult:DI (zero_extend:DI
7200 (match_operand:SI 1 "nonimmediate_operand" ""))
7202 (match_operand:SI 2 "register_operand" "")))
7204 (clobber (match_scratch:SI 3 ""))
7205 (clobber (reg:CC FLAGS_REG))])]
7209 (define_insn "*umulsi3_highpart_insn"
7210 [(set (match_operand:SI 0 "register_operand" "=d")
7213 (mult:DI (zero_extend:DI
7214 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7216 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7218 (clobber (match_scratch:SI 3 "=1"))
7219 (clobber (reg:CC FLAGS_REG))]
7220 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7222 [(set_attr "type" "imul")
7223 (set_attr "length_immediate" "0")
7224 (set (attr "athlon_decode")
7225 (if_then_else (eq_attr "cpu" "athlon")
7226 (const_string "vector")
7227 (const_string "double")))
7228 (set_attr "mode" "SI")])
7230 (define_insn "*umulsi3_highpart_zext"
7231 [(set (match_operand:DI 0 "register_operand" "=d")
7232 (zero_extend:DI (truncate:SI
7234 (mult:DI (zero_extend:DI
7235 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7237 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7239 (clobber (match_scratch:SI 3 "=1"))
7240 (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_expand "smuldi3_highpart"
7253 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7256 (mult:TI (sign_extend:TI
7257 (match_operand:DI 1 "nonimmediate_operand" ""))
7259 (match_operand:DI 2 "register_operand" "")))
7261 (clobber (match_scratch:DI 3 ""))
7262 (clobber (reg:CC FLAGS_REG))])]
7266 (define_insn "*smuldi3_highpart_rex64"
7267 [(set (match_operand:DI 0 "register_operand" "=d")
7270 (mult:TI (sign_extend:TI
7271 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7273 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7275 (clobber (match_scratch:DI 3 "=1"))
7276 (clobber (reg:CC FLAGS_REG))]
7278 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7280 [(set_attr "type" "imul")
7281 (set (attr "athlon_decode")
7282 (if_then_else (eq_attr "cpu" "athlon")
7283 (const_string "vector")
7284 (const_string "double")))
7285 (set_attr "mode" "DI")])
7287 (define_expand "smulsi3_highpart"
7288 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7291 (mult:DI (sign_extend:DI
7292 (match_operand:SI 1 "nonimmediate_operand" ""))
7294 (match_operand:SI 2 "register_operand" "")))
7296 (clobber (match_scratch:SI 3 ""))
7297 (clobber (reg:CC FLAGS_REG))])]
7301 (define_insn "*smulsi3_highpart_insn"
7302 [(set (match_operand:SI 0 "register_operand" "=d")
7305 (mult:DI (sign_extend:DI
7306 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7308 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7310 (clobber (match_scratch:SI 3 "=1"))
7311 (clobber (reg:CC FLAGS_REG))]
7312 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7314 [(set_attr "type" "imul")
7315 (set (attr "athlon_decode")
7316 (if_then_else (eq_attr "cpu" "athlon")
7317 (const_string "vector")
7318 (const_string "double")))
7319 (set_attr "mode" "SI")])
7321 (define_insn "*smulsi3_highpart_zext"
7322 [(set (match_operand:DI 0 "register_operand" "=d")
7323 (zero_extend:DI (truncate:SI
7325 (mult:DI (sign_extend:DI
7326 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7328 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7330 (clobber (match_scratch:SI 3 "=1"))
7331 (clobber (reg:CC FLAGS_REG))]
7333 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7335 [(set_attr "type" "imul")
7336 (set (attr "athlon_decode")
7337 (if_then_else (eq_attr "cpu" "athlon")
7338 (const_string "vector")
7339 (const_string "double")))
7340 (set_attr "mode" "SI")])
7342 ;; The patterns that match these are at the end of this file.
7344 (define_expand "mulxf3"
7345 [(set (match_operand:XF 0 "register_operand" "")
7346 (mult:XF (match_operand:XF 1 "register_operand" "")
7347 (match_operand:XF 2 "register_operand" "")))]
7351 (define_expand "muldf3"
7352 [(set (match_operand:DF 0 "register_operand" "")
7353 (mult:DF (match_operand:DF 1 "register_operand" "")
7354 (match_operand:DF 2 "nonimmediate_operand" "")))]
7355 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7358 (define_expand "mulsf3"
7359 [(set (match_operand:SF 0 "register_operand" "")
7360 (mult:SF (match_operand:SF 1 "register_operand" "")
7361 (match_operand:SF 2 "nonimmediate_operand" "")))]
7362 "TARGET_80387 || TARGET_SSE_MATH"
7365 ;; Divide instructions
7367 (define_insn "divqi3"
7368 [(set (match_operand:QI 0 "register_operand" "=a")
7369 (div:QI (match_operand:HI 1 "register_operand" "0")
7370 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7371 (clobber (reg:CC FLAGS_REG))]
7372 "TARGET_QIMODE_MATH"
7374 [(set_attr "type" "idiv")
7375 (set_attr "mode" "QI")])
7377 (define_insn "udivqi3"
7378 [(set (match_operand:QI 0 "register_operand" "=a")
7379 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7380 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7381 (clobber (reg:CC FLAGS_REG))]
7382 "TARGET_QIMODE_MATH"
7384 [(set_attr "type" "idiv")
7385 (set_attr "mode" "QI")])
7387 ;; The patterns that match these are at the end of this file.
7389 (define_expand "divxf3"
7390 [(set (match_operand:XF 0 "register_operand" "")
7391 (div:XF (match_operand:XF 1 "register_operand" "")
7392 (match_operand:XF 2 "register_operand" "")))]
7396 (define_expand "divdf3"
7397 [(set (match_operand:DF 0 "register_operand" "")
7398 (div:DF (match_operand:DF 1 "register_operand" "")
7399 (match_operand:DF 2 "nonimmediate_operand" "")))]
7400 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7403 (define_expand "divsf3"
7404 [(set (match_operand:SF 0 "register_operand" "")
7405 (div:SF (match_operand:SF 1 "register_operand" "")
7406 (match_operand:SF 2 "nonimmediate_operand" "")))]
7407 "TARGET_80387 || TARGET_SSE_MATH"
7410 ;; Remainder instructions.
7412 (define_expand "divmoddi4"
7413 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7414 (div:DI (match_operand:DI 1 "register_operand" "")
7415 (match_operand:DI 2 "nonimmediate_operand" "")))
7416 (set (match_operand:DI 3 "register_operand" "")
7417 (mod:DI (match_dup 1) (match_dup 2)))
7418 (clobber (reg:CC FLAGS_REG))])]
7422 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7423 ;; Penalize eax case slightly because it results in worse scheduling
7425 (define_insn "*divmoddi4_nocltd_rex64"
7426 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7427 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7428 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7429 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7430 (mod:DI (match_dup 2) (match_dup 3)))
7431 (clobber (reg:CC FLAGS_REG))]
7432 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7434 [(set_attr "type" "multi")])
7436 (define_insn "*divmoddi4_cltd_rex64"
7437 [(set (match_operand:DI 0 "register_operand" "=a")
7438 (div:DI (match_operand:DI 2 "register_operand" "a")
7439 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7440 (set (match_operand:DI 1 "register_operand" "=&d")
7441 (mod:DI (match_dup 2) (match_dup 3)))
7442 (clobber (reg:CC FLAGS_REG))]
7443 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7445 [(set_attr "type" "multi")])
7447 (define_insn "*divmoddi_noext_rex64"
7448 [(set (match_operand:DI 0 "register_operand" "=a")
7449 (div:DI (match_operand:DI 1 "register_operand" "0")
7450 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7451 (set (match_operand:DI 3 "register_operand" "=d")
7452 (mod:DI (match_dup 1) (match_dup 2)))
7453 (use (match_operand:DI 4 "register_operand" "3"))
7454 (clobber (reg:CC FLAGS_REG))]
7457 [(set_attr "type" "idiv")
7458 (set_attr "mode" "DI")])
7461 [(set (match_operand:DI 0 "register_operand" "")
7462 (div:DI (match_operand:DI 1 "register_operand" "")
7463 (match_operand:DI 2 "nonimmediate_operand" "")))
7464 (set (match_operand:DI 3 "register_operand" "")
7465 (mod:DI (match_dup 1) (match_dup 2)))
7466 (clobber (reg:CC FLAGS_REG))]
7467 "TARGET_64BIT && reload_completed"
7468 [(parallel [(set (match_dup 3)
7469 (ashiftrt:DI (match_dup 4) (const_int 63)))
7470 (clobber (reg:CC FLAGS_REG))])
7471 (parallel [(set (match_dup 0)
7472 (div:DI (reg:DI 0) (match_dup 2)))
7474 (mod:DI (reg:DI 0) (match_dup 2)))
7476 (clobber (reg:CC FLAGS_REG))])]
7478 /* Avoid use of cltd in favor of a mov+shift. */
7479 if (!TARGET_USE_CLTD && !optimize_size)
7481 if (true_regnum (operands[1]))
7482 emit_move_insn (operands[0], operands[1]);
7484 emit_move_insn (operands[3], operands[1]);
7485 operands[4] = operands[3];
7489 gcc_assert (!true_regnum (operands[1]));
7490 operands[4] = operands[1];
7495 (define_expand "divmodsi4"
7496 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7497 (div:SI (match_operand:SI 1 "register_operand" "")
7498 (match_operand:SI 2 "nonimmediate_operand" "")))
7499 (set (match_operand:SI 3 "register_operand" "")
7500 (mod:SI (match_dup 1) (match_dup 2)))
7501 (clobber (reg:CC FLAGS_REG))])]
7505 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7506 ;; Penalize eax case slightly because it results in worse scheduling
7508 (define_insn "*divmodsi4_nocltd"
7509 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7510 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7511 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7512 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7513 (mod:SI (match_dup 2) (match_dup 3)))
7514 (clobber (reg:CC FLAGS_REG))]
7515 "!optimize_size && !TARGET_USE_CLTD"
7517 [(set_attr "type" "multi")])
7519 (define_insn "*divmodsi4_cltd"
7520 [(set (match_operand:SI 0 "register_operand" "=a")
7521 (div:SI (match_operand:SI 2 "register_operand" "a")
7522 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7523 (set (match_operand:SI 1 "register_operand" "=&d")
7524 (mod:SI (match_dup 2) (match_dup 3)))
7525 (clobber (reg:CC FLAGS_REG))]
7526 "optimize_size || TARGET_USE_CLTD"
7528 [(set_attr "type" "multi")])
7530 (define_insn "*divmodsi_noext"
7531 [(set (match_operand:SI 0 "register_operand" "=a")
7532 (div:SI (match_operand:SI 1 "register_operand" "0")
7533 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7534 (set (match_operand:SI 3 "register_operand" "=d")
7535 (mod:SI (match_dup 1) (match_dup 2)))
7536 (use (match_operand:SI 4 "register_operand" "3"))
7537 (clobber (reg:CC FLAGS_REG))]
7540 [(set_attr "type" "idiv")
7541 (set_attr "mode" "SI")])
7544 [(set (match_operand:SI 0 "register_operand" "")
7545 (div:SI (match_operand:SI 1 "register_operand" "")
7546 (match_operand:SI 2 "nonimmediate_operand" "")))
7547 (set (match_operand:SI 3 "register_operand" "")
7548 (mod:SI (match_dup 1) (match_dup 2)))
7549 (clobber (reg:CC FLAGS_REG))]
7551 [(parallel [(set (match_dup 3)
7552 (ashiftrt:SI (match_dup 4) (const_int 31)))
7553 (clobber (reg:CC FLAGS_REG))])
7554 (parallel [(set (match_dup 0)
7555 (div:SI (reg:SI 0) (match_dup 2)))
7557 (mod:SI (reg:SI 0) (match_dup 2)))
7559 (clobber (reg:CC FLAGS_REG))])]
7561 /* Avoid use of cltd in favor of a mov+shift. */
7562 if (!TARGET_USE_CLTD && !optimize_size)
7564 if (true_regnum (operands[1]))
7565 emit_move_insn (operands[0], operands[1]);
7567 emit_move_insn (operands[3], operands[1]);
7568 operands[4] = operands[3];
7572 gcc_assert (!true_regnum (operands[1]));
7573 operands[4] = operands[1];
7577 (define_insn "divmodhi4"
7578 [(set (match_operand:HI 0 "register_operand" "=a")
7579 (div:HI (match_operand:HI 1 "register_operand" "0")
7580 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7581 (set (match_operand:HI 3 "register_operand" "=&d")
7582 (mod:HI (match_dup 1) (match_dup 2)))
7583 (clobber (reg:CC FLAGS_REG))]
7584 "TARGET_HIMODE_MATH"
7586 [(set_attr "type" "multi")
7587 (set_attr "length_immediate" "0")
7588 (set_attr "mode" "SI")])
7590 (define_insn "udivmoddi4"
7591 [(set (match_operand:DI 0 "register_operand" "=a")
7592 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7593 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7594 (set (match_operand:DI 3 "register_operand" "=&d")
7595 (umod:DI (match_dup 1) (match_dup 2)))
7596 (clobber (reg:CC FLAGS_REG))]
7598 "xor{q}\t%3, %3\;div{q}\t%2"
7599 [(set_attr "type" "multi")
7600 (set_attr "length_immediate" "0")
7601 (set_attr "mode" "DI")])
7603 (define_insn "*udivmoddi4_noext"
7604 [(set (match_operand:DI 0 "register_operand" "=a")
7605 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7606 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7607 (set (match_operand:DI 3 "register_operand" "=d")
7608 (umod:DI (match_dup 1) (match_dup 2)))
7610 (clobber (reg:CC FLAGS_REG))]
7613 [(set_attr "type" "idiv")
7614 (set_attr "mode" "DI")])
7617 [(set (match_operand:DI 0 "register_operand" "")
7618 (udiv:DI (match_operand:DI 1 "register_operand" "")
7619 (match_operand:DI 2 "nonimmediate_operand" "")))
7620 (set (match_operand:DI 3 "register_operand" "")
7621 (umod:DI (match_dup 1) (match_dup 2)))
7622 (clobber (reg:CC FLAGS_REG))]
7623 "TARGET_64BIT && reload_completed"
7624 [(set (match_dup 3) (const_int 0))
7625 (parallel [(set (match_dup 0)
7626 (udiv:DI (match_dup 1) (match_dup 2)))
7628 (umod:DI (match_dup 1) (match_dup 2)))
7630 (clobber (reg:CC FLAGS_REG))])]
7633 (define_insn "udivmodsi4"
7634 [(set (match_operand:SI 0 "register_operand" "=a")
7635 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7636 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7637 (set (match_operand:SI 3 "register_operand" "=&d")
7638 (umod:SI (match_dup 1) (match_dup 2)))
7639 (clobber (reg:CC FLAGS_REG))]
7641 "xor{l}\t%3, %3\;div{l}\t%2"
7642 [(set_attr "type" "multi")
7643 (set_attr "length_immediate" "0")
7644 (set_attr "mode" "SI")])
7646 (define_insn "*udivmodsi4_noext"
7647 [(set (match_operand:SI 0 "register_operand" "=a")
7648 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7649 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7650 (set (match_operand:SI 3 "register_operand" "=d")
7651 (umod:SI (match_dup 1) (match_dup 2)))
7653 (clobber (reg:CC FLAGS_REG))]
7656 [(set_attr "type" "idiv")
7657 (set_attr "mode" "SI")])
7660 [(set (match_operand:SI 0 "register_operand" "")
7661 (udiv:SI (match_operand:SI 1 "register_operand" "")
7662 (match_operand:SI 2 "nonimmediate_operand" "")))
7663 (set (match_operand:SI 3 "register_operand" "")
7664 (umod:SI (match_dup 1) (match_dup 2)))
7665 (clobber (reg:CC FLAGS_REG))]
7667 [(set (match_dup 3) (const_int 0))
7668 (parallel [(set (match_dup 0)
7669 (udiv:SI (match_dup 1) (match_dup 2)))
7671 (umod:SI (match_dup 1) (match_dup 2)))
7673 (clobber (reg:CC FLAGS_REG))])]
7676 (define_expand "udivmodhi4"
7677 [(set (match_dup 4) (const_int 0))
7678 (parallel [(set (match_operand:HI 0 "register_operand" "")
7679 (udiv:HI (match_operand:HI 1 "register_operand" "")
7680 (match_operand:HI 2 "nonimmediate_operand" "")))
7681 (set (match_operand:HI 3 "register_operand" "")
7682 (umod:HI (match_dup 1) (match_dup 2)))
7684 (clobber (reg:CC FLAGS_REG))])]
7685 "TARGET_HIMODE_MATH"
7686 "operands[4] = gen_reg_rtx (HImode);")
7688 (define_insn "*udivmodhi_noext"
7689 [(set (match_operand:HI 0 "register_operand" "=a")
7690 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7691 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7692 (set (match_operand:HI 3 "register_operand" "=d")
7693 (umod:HI (match_dup 1) (match_dup 2)))
7694 (use (match_operand:HI 4 "register_operand" "3"))
7695 (clobber (reg:CC FLAGS_REG))]
7698 [(set_attr "type" "idiv")
7699 (set_attr "mode" "HI")])
7701 ;; We cannot use div/idiv for double division, because it causes
7702 ;; "division by zero" on the overflow and that's not what we expect
7703 ;; from truncate. Because true (non truncating) double division is
7704 ;; never generated, we can't create this insn anyway.
7707 ; [(set (match_operand:SI 0 "register_operand" "=a")
7709 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7711 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7712 ; (set (match_operand:SI 3 "register_operand" "=d")
7714 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7715 ; (clobber (reg:CC FLAGS_REG))]
7717 ; "div{l}\t{%2, %0|%0, %2}"
7718 ; [(set_attr "type" "idiv")])
7720 ;;- Logical AND instructions
7722 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7723 ;; Note that this excludes ah.
7725 (define_insn "*testdi_1_rex64"
7726 [(set (reg FLAGS_REG)
7728 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7729 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7731 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7732 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7734 test{l}\t{%k1, %k0|%k0, %k1}
7735 test{l}\t{%k1, %k0|%k0, %k1}
7736 test{q}\t{%1, %0|%0, %1}
7737 test{q}\t{%1, %0|%0, %1}
7738 test{q}\t{%1, %0|%0, %1}"
7739 [(set_attr "type" "test")
7740 (set_attr "modrm" "0,1,0,1,1")
7741 (set_attr "mode" "SI,SI,DI,DI,DI")
7742 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7744 (define_insn "testsi_1"
7745 [(set (reg FLAGS_REG)
7747 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7748 (match_operand:SI 1 "general_operand" "in,in,rin"))
7750 "ix86_match_ccmode (insn, CCNOmode)
7751 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7752 "test{l}\t{%1, %0|%0, %1}"
7753 [(set_attr "type" "test")
7754 (set_attr "modrm" "0,1,1")
7755 (set_attr "mode" "SI")
7756 (set_attr "pent_pair" "uv,np,uv")])
7758 (define_expand "testsi_ccno_1"
7759 [(set (reg:CCNO FLAGS_REG)
7761 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7762 (match_operand:SI 1 "nonmemory_operand" ""))
7767 (define_insn "*testhi_1"
7768 [(set (reg FLAGS_REG)
7769 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7770 (match_operand:HI 1 "general_operand" "n,n,rn"))
7772 "ix86_match_ccmode (insn, CCNOmode)
7773 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7774 "test{w}\t{%1, %0|%0, %1}"
7775 [(set_attr "type" "test")
7776 (set_attr "modrm" "0,1,1")
7777 (set_attr "mode" "HI")
7778 (set_attr "pent_pair" "uv,np,uv")])
7780 (define_expand "testqi_ccz_1"
7781 [(set (reg:CCZ FLAGS_REG)
7782 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7783 (match_operand:QI 1 "nonmemory_operand" ""))
7788 (define_insn "*testqi_1_maybe_si"
7789 [(set (reg FLAGS_REG)
7792 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7793 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7795 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7796 && ix86_match_ccmode (insn,
7797 GET_CODE (operands[1]) == CONST_INT
7798 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7800 if (which_alternative == 3)
7802 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7803 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7804 return "test{l}\t{%1, %k0|%k0, %1}";
7806 return "test{b}\t{%1, %0|%0, %1}";
7808 [(set_attr "type" "test")
7809 (set_attr "modrm" "0,1,1,1")
7810 (set_attr "mode" "QI,QI,QI,SI")
7811 (set_attr "pent_pair" "uv,np,uv,np")])
7813 (define_insn "*testqi_1"
7814 [(set (reg FLAGS_REG)
7817 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7818 (match_operand:QI 1 "general_operand" "n,n,qn"))
7820 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7821 && ix86_match_ccmode (insn, CCNOmode)"
7822 "test{b}\t{%1, %0|%0, %1}"
7823 [(set_attr "type" "test")
7824 (set_attr "modrm" "0,1,1")
7825 (set_attr "mode" "QI")
7826 (set_attr "pent_pair" "uv,np,uv")])
7828 (define_expand "testqi_ext_ccno_0"
7829 [(set (reg:CCNO FLAGS_REG)
7833 (match_operand 0 "ext_register_operand" "")
7836 (match_operand 1 "const_int_operand" ""))
7841 (define_insn "*testqi_ext_0"
7842 [(set (reg FLAGS_REG)
7846 (match_operand 0 "ext_register_operand" "Q")
7849 (match_operand 1 "const_int_operand" "n"))
7851 "ix86_match_ccmode (insn, CCNOmode)"
7852 "test{b}\t{%1, %h0|%h0, %1}"
7853 [(set_attr "type" "test")
7854 (set_attr "mode" "QI")
7855 (set_attr "length_immediate" "1")
7856 (set_attr "pent_pair" "np")])
7858 (define_insn "*testqi_ext_1"
7859 [(set (reg FLAGS_REG)
7863 (match_operand 0 "ext_register_operand" "Q")
7867 (match_operand:QI 1 "general_operand" "Qm")))
7869 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7870 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7871 "test{b}\t{%1, %h0|%h0, %1}"
7872 [(set_attr "type" "test")
7873 (set_attr "mode" "QI")])
7875 (define_insn "*testqi_ext_1_rex64"
7876 [(set (reg FLAGS_REG)
7880 (match_operand 0 "ext_register_operand" "Q")
7884 (match_operand:QI 1 "register_operand" "Q")))
7886 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7887 "test{b}\t{%1, %h0|%h0, %1}"
7888 [(set_attr "type" "test")
7889 (set_attr "mode" "QI")])
7891 (define_insn "*testqi_ext_2"
7892 [(set (reg FLAGS_REG)
7896 (match_operand 0 "ext_register_operand" "Q")
7900 (match_operand 1 "ext_register_operand" "Q")
7904 "ix86_match_ccmode (insn, CCNOmode)"
7905 "test{b}\t{%h1, %h0|%h0, %h1}"
7906 [(set_attr "type" "test")
7907 (set_attr "mode" "QI")])
7909 ;; Combine likes to form bit extractions for some tests. Humor it.
7910 (define_insn "*testqi_ext_3"
7911 [(set (reg FLAGS_REG)
7912 (compare (zero_extract:SI
7913 (match_operand 0 "nonimmediate_operand" "rm")
7914 (match_operand:SI 1 "const_int_operand" "")
7915 (match_operand:SI 2 "const_int_operand" ""))
7917 "ix86_match_ccmode (insn, CCNOmode)
7918 && INTVAL (operands[1]) > 0
7919 && INTVAL (operands[2]) >= 0
7920 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7921 && (GET_MODE (operands[0]) == SImode
7922 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7923 || GET_MODE (operands[0]) == HImode
7924 || GET_MODE (operands[0]) == QImode)"
7927 (define_insn "*testqi_ext_3_rex64"
7928 [(set (reg FLAGS_REG)
7929 (compare (zero_extract:DI
7930 (match_operand 0 "nonimmediate_operand" "rm")
7931 (match_operand:DI 1 "const_int_operand" "")
7932 (match_operand:DI 2 "const_int_operand" ""))
7935 && ix86_match_ccmode (insn, CCNOmode)
7936 && INTVAL (operands[1]) > 0
7937 && INTVAL (operands[2]) >= 0
7938 /* Ensure that resulting mask is zero or sign extended operand. */
7939 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7940 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7941 && INTVAL (operands[1]) > 32))
7942 && (GET_MODE (operands[0]) == SImode
7943 || GET_MODE (operands[0]) == DImode
7944 || GET_MODE (operands[0]) == HImode
7945 || GET_MODE (operands[0]) == QImode)"
7949 [(set (match_operand 0 "flags_reg_operand" "")
7950 (match_operator 1 "compare_operator"
7952 (match_operand 2 "nonimmediate_operand" "")
7953 (match_operand 3 "const_int_operand" "")
7954 (match_operand 4 "const_int_operand" ""))
7956 "ix86_match_ccmode (insn, CCNOmode)"
7957 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7959 rtx val = operands[2];
7960 HOST_WIDE_INT len = INTVAL (operands[3]);
7961 HOST_WIDE_INT pos = INTVAL (operands[4]);
7963 enum machine_mode mode, submode;
7965 mode = GET_MODE (val);
7966 if (GET_CODE (val) == MEM)
7968 /* ??? Combine likes to put non-volatile mem extractions in QImode
7969 no matter the size of the test. So find a mode that works. */
7970 if (! MEM_VOLATILE_P (val))
7972 mode = smallest_mode_for_size (pos + len, MODE_INT);
7973 val = adjust_address (val, mode, 0);
7976 else if (GET_CODE (val) == SUBREG
7977 && (submode = GET_MODE (SUBREG_REG (val)),
7978 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7979 && pos + len <= GET_MODE_BITSIZE (submode))
7981 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7983 val = SUBREG_REG (val);
7985 else if (mode == HImode && pos + len <= 8)
7987 /* Small HImode tests can be converted to QImode. */
7989 val = gen_lowpart (QImode, val);
7992 if (len == HOST_BITS_PER_WIDE_INT)
7995 mask = ((HOST_WIDE_INT)1 << len) - 1;
7998 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8001 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8002 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8003 ;; this is relatively important trick.
8004 ;; Do the conversion only post-reload to avoid limiting of the register class
8007 [(set (match_operand 0 "flags_reg_operand" "")
8008 (match_operator 1 "compare_operator"
8009 [(and (match_operand 2 "register_operand" "")
8010 (match_operand 3 "const_int_operand" ""))
8013 && QI_REG_P (operands[2])
8014 && GET_MODE (operands[2]) != QImode
8015 && ((ix86_match_ccmode (insn, CCZmode)
8016 && !(INTVAL (operands[3]) & ~(255 << 8)))
8017 || (ix86_match_ccmode (insn, CCNOmode)
8018 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8021 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8024 "operands[2] = gen_lowpart (SImode, operands[2]);
8025 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8028 [(set (match_operand 0 "flags_reg_operand" "")
8029 (match_operator 1 "compare_operator"
8030 [(and (match_operand 2 "nonimmediate_operand" "")
8031 (match_operand 3 "const_int_operand" ""))
8034 && GET_MODE (operands[2]) != QImode
8035 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8036 && ((ix86_match_ccmode (insn, CCZmode)
8037 && !(INTVAL (operands[3]) & ~255))
8038 || (ix86_match_ccmode (insn, CCNOmode)
8039 && !(INTVAL (operands[3]) & ~127)))"
8041 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8043 "operands[2] = gen_lowpart (QImode, operands[2]);
8044 operands[3] = gen_lowpart (QImode, operands[3]);")
8047 ;; %%% This used to optimize known byte-wide and operations to memory,
8048 ;; and sometimes to QImode registers. If this is considered useful,
8049 ;; it should be done with splitters.
8051 (define_expand "anddi3"
8052 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8053 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8054 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8055 (clobber (reg:CC FLAGS_REG))]
8057 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8059 (define_insn "*anddi_1_rex64"
8060 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8061 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8062 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8063 (clobber (reg:CC FLAGS_REG))]
8064 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8066 switch (get_attr_type (insn))
8070 enum machine_mode mode;
8072 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8073 if (INTVAL (operands[2]) == 0xff)
8077 gcc_assert (INTVAL (operands[2]) == 0xffff);
8081 operands[1] = gen_lowpart (mode, operands[1]);
8083 return "movz{bq|x}\t{%1,%0|%0, %1}";
8085 return "movz{wq|x}\t{%1,%0|%0, %1}";
8089 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8090 if (get_attr_mode (insn) == MODE_SI)
8091 return "and{l}\t{%k2, %k0|%k0, %k2}";
8093 return "and{q}\t{%2, %0|%0, %2}";
8096 [(set_attr "type" "alu,alu,alu,imovx")
8097 (set_attr "length_immediate" "*,*,*,0")
8098 (set_attr "mode" "SI,DI,DI,DI")])
8100 (define_insn "*anddi_2"
8101 [(set (reg FLAGS_REG)
8102 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8103 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8105 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8106 (and:DI (match_dup 1) (match_dup 2)))]
8107 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8108 && ix86_binary_operator_ok (AND, DImode, operands)"
8110 and{l}\t{%k2, %k0|%k0, %k2}
8111 and{q}\t{%2, %0|%0, %2}
8112 and{q}\t{%2, %0|%0, %2}"
8113 [(set_attr "type" "alu")
8114 (set_attr "mode" "SI,DI,DI")])
8116 (define_expand "andsi3"
8117 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8118 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8119 (match_operand:SI 2 "general_operand" "")))
8120 (clobber (reg:CC FLAGS_REG))]
8122 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8124 (define_insn "*andsi_1"
8125 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8126 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8127 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8128 (clobber (reg:CC FLAGS_REG))]
8129 "ix86_binary_operator_ok (AND, SImode, operands)"
8131 switch (get_attr_type (insn))
8135 enum machine_mode mode;
8137 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8138 if (INTVAL (operands[2]) == 0xff)
8142 gcc_assert (INTVAL (operands[2]) == 0xffff);
8146 operands[1] = gen_lowpart (mode, operands[1]);
8148 return "movz{bl|x}\t{%1,%0|%0, %1}";
8150 return "movz{wl|x}\t{%1,%0|%0, %1}";
8154 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8155 return "and{l}\t{%2, %0|%0, %2}";
8158 [(set_attr "type" "alu,alu,imovx")
8159 (set_attr "length_immediate" "*,*,0")
8160 (set_attr "mode" "SI")])
8163 [(set (match_operand 0 "register_operand" "")
8165 (const_int -65536)))
8166 (clobber (reg:CC FLAGS_REG))]
8167 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8168 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8169 "operands[1] = gen_lowpart (HImode, operands[0]);")
8172 [(set (match_operand 0 "ext_register_operand" "")
8175 (clobber (reg:CC FLAGS_REG))]
8176 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8177 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8178 "operands[1] = gen_lowpart (QImode, operands[0]);")
8181 [(set (match_operand 0 "ext_register_operand" "")
8183 (const_int -65281)))
8184 (clobber (reg:CC FLAGS_REG))]
8185 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8186 [(parallel [(set (zero_extract:SI (match_dup 0)
8190 (zero_extract:SI (match_dup 0)
8193 (zero_extract:SI (match_dup 0)
8196 (clobber (reg:CC FLAGS_REG))])]
8197 "operands[0] = gen_lowpart (SImode, operands[0]);")
8199 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8200 (define_insn "*andsi_1_zext"
8201 [(set (match_operand:DI 0 "register_operand" "=r")
8203 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8204 (match_operand:SI 2 "general_operand" "rim"))))
8205 (clobber (reg:CC FLAGS_REG))]
8206 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8207 "and{l}\t{%2, %k0|%k0, %2}"
8208 [(set_attr "type" "alu")
8209 (set_attr "mode" "SI")])
8211 (define_insn "*andsi_2"
8212 [(set (reg FLAGS_REG)
8213 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8214 (match_operand:SI 2 "general_operand" "rim,ri"))
8216 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8217 (and:SI (match_dup 1) (match_dup 2)))]
8218 "ix86_match_ccmode (insn, CCNOmode)
8219 && ix86_binary_operator_ok (AND, SImode, operands)"
8220 "and{l}\t{%2, %0|%0, %2}"
8221 [(set_attr "type" "alu")
8222 (set_attr "mode" "SI")])
8224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8225 (define_insn "*andsi_2_zext"
8226 [(set (reg FLAGS_REG)
8227 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8228 (match_operand:SI 2 "general_operand" "rim"))
8230 (set (match_operand:DI 0 "register_operand" "=r")
8231 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8232 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8233 && ix86_binary_operator_ok (AND, SImode, operands)"
8234 "and{l}\t{%2, %k0|%k0, %2}"
8235 [(set_attr "type" "alu")
8236 (set_attr "mode" "SI")])
8238 (define_expand "andhi3"
8239 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8240 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8241 (match_operand:HI 2 "general_operand" "")))
8242 (clobber (reg:CC FLAGS_REG))]
8243 "TARGET_HIMODE_MATH"
8244 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8246 (define_insn "*andhi_1"
8247 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8248 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8249 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8250 (clobber (reg:CC FLAGS_REG))]
8251 "ix86_binary_operator_ok (AND, HImode, operands)"
8253 switch (get_attr_type (insn))
8256 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8257 gcc_assert (INTVAL (operands[2]) == 0xff);
8258 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8261 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8263 return "and{w}\t{%2, %0|%0, %2}";
8266 [(set_attr "type" "alu,alu,imovx")
8267 (set_attr "length_immediate" "*,*,0")
8268 (set_attr "mode" "HI,HI,SI")])
8270 (define_insn "*andhi_2"
8271 [(set (reg FLAGS_REG)
8272 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8273 (match_operand:HI 2 "general_operand" "rim,ri"))
8275 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8276 (and:HI (match_dup 1) (match_dup 2)))]
8277 "ix86_match_ccmode (insn, CCNOmode)
8278 && ix86_binary_operator_ok (AND, HImode, operands)"
8279 "and{w}\t{%2, %0|%0, %2}"
8280 [(set_attr "type" "alu")
8281 (set_attr "mode" "HI")])
8283 (define_expand "andqi3"
8284 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8285 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8286 (match_operand:QI 2 "general_operand" "")))
8287 (clobber (reg:CC FLAGS_REG))]
8288 "TARGET_QIMODE_MATH"
8289 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8291 ;; %%% Potential partial reg stall on alternative 2. What to do?
8292 (define_insn "*andqi_1"
8293 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8294 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8295 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8296 (clobber (reg:CC FLAGS_REG))]
8297 "ix86_binary_operator_ok (AND, QImode, operands)"
8299 and{b}\t{%2, %0|%0, %2}
8300 and{b}\t{%2, %0|%0, %2}
8301 and{l}\t{%k2, %k0|%k0, %k2}"
8302 [(set_attr "type" "alu")
8303 (set_attr "mode" "QI,QI,SI")])
8305 (define_insn "*andqi_1_slp"
8306 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8307 (and:QI (match_dup 0)
8308 (match_operand:QI 1 "general_operand" "qi,qmi")))
8309 (clobber (reg:CC FLAGS_REG))]
8310 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8311 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8312 "and{b}\t{%1, %0|%0, %1}"
8313 [(set_attr "type" "alu1")
8314 (set_attr "mode" "QI")])
8316 (define_insn "*andqi_2_maybe_si"
8317 [(set (reg FLAGS_REG)
8319 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8320 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8322 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8323 (and:QI (match_dup 1) (match_dup 2)))]
8324 "ix86_binary_operator_ok (AND, QImode, operands)
8325 && ix86_match_ccmode (insn,
8326 GET_CODE (operands[2]) == CONST_INT
8327 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8329 if (which_alternative == 2)
8331 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8332 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8333 return "and{l}\t{%2, %k0|%k0, %2}";
8335 return "and{b}\t{%2, %0|%0, %2}";
8337 [(set_attr "type" "alu")
8338 (set_attr "mode" "QI,QI,SI")])
8340 (define_insn "*andqi_2"
8341 [(set (reg FLAGS_REG)
8343 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8344 (match_operand:QI 2 "general_operand" "qim,qi"))
8346 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8347 (and:QI (match_dup 1) (match_dup 2)))]
8348 "ix86_match_ccmode (insn, CCNOmode)
8349 && ix86_binary_operator_ok (AND, QImode, operands)"
8350 "and{b}\t{%2, %0|%0, %2}"
8351 [(set_attr "type" "alu")
8352 (set_attr "mode" "QI")])
8354 (define_insn "*andqi_2_slp"
8355 [(set (reg FLAGS_REG)
8357 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8358 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8360 (set (strict_low_part (match_dup 0))
8361 (and:QI (match_dup 0) (match_dup 1)))]
8362 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8363 && ix86_match_ccmode (insn, CCNOmode)
8364 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8365 "and{b}\t{%1, %0|%0, %1}"
8366 [(set_attr "type" "alu1")
8367 (set_attr "mode" "QI")])
8369 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8370 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8371 ;; for a QImode operand, which of course failed.
8373 (define_insn "andqi_ext_0"
8374 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8379 (match_operand 1 "ext_register_operand" "0")
8382 (match_operand 2 "const_int_operand" "n")))
8383 (clobber (reg:CC FLAGS_REG))]
8385 "and{b}\t{%2, %h0|%h0, %2}"
8386 [(set_attr "type" "alu")
8387 (set_attr "length_immediate" "1")
8388 (set_attr "mode" "QI")])
8390 ;; Generated by peephole translating test to and. This shows up
8391 ;; often in fp comparisons.
8393 (define_insn "*andqi_ext_0_cc"
8394 [(set (reg FLAGS_REG)
8398 (match_operand 1 "ext_register_operand" "0")
8401 (match_operand 2 "const_int_operand" "n"))
8403 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8412 "ix86_match_ccmode (insn, CCNOmode)"
8413 "and{b}\t{%2, %h0|%h0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "length_immediate" "1")
8416 (set_attr "mode" "QI")])
8418 (define_insn "*andqi_ext_1"
8419 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8424 (match_operand 1 "ext_register_operand" "0")
8428 (match_operand:QI 2 "general_operand" "Qm"))))
8429 (clobber (reg:CC FLAGS_REG))]
8431 "and{b}\t{%2, %h0|%h0, %2}"
8432 [(set_attr "type" "alu")
8433 (set_attr "length_immediate" "0")
8434 (set_attr "mode" "QI")])
8436 (define_insn "*andqi_ext_1_rex64"
8437 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8442 (match_operand 1 "ext_register_operand" "0")
8446 (match_operand 2 "ext_register_operand" "Q"))))
8447 (clobber (reg:CC FLAGS_REG))]
8449 "and{b}\t{%2, %h0|%h0, %2}"
8450 [(set_attr "type" "alu")
8451 (set_attr "length_immediate" "0")
8452 (set_attr "mode" "QI")])
8454 (define_insn "*andqi_ext_2"
8455 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8460 (match_operand 1 "ext_register_operand" "%0")
8464 (match_operand 2 "ext_register_operand" "Q")
8467 (clobber (reg:CC FLAGS_REG))]
8469 "and{b}\t{%h2, %h0|%h0, %h2}"
8470 [(set_attr "type" "alu")
8471 (set_attr "length_immediate" "0")
8472 (set_attr "mode" "QI")])
8474 ;; Convert wide AND instructions with immediate operand to shorter QImode
8475 ;; equivalents when possible.
8476 ;; Don't do the splitting with memory operands, since it introduces risk
8477 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8478 ;; for size, but that can (should?) be handled by generic code instead.
8480 [(set (match_operand 0 "register_operand" "")
8481 (and (match_operand 1 "register_operand" "")
8482 (match_operand 2 "const_int_operand" "")))
8483 (clobber (reg:CC FLAGS_REG))]
8485 && QI_REG_P (operands[0])
8486 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8487 && !(~INTVAL (operands[2]) & ~(255 << 8))
8488 && GET_MODE (operands[0]) != QImode"
8489 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8490 (and:SI (zero_extract:SI (match_dup 1)
8491 (const_int 8) (const_int 8))
8493 (clobber (reg:CC FLAGS_REG))])]
8494 "operands[0] = gen_lowpart (SImode, operands[0]);
8495 operands[1] = gen_lowpart (SImode, operands[1]);
8496 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8498 ;; Since AND can be encoded with sign extended immediate, this is only
8499 ;; profitable when 7th bit is not set.
8501 [(set (match_operand 0 "register_operand" "")
8502 (and (match_operand 1 "general_operand" "")
8503 (match_operand 2 "const_int_operand" "")))
8504 (clobber (reg:CC FLAGS_REG))]
8506 && ANY_QI_REG_P (operands[0])
8507 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8508 && !(~INTVAL (operands[2]) & ~255)
8509 && !(INTVAL (operands[2]) & 128)
8510 && GET_MODE (operands[0]) != QImode"
8511 [(parallel [(set (strict_low_part (match_dup 0))
8512 (and:QI (match_dup 1)
8514 (clobber (reg:CC FLAGS_REG))])]
8515 "operands[0] = gen_lowpart (QImode, operands[0]);
8516 operands[1] = gen_lowpart (QImode, operands[1]);
8517 operands[2] = gen_lowpart (QImode, operands[2]);")
8519 ;; Logical inclusive OR instructions
8521 ;; %%% This used to optimize known byte-wide and operations to memory.
8522 ;; If this is considered useful, it should be done with splitters.
8524 (define_expand "iordi3"
8525 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8526 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8527 (match_operand:DI 2 "x86_64_general_operand" "")))
8528 (clobber (reg:CC FLAGS_REG))]
8530 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8532 (define_insn "*iordi_1_rex64"
8533 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8534 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8535 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8536 (clobber (reg:CC FLAGS_REG))]
8538 && ix86_binary_operator_ok (IOR, DImode, operands)"
8539 "or{q}\t{%2, %0|%0, %2}"
8540 [(set_attr "type" "alu")
8541 (set_attr "mode" "DI")])
8543 (define_insn "*iordi_2_rex64"
8544 [(set (reg FLAGS_REG)
8545 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8546 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8548 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8549 (ior:DI (match_dup 1) (match_dup 2)))]
8551 && ix86_match_ccmode (insn, CCNOmode)
8552 && ix86_binary_operator_ok (IOR, DImode, operands)"
8553 "or{q}\t{%2, %0|%0, %2}"
8554 [(set_attr "type" "alu")
8555 (set_attr "mode" "DI")])
8557 (define_insn "*iordi_3_rex64"
8558 [(set (reg FLAGS_REG)
8559 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8560 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8562 (clobber (match_scratch:DI 0 "=r"))]
8564 && ix86_match_ccmode (insn, CCNOmode)
8565 && ix86_binary_operator_ok (IOR, DImode, operands)"
8566 "or{q}\t{%2, %0|%0, %2}"
8567 [(set_attr "type" "alu")
8568 (set_attr "mode" "DI")])
8571 (define_expand "iorsi3"
8572 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8573 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8574 (match_operand:SI 2 "general_operand" "")))
8575 (clobber (reg:CC FLAGS_REG))]
8577 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8579 (define_insn "*iorsi_1"
8580 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8581 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8582 (match_operand:SI 2 "general_operand" "ri,rmi")))
8583 (clobber (reg:CC FLAGS_REG))]
8584 "ix86_binary_operator_ok (IOR, SImode, operands)"
8585 "or{l}\t{%2, %0|%0, %2}"
8586 [(set_attr "type" "alu")
8587 (set_attr "mode" "SI")])
8589 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8590 (define_insn "*iorsi_1_zext"
8591 [(set (match_operand:DI 0 "register_operand" "=rm")
8593 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8594 (match_operand:SI 2 "general_operand" "rim"))))
8595 (clobber (reg:CC FLAGS_REG))]
8596 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8597 "or{l}\t{%2, %k0|%k0, %2}"
8598 [(set_attr "type" "alu")
8599 (set_attr "mode" "SI")])
8601 (define_insn "*iorsi_1_zext_imm"
8602 [(set (match_operand:DI 0 "register_operand" "=rm")
8603 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8604 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8605 (clobber (reg:CC FLAGS_REG))]
8607 "or{l}\t{%2, %k0|%k0, %2}"
8608 [(set_attr "type" "alu")
8609 (set_attr "mode" "SI")])
8611 (define_insn "*iorsi_2"
8612 [(set (reg FLAGS_REG)
8613 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8614 (match_operand:SI 2 "general_operand" "rim,ri"))
8616 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8617 (ior:SI (match_dup 1) (match_dup 2)))]
8618 "ix86_match_ccmode (insn, CCNOmode)
8619 && ix86_binary_operator_ok (IOR, SImode, operands)"
8620 "or{l}\t{%2, %0|%0, %2}"
8621 [(set_attr "type" "alu")
8622 (set_attr "mode" "SI")])
8624 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8625 ;; ??? Special case for immediate operand is missing - it is tricky.
8626 (define_insn "*iorsi_2_zext"
8627 [(set (reg FLAGS_REG)
8628 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8629 (match_operand:SI 2 "general_operand" "rim"))
8631 (set (match_operand:DI 0 "register_operand" "=r")
8632 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8633 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8634 && ix86_binary_operator_ok (IOR, SImode, operands)"
8635 "or{l}\t{%2, %k0|%k0, %2}"
8636 [(set_attr "type" "alu")
8637 (set_attr "mode" "SI")])
8639 (define_insn "*iorsi_2_zext_imm"
8640 [(set (reg FLAGS_REG)
8641 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8642 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8644 (set (match_operand:DI 0 "register_operand" "=r")
8645 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8646 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8647 && ix86_binary_operator_ok (IOR, SImode, operands)"
8648 "or{l}\t{%2, %k0|%k0, %2}"
8649 [(set_attr "type" "alu")
8650 (set_attr "mode" "SI")])
8652 (define_insn "*iorsi_3"
8653 [(set (reg FLAGS_REG)
8654 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8655 (match_operand:SI 2 "general_operand" "rim"))
8657 (clobber (match_scratch:SI 0 "=r"))]
8658 "ix86_match_ccmode (insn, CCNOmode)
8659 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8660 "or{l}\t{%2, %0|%0, %2}"
8661 [(set_attr "type" "alu")
8662 (set_attr "mode" "SI")])
8664 (define_expand "iorhi3"
8665 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8666 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8667 (match_operand:HI 2 "general_operand" "")))
8668 (clobber (reg:CC FLAGS_REG))]
8669 "TARGET_HIMODE_MATH"
8670 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8672 (define_insn "*iorhi_1"
8673 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8674 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8675 (match_operand:HI 2 "general_operand" "rmi,ri")))
8676 (clobber (reg:CC FLAGS_REG))]
8677 "ix86_binary_operator_ok (IOR, HImode, operands)"
8678 "or{w}\t{%2, %0|%0, %2}"
8679 [(set_attr "type" "alu")
8680 (set_attr "mode" "HI")])
8682 (define_insn "*iorhi_2"
8683 [(set (reg FLAGS_REG)
8684 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8685 (match_operand:HI 2 "general_operand" "rim,ri"))
8687 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8688 (ior:HI (match_dup 1) (match_dup 2)))]
8689 "ix86_match_ccmode (insn, CCNOmode)
8690 && ix86_binary_operator_ok (IOR, HImode, operands)"
8691 "or{w}\t{%2, %0|%0, %2}"
8692 [(set_attr "type" "alu")
8693 (set_attr "mode" "HI")])
8695 (define_insn "*iorhi_3"
8696 [(set (reg FLAGS_REG)
8697 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8698 (match_operand:HI 2 "general_operand" "rim"))
8700 (clobber (match_scratch:HI 0 "=r"))]
8701 "ix86_match_ccmode (insn, CCNOmode)
8702 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8703 "or{w}\t{%2, %0|%0, %2}"
8704 [(set_attr "type" "alu")
8705 (set_attr "mode" "HI")])
8707 (define_expand "iorqi3"
8708 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8709 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8710 (match_operand:QI 2 "general_operand" "")))
8711 (clobber (reg:CC FLAGS_REG))]
8712 "TARGET_QIMODE_MATH"
8713 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8715 ;; %%% Potential partial reg stall on alternative 2. What to do?
8716 (define_insn "*iorqi_1"
8717 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8718 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8719 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8720 (clobber (reg:CC FLAGS_REG))]
8721 "ix86_binary_operator_ok (IOR, QImode, operands)"
8723 or{b}\t{%2, %0|%0, %2}
8724 or{b}\t{%2, %0|%0, %2}
8725 or{l}\t{%k2, %k0|%k0, %k2}"
8726 [(set_attr "type" "alu")
8727 (set_attr "mode" "QI,QI,SI")])
8729 (define_insn "*iorqi_1_slp"
8730 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8731 (ior:QI (match_dup 0)
8732 (match_operand:QI 1 "general_operand" "qmi,qi")))
8733 (clobber (reg:CC FLAGS_REG))]
8734 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8735 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8736 "or{b}\t{%1, %0|%0, %1}"
8737 [(set_attr "type" "alu1")
8738 (set_attr "mode" "QI")])
8740 (define_insn "*iorqi_2"
8741 [(set (reg FLAGS_REG)
8742 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8743 (match_operand:QI 2 "general_operand" "qim,qi"))
8745 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8746 (ior:QI (match_dup 1) (match_dup 2)))]
8747 "ix86_match_ccmode (insn, CCNOmode)
8748 && ix86_binary_operator_ok (IOR, QImode, operands)"
8749 "or{b}\t{%2, %0|%0, %2}"
8750 [(set_attr "type" "alu")
8751 (set_attr "mode" "QI")])
8753 (define_insn "*iorqi_2_slp"
8754 [(set (reg FLAGS_REG)
8755 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8756 (match_operand:QI 1 "general_operand" "qim,qi"))
8758 (set (strict_low_part (match_dup 0))
8759 (ior:QI (match_dup 0) (match_dup 1)))]
8760 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8761 && ix86_match_ccmode (insn, CCNOmode)
8762 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8763 "or{b}\t{%1, %0|%0, %1}"
8764 [(set_attr "type" "alu1")
8765 (set_attr "mode" "QI")])
8767 (define_insn "*iorqi_3"
8768 [(set (reg FLAGS_REG)
8769 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8770 (match_operand:QI 2 "general_operand" "qim"))
8772 (clobber (match_scratch:QI 0 "=q"))]
8773 "ix86_match_ccmode (insn, CCNOmode)
8774 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8775 "or{b}\t{%2, %0|%0, %2}"
8776 [(set_attr "type" "alu")
8777 (set_attr "mode" "QI")])
8779 (define_insn "iorqi_ext_0"
8780 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8785 (match_operand 1 "ext_register_operand" "0")
8788 (match_operand 2 "const_int_operand" "n")))
8789 (clobber (reg:CC FLAGS_REG))]
8790 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8791 "or{b}\t{%2, %h0|%h0, %2}"
8792 [(set_attr "type" "alu")
8793 (set_attr "length_immediate" "1")
8794 (set_attr "mode" "QI")])
8796 (define_insn "*iorqi_ext_1"
8797 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8802 (match_operand 1 "ext_register_operand" "0")
8806 (match_operand:QI 2 "general_operand" "Qm"))))
8807 (clobber (reg:CC FLAGS_REG))]
8809 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8810 "or{b}\t{%2, %h0|%h0, %2}"
8811 [(set_attr "type" "alu")
8812 (set_attr "length_immediate" "0")
8813 (set_attr "mode" "QI")])
8815 (define_insn "*iorqi_ext_1_rex64"
8816 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8821 (match_operand 1 "ext_register_operand" "0")
8825 (match_operand 2 "ext_register_operand" "Q"))))
8826 (clobber (reg:CC FLAGS_REG))]
8828 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8829 "or{b}\t{%2, %h0|%h0, %2}"
8830 [(set_attr "type" "alu")
8831 (set_attr "length_immediate" "0")
8832 (set_attr "mode" "QI")])
8834 (define_insn "*iorqi_ext_2"
8835 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8839 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8842 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8845 (clobber (reg:CC FLAGS_REG))]
8846 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8847 "ior{b}\t{%h2, %h0|%h0, %h2}"
8848 [(set_attr "type" "alu")
8849 (set_attr "length_immediate" "0")
8850 (set_attr "mode" "QI")])
8853 [(set (match_operand 0 "register_operand" "")
8854 (ior (match_operand 1 "register_operand" "")
8855 (match_operand 2 "const_int_operand" "")))
8856 (clobber (reg:CC FLAGS_REG))]
8858 && QI_REG_P (operands[0])
8859 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8860 && !(INTVAL (operands[2]) & ~(255 << 8))
8861 && GET_MODE (operands[0]) != QImode"
8862 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8863 (ior:SI (zero_extract:SI (match_dup 1)
8864 (const_int 8) (const_int 8))
8866 (clobber (reg:CC FLAGS_REG))])]
8867 "operands[0] = gen_lowpart (SImode, operands[0]);
8868 operands[1] = gen_lowpart (SImode, operands[1]);
8869 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8871 ;; Since OR can be encoded with sign extended immediate, this is only
8872 ;; profitable when 7th bit is set.
8874 [(set (match_operand 0 "register_operand" "")
8875 (ior (match_operand 1 "general_operand" "")
8876 (match_operand 2 "const_int_operand" "")))
8877 (clobber (reg:CC FLAGS_REG))]
8879 && ANY_QI_REG_P (operands[0])
8880 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8881 && !(INTVAL (operands[2]) & ~255)
8882 && (INTVAL (operands[2]) & 128)
8883 && GET_MODE (operands[0]) != QImode"
8884 [(parallel [(set (strict_low_part (match_dup 0))
8885 (ior:QI (match_dup 1)
8887 (clobber (reg:CC FLAGS_REG))])]
8888 "operands[0] = gen_lowpart (QImode, operands[0]);
8889 operands[1] = gen_lowpart (QImode, operands[1]);
8890 operands[2] = gen_lowpart (QImode, operands[2]);")
8892 ;; Logical XOR instructions
8894 ;; %%% This used to optimize known byte-wide and operations to memory.
8895 ;; If this is considered useful, it should be done with splitters.
8897 (define_expand "xordi3"
8898 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8899 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8900 (match_operand:DI 2 "x86_64_general_operand" "")))
8901 (clobber (reg:CC FLAGS_REG))]
8903 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8905 (define_insn "*xordi_1_rex64"
8906 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8907 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8908 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8909 (clobber (reg:CC FLAGS_REG))]
8911 && ix86_binary_operator_ok (XOR, DImode, operands)"
8913 xor{q}\t{%2, %0|%0, %2}
8914 xor{q}\t{%2, %0|%0, %2}"
8915 [(set_attr "type" "alu")
8916 (set_attr "mode" "DI,DI")])
8918 (define_insn "*xordi_2_rex64"
8919 [(set (reg FLAGS_REG)
8920 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8921 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8923 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8924 (xor:DI (match_dup 1) (match_dup 2)))]
8926 && ix86_match_ccmode (insn, CCNOmode)
8927 && ix86_binary_operator_ok (XOR, DImode, operands)"
8929 xor{q}\t{%2, %0|%0, %2}
8930 xor{q}\t{%2, %0|%0, %2}"
8931 [(set_attr "type" "alu")
8932 (set_attr "mode" "DI,DI")])
8934 (define_insn "*xordi_3_rex64"
8935 [(set (reg FLAGS_REG)
8936 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8937 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8939 (clobber (match_scratch:DI 0 "=r"))]
8941 && ix86_match_ccmode (insn, CCNOmode)
8942 && ix86_binary_operator_ok (XOR, DImode, operands)"
8943 "xor{q}\t{%2, %0|%0, %2}"
8944 [(set_attr "type" "alu")
8945 (set_attr "mode" "DI")])
8947 (define_expand "xorsi3"
8948 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8949 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8950 (match_operand:SI 2 "general_operand" "")))
8951 (clobber (reg:CC FLAGS_REG))]
8953 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8955 (define_insn "*xorsi_1"
8956 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8957 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8958 (match_operand:SI 2 "general_operand" "ri,rm")))
8959 (clobber (reg:CC FLAGS_REG))]
8960 "ix86_binary_operator_ok (XOR, SImode, operands)"
8961 "xor{l}\t{%2, %0|%0, %2}"
8962 [(set_attr "type" "alu")
8963 (set_attr "mode" "SI")])
8965 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8966 ;; Add speccase for immediates
8967 (define_insn "*xorsi_1_zext"
8968 [(set (match_operand:DI 0 "register_operand" "=r")
8970 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8971 (match_operand:SI 2 "general_operand" "rim"))))
8972 (clobber (reg:CC FLAGS_REG))]
8973 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8974 "xor{l}\t{%2, %k0|%k0, %2}"
8975 [(set_attr "type" "alu")
8976 (set_attr "mode" "SI")])
8978 (define_insn "*xorsi_1_zext_imm"
8979 [(set (match_operand:DI 0 "register_operand" "=r")
8980 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8981 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8982 (clobber (reg:CC FLAGS_REG))]
8983 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8984 "xor{l}\t{%2, %k0|%k0, %2}"
8985 [(set_attr "type" "alu")
8986 (set_attr "mode" "SI")])
8988 (define_insn "*xorsi_2"
8989 [(set (reg FLAGS_REG)
8990 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8991 (match_operand:SI 2 "general_operand" "rim,ri"))
8993 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8994 (xor:SI (match_dup 1) (match_dup 2)))]
8995 "ix86_match_ccmode (insn, CCNOmode)
8996 && ix86_binary_operator_ok (XOR, SImode, operands)"
8997 "xor{l}\t{%2, %0|%0, %2}"
8998 [(set_attr "type" "alu")
8999 (set_attr "mode" "SI")])
9001 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9002 ;; ??? Special case for immediate operand is missing - it is tricky.
9003 (define_insn "*xorsi_2_zext"
9004 [(set (reg FLAGS_REG)
9005 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9006 (match_operand:SI 2 "general_operand" "rim"))
9008 (set (match_operand:DI 0 "register_operand" "=r")
9009 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9010 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9011 && ix86_binary_operator_ok (XOR, SImode, operands)"
9012 "xor{l}\t{%2, %k0|%k0, %2}"
9013 [(set_attr "type" "alu")
9014 (set_attr "mode" "SI")])
9016 (define_insn "*xorsi_2_zext_imm"
9017 [(set (reg FLAGS_REG)
9018 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9019 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9021 (set (match_operand:DI 0 "register_operand" "=r")
9022 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9023 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9024 && ix86_binary_operator_ok (XOR, SImode, operands)"
9025 "xor{l}\t{%2, %k0|%k0, %2}"
9026 [(set_attr "type" "alu")
9027 (set_attr "mode" "SI")])
9029 (define_insn "*xorsi_3"
9030 [(set (reg FLAGS_REG)
9031 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9032 (match_operand:SI 2 "general_operand" "rim"))
9034 (clobber (match_scratch:SI 0 "=r"))]
9035 "ix86_match_ccmode (insn, CCNOmode)
9036 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9037 "xor{l}\t{%2, %0|%0, %2}"
9038 [(set_attr "type" "alu")
9039 (set_attr "mode" "SI")])
9041 (define_expand "xorhi3"
9042 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9043 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9044 (match_operand:HI 2 "general_operand" "")))
9045 (clobber (reg:CC FLAGS_REG))]
9046 "TARGET_HIMODE_MATH"
9047 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9049 (define_insn "*xorhi_1"
9050 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9051 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9052 (match_operand:HI 2 "general_operand" "rmi,ri")))
9053 (clobber (reg:CC FLAGS_REG))]
9054 "ix86_binary_operator_ok (XOR, HImode, operands)"
9055 "xor{w}\t{%2, %0|%0, %2}"
9056 [(set_attr "type" "alu")
9057 (set_attr "mode" "HI")])
9059 (define_insn "*xorhi_2"
9060 [(set (reg FLAGS_REG)
9061 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9062 (match_operand:HI 2 "general_operand" "rim,ri"))
9064 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9065 (xor:HI (match_dup 1) (match_dup 2)))]
9066 "ix86_match_ccmode (insn, CCNOmode)
9067 && ix86_binary_operator_ok (XOR, HImode, operands)"
9068 "xor{w}\t{%2, %0|%0, %2}"
9069 [(set_attr "type" "alu")
9070 (set_attr "mode" "HI")])
9072 (define_insn "*xorhi_3"
9073 [(set (reg FLAGS_REG)
9074 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9075 (match_operand:HI 2 "general_operand" "rim"))
9077 (clobber (match_scratch:HI 0 "=r"))]
9078 "ix86_match_ccmode (insn, CCNOmode)
9079 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9080 "xor{w}\t{%2, %0|%0, %2}"
9081 [(set_attr "type" "alu")
9082 (set_attr "mode" "HI")])
9084 (define_expand "xorqi3"
9085 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9086 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9087 (match_operand:QI 2 "general_operand" "")))
9088 (clobber (reg:CC FLAGS_REG))]
9089 "TARGET_QIMODE_MATH"
9090 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9092 ;; %%% Potential partial reg stall on alternative 2. What to do?
9093 (define_insn "*xorqi_1"
9094 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9095 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9096 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9097 (clobber (reg:CC FLAGS_REG))]
9098 "ix86_binary_operator_ok (XOR, QImode, operands)"
9100 xor{b}\t{%2, %0|%0, %2}
9101 xor{b}\t{%2, %0|%0, %2}
9102 xor{l}\t{%k2, %k0|%k0, %k2}"
9103 [(set_attr "type" "alu")
9104 (set_attr "mode" "QI,QI,SI")])
9106 (define_insn "*xorqi_1_slp"
9107 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9108 (xor:QI (match_dup 0)
9109 (match_operand:QI 1 "general_operand" "qi,qmi")))
9110 (clobber (reg:CC FLAGS_REG))]
9111 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9112 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9113 "xor{b}\t{%1, %0|%0, %1}"
9114 [(set_attr "type" "alu1")
9115 (set_attr "mode" "QI")])
9117 (define_insn "xorqi_ext_0"
9118 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9123 (match_operand 1 "ext_register_operand" "0")
9126 (match_operand 2 "const_int_operand" "n")))
9127 (clobber (reg:CC FLAGS_REG))]
9128 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9129 "xor{b}\t{%2, %h0|%h0, %2}"
9130 [(set_attr "type" "alu")
9131 (set_attr "length_immediate" "1")
9132 (set_attr "mode" "QI")])
9134 (define_insn "*xorqi_ext_1"
9135 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9140 (match_operand 1 "ext_register_operand" "0")
9144 (match_operand:QI 2 "general_operand" "Qm"))))
9145 (clobber (reg:CC FLAGS_REG))]
9147 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9148 "xor{b}\t{%2, %h0|%h0, %2}"
9149 [(set_attr "type" "alu")
9150 (set_attr "length_immediate" "0")
9151 (set_attr "mode" "QI")])
9153 (define_insn "*xorqi_ext_1_rex64"
9154 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9159 (match_operand 1 "ext_register_operand" "0")
9163 (match_operand 2 "ext_register_operand" "Q"))))
9164 (clobber (reg:CC FLAGS_REG))]
9166 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9167 "xor{b}\t{%2, %h0|%h0, %2}"
9168 [(set_attr "type" "alu")
9169 (set_attr "length_immediate" "0")
9170 (set_attr "mode" "QI")])
9172 (define_insn "*xorqi_ext_2"
9173 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9177 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9180 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9183 (clobber (reg:CC FLAGS_REG))]
9184 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9185 "xor{b}\t{%h2, %h0|%h0, %h2}"
9186 [(set_attr "type" "alu")
9187 (set_attr "length_immediate" "0")
9188 (set_attr "mode" "QI")])
9190 (define_insn "*xorqi_cc_1"
9191 [(set (reg FLAGS_REG)
9193 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9194 (match_operand:QI 2 "general_operand" "qim,qi"))
9196 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9197 (xor:QI (match_dup 1) (match_dup 2)))]
9198 "ix86_match_ccmode (insn, CCNOmode)
9199 && ix86_binary_operator_ok (XOR, QImode, operands)"
9200 "xor{b}\t{%2, %0|%0, %2}"
9201 [(set_attr "type" "alu")
9202 (set_attr "mode" "QI")])
9204 (define_insn "*xorqi_2_slp"
9205 [(set (reg FLAGS_REG)
9206 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9207 (match_operand:QI 1 "general_operand" "qim,qi"))
9209 (set (strict_low_part (match_dup 0))
9210 (xor:QI (match_dup 0) (match_dup 1)))]
9211 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9212 && ix86_match_ccmode (insn, CCNOmode)
9213 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9214 "xor{b}\t{%1, %0|%0, %1}"
9215 [(set_attr "type" "alu1")
9216 (set_attr "mode" "QI")])
9218 (define_insn "*xorqi_cc_2"
9219 [(set (reg FLAGS_REG)
9221 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9222 (match_operand:QI 2 "general_operand" "qim"))
9224 (clobber (match_scratch:QI 0 "=q"))]
9225 "ix86_match_ccmode (insn, CCNOmode)
9226 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9227 "xor{b}\t{%2, %0|%0, %2}"
9228 [(set_attr "type" "alu")
9229 (set_attr "mode" "QI")])
9231 (define_insn "*xorqi_cc_ext_1"
9232 [(set (reg FLAGS_REG)
9236 (match_operand 1 "ext_register_operand" "0")
9239 (match_operand:QI 2 "general_operand" "qmn"))
9241 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9245 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9247 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9248 "xor{b}\t{%2, %h0|%h0, %2}"
9249 [(set_attr "type" "alu")
9250 (set_attr "mode" "QI")])
9252 (define_insn "*xorqi_cc_ext_1_rex64"
9253 [(set (reg FLAGS_REG)
9257 (match_operand 1 "ext_register_operand" "0")
9260 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9262 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9266 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9268 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9269 "xor{b}\t{%2, %h0|%h0, %2}"
9270 [(set_attr "type" "alu")
9271 (set_attr "mode" "QI")])
9273 (define_expand "xorqi_cc_ext_1"
9275 (set (reg:CCNO FLAGS_REG)
9279 (match_operand 1 "ext_register_operand" "")
9282 (match_operand:QI 2 "general_operand" ""))
9284 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9288 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9294 [(set (match_operand 0 "register_operand" "")
9295 (xor (match_operand 1 "register_operand" "")
9296 (match_operand 2 "const_int_operand" "")))
9297 (clobber (reg:CC FLAGS_REG))]
9299 && QI_REG_P (operands[0])
9300 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9301 && !(INTVAL (operands[2]) & ~(255 << 8))
9302 && GET_MODE (operands[0]) != QImode"
9303 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9304 (xor:SI (zero_extract:SI (match_dup 1)
9305 (const_int 8) (const_int 8))
9307 (clobber (reg:CC FLAGS_REG))])]
9308 "operands[0] = gen_lowpart (SImode, operands[0]);
9309 operands[1] = gen_lowpart (SImode, operands[1]);
9310 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9312 ;; Since XOR can be encoded with sign extended immediate, this is only
9313 ;; profitable when 7th bit is set.
9315 [(set (match_operand 0 "register_operand" "")
9316 (xor (match_operand 1 "general_operand" "")
9317 (match_operand 2 "const_int_operand" "")))
9318 (clobber (reg:CC FLAGS_REG))]
9320 && ANY_QI_REG_P (operands[0])
9321 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9322 && !(INTVAL (operands[2]) & ~255)
9323 && (INTVAL (operands[2]) & 128)
9324 && GET_MODE (operands[0]) != QImode"
9325 [(parallel [(set (strict_low_part (match_dup 0))
9326 (xor:QI (match_dup 1)
9328 (clobber (reg:CC FLAGS_REG))])]
9329 "operands[0] = gen_lowpart (QImode, operands[0]);
9330 operands[1] = gen_lowpart (QImode, operands[1]);
9331 operands[2] = gen_lowpart (QImode, operands[2]);")
9333 ;; Negation instructions
9335 (define_expand "negti2"
9336 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9337 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9338 (clobber (reg:CC FLAGS_REG))])]
9340 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9342 (define_insn "*negti2_1"
9343 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9344 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9345 (clobber (reg:CC FLAGS_REG))]
9347 && ix86_unary_operator_ok (NEG, TImode, operands)"
9351 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9352 (neg:TI (match_operand:TI 1 "general_operand" "")))
9353 (clobber (reg:CC FLAGS_REG))]
9354 "TARGET_64BIT && reload_completed"
9356 [(set (reg:CCZ FLAGS_REG)
9357 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9358 (set (match_dup 0) (neg:DI (match_dup 2)))])
9361 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9364 (clobber (reg:CC FLAGS_REG))])
9367 (neg:DI (match_dup 1)))
9368 (clobber (reg:CC FLAGS_REG))])]
9369 "split_ti (operands+1, 1, operands+2, operands+3);
9370 split_ti (operands+0, 1, operands+0, operands+1);")
9372 (define_expand "negdi2"
9373 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9374 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9375 (clobber (reg:CC FLAGS_REG))])]
9377 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9379 (define_insn "*negdi2_1"
9380 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9381 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9382 (clobber (reg:CC FLAGS_REG))]
9384 && ix86_unary_operator_ok (NEG, DImode, operands)"
9388 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9389 (neg:DI (match_operand:DI 1 "general_operand" "")))
9390 (clobber (reg:CC FLAGS_REG))]
9391 "!TARGET_64BIT && reload_completed"
9393 [(set (reg:CCZ FLAGS_REG)
9394 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9395 (set (match_dup 0) (neg:SI (match_dup 2)))])
9398 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9401 (clobber (reg:CC FLAGS_REG))])
9404 (neg:SI (match_dup 1)))
9405 (clobber (reg:CC FLAGS_REG))])]
9406 "split_di (operands+1, 1, operands+2, operands+3);
9407 split_di (operands+0, 1, operands+0, operands+1);")
9409 (define_insn "*negdi2_1_rex64"
9410 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9411 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9412 (clobber (reg:CC FLAGS_REG))]
9413 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9415 [(set_attr "type" "negnot")
9416 (set_attr "mode" "DI")])
9418 ;; The problem with neg is that it does not perform (compare x 0),
9419 ;; it really performs (compare 0 x), which leaves us with the zero
9420 ;; flag being the only useful item.
9422 (define_insn "*negdi2_cmpz_rex64"
9423 [(set (reg:CCZ FLAGS_REG)
9424 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9426 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9427 (neg:DI (match_dup 1)))]
9428 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9430 [(set_attr "type" "negnot")
9431 (set_attr "mode" "DI")])
9434 (define_expand "negsi2"
9435 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9436 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9437 (clobber (reg:CC FLAGS_REG))])]
9439 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9441 (define_insn "*negsi2_1"
9442 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9443 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9444 (clobber (reg:CC FLAGS_REG))]
9445 "ix86_unary_operator_ok (NEG, SImode, operands)"
9447 [(set_attr "type" "negnot")
9448 (set_attr "mode" "SI")])
9450 ;; Combine is quite creative about this pattern.
9451 (define_insn "*negsi2_1_zext"
9452 [(set (match_operand:DI 0 "register_operand" "=r")
9453 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9456 (clobber (reg:CC FLAGS_REG))]
9457 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9459 [(set_attr "type" "negnot")
9460 (set_attr "mode" "SI")])
9462 ;; The problem with neg is that it does not perform (compare x 0),
9463 ;; it really performs (compare 0 x), which leaves us with the zero
9464 ;; flag being the only useful item.
9466 (define_insn "*negsi2_cmpz"
9467 [(set (reg:CCZ FLAGS_REG)
9468 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9470 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9471 (neg:SI (match_dup 1)))]
9472 "ix86_unary_operator_ok (NEG, SImode, operands)"
9474 [(set_attr "type" "negnot")
9475 (set_attr "mode" "SI")])
9477 (define_insn "*negsi2_cmpz_zext"
9478 [(set (reg:CCZ FLAGS_REG)
9479 (compare:CCZ (lshiftrt:DI
9481 (match_operand:DI 1 "register_operand" "0")
9485 (set (match_operand:DI 0 "register_operand" "=r")
9486 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9489 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9491 [(set_attr "type" "negnot")
9492 (set_attr "mode" "SI")])
9494 (define_expand "neghi2"
9495 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9496 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9497 (clobber (reg:CC FLAGS_REG))])]
9498 "TARGET_HIMODE_MATH"
9499 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9501 (define_insn "*neghi2_1"
9502 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9503 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9504 (clobber (reg:CC FLAGS_REG))]
9505 "ix86_unary_operator_ok (NEG, HImode, operands)"
9507 [(set_attr "type" "negnot")
9508 (set_attr "mode" "HI")])
9510 (define_insn "*neghi2_cmpz"
9511 [(set (reg:CCZ FLAGS_REG)
9512 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9514 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9515 (neg:HI (match_dup 1)))]
9516 "ix86_unary_operator_ok (NEG, HImode, operands)"
9518 [(set_attr "type" "negnot")
9519 (set_attr "mode" "HI")])
9521 (define_expand "negqi2"
9522 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9523 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9524 (clobber (reg:CC FLAGS_REG))])]
9525 "TARGET_QIMODE_MATH"
9526 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9528 (define_insn "*negqi2_1"
9529 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9530 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9531 (clobber (reg:CC FLAGS_REG))]
9532 "ix86_unary_operator_ok (NEG, QImode, operands)"
9534 [(set_attr "type" "negnot")
9535 (set_attr "mode" "QI")])
9537 (define_insn "*negqi2_cmpz"
9538 [(set (reg:CCZ FLAGS_REG)
9539 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9541 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9542 (neg:QI (match_dup 1)))]
9543 "ix86_unary_operator_ok (NEG, QImode, operands)"
9545 [(set_attr "type" "negnot")
9546 (set_attr "mode" "QI")])
9548 ;; Changing of sign for FP values is doable using integer unit too.
9550 (define_expand "negsf2"
9551 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9552 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9553 "TARGET_80387 || TARGET_SSE_MATH"
9554 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9556 (define_expand "abssf2"
9557 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9558 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9559 "TARGET_80387 || TARGET_SSE_MATH"
9560 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9562 (define_insn "*absnegsf2_mixed"
9563 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9564 (match_operator:SF 3 "absneg_operator"
9565 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9566 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9567 (clobber (reg:CC FLAGS_REG))]
9568 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9569 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9572 (define_insn "*absnegsf2_sse"
9573 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9574 (match_operator:SF 3 "absneg_operator"
9575 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9576 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9577 (clobber (reg:CC FLAGS_REG))]
9579 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9582 (define_insn "*absnegsf2_i387"
9583 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9584 (match_operator:SF 3 "absneg_operator"
9585 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9586 (use (match_operand 2 "" ""))
9587 (clobber (reg:CC FLAGS_REG))]
9588 "TARGET_80387 && !TARGET_SSE_MATH
9589 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9592 (define_expand "copysignsf3"
9593 [(match_operand:SF 0 "register_operand" "")
9594 (match_operand:SF 1 "nonmemory_operand" "")
9595 (match_operand:SF 2 "register_operand" "")]
9598 ix86_expand_copysign (operands);
9602 (define_insn_and_split "copysignsf3_const"
9603 [(set (match_operand:SF 0 "register_operand" "=x")
9605 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9606 (match_operand:SF 2 "register_operand" "0")
9607 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9611 "&& reload_completed"
9614 ix86_split_copysign_const (operands);
9618 (define_insn "copysignsf3_var"
9619 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9621 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9622 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9623 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9624 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9626 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9631 [(set (match_operand:SF 0 "register_operand" "")
9633 [(match_operand:SF 2 "register_operand" "")
9634 (match_operand:SF 3 "register_operand" "")
9635 (match_operand:V4SF 4 "" "")
9636 (match_operand:V4SF 5 "" "")]
9638 (clobber (match_scratch:V4SF 1 ""))]
9639 "TARGET_SSE_MATH && reload_completed"
9642 ix86_split_copysign_var (operands);
9646 (define_expand "negdf2"
9647 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9648 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9649 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9650 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9652 (define_expand "absdf2"
9653 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9654 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9655 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9656 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9658 (define_insn "*absnegdf2_mixed"
9659 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9660 (match_operator:DF 3 "absneg_operator"
9661 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9662 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9663 (clobber (reg:CC FLAGS_REG))]
9664 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9665 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9668 (define_insn "*absnegdf2_sse"
9669 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9670 (match_operator:DF 3 "absneg_operator"
9671 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9672 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9673 (clobber (reg:CC FLAGS_REG))]
9674 "TARGET_SSE2 && TARGET_SSE_MATH
9675 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9678 (define_insn "*absnegdf2_i387"
9679 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9680 (match_operator:DF 3 "absneg_operator"
9681 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9682 (use (match_operand 2 "" ""))
9683 (clobber (reg:CC FLAGS_REG))]
9684 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9685 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9688 (define_expand "copysigndf3"
9689 [(match_operand:DF 0 "register_operand" "")
9690 (match_operand:DF 1 "nonmemory_operand" "")
9691 (match_operand:DF 2 "register_operand" "")]
9692 "TARGET_SSE2 && TARGET_SSE_MATH"
9694 ix86_expand_copysign (operands);
9698 (define_insn_and_split "copysigndf3_const"
9699 [(set (match_operand:DF 0 "register_operand" "=x")
9701 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9702 (match_operand:DF 2 "register_operand" "0")
9703 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9705 "TARGET_SSE2 && TARGET_SSE_MATH"
9707 "&& reload_completed"
9710 ix86_split_copysign_const (operands);
9714 (define_insn "copysigndf3_var"
9715 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9717 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9718 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9719 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9720 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9722 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9723 "TARGET_SSE2 && TARGET_SSE_MATH"
9727 [(set (match_operand:DF 0 "register_operand" "")
9729 [(match_operand:DF 2 "register_operand" "")
9730 (match_operand:DF 3 "register_operand" "")
9731 (match_operand:V2DF 4 "" "")
9732 (match_operand:V2DF 5 "" "")]
9734 (clobber (match_scratch:V2DF 1 ""))]
9735 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9738 ix86_split_copysign_var (operands);
9742 (define_expand "negxf2"
9743 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9744 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9746 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9748 (define_expand "absxf2"
9749 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9750 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9752 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9754 (define_insn "*absnegxf2_i387"
9755 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9756 (match_operator:XF 3 "absneg_operator"
9757 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9758 (use (match_operand 2 "" ""))
9759 (clobber (reg:CC FLAGS_REG))]
9761 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9764 ;; Splitters for fp abs and neg.
9767 [(set (match_operand 0 "fp_register_operand" "")
9768 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9769 (use (match_operand 2 "" ""))
9770 (clobber (reg:CC FLAGS_REG))]
9772 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9775 [(set (match_operand 0 "register_operand" "")
9776 (match_operator 3 "absneg_operator"
9777 [(match_operand 1 "register_operand" "")]))
9778 (use (match_operand 2 "nonimmediate_operand" ""))
9779 (clobber (reg:CC FLAGS_REG))]
9780 "reload_completed && SSE_REG_P (operands[0])"
9781 [(set (match_dup 0) (match_dup 3))]
9783 enum machine_mode mode = GET_MODE (operands[0]);
9784 enum machine_mode vmode = GET_MODE (operands[2]);
9787 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9788 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9789 if (operands_match_p (operands[0], operands[2]))
9792 operands[1] = operands[2];
9795 if (GET_CODE (operands[3]) == ABS)
9796 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9798 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9803 [(set (match_operand:SF 0 "register_operand" "")
9804 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9805 (use (match_operand:V4SF 2 "" ""))
9806 (clobber (reg:CC FLAGS_REG))]
9808 [(parallel [(set (match_dup 0) (match_dup 1))
9809 (clobber (reg:CC FLAGS_REG))])]
9812 operands[0] = gen_lowpart (SImode, operands[0]);
9813 if (GET_CODE (operands[1]) == ABS)
9815 tmp = gen_int_mode (0x7fffffff, SImode);
9816 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9820 tmp = gen_int_mode (0x80000000, SImode);
9821 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9827 [(set (match_operand:DF 0 "register_operand" "")
9828 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9829 (use (match_operand 2 "" ""))
9830 (clobber (reg:CC FLAGS_REG))]
9832 [(parallel [(set (match_dup 0) (match_dup 1))
9833 (clobber (reg:CC FLAGS_REG))])]
9838 tmp = gen_lowpart (DImode, operands[0]);
9839 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9842 if (GET_CODE (operands[1]) == ABS)
9845 tmp = gen_rtx_NOT (DImode, tmp);
9849 operands[0] = gen_highpart (SImode, operands[0]);
9850 if (GET_CODE (operands[1]) == ABS)
9852 tmp = gen_int_mode (0x7fffffff, SImode);
9853 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9857 tmp = gen_int_mode (0x80000000, SImode);
9858 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9865 [(set (match_operand:XF 0 "register_operand" "")
9866 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9867 (use (match_operand 2 "" ""))
9868 (clobber (reg:CC FLAGS_REG))]
9870 [(parallel [(set (match_dup 0) (match_dup 1))
9871 (clobber (reg:CC FLAGS_REG))])]
9874 operands[0] = gen_rtx_REG (SImode,
9875 true_regnum (operands[0])
9876 + (TARGET_64BIT ? 1 : 2));
9877 if (GET_CODE (operands[1]) == ABS)
9879 tmp = GEN_INT (0x7fff);
9880 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9884 tmp = GEN_INT (0x8000);
9885 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9891 [(set (match_operand 0 "memory_operand" "")
9892 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9893 (use (match_operand 2 "" ""))
9894 (clobber (reg:CC FLAGS_REG))]
9896 [(parallel [(set (match_dup 0) (match_dup 1))
9897 (clobber (reg:CC FLAGS_REG))])]
9899 enum machine_mode mode = GET_MODE (operands[0]);
9900 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9903 operands[0] = adjust_address (operands[0], QImode, size - 1);
9904 if (GET_CODE (operands[1]) == ABS)
9906 tmp = gen_int_mode (0x7f, QImode);
9907 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9911 tmp = gen_int_mode (0x80, QImode);
9912 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9917 ;; Conditionalize these after reload. If they match before reload, we
9918 ;; lose the clobber and ability to use integer instructions.
9920 (define_insn "*negsf2_1"
9921 [(set (match_operand:SF 0 "register_operand" "=f")
9922 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9923 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9925 [(set_attr "type" "fsgn")
9926 (set_attr "mode" "SF")])
9928 (define_insn "*negdf2_1"
9929 [(set (match_operand:DF 0 "register_operand" "=f")
9930 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9931 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9933 [(set_attr "type" "fsgn")
9934 (set_attr "mode" "DF")])
9936 (define_insn "*negxf2_1"
9937 [(set (match_operand:XF 0 "register_operand" "=f")
9938 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9941 [(set_attr "type" "fsgn")
9942 (set_attr "mode" "XF")])
9944 (define_insn "*abssf2_1"
9945 [(set (match_operand:SF 0 "register_operand" "=f")
9946 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9947 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9949 [(set_attr "type" "fsgn")
9950 (set_attr "mode" "SF")])
9952 (define_insn "*absdf2_1"
9953 [(set (match_operand:DF 0 "register_operand" "=f")
9954 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9955 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9957 [(set_attr "type" "fsgn")
9958 (set_attr "mode" "DF")])
9960 (define_insn "*absxf2_1"
9961 [(set (match_operand:XF 0 "register_operand" "=f")
9962 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9965 [(set_attr "type" "fsgn")
9966 (set_attr "mode" "DF")])
9968 (define_insn "*negextendsfdf2"
9969 [(set (match_operand:DF 0 "register_operand" "=f")
9970 (neg:DF (float_extend:DF
9971 (match_operand:SF 1 "register_operand" "0"))))]
9972 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9974 [(set_attr "type" "fsgn")
9975 (set_attr "mode" "DF")])
9977 (define_insn "*negextenddfxf2"
9978 [(set (match_operand:XF 0 "register_operand" "=f")
9979 (neg:XF (float_extend:XF
9980 (match_operand:DF 1 "register_operand" "0"))))]
9983 [(set_attr "type" "fsgn")
9984 (set_attr "mode" "XF")])
9986 (define_insn "*negextendsfxf2"
9987 [(set (match_operand:XF 0 "register_operand" "=f")
9988 (neg:XF (float_extend:XF
9989 (match_operand:SF 1 "register_operand" "0"))))]
9992 [(set_attr "type" "fsgn")
9993 (set_attr "mode" "XF")])
9995 (define_insn "*absextendsfdf2"
9996 [(set (match_operand:DF 0 "register_operand" "=f")
9997 (abs:DF (float_extend:DF
9998 (match_operand:SF 1 "register_operand" "0"))))]
9999 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10001 [(set_attr "type" "fsgn")
10002 (set_attr "mode" "DF")])
10004 (define_insn "*absextenddfxf2"
10005 [(set (match_operand:XF 0 "register_operand" "=f")
10006 (abs:XF (float_extend:XF
10007 (match_operand:DF 1 "register_operand" "0"))))]
10010 [(set_attr "type" "fsgn")
10011 (set_attr "mode" "XF")])
10013 (define_insn "*absextendsfxf2"
10014 [(set (match_operand:XF 0 "register_operand" "=f")
10015 (abs:XF (float_extend:XF
10016 (match_operand:SF 1 "register_operand" "0"))))]
10019 [(set_attr "type" "fsgn")
10020 (set_attr "mode" "XF")])
10022 ;; One complement instructions
10024 (define_expand "one_cmpldi2"
10025 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10026 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10028 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10030 (define_insn "*one_cmpldi2_1_rex64"
10031 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10032 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10033 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10035 [(set_attr "type" "negnot")
10036 (set_attr "mode" "DI")])
10038 (define_insn "*one_cmpldi2_2_rex64"
10039 [(set (reg FLAGS_REG)
10040 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10042 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10043 (not:DI (match_dup 1)))]
10044 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10045 && ix86_unary_operator_ok (NOT, DImode, operands)"
10047 [(set_attr "type" "alu1")
10048 (set_attr "mode" "DI")])
10051 [(set (match_operand 0 "flags_reg_operand" "")
10052 (match_operator 2 "compare_operator"
10053 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10055 (set (match_operand:DI 1 "nonimmediate_operand" "")
10056 (not:DI (match_dup 3)))]
10057 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10058 [(parallel [(set (match_dup 0)
10060 [(xor:DI (match_dup 3) (const_int -1))
10063 (xor:DI (match_dup 3) (const_int -1)))])]
10066 (define_expand "one_cmplsi2"
10067 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10068 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10070 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10072 (define_insn "*one_cmplsi2_1"
10073 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10074 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10075 "ix86_unary_operator_ok (NOT, SImode, operands)"
10077 [(set_attr "type" "negnot")
10078 (set_attr "mode" "SI")])
10080 ;; ??? Currently never generated - xor is used instead.
10081 (define_insn "*one_cmplsi2_1_zext"
10082 [(set (match_operand:DI 0 "register_operand" "=r")
10083 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10084 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10086 [(set_attr "type" "negnot")
10087 (set_attr "mode" "SI")])
10089 (define_insn "*one_cmplsi2_2"
10090 [(set (reg FLAGS_REG)
10091 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10093 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10094 (not:SI (match_dup 1)))]
10095 "ix86_match_ccmode (insn, CCNOmode)
10096 && ix86_unary_operator_ok (NOT, SImode, operands)"
10098 [(set_attr "type" "alu1")
10099 (set_attr "mode" "SI")])
10102 [(set (match_operand 0 "flags_reg_operand" "")
10103 (match_operator 2 "compare_operator"
10104 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10106 (set (match_operand:SI 1 "nonimmediate_operand" "")
10107 (not:SI (match_dup 3)))]
10108 "ix86_match_ccmode (insn, CCNOmode)"
10109 [(parallel [(set (match_dup 0)
10110 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10113 (xor:SI (match_dup 3) (const_int -1)))])]
10116 ;; ??? Currently never generated - xor is used instead.
10117 (define_insn "*one_cmplsi2_2_zext"
10118 [(set (reg FLAGS_REG)
10119 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10121 (set (match_operand:DI 0 "register_operand" "=r")
10122 (zero_extend:DI (not:SI (match_dup 1))))]
10123 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10124 && ix86_unary_operator_ok (NOT, SImode, operands)"
10126 [(set_attr "type" "alu1")
10127 (set_attr "mode" "SI")])
10130 [(set (match_operand 0 "flags_reg_operand" "")
10131 (match_operator 2 "compare_operator"
10132 [(not:SI (match_operand:SI 3 "register_operand" ""))
10134 (set (match_operand:DI 1 "register_operand" "")
10135 (zero_extend:DI (not:SI (match_dup 3))))]
10136 "ix86_match_ccmode (insn, CCNOmode)"
10137 [(parallel [(set (match_dup 0)
10138 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10141 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10144 (define_expand "one_cmplhi2"
10145 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10146 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10147 "TARGET_HIMODE_MATH"
10148 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10150 (define_insn "*one_cmplhi2_1"
10151 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10152 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10153 "ix86_unary_operator_ok (NOT, HImode, operands)"
10155 [(set_attr "type" "negnot")
10156 (set_attr "mode" "HI")])
10158 (define_insn "*one_cmplhi2_2"
10159 [(set (reg FLAGS_REG)
10160 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10162 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10163 (not:HI (match_dup 1)))]
10164 "ix86_match_ccmode (insn, CCNOmode)
10165 && ix86_unary_operator_ok (NEG, HImode, operands)"
10167 [(set_attr "type" "alu1")
10168 (set_attr "mode" "HI")])
10171 [(set (match_operand 0 "flags_reg_operand" "")
10172 (match_operator 2 "compare_operator"
10173 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10175 (set (match_operand:HI 1 "nonimmediate_operand" "")
10176 (not:HI (match_dup 3)))]
10177 "ix86_match_ccmode (insn, CCNOmode)"
10178 [(parallel [(set (match_dup 0)
10179 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10182 (xor:HI (match_dup 3) (const_int -1)))])]
10185 ;; %%% Potential partial reg stall on alternative 1. What to do?
10186 (define_expand "one_cmplqi2"
10187 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10188 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10189 "TARGET_QIMODE_MATH"
10190 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10192 (define_insn "*one_cmplqi2_1"
10193 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10194 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10195 "ix86_unary_operator_ok (NOT, QImode, operands)"
10199 [(set_attr "type" "negnot")
10200 (set_attr "mode" "QI,SI")])
10202 (define_insn "*one_cmplqi2_2"
10203 [(set (reg FLAGS_REG)
10204 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10206 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10207 (not:QI (match_dup 1)))]
10208 "ix86_match_ccmode (insn, CCNOmode)
10209 && ix86_unary_operator_ok (NOT, QImode, operands)"
10211 [(set_attr "type" "alu1")
10212 (set_attr "mode" "QI")])
10215 [(set (match_operand 0 "flags_reg_operand" "")
10216 (match_operator 2 "compare_operator"
10217 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10219 (set (match_operand:QI 1 "nonimmediate_operand" "")
10220 (not:QI (match_dup 3)))]
10221 "ix86_match_ccmode (insn, CCNOmode)"
10222 [(parallel [(set (match_dup 0)
10223 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10226 (xor:QI (match_dup 3) (const_int -1)))])]
10229 ;; Arithmetic shift instructions
10231 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10232 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10233 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10234 ;; from the assembler input.
10236 ;; This instruction shifts the target reg/mem as usual, but instead of
10237 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10238 ;; is a left shift double, bits are taken from the high order bits of
10239 ;; reg, else if the insn is a shift right double, bits are taken from the
10240 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10241 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10243 ;; Since sh[lr]d does not change the `reg' operand, that is done
10244 ;; separately, making all shifts emit pairs of shift double and normal
10245 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10246 ;; support a 63 bit shift, each shift where the count is in a reg expands
10247 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10249 ;; If the shift count is a constant, we need never emit more than one
10250 ;; shift pair, instead using moves and sign extension for counts greater
10253 (define_expand "ashlti3"
10254 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10255 (ashift:TI (match_operand:TI 1 "register_operand" "")
10256 (match_operand:QI 2 "nonmemory_operand" "")))
10257 (clobber (reg:CC FLAGS_REG))])]
10260 if (! immediate_operand (operands[2], QImode))
10262 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10265 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10269 (define_insn "ashlti3_1"
10270 [(set (match_operand:TI 0 "register_operand" "=r")
10271 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10272 (match_operand:QI 2 "register_operand" "c")))
10273 (clobber (match_scratch:DI 3 "=&r"))
10274 (clobber (reg:CC FLAGS_REG))]
10277 [(set_attr "type" "multi")])
10279 (define_insn "*ashlti3_2"
10280 [(set (match_operand:TI 0 "register_operand" "=r")
10281 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10282 (match_operand:QI 2 "immediate_operand" "O")))
10283 (clobber (reg:CC FLAGS_REG))]
10286 [(set_attr "type" "multi")])
10289 [(set (match_operand:TI 0 "register_operand" "")
10290 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10291 (match_operand:QI 2 "register_operand" "")))
10292 (clobber (match_scratch:DI 3 ""))
10293 (clobber (reg:CC FLAGS_REG))]
10294 "TARGET_64BIT && reload_completed"
10296 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10299 [(set (match_operand:TI 0 "register_operand" "")
10300 (ashift:TI (match_operand:TI 1 "register_operand" "")
10301 (match_operand:QI 2 "immediate_operand" "")))
10302 (clobber (reg:CC FLAGS_REG))]
10303 "TARGET_64BIT && reload_completed"
10305 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10307 (define_insn "x86_64_shld"
10308 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10309 (ior:DI (ashift:DI (match_dup 0)
10310 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10311 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10312 (minus:QI (const_int 64) (match_dup 2)))))
10313 (clobber (reg:CC FLAGS_REG))]
10316 shld{q}\t{%2, %1, %0|%0, %1, %2}
10317 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10318 [(set_attr "type" "ishift")
10319 (set_attr "prefix_0f" "1")
10320 (set_attr "mode" "DI")
10321 (set_attr "athlon_decode" "vector")])
10323 (define_expand "x86_64_shift_adj"
10324 [(set (reg:CCZ FLAGS_REG)
10325 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10328 (set (match_operand:DI 0 "register_operand" "")
10329 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10330 (match_operand:DI 1 "register_operand" "")
10333 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10334 (match_operand:DI 3 "register_operand" "r")
10339 (define_expand "ashldi3"
10340 [(set (match_operand:DI 0 "shiftdi_operand" "")
10341 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10342 (match_operand:QI 2 "nonmemory_operand" "")))]
10344 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10346 (define_insn "*ashldi3_1_rex64"
10347 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10348 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10349 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10350 (clobber (reg:CC FLAGS_REG))]
10351 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10353 switch (get_attr_type (insn))
10356 gcc_assert (operands[2] == const1_rtx);
10357 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10358 return "add{q}\t{%0, %0|%0, %0}";
10361 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10362 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10363 operands[1] = gen_rtx_MULT (DImode, operands[1],
10364 GEN_INT (1 << INTVAL (operands[2])));
10365 return "lea{q}\t{%a1, %0|%0, %a1}";
10368 if (REG_P (operands[2]))
10369 return "sal{q}\t{%b2, %0|%0, %b2}";
10370 else if (operands[2] == const1_rtx
10371 && (TARGET_SHIFT1 || optimize_size))
10372 return "sal{q}\t%0";
10374 return "sal{q}\t{%2, %0|%0, %2}";
10377 [(set (attr "type")
10378 (cond [(eq_attr "alternative" "1")
10379 (const_string "lea")
10380 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10382 (match_operand 0 "register_operand" ""))
10383 (match_operand 2 "const1_operand" ""))
10384 (const_string "alu")
10386 (const_string "ishift")))
10387 (set_attr "mode" "DI")])
10389 ;; Convert lea to the lea pattern to avoid flags dependency.
10391 [(set (match_operand:DI 0 "register_operand" "")
10392 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10393 (match_operand:QI 2 "immediate_operand" "")))
10394 (clobber (reg:CC FLAGS_REG))]
10395 "TARGET_64BIT && reload_completed
10396 && true_regnum (operands[0]) != true_regnum (operands[1])"
10397 [(set (match_dup 0)
10398 (mult:DI (match_dup 1)
10400 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10402 ;; This pattern can't accept a variable shift count, since shifts by
10403 ;; zero don't affect the flags. We assume that shifts by constant
10404 ;; zero are optimized away.
10405 (define_insn "*ashldi3_cmp_rex64"
10406 [(set (reg FLAGS_REG)
10408 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10409 (match_operand:QI 2 "immediate_operand" "e"))
10411 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10412 (ashift:DI (match_dup 1) (match_dup 2)))]
10413 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10414 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10416 || !TARGET_PARTIAL_FLAG_REG_STALL
10417 || (operands[2] == const1_rtx
10419 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10421 switch (get_attr_type (insn))
10424 gcc_assert (operands[2] == const1_rtx);
10425 return "add{q}\t{%0, %0|%0, %0}";
10428 if (REG_P (operands[2]))
10429 return "sal{q}\t{%b2, %0|%0, %b2}";
10430 else if (operands[2] == const1_rtx
10431 && (TARGET_SHIFT1 || optimize_size))
10432 return "sal{q}\t%0";
10434 return "sal{q}\t{%2, %0|%0, %2}";
10437 [(set (attr "type")
10438 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10440 (match_operand 0 "register_operand" ""))
10441 (match_operand 2 "const1_operand" ""))
10442 (const_string "alu")
10444 (const_string "ishift")))
10445 (set_attr "mode" "DI")])
10447 (define_insn "*ashldi3_cconly_rex64"
10448 [(set (reg FLAGS_REG)
10450 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10451 (match_operand:QI 2 "immediate_operand" "e"))
10453 (clobber (match_scratch:DI 0 "=r"))]
10454 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10455 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10457 || !TARGET_PARTIAL_FLAG_REG_STALL
10458 || (operands[2] == const1_rtx
10460 || TARGET_DOUBLE_WITH_ADD)))"
10462 switch (get_attr_type (insn))
10465 gcc_assert (operands[2] == const1_rtx);
10466 return "add{q}\t{%0, %0|%0, %0}";
10469 if (REG_P (operands[2]))
10470 return "sal{q}\t{%b2, %0|%0, %b2}";
10471 else if (operands[2] == const1_rtx
10472 && (TARGET_SHIFT1 || optimize_size))
10473 return "sal{q}\t%0";
10475 return "sal{q}\t{%2, %0|%0, %2}";
10478 [(set (attr "type")
10479 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10481 (match_operand 0 "register_operand" ""))
10482 (match_operand 2 "const1_operand" ""))
10483 (const_string "alu")
10485 (const_string "ishift")))
10486 (set_attr "mode" "DI")])
10488 (define_insn "*ashldi3_1"
10489 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10490 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10491 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10492 (clobber (reg:CC FLAGS_REG))]
10495 [(set_attr "type" "multi")])
10497 ;; By default we don't ask for a scratch register, because when DImode
10498 ;; values are manipulated, registers are already at a premium. But if
10499 ;; we have one handy, we won't turn it away.
10501 [(match_scratch:SI 3 "r")
10502 (parallel [(set (match_operand:DI 0 "register_operand" "")
10503 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10504 (match_operand:QI 2 "nonmemory_operand" "")))
10505 (clobber (reg:CC FLAGS_REG))])
10507 "!TARGET_64BIT && TARGET_CMOVE"
10509 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10512 [(set (match_operand:DI 0 "register_operand" "")
10513 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10514 (match_operand:QI 2 "nonmemory_operand" "")))
10515 (clobber (reg:CC FLAGS_REG))]
10516 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10517 ? flow2_completed : reload_completed)"
10519 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10521 (define_insn "x86_shld_1"
10522 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10523 (ior:SI (ashift:SI (match_dup 0)
10524 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10525 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10526 (minus:QI (const_int 32) (match_dup 2)))))
10527 (clobber (reg:CC FLAGS_REG))]
10530 shld{l}\t{%2, %1, %0|%0, %1, %2}
10531 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10532 [(set_attr "type" "ishift")
10533 (set_attr "prefix_0f" "1")
10534 (set_attr "mode" "SI")
10535 (set_attr "pent_pair" "np")
10536 (set_attr "athlon_decode" "vector")])
10538 (define_expand "x86_shift_adj_1"
10539 [(set (reg:CCZ FLAGS_REG)
10540 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10543 (set (match_operand:SI 0 "register_operand" "")
10544 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10545 (match_operand:SI 1 "register_operand" "")
10548 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10549 (match_operand:SI 3 "register_operand" "r")
10554 (define_expand "x86_shift_adj_2"
10555 [(use (match_operand:SI 0 "register_operand" ""))
10556 (use (match_operand:SI 1 "register_operand" ""))
10557 (use (match_operand:QI 2 "register_operand" ""))]
10560 rtx label = gen_label_rtx ();
10563 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10565 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10566 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10567 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10568 gen_rtx_LABEL_REF (VOIDmode, label),
10570 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10571 JUMP_LABEL (tmp) = label;
10573 emit_move_insn (operands[0], operands[1]);
10574 ix86_expand_clear (operands[1]);
10576 emit_label (label);
10577 LABEL_NUSES (label) = 1;
10582 (define_expand "ashlsi3"
10583 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10584 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10585 (match_operand:QI 2 "nonmemory_operand" "")))
10586 (clobber (reg:CC FLAGS_REG))]
10588 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10590 (define_insn "*ashlsi3_1"
10591 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10592 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10593 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10594 (clobber (reg:CC FLAGS_REG))]
10595 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10597 switch (get_attr_type (insn))
10600 gcc_assert (operands[2] == const1_rtx);
10601 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10602 return "add{l}\t{%0, %0|%0, %0}";
10608 if (REG_P (operands[2]))
10609 return "sal{l}\t{%b2, %0|%0, %b2}";
10610 else if (operands[2] == const1_rtx
10611 && (TARGET_SHIFT1 || optimize_size))
10612 return "sal{l}\t%0";
10614 return "sal{l}\t{%2, %0|%0, %2}";
10617 [(set (attr "type")
10618 (cond [(eq_attr "alternative" "1")
10619 (const_string "lea")
10620 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10622 (match_operand 0 "register_operand" ""))
10623 (match_operand 2 "const1_operand" ""))
10624 (const_string "alu")
10626 (const_string "ishift")))
10627 (set_attr "mode" "SI")])
10629 ;; Convert lea to the lea pattern to avoid flags dependency.
10631 [(set (match_operand 0 "register_operand" "")
10632 (ashift (match_operand 1 "index_register_operand" "")
10633 (match_operand:QI 2 "const_int_operand" "")))
10634 (clobber (reg:CC FLAGS_REG))]
10636 && true_regnum (operands[0]) != true_regnum (operands[1])
10637 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10641 enum machine_mode mode = GET_MODE (operands[0]);
10643 if (GET_MODE_SIZE (mode) < 4)
10644 operands[0] = gen_lowpart (SImode, operands[0]);
10646 operands[1] = gen_lowpart (Pmode, operands[1]);
10647 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10649 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10650 if (Pmode != SImode)
10651 pat = gen_rtx_SUBREG (SImode, pat, 0);
10652 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10656 ;; Rare case of shifting RSP is handled by generating move and shift
10658 [(set (match_operand 0 "register_operand" "")
10659 (ashift (match_operand 1 "register_operand" "")
10660 (match_operand:QI 2 "const_int_operand" "")))
10661 (clobber (reg:CC FLAGS_REG))]
10663 && true_regnum (operands[0]) != true_regnum (operands[1])"
10667 emit_move_insn (operands[0], operands[1]);
10668 pat = gen_rtx_SET (VOIDmode, operands[0],
10669 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10670 operands[0], operands[2]));
10671 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10672 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10676 (define_insn "*ashlsi3_1_zext"
10677 [(set (match_operand:DI 0 "register_operand" "=r,r")
10678 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10679 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10680 (clobber (reg:CC FLAGS_REG))]
10681 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10683 switch (get_attr_type (insn))
10686 gcc_assert (operands[2] == const1_rtx);
10687 return "add{l}\t{%k0, %k0|%k0, %k0}";
10693 if (REG_P (operands[2]))
10694 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10695 else if (operands[2] == const1_rtx
10696 && (TARGET_SHIFT1 || optimize_size))
10697 return "sal{l}\t%k0";
10699 return "sal{l}\t{%2, %k0|%k0, %2}";
10702 [(set (attr "type")
10703 (cond [(eq_attr "alternative" "1")
10704 (const_string "lea")
10705 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10707 (match_operand 2 "const1_operand" ""))
10708 (const_string "alu")
10710 (const_string "ishift")))
10711 (set_attr "mode" "SI")])
10713 ;; Convert lea to the lea pattern to avoid flags dependency.
10715 [(set (match_operand:DI 0 "register_operand" "")
10716 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10717 (match_operand:QI 2 "const_int_operand" ""))))
10718 (clobber (reg:CC FLAGS_REG))]
10719 "TARGET_64BIT && reload_completed
10720 && true_regnum (operands[0]) != true_regnum (operands[1])"
10721 [(set (match_dup 0) (zero_extend:DI
10722 (subreg:SI (mult:SI (match_dup 1)
10723 (match_dup 2)) 0)))]
10725 operands[1] = gen_lowpart (Pmode, operands[1]);
10726 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10729 ;; This pattern can't accept a variable shift count, since shifts by
10730 ;; zero don't affect the flags. We assume that shifts by constant
10731 ;; zero are optimized away.
10732 (define_insn "*ashlsi3_cmp"
10733 [(set (reg FLAGS_REG)
10735 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10736 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10738 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10739 (ashift:SI (match_dup 1) (match_dup 2)))]
10740 "ix86_match_ccmode (insn, CCGOCmode)
10741 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10743 || !TARGET_PARTIAL_FLAG_REG_STALL
10744 || (operands[2] == const1_rtx
10746 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10748 switch (get_attr_type (insn))
10751 gcc_assert (operands[2] == const1_rtx);
10752 return "add{l}\t{%0, %0|%0, %0}";
10755 if (REG_P (operands[2]))
10756 return "sal{l}\t{%b2, %0|%0, %b2}";
10757 else if (operands[2] == const1_rtx
10758 && (TARGET_SHIFT1 || optimize_size))
10759 return "sal{l}\t%0";
10761 return "sal{l}\t{%2, %0|%0, %2}";
10764 [(set (attr "type")
10765 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10767 (match_operand 0 "register_operand" ""))
10768 (match_operand 2 "const1_operand" ""))
10769 (const_string "alu")
10771 (const_string "ishift")))
10772 (set_attr "mode" "SI")])
10774 (define_insn "*ashlsi3_cconly"
10775 [(set (reg FLAGS_REG)
10777 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10778 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10780 (clobber (match_scratch:SI 0 "=r"))]
10781 "ix86_match_ccmode (insn, CCGOCmode)
10782 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10784 || !TARGET_PARTIAL_FLAG_REG_STALL
10785 || (operands[2] == const1_rtx
10787 || TARGET_DOUBLE_WITH_ADD)))"
10789 switch (get_attr_type (insn))
10792 gcc_assert (operands[2] == const1_rtx);
10793 return "add{l}\t{%0, %0|%0, %0}";
10796 if (REG_P (operands[2]))
10797 return "sal{l}\t{%b2, %0|%0, %b2}";
10798 else if (operands[2] == const1_rtx
10799 && (TARGET_SHIFT1 || optimize_size))
10800 return "sal{l}\t%0";
10802 return "sal{l}\t{%2, %0|%0, %2}";
10805 [(set (attr "type")
10806 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10808 (match_operand 0 "register_operand" ""))
10809 (match_operand 2 "const1_operand" ""))
10810 (const_string "alu")
10812 (const_string "ishift")))
10813 (set_attr "mode" "SI")])
10815 (define_insn "*ashlsi3_cmp_zext"
10816 [(set (reg FLAGS_REG)
10818 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10819 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10821 (set (match_operand:DI 0 "register_operand" "=r")
10822 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10823 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10824 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10826 || !TARGET_PARTIAL_FLAG_REG_STALL
10827 || (operands[2] == const1_rtx
10829 || TARGET_DOUBLE_WITH_ADD)))"
10831 switch (get_attr_type (insn))
10834 gcc_assert (operands[2] == const1_rtx);
10835 return "add{l}\t{%k0, %k0|%k0, %k0}";
10838 if (REG_P (operands[2]))
10839 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10840 else if (operands[2] == const1_rtx
10841 && (TARGET_SHIFT1 || optimize_size))
10842 return "sal{l}\t%k0";
10844 return "sal{l}\t{%2, %k0|%k0, %2}";
10847 [(set (attr "type")
10848 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10850 (match_operand 2 "const1_operand" ""))
10851 (const_string "alu")
10853 (const_string "ishift")))
10854 (set_attr "mode" "SI")])
10856 (define_expand "ashlhi3"
10857 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10858 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10859 (match_operand:QI 2 "nonmemory_operand" "")))
10860 (clobber (reg:CC FLAGS_REG))]
10861 "TARGET_HIMODE_MATH"
10862 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10864 (define_insn "*ashlhi3_1_lea"
10865 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10866 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10867 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10868 (clobber (reg:CC FLAGS_REG))]
10869 "!TARGET_PARTIAL_REG_STALL
10870 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10872 switch (get_attr_type (insn))
10877 gcc_assert (operands[2] == const1_rtx);
10878 return "add{w}\t{%0, %0|%0, %0}";
10881 if (REG_P (operands[2]))
10882 return "sal{w}\t{%b2, %0|%0, %b2}";
10883 else if (operands[2] == const1_rtx
10884 && (TARGET_SHIFT1 || optimize_size))
10885 return "sal{w}\t%0";
10887 return "sal{w}\t{%2, %0|%0, %2}";
10890 [(set (attr "type")
10891 (cond [(eq_attr "alternative" "1")
10892 (const_string "lea")
10893 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10895 (match_operand 0 "register_operand" ""))
10896 (match_operand 2 "const1_operand" ""))
10897 (const_string "alu")
10899 (const_string "ishift")))
10900 (set_attr "mode" "HI,SI")])
10902 (define_insn "*ashlhi3_1"
10903 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10904 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10905 (match_operand:QI 2 "nonmemory_operand" "cI")))
10906 (clobber (reg:CC FLAGS_REG))]
10907 "TARGET_PARTIAL_REG_STALL
10908 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10910 switch (get_attr_type (insn))
10913 gcc_assert (operands[2] == const1_rtx);
10914 return "add{w}\t{%0, %0|%0, %0}";
10917 if (REG_P (operands[2]))
10918 return "sal{w}\t{%b2, %0|%0, %b2}";
10919 else if (operands[2] == const1_rtx
10920 && (TARGET_SHIFT1 || optimize_size))
10921 return "sal{w}\t%0";
10923 return "sal{w}\t{%2, %0|%0, %2}";
10926 [(set (attr "type")
10927 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10929 (match_operand 0 "register_operand" ""))
10930 (match_operand 2 "const1_operand" ""))
10931 (const_string "alu")
10933 (const_string "ishift")))
10934 (set_attr "mode" "HI")])
10936 ;; This pattern can't accept a variable shift count, since shifts by
10937 ;; zero don't affect the flags. We assume that shifts by constant
10938 ;; zero are optimized away.
10939 (define_insn "*ashlhi3_cmp"
10940 [(set (reg FLAGS_REG)
10942 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10943 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10945 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10946 (ashift:HI (match_dup 1) (match_dup 2)))]
10947 "ix86_match_ccmode (insn, CCGOCmode)
10948 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10950 || !TARGET_PARTIAL_FLAG_REG_STALL
10951 || (operands[2] == const1_rtx
10953 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10955 switch (get_attr_type (insn))
10958 gcc_assert (operands[2] == const1_rtx);
10959 return "add{w}\t{%0, %0|%0, %0}";
10962 if (REG_P (operands[2]))
10963 return "sal{w}\t{%b2, %0|%0, %b2}";
10964 else if (operands[2] == const1_rtx
10965 && (TARGET_SHIFT1 || optimize_size))
10966 return "sal{w}\t%0";
10968 return "sal{w}\t{%2, %0|%0, %2}";
10971 [(set (attr "type")
10972 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10974 (match_operand 0 "register_operand" ""))
10975 (match_operand 2 "const1_operand" ""))
10976 (const_string "alu")
10978 (const_string "ishift")))
10979 (set_attr "mode" "HI")])
10981 (define_insn "*ashlhi3_cconly"
10982 [(set (reg FLAGS_REG)
10984 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10985 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10987 (clobber (match_scratch:HI 0 "=r"))]
10988 "ix86_match_ccmode (insn, CCGOCmode)
10989 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10991 || !TARGET_PARTIAL_FLAG_REG_STALL
10992 || (operands[2] == const1_rtx
10994 || TARGET_DOUBLE_WITH_ADD)))"
10996 switch (get_attr_type (insn))
10999 gcc_assert (operands[2] == const1_rtx);
11000 return "add{w}\t{%0, %0|%0, %0}";
11003 if (REG_P (operands[2]))
11004 return "sal{w}\t{%b2, %0|%0, %b2}";
11005 else if (operands[2] == const1_rtx
11006 && (TARGET_SHIFT1 || optimize_size))
11007 return "sal{w}\t%0";
11009 return "sal{w}\t{%2, %0|%0, %2}";
11012 [(set (attr "type")
11013 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11015 (match_operand 0 "register_operand" ""))
11016 (match_operand 2 "const1_operand" ""))
11017 (const_string "alu")
11019 (const_string "ishift")))
11020 (set_attr "mode" "HI")])
11022 (define_expand "ashlqi3"
11023 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11024 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11025 (match_operand:QI 2 "nonmemory_operand" "")))
11026 (clobber (reg:CC FLAGS_REG))]
11027 "TARGET_QIMODE_MATH"
11028 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11030 ;; %%% Potential partial reg stall on alternative 2. What to do?
11032 (define_insn "*ashlqi3_1_lea"
11033 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11034 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11035 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11036 (clobber (reg:CC FLAGS_REG))]
11037 "!TARGET_PARTIAL_REG_STALL
11038 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11040 switch (get_attr_type (insn))
11045 gcc_assert (operands[2] == const1_rtx);
11046 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11047 return "add{l}\t{%k0, %k0|%k0, %k0}";
11049 return "add{b}\t{%0, %0|%0, %0}";
11052 if (REG_P (operands[2]))
11054 if (get_attr_mode (insn) == MODE_SI)
11055 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11057 return "sal{b}\t{%b2, %0|%0, %b2}";
11059 else if (operands[2] == const1_rtx
11060 && (TARGET_SHIFT1 || optimize_size))
11062 if (get_attr_mode (insn) == MODE_SI)
11063 return "sal{l}\t%0";
11065 return "sal{b}\t%0";
11069 if (get_attr_mode (insn) == MODE_SI)
11070 return "sal{l}\t{%2, %k0|%k0, %2}";
11072 return "sal{b}\t{%2, %0|%0, %2}";
11076 [(set (attr "type")
11077 (cond [(eq_attr "alternative" "2")
11078 (const_string "lea")
11079 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11081 (match_operand 0 "register_operand" ""))
11082 (match_operand 2 "const1_operand" ""))
11083 (const_string "alu")
11085 (const_string "ishift")))
11086 (set_attr "mode" "QI,SI,SI")])
11088 (define_insn "*ashlqi3_1"
11089 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11090 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11091 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11092 (clobber (reg:CC FLAGS_REG))]
11093 "TARGET_PARTIAL_REG_STALL
11094 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11096 switch (get_attr_type (insn))
11099 gcc_assert (operands[2] == const1_rtx);
11100 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11101 return "add{l}\t{%k0, %k0|%k0, %k0}";
11103 return "add{b}\t{%0, %0|%0, %0}";
11106 if (REG_P (operands[2]))
11108 if (get_attr_mode (insn) == MODE_SI)
11109 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11111 return "sal{b}\t{%b2, %0|%0, %b2}";
11113 else if (operands[2] == const1_rtx
11114 && (TARGET_SHIFT1 || optimize_size))
11116 if (get_attr_mode (insn) == MODE_SI)
11117 return "sal{l}\t%0";
11119 return "sal{b}\t%0";
11123 if (get_attr_mode (insn) == MODE_SI)
11124 return "sal{l}\t{%2, %k0|%k0, %2}";
11126 return "sal{b}\t{%2, %0|%0, %2}";
11130 [(set (attr "type")
11131 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11133 (match_operand 0 "register_operand" ""))
11134 (match_operand 2 "const1_operand" ""))
11135 (const_string "alu")
11137 (const_string "ishift")))
11138 (set_attr "mode" "QI,SI")])
11140 ;; This pattern can't accept a variable shift count, since shifts by
11141 ;; zero don't affect the flags. We assume that shifts by constant
11142 ;; zero are optimized away.
11143 (define_insn "*ashlqi3_cmp"
11144 [(set (reg FLAGS_REG)
11146 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11147 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11149 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11150 (ashift:QI (match_dup 1) (match_dup 2)))]
11151 "ix86_match_ccmode (insn, CCGOCmode)
11152 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11154 || !TARGET_PARTIAL_FLAG_REG_STALL
11155 || (operands[2] == const1_rtx
11157 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11159 switch (get_attr_type (insn))
11162 gcc_assert (operands[2] == const1_rtx);
11163 return "add{b}\t{%0, %0|%0, %0}";
11166 if (REG_P (operands[2]))
11167 return "sal{b}\t{%b2, %0|%0, %b2}";
11168 else if (operands[2] == const1_rtx
11169 && (TARGET_SHIFT1 || optimize_size))
11170 return "sal{b}\t%0";
11172 return "sal{b}\t{%2, %0|%0, %2}";
11175 [(set (attr "type")
11176 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11178 (match_operand 0 "register_operand" ""))
11179 (match_operand 2 "const1_operand" ""))
11180 (const_string "alu")
11182 (const_string "ishift")))
11183 (set_attr "mode" "QI")])
11185 (define_insn "*ashlqi3_cconly"
11186 [(set (reg FLAGS_REG)
11188 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11189 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11191 (clobber (match_scratch:QI 0 "=q"))]
11192 "ix86_match_ccmode (insn, CCGOCmode)
11193 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11195 || !TARGET_PARTIAL_FLAG_REG_STALL
11196 || (operands[2] == const1_rtx
11198 || TARGET_DOUBLE_WITH_ADD)))"
11200 switch (get_attr_type (insn))
11203 gcc_assert (operands[2] == const1_rtx);
11204 return "add{b}\t{%0, %0|%0, %0}";
11207 if (REG_P (operands[2]))
11208 return "sal{b}\t{%b2, %0|%0, %b2}";
11209 else if (operands[2] == const1_rtx
11210 && (TARGET_SHIFT1 || optimize_size))
11211 return "sal{b}\t%0";
11213 return "sal{b}\t{%2, %0|%0, %2}";
11216 [(set (attr "type")
11217 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11219 (match_operand 0 "register_operand" ""))
11220 (match_operand 2 "const1_operand" ""))
11221 (const_string "alu")
11223 (const_string "ishift")))
11224 (set_attr "mode" "QI")])
11226 ;; See comment above `ashldi3' about how this works.
11228 (define_expand "ashrti3"
11229 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11230 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11231 (match_operand:QI 2 "nonmemory_operand" "")))
11232 (clobber (reg:CC FLAGS_REG))])]
11235 if (! immediate_operand (operands[2], QImode))
11237 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11240 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11244 (define_insn "ashrti3_1"
11245 [(set (match_operand:TI 0 "register_operand" "=r")
11246 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11247 (match_operand:QI 2 "register_operand" "c")))
11248 (clobber (match_scratch:DI 3 "=&r"))
11249 (clobber (reg:CC FLAGS_REG))]
11252 [(set_attr "type" "multi")])
11254 (define_insn "*ashrti3_2"
11255 [(set (match_operand:TI 0 "register_operand" "=r")
11256 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11257 (match_operand:QI 2 "immediate_operand" "O")))
11258 (clobber (reg:CC FLAGS_REG))]
11261 [(set_attr "type" "multi")])
11264 [(set (match_operand:TI 0 "register_operand" "")
11265 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11266 (match_operand:QI 2 "register_operand" "")))
11267 (clobber (match_scratch:DI 3 ""))
11268 (clobber (reg:CC FLAGS_REG))]
11269 "TARGET_64BIT && reload_completed"
11271 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11274 [(set (match_operand:TI 0 "register_operand" "")
11275 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11276 (match_operand:QI 2 "immediate_operand" "")))
11277 (clobber (reg:CC FLAGS_REG))]
11278 "TARGET_64BIT && reload_completed"
11280 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11282 (define_insn "x86_64_shrd"
11283 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11284 (ior:DI (ashiftrt:DI (match_dup 0)
11285 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11286 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11287 (minus:QI (const_int 64) (match_dup 2)))))
11288 (clobber (reg:CC FLAGS_REG))]
11291 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11292 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11293 [(set_attr "type" "ishift")
11294 (set_attr "prefix_0f" "1")
11295 (set_attr "mode" "DI")
11296 (set_attr "athlon_decode" "vector")])
11298 (define_expand "ashrdi3"
11299 [(set (match_operand:DI 0 "shiftdi_operand" "")
11300 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11301 (match_operand:QI 2 "nonmemory_operand" "")))]
11303 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11305 (define_insn "*ashrdi3_63_rex64"
11306 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11307 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11308 (match_operand:DI 2 "const_int_operand" "i,i")))
11309 (clobber (reg:CC FLAGS_REG))]
11310 "TARGET_64BIT && INTVAL (operands[2]) == 63
11311 && (TARGET_USE_CLTD || optimize_size)
11312 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11315 sar{q}\t{%2, %0|%0, %2}"
11316 [(set_attr "type" "imovx,ishift")
11317 (set_attr "prefix_0f" "0,*")
11318 (set_attr "length_immediate" "0,*")
11319 (set_attr "modrm" "0,1")
11320 (set_attr "mode" "DI")])
11322 (define_insn "*ashrdi3_1_one_bit_rex64"
11323 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11324 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11325 (match_operand:QI 2 "const1_operand" "")))
11326 (clobber (reg:CC FLAGS_REG))]
11327 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11328 && (TARGET_SHIFT1 || optimize_size)"
11330 [(set_attr "type" "ishift")
11331 (set (attr "length")
11332 (if_then_else (match_operand:DI 0 "register_operand" "")
11334 (const_string "*")))])
11336 (define_insn "*ashrdi3_1_rex64"
11337 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11338 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11339 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11340 (clobber (reg:CC FLAGS_REG))]
11341 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11343 sar{q}\t{%2, %0|%0, %2}
11344 sar{q}\t{%b2, %0|%0, %b2}"
11345 [(set_attr "type" "ishift")
11346 (set_attr "mode" "DI")])
11348 ;; This pattern can't accept a variable shift count, since shifts by
11349 ;; zero don't affect the flags. We assume that shifts by constant
11350 ;; zero are optimized away.
11351 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11352 [(set (reg FLAGS_REG)
11354 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11355 (match_operand:QI 2 "const1_operand" ""))
11357 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11358 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11359 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11360 && (TARGET_SHIFT1 || optimize_size)
11361 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11363 [(set_attr "type" "ishift")
11364 (set (attr "length")
11365 (if_then_else (match_operand:DI 0 "register_operand" "")
11367 (const_string "*")))])
11369 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11370 [(set (reg FLAGS_REG)
11372 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11373 (match_operand:QI 2 "const1_operand" ""))
11375 (clobber (match_scratch:DI 0 "=r"))]
11376 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11377 && (TARGET_SHIFT1 || optimize_size)
11378 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11380 [(set_attr "type" "ishift")
11381 (set_attr "length" "2")])
11383 ;; This pattern can't accept a variable shift count, since shifts by
11384 ;; zero don't affect the flags. We assume that shifts by constant
11385 ;; zero are optimized away.
11386 (define_insn "*ashrdi3_cmp_rex64"
11387 [(set (reg FLAGS_REG)
11389 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11390 (match_operand:QI 2 "const_int_operand" "n"))
11392 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11393 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11394 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11395 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11397 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11398 "sar{q}\t{%2, %0|%0, %2}"
11399 [(set_attr "type" "ishift")
11400 (set_attr "mode" "DI")])
11402 (define_insn "*ashrdi3_cconly_rex64"
11403 [(set (reg FLAGS_REG)
11405 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11406 (match_operand:QI 2 "const_int_operand" "n"))
11408 (clobber (match_scratch:DI 0 "=r"))]
11409 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11410 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11412 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11413 "sar{q}\t{%2, %0|%0, %2}"
11414 [(set_attr "type" "ishift")
11415 (set_attr "mode" "DI")])
11417 (define_insn "*ashrdi3_1"
11418 [(set (match_operand:DI 0 "register_operand" "=r")
11419 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11420 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11421 (clobber (reg:CC FLAGS_REG))]
11424 [(set_attr "type" "multi")])
11426 ;; By default we don't ask for a scratch register, because when DImode
11427 ;; values are manipulated, registers are already at a premium. But if
11428 ;; we have one handy, we won't turn it away.
11430 [(match_scratch:SI 3 "r")
11431 (parallel [(set (match_operand:DI 0 "register_operand" "")
11432 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11433 (match_operand:QI 2 "nonmemory_operand" "")))
11434 (clobber (reg:CC FLAGS_REG))])
11436 "!TARGET_64BIT && TARGET_CMOVE"
11438 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11441 [(set (match_operand:DI 0 "register_operand" "")
11442 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11443 (match_operand:QI 2 "nonmemory_operand" "")))
11444 (clobber (reg:CC FLAGS_REG))]
11445 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11446 ? flow2_completed : reload_completed)"
11448 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11450 (define_insn "x86_shrd_1"
11451 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11452 (ior:SI (ashiftrt:SI (match_dup 0)
11453 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11454 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11455 (minus:QI (const_int 32) (match_dup 2)))))
11456 (clobber (reg:CC FLAGS_REG))]
11459 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11460 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11461 [(set_attr "type" "ishift")
11462 (set_attr "prefix_0f" "1")
11463 (set_attr "pent_pair" "np")
11464 (set_attr "mode" "SI")])
11466 (define_expand "x86_shift_adj_3"
11467 [(use (match_operand:SI 0 "register_operand" ""))
11468 (use (match_operand:SI 1 "register_operand" ""))
11469 (use (match_operand:QI 2 "register_operand" ""))]
11472 rtx label = gen_label_rtx ();
11475 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11477 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11478 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11479 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11480 gen_rtx_LABEL_REF (VOIDmode, label),
11482 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11483 JUMP_LABEL (tmp) = label;
11485 emit_move_insn (operands[0], operands[1]);
11486 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11488 emit_label (label);
11489 LABEL_NUSES (label) = 1;
11494 (define_insn "ashrsi3_31"
11495 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11496 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11497 (match_operand:SI 2 "const_int_operand" "i,i")))
11498 (clobber (reg:CC FLAGS_REG))]
11499 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11500 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11503 sar{l}\t{%2, %0|%0, %2}"
11504 [(set_attr "type" "imovx,ishift")
11505 (set_attr "prefix_0f" "0,*")
11506 (set_attr "length_immediate" "0,*")
11507 (set_attr "modrm" "0,1")
11508 (set_attr "mode" "SI")])
11510 (define_insn "*ashrsi3_31_zext"
11511 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11512 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11513 (match_operand:SI 2 "const_int_operand" "i,i"))))
11514 (clobber (reg:CC FLAGS_REG))]
11515 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11516 && INTVAL (operands[2]) == 31
11517 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11520 sar{l}\t{%2, %k0|%k0, %2}"
11521 [(set_attr "type" "imovx,ishift")
11522 (set_attr "prefix_0f" "0,*")
11523 (set_attr "length_immediate" "0,*")
11524 (set_attr "modrm" "0,1")
11525 (set_attr "mode" "SI")])
11527 (define_expand "ashrsi3"
11528 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11529 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11530 (match_operand:QI 2 "nonmemory_operand" "")))
11531 (clobber (reg:CC FLAGS_REG))]
11533 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11535 (define_insn "*ashrsi3_1_one_bit"
11536 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11537 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11538 (match_operand:QI 2 "const1_operand" "")))
11539 (clobber (reg:CC FLAGS_REG))]
11540 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11541 && (TARGET_SHIFT1 || optimize_size)"
11543 [(set_attr "type" "ishift")
11544 (set (attr "length")
11545 (if_then_else (match_operand:SI 0 "register_operand" "")
11547 (const_string "*")))])
11549 (define_insn "*ashrsi3_1_one_bit_zext"
11550 [(set (match_operand:DI 0 "register_operand" "=r")
11551 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11552 (match_operand:QI 2 "const1_operand" ""))))
11553 (clobber (reg:CC FLAGS_REG))]
11554 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11555 && (TARGET_SHIFT1 || optimize_size)"
11557 [(set_attr "type" "ishift")
11558 (set_attr "length" "2")])
11560 (define_insn "*ashrsi3_1"
11561 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11562 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11563 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11564 (clobber (reg:CC FLAGS_REG))]
11565 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11567 sar{l}\t{%2, %0|%0, %2}
11568 sar{l}\t{%b2, %0|%0, %b2}"
11569 [(set_attr "type" "ishift")
11570 (set_attr "mode" "SI")])
11572 (define_insn "*ashrsi3_1_zext"
11573 [(set (match_operand:DI 0 "register_operand" "=r,r")
11574 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11575 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11576 (clobber (reg:CC FLAGS_REG))]
11577 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11579 sar{l}\t{%2, %k0|%k0, %2}
11580 sar{l}\t{%b2, %k0|%k0, %b2}"
11581 [(set_attr "type" "ishift")
11582 (set_attr "mode" "SI")])
11584 ;; This pattern can't accept a variable shift count, since shifts by
11585 ;; zero don't affect the flags. We assume that shifts by constant
11586 ;; zero are optimized away.
11587 (define_insn "*ashrsi3_one_bit_cmp"
11588 [(set (reg FLAGS_REG)
11590 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11591 (match_operand:QI 2 "const1_operand" ""))
11593 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11594 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11595 "ix86_match_ccmode (insn, CCGOCmode)
11596 && (TARGET_SHIFT1 || optimize_size)
11597 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11599 [(set_attr "type" "ishift")
11600 (set (attr "length")
11601 (if_then_else (match_operand:SI 0 "register_operand" "")
11603 (const_string "*")))])
11605 (define_insn "*ashrsi3_one_bit_cconly"
11606 [(set (reg FLAGS_REG)
11608 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11609 (match_operand:QI 2 "const1_operand" ""))
11611 (clobber (match_scratch:SI 0 "=r"))]
11612 "ix86_match_ccmode (insn, CCGOCmode)
11613 && (TARGET_SHIFT1 || optimize_size)
11614 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11616 [(set_attr "type" "ishift")
11617 (set_attr "length" "2")])
11619 (define_insn "*ashrsi3_one_bit_cmp_zext"
11620 [(set (reg FLAGS_REG)
11622 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11623 (match_operand:QI 2 "const1_operand" ""))
11625 (set (match_operand:DI 0 "register_operand" "=r")
11626 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11627 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11628 && (TARGET_SHIFT1 || optimize_size)
11629 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11631 [(set_attr "type" "ishift")
11632 (set_attr "length" "2")])
11634 ;; This pattern can't accept a variable shift count, since shifts by
11635 ;; zero don't affect the flags. We assume that shifts by constant
11636 ;; zero are optimized away.
11637 (define_insn "*ashrsi3_cmp"
11638 [(set (reg FLAGS_REG)
11640 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11641 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11643 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11644 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11645 "ix86_match_ccmode (insn, CCGOCmode)
11646 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11648 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11649 "sar{l}\t{%2, %0|%0, %2}"
11650 [(set_attr "type" "ishift")
11651 (set_attr "mode" "SI")])
11653 (define_insn "*ashrsi3_cconly"
11654 [(set (reg FLAGS_REG)
11656 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11657 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11659 (clobber (match_scratch:SI 0 "=r"))]
11660 "ix86_match_ccmode (insn, CCGOCmode)
11661 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11663 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11664 "sar{l}\t{%2, %0|%0, %2}"
11665 [(set_attr "type" "ishift")
11666 (set_attr "mode" "SI")])
11668 (define_insn "*ashrsi3_cmp_zext"
11669 [(set (reg FLAGS_REG)
11671 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11672 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11674 (set (match_operand:DI 0 "register_operand" "=r")
11675 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11676 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11677 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11679 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11680 "sar{l}\t{%2, %k0|%k0, %2}"
11681 [(set_attr "type" "ishift")
11682 (set_attr "mode" "SI")])
11684 (define_expand "ashrhi3"
11685 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11686 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11687 (match_operand:QI 2 "nonmemory_operand" "")))
11688 (clobber (reg:CC FLAGS_REG))]
11689 "TARGET_HIMODE_MATH"
11690 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11692 (define_insn "*ashrhi3_1_one_bit"
11693 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11694 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11695 (match_operand:QI 2 "const1_operand" "")))
11696 (clobber (reg:CC FLAGS_REG))]
11697 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11698 && (TARGET_SHIFT1 || optimize_size)"
11700 [(set_attr "type" "ishift")
11701 (set (attr "length")
11702 (if_then_else (match_operand 0 "register_operand" "")
11704 (const_string "*")))])
11706 (define_insn "*ashrhi3_1"
11707 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11708 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11709 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11710 (clobber (reg:CC FLAGS_REG))]
11711 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11713 sar{w}\t{%2, %0|%0, %2}
11714 sar{w}\t{%b2, %0|%0, %b2}"
11715 [(set_attr "type" "ishift")
11716 (set_attr "mode" "HI")])
11718 ;; This pattern can't accept a variable shift count, since shifts by
11719 ;; zero don't affect the flags. We assume that shifts by constant
11720 ;; zero are optimized away.
11721 (define_insn "*ashrhi3_one_bit_cmp"
11722 [(set (reg FLAGS_REG)
11724 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11725 (match_operand:QI 2 "const1_operand" ""))
11727 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11728 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11729 "ix86_match_ccmode (insn, CCGOCmode)
11730 && (TARGET_SHIFT1 || optimize_size)
11731 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11733 [(set_attr "type" "ishift")
11734 (set (attr "length")
11735 (if_then_else (match_operand 0 "register_operand" "")
11737 (const_string "*")))])
11739 (define_insn "*ashrhi3_one_bit_cconly"
11740 [(set (reg FLAGS_REG)
11742 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11743 (match_operand:QI 2 "const1_operand" ""))
11745 (clobber (match_scratch:HI 0 "=r"))]
11746 "ix86_match_ccmode (insn, CCGOCmode)
11747 && (TARGET_SHIFT1 || optimize_size)
11748 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11750 [(set_attr "type" "ishift")
11751 (set_attr "length" "2")])
11753 ;; This pattern can't accept a variable shift count, since shifts by
11754 ;; zero don't affect the flags. We assume that shifts by constant
11755 ;; zero are optimized away.
11756 (define_insn "*ashrhi3_cmp"
11757 [(set (reg FLAGS_REG)
11759 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11760 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11762 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11763 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11764 "ix86_match_ccmode (insn, CCGOCmode)
11765 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11767 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11768 "sar{w}\t{%2, %0|%0, %2}"
11769 [(set_attr "type" "ishift")
11770 (set_attr "mode" "HI")])
11772 (define_insn "*ashrhi3_cconly"
11773 [(set (reg FLAGS_REG)
11775 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11776 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11778 (clobber (match_scratch:HI 0 "=r"))]
11779 "ix86_match_ccmode (insn, CCGOCmode)
11780 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11782 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11783 "sar{w}\t{%2, %0|%0, %2}"
11784 [(set_attr "type" "ishift")
11785 (set_attr "mode" "HI")])
11787 (define_expand "ashrqi3"
11788 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11789 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11790 (match_operand:QI 2 "nonmemory_operand" "")))
11791 (clobber (reg:CC FLAGS_REG))]
11792 "TARGET_QIMODE_MATH"
11793 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11795 (define_insn "*ashrqi3_1_one_bit"
11796 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11797 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11798 (match_operand:QI 2 "const1_operand" "")))
11799 (clobber (reg:CC FLAGS_REG))]
11800 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11801 && (TARGET_SHIFT1 || optimize_size)"
11803 [(set_attr "type" "ishift")
11804 (set (attr "length")
11805 (if_then_else (match_operand 0 "register_operand" "")
11807 (const_string "*")))])
11809 (define_insn "*ashrqi3_1_one_bit_slp"
11810 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11811 (ashiftrt:QI (match_dup 0)
11812 (match_operand:QI 1 "const1_operand" "")))
11813 (clobber (reg:CC FLAGS_REG))]
11814 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11815 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11816 && (TARGET_SHIFT1 || optimize_size)"
11818 [(set_attr "type" "ishift1")
11819 (set (attr "length")
11820 (if_then_else (match_operand 0 "register_operand" "")
11822 (const_string "*")))])
11824 (define_insn "*ashrqi3_1"
11825 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11826 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11827 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11828 (clobber (reg:CC FLAGS_REG))]
11829 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11831 sar{b}\t{%2, %0|%0, %2}
11832 sar{b}\t{%b2, %0|%0, %b2}"
11833 [(set_attr "type" "ishift")
11834 (set_attr "mode" "QI")])
11836 (define_insn "*ashrqi3_1_slp"
11837 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11838 (ashiftrt:QI (match_dup 0)
11839 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11840 (clobber (reg:CC FLAGS_REG))]
11841 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11842 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11844 sar{b}\t{%1, %0|%0, %1}
11845 sar{b}\t{%b1, %0|%0, %b1}"
11846 [(set_attr "type" "ishift1")
11847 (set_attr "mode" "QI")])
11849 ;; This pattern can't accept a variable shift count, since shifts by
11850 ;; zero don't affect the flags. We assume that shifts by constant
11851 ;; zero are optimized away.
11852 (define_insn "*ashrqi3_one_bit_cmp"
11853 [(set (reg FLAGS_REG)
11855 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11856 (match_operand:QI 2 "const1_operand" "I"))
11858 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11859 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11860 "ix86_match_ccmode (insn, CCGOCmode)
11861 && (TARGET_SHIFT1 || optimize_size)
11862 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11864 [(set_attr "type" "ishift")
11865 (set (attr "length")
11866 (if_then_else (match_operand 0 "register_operand" "")
11868 (const_string "*")))])
11870 (define_insn "*ashrqi3_one_bit_cconly"
11871 [(set (reg FLAGS_REG)
11873 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11874 (match_operand:QI 2 "const1_operand" "I"))
11876 (clobber (match_scratch:QI 0 "=q"))]
11877 "ix86_match_ccmode (insn, CCGOCmode)
11878 && (TARGET_SHIFT1 || optimize_size)
11879 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11881 [(set_attr "type" "ishift")
11882 (set_attr "length" "2")])
11884 ;; This pattern can't accept a variable shift count, since shifts by
11885 ;; zero don't affect the flags. We assume that shifts by constant
11886 ;; zero are optimized away.
11887 (define_insn "*ashrqi3_cmp"
11888 [(set (reg FLAGS_REG)
11890 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11891 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11893 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11894 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11895 "ix86_match_ccmode (insn, CCGOCmode)
11896 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11898 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11899 "sar{b}\t{%2, %0|%0, %2}"
11900 [(set_attr "type" "ishift")
11901 (set_attr "mode" "QI")])
11903 (define_insn "*ashrqi3_cconly"
11904 [(set (reg FLAGS_REG)
11906 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11907 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11909 (clobber (match_scratch:QI 0 "=q"))]
11910 "ix86_match_ccmode (insn, CCGOCmode)
11911 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11913 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11914 "sar{b}\t{%2, %0|%0, %2}"
11915 [(set_attr "type" "ishift")
11916 (set_attr "mode" "QI")])
11919 ;; Logical shift instructions
11921 ;; See comment above `ashldi3' about how this works.
11923 (define_expand "lshrti3"
11924 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11925 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11926 (match_operand:QI 2 "nonmemory_operand" "")))
11927 (clobber (reg:CC FLAGS_REG))])]
11930 if (! immediate_operand (operands[2], QImode))
11932 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11935 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11939 (define_insn "lshrti3_1"
11940 [(set (match_operand:TI 0 "register_operand" "=r")
11941 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11942 (match_operand:QI 2 "register_operand" "c")))
11943 (clobber (match_scratch:DI 3 "=&r"))
11944 (clobber (reg:CC FLAGS_REG))]
11947 [(set_attr "type" "multi")])
11949 (define_insn "*lshrti3_2"
11950 [(set (match_operand:TI 0 "register_operand" "=r")
11951 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11952 (match_operand:QI 2 "immediate_operand" "O")))
11953 (clobber (reg:CC FLAGS_REG))]
11956 [(set_attr "type" "multi")])
11959 [(set (match_operand:TI 0 "register_operand" "")
11960 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11961 (match_operand:QI 2 "register_operand" "")))
11962 (clobber (match_scratch:DI 3 ""))
11963 (clobber (reg:CC FLAGS_REG))]
11964 "TARGET_64BIT && reload_completed"
11966 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11969 [(set (match_operand:TI 0 "register_operand" "")
11970 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11971 (match_operand:QI 2 "immediate_operand" "")))
11972 (clobber (reg:CC FLAGS_REG))]
11973 "TARGET_64BIT && reload_completed"
11975 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11977 (define_expand "lshrdi3"
11978 [(set (match_operand:DI 0 "shiftdi_operand" "")
11979 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11980 (match_operand:QI 2 "nonmemory_operand" "")))]
11982 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11984 (define_insn "*lshrdi3_1_one_bit_rex64"
11985 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11986 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11987 (match_operand:QI 2 "const1_operand" "")))
11988 (clobber (reg:CC FLAGS_REG))]
11989 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11990 && (TARGET_SHIFT1 || optimize_size)"
11992 [(set_attr "type" "ishift")
11993 (set (attr "length")
11994 (if_then_else (match_operand:DI 0 "register_operand" "")
11996 (const_string "*")))])
11998 (define_insn "*lshrdi3_1_rex64"
11999 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12000 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12001 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12002 (clobber (reg:CC FLAGS_REG))]
12003 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12005 shr{q}\t{%2, %0|%0, %2}
12006 shr{q}\t{%b2, %0|%0, %b2}"
12007 [(set_attr "type" "ishift")
12008 (set_attr "mode" "DI")])
12010 ;; This pattern can't accept a variable shift count, since shifts by
12011 ;; zero don't affect the flags. We assume that shifts by constant
12012 ;; zero are optimized away.
12013 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12014 [(set (reg FLAGS_REG)
12016 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12017 (match_operand:QI 2 "const1_operand" ""))
12019 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12020 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12021 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12022 && (TARGET_SHIFT1 || optimize_size)
12023 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12025 [(set_attr "type" "ishift")
12026 (set (attr "length")
12027 (if_then_else (match_operand:DI 0 "register_operand" "")
12029 (const_string "*")))])
12031 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12032 [(set (reg FLAGS_REG)
12034 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12035 (match_operand:QI 2 "const1_operand" ""))
12037 (clobber (match_scratch:DI 0 "=r"))]
12038 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12039 && (TARGET_SHIFT1 || optimize_size)
12040 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12042 [(set_attr "type" "ishift")
12043 (set_attr "length" "2")])
12045 ;; This pattern can't accept a variable shift count, since shifts by
12046 ;; zero don't affect the flags. We assume that shifts by constant
12047 ;; zero are optimized away.
12048 (define_insn "*lshrdi3_cmp_rex64"
12049 [(set (reg FLAGS_REG)
12051 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12052 (match_operand:QI 2 "const_int_operand" "e"))
12054 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12055 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12056 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12057 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12059 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12060 "shr{q}\t{%2, %0|%0, %2}"
12061 [(set_attr "type" "ishift")
12062 (set_attr "mode" "DI")])
12064 (define_insn "*lshrdi3_cconly_rex64"
12065 [(set (reg FLAGS_REG)
12067 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12068 (match_operand:QI 2 "const_int_operand" "e"))
12070 (clobber (match_scratch:DI 0 "=r"))]
12071 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12072 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12074 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12075 "shr{q}\t{%2, %0|%0, %2}"
12076 [(set_attr "type" "ishift")
12077 (set_attr "mode" "DI")])
12079 (define_insn "*lshrdi3_1"
12080 [(set (match_operand:DI 0 "register_operand" "=r")
12081 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12082 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12083 (clobber (reg:CC FLAGS_REG))]
12086 [(set_attr "type" "multi")])
12088 ;; By default we don't ask for a scratch register, because when DImode
12089 ;; values are manipulated, registers are already at a premium. But if
12090 ;; we have one handy, we won't turn it away.
12092 [(match_scratch:SI 3 "r")
12093 (parallel [(set (match_operand:DI 0 "register_operand" "")
12094 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12095 (match_operand:QI 2 "nonmemory_operand" "")))
12096 (clobber (reg:CC FLAGS_REG))])
12098 "!TARGET_64BIT && TARGET_CMOVE"
12100 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12103 [(set (match_operand:DI 0 "register_operand" "")
12104 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12105 (match_operand:QI 2 "nonmemory_operand" "")))
12106 (clobber (reg:CC FLAGS_REG))]
12107 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12108 ? flow2_completed : reload_completed)"
12110 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12112 (define_expand "lshrsi3"
12113 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12114 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12115 (match_operand:QI 2 "nonmemory_operand" "")))
12116 (clobber (reg:CC FLAGS_REG))]
12118 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12120 (define_insn "*lshrsi3_1_one_bit"
12121 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12122 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12123 (match_operand:QI 2 "const1_operand" "")))
12124 (clobber (reg:CC FLAGS_REG))]
12125 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12126 && (TARGET_SHIFT1 || optimize_size)"
12128 [(set_attr "type" "ishift")
12129 (set (attr "length")
12130 (if_then_else (match_operand:SI 0 "register_operand" "")
12132 (const_string "*")))])
12134 (define_insn "*lshrsi3_1_one_bit_zext"
12135 [(set (match_operand:DI 0 "register_operand" "=r")
12136 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12137 (match_operand:QI 2 "const1_operand" "")))
12138 (clobber (reg:CC FLAGS_REG))]
12139 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12140 && (TARGET_SHIFT1 || optimize_size)"
12142 [(set_attr "type" "ishift")
12143 (set_attr "length" "2")])
12145 (define_insn "*lshrsi3_1"
12146 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12147 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12148 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12149 (clobber (reg:CC FLAGS_REG))]
12150 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12152 shr{l}\t{%2, %0|%0, %2}
12153 shr{l}\t{%b2, %0|%0, %b2}"
12154 [(set_attr "type" "ishift")
12155 (set_attr "mode" "SI")])
12157 (define_insn "*lshrsi3_1_zext"
12158 [(set (match_operand:DI 0 "register_operand" "=r,r")
12160 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12161 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12162 (clobber (reg:CC FLAGS_REG))]
12163 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12165 shr{l}\t{%2, %k0|%k0, %2}
12166 shr{l}\t{%b2, %k0|%k0, %b2}"
12167 [(set_attr "type" "ishift")
12168 (set_attr "mode" "SI")])
12170 ;; This pattern can't accept a variable shift count, since shifts by
12171 ;; zero don't affect the flags. We assume that shifts by constant
12172 ;; zero are optimized away.
12173 (define_insn "*lshrsi3_one_bit_cmp"
12174 [(set (reg FLAGS_REG)
12176 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12177 (match_operand:QI 2 "const1_operand" ""))
12179 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12180 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12181 "ix86_match_ccmode (insn, CCGOCmode)
12182 && (TARGET_SHIFT1 || optimize_size)
12183 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12185 [(set_attr "type" "ishift")
12186 (set (attr "length")
12187 (if_then_else (match_operand:SI 0 "register_operand" "")
12189 (const_string "*")))])
12191 (define_insn "*lshrsi3_one_bit_cconly"
12192 [(set (reg FLAGS_REG)
12194 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12195 (match_operand:QI 2 "const1_operand" ""))
12197 (clobber (match_scratch:SI 0 "=r"))]
12198 "ix86_match_ccmode (insn, CCGOCmode)
12199 && (TARGET_SHIFT1 || optimize_size)
12200 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12202 [(set_attr "type" "ishift")
12203 (set_attr "length" "2")])
12205 (define_insn "*lshrsi3_cmp_one_bit_zext"
12206 [(set (reg FLAGS_REG)
12208 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12209 (match_operand:QI 2 "const1_operand" ""))
12211 (set (match_operand:DI 0 "register_operand" "=r")
12212 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12213 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12214 && (TARGET_SHIFT1 || optimize_size)
12215 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12217 [(set_attr "type" "ishift")
12218 (set_attr "length" "2")])
12220 ;; This pattern can't accept a variable shift count, since shifts by
12221 ;; zero don't affect the flags. We assume that shifts by constant
12222 ;; zero are optimized away.
12223 (define_insn "*lshrsi3_cmp"
12224 [(set (reg FLAGS_REG)
12226 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12227 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12229 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12230 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12231 "ix86_match_ccmode (insn, CCGOCmode)
12232 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12234 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12235 "shr{l}\t{%2, %0|%0, %2}"
12236 [(set_attr "type" "ishift")
12237 (set_attr "mode" "SI")])
12239 (define_insn "*lshrsi3_cconly"
12240 [(set (reg FLAGS_REG)
12242 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12243 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12245 (clobber (match_scratch:SI 0 "=r"))]
12246 "ix86_match_ccmode (insn, CCGOCmode)
12247 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12249 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12250 "shr{l}\t{%2, %0|%0, %2}"
12251 [(set_attr "type" "ishift")
12252 (set_attr "mode" "SI")])
12254 (define_insn "*lshrsi3_cmp_zext"
12255 [(set (reg FLAGS_REG)
12257 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12258 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12260 (set (match_operand:DI 0 "register_operand" "=r")
12261 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12262 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12263 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12265 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12266 "shr{l}\t{%2, %k0|%k0, %2}"
12267 [(set_attr "type" "ishift")
12268 (set_attr "mode" "SI")])
12270 (define_expand "lshrhi3"
12271 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12272 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12273 (match_operand:QI 2 "nonmemory_operand" "")))
12274 (clobber (reg:CC FLAGS_REG))]
12275 "TARGET_HIMODE_MATH"
12276 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12278 (define_insn "*lshrhi3_1_one_bit"
12279 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12280 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12281 (match_operand:QI 2 "const1_operand" "")))
12282 (clobber (reg:CC FLAGS_REG))]
12283 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12284 && (TARGET_SHIFT1 || optimize_size)"
12286 [(set_attr "type" "ishift")
12287 (set (attr "length")
12288 (if_then_else (match_operand 0 "register_operand" "")
12290 (const_string "*")))])
12292 (define_insn "*lshrhi3_1"
12293 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12294 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12295 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12296 (clobber (reg:CC FLAGS_REG))]
12297 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12299 shr{w}\t{%2, %0|%0, %2}
12300 shr{w}\t{%b2, %0|%0, %b2}"
12301 [(set_attr "type" "ishift")
12302 (set_attr "mode" "HI")])
12304 ;; This pattern can't accept a variable shift count, since shifts by
12305 ;; zero don't affect the flags. We assume that shifts by constant
12306 ;; zero are optimized away.
12307 (define_insn "*lshrhi3_one_bit_cmp"
12308 [(set (reg FLAGS_REG)
12310 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12311 (match_operand:QI 2 "const1_operand" ""))
12313 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12314 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12315 "ix86_match_ccmode (insn, CCGOCmode)
12316 && (TARGET_SHIFT1 || optimize_size)
12317 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12319 [(set_attr "type" "ishift")
12320 (set (attr "length")
12321 (if_then_else (match_operand:SI 0 "register_operand" "")
12323 (const_string "*")))])
12325 (define_insn "*lshrhi3_one_bit_cconly"
12326 [(set (reg FLAGS_REG)
12328 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12329 (match_operand:QI 2 "const1_operand" ""))
12331 (clobber (match_scratch:HI 0 "=r"))]
12332 "ix86_match_ccmode (insn, CCGOCmode)
12333 && (TARGET_SHIFT1 || optimize_size)
12334 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12336 [(set_attr "type" "ishift")
12337 (set_attr "length" "2")])
12339 ;; This pattern can't accept a variable shift count, since shifts by
12340 ;; zero don't affect the flags. We assume that shifts by constant
12341 ;; zero are optimized away.
12342 (define_insn "*lshrhi3_cmp"
12343 [(set (reg FLAGS_REG)
12345 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12346 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12348 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12349 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12350 "ix86_match_ccmode (insn, CCGOCmode)
12351 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12353 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12354 "shr{w}\t{%2, %0|%0, %2}"
12355 [(set_attr "type" "ishift")
12356 (set_attr "mode" "HI")])
12358 (define_insn "*lshrhi3_cconly"
12359 [(set (reg FLAGS_REG)
12361 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12362 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12364 (clobber (match_scratch:HI 0 "=r"))]
12365 "ix86_match_ccmode (insn, CCGOCmode)
12366 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12368 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12369 "shr{w}\t{%2, %0|%0, %2}"
12370 [(set_attr "type" "ishift")
12371 (set_attr "mode" "HI")])
12373 (define_expand "lshrqi3"
12374 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12375 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12376 (match_operand:QI 2 "nonmemory_operand" "")))
12377 (clobber (reg:CC FLAGS_REG))]
12378 "TARGET_QIMODE_MATH"
12379 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12381 (define_insn "*lshrqi3_1_one_bit"
12382 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12383 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12384 (match_operand:QI 2 "const1_operand" "")))
12385 (clobber (reg:CC FLAGS_REG))]
12386 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12387 && (TARGET_SHIFT1 || optimize_size)"
12389 [(set_attr "type" "ishift")
12390 (set (attr "length")
12391 (if_then_else (match_operand 0 "register_operand" "")
12393 (const_string "*")))])
12395 (define_insn "*lshrqi3_1_one_bit_slp"
12396 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12397 (lshiftrt:QI (match_dup 0)
12398 (match_operand:QI 1 "const1_operand" "")))
12399 (clobber (reg:CC FLAGS_REG))]
12400 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12401 && (TARGET_SHIFT1 || optimize_size)"
12403 [(set_attr "type" "ishift1")
12404 (set (attr "length")
12405 (if_then_else (match_operand 0 "register_operand" "")
12407 (const_string "*")))])
12409 (define_insn "*lshrqi3_1"
12410 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12411 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12412 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12413 (clobber (reg:CC FLAGS_REG))]
12414 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12416 shr{b}\t{%2, %0|%0, %2}
12417 shr{b}\t{%b2, %0|%0, %b2}"
12418 [(set_attr "type" "ishift")
12419 (set_attr "mode" "QI")])
12421 (define_insn "*lshrqi3_1_slp"
12422 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12423 (lshiftrt:QI (match_dup 0)
12424 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12425 (clobber (reg:CC FLAGS_REG))]
12426 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12427 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12429 shr{b}\t{%1, %0|%0, %1}
12430 shr{b}\t{%b1, %0|%0, %b1}"
12431 [(set_attr "type" "ishift1")
12432 (set_attr "mode" "QI")])
12434 ;; This pattern can't accept a variable shift count, since shifts by
12435 ;; zero don't affect the flags. We assume that shifts by constant
12436 ;; zero are optimized away.
12437 (define_insn "*lshrqi2_one_bit_cmp"
12438 [(set (reg FLAGS_REG)
12440 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12441 (match_operand:QI 2 "const1_operand" ""))
12443 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12444 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12445 "ix86_match_ccmode (insn, CCGOCmode)
12446 && (TARGET_SHIFT1 || optimize_size)
12447 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12449 [(set_attr "type" "ishift")
12450 (set (attr "length")
12451 (if_then_else (match_operand:SI 0 "register_operand" "")
12453 (const_string "*")))])
12455 (define_insn "*lshrqi2_one_bit_cconly"
12456 [(set (reg FLAGS_REG)
12458 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12459 (match_operand:QI 2 "const1_operand" ""))
12461 (clobber (match_scratch:QI 0 "=q"))]
12462 "ix86_match_ccmode (insn, CCGOCmode)
12463 && (TARGET_SHIFT1 || optimize_size)
12464 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12466 [(set_attr "type" "ishift")
12467 (set_attr "length" "2")])
12469 ;; This pattern can't accept a variable shift count, since shifts by
12470 ;; zero don't affect the flags. We assume that shifts by constant
12471 ;; zero are optimized away.
12472 (define_insn "*lshrqi2_cmp"
12473 [(set (reg FLAGS_REG)
12475 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12476 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12478 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12479 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12480 "ix86_match_ccmode (insn, CCGOCmode)
12481 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12483 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12484 "shr{b}\t{%2, %0|%0, %2}"
12485 [(set_attr "type" "ishift")
12486 (set_attr "mode" "QI")])
12488 (define_insn "*lshrqi2_cconly"
12489 [(set (reg FLAGS_REG)
12491 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12492 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12494 (clobber (match_scratch:QI 0 "=q"))]
12495 "ix86_match_ccmode (insn, CCGOCmode)
12496 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12498 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12499 "shr{b}\t{%2, %0|%0, %2}"
12500 [(set_attr "type" "ishift")
12501 (set_attr "mode" "QI")])
12503 ;; Rotate instructions
12505 (define_expand "rotldi3"
12506 [(set (match_operand:DI 0 "shiftdi_operand" "")
12507 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12508 (match_operand:QI 2 "nonmemory_operand" "")))
12509 (clobber (reg:CC FLAGS_REG))]
12514 ix86_expand_binary_operator (ROTATE, DImode, operands);
12517 if (!const_1_to_31_operand (operands[2], VOIDmode))
12519 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12523 ;; Implement rotation using two double-precision shift instructions
12524 ;; and a scratch register.
12525 (define_insn_and_split "ix86_rotldi3"
12526 [(set (match_operand:DI 0 "register_operand" "=r")
12527 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12528 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12529 (clobber (reg:CC FLAGS_REG))
12530 (clobber (match_scratch:SI 3 "=&r"))]
12533 "&& reload_completed"
12534 [(set (match_dup 3) (match_dup 4))
12536 [(set (match_dup 4)
12537 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12538 (lshiftrt:SI (match_dup 5)
12539 (minus:QI (const_int 32) (match_dup 2)))))
12540 (clobber (reg:CC FLAGS_REG))])
12542 [(set (match_dup 5)
12543 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12544 (lshiftrt:SI (match_dup 3)
12545 (minus:QI (const_int 32) (match_dup 2)))))
12546 (clobber (reg:CC FLAGS_REG))])]
12547 "split_di (operands, 1, operands + 4, operands + 5);")
12549 (define_insn "*rotlsi3_1_one_bit_rex64"
12550 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12551 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12552 (match_operand:QI 2 "const1_operand" "")))
12553 (clobber (reg:CC FLAGS_REG))]
12554 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12555 && (TARGET_SHIFT1 || optimize_size)"
12557 [(set_attr "type" "rotate")
12558 (set (attr "length")
12559 (if_then_else (match_operand:DI 0 "register_operand" "")
12561 (const_string "*")))])
12563 (define_insn "*rotldi3_1_rex64"
12564 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12565 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12566 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12567 (clobber (reg:CC FLAGS_REG))]
12568 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12570 rol{q}\t{%2, %0|%0, %2}
12571 rol{q}\t{%b2, %0|%0, %b2}"
12572 [(set_attr "type" "rotate")
12573 (set_attr "mode" "DI")])
12575 (define_expand "rotlsi3"
12576 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12577 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12578 (match_operand:QI 2 "nonmemory_operand" "")))
12579 (clobber (reg:CC FLAGS_REG))]
12581 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12583 (define_insn "*rotlsi3_1_one_bit"
12584 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12585 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12586 (match_operand:QI 2 "const1_operand" "")))
12587 (clobber (reg:CC FLAGS_REG))]
12588 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12589 && (TARGET_SHIFT1 || optimize_size)"
12591 [(set_attr "type" "rotate")
12592 (set (attr "length")
12593 (if_then_else (match_operand:SI 0 "register_operand" "")
12595 (const_string "*")))])
12597 (define_insn "*rotlsi3_1_one_bit_zext"
12598 [(set (match_operand:DI 0 "register_operand" "=r")
12600 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12601 (match_operand:QI 2 "const1_operand" ""))))
12602 (clobber (reg:CC FLAGS_REG))]
12603 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12604 && (TARGET_SHIFT1 || optimize_size)"
12606 [(set_attr "type" "rotate")
12607 (set_attr "length" "2")])
12609 (define_insn "*rotlsi3_1"
12610 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12611 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12612 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12613 (clobber (reg:CC FLAGS_REG))]
12614 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12616 rol{l}\t{%2, %0|%0, %2}
12617 rol{l}\t{%b2, %0|%0, %b2}"
12618 [(set_attr "type" "rotate")
12619 (set_attr "mode" "SI")])
12621 (define_insn "*rotlsi3_1_zext"
12622 [(set (match_operand:DI 0 "register_operand" "=r,r")
12624 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12625 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12626 (clobber (reg:CC FLAGS_REG))]
12627 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12629 rol{l}\t{%2, %k0|%k0, %2}
12630 rol{l}\t{%b2, %k0|%k0, %b2}"
12631 [(set_attr "type" "rotate")
12632 (set_attr "mode" "SI")])
12634 (define_expand "rotlhi3"
12635 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12636 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12637 (match_operand:QI 2 "nonmemory_operand" "")))
12638 (clobber (reg:CC FLAGS_REG))]
12639 "TARGET_HIMODE_MATH"
12640 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12642 (define_insn "*rotlhi3_1_one_bit"
12643 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12644 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12645 (match_operand:QI 2 "const1_operand" "")))
12646 (clobber (reg:CC FLAGS_REG))]
12647 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12648 && (TARGET_SHIFT1 || optimize_size)"
12650 [(set_attr "type" "rotate")
12651 (set (attr "length")
12652 (if_then_else (match_operand 0 "register_operand" "")
12654 (const_string "*")))])
12656 (define_insn "*rotlhi3_1"
12657 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12658 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12659 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12660 (clobber (reg:CC FLAGS_REG))]
12661 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12663 rol{w}\t{%2, %0|%0, %2}
12664 rol{w}\t{%b2, %0|%0, %b2}"
12665 [(set_attr "type" "rotate")
12666 (set_attr "mode" "HI")])
12668 (define_expand "rotlqi3"
12669 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12670 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12671 (match_operand:QI 2 "nonmemory_operand" "")))
12672 (clobber (reg:CC FLAGS_REG))]
12673 "TARGET_QIMODE_MATH"
12674 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12676 (define_insn "*rotlqi3_1_one_bit_slp"
12677 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12678 (rotate:QI (match_dup 0)
12679 (match_operand:QI 1 "const1_operand" "")))
12680 (clobber (reg:CC FLAGS_REG))]
12681 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12682 && (TARGET_SHIFT1 || optimize_size)"
12684 [(set_attr "type" "rotate1")
12685 (set (attr "length")
12686 (if_then_else (match_operand 0 "register_operand" "")
12688 (const_string "*")))])
12690 (define_insn "*rotlqi3_1_one_bit"
12691 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12692 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12693 (match_operand:QI 2 "const1_operand" "")))
12694 (clobber (reg:CC FLAGS_REG))]
12695 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12696 && (TARGET_SHIFT1 || optimize_size)"
12698 [(set_attr "type" "rotate")
12699 (set (attr "length")
12700 (if_then_else (match_operand 0 "register_operand" "")
12702 (const_string "*")))])
12704 (define_insn "*rotlqi3_1_slp"
12705 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12706 (rotate:QI (match_dup 0)
12707 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12708 (clobber (reg:CC FLAGS_REG))]
12709 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12710 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12712 rol{b}\t{%1, %0|%0, %1}
12713 rol{b}\t{%b1, %0|%0, %b1}"
12714 [(set_attr "type" "rotate1")
12715 (set_attr "mode" "QI")])
12717 (define_insn "*rotlqi3_1"
12718 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12719 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12720 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12721 (clobber (reg:CC FLAGS_REG))]
12722 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12724 rol{b}\t{%2, %0|%0, %2}
12725 rol{b}\t{%b2, %0|%0, %b2}"
12726 [(set_attr "type" "rotate")
12727 (set_attr "mode" "QI")])
12729 (define_expand "rotrdi3"
12730 [(set (match_operand:DI 0 "shiftdi_operand" "")
12731 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12732 (match_operand:QI 2 "nonmemory_operand" "")))
12733 (clobber (reg:CC FLAGS_REG))]
12738 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12741 if (!const_1_to_31_operand (operands[2], VOIDmode))
12743 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12747 ;; Implement rotation using two double-precision shift instructions
12748 ;; and a scratch register.
12749 (define_insn_and_split "ix86_rotrdi3"
12750 [(set (match_operand:DI 0 "register_operand" "=r")
12751 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12752 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12753 (clobber (reg:CC FLAGS_REG))
12754 (clobber (match_scratch:SI 3 "=&r"))]
12757 "&& reload_completed"
12758 [(set (match_dup 3) (match_dup 4))
12760 [(set (match_dup 4)
12761 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12762 (ashift:SI (match_dup 5)
12763 (minus:QI (const_int 32) (match_dup 2)))))
12764 (clobber (reg:CC FLAGS_REG))])
12766 [(set (match_dup 5)
12767 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12768 (ashift:SI (match_dup 3)
12769 (minus:QI (const_int 32) (match_dup 2)))))
12770 (clobber (reg:CC FLAGS_REG))])]
12771 "split_di (operands, 1, operands + 4, operands + 5);")
12773 (define_insn "*rotrdi3_1_one_bit_rex64"
12774 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12775 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12776 (match_operand:QI 2 "const1_operand" "")))
12777 (clobber (reg:CC FLAGS_REG))]
12778 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12779 && (TARGET_SHIFT1 || optimize_size)"
12781 [(set_attr "type" "rotate")
12782 (set (attr "length")
12783 (if_then_else (match_operand:DI 0 "register_operand" "")
12785 (const_string "*")))])
12787 (define_insn "*rotrdi3_1_rex64"
12788 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12789 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12790 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12791 (clobber (reg:CC FLAGS_REG))]
12792 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12794 ror{q}\t{%2, %0|%0, %2}
12795 ror{q}\t{%b2, %0|%0, %b2}"
12796 [(set_attr "type" "rotate")
12797 (set_attr "mode" "DI")])
12799 (define_expand "rotrsi3"
12800 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12801 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12802 (match_operand:QI 2 "nonmemory_operand" "")))
12803 (clobber (reg:CC FLAGS_REG))]
12805 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12807 (define_insn "*rotrsi3_1_one_bit"
12808 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12809 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12810 (match_operand:QI 2 "const1_operand" "")))
12811 (clobber (reg:CC FLAGS_REG))]
12812 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12813 && (TARGET_SHIFT1 || optimize_size)"
12815 [(set_attr "type" "rotate")
12816 (set (attr "length")
12817 (if_then_else (match_operand:SI 0 "register_operand" "")
12819 (const_string "*")))])
12821 (define_insn "*rotrsi3_1_one_bit_zext"
12822 [(set (match_operand:DI 0 "register_operand" "=r")
12824 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12825 (match_operand:QI 2 "const1_operand" ""))))
12826 (clobber (reg:CC FLAGS_REG))]
12827 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12828 && (TARGET_SHIFT1 || optimize_size)"
12830 [(set_attr "type" "rotate")
12831 (set (attr "length")
12832 (if_then_else (match_operand:SI 0 "register_operand" "")
12834 (const_string "*")))])
12836 (define_insn "*rotrsi3_1"
12837 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12838 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12839 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12840 (clobber (reg:CC FLAGS_REG))]
12841 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12843 ror{l}\t{%2, %0|%0, %2}
12844 ror{l}\t{%b2, %0|%0, %b2}"
12845 [(set_attr "type" "rotate")
12846 (set_attr "mode" "SI")])
12848 (define_insn "*rotrsi3_1_zext"
12849 [(set (match_operand:DI 0 "register_operand" "=r,r")
12851 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12852 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12853 (clobber (reg:CC FLAGS_REG))]
12854 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12856 ror{l}\t{%2, %k0|%k0, %2}
12857 ror{l}\t{%b2, %k0|%k0, %b2}"
12858 [(set_attr "type" "rotate")
12859 (set_attr "mode" "SI")])
12861 (define_expand "rotrhi3"
12862 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12863 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12864 (match_operand:QI 2 "nonmemory_operand" "")))
12865 (clobber (reg:CC FLAGS_REG))]
12866 "TARGET_HIMODE_MATH"
12867 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12869 (define_insn "*rotrhi3_one_bit"
12870 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12871 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12872 (match_operand:QI 2 "const1_operand" "")))
12873 (clobber (reg:CC FLAGS_REG))]
12874 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12875 && (TARGET_SHIFT1 || optimize_size)"
12877 [(set_attr "type" "rotate")
12878 (set (attr "length")
12879 (if_then_else (match_operand 0 "register_operand" "")
12881 (const_string "*")))])
12883 (define_insn "*rotrhi3"
12884 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12885 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12886 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12887 (clobber (reg:CC FLAGS_REG))]
12888 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12890 ror{w}\t{%2, %0|%0, %2}
12891 ror{w}\t{%b2, %0|%0, %b2}"
12892 [(set_attr "type" "rotate")
12893 (set_attr "mode" "HI")])
12895 (define_expand "rotrqi3"
12896 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12897 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12898 (match_operand:QI 2 "nonmemory_operand" "")))
12899 (clobber (reg:CC FLAGS_REG))]
12900 "TARGET_QIMODE_MATH"
12901 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12903 (define_insn "*rotrqi3_1_one_bit"
12904 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12905 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12906 (match_operand:QI 2 "const1_operand" "")))
12907 (clobber (reg:CC FLAGS_REG))]
12908 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12909 && (TARGET_SHIFT1 || optimize_size)"
12911 [(set_attr "type" "rotate")
12912 (set (attr "length")
12913 (if_then_else (match_operand 0 "register_operand" "")
12915 (const_string "*")))])
12917 (define_insn "*rotrqi3_1_one_bit_slp"
12918 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12919 (rotatert:QI (match_dup 0)
12920 (match_operand:QI 1 "const1_operand" "")))
12921 (clobber (reg:CC FLAGS_REG))]
12922 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12923 && (TARGET_SHIFT1 || optimize_size)"
12925 [(set_attr "type" "rotate1")
12926 (set (attr "length")
12927 (if_then_else (match_operand 0 "register_operand" "")
12929 (const_string "*")))])
12931 (define_insn "*rotrqi3_1"
12932 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12933 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12934 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12935 (clobber (reg:CC FLAGS_REG))]
12936 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12938 ror{b}\t{%2, %0|%0, %2}
12939 ror{b}\t{%b2, %0|%0, %b2}"
12940 [(set_attr "type" "rotate")
12941 (set_attr "mode" "QI")])
12943 (define_insn "*rotrqi3_1_slp"
12944 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12945 (rotatert:QI (match_dup 0)
12946 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12947 (clobber (reg:CC FLAGS_REG))]
12948 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12949 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12951 ror{b}\t{%1, %0|%0, %1}
12952 ror{b}\t{%b1, %0|%0, %b1}"
12953 [(set_attr "type" "rotate1")
12954 (set_attr "mode" "QI")])
12956 ;; Bit set / bit test instructions
12958 (define_expand "extv"
12959 [(set (match_operand:SI 0 "register_operand" "")
12960 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12961 (match_operand:SI 2 "const8_operand" "")
12962 (match_operand:SI 3 "const8_operand" "")))]
12965 /* Handle extractions from %ah et al. */
12966 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12969 /* From mips.md: extract_bit_field doesn't verify that our source
12970 matches the predicate, so check it again here. */
12971 if (! ext_register_operand (operands[1], VOIDmode))
12975 (define_expand "extzv"
12976 [(set (match_operand:SI 0 "register_operand" "")
12977 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12978 (match_operand:SI 2 "const8_operand" "")
12979 (match_operand:SI 3 "const8_operand" "")))]
12982 /* Handle extractions from %ah et al. */
12983 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12986 /* From mips.md: extract_bit_field doesn't verify that our source
12987 matches the predicate, so check it again here. */
12988 if (! ext_register_operand (operands[1], VOIDmode))
12992 (define_expand "insv"
12993 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12994 (match_operand 1 "const8_operand" "")
12995 (match_operand 2 "const8_operand" ""))
12996 (match_operand 3 "register_operand" ""))]
12999 /* Handle insertions to %ah et al. */
13000 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13003 /* From mips.md: insert_bit_field doesn't verify that our source
13004 matches the predicate, so check it again here. */
13005 if (! ext_register_operand (operands[0], VOIDmode))
13009 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13011 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13016 ;; %%% bts, btr, btc, bt.
13017 ;; In general these instructions are *slow* when applied to memory,
13018 ;; since they enforce atomic operation. When applied to registers,
13019 ;; it depends on the cpu implementation. They're never faster than
13020 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13021 ;; no point. But in 64-bit, we can't hold the relevant immediates
13022 ;; within the instruction itself, so operating on bits in the high
13023 ;; 32-bits of a register becomes easier.
13025 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13026 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13027 ;; negdf respectively, so they can never be disabled entirely.
13029 (define_insn "*btsq"
13030 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13032 (match_operand:DI 1 "const_0_to_63_operand" ""))
13034 (clobber (reg:CC FLAGS_REG))]
13035 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13037 [(set_attr "type" "alu1")])
13039 (define_insn "*btrq"
13040 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13042 (match_operand:DI 1 "const_0_to_63_operand" ""))
13044 (clobber (reg:CC FLAGS_REG))]
13045 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13047 [(set_attr "type" "alu1")])
13049 (define_insn "*btcq"
13050 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13052 (match_operand:DI 1 "const_0_to_63_operand" ""))
13053 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13054 (clobber (reg:CC FLAGS_REG))]
13055 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13057 [(set_attr "type" "alu1")])
13059 ;; Allow Nocona to avoid these instructions if a register is available.
13062 [(match_scratch:DI 2 "r")
13063 (parallel [(set (zero_extract:DI
13064 (match_operand:DI 0 "register_operand" "")
13066 (match_operand:DI 1 "const_0_to_63_operand" ""))
13068 (clobber (reg:CC FLAGS_REG))])]
13069 "TARGET_64BIT && !TARGET_USE_BT"
13072 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13075 if (HOST_BITS_PER_WIDE_INT >= 64)
13076 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13077 else if (i < HOST_BITS_PER_WIDE_INT)
13078 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13080 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13082 op1 = immed_double_const (lo, hi, DImode);
13085 emit_move_insn (operands[2], op1);
13089 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13094 [(match_scratch:DI 2 "r")
13095 (parallel [(set (zero_extract:DI
13096 (match_operand:DI 0 "register_operand" "")
13098 (match_operand:DI 1 "const_0_to_63_operand" ""))
13100 (clobber (reg:CC FLAGS_REG))])]
13101 "TARGET_64BIT && !TARGET_USE_BT"
13104 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13107 if (HOST_BITS_PER_WIDE_INT >= 64)
13108 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13109 else if (i < HOST_BITS_PER_WIDE_INT)
13110 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13112 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13114 op1 = immed_double_const (~lo, ~hi, DImode);
13117 emit_move_insn (operands[2], op1);
13121 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13126 [(match_scratch:DI 2 "r")
13127 (parallel [(set (zero_extract:DI
13128 (match_operand:DI 0 "register_operand" "")
13130 (match_operand:DI 1 "const_0_to_63_operand" ""))
13131 (not:DI (zero_extract:DI
13132 (match_dup 0) (const_int 1) (match_dup 1))))
13133 (clobber (reg:CC FLAGS_REG))])]
13134 "TARGET_64BIT && !TARGET_USE_BT"
13137 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13140 if (HOST_BITS_PER_WIDE_INT >= 64)
13141 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13142 else if (i < HOST_BITS_PER_WIDE_INT)
13143 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13145 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13147 op1 = immed_double_const (lo, hi, DImode);
13150 emit_move_insn (operands[2], op1);
13154 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13158 ;; Store-flag instructions.
13160 ;; For all sCOND expanders, also expand the compare or test insn that
13161 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13163 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13164 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13165 ;; way, which can later delete the movzx if only QImode is needed.
13167 (define_expand "seq"
13168 [(set (match_operand:QI 0 "register_operand" "")
13169 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13171 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13173 (define_expand "sne"
13174 [(set (match_operand:QI 0 "register_operand" "")
13175 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13177 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13179 (define_expand "sgt"
13180 [(set (match_operand:QI 0 "register_operand" "")
13181 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13183 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13185 (define_expand "sgtu"
13186 [(set (match_operand:QI 0 "register_operand" "")
13187 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13189 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13191 (define_expand "slt"
13192 [(set (match_operand:QI 0 "register_operand" "")
13193 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13195 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13197 (define_expand "sltu"
13198 [(set (match_operand:QI 0 "register_operand" "")
13199 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13201 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13203 (define_expand "sge"
13204 [(set (match_operand:QI 0 "register_operand" "")
13205 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13207 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13209 (define_expand "sgeu"
13210 [(set (match_operand:QI 0 "register_operand" "")
13211 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13213 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13215 (define_expand "sle"
13216 [(set (match_operand:QI 0 "register_operand" "")
13217 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13219 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13221 (define_expand "sleu"
13222 [(set (match_operand:QI 0 "register_operand" "")
13223 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13225 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13227 (define_expand "sunordered"
13228 [(set (match_operand:QI 0 "register_operand" "")
13229 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13230 "TARGET_80387 || TARGET_SSE"
13231 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13233 (define_expand "sordered"
13234 [(set (match_operand:QI 0 "register_operand" "")
13235 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13237 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13239 (define_expand "suneq"
13240 [(set (match_operand:QI 0 "register_operand" "")
13241 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13242 "TARGET_80387 || TARGET_SSE"
13243 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13245 (define_expand "sunge"
13246 [(set (match_operand:QI 0 "register_operand" "")
13247 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13248 "TARGET_80387 || TARGET_SSE"
13249 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13251 (define_expand "sungt"
13252 [(set (match_operand:QI 0 "register_operand" "")
13253 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13254 "TARGET_80387 || TARGET_SSE"
13255 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13257 (define_expand "sunle"
13258 [(set (match_operand:QI 0 "register_operand" "")
13259 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13260 "TARGET_80387 || TARGET_SSE"
13261 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13263 (define_expand "sunlt"
13264 [(set (match_operand:QI 0 "register_operand" "")
13265 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13266 "TARGET_80387 || TARGET_SSE"
13267 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13269 (define_expand "sltgt"
13270 [(set (match_operand:QI 0 "register_operand" "")
13271 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13272 "TARGET_80387 || TARGET_SSE"
13273 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13275 (define_insn "*setcc_1"
13276 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13277 (match_operator:QI 1 "ix86_comparison_operator"
13278 [(reg FLAGS_REG) (const_int 0)]))]
13281 [(set_attr "type" "setcc")
13282 (set_attr "mode" "QI")])
13284 (define_insn "*setcc_2"
13285 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13286 (match_operator:QI 1 "ix86_comparison_operator"
13287 [(reg FLAGS_REG) (const_int 0)]))]
13290 [(set_attr "type" "setcc")
13291 (set_attr "mode" "QI")])
13293 ;; In general it is not safe to assume too much about CCmode registers,
13294 ;; so simplify-rtx stops when it sees a second one. Under certain
13295 ;; conditions this is safe on x86, so help combine not create
13302 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13303 (ne:QI (match_operator 1 "ix86_comparison_operator"
13304 [(reg FLAGS_REG) (const_int 0)])
13307 [(set (match_dup 0) (match_dup 1))]
13309 PUT_MODE (operands[1], QImode);
13313 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13314 (ne:QI (match_operator 1 "ix86_comparison_operator"
13315 [(reg FLAGS_REG) (const_int 0)])
13318 [(set (match_dup 0) (match_dup 1))]
13320 PUT_MODE (operands[1], QImode);
13324 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13325 (eq:QI (match_operator 1 "ix86_comparison_operator"
13326 [(reg FLAGS_REG) (const_int 0)])
13329 [(set (match_dup 0) (match_dup 1))]
13331 rtx new_op1 = copy_rtx (operands[1]);
13332 operands[1] = new_op1;
13333 PUT_MODE (new_op1, QImode);
13334 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13335 GET_MODE (XEXP (new_op1, 0))));
13337 /* Make sure that (a) the CCmode we have for the flags is strong
13338 enough for the reversed compare or (b) we have a valid FP compare. */
13339 if (! ix86_comparison_operator (new_op1, VOIDmode))
13344 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13345 (eq:QI (match_operator 1 "ix86_comparison_operator"
13346 [(reg FLAGS_REG) (const_int 0)])
13349 [(set (match_dup 0) (match_dup 1))]
13351 rtx new_op1 = copy_rtx (operands[1]);
13352 operands[1] = new_op1;
13353 PUT_MODE (new_op1, QImode);
13354 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13355 GET_MODE (XEXP (new_op1, 0))));
13357 /* Make sure that (a) the CCmode we have for the flags is strong
13358 enough for the reversed compare or (b) we have a valid FP compare. */
13359 if (! ix86_comparison_operator (new_op1, VOIDmode))
13363 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13364 ;; subsequent logical operations are used to imitate conditional moves.
13365 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13368 (define_insn "*sse_setccsf"
13369 [(set (match_operand:SF 0 "register_operand" "=x")
13370 (match_operator:SF 1 "sse_comparison_operator"
13371 [(match_operand:SF 2 "register_operand" "0")
13372 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13374 "cmp%D1ss\t{%3, %0|%0, %3}"
13375 [(set_attr "type" "ssecmp")
13376 (set_attr "mode" "SF")])
13378 (define_insn "*sse_setccdf"
13379 [(set (match_operand:DF 0 "register_operand" "=Y")
13380 (match_operator:DF 1 "sse_comparison_operator"
13381 [(match_operand:DF 2 "register_operand" "0")
13382 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13384 "cmp%D1sd\t{%3, %0|%0, %3}"
13385 [(set_attr "type" "ssecmp")
13386 (set_attr "mode" "DF")])
13388 ;; Basic conditional jump instructions.
13389 ;; We ignore the overflow flag for signed branch instructions.
13391 ;; For all bCOND expanders, also expand the compare or test insn that
13392 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13394 (define_expand "beq"
13396 (if_then_else (match_dup 1)
13397 (label_ref (match_operand 0 "" ""))
13400 "ix86_expand_branch (EQ, operands[0]); DONE;")
13402 (define_expand "bne"
13404 (if_then_else (match_dup 1)
13405 (label_ref (match_operand 0 "" ""))
13408 "ix86_expand_branch (NE, operands[0]); DONE;")
13410 (define_expand "bgt"
13412 (if_then_else (match_dup 1)
13413 (label_ref (match_operand 0 "" ""))
13416 "ix86_expand_branch (GT, operands[0]); DONE;")
13418 (define_expand "bgtu"
13420 (if_then_else (match_dup 1)
13421 (label_ref (match_operand 0 "" ""))
13424 "ix86_expand_branch (GTU, operands[0]); DONE;")
13426 (define_expand "blt"
13428 (if_then_else (match_dup 1)
13429 (label_ref (match_operand 0 "" ""))
13432 "ix86_expand_branch (LT, operands[0]); DONE;")
13434 (define_expand "bltu"
13436 (if_then_else (match_dup 1)
13437 (label_ref (match_operand 0 "" ""))
13440 "ix86_expand_branch (LTU, operands[0]); DONE;")
13442 (define_expand "bge"
13444 (if_then_else (match_dup 1)
13445 (label_ref (match_operand 0 "" ""))
13448 "ix86_expand_branch (GE, operands[0]); DONE;")
13450 (define_expand "bgeu"
13452 (if_then_else (match_dup 1)
13453 (label_ref (match_operand 0 "" ""))
13456 "ix86_expand_branch (GEU, operands[0]); DONE;")
13458 (define_expand "ble"
13460 (if_then_else (match_dup 1)
13461 (label_ref (match_operand 0 "" ""))
13464 "ix86_expand_branch (LE, operands[0]); DONE;")
13466 (define_expand "bleu"
13468 (if_then_else (match_dup 1)
13469 (label_ref (match_operand 0 "" ""))
13472 "ix86_expand_branch (LEU, operands[0]); DONE;")
13474 (define_expand "bunordered"
13476 (if_then_else (match_dup 1)
13477 (label_ref (match_operand 0 "" ""))
13479 "TARGET_80387 || TARGET_SSE_MATH"
13480 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13482 (define_expand "bordered"
13484 (if_then_else (match_dup 1)
13485 (label_ref (match_operand 0 "" ""))
13487 "TARGET_80387 || TARGET_SSE_MATH"
13488 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13490 (define_expand "buneq"
13492 (if_then_else (match_dup 1)
13493 (label_ref (match_operand 0 "" ""))
13495 "TARGET_80387 || TARGET_SSE_MATH"
13496 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13498 (define_expand "bunge"
13500 (if_then_else (match_dup 1)
13501 (label_ref (match_operand 0 "" ""))
13503 "TARGET_80387 || TARGET_SSE_MATH"
13504 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13506 (define_expand "bungt"
13508 (if_then_else (match_dup 1)
13509 (label_ref (match_operand 0 "" ""))
13511 "TARGET_80387 || TARGET_SSE_MATH"
13512 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13514 (define_expand "bunle"
13516 (if_then_else (match_dup 1)
13517 (label_ref (match_operand 0 "" ""))
13519 "TARGET_80387 || TARGET_SSE_MATH"
13520 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13522 (define_expand "bunlt"
13524 (if_then_else (match_dup 1)
13525 (label_ref (match_operand 0 "" ""))
13527 "TARGET_80387 || TARGET_SSE_MATH"
13528 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13530 (define_expand "bltgt"
13532 (if_then_else (match_dup 1)
13533 (label_ref (match_operand 0 "" ""))
13535 "TARGET_80387 || TARGET_SSE_MATH"
13536 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13538 (define_insn "*jcc_1"
13540 (if_then_else (match_operator 1 "ix86_comparison_operator"
13541 [(reg FLAGS_REG) (const_int 0)])
13542 (label_ref (match_operand 0 "" ""))
13546 [(set_attr "type" "ibr")
13547 (set_attr "modrm" "0")
13548 (set (attr "length")
13549 (if_then_else (and (ge (minus (match_dup 0) (pc))
13551 (lt (minus (match_dup 0) (pc))
13556 (define_insn "*jcc_2"
13558 (if_then_else (match_operator 1 "ix86_comparison_operator"
13559 [(reg FLAGS_REG) (const_int 0)])
13561 (label_ref (match_operand 0 "" ""))))]
13564 [(set_attr "type" "ibr")
13565 (set_attr "modrm" "0")
13566 (set (attr "length")
13567 (if_then_else (and (ge (minus (match_dup 0) (pc))
13569 (lt (minus (match_dup 0) (pc))
13574 ;; In general it is not safe to assume too much about CCmode registers,
13575 ;; so simplify-rtx stops when it sees a second one. Under certain
13576 ;; conditions this is safe on x86, so help combine not create
13584 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13585 [(reg FLAGS_REG) (const_int 0)])
13587 (label_ref (match_operand 1 "" ""))
13591 (if_then_else (match_dup 0)
13592 (label_ref (match_dup 1))
13595 PUT_MODE (operands[0], VOIDmode);
13600 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13601 [(reg FLAGS_REG) (const_int 0)])
13603 (label_ref (match_operand 1 "" ""))
13607 (if_then_else (match_dup 0)
13608 (label_ref (match_dup 1))
13611 rtx new_op0 = copy_rtx (operands[0]);
13612 operands[0] = new_op0;
13613 PUT_MODE (new_op0, VOIDmode);
13614 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13615 GET_MODE (XEXP (new_op0, 0))));
13617 /* Make sure that (a) the CCmode we have for the flags is strong
13618 enough for the reversed compare or (b) we have a valid FP compare. */
13619 if (! ix86_comparison_operator (new_op0, VOIDmode))
13623 ;; Define combination compare-and-branch fp compare instructions to use
13624 ;; during early optimization. Splitting the operation apart early makes
13625 ;; for bad code when we want to reverse the operation.
13627 (define_insn "*fp_jcc_1_mixed"
13629 (if_then_else (match_operator 0 "comparison_operator"
13630 [(match_operand 1 "register_operand" "f,x")
13631 (match_operand 2 "nonimmediate_operand" "f,xm")])
13632 (label_ref (match_operand 3 "" ""))
13634 (clobber (reg:CCFP FPSR_REG))
13635 (clobber (reg:CCFP FLAGS_REG))]
13636 "TARGET_MIX_SSE_I387
13637 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13638 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13639 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13642 (define_insn "*fp_jcc_1_sse"
13644 (if_then_else (match_operator 0 "comparison_operator"
13645 [(match_operand 1 "register_operand" "x")
13646 (match_operand 2 "nonimmediate_operand" "xm")])
13647 (label_ref (match_operand 3 "" ""))
13649 (clobber (reg:CCFP FPSR_REG))
13650 (clobber (reg:CCFP FLAGS_REG))]
13652 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13653 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13654 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13657 (define_insn "*fp_jcc_1_387"
13659 (if_then_else (match_operator 0 "comparison_operator"
13660 [(match_operand 1 "register_operand" "f")
13661 (match_operand 2 "register_operand" "f")])
13662 (label_ref (match_operand 3 "" ""))
13664 (clobber (reg:CCFP FPSR_REG))
13665 (clobber (reg:CCFP FLAGS_REG))]
13666 "TARGET_CMOVE && TARGET_80387
13667 && FLOAT_MODE_P (GET_MODE (operands[1]))
13668 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13669 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13672 (define_insn "*fp_jcc_2_mixed"
13674 (if_then_else (match_operator 0 "comparison_operator"
13675 [(match_operand 1 "register_operand" "f,x")
13676 (match_operand 2 "nonimmediate_operand" "f,xm")])
13678 (label_ref (match_operand 3 "" ""))))
13679 (clobber (reg:CCFP FPSR_REG))
13680 (clobber (reg:CCFP FLAGS_REG))]
13681 "TARGET_MIX_SSE_I387
13682 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13683 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13684 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13687 (define_insn "*fp_jcc_2_sse"
13689 (if_then_else (match_operator 0 "comparison_operator"
13690 [(match_operand 1 "register_operand" "x")
13691 (match_operand 2 "nonimmediate_operand" "xm")])
13693 (label_ref (match_operand 3 "" ""))))
13694 (clobber (reg:CCFP FPSR_REG))
13695 (clobber (reg:CCFP FLAGS_REG))]
13697 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13698 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13699 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13702 (define_insn "*fp_jcc_2_387"
13704 (if_then_else (match_operator 0 "comparison_operator"
13705 [(match_operand 1 "register_operand" "f")
13706 (match_operand 2 "register_operand" "f")])
13708 (label_ref (match_operand 3 "" ""))))
13709 (clobber (reg:CCFP FPSR_REG))
13710 (clobber (reg:CCFP FLAGS_REG))]
13711 "TARGET_CMOVE && TARGET_80387
13712 && FLOAT_MODE_P (GET_MODE (operands[1]))
13713 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13714 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13717 (define_insn "*fp_jcc_3_387"
13719 (if_then_else (match_operator 0 "comparison_operator"
13720 [(match_operand 1 "register_operand" "f")
13721 (match_operand 2 "nonimmediate_operand" "fm")])
13722 (label_ref (match_operand 3 "" ""))
13724 (clobber (reg:CCFP FPSR_REG))
13725 (clobber (reg:CCFP FLAGS_REG))
13726 (clobber (match_scratch:HI 4 "=a"))]
13728 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13729 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13730 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13731 && SELECT_CC_MODE (GET_CODE (operands[0]),
13732 operands[1], operands[2]) == CCFPmode
13733 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13736 (define_insn "*fp_jcc_4_387"
13738 (if_then_else (match_operator 0 "comparison_operator"
13739 [(match_operand 1 "register_operand" "f")
13740 (match_operand 2 "nonimmediate_operand" "fm")])
13742 (label_ref (match_operand 3 "" ""))))
13743 (clobber (reg:CCFP FPSR_REG))
13744 (clobber (reg:CCFP FLAGS_REG))
13745 (clobber (match_scratch:HI 4 "=a"))]
13747 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13748 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13749 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13750 && SELECT_CC_MODE (GET_CODE (operands[0]),
13751 operands[1], operands[2]) == CCFPmode
13752 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13755 (define_insn "*fp_jcc_5_387"
13757 (if_then_else (match_operator 0 "comparison_operator"
13758 [(match_operand 1 "register_operand" "f")
13759 (match_operand 2 "register_operand" "f")])
13760 (label_ref (match_operand 3 "" ""))
13762 (clobber (reg:CCFP FPSR_REG))
13763 (clobber (reg:CCFP FLAGS_REG))
13764 (clobber (match_scratch:HI 4 "=a"))]
13766 && FLOAT_MODE_P (GET_MODE (operands[1]))
13767 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13768 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13771 (define_insn "*fp_jcc_6_387"
13773 (if_then_else (match_operator 0 "comparison_operator"
13774 [(match_operand 1 "register_operand" "f")
13775 (match_operand 2 "register_operand" "f")])
13777 (label_ref (match_operand 3 "" ""))))
13778 (clobber (reg:CCFP FPSR_REG))
13779 (clobber (reg:CCFP FLAGS_REG))
13780 (clobber (match_scratch:HI 4 "=a"))]
13782 && FLOAT_MODE_P (GET_MODE (operands[1]))
13783 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13784 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13787 (define_insn "*fp_jcc_7_387"
13789 (if_then_else (match_operator 0 "comparison_operator"
13790 [(match_operand 1 "register_operand" "f")
13791 (match_operand 2 "const0_operand" "X")])
13792 (label_ref (match_operand 3 "" ""))
13794 (clobber (reg:CCFP FPSR_REG))
13795 (clobber (reg:CCFP FLAGS_REG))
13796 (clobber (match_scratch:HI 4 "=a"))]
13798 && FLOAT_MODE_P (GET_MODE (operands[1]))
13799 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13800 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13801 && SELECT_CC_MODE (GET_CODE (operands[0]),
13802 operands[1], operands[2]) == CCFPmode
13803 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13806 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13807 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13808 ;; with a precedence over other operators and is always put in the first
13809 ;; place. Swap condition and operands to match ficom instruction.
13811 (define_insn "*fp_jcc_8<mode>_387"
13813 (if_then_else (match_operator 0 "comparison_operator"
13814 [(match_operator 1 "float_operator"
13815 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13816 (match_operand 3 "register_operand" "f,f")])
13817 (label_ref (match_operand 4 "" ""))
13819 (clobber (reg:CCFP FPSR_REG))
13820 (clobber (reg:CCFP FLAGS_REG))
13821 (clobber (match_scratch:HI 5 "=a,a"))]
13822 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13823 && FLOAT_MODE_P (GET_MODE (operands[3]))
13824 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13825 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13826 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13827 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13832 (if_then_else (match_operator 0 "comparison_operator"
13833 [(match_operand 1 "register_operand" "")
13834 (match_operand 2 "nonimmediate_operand" "")])
13835 (match_operand 3 "" "")
13836 (match_operand 4 "" "")))
13837 (clobber (reg:CCFP FPSR_REG))
13838 (clobber (reg:CCFP FLAGS_REG))]
13842 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13843 operands[3], operands[4], NULL_RTX, NULL_RTX);
13849 (if_then_else (match_operator 0 "comparison_operator"
13850 [(match_operand 1 "register_operand" "")
13851 (match_operand 2 "general_operand" "")])
13852 (match_operand 3 "" "")
13853 (match_operand 4 "" "")))
13854 (clobber (reg:CCFP FPSR_REG))
13855 (clobber (reg:CCFP FLAGS_REG))
13856 (clobber (match_scratch:HI 5 "=a"))]
13860 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13861 operands[3], operands[4], operands[5], NULL_RTX);
13867 (if_then_else (match_operator 0 "comparison_operator"
13868 [(match_operator 1 "float_operator"
13869 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13870 (match_operand 3 "register_operand" "")])
13871 (match_operand 4 "" "")
13872 (match_operand 5 "" "")))
13873 (clobber (reg:CCFP FPSR_REG))
13874 (clobber (reg:CCFP FLAGS_REG))
13875 (clobber (match_scratch:HI 6 "=a"))]
13879 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13880 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13881 operands[3], operands[7],
13882 operands[4], operands[5], operands[6], NULL_RTX);
13886 ;; %%% Kill this when reload knows how to do it.
13889 (if_then_else (match_operator 0 "comparison_operator"
13890 [(match_operator 1 "float_operator"
13891 [(match_operand:X87MODEI12 2 "register_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] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13902 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13903 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13904 operands[3], operands[7],
13905 operands[4], operands[5], operands[6], operands[2]);
13909 ;; Unconditional and other jump instructions
13911 (define_insn "jump"
13913 (label_ref (match_operand 0 "" "")))]
13916 [(set_attr "type" "ibr")
13917 (set (attr "length")
13918 (if_then_else (and (ge (minus (match_dup 0) (pc))
13920 (lt (minus (match_dup 0) (pc))
13924 (set_attr "modrm" "0")])
13926 (define_expand "indirect_jump"
13927 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13931 (define_insn "*indirect_jump"
13932 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13935 [(set_attr "type" "ibr")
13936 (set_attr "length_immediate" "0")])
13938 (define_insn "*indirect_jump_rtx64"
13939 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13942 [(set_attr "type" "ibr")
13943 (set_attr "length_immediate" "0")])
13945 (define_expand "tablejump"
13946 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13947 (use (label_ref (match_operand 1 "" "")))])]
13950 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13951 relative. Convert the relative address to an absolute address. */
13955 enum rtx_code code;
13961 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13963 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13967 op1 = pic_offset_table_rtx;
13972 op0 = pic_offset_table_rtx;
13976 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13981 (define_insn "*tablejump_1"
13982 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13983 (use (label_ref (match_operand 1 "" "")))]
13986 [(set_attr "type" "ibr")
13987 (set_attr "length_immediate" "0")])
13989 (define_insn "*tablejump_1_rtx64"
13990 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13991 (use (label_ref (match_operand 1 "" "")))]
13994 [(set_attr "type" "ibr")
13995 (set_attr "length_immediate" "0")])
13997 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14000 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14001 (set (match_operand:QI 1 "register_operand" "")
14002 (match_operator:QI 2 "ix86_comparison_operator"
14003 [(reg FLAGS_REG) (const_int 0)]))
14004 (set (match_operand 3 "q_regs_operand" "")
14005 (zero_extend (match_dup 1)))]
14006 "(peep2_reg_dead_p (3, operands[1])
14007 || operands_match_p (operands[1], operands[3]))
14008 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14009 [(set (match_dup 4) (match_dup 0))
14010 (set (strict_low_part (match_dup 5))
14013 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14014 operands[5] = gen_lowpart (QImode, operands[3]);
14015 ix86_expand_clear (operands[3]);
14018 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14021 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14022 (set (match_operand:QI 1 "register_operand" "")
14023 (match_operator:QI 2 "ix86_comparison_operator"
14024 [(reg FLAGS_REG) (const_int 0)]))
14025 (parallel [(set (match_operand 3 "q_regs_operand" "")
14026 (zero_extend (match_dup 1)))
14027 (clobber (reg:CC FLAGS_REG))])]
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 ;; Call instructions.
14042 ;; The predicates normally associated with named expanders are not properly
14043 ;; checked for calls. This is a bug in the generic code, but it isn't that
14044 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14046 ;; Call subroutine returning no value.
14048 (define_expand "call_pop"
14049 [(parallel [(call (match_operand:QI 0 "" "")
14050 (match_operand:SI 1 "" ""))
14051 (set (reg:SI SP_REG)
14052 (plus:SI (reg:SI SP_REG)
14053 (match_operand:SI 3 "" "")))])]
14056 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14060 (define_insn "*call_pop_0"
14061 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14062 (match_operand:SI 1 "" ""))
14063 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14064 (match_operand:SI 2 "immediate_operand" "")))]
14067 if (SIBLING_CALL_P (insn))
14070 return "call\t%P0";
14072 [(set_attr "type" "call")])
14074 (define_insn "*call_pop_1"
14075 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14076 (match_operand:SI 1 "" ""))
14077 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14078 (match_operand:SI 2 "immediate_operand" "i")))]
14081 if (constant_call_address_operand (operands[0], Pmode))
14083 if (SIBLING_CALL_P (insn))
14086 return "call\t%P0";
14088 if (SIBLING_CALL_P (insn))
14091 return "call\t%A0";
14093 [(set_attr "type" "call")])
14095 (define_expand "call"
14096 [(call (match_operand:QI 0 "" "")
14097 (match_operand 1 "" ""))
14098 (use (match_operand 2 "" ""))]
14101 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14105 (define_expand "sibcall"
14106 [(call (match_operand:QI 0 "" "")
14107 (match_operand 1 "" ""))
14108 (use (match_operand 2 "" ""))]
14111 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14115 (define_insn "*call_0"
14116 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14117 (match_operand 1 "" ""))]
14120 if (SIBLING_CALL_P (insn))
14123 return "call\t%P0";
14125 [(set_attr "type" "call")])
14127 (define_insn "*call_1"
14128 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14129 (match_operand 1 "" ""))]
14130 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14132 if (constant_call_address_operand (operands[0], Pmode))
14133 return "call\t%P0";
14134 return "call\t%A0";
14136 [(set_attr "type" "call")])
14138 (define_insn "*sibcall_1"
14139 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14140 (match_operand 1 "" ""))]
14141 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14143 if (constant_call_address_operand (operands[0], Pmode))
14147 [(set_attr "type" "call")])
14149 (define_insn "*call_1_rex64"
14150 [(call (mem:QI (match_operand:DI 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_rex64"
14161 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14162 (match_operand 1 "" ""))]
14163 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14165 [(set_attr "type" "call")])
14167 (define_insn "*sibcall_1_rex64_v"
14168 [(call (mem:QI (reg:DI R11_REG))
14169 (match_operand 0 "" ""))]
14170 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14172 [(set_attr "type" "call")])
14175 ;; Call subroutine, returning value in operand 0
14177 (define_expand "call_value_pop"
14178 [(parallel [(set (match_operand 0 "" "")
14179 (call (match_operand:QI 1 "" "")
14180 (match_operand:SI 2 "" "")))
14181 (set (reg:SI SP_REG)
14182 (plus:SI (reg:SI SP_REG)
14183 (match_operand:SI 4 "" "")))])]
14186 ix86_expand_call (operands[0], operands[1], operands[2],
14187 operands[3], operands[4], 0);
14191 (define_expand "call_value"
14192 [(set (match_operand 0 "" "")
14193 (call (match_operand:QI 1 "" "")
14194 (match_operand:SI 2 "" "")))
14195 (use (match_operand:SI 3 "" ""))]
14196 ;; Operand 2 not used on the i386.
14199 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14203 (define_expand "sibcall_value"
14204 [(set (match_operand 0 "" "")
14205 (call (match_operand:QI 1 "" "")
14206 (match_operand:SI 2 "" "")))
14207 (use (match_operand:SI 3 "" ""))]
14208 ;; Operand 2 not used on the i386.
14211 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14215 ;; Call subroutine returning any type.
14217 (define_expand "untyped_call"
14218 [(parallel [(call (match_operand 0 "" "")
14220 (match_operand 1 "" "")
14221 (match_operand 2 "" "")])]
14226 /* In order to give reg-stack an easier job in validating two
14227 coprocessor registers as containing a possible return value,
14228 simply pretend the untyped call returns a complex long double
14231 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14232 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14233 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14236 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14238 rtx set = XVECEXP (operands[2], 0, i);
14239 emit_move_insn (SET_DEST (set), SET_SRC (set));
14242 /* The optimizer does not know that the call sets the function value
14243 registers we stored in the result block. We avoid problems by
14244 claiming that all hard registers are used and clobbered at this
14246 emit_insn (gen_blockage (const0_rtx));
14251 ;; Prologue and epilogue instructions
14253 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14254 ;; all of memory. This blocks insns from being moved across this point.
14256 (define_insn "blockage"
14257 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14260 [(set_attr "length" "0")])
14262 ;; Insn emitted into the body of a function to return from a function.
14263 ;; This is only done if the function's epilogue is known to be simple.
14264 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14266 (define_expand "return"
14268 "ix86_can_use_return_insn_p ()"
14270 if (current_function_pops_args)
14272 rtx popc = GEN_INT (current_function_pops_args);
14273 emit_jump_insn (gen_return_pop_internal (popc));
14278 (define_insn "return_internal"
14282 [(set_attr "length" "1")
14283 (set_attr "length_immediate" "0")
14284 (set_attr "modrm" "0")])
14286 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14287 ;; instruction Athlon and K8 have.
14289 (define_insn "return_internal_long"
14291 (unspec [(const_int 0)] UNSPEC_REP)]
14294 [(set_attr "length" "1")
14295 (set_attr "length_immediate" "0")
14296 (set_attr "prefix_rep" "1")
14297 (set_attr "modrm" "0")])
14299 (define_insn "return_pop_internal"
14301 (use (match_operand:SI 0 "const_int_operand" ""))]
14304 [(set_attr "length" "3")
14305 (set_attr "length_immediate" "2")
14306 (set_attr "modrm" "0")])
14308 (define_insn "return_indirect_internal"
14310 (use (match_operand:SI 0 "register_operand" "r"))]
14313 [(set_attr "type" "ibr")
14314 (set_attr "length_immediate" "0")])
14320 [(set_attr "length" "1")
14321 (set_attr "length_immediate" "0")
14322 (set_attr "modrm" "0")])
14324 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14325 ;; branch prediction penalty for the third jump in a 16-byte
14328 (define_insn "align"
14329 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14332 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14333 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14335 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14336 The align insn is used to avoid 3 jump instructions in the row to improve
14337 branch prediction and the benefits hardly outweigh the cost of extra 8
14338 nops on the average inserted by full alignment pseudo operation. */
14342 [(set_attr "length" "16")])
14344 (define_expand "prologue"
14347 "ix86_expand_prologue (); DONE;")
14349 (define_insn "set_got"
14350 [(set (match_operand:SI 0 "register_operand" "=r")
14351 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14352 (clobber (reg:CC FLAGS_REG))]
14354 { return output_set_got (operands[0], NULL_RTX); }
14355 [(set_attr "type" "multi")
14356 (set_attr "length" "12")])
14358 (define_insn "set_got_labelled"
14359 [(set (match_operand:SI 0 "register_operand" "=r")
14360 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14362 (clobber (reg:CC FLAGS_REG))]
14364 { return output_set_got (operands[0], operands[1]); }
14365 [(set_attr "type" "multi")
14366 (set_attr "length" "12")])
14368 (define_insn "set_got_rex64"
14369 [(set (match_operand:DI 0 "register_operand" "=r")
14370 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14372 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14373 [(set_attr "type" "lea")
14374 (set_attr "length" "6")])
14376 (define_expand "epilogue"
14379 "ix86_expand_epilogue (1); DONE;")
14381 (define_expand "sibcall_epilogue"
14384 "ix86_expand_epilogue (0); DONE;")
14386 (define_expand "eh_return"
14387 [(use (match_operand 0 "register_operand" ""))]
14390 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14392 /* Tricky bit: we write the address of the handler to which we will
14393 be returning into someone else's stack frame, one word below the
14394 stack address we wish to restore. */
14395 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14396 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14397 tmp = gen_rtx_MEM (Pmode, tmp);
14398 emit_move_insn (tmp, ra);
14400 if (Pmode == SImode)
14401 emit_jump_insn (gen_eh_return_si (sa));
14403 emit_jump_insn (gen_eh_return_di (sa));
14408 (define_insn_and_split "eh_return_si"
14410 (unspec [(match_operand:SI 0 "register_operand" "c")]
14411 UNSPEC_EH_RETURN))]
14416 "ix86_expand_epilogue (2); DONE;")
14418 (define_insn_and_split "eh_return_di"
14420 (unspec [(match_operand:DI 0 "register_operand" "c")]
14421 UNSPEC_EH_RETURN))]
14426 "ix86_expand_epilogue (2); DONE;")
14428 (define_insn "leave"
14429 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14430 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14431 (clobber (mem:BLK (scratch)))]
14434 [(set_attr "type" "leave")])
14436 (define_insn "leave_rex64"
14437 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14438 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14439 (clobber (mem:BLK (scratch)))]
14442 [(set_attr "type" "leave")])
14444 (define_expand "ffssi2"
14446 [(set (match_operand:SI 0 "register_operand" "")
14447 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14448 (clobber (match_scratch:SI 2 ""))
14449 (clobber (reg:CC FLAGS_REG))])]
14453 (define_insn_and_split "*ffs_cmove"
14454 [(set (match_operand:SI 0 "register_operand" "=r")
14455 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14456 (clobber (match_scratch:SI 2 "=&r"))
14457 (clobber (reg:CC FLAGS_REG))]
14460 "&& reload_completed"
14461 [(set (match_dup 2) (const_int -1))
14462 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14463 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14464 (set (match_dup 0) (if_then_else:SI
14465 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14468 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14469 (clobber (reg:CC FLAGS_REG))])]
14472 (define_insn_and_split "*ffs_no_cmove"
14473 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14474 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14475 (clobber (match_scratch:SI 2 "=&q"))
14476 (clobber (reg:CC FLAGS_REG))]
14480 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14481 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14482 (set (strict_low_part (match_dup 3))
14483 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14484 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14485 (clobber (reg:CC FLAGS_REG))])
14486 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14487 (clobber (reg:CC FLAGS_REG))])
14488 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14489 (clobber (reg:CC FLAGS_REG))])]
14491 operands[3] = gen_lowpart (QImode, operands[2]);
14492 ix86_expand_clear (operands[2]);
14495 (define_insn "*ffssi_1"
14496 [(set (reg:CCZ FLAGS_REG)
14497 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14499 (set (match_operand:SI 0 "register_operand" "=r")
14500 (ctz:SI (match_dup 1)))]
14502 "bsf{l}\t{%1, %0|%0, %1}"
14503 [(set_attr "prefix_0f" "1")])
14505 (define_expand "ffsdi2"
14507 [(set (match_operand:DI 0 "register_operand" "")
14508 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14509 (clobber (match_scratch:DI 2 ""))
14510 (clobber (reg:CC FLAGS_REG))])]
14511 "TARGET_64BIT && TARGET_CMOVE"
14514 (define_insn_and_split "*ffs_rex64"
14515 [(set (match_operand:DI 0 "register_operand" "=r")
14516 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14517 (clobber (match_scratch:DI 2 "=&r"))
14518 (clobber (reg:CC FLAGS_REG))]
14519 "TARGET_64BIT && TARGET_CMOVE"
14521 "&& reload_completed"
14522 [(set (match_dup 2) (const_int -1))
14523 (parallel [(set (reg:CCZ FLAGS_REG)
14524 (compare:CCZ (match_dup 1) (const_int 0)))
14525 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14526 (set (match_dup 0) (if_then_else:DI
14527 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14530 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14531 (clobber (reg:CC FLAGS_REG))])]
14534 (define_insn "*ffsdi_1"
14535 [(set (reg:CCZ FLAGS_REG)
14536 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14538 (set (match_operand:DI 0 "register_operand" "=r")
14539 (ctz:DI (match_dup 1)))]
14541 "bsf{q}\t{%1, %0|%0, %1}"
14542 [(set_attr "prefix_0f" "1")])
14544 (define_insn "ctzsi2"
14545 [(set (match_operand:SI 0 "register_operand" "=r")
14546 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14547 (clobber (reg:CC FLAGS_REG))]
14549 "bsf{l}\t{%1, %0|%0, %1}"
14550 [(set_attr "prefix_0f" "1")])
14552 (define_insn "ctzdi2"
14553 [(set (match_operand:DI 0 "register_operand" "=r")
14554 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14555 (clobber (reg:CC FLAGS_REG))]
14557 "bsf{q}\t{%1, %0|%0, %1}"
14558 [(set_attr "prefix_0f" "1")])
14560 (define_expand "clzsi2"
14562 [(set (match_operand:SI 0 "register_operand" "")
14563 (minus:SI (const_int 31)
14564 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14565 (clobber (reg:CC FLAGS_REG))])
14567 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14568 (clobber (reg:CC FLAGS_REG))])]
14572 (define_insn "*bsr"
14573 [(set (match_operand:SI 0 "register_operand" "=r")
14574 (minus:SI (const_int 31)
14575 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14576 (clobber (reg:CC FLAGS_REG))]
14578 "bsr{l}\t{%1, %0|%0, %1}"
14579 [(set_attr "prefix_0f" "1")])
14581 (define_expand "clzdi2"
14583 [(set (match_operand:DI 0 "register_operand" "")
14584 (minus:DI (const_int 63)
14585 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14586 (clobber (reg:CC FLAGS_REG))])
14588 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14589 (clobber (reg:CC FLAGS_REG))])]
14593 (define_insn "*bsr_rex64"
14594 [(set (match_operand:DI 0 "register_operand" "=r")
14595 (minus:DI (const_int 63)
14596 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14597 (clobber (reg:CC FLAGS_REG))]
14599 "bsr{q}\t{%1, %0|%0, %1}"
14600 [(set_attr "prefix_0f" "1")])
14602 ;; Thread-local storage patterns for ELF.
14604 ;; Note that these code sequences must appear exactly as shown
14605 ;; in order to allow linker relaxation.
14607 (define_insn "*tls_global_dynamic_32_gnu"
14608 [(set (match_operand:SI 0 "register_operand" "=a")
14609 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14610 (match_operand:SI 2 "tls_symbolic_operand" "")
14611 (match_operand:SI 3 "call_insn_operand" "")]
14613 (clobber (match_scratch:SI 4 "=d"))
14614 (clobber (match_scratch:SI 5 "=c"))
14615 (clobber (reg:CC FLAGS_REG))]
14616 "!TARGET_64BIT && TARGET_GNU_TLS"
14617 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14618 [(set_attr "type" "multi")
14619 (set_attr "length" "12")])
14621 (define_insn "*tls_global_dynamic_32_sun"
14622 [(set (match_operand:SI 0 "register_operand" "=a")
14623 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14624 (match_operand:SI 2 "tls_symbolic_operand" "")
14625 (match_operand:SI 3 "call_insn_operand" "")]
14627 (clobber (match_scratch:SI 4 "=d"))
14628 (clobber (match_scratch:SI 5 "=c"))
14629 (clobber (reg:CC FLAGS_REG))]
14630 "!TARGET_64BIT && TARGET_SUN_TLS"
14631 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14632 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14633 [(set_attr "type" "multi")
14634 (set_attr "length" "14")])
14636 (define_expand "tls_global_dynamic_32"
14637 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14640 (match_operand:SI 1 "tls_symbolic_operand" "")
14643 (clobber (match_scratch:SI 4 ""))
14644 (clobber (match_scratch:SI 5 ""))
14645 (clobber (reg:CC FLAGS_REG))])]
14649 operands[2] = pic_offset_table_rtx;
14652 operands[2] = gen_reg_rtx (Pmode);
14653 emit_insn (gen_set_got (operands[2]));
14655 if (TARGET_GNU2_TLS)
14657 emit_insn (gen_tls_dynamic_gnu2_32
14658 (operands[0], operands[1], operands[2]));
14661 operands[3] = ix86_tls_get_addr ();
14664 (define_insn "*tls_global_dynamic_64"
14665 [(set (match_operand:DI 0 "register_operand" "=a")
14666 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14667 (match_operand:DI 3 "" "")))
14668 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14671 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14672 [(set_attr "type" "multi")
14673 (set_attr "length" "16")])
14675 (define_expand "tls_global_dynamic_64"
14676 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14677 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14678 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14682 if (TARGET_GNU2_TLS)
14684 emit_insn (gen_tls_dynamic_gnu2_64
14685 (operands[0], operands[1]));
14688 operands[2] = ix86_tls_get_addr ();
14691 (define_insn "*tls_local_dynamic_base_32_gnu"
14692 [(set (match_operand:SI 0 "register_operand" "=a")
14693 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14694 (match_operand:SI 2 "call_insn_operand" "")]
14695 UNSPEC_TLS_LD_BASE))
14696 (clobber (match_scratch:SI 3 "=d"))
14697 (clobber (match_scratch:SI 4 "=c"))
14698 (clobber (reg:CC FLAGS_REG))]
14699 "!TARGET_64BIT && TARGET_GNU_TLS"
14700 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14701 [(set_attr "type" "multi")
14702 (set_attr "length" "11")])
14704 (define_insn "*tls_local_dynamic_base_32_sun"
14705 [(set (match_operand:SI 0 "register_operand" "=a")
14706 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14707 (match_operand:SI 2 "call_insn_operand" "")]
14708 UNSPEC_TLS_LD_BASE))
14709 (clobber (match_scratch:SI 3 "=d"))
14710 (clobber (match_scratch:SI 4 "=c"))
14711 (clobber (reg:CC FLAGS_REG))]
14712 "!TARGET_64BIT && TARGET_SUN_TLS"
14713 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14714 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14715 [(set_attr "type" "multi")
14716 (set_attr "length" "13")])
14718 (define_expand "tls_local_dynamic_base_32"
14719 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14720 (unspec:SI [(match_dup 1) (match_dup 2)]
14721 UNSPEC_TLS_LD_BASE))
14722 (clobber (match_scratch:SI 3 ""))
14723 (clobber (match_scratch:SI 4 ""))
14724 (clobber (reg:CC FLAGS_REG))])]
14728 operands[1] = pic_offset_table_rtx;
14731 operands[1] = gen_reg_rtx (Pmode);
14732 emit_insn (gen_set_got (operands[1]));
14734 if (TARGET_GNU2_TLS)
14736 emit_insn (gen_tls_dynamic_gnu2_32
14737 (operands[0], ix86_tls_module_base (), operands[1]));
14740 operands[2] = ix86_tls_get_addr ();
14743 (define_insn "*tls_local_dynamic_base_64"
14744 [(set (match_operand:DI 0 "register_operand" "=a")
14745 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14746 (match_operand:DI 2 "" "")))
14747 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14749 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14750 [(set_attr "type" "multi")
14751 (set_attr "length" "12")])
14753 (define_expand "tls_local_dynamic_base_64"
14754 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14755 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14756 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14759 if (TARGET_GNU2_TLS)
14761 emit_insn (gen_tls_dynamic_gnu2_64
14762 (operands[0], ix86_tls_module_base ()));
14765 operands[1] = ix86_tls_get_addr ();
14768 ;; Local dynamic of a single variable is a lose. Show combine how
14769 ;; to convert that back to global dynamic.
14771 (define_insn_and_split "*tls_local_dynamic_32_once"
14772 [(set (match_operand:SI 0 "register_operand" "=a")
14773 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14774 (match_operand:SI 2 "call_insn_operand" "")]
14775 UNSPEC_TLS_LD_BASE)
14776 (const:SI (unspec:SI
14777 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14779 (clobber (match_scratch:SI 4 "=d"))
14780 (clobber (match_scratch:SI 5 "=c"))
14781 (clobber (reg:CC FLAGS_REG))]
14785 [(parallel [(set (match_dup 0)
14786 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14788 (clobber (match_dup 4))
14789 (clobber (match_dup 5))
14790 (clobber (reg:CC FLAGS_REG))])]
14793 ;; Load and add the thread base pointer from %gs:0.
14795 (define_insn "*load_tp_si"
14796 [(set (match_operand:SI 0 "register_operand" "=r")
14797 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14799 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14800 [(set_attr "type" "imov")
14801 (set_attr "modrm" "0")
14802 (set_attr "length" "7")
14803 (set_attr "memory" "load")
14804 (set_attr "imm_disp" "false")])
14806 (define_insn "*add_tp_si"
14807 [(set (match_operand:SI 0 "register_operand" "=r")
14808 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14809 (match_operand:SI 1 "register_operand" "0")))
14810 (clobber (reg:CC FLAGS_REG))]
14812 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14813 [(set_attr "type" "alu")
14814 (set_attr "modrm" "0")
14815 (set_attr "length" "7")
14816 (set_attr "memory" "load")
14817 (set_attr "imm_disp" "false")])
14819 (define_insn "*load_tp_di"
14820 [(set (match_operand:DI 0 "register_operand" "=r")
14821 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14823 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14824 [(set_attr "type" "imov")
14825 (set_attr "modrm" "0")
14826 (set_attr "length" "7")
14827 (set_attr "memory" "load")
14828 (set_attr "imm_disp" "false")])
14830 (define_insn "*add_tp_di"
14831 [(set (match_operand:DI 0 "register_operand" "=r")
14832 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14833 (match_operand:DI 1 "register_operand" "0")))
14834 (clobber (reg:CC FLAGS_REG))]
14836 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14837 [(set_attr "type" "alu")
14838 (set_attr "modrm" "0")
14839 (set_attr "length" "7")
14840 (set_attr "memory" "load")
14841 (set_attr "imm_disp" "false")])
14843 ;; GNU2 TLS patterns can be split.
14845 (define_expand "tls_dynamic_gnu2_32"
14846 [(set (match_dup 3)
14847 (plus:SI (match_operand:SI 2 "register_operand" "")
14849 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14852 [(set (match_operand:SI 0 "register_operand" "")
14853 (unspec:SI [(match_dup 1) (match_dup 3)
14854 (match_dup 2) (reg:SI SP_REG)]
14856 (clobber (reg:CC FLAGS_REG))])]
14857 "!TARGET_64BIT && TARGET_GNU2_TLS"
14859 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14860 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14863 (define_insn "*tls_dynamic_lea_32"
14864 [(set (match_operand:SI 0 "register_operand" "=r")
14865 (plus:SI (match_operand:SI 1 "register_operand" "b")
14867 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14868 UNSPEC_TLSDESC))))]
14869 "!TARGET_64BIT && TARGET_GNU2_TLS"
14870 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14871 [(set_attr "type" "lea")
14872 (set_attr "mode" "SI")
14873 (set_attr "length" "6")
14874 (set_attr "length_address" "4")])
14876 (define_insn "*tls_dynamic_call_32"
14877 [(set (match_operand:SI 0 "register_operand" "=a")
14878 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14879 (match_operand:SI 2 "register_operand" "0")
14880 ;; we have to make sure %ebx still points to the GOT
14881 (match_operand:SI 3 "register_operand" "b")
14884 (clobber (reg:CC FLAGS_REG))]
14885 "!TARGET_64BIT && TARGET_GNU2_TLS"
14886 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14887 [(set_attr "type" "call")
14888 (set_attr "length" "2")
14889 (set_attr "length_address" "0")])
14891 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14892 [(set (match_operand:SI 0 "register_operand" "=&a")
14894 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14895 (match_operand:SI 4 "" "")
14896 (match_operand:SI 2 "register_operand" "b")
14899 (const:SI (unspec:SI
14900 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14902 (clobber (reg:CC FLAGS_REG))]
14903 "!TARGET_64BIT && TARGET_GNU2_TLS"
14906 [(set (match_dup 0) (match_dup 5))]
14908 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14909 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14912 (define_expand "tls_dynamic_gnu2_64"
14913 [(set (match_dup 2)
14914 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14917 [(set (match_operand:DI 0 "register_operand" "")
14918 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14920 (clobber (reg:CC FLAGS_REG))])]
14921 "TARGET_64BIT && TARGET_GNU2_TLS"
14923 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14924 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14927 (define_insn "*tls_dynamic_lea_64"
14928 [(set (match_operand:DI 0 "register_operand" "=r")
14929 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14931 "TARGET_64BIT && TARGET_GNU2_TLS"
14932 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14933 [(set_attr "type" "lea")
14934 (set_attr "mode" "DI")
14935 (set_attr "length" "7")
14936 (set_attr "length_address" "4")])
14938 (define_insn "*tls_dynamic_call_64"
14939 [(set (match_operand:DI 0 "register_operand" "=a")
14940 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14941 (match_operand:DI 2 "register_operand" "0")
14944 (clobber (reg:CC FLAGS_REG))]
14945 "TARGET_64BIT && TARGET_GNU2_TLS"
14946 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14947 [(set_attr "type" "call")
14948 (set_attr "length" "2")
14949 (set_attr "length_address" "0")])
14951 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14952 [(set (match_operand:DI 0 "register_operand" "=&a")
14954 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14955 (match_operand:DI 3 "" "")
14958 (const:DI (unspec:DI
14959 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14961 (clobber (reg:CC FLAGS_REG))]
14962 "TARGET_64BIT && TARGET_GNU2_TLS"
14965 [(set (match_dup 0) (match_dup 4))]
14967 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14968 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14973 ;; These patterns match the binary 387 instructions for addM3, subM3,
14974 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14975 ;; SFmode. The first is the normal insn, the second the same insn but
14976 ;; with one operand a conversion, and the third the same insn but with
14977 ;; the other operand a conversion. The conversion may be SFmode or
14978 ;; SImode if the target mode DFmode, but only SImode if the target mode
14981 ;; Gcc is slightly more smart about handling normal two address instructions
14982 ;; so use special patterns for add and mull.
14984 (define_insn "*fop_sf_comm_mixed"
14985 [(set (match_operand:SF 0 "register_operand" "=f,x")
14986 (match_operator:SF 3 "binary_fp_operator"
14987 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14988 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14989 "TARGET_MIX_SSE_I387
14990 && COMMUTATIVE_ARITH_P (operands[3])
14991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14992 "* return output_387_binary_op (insn, operands);"
14993 [(set (attr "type")
14994 (if_then_else (eq_attr "alternative" "1")
14995 (if_then_else (match_operand:SF 3 "mult_operator" "")
14996 (const_string "ssemul")
14997 (const_string "sseadd"))
14998 (if_then_else (match_operand:SF 3 "mult_operator" "")
14999 (const_string "fmul")
15000 (const_string "fop"))))
15001 (set_attr "mode" "SF")])
15003 (define_insn "*fop_sf_comm_sse"
15004 [(set (match_operand:SF 0 "register_operand" "=x")
15005 (match_operator:SF 3 "binary_fp_operator"
15006 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15007 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15009 && COMMUTATIVE_ARITH_P (operands[3])
15010 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15011 "* return output_387_binary_op (insn, operands);"
15012 [(set (attr "type")
15013 (if_then_else (match_operand:SF 3 "mult_operator" "")
15014 (const_string "ssemul")
15015 (const_string "sseadd")))
15016 (set_attr "mode" "SF")])
15018 (define_insn "*fop_sf_comm_i387"
15019 [(set (match_operand:SF 0 "register_operand" "=f")
15020 (match_operator:SF 3 "binary_fp_operator"
15021 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15022 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15024 && COMMUTATIVE_ARITH_P (operands[3])
15025 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15026 "* return output_387_binary_op (insn, operands);"
15027 [(set (attr "type")
15028 (if_then_else (match_operand:SF 3 "mult_operator" "")
15029 (const_string "fmul")
15030 (const_string "fop")))
15031 (set_attr "mode" "SF")])
15033 (define_insn "*fop_sf_1_mixed"
15034 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15035 (match_operator:SF 3 "binary_fp_operator"
15036 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15037 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15038 "TARGET_MIX_SSE_I387
15039 && !COMMUTATIVE_ARITH_P (operands[3])
15040 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15041 "* return output_387_binary_op (insn, operands);"
15042 [(set (attr "type")
15043 (cond [(and (eq_attr "alternative" "2")
15044 (match_operand:SF 3 "mult_operator" ""))
15045 (const_string "ssemul")
15046 (and (eq_attr "alternative" "2")
15047 (match_operand:SF 3 "div_operator" ""))
15048 (const_string "ssediv")
15049 (eq_attr "alternative" "2")
15050 (const_string "sseadd")
15051 (match_operand:SF 3 "mult_operator" "")
15052 (const_string "fmul")
15053 (match_operand:SF 3 "div_operator" "")
15054 (const_string "fdiv")
15056 (const_string "fop")))
15057 (set_attr "mode" "SF")])
15059 (define_insn "*fop_sf_1_sse"
15060 [(set (match_operand:SF 0 "register_operand" "=x")
15061 (match_operator:SF 3 "binary_fp_operator"
15062 [(match_operand:SF 1 "register_operand" "0")
15063 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15065 && !COMMUTATIVE_ARITH_P (operands[3])"
15066 "* return output_387_binary_op (insn, operands);"
15067 [(set (attr "type")
15068 (cond [(match_operand:SF 3 "mult_operator" "")
15069 (const_string "ssemul")
15070 (match_operand:SF 3 "div_operator" "")
15071 (const_string "ssediv")
15073 (const_string "sseadd")))
15074 (set_attr "mode" "SF")])
15076 ;; This pattern is not fully shadowed by the pattern above.
15077 (define_insn "*fop_sf_1_i387"
15078 [(set (match_operand:SF 0 "register_operand" "=f,f")
15079 (match_operator:SF 3 "binary_fp_operator"
15080 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15081 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15082 "TARGET_80387 && !TARGET_SSE_MATH
15083 && !COMMUTATIVE_ARITH_P (operands[3])
15084 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15085 "* return output_387_binary_op (insn, operands);"
15086 [(set (attr "type")
15087 (cond [(match_operand:SF 3 "mult_operator" "")
15088 (const_string "fmul")
15089 (match_operand:SF 3 "div_operator" "")
15090 (const_string "fdiv")
15092 (const_string "fop")))
15093 (set_attr "mode" "SF")])
15095 ;; ??? Add SSE splitters for these!
15096 (define_insn "*fop_sf_2<mode>_i387"
15097 [(set (match_operand:SF 0 "register_operand" "=f,f")
15098 (match_operator:SF 3 "binary_fp_operator"
15099 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15100 (match_operand:SF 2 "register_operand" "0,0")]))]
15101 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15102 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15103 [(set (attr "type")
15104 (cond [(match_operand:SF 3 "mult_operator" "")
15105 (const_string "fmul")
15106 (match_operand:SF 3 "div_operator" "")
15107 (const_string "fdiv")
15109 (const_string "fop")))
15110 (set_attr "fp_int_src" "true")
15111 (set_attr "mode" "<MODE>")])
15113 (define_insn "*fop_sf_3<mode>_i387"
15114 [(set (match_operand:SF 0 "register_operand" "=f,f")
15115 (match_operator:SF 3 "binary_fp_operator"
15116 [(match_operand:SF 1 "register_operand" "0,0")
15117 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15118 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15119 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15120 [(set (attr "type")
15121 (cond [(match_operand:SF 3 "mult_operator" "")
15122 (const_string "fmul")
15123 (match_operand:SF 3 "div_operator" "")
15124 (const_string "fdiv")
15126 (const_string "fop")))
15127 (set_attr "fp_int_src" "true")
15128 (set_attr "mode" "<MODE>")])
15130 (define_insn "*fop_df_comm_mixed"
15131 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15132 (match_operator:DF 3 "binary_fp_operator"
15133 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15134 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15135 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15136 && COMMUTATIVE_ARITH_P (operands[3])
15137 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15138 "* return output_387_binary_op (insn, operands);"
15139 [(set (attr "type")
15140 (if_then_else (eq_attr "alternative" "1")
15141 (if_then_else (match_operand:DF 3 "mult_operator" "")
15142 (const_string "ssemul")
15143 (const_string "sseadd"))
15144 (if_then_else (match_operand:DF 3 "mult_operator" "")
15145 (const_string "fmul")
15146 (const_string "fop"))))
15147 (set_attr "mode" "DF")])
15149 (define_insn "*fop_df_comm_sse"
15150 [(set (match_operand:DF 0 "register_operand" "=Y")
15151 (match_operator:DF 3 "binary_fp_operator"
15152 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15153 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15154 "TARGET_SSE2 && TARGET_SSE_MATH
15155 && COMMUTATIVE_ARITH_P (operands[3])
15156 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15157 "* return output_387_binary_op (insn, operands);"
15158 [(set (attr "type")
15159 (if_then_else (match_operand:DF 3 "mult_operator" "")
15160 (const_string "ssemul")
15161 (const_string "sseadd")))
15162 (set_attr "mode" "DF")])
15164 (define_insn "*fop_df_comm_i387"
15165 [(set (match_operand:DF 0 "register_operand" "=f")
15166 (match_operator:DF 3 "binary_fp_operator"
15167 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15168 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15170 && COMMUTATIVE_ARITH_P (operands[3])
15171 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15172 "* return output_387_binary_op (insn, operands);"
15173 [(set (attr "type")
15174 (if_then_else (match_operand:DF 3 "mult_operator" "")
15175 (const_string "fmul")
15176 (const_string "fop")))
15177 (set_attr "mode" "DF")])
15179 (define_insn "*fop_df_1_mixed"
15180 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15181 (match_operator:DF 3 "binary_fp_operator"
15182 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15183 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15184 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15185 && !COMMUTATIVE_ARITH_P (operands[3])
15186 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15187 "* return output_387_binary_op (insn, operands);"
15188 [(set (attr "type")
15189 (cond [(and (eq_attr "alternative" "2")
15190 (match_operand:DF 3 "mult_operator" ""))
15191 (const_string "ssemul")
15192 (and (eq_attr "alternative" "2")
15193 (match_operand:DF 3 "div_operator" ""))
15194 (const_string "ssediv")
15195 (eq_attr "alternative" "2")
15196 (const_string "sseadd")
15197 (match_operand:DF 3 "mult_operator" "")
15198 (const_string "fmul")
15199 (match_operand:DF 3 "div_operator" "")
15200 (const_string "fdiv")
15202 (const_string "fop")))
15203 (set_attr "mode" "DF")])
15205 (define_insn "*fop_df_1_sse"
15206 [(set (match_operand:DF 0 "register_operand" "=Y")
15207 (match_operator:DF 3 "binary_fp_operator"
15208 [(match_operand:DF 1 "register_operand" "0")
15209 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15210 "TARGET_SSE2 && TARGET_SSE_MATH
15211 && !COMMUTATIVE_ARITH_P (operands[3])"
15212 "* return output_387_binary_op (insn, operands);"
15213 [(set_attr "mode" "DF")
15215 (cond [(match_operand:DF 3 "mult_operator" "")
15216 (const_string "ssemul")
15217 (match_operand:DF 3 "div_operator" "")
15218 (const_string "ssediv")
15220 (const_string "sseadd")))])
15222 ;; This pattern is not fully shadowed by the pattern above.
15223 (define_insn "*fop_df_1_i387"
15224 [(set (match_operand:DF 0 "register_operand" "=f,f")
15225 (match_operator:DF 3 "binary_fp_operator"
15226 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15227 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15228 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15229 && !COMMUTATIVE_ARITH_P (operands[3])
15230 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15231 "* return output_387_binary_op (insn, operands);"
15232 [(set (attr "type")
15233 (cond [(match_operand:DF 3 "mult_operator" "")
15234 (const_string "fmul")
15235 (match_operand:DF 3 "div_operator" "")
15236 (const_string "fdiv")
15238 (const_string "fop")))
15239 (set_attr "mode" "DF")])
15241 ;; ??? Add SSE splitters for these!
15242 (define_insn "*fop_df_2<mode>_i387"
15243 [(set (match_operand:DF 0 "register_operand" "=f,f")
15244 (match_operator:DF 3 "binary_fp_operator"
15245 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15246 (match_operand:DF 2 "register_operand" "0,0")]))]
15247 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15248 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15249 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15250 [(set (attr "type")
15251 (cond [(match_operand:DF 3 "mult_operator" "")
15252 (const_string "fmul")
15253 (match_operand:DF 3 "div_operator" "")
15254 (const_string "fdiv")
15256 (const_string "fop")))
15257 (set_attr "fp_int_src" "true")
15258 (set_attr "mode" "<MODE>")])
15260 (define_insn "*fop_df_3<mode>_i387"
15261 [(set (match_operand:DF 0 "register_operand" "=f,f")
15262 (match_operator:DF 3 "binary_fp_operator"
15263 [(match_operand:DF 1 "register_operand" "0,0")
15264 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15265 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15266 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15267 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15268 [(set (attr "type")
15269 (cond [(match_operand:DF 3 "mult_operator" "")
15270 (const_string "fmul")
15271 (match_operand:DF 3 "div_operator" "")
15272 (const_string "fdiv")
15274 (const_string "fop")))
15275 (set_attr "fp_int_src" "true")
15276 (set_attr "mode" "<MODE>")])
15278 (define_insn "*fop_df_4_i387"
15279 [(set (match_operand:DF 0 "register_operand" "=f,f")
15280 (match_operator:DF 3 "binary_fp_operator"
15281 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15282 (match_operand:DF 2 "register_operand" "0,f")]))]
15283 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15284 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15285 "* return output_387_binary_op (insn, operands);"
15286 [(set (attr "type")
15287 (cond [(match_operand:DF 3 "mult_operator" "")
15288 (const_string "fmul")
15289 (match_operand:DF 3 "div_operator" "")
15290 (const_string "fdiv")
15292 (const_string "fop")))
15293 (set_attr "mode" "SF")])
15295 (define_insn "*fop_df_5_i387"
15296 [(set (match_operand:DF 0 "register_operand" "=f,f")
15297 (match_operator:DF 3 "binary_fp_operator"
15298 [(match_operand:DF 1 "register_operand" "0,f")
15300 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15301 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15302 "* return output_387_binary_op (insn, operands);"
15303 [(set (attr "type")
15304 (cond [(match_operand:DF 3 "mult_operator" "")
15305 (const_string "fmul")
15306 (match_operand:DF 3 "div_operator" "")
15307 (const_string "fdiv")
15309 (const_string "fop")))
15310 (set_attr "mode" "SF")])
15312 (define_insn "*fop_df_6_i387"
15313 [(set (match_operand:DF 0 "register_operand" "=f,f")
15314 (match_operator:DF 3 "binary_fp_operator"
15316 (match_operand:SF 1 "register_operand" "0,f"))
15318 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15319 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15320 "* return output_387_binary_op (insn, operands);"
15321 [(set (attr "type")
15322 (cond [(match_operand:DF 3 "mult_operator" "")
15323 (const_string "fmul")
15324 (match_operand:DF 3 "div_operator" "")
15325 (const_string "fdiv")
15327 (const_string "fop")))
15328 (set_attr "mode" "SF")])
15330 (define_insn "*fop_xf_comm_i387"
15331 [(set (match_operand:XF 0 "register_operand" "=f")
15332 (match_operator:XF 3 "binary_fp_operator"
15333 [(match_operand:XF 1 "register_operand" "%0")
15334 (match_operand:XF 2 "register_operand" "f")]))]
15336 && COMMUTATIVE_ARITH_P (operands[3])"
15337 "* return output_387_binary_op (insn, operands);"
15338 [(set (attr "type")
15339 (if_then_else (match_operand:XF 3 "mult_operator" "")
15340 (const_string "fmul")
15341 (const_string "fop")))
15342 (set_attr "mode" "XF")])
15344 (define_insn "*fop_xf_1_i387"
15345 [(set (match_operand:XF 0 "register_operand" "=f,f")
15346 (match_operator:XF 3 "binary_fp_operator"
15347 [(match_operand:XF 1 "register_operand" "0,f")
15348 (match_operand:XF 2 "register_operand" "f,0")]))]
15350 && !COMMUTATIVE_ARITH_P (operands[3])"
15351 "* return output_387_binary_op (insn, operands);"
15352 [(set (attr "type")
15353 (cond [(match_operand:XF 3 "mult_operator" "")
15354 (const_string "fmul")
15355 (match_operand:XF 3 "div_operator" "")
15356 (const_string "fdiv")
15358 (const_string "fop")))
15359 (set_attr "mode" "XF")])
15361 (define_insn "*fop_xf_2<mode>_i387"
15362 [(set (match_operand:XF 0 "register_operand" "=f,f")
15363 (match_operator:XF 3 "binary_fp_operator"
15364 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15365 (match_operand:XF 2 "register_operand" "0,0")]))]
15366 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15367 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15368 [(set (attr "type")
15369 (cond [(match_operand:XF 3 "mult_operator" "")
15370 (const_string "fmul")
15371 (match_operand:XF 3 "div_operator" "")
15372 (const_string "fdiv")
15374 (const_string "fop")))
15375 (set_attr "fp_int_src" "true")
15376 (set_attr "mode" "<MODE>")])
15378 (define_insn "*fop_xf_3<mode>_i387"
15379 [(set (match_operand:XF 0 "register_operand" "=f,f")
15380 (match_operator:XF 3 "binary_fp_operator"
15381 [(match_operand:XF 1 "register_operand" "0,0")
15382 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15383 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15384 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15385 [(set (attr "type")
15386 (cond [(match_operand:XF 3 "mult_operator" "")
15387 (const_string "fmul")
15388 (match_operand:XF 3 "div_operator" "")
15389 (const_string "fdiv")
15391 (const_string "fop")))
15392 (set_attr "fp_int_src" "true")
15393 (set_attr "mode" "<MODE>")])
15395 (define_insn "*fop_xf_4_i387"
15396 [(set (match_operand:XF 0 "register_operand" "=f,f")
15397 (match_operator:XF 3 "binary_fp_operator"
15398 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15399 (match_operand:XF 2 "register_operand" "0,f")]))]
15401 "* return output_387_binary_op (insn, operands);"
15402 [(set (attr "type")
15403 (cond [(match_operand:XF 3 "mult_operator" "")
15404 (const_string "fmul")
15405 (match_operand:XF 3 "div_operator" "")
15406 (const_string "fdiv")
15408 (const_string "fop")))
15409 (set_attr "mode" "SF")])
15411 (define_insn "*fop_xf_5_i387"
15412 [(set (match_operand:XF 0 "register_operand" "=f,f")
15413 (match_operator:XF 3 "binary_fp_operator"
15414 [(match_operand:XF 1 "register_operand" "0,f")
15416 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15418 "* return output_387_binary_op (insn, operands);"
15419 [(set (attr "type")
15420 (cond [(match_operand:XF 3 "mult_operator" "")
15421 (const_string "fmul")
15422 (match_operand:XF 3 "div_operator" "")
15423 (const_string "fdiv")
15425 (const_string "fop")))
15426 (set_attr "mode" "SF")])
15428 (define_insn "*fop_xf_6_i387"
15429 [(set (match_operand:XF 0 "register_operand" "=f,f")
15430 (match_operator:XF 3 "binary_fp_operator"
15432 (match_operand 1 "register_operand" "0,f"))
15434 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15436 "* return output_387_binary_op (insn, operands);"
15437 [(set (attr "type")
15438 (cond [(match_operand:XF 3 "mult_operator" "")
15439 (const_string "fmul")
15440 (match_operand:XF 3 "div_operator" "")
15441 (const_string "fdiv")
15443 (const_string "fop")))
15444 (set_attr "mode" "SF")])
15447 [(set (match_operand 0 "register_operand" "")
15448 (match_operator 3 "binary_fp_operator"
15449 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15450 (match_operand 2 "register_operand" "")]))]
15451 "TARGET_80387 && reload_completed
15452 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15455 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15456 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15457 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15458 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15459 GET_MODE (operands[3]),
15462 ix86_free_from_memory (GET_MODE (operands[1]));
15467 [(set (match_operand 0 "register_operand" "")
15468 (match_operator 3 "binary_fp_operator"
15469 [(match_operand 1 "register_operand" "")
15470 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15471 "TARGET_80387 && reload_completed
15472 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15475 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15476 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15477 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15478 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15479 GET_MODE (operands[3]),
15482 ix86_free_from_memory (GET_MODE (operands[2]));
15486 ;; FPU special functions.
15488 (define_expand "sqrtsf2"
15489 [(set (match_operand:SF 0 "register_operand" "")
15490 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15491 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15493 if (!TARGET_SSE_MATH)
15494 operands[1] = force_reg (SFmode, operands[1]);
15497 (define_insn "*sqrtsf2_mixed"
15498 [(set (match_operand:SF 0 "register_operand" "=f,x")
15499 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15500 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15503 sqrtss\t{%1, %0|%0, %1}"
15504 [(set_attr "type" "fpspc,sse")
15505 (set_attr "mode" "SF,SF")
15506 (set_attr "athlon_decode" "direct,*")])
15508 (define_insn "*sqrtsf2_sse"
15509 [(set (match_operand:SF 0 "register_operand" "=x")
15510 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15512 "sqrtss\t{%1, %0|%0, %1}"
15513 [(set_attr "type" "sse")
15514 (set_attr "mode" "SF")
15515 (set_attr "athlon_decode" "*")])
15517 (define_insn "*sqrtsf2_i387"
15518 [(set (match_operand:SF 0 "register_operand" "=f")
15519 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15520 "TARGET_USE_FANCY_MATH_387"
15522 [(set_attr "type" "fpspc")
15523 (set_attr "mode" "SF")
15524 (set_attr "athlon_decode" "direct")])
15526 (define_expand "sqrtdf2"
15527 [(set (match_operand:DF 0 "register_operand" "")
15528 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15529 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15531 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15532 operands[1] = force_reg (DFmode, operands[1]);
15535 (define_insn "*sqrtdf2_mixed"
15536 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15537 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15538 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15541 sqrtsd\t{%1, %0|%0, %1}"
15542 [(set_attr "type" "fpspc,sse")
15543 (set_attr "mode" "DF,DF")
15544 (set_attr "athlon_decode" "direct,*")])
15546 (define_insn "*sqrtdf2_sse"
15547 [(set (match_operand:DF 0 "register_operand" "=Y")
15548 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15549 "TARGET_SSE2 && TARGET_SSE_MATH"
15550 "sqrtsd\t{%1, %0|%0, %1}"
15551 [(set_attr "type" "sse")
15552 (set_attr "mode" "DF")
15553 (set_attr "athlon_decode" "*")])
15555 (define_insn "*sqrtdf2_i387"
15556 [(set (match_operand:DF 0 "register_operand" "=f")
15557 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15558 "TARGET_USE_FANCY_MATH_387"
15560 [(set_attr "type" "fpspc")
15561 (set_attr "mode" "DF")
15562 (set_attr "athlon_decode" "direct")])
15564 (define_insn "*sqrtextendsfdf2_i387"
15565 [(set (match_operand:DF 0 "register_operand" "=f")
15566 (sqrt:DF (float_extend:DF
15567 (match_operand:SF 1 "register_operand" "0"))))]
15568 "TARGET_USE_FANCY_MATH_387
15569 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15571 [(set_attr "type" "fpspc")
15572 (set_attr "mode" "DF")
15573 (set_attr "athlon_decode" "direct")])
15575 (define_insn "sqrtxf2"
15576 [(set (match_operand:XF 0 "register_operand" "=f")
15577 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15578 "TARGET_USE_FANCY_MATH_387"
15580 [(set_attr "type" "fpspc")
15581 (set_attr "mode" "XF")
15582 (set_attr "athlon_decode" "direct")])
15584 (define_insn "*sqrtextendsfxf2_i387"
15585 [(set (match_operand:XF 0 "register_operand" "=f")
15586 (sqrt:XF (float_extend:XF
15587 (match_operand:SF 1 "register_operand" "0"))))]
15588 "TARGET_USE_FANCY_MATH_387"
15590 [(set_attr "type" "fpspc")
15591 (set_attr "mode" "XF")
15592 (set_attr "athlon_decode" "direct")])
15594 (define_insn "*sqrtextenddfxf2_i387"
15595 [(set (match_operand:XF 0 "register_operand" "=f")
15596 (sqrt:XF (float_extend:XF
15597 (match_operand:DF 1 "register_operand" "0"))))]
15598 "TARGET_USE_FANCY_MATH_387"
15600 [(set_attr "type" "fpspc")
15601 (set_attr "mode" "XF")
15602 (set_attr "athlon_decode" "direct")])
15604 (define_insn "fpremxf4"
15605 [(set (match_operand:XF 0 "register_operand" "=f")
15606 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15607 (match_operand:XF 3 "register_operand" "1")]
15609 (set (match_operand:XF 1 "register_operand" "=u")
15610 (unspec:XF [(match_dup 2) (match_dup 3)]
15612 (set (reg:CCFP FPSR_REG)
15613 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15614 "TARGET_USE_FANCY_MATH_387"
15616 [(set_attr "type" "fpspc")
15617 (set_attr "mode" "XF")])
15619 (define_expand "fmodsf3"
15620 [(use (match_operand:SF 0 "register_operand" ""))
15621 (use (match_operand:SF 1 "register_operand" ""))
15622 (use (match_operand:SF 2 "register_operand" ""))]
15623 "TARGET_USE_FANCY_MATH_387
15624 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15626 rtx label = gen_label_rtx ();
15628 rtx op1 = gen_reg_rtx (XFmode);
15629 rtx op2 = gen_reg_rtx (XFmode);
15631 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15632 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15634 emit_label (label);
15636 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15637 ix86_emit_fp_unordered_jump (label);
15639 emit_insn (gen_truncxfsf2 (operands[0], op1));
15643 (define_expand "fmoddf3"
15644 [(use (match_operand:DF 0 "register_operand" ""))
15645 (use (match_operand:DF 1 "register_operand" ""))
15646 (use (match_operand:DF 2 "register_operand" ""))]
15647 "TARGET_USE_FANCY_MATH_387
15648 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15650 rtx label = gen_label_rtx ();
15652 rtx op1 = gen_reg_rtx (XFmode);
15653 rtx op2 = gen_reg_rtx (XFmode);
15655 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15656 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15658 emit_label (label);
15660 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15661 ix86_emit_fp_unordered_jump (label);
15663 emit_insn (gen_truncxfdf2 (operands[0], op1));
15667 (define_expand "fmodxf3"
15668 [(use (match_operand:XF 0 "register_operand" ""))
15669 (use (match_operand:XF 1 "register_operand" ""))
15670 (use (match_operand:XF 2 "register_operand" ""))]
15671 "TARGET_USE_FANCY_MATH_387"
15673 rtx label = gen_label_rtx ();
15675 emit_label (label);
15677 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15678 operands[1], operands[2]));
15679 ix86_emit_fp_unordered_jump (label);
15681 emit_move_insn (operands[0], operands[1]);
15685 (define_insn "fprem1xf4"
15686 [(set (match_operand:XF 0 "register_operand" "=f")
15687 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15688 (match_operand:XF 3 "register_operand" "1")]
15690 (set (match_operand:XF 1 "register_operand" "=u")
15691 (unspec:XF [(match_dup 2) (match_dup 3)]
15693 (set (reg:CCFP FPSR_REG)
15694 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15695 "TARGET_USE_FANCY_MATH_387"
15697 [(set_attr "type" "fpspc")
15698 (set_attr "mode" "XF")])
15700 (define_expand "remaindersf3"
15701 [(use (match_operand:SF 0 "register_operand" ""))
15702 (use (match_operand:SF 1 "register_operand" ""))
15703 (use (match_operand:SF 2 "register_operand" ""))]
15704 "TARGET_USE_FANCY_MATH_387
15705 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15707 rtx label = gen_label_rtx ();
15709 rtx op1 = gen_reg_rtx (XFmode);
15710 rtx op2 = gen_reg_rtx (XFmode);
15712 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15713 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15715 emit_label (label);
15717 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15718 ix86_emit_fp_unordered_jump (label);
15720 emit_insn (gen_truncxfsf2 (operands[0], op1));
15724 (define_expand "remainderdf3"
15725 [(use (match_operand:DF 0 "register_operand" ""))
15726 (use (match_operand:DF 1 "register_operand" ""))
15727 (use (match_operand:DF 2 "register_operand" ""))]
15728 "TARGET_USE_FANCY_MATH_387
15729 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15731 rtx label = gen_label_rtx ();
15733 rtx op1 = gen_reg_rtx (XFmode);
15734 rtx op2 = gen_reg_rtx (XFmode);
15736 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15737 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15739 emit_label (label);
15741 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15742 ix86_emit_fp_unordered_jump (label);
15744 emit_insn (gen_truncxfdf2 (operands[0], op1));
15748 (define_expand "remainderxf3"
15749 [(use (match_operand:XF 0 "register_operand" ""))
15750 (use (match_operand:XF 1 "register_operand" ""))
15751 (use (match_operand:XF 2 "register_operand" ""))]
15752 "TARGET_USE_FANCY_MATH_387"
15754 rtx label = gen_label_rtx ();
15756 emit_label (label);
15758 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15759 operands[1], operands[2]));
15760 ix86_emit_fp_unordered_jump (label);
15762 emit_move_insn (operands[0], operands[1]);
15766 (define_insn "*sindf2"
15767 [(set (match_operand:DF 0 "register_operand" "=f")
15768 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15769 "TARGET_USE_FANCY_MATH_387
15770 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15771 && flag_unsafe_math_optimizations"
15773 [(set_attr "type" "fpspc")
15774 (set_attr "mode" "DF")])
15776 (define_insn "*sinsf2"
15777 [(set (match_operand:SF 0 "register_operand" "=f")
15778 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15779 "TARGET_USE_FANCY_MATH_387
15780 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15781 && flag_unsafe_math_optimizations"
15783 [(set_attr "type" "fpspc")
15784 (set_attr "mode" "SF")])
15786 (define_insn "*sinextendsfdf2"
15787 [(set (match_operand:DF 0 "register_operand" "=f")
15788 (unspec:DF [(float_extend:DF
15789 (match_operand:SF 1 "register_operand" "0"))]
15791 "TARGET_USE_FANCY_MATH_387
15792 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15793 && flag_unsafe_math_optimizations"
15795 [(set_attr "type" "fpspc")
15796 (set_attr "mode" "DF")])
15798 (define_insn "*sinxf2"
15799 [(set (match_operand:XF 0 "register_operand" "=f")
15800 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15801 "TARGET_USE_FANCY_MATH_387
15802 && flag_unsafe_math_optimizations"
15804 [(set_attr "type" "fpspc")
15805 (set_attr "mode" "XF")])
15807 (define_insn "*cosdf2"
15808 [(set (match_operand:DF 0 "register_operand" "=f")
15809 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15810 "TARGET_USE_FANCY_MATH_387
15811 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15812 && flag_unsafe_math_optimizations"
15814 [(set_attr "type" "fpspc")
15815 (set_attr "mode" "DF")])
15817 (define_insn "*cossf2"
15818 [(set (match_operand:SF 0 "register_operand" "=f")
15819 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15820 "TARGET_USE_FANCY_MATH_387
15821 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15822 && flag_unsafe_math_optimizations"
15824 [(set_attr "type" "fpspc")
15825 (set_attr "mode" "SF")])
15827 (define_insn "*cosextendsfdf2"
15828 [(set (match_operand:DF 0 "register_operand" "=f")
15829 (unspec:DF [(float_extend:DF
15830 (match_operand:SF 1 "register_operand" "0"))]
15832 "TARGET_USE_FANCY_MATH_387
15833 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15834 && flag_unsafe_math_optimizations"
15836 [(set_attr "type" "fpspc")
15837 (set_attr "mode" "DF")])
15839 (define_insn "*cosxf2"
15840 [(set (match_operand:XF 0 "register_operand" "=f")
15841 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15842 "TARGET_USE_FANCY_MATH_387
15843 && flag_unsafe_math_optimizations"
15845 [(set_attr "type" "fpspc")
15846 (set_attr "mode" "XF")])
15848 ;; With sincos pattern defined, sin and cos builtin function will be
15849 ;; expanded to sincos pattern with one of its outputs left unused.
15850 ;; Cse pass will detected, if two sincos patterns can be combined,
15851 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15852 ;; depending on the unused output.
15854 (define_insn "sincosdf3"
15855 [(set (match_operand:DF 0 "register_operand" "=f")
15856 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15857 UNSPEC_SINCOS_COS))
15858 (set (match_operand:DF 1 "register_operand" "=u")
15859 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15860 "TARGET_USE_FANCY_MATH_387
15861 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15862 && flag_unsafe_math_optimizations"
15864 [(set_attr "type" "fpspc")
15865 (set_attr "mode" "DF")])
15868 [(set (match_operand:DF 0 "register_operand" "")
15869 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15870 UNSPEC_SINCOS_COS))
15871 (set (match_operand:DF 1 "register_operand" "")
15872 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15873 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15874 && !reload_completed && !reload_in_progress"
15875 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15879 [(set (match_operand:DF 0 "register_operand" "")
15880 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15881 UNSPEC_SINCOS_COS))
15882 (set (match_operand:DF 1 "register_operand" "")
15883 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15884 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15885 && !reload_completed && !reload_in_progress"
15886 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15889 (define_insn "sincossf3"
15890 [(set (match_operand:SF 0 "register_operand" "=f")
15891 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15892 UNSPEC_SINCOS_COS))
15893 (set (match_operand:SF 1 "register_operand" "=u")
15894 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15895 "TARGET_USE_FANCY_MATH_387
15896 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15897 && flag_unsafe_math_optimizations"
15899 [(set_attr "type" "fpspc")
15900 (set_attr "mode" "SF")])
15903 [(set (match_operand:SF 0 "register_operand" "")
15904 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15905 UNSPEC_SINCOS_COS))
15906 (set (match_operand:SF 1 "register_operand" "")
15907 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15908 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15909 && !reload_completed && !reload_in_progress"
15910 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15914 [(set (match_operand:SF 0 "register_operand" "")
15915 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15916 UNSPEC_SINCOS_COS))
15917 (set (match_operand:SF 1 "register_operand" "")
15918 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15919 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15920 && !reload_completed && !reload_in_progress"
15921 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15924 (define_insn "*sincosextendsfdf3"
15925 [(set (match_operand:DF 0 "register_operand" "=f")
15926 (unspec:DF [(float_extend:DF
15927 (match_operand:SF 2 "register_operand" "0"))]
15928 UNSPEC_SINCOS_COS))
15929 (set (match_operand:DF 1 "register_operand" "=u")
15930 (unspec:DF [(float_extend:DF
15931 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15932 "TARGET_USE_FANCY_MATH_387
15933 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15934 && flag_unsafe_math_optimizations"
15936 [(set_attr "type" "fpspc")
15937 (set_attr "mode" "DF")])
15940 [(set (match_operand:DF 0 "register_operand" "")
15941 (unspec:DF [(float_extend:DF
15942 (match_operand:SF 2 "register_operand" ""))]
15943 UNSPEC_SINCOS_COS))
15944 (set (match_operand:DF 1 "register_operand" "")
15945 (unspec:DF [(float_extend:DF
15946 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15947 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15948 && !reload_completed && !reload_in_progress"
15949 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15950 (match_dup 2))] UNSPEC_SIN))]
15954 [(set (match_operand:DF 0 "register_operand" "")
15955 (unspec:DF [(float_extend:DF
15956 (match_operand:SF 2 "register_operand" ""))]
15957 UNSPEC_SINCOS_COS))
15958 (set (match_operand:DF 1 "register_operand" "")
15959 (unspec:DF [(float_extend:DF
15960 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15961 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15962 && !reload_completed && !reload_in_progress"
15963 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15964 (match_dup 2))] UNSPEC_COS))]
15967 (define_insn "sincosxf3"
15968 [(set (match_operand:XF 0 "register_operand" "=f")
15969 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15970 UNSPEC_SINCOS_COS))
15971 (set (match_operand:XF 1 "register_operand" "=u")
15972 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15973 "TARGET_USE_FANCY_MATH_387
15974 && flag_unsafe_math_optimizations"
15976 [(set_attr "type" "fpspc")
15977 (set_attr "mode" "XF")])
15980 [(set (match_operand:XF 0 "register_operand" "")
15981 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15982 UNSPEC_SINCOS_COS))
15983 (set (match_operand:XF 1 "register_operand" "")
15984 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15985 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15986 && !reload_completed && !reload_in_progress"
15987 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15991 [(set (match_operand:XF 0 "register_operand" "")
15992 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15993 UNSPEC_SINCOS_COS))
15994 (set (match_operand:XF 1 "register_operand" "")
15995 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15996 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15997 && !reload_completed && !reload_in_progress"
15998 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16001 (define_insn "*tandf3_1"
16002 [(set (match_operand:DF 0 "register_operand" "=f")
16003 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16005 (set (match_operand:DF 1 "register_operand" "=u")
16006 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16007 "TARGET_USE_FANCY_MATH_387
16008 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16009 && flag_unsafe_math_optimizations"
16011 [(set_attr "type" "fpspc")
16012 (set_attr "mode" "DF")])
16014 ;; optimize sequence: fptan
16017 ;; into fptan insn.
16020 [(parallel[(set (match_operand:DF 0 "register_operand" "")
16021 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16023 (set (match_operand:DF 1 "register_operand" "")
16024 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16026 (match_operand:DF 3 "immediate_operand" ""))]
16027 "standard_80387_constant_p (operands[3]) == 2"
16028 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16029 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16032 (define_expand "tandf2"
16033 [(parallel [(set (match_dup 2)
16034 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16036 (set (match_operand:DF 0 "register_operand" "")
16037 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16038 "TARGET_USE_FANCY_MATH_387
16039 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16040 && flag_unsafe_math_optimizations"
16042 operands[2] = gen_reg_rtx (DFmode);
16045 (define_insn "*tansf3_1"
16046 [(set (match_operand:SF 0 "register_operand" "=f")
16047 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16049 (set (match_operand:SF 1 "register_operand" "=u")
16050 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16051 "TARGET_USE_FANCY_MATH_387
16052 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16053 && flag_unsafe_math_optimizations"
16055 [(set_attr "type" "fpspc")
16056 (set_attr "mode" "SF")])
16058 ;; optimize sequence: fptan
16061 ;; into fptan insn.
16064 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16065 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16067 (set (match_operand:SF 1 "register_operand" "")
16068 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16070 (match_operand:SF 3 "immediate_operand" ""))]
16071 "standard_80387_constant_p (operands[3]) == 2"
16072 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16073 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16076 (define_expand "tansf2"
16077 [(parallel [(set (match_dup 2)
16078 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16080 (set (match_operand:SF 0 "register_operand" "")
16081 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16082 "TARGET_USE_FANCY_MATH_387
16083 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16084 && flag_unsafe_math_optimizations"
16086 operands[2] = gen_reg_rtx (SFmode);
16089 (define_insn "*tanxf3_1"
16090 [(set (match_operand:XF 0 "register_operand" "=f")
16091 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16093 (set (match_operand:XF 1 "register_operand" "=u")
16094 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16095 "TARGET_USE_FANCY_MATH_387
16096 && flag_unsafe_math_optimizations"
16098 [(set_attr "type" "fpspc")
16099 (set_attr "mode" "XF")])
16101 ;; optimize sequence: fptan
16104 ;; into fptan insn.
16107 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16108 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16110 (set (match_operand:XF 1 "register_operand" "")
16111 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16113 (match_operand:XF 3 "immediate_operand" ""))]
16114 "standard_80387_constant_p (operands[3]) == 2"
16115 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16116 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16119 (define_expand "tanxf2"
16120 [(parallel [(set (match_dup 2)
16121 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16123 (set (match_operand:XF 0 "register_operand" "")
16124 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16125 "TARGET_USE_FANCY_MATH_387
16126 && flag_unsafe_math_optimizations"
16128 operands[2] = gen_reg_rtx (XFmode);
16131 (define_insn "atan2df3_1"
16132 [(set (match_operand:DF 0 "register_operand" "=f")
16133 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16134 (match_operand:DF 1 "register_operand" "u")]
16136 (clobber (match_scratch:DF 3 "=1"))]
16137 "TARGET_USE_FANCY_MATH_387
16138 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16139 && flag_unsafe_math_optimizations"
16141 [(set_attr "type" "fpspc")
16142 (set_attr "mode" "DF")])
16144 (define_expand "atan2df3"
16145 [(use (match_operand:DF 0 "register_operand" ""))
16146 (use (match_operand:DF 2 "register_operand" ""))
16147 (use (match_operand:DF 1 "register_operand" ""))]
16148 "TARGET_USE_FANCY_MATH_387
16149 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16150 && flag_unsafe_math_optimizations"
16152 rtx copy = gen_reg_rtx (DFmode);
16153 emit_move_insn (copy, operands[1]);
16154 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16158 (define_expand "atandf2"
16159 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16160 (unspec:DF [(match_dup 2)
16161 (match_operand:DF 1 "register_operand" "")]
16163 (clobber (match_scratch:DF 3 ""))])]
16164 "TARGET_USE_FANCY_MATH_387
16165 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16166 && flag_unsafe_math_optimizations"
16168 operands[2] = gen_reg_rtx (DFmode);
16169 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16172 (define_insn "atan2sf3_1"
16173 [(set (match_operand:SF 0 "register_operand" "=f")
16174 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16175 (match_operand:SF 1 "register_operand" "u")]
16177 (clobber (match_scratch:SF 3 "=1"))]
16178 "TARGET_USE_FANCY_MATH_387
16179 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16180 && flag_unsafe_math_optimizations"
16182 [(set_attr "type" "fpspc")
16183 (set_attr "mode" "SF")])
16185 (define_expand "atan2sf3"
16186 [(use (match_operand:SF 0 "register_operand" ""))
16187 (use (match_operand:SF 2 "register_operand" ""))
16188 (use (match_operand:SF 1 "register_operand" ""))]
16189 "TARGET_USE_FANCY_MATH_387
16190 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16191 && flag_unsafe_math_optimizations"
16193 rtx copy = gen_reg_rtx (SFmode);
16194 emit_move_insn (copy, operands[1]);
16195 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16199 (define_expand "atansf2"
16200 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16201 (unspec:SF [(match_dup 2)
16202 (match_operand:SF 1 "register_operand" "")]
16204 (clobber (match_scratch:SF 3 ""))])]
16205 "TARGET_USE_FANCY_MATH_387
16206 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16207 && flag_unsafe_math_optimizations"
16209 operands[2] = gen_reg_rtx (SFmode);
16210 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16213 (define_insn "atan2xf3_1"
16214 [(set (match_operand:XF 0 "register_operand" "=f")
16215 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16216 (match_operand:XF 1 "register_operand" "u")]
16218 (clobber (match_scratch:XF 3 "=1"))]
16219 "TARGET_USE_FANCY_MATH_387
16220 && flag_unsafe_math_optimizations"
16222 [(set_attr "type" "fpspc")
16223 (set_attr "mode" "XF")])
16225 (define_expand "atan2xf3"
16226 [(use (match_operand:XF 0 "register_operand" ""))
16227 (use (match_operand:XF 2 "register_operand" ""))
16228 (use (match_operand:XF 1 "register_operand" ""))]
16229 "TARGET_USE_FANCY_MATH_387
16230 && flag_unsafe_math_optimizations"
16232 rtx copy = gen_reg_rtx (XFmode);
16233 emit_move_insn (copy, operands[1]);
16234 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16238 (define_expand "atanxf2"
16239 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16240 (unspec:XF [(match_dup 2)
16241 (match_operand:XF 1 "register_operand" "")]
16243 (clobber (match_scratch:XF 3 ""))])]
16244 "TARGET_USE_FANCY_MATH_387
16245 && flag_unsafe_math_optimizations"
16247 operands[2] = gen_reg_rtx (XFmode);
16248 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16251 (define_expand "asindf2"
16252 [(set (match_dup 2)
16253 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16254 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16255 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16256 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16257 (parallel [(set (match_dup 7)
16258 (unspec:XF [(match_dup 6) (match_dup 2)]
16260 (clobber (match_scratch:XF 8 ""))])
16261 (set (match_operand:DF 0 "register_operand" "")
16262 (float_truncate:DF (match_dup 7)))]
16263 "TARGET_USE_FANCY_MATH_387
16264 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16265 && flag_unsafe_math_optimizations"
16269 for (i=2; i<8; i++)
16270 operands[i] = gen_reg_rtx (XFmode);
16272 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16275 (define_expand "asinsf2"
16276 [(set (match_dup 2)
16277 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16278 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16279 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16280 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16281 (parallel [(set (match_dup 7)
16282 (unspec:XF [(match_dup 6) (match_dup 2)]
16284 (clobber (match_scratch:XF 8 ""))])
16285 (set (match_operand:SF 0 "register_operand" "")
16286 (float_truncate:SF (match_dup 7)))]
16287 "TARGET_USE_FANCY_MATH_387
16288 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16289 && flag_unsafe_math_optimizations"
16293 for (i=2; i<8; i++)
16294 operands[i] = gen_reg_rtx (XFmode);
16296 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16299 (define_expand "asinxf2"
16300 [(set (match_dup 2)
16301 (mult:XF (match_operand:XF 1 "register_operand" "")
16303 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16304 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16305 (parallel [(set (match_operand:XF 0 "register_operand" "")
16306 (unspec:XF [(match_dup 5) (match_dup 1)]
16308 (clobber (match_scratch:XF 6 ""))])]
16309 "TARGET_USE_FANCY_MATH_387
16310 && flag_unsafe_math_optimizations"
16314 for (i=2; i<6; i++)
16315 operands[i] = gen_reg_rtx (XFmode);
16317 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16320 (define_expand "acosdf2"
16321 [(set (match_dup 2)
16322 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16323 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16324 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16325 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16326 (parallel [(set (match_dup 7)
16327 (unspec:XF [(match_dup 2) (match_dup 6)]
16329 (clobber (match_scratch:XF 8 ""))])
16330 (set (match_operand:DF 0 "register_operand" "")
16331 (float_truncate:DF (match_dup 7)))]
16332 "TARGET_USE_FANCY_MATH_387
16333 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16334 && flag_unsafe_math_optimizations"
16338 for (i=2; i<8; i++)
16339 operands[i] = gen_reg_rtx (XFmode);
16341 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16344 (define_expand "acossf2"
16345 [(set (match_dup 2)
16346 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16347 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16348 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16349 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16350 (parallel [(set (match_dup 7)
16351 (unspec:XF [(match_dup 2) (match_dup 6)]
16353 (clobber (match_scratch:XF 8 ""))])
16354 (set (match_operand:SF 0 "register_operand" "")
16355 (float_truncate:SF (match_dup 7)))]
16356 "TARGET_USE_FANCY_MATH_387
16357 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16358 && flag_unsafe_math_optimizations"
16362 for (i=2; i<8; i++)
16363 operands[i] = gen_reg_rtx (XFmode);
16365 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16368 (define_expand "acosxf2"
16369 [(set (match_dup 2)
16370 (mult:XF (match_operand:XF 1 "register_operand" "")
16372 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16373 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16374 (parallel [(set (match_operand:XF 0 "register_operand" "")
16375 (unspec:XF [(match_dup 1) (match_dup 5)]
16377 (clobber (match_scratch:XF 6 ""))])]
16378 "TARGET_USE_FANCY_MATH_387
16379 && flag_unsafe_math_optimizations"
16383 for (i=2; i<6; i++)
16384 operands[i] = gen_reg_rtx (XFmode);
16386 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16389 (define_insn "fyl2x_xf3"
16390 [(set (match_operand:XF 0 "register_operand" "=f")
16391 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16392 (match_operand:XF 1 "register_operand" "u")]
16394 (clobber (match_scratch:XF 3 "=1"))]
16395 "TARGET_USE_FANCY_MATH_387
16396 && flag_unsafe_math_optimizations"
16398 [(set_attr "type" "fpspc")
16399 (set_attr "mode" "XF")])
16401 (define_expand "logsf2"
16402 [(set (match_dup 2)
16403 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16404 (parallel [(set (match_dup 4)
16405 (unspec:XF [(match_dup 2)
16406 (match_dup 3)] UNSPEC_FYL2X))
16407 (clobber (match_scratch:XF 5 ""))])
16408 (set (match_operand:SF 0 "register_operand" "")
16409 (float_truncate:SF (match_dup 4)))]
16410 "TARGET_USE_FANCY_MATH_387
16411 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16412 && flag_unsafe_math_optimizations"
16416 operands[2] = gen_reg_rtx (XFmode);
16417 operands[3] = gen_reg_rtx (XFmode);
16418 operands[4] = gen_reg_rtx (XFmode);
16420 temp = standard_80387_constant_rtx (4); /* fldln2 */
16421 emit_move_insn (operands[3], temp);
16424 (define_expand "logdf2"
16425 [(set (match_dup 2)
16426 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16427 (parallel [(set (match_dup 4)
16428 (unspec:XF [(match_dup 2)
16429 (match_dup 3)] UNSPEC_FYL2X))
16430 (clobber (match_scratch:XF 5 ""))])
16431 (set (match_operand:DF 0 "register_operand" "")
16432 (float_truncate:DF (match_dup 4)))]
16433 "TARGET_USE_FANCY_MATH_387
16434 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16435 && flag_unsafe_math_optimizations"
16439 operands[2] = gen_reg_rtx (XFmode);
16440 operands[3] = gen_reg_rtx (XFmode);
16441 operands[4] = gen_reg_rtx (XFmode);
16443 temp = standard_80387_constant_rtx (4); /* fldln2 */
16444 emit_move_insn (operands[3], temp);
16447 (define_expand "logxf2"
16448 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16449 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16450 (match_dup 2)] UNSPEC_FYL2X))
16451 (clobber (match_scratch:XF 3 ""))])]
16452 "TARGET_USE_FANCY_MATH_387
16453 && flag_unsafe_math_optimizations"
16457 operands[2] = gen_reg_rtx (XFmode);
16458 temp = standard_80387_constant_rtx (4); /* fldln2 */
16459 emit_move_insn (operands[2], temp);
16462 (define_expand "log10sf2"
16463 [(set (match_dup 2)
16464 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16465 (parallel [(set (match_dup 4)
16466 (unspec:XF [(match_dup 2)
16467 (match_dup 3)] UNSPEC_FYL2X))
16468 (clobber (match_scratch:XF 5 ""))])
16469 (set (match_operand:SF 0 "register_operand" "")
16470 (float_truncate:SF (match_dup 4)))]
16471 "TARGET_USE_FANCY_MATH_387
16472 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16473 && flag_unsafe_math_optimizations"
16477 operands[2] = gen_reg_rtx (XFmode);
16478 operands[3] = gen_reg_rtx (XFmode);
16479 operands[4] = gen_reg_rtx (XFmode);
16481 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16482 emit_move_insn (operands[3], temp);
16485 (define_expand "log10df2"
16486 [(set (match_dup 2)
16487 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16488 (parallel [(set (match_dup 4)
16489 (unspec:XF [(match_dup 2)
16490 (match_dup 3)] UNSPEC_FYL2X))
16491 (clobber (match_scratch:XF 5 ""))])
16492 (set (match_operand:DF 0 "register_operand" "")
16493 (float_truncate:DF (match_dup 4)))]
16494 "TARGET_USE_FANCY_MATH_387
16495 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16496 && flag_unsafe_math_optimizations"
16500 operands[2] = gen_reg_rtx (XFmode);
16501 operands[3] = gen_reg_rtx (XFmode);
16502 operands[4] = gen_reg_rtx (XFmode);
16504 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16505 emit_move_insn (operands[3], temp);
16508 (define_expand "log10xf2"
16509 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16510 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16511 (match_dup 2)] UNSPEC_FYL2X))
16512 (clobber (match_scratch:XF 3 ""))])]
16513 "TARGET_USE_FANCY_MATH_387
16514 && flag_unsafe_math_optimizations"
16518 operands[2] = gen_reg_rtx (XFmode);
16519 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16520 emit_move_insn (operands[2], temp);
16523 (define_expand "log2sf2"
16524 [(set (match_dup 2)
16525 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16526 (parallel [(set (match_dup 4)
16527 (unspec:XF [(match_dup 2)
16528 (match_dup 3)] UNSPEC_FYL2X))
16529 (clobber (match_scratch:XF 5 ""))])
16530 (set (match_operand:SF 0 "register_operand" "")
16531 (float_truncate:SF (match_dup 4)))]
16532 "TARGET_USE_FANCY_MATH_387
16533 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16534 && flag_unsafe_math_optimizations"
16536 operands[2] = gen_reg_rtx (XFmode);
16537 operands[3] = gen_reg_rtx (XFmode);
16538 operands[4] = gen_reg_rtx (XFmode);
16540 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16543 (define_expand "log2df2"
16544 [(set (match_dup 2)
16545 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16546 (parallel [(set (match_dup 4)
16547 (unspec:XF [(match_dup 2)
16548 (match_dup 3)] UNSPEC_FYL2X))
16549 (clobber (match_scratch:XF 5 ""))])
16550 (set (match_operand:DF 0 "register_operand" "")
16551 (float_truncate:DF (match_dup 4)))]
16552 "TARGET_USE_FANCY_MATH_387
16553 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16554 && flag_unsafe_math_optimizations"
16556 operands[2] = gen_reg_rtx (XFmode);
16557 operands[3] = gen_reg_rtx (XFmode);
16558 operands[4] = gen_reg_rtx (XFmode);
16560 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16563 (define_expand "log2xf2"
16564 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16565 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16566 (match_dup 2)] UNSPEC_FYL2X))
16567 (clobber (match_scratch:XF 3 ""))])]
16568 "TARGET_USE_FANCY_MATH_387
16569 && flag_unsafe_math_optimizations"
16571 operands[2] = gen_reg_rtx (XFmode);
16572 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16575 (define_insn "fyl2xp1_xf3"
16576 [(set (match_operand:XF 0 "register_operand" "=f")
16577 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16578 (match_operand:XF 1 "register_operand" "u")]
16580 (clobber (match_scratch:XF 3 "=1"))]
16581 "TARGET_USE_FANCY_MATH_387
16582 && flag_unsafe_math_optimizations"
16584 [(set_attr "type" "fpspc")
16585 (set_attr "mode" "XF")])
16587 (define_expand "log1psf2"
16588 [(use (match_operand:SF 0 "register_operand" ""))
16589 (use (match_operand:SF 1 "register_operand" ""))]
16590 "TARGET_USE_FANCY_MATH_387
16591 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16592 && flag_unsafe_math_optimizations"
16594 rtx op0 = gen_reg_rtx (XFmode);
16595 rtx op1 = gen_reg_rtx (XFmode);
16597 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16598 ix86_emit_i387_log1p (op0, op1);
16599 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16603 (define_expand "log1pdf2"
16604 [(use (match_operand:DF 0 "register_operand" ""))
16605 (use (match_operand:DF 1 "register_operand" ""))]
16606 "TARGET_USE_FANCY_MATH_387
16607 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16608 && flag_unsafe_math_optimizations"
16610 rtx op0 = gen_reg_rtx (XFmode);
16611 rtx op1 = gen_reg_rtx (XFmode);
16613 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16614 ix86_emit_i387_log1p (op0, op1);
16615 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16619 (define_expand "log1pxf2"
16620 [(use (match_operand:XF 0 "register_operand" ""))
16621 (use (match_operand:XF 1 "register_operand" ""))]
16622 "TARGET_USE_FANCY_MATH_387
16623 && flag_unsafe_math_optimizations"
16625 ix86_emit_i387_log1p (operands[0], operands[1]);
16629 (define_insn "*fxtractxf3"
16630 [(set (match_operand:XF 0 "register_operand" "=f")
16631 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16632 UNSPEC_XTRACT_FRACT))
16633 (set (match_operand:XF 1 "register_operand" "=u")
16634 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16635 "TARGET_USE_FANCY_MATH_387
16636 && flag_unsafe_math_optimizations"
16638 [(set_attr "type" "fpspc")
16639 (set_attr "mode" "XF")])
16641 (define_expand "logbsf2"
16642 [(set (match_dup 2)
16643 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16644 (parallel [(set (match_dup 3)
16645 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16647 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16648 (set (match_operand:SF 0 "register_operand" "")
16649 (float_truncate:SF (match_dup 4)))]
16650 "TARGET_USE_FANCY_MATH_387
16651 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16652 && flag_unsafe_math_optimizations"
16654 operands[2] = gen_reg_rtx (XFmode);
16655 operands[3] = gen_reg_rtx (XFmode);
16656 operands[4] = gen_reg_rtx (XFmode);
16659 (define_expand "logbdf2"
16660 [(set (match_dup 2)
16661 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16662 (parallel [(set (match_dup 3)
16663 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16665 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16666 (set (match_operand:DF 0 "register_operand" "")
16667 (float_truncate:DF (match_dup 4)))]
16668 "TARGET_USE_FANCY_MATH_387
16669 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16670 && flag_unsafe_math_optimizations"
16672 operands[2] = gen_reg_rtx (XFmode);
16673 operands[3] = gen_reg_rtx (XFmode);
16674 operands[4] = gen_reg_rtx (XFmode);
16677 (define_expand "logbxf2"
16678 [(parallel [(set (match_dup 2)
16679 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16680 UNSPEC_XTRACT_FRACT))
16681 (set (match_operand:XF 0 "register_operand" "")
16682 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16683 "TARGET_USE_FANCY_MATH_387
16684 && flag_unsafe_math_optimizations"
16686 operands[2] = gen_reg_rtx (XFmode);
16689 (define_expand "ilogbsi2"
16690 [(parallel [(set (match_dup 2)
16691 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16692 UNSPEC_XTRACT_FRACT))
16693 (set (match_operand:XF 3 "register_operand" "")
16694 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16695 (parallel [(set (match_operand:SI 0 "register_operand" "")
16696 (fix:SI (match_dup 3)))
16697 (clobber (reg:CC FLAGS_REG))])]
16698 "TARGET_USE_FANCY_MATH_387
16699 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16700 && flag_unsafe_math_optimizations"
16702 operands[2] = gen_reg_rtx (XFmode);
16703 operands[3] = gen_reg_rtx (XFmode);
16706 (define_insn "*f2xm1xf2"
16707 [(set (match_operand:XF 0 "register_operand" "=f")
16708 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16710 "TARGET_USE_FANCY_MATH_387
16711 && flag_unsafe_math_optimizations"
16713 [(set_attr "type" "fpspc")
16714 (set_attr "mode" "XF")])
16716 (define_insn "*fscalexf4"
16717 [(set (match_operand:XF 0 "register_operand" "=f")
16718 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16719 (match_operand:XF 3 "register_operand" "1")]
16720 UNSPEC_FSCALE_FRACT))
16721 (set (match_operand:XF 1 "register_operand" "=u")
16722 (unspec:XF [(match_dup 2) (match_dup 3)]
16723 UNSPEC_FSCALE_EXP))]
16724 "TARGET_USE_FANCY_MATH_387
16725 && flag_unsafe_math_optimizations"
16727 [(set_attr "type" "fpspc")
16728 (set_attr "mode" "XF")])
16730 (define_expand "expsf2"
16731 [(set (match_dup 2)
16732 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16733 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16734 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16735 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16736 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16737 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16738 (parallel [(set (match_dup 10)
16739 (unspec:XF [(match_dup 9) (match_dup 5)]
16740 UNSPEC_FSCALE_FRACT))
16741 (set (match_dup 11)
16742 (unspec:XF [(match_dup 9) (match_dup 5)]
16743 UNSPEC_FSCALE_EXP))])
16744 (set (match_operand:SF 0 "register_operand" "")
16745 (float_truncate:SF (match_dup 10)))]
16746 "TARGET_USE_FANCY_MATH_387
16747 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16748 && flag_unsafe_math_optimizations"
16753 for (i=2; i<12; i++)
16754 operands[i] = gen_reg_rtx (XFmode);
16755 temp = standard_80387_constant_rtx (5); /* fldl2e */
16756 emit_move_insn (operands[3], temp);
16757 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16760 (define_expand "expdf2"
16761 [(set (match_dup 2)
16762 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16763 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16764 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16765 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16766 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16767 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16768 (parallel [(set (match_dup 10)
16769 (unspec:XF [(match_dup 9) (match_dup 5)]
16770 UNSPEC_FSCALE_FRACT))
16771 (set (match_dup 11)
16772 (unspec:XF [(match_dup 9) (match_dup 5)]
16773 UNSPEC_FSCALE_EXP))])
16774 (set (match_operand:DF 0 "register_operand" "")
16775 (float_truncate:DF (match_dup 10)))]
16776 "TARGET_USE_FANCY_MATH_387
16777 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16778 && flag_unsafe_math_optimizations"
16783 for (i=2; i<12; i++)
16784 operands[i] = gen_reg_rtx (XFmode);
16785 temp = standard_80387_constant_rtx (5); /* fldl2e */
16786 emit_move_insn (operands[3], temp);
16787 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16790 (define_expand "expxf2"
16791 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16793 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16794 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16795 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16796 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16797 (parallel [(set (match_operand:XF 0 "register_operand" "")
16798 (unspec:XF [(match_dup 8) (match_dup 4)]
16799 UNSPEC_FSCALE_FRACT))
16801 (unspec:XF [(match_dup 8) (match_dup 4)]
16802 UNSPEC_FSCALE_EXP))])]
16803 "TARGET_USE_FANCY_MATH_387
16804 && flag_unsafe_math_optimizations"
16809 for (i=2; i<10; i++)
16810 operands[i] = gen_reg_rtx (XFmode);
16811 temp = standard_80387_constant_rtx (5); /* fldl2e */
16812 emit_move_insn (operands[2], temp);
16813 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16816 (define_expand "exp10sf2"
16817 [(set (match_dup 2)
16818 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16819 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16820 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16821 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16822 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16823 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16824 (parallel [(set (match_dup 10)
16825 (unspec:XF [(match_dup 9) (match_dup 5)]
16826 UNSPEC_FSCALE_FRACT))
16827 (set (match_dup 11)
16828 (unspec:XF [(match_dup 9) (match_dup 5)]
16829 UNSPEC_FSCALE_EXP))])
16830 (set (match_operand:SF 0 "register_operand" "")
16831 (float_truncate:SF (match_dup 10)))]
16832 "TARGET_USE_FANCY_MATH_387
16833 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16834 && flag_unsafe_math_optimizations"
16839 for (i=2; i<12; i++)
16840 operands[i] = gen_reg_rtx (XFmode);
16841 temp = standard_80387_constant_rtx (6); /* fldl2t */
16842 emit_move_insn (operands[3], temp);
16843 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16846 (define_expand "exp10df2"
16847 [(set (match_dup 2)
16848 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16849 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16850 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16851 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16852 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16853 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16854 (parallel [(set (match_dup 10)
16855 (unspec:XF [(match_dup 9) (match_dup 5)]
16856 UNSPEC_FSCALE_FRACT))
16857 (set (match_dup 11)
16858 (unspec:XF [(match_dup 9) (match_dup 5)]
16859 UNSPEC_FSCALE_EXP))])
16860 (set (match_operand:DF 0 "register_operand" "")
16861 (float_truncate:DF (match_dup 10)))]
16862 "TARGET_USE_FANCY_MATH_387
16863 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16864 && flag_unsafe_math_optimizations"
16869 for (i=2; i<12; i++)
16870 operands[i] = gen_reg_rtx (XFmode);
16871 temp = standard_80387_constant_rtx (6); /* fldl2t */
16872 emit_move_insn (operands[3], temp);
16873 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16876 (define_expand "exp10xf2"
16877 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16879 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16880 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16881 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16882 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16883 (parallel [(set (match_operand:XF 0 "register_operand" "")
16884 (unspec:XF [(match_dup 8) (match_dup 4)]
16885 UNSPEC_FSCALE_FRACT))
16887 (unspec:XF [(match_dup 8) (match_dup 4)]
16888 UNSPEC_FSCALE_EXP))])]
16889 "TARGET_USE_FANCY_MATH_387
16890 && flag_unsafe_math_optimizations"
16895 for (i=2; i<10; i++)
16896 operands[i] = gen_reg_rtx (XFmode);
16897 temp = standard_80387_constant_rtx (6); /* fldl2t */
16898 emit_move_insn (operands[2], temp);
16899 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16902 (define_expand "exp2sf2"
16903 [(set (match_dup 2)
16904 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16905 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16906 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16907 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16908 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16909 (parallel [(set (match_dup 8)
16910 (unspec:XF [(match_dup 7) (match_dup 3)]
16911 UNSPEC_FSCALE_FRACT))
16913 (unspec:XF [(match_dup 7) (match_dup 3)]
16914 UNSPEC_FSCALE_EXP))])
16915 (set (match_operand:SF 0 "register_operand" "")
16916 (float_truncate:SF (match_dup 8)))]
16917 "TARGET_USE_FANCY_MATH_387
16918 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16919 && flag_unsafe_math_optimizations"
16923 for (i=2; i<10; i++)
16924 operands[i] = gen_reg_rtx (XFmode);
16925 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16928 (define_expand "exp2df2"
16929 [(set (match_dup 2)
16930 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16931 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16932 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16933 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16934 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16935 (parallel [(set (match_dup 8)
16936 (unspec:XF [(match_dup 7) (match_dup 3)]
16937 UNSPEC_FSCALE_FRACT))
16939 (unspec:XF [(match_dup 7) (match_dup 3)]
16940 UNSPEC_FSCALE_EXP))])
16941 (set (match_operand:DF 0 "register_operand" "")
16942 (float_truncate:DF (match_dup 8)))]
16943 "TARGET_USE_FANCY_MATH_387
16944 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16945 && flag_unsafe_math_optimizations"
16949 for (i=2; i<10; i++)
16950 operands[i] = gen_reg_rtx (XFmode);
16951 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16954 (define_expand "exp2xf2"
16955 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16956 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16957 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16958 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16959 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16960 (parallel [(set (match_operand:XF 0 "register_operand" "")
16961 (unspec:XF [(match_dup 7) (match_dup 3)]
16962 UNSPEC_FSCALE_FRACT))
16964 (unspec:XF [(match_dup 7) (match_dup 3)]
16965 UNSPEC_FSCALE_EXP))])]
16966 "TARGET_USE_FANCY_MATH_387
16967 && flag_unsafe_math_optimizations"
16971 for (i=2; i<9; i++)
16972 operands[i] = gen_reg_rtx (XFmode);
16973 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16976 (define_expand "expm1df2"
16977 [(set (match_dup 2)
16978 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16979 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16980 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16981 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16982 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16983 (parallel [(set (match_dup 8)
16984 (unspec:XF [(match_dup 7) (match_dup 5)]
16985 UNSPEC_FSCALE_FRACT))
16987 (unspec:XF [(match_dup 7) (match_dup 5)]
16988 UNSPEC_FSCALE_EXP))])
16989 (parallel [(set (match_dup 11)
16990 (unspec:XF [(match_dup 10) (match_dup 9)]
16991 UNSPEC_FSCALE_FRACT))
16992 (set (match_dup 12)
16993 (unspec:XF [(match_dup 10) (match_dup 9)]
16994 UNSPEC_FSCALE_EXP))])
16995 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16996 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16997 (set (match_operand:DF 0 "register_operand" "")
16998 (float_truncate:DF (match_dup 14)))]
16999 "TARGET_USE_FANCY_MATH_387
17000 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17001 && flag_unsafe_math_optimizations"
17006 for (i=2; i<15; i++)
17007 operands[i] = gen_reg_rtx (XFmode);
17008 temp = standard_80387_constant_rtx (5); /* fldl2e */
17009 emit_move_insn (operands[3], temp);
17010 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17013 (define_expand "expm1sf2"
17014 [(set (match_dup 2)
17015 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17016 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17017 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17018 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17019 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17020 (parallel [(set (match_dup 8)
17021 (unspec:XF [(match_dup 7) (match_dup 5)]
17022 UNSPEC_FSCALE_FRACT))
17024 (unspec:XF [(match_dup 7) (match_dup 5)]
17025 UNSPEC_FSCALE_EXP))])
17026 (parallel [(set (match_dup 11)
17027 (unspec:XF [(match_dup 10) (match_dup 9)]
17028 UNSPEC_FSCALE_FRACT))
17029 (set (match_dup 12)
17030 (unspec:XF [(match_dup 10) (match_dup 9)]
17031 UNSPEC_FSCALE_EXP))])
17032 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17033 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17034 (set (match_operand:SF 0 "register_operand" "")
17035 (float_truncate:SF (match_dup 14)))]
17036 "TARGET_USE_FANCY_MATH_387
17037 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17038 && flag_unsafe_math_optimizations"
17043 for (i=2; i<15; i++)
17044 operands[i] = gen_reg_rtx (XFmode);
17045 temp = standard_80387_constant_rtx (5); /* fldl2e */
17046 emit_move_insn (operands[3], temp);
17047 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17050 (define_expand "expm1xf2"
17051 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17053 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17054 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17055 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17056 (parallel [(set (match_dup 7)
17057 (unspec:XF [(match_dup 6) (match_dup 4)]
17058 UNSPEC_FSCALE_FRACT))
17060 (unspec:XF [(match_dup 6) (match_dup 4)]
17061 UNSPEC_FSCALE_EXP))])
17062 (parallel [(set (match_dup 10)
17063 (unspec:XF [(match_dup 9) (match_dup 8)]
17064 UNSPEC_FSCALE_FRACT))
17065 (set (match_dup 11)
17066 (unspec:XF [(match_dup 9) (match_dup 8)]
17067 UNSPEC_FSCALE_EXP))])
17068 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17069 (set (match_operand:XF 0 "register_operand" "")
17070 (plus:XF (match_dup 12) (match_dup 7)))]
17071 "TARGET_USE_FANCY_MATH_387
17072 && flag_unsafe_math_optimizations"
17077 for (i=2; i<13; i++)
17078 operands[i] = gen_reg_rtx (XFmode);
17079 temp = standard_80387_constant_rtx (5); /* fldl2e */
17080 emit_move_insn (operands[2], temp);
17081 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17084 (define_expand "ldexpdf3"
17085 [(set (match_dup 3)
17086 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17088 (float:XF (match_operand:SI 2 "register_operand" "")))
17089 (parallel [(set (match_dup 5)
17090 (unspec:XF [(match_dup 3) (match_dup 4)]
17091 UNSPEC_FSCALE_FRACT))
17093 (unspec:XF [(match_dup 3) (match_dup 4)]
17094 UNSPEC_FSCALE_EXP))])
17095 (set (match_operand:DF 0 "register_operand" "")
17096 (float_truncate:DF (match_dup 5)))]
17097 "TARGET_USE_FANCY_MATH_387
17098 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17099 && flag_unsafe_math_optimizations"
17103 for (i=3; i<7; i++)
17104 operands[i] = gen_reg_rtx (XFmode);
17107 (define_expand "ldexpsf3"
17108 [(set (match_dup 3)
17109 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17111 (float:XF (match_operand:SI 2 "register_operand" "")))
17112 (parallel [(set (match_dup 5)
17113 (unspec:XF [(match_dup 3) (match_dup 4)]
17114 UNSPEC_FSCALE_FRACT))
17116 (unspec:XF [(match_dup 3) (match_dup 4)]
17117 UNSPEC_FSCALE_EXP))])
17118 (set (match_operand:SF 0 "register_operand" "")
17119 (float_truncate:SF (match_dup 5)))]
17120 "TARGET_USE_FANCY_MATH_387
17121 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17122 && flag_unsafe_math_optimizations"
17126 for (i=3; i<7; i++)
17127 operands[i] = gen_reg_rtx (XFmode);
17130 (define_expand "ldexpxf3"
17131 [(set (match_dup 3)
17132 (float:XF (match_operand:SI 2 "register_operand" "")))
17133 (parallel [(set (match_operand:XF 0 " register_operand" "")
17134 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17136 UNSPEC_FSCALE_FRACT))
17138 (unspec:XF [(match_dup 1) (match_dup 3)]
17139 UNSPEC_FSCALE_EXP))])]
17140 "TARGET_USE_FANCY_MATH_387
17141 && flag_unsafe_math_optimizations"
17145 for (i=3; i<5; i++)
17146 operands[i] = gen_reg_rtx (XFmode);
17150 (define_insn "frndintxf2"
17151 [(set (match_operand:XF 0 "register_operand" "=f")
17152 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17154 "TARGET_USE_FANCY_MATH_387
17155 && flag_unsafe_math_optimizations"
17157 [(set_attr "type" "fpspc")
17158 (set_attr "mode" "XF")])
17160 (define_expand "rintdf2"
17161 [(use (match_operand:DF 0 "register_operand" ""))
17162 (use (match_operand:DF 1 "register_operand" ""))]
17163 "TARGET_USE_FANCY_MATH_387
17164 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17165 && flag_unsafe_math_optimizations"
17167 rtx op0 = gen_reg_rtx (XFmode);
17168 rtx op1 = gen_reg_rtx (XFmode);
17170 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17171 emit_insn (gen_frndintxf2 (op0, op1));
17173 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17177 (define_expand "rintsf2"
17178 [(use (match_operand:SF 0 "register_operand" ""))
17179 (use (match_operand:SF 1 "register_operand" ""))]
17180 "TARGET_USE_FANCY_MATH_387
17181 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17182 && flag_unsafe_math_optimizations"
17184 rtx op0 = gen_reg_rtx (XFmode);
17185 rtx op1 = gen_reg_rtx (XFmode);
17187 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17188 emit_insn (gen_frndintxf2 (op0, op1));
17190 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17194 (define_expand "rintxf2"
17195 [(use (match_operand:XF 0 "register_operand" ""))
17196 (use (match_operand:XF 1 "register_operand" ""))]
17197 "TARGET_USE_FANCY_MATH_387
17198 && flag_unsafe_math_optimizations"
17200 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17204 (define_insn_and_split "*fistdi2_1"
17205 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17206 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17208 "TARGET_USE_FANCY_MATH_387
17209 && !(reload_completed || reload_in_progress)"
17214 if (memory_operand (operands[0], VOIDmode))
17215 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17218 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17219 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17224 [(set_attr "type" "fpspc")
17225 (set_attr "mode" "DI")])
17227 (define_insn "fistdi2"
17228 [(set (match_operand:DI 0 "memory_operand" "=m")
17229 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17231 (clobber (match_scratch:XF 2 "=&1f"))]
17232 "TARGET_USE_FANCY_MATH_387"
17233 "* return output_fix_trunc (insn, operands, 0);"
17234 [(set_attr "type" "fpspc")
17235 (set_attr "mode" "DI")])
17237 (define_insn "fistdi2_with_temp"
17238 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17239 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17241 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17242 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17243 "TARGET_USE_FANCY_MATH_387"
17245 [(set_attr "type" "fpspc")
17246 (set_attr "mode" "DI")])
17249 [(set (match_operand:DI 0 "register_operand" "")
17250 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17252 (clobber (match_operand:DI 2 "memory_operand" ""))
17253 (clobber (match_scratch 3 ""))]
17255 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17256 (clobber (match_dup 3))])
17257 (set (match_dup 0) (match_dup 2))]
17261 [(set (match_operand:DI 0 "memory_operand" "")
17262 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17264 (clobber (match_operand:DI 2 "memory_operand" ""))
17265 (clobber (match_scratch 3 ""))]
17267 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17268 (clobber (match_dup 3))])]
17271 (define_insn_and_split "*fist<mode>2_1"
17272 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17273 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17275 "TARGET_USE_FANCY_MATH_387
17276 && !(reload_completed || reload_in_progress)"
17281 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17282 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17286 [(set_attr "type" "fpspc")
17287 (set_attr "mode" "<MODE>")])
17289 (define_insn "fist<mode>2"
17290 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17291 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17293 "TARGET_USE_FANCY_MATH_387"
17294 "* return output_fix_trunc (insn, operands, 0);"
17295 [(set_attr "type" "fpspc")
17296 (set_attr "mode" "<MODE>")])
17298 (define_insn "fist<mode>2_with_temp"
17299 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17300 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17302 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17303 "TARGET_USE_FANCY_MATH_387"
17305 [(set_attr "type" "fpspc")
17306 (set_attr "mode" "<MODE>")])
17309 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17310 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17312 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17314 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17316 (set (match_dup 0) (match_dup 2))]
17320 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17321 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17323 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17325 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17329 (define_expand "lrintxf<mode>2"
17330 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17331 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17333 "TARGET_USE_FANCY_MATH_387"
17336 (define_expand "lrint<mode>di2"
17337 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17338 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17339 UNSPEC_FIX_NOTRUNC))]
17340 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17343 (define_expand "lrint<mode>si2"
17344 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17345 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17346 UNSPEC_FIX_NOTRUNC))]
17347 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17350 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17351 (define_insn_and_split "frndintxf2_floor"
17352 [(set (match_operand:XF 0 "register_operand" "=f")
17353 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17354 UNSPEC_FRNDINT_FLOOR))
17355 (clobber (reg:CC FLAGS_REG))]
17356 "TARGET_USE_FANCY_MATH_387
17357 && flag_unsafe_math_optimizations
17358 && !(reload_completed || reload_in_progress)"
17363 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17365 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17366 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17368 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17369 operands[2], operands[3]));
17372 [(set_attr "type" "frndint")
17373 (set_attr "i387_cw" "floor")
17374 (set_attr "mode" "XF")])
17376 (define_insn "frndintxf2_floor_i387"
17377 [(set (match_operand:XF 0 "register_operand" "=f")
17378 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17379 UNSPEC_FRNDINT_FLOOR))
17380 (use (match_operand:HI 2 "memory_operand" "m"))
17381 (use (match_operand:HI 3 "memory_operand" "m"))]
17382 "TARGET_USE_FANCY_MATH_387
17383 && flag_unsafe_math_optimizations"
17384 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17385 [(set_attr "type" "frndint")
17386 (set_attr "i387_cw" "floor")
17387 (set_attr "mode" "XF")])
17389 (define_expand "floorxf2"
17390 [(use (match_operand:XF 0 "register_operand" ""))
17391 (use (match_operand:XF 1 "register_operand" ""))]
17392 "TARGET_USE_FANCY_MATH_387
17393 && flag_unsafe_math_optimizations"
17395 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17399 (define_expand "floordf2"
17400 [(use (match_operand:DF 0 "register_operand" ""))
17401 (use (match_operand:DF 1 "register_operand" ""))]
17402 "TARGET_USE_FANCY_MATH_387
17403 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17404 && flag_unsafe_math_optimizations"
17406 rtx op0 = gen_reg_rtx (XFmode);
17407 rtx op1 = gen_reg_rtx (XFmode);
17409 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17410 emit_insn (gen_frndintxf2_floor (op0, op1));
17412 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17416 (define_expand "floorsf2"
17417 [(use (match_operand:SF 0 "register_operand" ""))
17418 (use (match_operand:SF 1 "register_operand" ""))]
17419 "TARGET_USE_FANCY_MATH_387
17420 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17421 && flag_unsafe_math_optimizations"
17423 rtx op0 = gen_reg_rtx (XFmode);
17424 rtx op1 = gen_reg_rtx (XFmode);
17426 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17427 emit_insn (gen_frndintxf2_floor (op0, op1));
17429 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17433 (define_insn_and_split "*fist<mode>2_floor_1"
17434 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17435 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17436 UNSPEC_FIST_FLOOR))
17437 (clobber (reg:CC FLAGS_REG))]
17438 "TARGET_USE_FANCY_MATH_387
17439 && flag_unsafe_math_optimizations
17440 && !(reload_completed || reload_in_progress)"
17445 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17447 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17448 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17449 if (memory_operand (operands[0], VOIDmode))
17450 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17451 operands[2], operands[3]));
17454 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17455 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17456 operands[2], operands[3],
17461 [(set_attr "type" "fistp")
17462 (set_attr "i387_cw" "floor")
17463 (set_attr "mode" "<MODE>")])
17465 (define_insn "fistdi2_floor"
17466 [(set (match_operand:DI 0 "memory_operand" "=m")
17467 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17468 UNSPEC_FIST_FLOOR))
17469 (use (match_operand:HI 2 "memory_operand" "m"))
17470 (use (match_operand:HI 3 "memory_operand" "m"))
17471 (clobber (match_scratch:XF 4 "=&1f"))]
17472 "TARGET_USE_FANCY_MATH_387
17473 && flag_unsafe_math_optimizations"
17474 "* return output_fix_trunc (insn, operands, 0);"
17475 [(set_attr "type" "fistp")
17476 (set_attr "i387_cw" "floor")
17477 (set_attr "mode" "DI")])
17479 (define_insn "fistdi2_floor_with_temp"
17480 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17481 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17482 UNSPEC_FIST_FLOOR))
17483 (use (match_operand:HI 2 "memory_operand" "m,m"))
17484 (use (match_operand:HI 3 "memory_operand" "m,m"))
17485 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17486 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17487 "TARGET_USE_FANCY_MATH_387
17488 && flag_unsafe_math_optimizations"
17490 [(set_attr "type" "fistp")
17491 (set_attr "i387_cw" "floor")
17492 (set_attr "mode" "DI")])
17495 [(set (match_operand:DI 0 "register_operand" "")
17496 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17497 UNSPEC_FIST_FLOOR))
17498 (use (match_operand:HI 2 "memory_operand" ""))
17499 (use (match_operand:HI 3 "memory_operand" ""))
17500 (clobber (match_operand:DI 4 "memory_operand" ""))
17501 (clobber (match_scratch 5 ""))]
17503 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17504 (use (match_dup 2))
17505 (use (match_dup 3))
17506 (clobber (match_dup 5))])
17507 (set (match_dup 0) (match_dup 4))]
17511 [(set (match_operand:DI 0 "memory_operand" "")
17512 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17513 UNSPEC_FIST_FLOOR))
17514 (use (match_operand:HI 2 "memory_operand" ""))
17515 (use (match_operand:HI 3 "memory_operand" ""))
17516 (clobber (match_operand:DI 4 "memory_operand" ""))
17517 (clobber (match_scratch 5 ""))]
17519 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17520 (use (match_dup 2))
17521 (use (match_dup 3))
17522 (clobber (match_dup 5))])]
17525 (define_insn "fist<mode>2_floor"
17526 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17527 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17528 UNSPEC_FIST_FLOOR))
17529 (use (match_operand:HI 2 "memory_operand" "m"))
17530 (use (match_operand:HI 3 "memory_operand" "m"))]
17531 "TARGET_USE_FANCY_MATH_387
17532 && flag_unsafe_math_optimizations"
17533 "* return output_fix_trunc (insn, operands, 0);"
17534 [(set_attr "type" "fistp")
17535 (set_attr "i387_cw" "floor")
17536 (set_attr "mode" "<MODE>")])
17538 (define_insn "fist<mode>2_floor_with_temp"
17539 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17540 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17541 UNSPEC_FIST_FLOOR))
17542 (use (match_operand:HI 2 "memory_operand" "m,m"))
17543 (use (match_operand:HI 3 "memory_operand" "m,m"))
17544 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17545 "TARGET_USE_FANCY_MATH_387
17546 && flag_unsafe_math_optimizations"
17548 [(set_attr "type" "fistp")
17549 (set_attr "i387_cw" "floor")
17550 (set_attr "mode" "<MODE>")])
17553 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17554 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17555 UNSPEC_FIST_FLOOR))
17556 (use (match_operand:HI 2 "memory_operand" ""))
17557 (use (match_operand:HI 3 "memory_operand" ""))
17558 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17560 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17561 UNSPEC_FIST_FLOOR))
17562 (use (match_dup 2))
17563 (use (match_dup 3))])
17564 (set (match_dup 0) (match_dup 4))]
17568 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17569 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17570 UNSPEC_FIST_FLOOR))
17571 (use (match_operand:HI 2 "memory_operand" ""))
17572 (use (match_operand:HI 3 "memory_operand" ""))
17573 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17575 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17576 UNSPEC_FIST_FLOOR))
17577 (use (match_dup 2))
17578 (use (match_dup 3))])]
17581 (define_expand "lfloor<mode>2"
17582 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17583 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17584 UNSPEC_FIST_FLOOR))
17585 (clobber (reg:CC FLAGS_REG))])]
17586 "TARGET_USE_FANCY_MATH_387
17587 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17588 && flag_unsafe_math_optimizations"
17591 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17592 (define_insn_and_split "frndintxf2_ceil"
17593 [(set (match_operand:XF 0 "register_operand" "=f")
17594 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17595 UNSPEC_FRNDINT_CEIL))
17596 (clobber (reg:CC FLAGS_REG))]
17597 "TARGET_USE_FANCY_MATH_387
17598 && flag_unsafe_math_optimizations
17599 && !(reload_completed || reload_in_progress)"
17604 ix86_optimize_mode_switching[I387_CEIL] = 1;
17606 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17607 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17609 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17610 operands[2], operands[3]));
17613 [(set_attr "type" "frndint")
17614 (set_attr "i387_cw" "ceil")
17615 (set_attr "mode" "XF")])
17617 (define_insn "frndintxf2_ceil_i387"
17618 [(set (match_operand:XF 0 "register_operand" "=f")
17619 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17620 UNSPEC_FRNDINT_CEIL))
17621 (use (match_operand:HI 2 "memory_operand" "m"))
17622 (use (match_operand:HI 3 "memory_operand" "m"))]
17623 "TARGET_USE_FANCY_MATH_387
17624 && flag_unsafe_math_optimizations"
17625 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17626 [(set_attr "type" "frndint")
17627 (set_attr "i387_cw" "ceil")
17628 (set_attr "mode" "XF")])
17630 (define_expand "ceilxf2"
17631 [(use (match_operand:XF 0 "register_operand" ""))
17632 (use (match_operand:XF 1 "register_operand" ""))]
17633 "TARGET_USE_FANCY_MATH_387
17634 && flag_unsafe_math_optimizations"
17636 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17640 (define_expand "ceildf2"
17641 [(use (match_operand:DF 0 "register_operand" ""))
17642 (use (match_operand:DF 1 "register_operand" ""))]
17643 "TARGET_USE_FANCY_MATH_387
17644 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17645 && flag_unsafe_math_optimizations"
17647 rtx op0 = gen_reg_rtx (XFmode);
17648 rtx op1 = gen_reg_rtx (XFmode);
17650 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17651 emit_insn (gen_frndintxf2_ceil (op0, op1));
17653 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17657 (define_expand "ceilsf2"
17658 [(use (match_operand:SF 0 "register_operand" ""))
17659 (use (match_operand:SF 1 "register_operand" ""))]
17660 "TARGET_USE_FANCY_MATH_387
17661 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17662 && flag_unsafe_math_optimizations"
17664 rtx op0 = gen_reg_rtx (XFmode);
17665 rtx op1 = gen_reg_rtx (XFmode);
17667 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17668 emit_insn (gen_frndintxf2_ceil (op0, op1));
17670 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17674 (define_insn_and_split "*fist<mode>2_ceil_1"
17675 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17676 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17678 (clobber (reg:CC FLAGS_REG))]
17679 "TARGET_USE_FANCY_MATH_387
17680 && flag_unsafe_math_optimizations
17681 && !(reload_completed || reload_in_progress)"
17686 ix86_optimize_mode_switching[I387_CEIL] = 1;
17688 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17689 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17690 if (memory_operand (operands[0], VOIDmode))
17691 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17692 operands[2], operands[3]));
17695 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17696 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17697 operands[2], operands[3],
17702 [(set_attr "type" "fistp")
17703 (set_attr "i387_cw" "ceil")
17704 (set_attr "mode" "<MODE>")])
17706 (define_insn "fistdi2_ceil"
17707 [(set (match_operand:DI 0 "memory_operand" "=m")
17708 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17710 (use (match_operand:HI 2 "memory_operand" "m"))
17711 (use (match_operand:HI 3 "memory_operand" "m"))
17712 (clobber (match_scratch:XF 4 "=&1f"))]
17713 "TARGET_USE_FANCY_MATH_387
17714 && flag_unsafe_math_optimizations"
17715 "* return output_fix_trunc (insn, operands, 0);"
17716 [(set_attr "type" "fistp")
17717 (set_attr "i387_cw" "ceil")
17718 (set_attr "mode" "DI")])
17720 (define_insn "fistdi2_ceil_with_temp"
17721 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17722 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17724 (use (match_operand:HI 2 "memory_operand" "m,m"))
17725 (use (match_operand:HI 3 "memory_operand" "m,m"))
17726 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17727 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17728 "TARGET_USE_FANCY_MATH_387
17729 && flag_unsafe_math_optimizations"
17731 [(set_attr "type" "fistp")
17732 (set_attr "i387_cw" "ceil")
17733 (set_attr "mode" "DI")])
17736 [(set (match_operand:DI 0 "register_operand" "")
17737 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17739 (use (match_operand:HI 2 "memory_operand" ""))
17740 (use (match_operand:HI 3 "memory_operand" ""))
17741 (clobber (match_operand:DI 4 "memory_operand" ""))
17742 (clobber (match_scratch 5 ""))]
17744 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17745 (use (match_dup 2))
17746 (use (match_dup 3))
17747 (clobber (match_dup 5))])
17748 (set (match_dup 0) (match_dup 4))]
17752 [(set (match_operand:DI 0 "memory_operand" "")
17753 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17755 (use (match_operand:HI 2 "memory_operand" ""))
17756 (use (match_operand:HI 3 "memory_operand" ""))
17757 (clobber (match_operand:DI 4 "memory_operand" ""))
17758 (clobber (match_scratch 5 ""))]
17760 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17761 (use (match_dup 2))
17762 (use (match_dup 3))
17763 (clobber (match_dup 5))])]
17766 (define_insn "fist<mode>2_ceil"
17767 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17768 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17770 (use (match_operand:HI 2 "memory_operand" "m"))
17771 (use (match_operand:HI 3 "memory_operand" "m"))]
17772 "TARGET_USE_FANCY_MATH_387
17773 && flag_unsafe_math_optimizations"
17774 "* return output_fix_trunc (insn, operands, 0);"
17775 [(set_attr "type" "fistp")
17776 (set_attr "i387_cw" "ceil")
17777 (set_attr "mode" "<MODE>")])
17779 (define_insn "fist<mode>2_ceil_with_temp"
17780 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17781 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17783 (use (match_operand:HI 2 "memory_operand" "m,m"))
17784 (use (match_operand:HI 3 "memory_operand" "m,m"))
17785 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17786 "TARGET_USE_FANCY_MATH_387
17787 && flag_unsafe_math_optimizations"
17789 [(set_attr "type" "fistp")
17790 (set_attr "i387_cw" "ceil")
17791 (set_attr "mode" "<MODE>")])
17794 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17795 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17797 (use (match_operand:HI 2 "memory_operand" ""))
17798 (use (match_operand:HI 3 "memory_operand" ""))
17799 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17801 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17803 (use (match_dup 2))
17804 (use (match_dup 3))])
17805 (set (match_dup 0) (match_dup 4))]
17809 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17810 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17812 (use (match_operand:HI 2 "memory_operand" ""))
17813 (use (match_operand:HI 3 "memory_operand" ""))
17814 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17816 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17818 (use (match_dup 2))
17819 (use (match_dup 3))])]
17822 (define_expand "lceil<mode>2"
17823 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17824 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17826 (clobber (reg:CC FLAGS_REG))])]
17827 "TARGET_USE_FANCY_MATH_387
17828 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17829 && flag_unsafe_math_optimizations"
17832 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17833 (define_insn_and_split "frndintxf2_trunc"
17834 [(set (match_operand:XF 0 "register_operand" "=f")
17835 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17836 UNSPEC_FRNDINT_TRUNC))
17837 (clobber (reg:CC FLAGS_REG))]
17838 "TARGET_USE_FANCY_MATH_387
17839 && flag_unsafe_math_optimizations
17840 && !(reload_completed || reload_in_progress)"
17845 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17847 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17848 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17850 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17851 operands[2], operands[3]));
17854 [(set_attr "type" "frndint")
17855 (set_attr "i387_cw" "trunc")
17856 (set_attr "mode" "XF")])
17858 (define_insn "frndintxf2_trunc_i387"
17859 [(set (match_operand:XF 0 "register_operand" "=f")
17860 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17861 UNSPEC_FRNDINT_TRUNC))
17862 (use (match_operand:HI 2 "memory_operand" "m"))
17863 (use (match_operand:HI 3 "memory_operand" "m"))]
17864 "TARGET_USE_FANCY_MATH_387
17865 && flag_unsafe_math_optimizations"
17866 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17867 [(set_attr "type" "frndint")
17868 (set_attr "i387_cw" "trunc")
17869 (set_attr "mode" "XF")])
17871 (define_expand "btruncxf2"
17872 [(use (match_operand:XF 0 "register_operand" ""))
17873 (use (match_operand:XF 1 "register_operand" ""))]
17874 "TARGET_USE_FANCY_MATH_387
17875 && flag_unsafe_math_optimizations"
17877 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17881 (define_expand "btruncdf2"
17882 [(use (match_operand:DF 0 "register_operand" ""))
17883 (use (match_operand:DF 1 "register_operand" ""))]
17884 "TARGET_USE_FANCY_MATH_387
17885 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17886 && flag_unsafe_math_optimizations"
17888 rtx op0 = gen_reg_rtx (XFmode);
17889 rtx op1 = gen_reg_rtx (XFmode);
17891 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17892 emit_insn (gen_frndintxf2_trunc (op0, op1));
17894 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17898 (define_expand "btruncsf2"
17899 [(use (match_operand:SF 0 "register_operand" ""))
17900 (use (match_operand:SF 1 "register_operand" ""))]
17901 "TARGET_USE_FANCY_MATH_387
17902 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17903 && flag_unsafe_math_optimizations"
17905 rtx op0 = gen_reg_rtx (XFmode);
17906 rtx op1 = gen_reg_rtx (XFmode);
17908 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17909 emit_insn (gen_frndintxf2_trunc (op0, op1));
17911 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17915 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17916 (define_insn_and_split "frndintxf2_mask_pm"
17917 [(set (match_operand:XF 0 "register_operand" "=f")
17918 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17919 UNSPEC_FRNDINT_MASK_PM))
17920 (clobber (reg:CC FLAGS_REG))]
17921 "TARGET_USE_FANCY_MATH_387
17922 && flag_unsafe_math_optimizations
17923 && !(reload_completed || reload_in_progress)"
17928 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17930 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17931 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17933 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17934 operands[2], operands[3]));
17937 [(set_attr "type" "frndint")
17938 (set_attr "i387_cw" "mask_pm")
17939 (set_attr "mode" "XF")])
17941 (define_insn "frndintxf2_mask_pm_i387"
17942 [(set (match_operand:XF 0 "register_operand" "=f")
17943 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17944 UNSPEC_FRNDINT_MASK_PM))
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 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17950 [(set_attr "type" "frndint")
17951 (set_attr "i387_cw" "mask_pm")
17952 (set_attr "mode" "XF")])
17954 (define_expand "nearbyintxf2"
17955 [(use (match_operand:XF 0 "register_operand" ""))
17956 (use (match_operand:XF 1 "register_operand" ""))]
17957 "TARGET_USE_FANCY_MATH_387
17958 && flag_unsafe_math_optimizations"
17960 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17965 (define_expand "nearbyintdf2"
17966 [(use (match_operand:DF 0 "register_operand" ""))
17967 (use (match_operand:DF 1 "register_operand" ""))]
17968 "TARGET_USE_FANCY_MATH_387
17969 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17970 && flag_unsafe_math_optimizations"
17972 rtx op0 = gen_reg_rtx (XFmode);
17973 rtx op1 = gen_reg_rtx (XFmode);
17975 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17976 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17978 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17982 (define_expand "nearbyintsf2"
17983 [(use (match_operand:SF 0 "register_operand" ""))
17984 (use (match_operand:SF 1 "register_operand" ""))]
17985 "TARGET_USE_FANCY_MATH_387
17986 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17987 && flag_unsafe_math_optimizations"
17989 rtx op0 = gen_reg_rtx (XFmode);
17990 rtx op1 = gen_reg_rtx (XFmode);
17992 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17993 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17995 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18000 ;; Block operation instructions
18003 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18006 [(set_attr "type" "cld")])
18008 (define_expand "movmemsi"
18009 [(use (match_operand:BLK 0 "memory_operand" ""))
18010 (use (match_operand:BLK 1 "memory_operand" ""))
18011 (use (match_operand:SI 2 "nonmemory_operand" ""))
18012 (use (match_operand:SI 3 "const_int_operand" ""))]
18013 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18015 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18021 (define_expand "movmemdi"
18022 [(use (match_operand:BLK 0 "memory_operand" ""))
18023 (use (match_operand:BLK 1 "memory_operand" ""))
18024 (use (match_operand:DI 2 "nonmemory_operand" ""))
18025 (use (match_operand:DI 3 "const_int_operand" ""))]
18028 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18034 ;; Most CPUs don't like single string operations
18035 ;; Handle this case here to simplify previous expander.
18037 (define_expand "strmov"
18038 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18039 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18040 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18041 (clobber (reg:CC FLAGS_REG))])
18042 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18043 (clobber (reg:CC FLAGS_REG))])]
18046 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18048 /* If .md ever supports :P for Pmode, these can be directly
18049 in the pattern above. */
18050 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18051 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18053 if (TARGET_SINGLE_STRINGOP || optimize_size)
18055 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18056 operands[2], operands[3],
18057 operands[5], operands[6]));
18061 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18064 (define_expand "strmov_singleop"
18065 [(parallel [(set (match_operand 1 "memory_operand" "")
18066 (match_operand 3 "memory_operand" ""))
18067 (set (match_operand 0 "register_operand" "")
18068 (match_operand 4 "" ""))
18069 (set (match_operand 2 "register_operand" "")
18070 (match_operand 5 "" ""))
18071 (use (reg:SI DIRFLAG_REG))])]
18072 "TARGET_SINGLE_STRINGOP || optimize_size"
18075 (define_insn "*strmovdi_rex_1"
18076 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18077 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18078 (set (match_operand:DI 0 "register_operand" "=D")
18079 (plus:DI (match_dup 2)
18081 (set (match_operand:DI 1 "register_operand" "=S")
18082 (plus:DI (match_dup 3)
18084 (use (reg:SI DIRFLAG_REG))]
18085 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18087 [(set_attr "type" "str")
18088 (set_attr "mode" "DI")
18089 (set_attr "memory" "both")])
18091 (define_insn "*strmovsi_1"
18092 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18093 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18094 (set (match_operand:SI 0 "register_operand" "=D")
18095 (plus:SI (match_dup 2)
18097 (set (match_operand:SI 1 "register_operand" "=S")
18098 (plus:SI (match_dup 3)
18100 (use (reg:SI DIRFLAG_REG))]
18101 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18103 [(set_attr "type" "str")
18104 (set_attr "mode" "SI")
18105 (set_attr "memory" "both")])
18107 (define_insn "*strmovsi_rex_1"
18108 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18109 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18110 (set (match_operand:DI 0 "register_operand" "=D")
18111 (plus:DI (match_dup 2)
18113 (set (match_operand:DI 1 "register_operand" "=S")
18114 (plus:DI (match_dup 3)
18116 (use (reg:SI DIRFLAG_REG))]
18117 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18119 [(set_attr "type" "str")
18120 (set_attr "mode" "SI")
18121 (set_attr "memory" "both")])
18123 (define_insn "*strmovhi_1"
18124 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18125 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18126 (set (match_operand:SI 0 "register_operand" "=D")
18127 (plus:SI (match_dup 2)
18129 (set (match_operand:SI 1 "register_operand" "=S")
18130 (plus:SI (match_dup 3)
18132 (use (reg:SI DIRFLAG_REG))]
18133 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18135 [(set_attr "type" "str")
18136 (set_attr "memory" "both")
18137 (set_attr "mode" "HI")])
18139 (define_insn "*strmovhi_rex_1"
18140 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18141 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18142 (set (match_operand:DI 0 "register_operand" "=D")
18143 (plus:DI (match_dup 2)
18145 (set (match_operand:DI 1 "register_operand" "=S")
18146 (plus:DI (match_dup 3)
18148 (use (reg:SI DIRFLAG_REG))]
18149 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18151 [(set_attr "type" "str")
18152 (set_attr "memory" "both")
18153 (set_attr "mode" "HI")])
18155 (define_insn "*strmovqi_1"
18156 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18157 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18158 (set (match_operand:SI 0 "register_operand" "=D")
18159 (plus:SI (match_dup 2)
18161 (set (match_operand:SI 1 "register_operand" "=S")
18162 (plus:SI (match_dup 3)
18164 (use (reg:SI DIRFLAG_REG))]
18165 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18167 [(set_attr "type" "str")
18168 (set_attr "memory" "both")
18169 (set_attr "mode" "QI")])
18171 (define_insn "*strmovqi_rex_1"
18172 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18173 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18174 (set (match_operand:DI 0 "register_operand" "=D")
18175 (plus:DI (match_dup 2)
18177 (set (match_operand:DI 1 "register_operand" "=S")
18178 (plus:DI (match_dup 3)
18180 (use (reg:SI DIRFLAG_REG))]
18181 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18183 [(set_attr "type" "str")
18184 (set_attr "memory" "both")
18185 (set_attr "mode" "QI")])
18187 (define_expand "rep_mov"
18188 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18189 (set (match_operand 0 "register_operand" "")
18190 (match_operand 5 "" ""))
18191 (set (match_operand 2 "register_operand" "")
18192 (match_operand 6 "" ""))
18193 (set (match_operand 1 "memory_operand" "")
18194 (match_operand 3 "memory_operand" ""))
18195 (use (match_dup 4))
18196 (use (reg:SI DIRFLAG_REG))])]
18200 (define_insn "*rep_movdi_rex64"
18201 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18202 (set (match_operand:DI 0 "register_operand" "=D")
18203 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18205 (match_operand:DI 3 "register_operand" "0")))
18206 (set (match_operand:DI 1 "register_operand" "=S")
18207 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18208 (match_operand:DI 4 "register_operand" "1")))
18209 (set (mem:BLK (match_dup 3))
18210 (mem:BLK (match_dup 4)))
18211 (use (match_dup 5))
18212 (use (reg:SI DIRFLAG_REG))]
18214 "{rep\;movsq|rep movsq}"
18215 [(set_attr "type" "str")
18216 (set_attr "prefix_rep" "1")
18217 (set_attr "memory" "both")
18218 (set_attr "mode" "DI")])
18220 (define_insn "*rep_movsi"
18221 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18222 (set (match_operand:SI 0 "register_operand" "=D")
18223 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18225 (match_operand:SI 3 "register_operand" "0")))
18226 (set (match_operand:SI 1 "register_operand" "=S")
18227 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18228 (match_operand:SI 4 "register_operand" "1")))
18229 (set (mem:BLK (match_dup 3))
18230 (mem:BLK (match_dup 4)))
18231 (use (match_dup 5))
18232 (use (reg:SI DIRFLAG_REG))]
18234 "{rep\;movsl|rep movsd}"
18235 [(set_attr "type" "str")
18236 (set_attr "prefix_rep" "1")
18237 (set_attr "memory" "both")
18238 (set_attr "mode" "SI")])
18240 (define_insn "*rep_movsi_rex64"
18241 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18242 (set (match_operand:DI 0 "register_operand" "=D")
18243 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18245 (match_operand:DI 3 "register_operand" "0")))
18246 (set (match_operand:DI 1 "register_operand" "=S")
18247 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18248 (match_operand:DI 4 "register_operand" "1")))
18249 (set (mem:BLK (match_dup 3))
18250 (mem:BLK (match_dup 4)))
18251 (use (match_dup 5))
18252 (use (reg:SI DIRFLAG_REG))]
18254 "{rep\;movsl|rep movsd}"
18255 [(set_attr "type" "str")
18256 (set_attr "prefix_rep" "1")
18257 (set_attr "memory" "both")
18258 (set_attr "mode" "SI")])
18260 (define_insn "*rep_movqi"
18261 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18262 (set (match_operand:SI 0 "register_operand" "=D")
18263 (plus:SI (match_operand:SI 3 "register_operand" "0")
18264 (match_operand:SI 5 "register_operand" "2")))
18265 (set (match_operand:SI 1 "register_operand" "=S")
18266 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18267 (set (mem:BLK (match_dup 3))
18268 (mem:BLK (match_dup 4)))
18269 (use (match_dup 5))
18270 (use (reg:SI DIRFLAG_REG))]
18272 "{rep\;movsb|rep movsb}"
18273 [(set_attr "type" "str")
18274 (set_attr "prefix_rep" "1")
18275 (set_attr "memory" "both")
18276 (set_attr "mode" "SI")])
18278 (define_insn "*rep_movqi_rex64"
18279 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18280 (set (match_operand:DI 0 "register_operand" "=D")
18281 (plus:DI (match_operand:DI 3 "register_operand" "0")
18282 (match_operand:DI 5 "register_operand" "2")))
18283 (set (match_operand:DI 1 "register_operand" "=S")
18284 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18285 (set (mem:BLK (match_dup 3))
18286 (mem:BLK (match_dup 4)))
18287 (use (match_dup 5))
18288 (use (reg:SI DIRFLAG_REG))]
18290 "{rep\;movsb|rep movsb}"
18291 [(set_attr "type" "str")
18292 (set_attr "prefix_rep" "1")
18293 (set_attr "memory" "both")
18294 (set_attr "mode" "SI")])
18296 (define_expand "setmemsi"
18297 [(use (match_operand:BLK 0 "memory_operand" ""))
18298 (use (match_operand:SI 1 "nonmemory_operand" ""))
18299 (use (match_operand 2 "const_int_operand" ""))
18300 (use (match_operand 3 "const_int_operand" ""))]
18303 /* If value to set is not zero, use the library routine. */
18304 if (operands[2] != const0_rtx)
18307 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18313 (define_expand "setmemdi"
18314 [(use (match_operand:BLK 0 "memory_operand" ""))
18315 (use (match_operand:DI 1 "nonmemory_operand" ""))
18316 (use (match_operand 2 "const_int_operand" ""))
18317 (use (match_operand 3 "const_int_operand" ""))]
18320 /* If value to set is not zero, use the library routine. */
18321 if (operands[2] != const0_rtx)
18324 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18330 ;; Most CPUs don't like single string operations
18331 ;; Handle this case here to simplify previous expander.
18333 (define_expand "strset"
18334 [(set (match_operand 1 "memory_operand" "")
18335 (match_operand 2 "register_operand" ""))
18336 (parallel [(set (match_operand 0 "register_operand" "")
18338 (clobber (reg:CC FLAGS_REG))])]
18341 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18342 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18344 /* If .md ever supports :P for Pmode, this can be directly
18345 in the pattern above. */
18346 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18347 GEN_INT (GET_MODE_SIZE (GET_MODE
18349 if (TARGET_SINGLE_STRINGOP || optimize_size)
18351 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18357 (define_expand "strset_singleop"
18358 [(parallel [(set (match_operand 1 "memory_operand" "")
18359 (match_operand 2 "register_operand" ""))
18360 (set (match_operand 0 "register_operand" "")
18361 (match_operand 3 "" ""))
18362 (use (reg:SI DIRFLAG_REG))])]
18363 "TARGET_SINGLE_STRINGOP || optimize_size"
18366 (define_insn "*strsetdi_rex_1"
18367 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18368 (match_operand:DI 2 "register_operand" "a"))
18369 (set (match_operand:DI 0 "register_operand" "=D")
18370 (plus:DI (match_dup 1)
18372 (use (reg:SI DIRFLAG_REG))]
18373 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18375 [(set_attr "type" "str")
18376 (set_attr "memory" "store")
18377 (set_attr "mode" "DI")])
18379 (define_insn "*strsetsi_1"
18380 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18381 (match_operand:SI 2 "register_operand" "a"))
18382 (set (match_operand:SI 0 "register_operand" "=D")
18383 (plus:SI (match_dup 1)
18385 (use (reg:SI DIRFLAG_REG))]
18386 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18388 [(set_attr "type" "str")
18389 (set_attr "memory" "store")
18390 (set_attr "mode" "SI")])
18392 (define_insn "*strsetsi_rex_1"
18393 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18394 (match_operand:SI 2 "register_operand" "a"))
18395 (set (match_operand:DI 0 "register_operand" "=D")
18396 (plus:DI (match_dup 1)
18398 (use (reg:SI DIRFLAG_REG))]
18399 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18401 [(set_attr "type" "str")
18402 (set_attr "memory" "store")
18403 (set_attr "mode" "SI")])
18405 (define_insn "*strsethi_1"
18406 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18407 (match_operand:HI 2 "register_operand" "a"))
18408 (set (match_operand:SI 0 "register_operand" "=D")
18409 (plus:SI (match_dup 1)
18411 (use (reg:SI DIRFLAG_REG))]
18412 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18414 [(set_attr "type" "str")
18415 (set_attr "memory" "store")
18416 (set_attr "mode" "HI")])
18418 (define_insn "*strsethi_rex_1"
18419 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18420 (match_operand:HI 2 "register_operand" "a"))
18421 (set (match_operand:DI 0 "register_operand" "=D")
18422 (plus:DI (match_dup 1)
18424 (use (reg:SI DIRFLAG_REG))]
18425 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18427 [(set_attr "type" "str")
18428 (set_attr "memory" "store")
18429 (set_attr "mode" "HI")])
18431 (define_insn "*strsetqi_1"
18432 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18433 (match_operand:QI 2 "register_operand" "a"))
18434 (set (match_operand:SI 0 "register_operand" "=D")
18435 (plus:SI (match_dup 1)
18437 (use (reg:SI DIRFLAG_REG))]
18438 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18440 [(set_attr "type" "str")
18441 (set_attr "memory" "store")
18442 (set_attr "mode" "QI")])
18444 (define_insn "*strsetqi_rex_1"
18445 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18446 (match_operand:QI 2 "register_operand" "a"))
18447 (set (match_operand:DI 0 "register_operand" "=D")
18448 (plus:DI (match_dup 1)
18450 (use (reg:SI DIRFLAG_REG))]
18451 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18453 [(set_attr "type" "str")
18454 (set_attr "memory" "store")
18455 (set_attr "mode" "QI")])
18457 (define_expand "rep_stos"
18458 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18459 (set (match_operand 0 "register_operand" "")
18460 (match_operand 4 "" ""))
18461 (set (match_operand 2 "memory_operand" "") (const_int 0))
18462 (use (match_operand 3 "register_operand" ""))
18463 (use (match_dup 1))
18464 (use (reg:SI DIRFLAG_REG))])]
18468 (define_insn "*rep_stosdi_rex64"
18469 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18470 (set (match_operand:DI 0 "register_operand" "=D")
18471 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18473 (match_operand:DI 3 "register_operand" "0")))
18474 (set (mem:BLK (match_dup 3))
18476 (use (match_operand:DI 2 "register_operand" "a"))
18477 (use (match_dup 4))
18478 (use (reg:SI DIRFLAG_REG))]
18480 "{rep\;stosq|rep stosq}"
18481 [(set_attr "type" "str")
18482 (set_attr "prefix_rep" "1")
18483 (set_attr "memory" "store")
18484 (set_attr "mode" "DI")])
18486 (define_insn "*rep_stossi"
18487 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18488 (set (match_operand:SI 0 "register_operand" "=D")
18489 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18491 (match_operand:SI 3 "register_operand" "0")))
18492 (set (mem:BLK (match_dup 3))
18494 (use (match_operand:SI 2 "register_operand" "a"))
18495 (use (match_dup 4))
18496 (use (reg:SI DIRFLAG_REG))]
18498 "{rep\;stosl|rep stosd}"
18499 [(set_attr "type" "str")
18500 (set_attr "prefix_rep" "1")
18501 (set_attr "memory" "store")
18502 (set_attr "mode" "SI")])
18504 (define_insn "*rep_stossi_rex64"
18505 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18506 (set (match_operand:DI 0 "register_operand" "=D")
18507 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18509 (match_operand:DI 3 "register_operand" "0")))
18510 (set (mem:BLK (match_dup 3))
18512 (use (match_operand:SI 2 "register_operand" "a"))
18513 (use (match_dup 4))
18514 (use (reg:SI DIRFLAG_REG))]
18516 "{rep\;stosl|rep stosd}"
18517 [(set_attr "type" "str")
18518 (set_attr "prefix_rep" "1")
18519 (set_attr "memory" "store")
18520 (set_attr "mode" "SI")])
18522 (define_insn "*rep_stosqi"
18523 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18524 (set (match_operand:SI 0 "register_operand" "=D")
18525 (plus:SI (match_operand:SI 3 "register_operand" "0")
18526 (match_operand:SI 4 "register_operand" "1")))
18527 (set (mem:BLK (match_dup 3))
18529 (use (match_operand:QI 2 "register_operand" "a"))
18530 (use (match_dup 4))
18531 (use (reg:SI DIRFLAG_REG))]
18533 "{rep\;stosb|rep stosb}"
18534 [(set_attr "type" "str")
18535 (set_attr "prefix_rep" "1")
18536 (set_attr "memory" "store")
18537 (set_attr "mode" "QI")])
18539 (define_insn "*rep_stosqi_rex64"
18540 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18541 (set (match_operand:DI 0 "register_operand" "=D")
18542 (plus:DI (match_operand:DI 3 "register_operand" "0")
18543 (match_operand:DI 4 "register_operand" "1")))
18544 (set (mem:BLK (match_dup 3))
18546 (use (match_operand:QI 2 "register_operand" "a"))
18547 (use (match_dup 4))
18548 (use (reg:SI DIRFLAG_REG))]
18550 "{rep\;stosb|rep stosb}"
18551 [(set_attr "type" "str")
18552 (set_attr "prefix_rep" "1")
18553 (set_attr "memory" "store")
18554 (set_attr "mode" "QI")])
18556 (define_expand "cmpstrnsi"
18557 [(set (match_operand:SI 0 "register_operand" "")
18558 (compare:SI (match_operand:BLK 1 "general_operand" "")
18559 (match_operand:BLK 2 "general_operand" "")))
18560 (use (match_operand 3 "general_operand" ""))
18561 (use (match_operand 4 "immediate_operand" ""))]
18562 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18564 rtx addr1, addr2, out, outlow, count, countreg, align;
18566 /* Can't use this if the user has appropriated esi or edi. */
18567 if (global_regs[4] || global_regs[5])
18571 if (GET_CODE (out) != REG)
18572 out = gen_reg_rtx (SImode);
18574 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18575 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18576 if (addr1 != XEXP (operands[1], 0))
18577 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18578 if (addr2 != XEXP (operands[2], 0))
18579 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18581 count = operands[3];
18582 countreg = ix86_zero_extend_to_Pmode (count);
18584 /* %%% Iff we are testing strict equality, we can use known alignment
18585 to good advantage. This may be possible with combine, particularly
18586 once cc0 is dead. */
18587 align = operands[4];
18589 emit_insn (gen_cld ());
18590 if (GET_CODE (count) == CONST_INT)
18592 if (INTVAL (count) == 0)
18594 emit_move_insn (operands[0], const0_rtx);
18597 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18598 operands[1], operands[2]));
18603 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18605 emit_insn (gen_cmpsi_1 (countreg, countreg));
18606 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18607 operands[1], operands[2]));
18610 outlow = gen_lowpart (QImode, out);
18611 emit_insn (gen_cmpintqi (outlow));
18612 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18614 if (operands[0] != out)
18615 emit_move_insn (operands[0], out);
18620 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18622 (define_expand "cmpintqi"
18623 [(set (match_dup 1)
18624 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18626 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18627 (parallel [(set (match_operand:QI 0 "register_operand" "")
18628 (minus:QI (match_dup 1)
18630 (clobber (reg:CC FLAGS_REG))])]
18632 "operands[1] = gen_reg_rtx (QImode);
18633 operands[2] = gen_reg_rtx (QImode);")
18635 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18636 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18638 (define_expand "cmpstrnqi_nz_1"
18639 [(parallel [(set (reg:CC FLAGS_REG)
18640 (compare:CC (match_operand 4 "memory_operand" "")
18641 (match_operand 5 "memory_operand" "")))
18642 (use (match_operand 2 "register_operand" ""))
18643 (use (match_operand:SI 3 "immediate_operand" ""))
18644 (use (reg:SI DIRFLAG_REG))
18645 (clobber (match_operand 0 "register_operand" ""))
18646 (clobber (match_operand 1 "register_operand" ""))
18647 (clobber (match_dup 2))])]
18651 (define_insn "*cmpstrnqi_nz_1"
18652 [(set (reg:CC FLAGS_REG)
18653 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18654 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18655 (use (match_operand:SI 6 "register_operand" "2"))
18656 (use (match_operand:SI 3 "immediate_operand" "i"))
18657 (use (reg:SI DIRFLAG_REG))
18658 (clobber (match_operand:SI 0 "register_operand" "=S"))
18659 (clobber (match_operand:SI 1 "register_operand" "=D"))
18660 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18663 [(set_attr "type" "str")
18664 (set_attr "mode" "QI")
18665 (set_attr "prefix_rep" "1")])
18667 (define_insn "*cmpstrnqi_nz_rex_1"
18668 [(set (reg:CC FLAGS_REG)
18669 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18670 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18671 (use (match_operand:DI 6 "register_operand" "2"))
18672 (use (match_operand:SI 3 "immediate_operand" "i"))
18673 (use (reg:SI DIRFLAG_REG))
18674 (clobber (match_operand:DI 0 "register_operand" "=S"))
18675 (clobber (match_operand:DI 1 "register_operand" "=D"))
18676 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18679 [(set_attr "type" "str")
18680 (set_attr "mode" "QI")
18681 (set_attr "prefix_rep" "1")])
18683 ;; The same, but the count is not known to not be zero.
18685 (define_expand "cmpstrnqi_1"
18686 [(parallel [(set (reg:CC FLAGS_REG)
18687 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18689 (compare:CC (match_operand 4 "memory_operand" "")
18690 (match_operand 5 "memory_operand" ""))
18692 (use (match_operand:SI 3 "immediate_operand" ""))
18693 (use (reg:CC FLAGS_REG))
18694 (use (reg:SI DIRFLAG_REG))
18695 (clobber (match_operand 0 "register_operand" ""))
18696 (clobber (match_operand 1 "register_operand" ""))
18697 (clobber (match_dup 2))])]
18701 (define_insn "*cmpstrnqi_1"
18702 [(set (reg:CC FLAGS_REG)
18703 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18705 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18706 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18708 (use (match_operand:SI 3 "immediate_operand" "i"))
18709 (use (reg:CC FLAGS_REG))
18710 (use (reg:SI DIRFLAG_REG))
18711 (clobber (match_operand:SI 0 "register_operand" "=S"))
18712 (clobber (match_operand:SI 1 "register_operand" "=D"))
18713 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18716 [(set_attr "type" "str")
18717 (set_attr "mode" "QI")
18718 (set_attr "prefix_rep" "1")])
18720 (define_insn "*cmpstrnqi_rex_1"
18721 [(set (reg:CC FLAGS_REG)
18722 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18724 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18725 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18727 (use (match_operand:SI 3 "immediate_operand" "i"))
18728 (use (reg:CC FLAGS_REG))
18729 (use (reg:SI DIRFLAG_REG))
18730 (clobber (match_operand:DI 0 "register_operand" "=S"))
18731 (clobber (match_operand:DI 1 "register_operand" "=D"))
18732 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18735 [(set_attr "type" "str")
18736 (set_attr "mode" "QI")
18737 (set_attr "prefix_rep" "1")])
18739 (define_expand "strlensi"
18740 [(set (match_operand:SI 0 "register_operand" "")
18741 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18742 (match_operand:QI 2 "immediate_operand" "")
18743 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18746 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18752 (define_expand "strlendi"
18753 [(set (match_operand:DI 0 "register_operand" "")
18754 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18755 (match_operand:QI 2 "immediate_operand" "")
18756 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18759 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18765 (define_expand "strlenqi_1"
18766 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18767 (use (reg:SI DIRFLAG_REG))
18768 (clobber (match_operand 1 "register_operand" ""))
18769 (clobber (reg:CC FLAGS_REG))])]
18773 (define_insn "*strlenqi_1"
18774 [(set (match_operand:SI 0 "register_operand" "=&c")
18775 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18776 (match_operand:QI 2 "register_operand" "a")
18777 (match_operand:SI 3 "immediate_operand" "i")
18778 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18779 (use (reg:SI DIRFLAG_REG))
18780 (clobber (match_operand:SI 1 "register_operand" "=D"))
18781 (clobber (reg:CC FLAGS_REG))]
18784 [(set_attr "type" "str")
18785 (set_attr "mode" "QI")
18786 (set_attr "prefix_rep" "1")])
18788 (define_insn "*strlenqi_rex_1"
18789 [(set (match_operand:DI 0 "register_operand" "=&c")
18790 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18791 (match_operand:QI 2 "register_operand" "a")
18792 (match_operand:DI 3 "immediate_operand" "i")
18793 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18794 (use (reg:SI DIRFLAG_REG))
18795 (clobber (match_operand:DI 1 "register_operand" "=D"))
18796 (clobber (reg:CC FLAGS_REG))]
18799 [(set_attr "type" "str")
18800 (set_attr "mode" "QI")
18801 (set_attr "prefix_rep" "1")])
18803 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18804 ;; handled in combine, but it is not currently up to the task.
18805 ;; When used for their truth value, the cmpstrn* expanders generate
18814 ;; The intermediate three instructions are unnecessary.
18816 ;; This one handles cmpstrn*_nz_1...
18819 (set (reg:CC FLAGS_REG)
18820 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18821 (mem:BLK (match_operand 5 "register_operand" ""))))
18822 (use (match_operand 6 "register_operand" ""))
18823 (use (match_operand:SI 3 "immediate_operand" ""))
18824 (use (reg:SI DIRFLAG_REG))
18825 (clobber (match_operand 0 "register_operand" ""))
18826 (clobber (match_operand 1 "register_operand" ""))
18827 (clobber (match_operand 2 "register_operand" ""))])
18828 (set (match_operand:QI 7 "register_operand" "")
18829 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18830 (set (match_operand:QI 8 "register_operand" "")
18831 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18832 (set (reg FLAGS_REG)
18833 (compare (match_dup 7) (match_dup 8)))
18835 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18837 (set (reg:CC FLAGS_REG)
18838 (compare:CC (mem:BLK (match_dup 4))
18839 (mem:BLK (match_dup 5))))
18840 (use (match_dup 6))
18841 (use (match_dup 3))
18842 (use (reg:SI DIRFLAG_REG))
18843 (clobber (match_dup 0))
18844 (clobber (match_dup 1))
18845 (clobber (match_dup 2))])]
18848 ;; ...and this one handles cmpstrn*_1.
18851 (set (reg:CC FLAGS_REG)
18852 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18854 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18855 (mem:BLK (match_operand 5 "register_operand" "")))
18857 (use (match_operand:SI 3 "immediate_operand" ""))
18858 (use (reg:CC FLAGS_REG))
18859 (use (reg:SI DIRFLAG_REG))
18860 (clobber (match_operand 0 "register_operand" ""))
18861 (clobber (match_operand 1 "register_operand" ""))
18862 (clobber (match_operand 2 "register_operand" ""))])
18863 (set (match_operand:QI 7 "register_operand" "")
18864 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18865 (set (match_operand:QI 8 "register_operand" "")
18866 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18867 (set (reg FLAGS_REG)
18868 (compare (match_dup 7) (match_dup 8)))
18870 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18872 (set (reg:CC FLAGS_REG)
18873 (if_then_else:CC (ne (match_dup 6)
18875 (compare:CC (mem:BLK (match_dup 4))
18876 (mem:BLK (match_dup 5)))
18878 (use (match_dup 3))
18879 (use (reg:CC FLAGS_REG))
18880 (use (reg:SI DIRFLAG_REG))
18881 (clobber (match_dup 0))
18882 (clobber (match_dup 1))
18883 (clobber (match_dup 2))])]
18888 ;; Conditional move instructions.
18890 (define_expand "movdicc"
18891 [(set (match_operand:DI 0 "register_operand" "")
18892 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18893 (match_operand:DI 2 "general_operand" "")
18894 (match_operand:DI 3 "general_operand" "")))]
18896 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18898 (define_insn "x86_movdicc_0_m1_rex64"
18899 [(set (match_operand:DI 0 "register_operand" "=r")
18900 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18903 (clobber (reg:CC FLAGS_REG))]
18906 ; Since we don't have the proper number of operands for an alu insn,
18907 ; fill in all the blanks.
18908 [(set_attr "type" "alu")
18909 (set_attr "pent_pair" "pu")
18910 (set_attr "memory" "none")
18911 (set_attr "imm_disp" "false")
18912 (set_attr "mode" "DI")
18913 (set_attr "length_immediate" "0")])
18915 (define_insn "*movdicc_c_rex64"
18916 [(set (match_operand:DI 0 "register_operand" "=r,r")
18917 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18918 [(reg FLAGS_REG) (const_int 0)])
18919 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18920 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18921 "TARGET_64BIT && TARGET_CMOVE
18922 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18924 cmov%O2%C1\t{%2, %0|%0, %2}
18925 cmov%O2%c1\t{%3, %0|%0, %3}"
18926 [(set_attr "type" "icmov")
18927 (set_attr "mode" "DI")])
18929 (define_expand "movsicc"
18930 [(set (match_operand:SI 0 "register_operand" "")
18931 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18932 (match_operand:SI 2 "general_operand" "")
18933 (match_operand:SI 3 "general_operand" "")))]
18935 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18937 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18938 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18939 ;; So just document what we're doing explicitly.
18941 (define_insn "x86_movsicc_0_m1"
18942 [(set (match_operand:SI 0 "register_operand" "=r")
18943 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18946 (clobber (reg:CC FLAGS_REG))]
18949 ; Since we don't have the proper number of operands for an alu insn,
18950 ; fill in all the blanks.
18951 [(set_attr "type" "alu")
18952 (set_attr "pent_pair" "pu")
18953 (set_attr "memory" "none")
18954 (set_attr "imm_disp" "false")
18955 (set_attr "mode" "SI")
18956 (set_attr "length_immediate" "0")])
18958 (define_insn "*movsicc_noc"
18959 [(set (match_operand:SI 0 "register_operand" "=r,r")
18960 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18961 [(reg FLAGS_REG) (const_int 0)])
18962 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18963 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18965 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18967 cmov%O2%C1\t{%2, %0|%0, %2}
18968 cmov%O2%c1\t{%3, %0|%0, %3}"
18969 [(set_attr "type" "icmov")
18970 (set_attr "mode" "SI")])
18972 (define_expand "movhicc"
18973 [(set (match_operand:HI 0 "register_operand" "")
18974 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18975 (match_operand:HI 2 "general_operand" "")
18976 (match_operand:HI 3 "general_operand" "")))]
18977 "TARGET_HIMODE_MATH"
18978 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18980 (define_insn "*movhicc_noc"
18981 [(set (match_operand:HI 0 "register_operand" "=r,r")
18982 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18983 [(reg FLAGS_REG) (const_int 0)])
18984 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18985 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18987 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18989 cmov%O2%C1\t{%2, %0|%0, %2}
18990 cmov%O2%c1\t{%3, %0|%0, %3}"
18991 [(set_attr "type" "icmov")
18992 (set_attr "mode" "HI")])
18994 (define_expand "movqicc"
18995 [(set (match_operand:QI 0 "register_operand" "")
18996 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18997 (match_operand:QI 2 "general_operand" "")
18998 (match_operand:QI 3 "general_operand" "")))]
18999 "TARGET_QIMODE_MATH"
19000 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19002 (define_insn_and_split "*movqicc_noc"
19003 [(set (match_operand:QI 0 "register_operand" "=r,r")
19004 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19005 [(match_operand 4 "flags_reg_operand" "")
19007 (match_operand:QI 2 "register_operand" "r,0")
19008 (match_operand:QI 3 "register_operand" "0,r")))]
19009 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19011 "&& reload_completed"
19012 [(set (match_dup 0)
19013 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19016 "operands[0] = gen_lowpart (SImode, operands[0]);
19017 operands[2] = gen_lowpart (SImode, operands[2]);
19018 operands[3] = gen_lowpart (SImode, operands[3]);"
19019 [(set_attr "type" "icmov")
19020 (set_attr "mode" "SI")])
19022 (define_expand "movsfcc"
19023 [(set (match_operand:SF 0 "register_operand" "")
19024 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19025 (match_operand:SF 2 "register_operand" "")
19026 (match_operand:SF 3 "register_operand" "")))]
19027 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19028 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19030 (define_insn "*movsfcc_1_387"
19031 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19032 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19033 [(reg FLAGS_REG) (const_int 0)])
19034 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19035 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19036 "TARGET_80387 && TARGET_CMOVE
19037 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19039 fcmov%F1\t{%2, %0|%0, %2}
19040 fcmov%f1\t{%3, %0|%0, %3}
19041 cmov%O2%C1\t{%2, %0|%0, %2}
19042 cmov%O2%c1\t{%3, %0|%0, %3}"
19043 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19044 (set_attr "mode" "SF,SF,SI,SI")])
19046 (define_expand "movdfcc"
19047 [(set (match_operand:DF 0 "register_operand" "")
19048 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19049 (match_operand:DF 2 "register_operand" "")
19050 (match_operand:DF 3 "register_operand" "")))]
19051 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19052 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19054 (define_insn "*movdfcc_1"
19055 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19056 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19057 [(reg FLAGS_REG) (const_int 0)])
19058 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19059 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19060 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19061 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19063 fcmov%F1\t{%2, %0|%0, %2}
19064 fcmov%f1\t{%3, %0|%0, %3}
19067 [(set_attr "type" "fcmov,fcmov,multi,multi")
19068 (set_attr "mode" "DF")])
19070 (define_insn "*movdfcc_1_rex64"
19071 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19072 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19073 [(reg FLAGS_REG) (const_int 0)])
19074 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19075 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19076 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19077 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19079 fcmov%F1\t{%2, %0|%0, %2}
19080 fcmov%f1\t{%3, %0|%0, %3}
19081 cmov%O2%C1\t{%2, %0|%0, %2}
19082 cmov%O2%c1\t{%3, %0|%0, %3}"
19083 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19084 (set_attr "mode" "DF")])
19087 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19088 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19089 [(match_operand 4 "flags_reg_operand" "")
19091 (match_operand:DF 2 "nonimmediate_operand" "")
19092 (match_operand:DF 3 "nonimmediate_operand" "")))]
19093 "!TARGET_64BIT && reload_completed"
19094 [(set (match_dup 2)
19095 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19099 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19102 "split_di (operands+2, 1, operands+5, operands+6);
19103 split_di (operands+3, 1, operands+7, operands+8);
19104 split_di (operands, 1, operands+2, operands+3);")
19106 (define_expand "movxfcc"
19107 [(set (match_operand:XF 0 "register_operand" "")
19108 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19109 (match_operand:XF 2 "register_operand" "")
19110 (match_operand:XF 3 "register_operand" "")))]
19111 "TARGET_80387 && TARGET_CMOVE"
19112 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19114 (define_insn "*movxfcc_1"
19115 [(set (match_operand:XF 0 "register_operand" "=f,f")
19116 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19117 [(reg FLAGS_REG) (const_int 0)])
19118 (match_operand:XF 2 "register_operand" "f,0")
19119 (match_operand:XF 3 "register_operand" "0,f")))]
19120 "TARGET_80387 && TARGET_CMOVE"
19122 fcmov%F1\t{%2, %0|%0, %2}
19123 fcmov%f1\t{%3, %0|%0, %3}"
19124 [(set_attr "type" "fcmov")
19125 (set_attr "mode" "XF")])
19127 ;; These versions of the min/max patterns are intentionally ignorant of
19128 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19129 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19130 ;; are undefined in this condition, we're certain this is correct.
19132 (define_insn "sminsf3"
19133 [(set (match_operand:SF 0 "register_operand" "=x")
19134 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19135 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19137 "minss\t{%2, %0|%0, %2}"
19138 [(set_attr "type" "sseadd")
19139 (set_attr "mode" "SF")])
19141 (define_insn "smaxsf3"
19142 [(set (match_operand:SF 0 "register_operand" "=x")
19143 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19144 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19146 "maxss\t{%2, %0|%0, %2}"
19147 [(set_attr "type" "sseadd")
19148 (set_attr "mode" "SF")])
19150 (define_insn "smindf3"
19151 [(set (match_operand:DF 0 "register_operand" "=x")
19152 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19153 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19154 "TARGET_SSE2 && TARGET_SSE_MATH"
19155 "minsd\t{%2, %0|%0, %2}"
19156 [(set_attr "type" "sseadd")
19157 (set_attr "mode" "DF")])
19159 (define_insn "smaxdf3"
19160 [(set (match_operand:DF 0 "register_operand" "=x")
19161 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19162 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19163 "TARGET_SSE2 && TARGET_SSE_MATH"
19164 "maxsd\t{%2, %0|%0, %2}"
19165 [(set_attr "type" "sseadd")
19166 (set_attr "mode" "DF")])
19168 ;; These versions of the min/max patterns implement exactly the operations
19169 ;; min = (op1 < op2 ? op1 : op2)
19170 ;; max = (!(op1 < op2) ? op1 : op2)
19171 ;; Their operands are not commutative, and thus they may be used in the
19172 ;; presence of -0.0 and NaN.
19174 (define_insn "*ieee_sminsf3"
19175 [(set (match_operand:SF 0 "register_operand" "=x")
19176 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19177 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19180 "minss\t{%2, %0|%0, %2}"
19181 [(set_attr "type" "sseadd")
19182 (set_attr "mode" "SF")])
19184 (define_insn "*ieee_smaxsf3"
19185 [(set (match_operand:SF 0 "register_operand" "=x")
19186 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19187 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19190 "maxss\t{%2, %0|%0, %2}"
19191 [(set_attr "type" "sseadd")
19192 (set_attr "mode" "SF")])
19194 (define_insn "*ieee_smindf3"
19195 [(set (match_operand:DF 0 "register_operand" "=x")
19196 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19197 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19199 "TARGET_SSE2 && TARGET_SSE_MATH"
19200 "minsd\t{%2, %0|%0, %2}"
19201 [(set_attr "type" "sseadd")
19202 (set_attr "mode" "DF")])
19204 (define_insn "*ieee_smaxdf3"
19205 [(set (match_operand:DF 0 "register_operand" "=x")
19206 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19207 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19209 "TARGET_SSE2 && TARGET_SSE_MATH"
19210 "maxsd\t{%2, %0|%0, %2}"
19211 [(set_attr "type" "sseadd")
19212 (set_attr "mode" "DF")])
19214 ;; Make two stack loads independent:
19216 ;; fld %st(0) -> fld bb
19217 ;; fmul bb fmul %st(1), %st
19219 ;; Actually we only match the last two instructions for simplicity.
19221 [(set (match_operand 0 "fp_register_operand" "")
19222 (match_operand 1 "fp_register_operand" ""))
19224 (match_operator 2 "binary_fp_operator"
19226 (match_operand 3 "memory_operand" "")]))]
19227 "REGNO (operands[0]) != REGNO (operands[1])"
19228 [(set (match_dup 0) (match_dup 3))
19229 (set (match_dup 0) (match_dup 4))]
19231 ;; The % modifier is not operational anymore in peephole2's, so we have to
19232 ;; swap the operands manually in the case of addition and multiplication.
19233 "if (COMMUTATIVE_ARITH_P (operands[2]))
19234 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19235 operands[0], operands[1]);
19237 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19238 operands[1], operands[0]);")
19240 ;; Conditional addition patterns
19241 (define_expand "addqicc"
19242 [(match_operand:QI 0 "register_operand" "")
19243 (match_operand 1 "comparison_operator" "")
19244 (match_operand:QI 2 "register_operand" "")
19245 (match_operand:QI 3 "const_int_operand" "")]
19247 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19249 (define_expand "addhicc"
19250 [(match_operand:HI 0 "register_operand" "")
19251 (match_operand 1 "comparison_operator" "")
19252 (match_operand:HI 2 "register_operand" "")
19253 (match_operand:HI 3 "const_int_operand" "")]
19255 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19257 (define_expand "addsicc"
19258 [(match_operand:SI 0 "register_operand" "")
19259 (match_operand 1 "comparison_operator" "")
19260 (match_operand:SI 2 "register_operand" "")
19261 (match_operand:SI 3 "const_int_operand" "")]
19263 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19265 (define_expand "adddicc"
19266 [(match_operand:DI 0 "register_operand" "")
19267 (match_operand 1 "comparison_operator" "")
19268 (match_operand:DI 2 "register_operand" "")
19269 (match_operand:DI 3 "const_int_operand" "")]
19271 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19274 ;; Misc patterns (?)
19276 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19277 ;; Otherwise there will be nothing to keep
19279 ;; [(set (reg ebp) (reg esp))]
19280 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19281 ;; (clobber (eflags)]
19282 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19284 ;; in proper program order.
19285 (define_insn "pro_epilogue_adjust_stack_1"
19286 [(set (match_operand:SI 0 "register_operand" "=r,r")
19287 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19288 (match_operand:SI 2 "immediate_operand" "i,i")))
19289 (clobber (reg:CC FLAGS_REG))
19290 (clobber (mem:BLK (scratch)))]
19293 switch (get_attr_type (insn))
19296 return "mov{l}\t{%1, %0|%0, %1}";
19299 if (GET_CODE (operands[2]) == CONST_INT
19300 && (INTVAL (operands[2]) == 128
19301 || (INTVAL (operands[2]) < 0
19302 && INTVAL (operands[2]) != -128)))
19304 operands[2] = GEN_INT (-INTVAL (operands[2]));
19305 return "sub{l}\t{%2, %0|%0, %2}";
19307 return "add{l}\t{%2, %0|%0, %2}";
19310 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19311 return "lea{l}\t{%a2, %0|%0, %a2}";
19314 gcc_unreachable ();
19317 [(set (attr "type")
19318 (cond [(eq_attr "alternative" "0")
19319 (const_string "alu")
19320 (match_operand:SI 2 "const0_operand" "")
19321 (const_string "imov")
19323 (const_string "lea")))
19324 (set_attr "mode" "SI")])
19326 (define_insn "pro_epilogue_adjust_stack_rex64"
19327 [(set (match_operand:DI 0 "register_operand" "=r,r")
19328 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19329 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19330 (clobber (reg:CC FLAGS_REG))
19331 (clobber (mem:BLK (scratch)))]
19334 switch (get_attr_type (insn))
19337 return "mov{q}\t{%1, %0|%0, %1}";
19340 if (GET_CODE (operands[2]) == CONST_INT
19341 /* Avoid overflows. */
19342 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19343 && (INTVAL (operands[2]) == 128
19344 || (INTVAL (operands[2]) < 0
19345 && INTVAL (operands[2]) != -128)))
19347 operands[2] = GEN_INT (-INTVAL (operands[2]));
19348 return "sub{q}\t{%2, %0|%0, %2}";
19350 return "add{q}\t{%2, %0|%0, %2}";
19353 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19354 return "lea{q}\t{%a2, %0|%0, %a2}";
19357 gcc_unreachable ();
19360 [(set (attr "type")
19361 (cond [(eq_attr "alternative" "0")
19362 (const_string "alu")
19363 (match_operand:DI 2 "const0_operand" "")
19364 (const_string "imov")
19366 (const_string "lea")))
19367 (set_attr "mode" "DI")])
19369 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19370 [(set (match_operand:DI 0 "register_operand" "=r,r")
19371 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19372 (match_operand:DI 3 "immediate_operand" "i,i")))
19373 (use (match_operand:DI 2 "register_operand" "r,r"))
19374 (clobber (reg:CC FLAGS_REG))
19375 (clobber (mem:BLK (scratch)))]
19378 switch (get_attr_type (insn))
19381 return "add{q}\t{%2, %0|%0, %2}";
19384 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19385 return "lea{q}\t{%a2, %0|%0, %a2}";
19388 gcc_unreachable ();
19391 [(set_attr "type" "alu,lea")
19392 (set_attr "mode" "DI")])
19394 (define_expand "allocate_stack_worker"
19395 [(match_operand:SI 0 "register_operand" "")]
19396 "TARGET_STACK_PROBE"
19398 if (reload_completed)
19401 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19403 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19408 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19410 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19415 (define_insn "allocate_stack_worker_1"
19416 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19417 UNSPECV_STACK_PROBE)
19418 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19419 (clobber (match_scratch:SI 1 "=0"))
19420 (clobber (reg:CC FLAGS_REG))]
19421 "!TARGET_64BIT && TARGET_STACK_PROBE"
19423 [(set_attr "type" "multi")
19424 (set_attr "length" "5")])
19426 (define_expand "allocate_stack_worker_postreload"
19427 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19428 UNSPECV_STACK_PROBE)
19429 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19430 (clobber (match_dup 0))
19431 (clobber (reg:CC FLAGS_REG))])]
19435 (define_insn "allocate_stack_worker_rex64"
19436 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19437 UNSPECV_STACK_PROBE)
19438 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19439 (clobber (match_scratch:DI 1 "=0"))
19440 (clobber (reg:CC FLAGS_REG))]
19441 "TARGET_64BIT && TARGET_STACK_PROBE"
19443 [(set_attr "type" "multi")
19444 (set_attr "length" "5")])
19446 (define_expand "allocate_stack_worker_rex64_postreload"
19447 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19448 UNSPECV_STACK_PROBE)
19449 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19450 (clobber (match_dup 0))
19451 (clobber (reg:CC FLAGS_REG))])]
19455 (define_expand "allocate_stack"
19456 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19457 (minus:SI (reg:SI SP_REG)
19458 (match_operand:SI 1 "general_operand" "")))
19459 (clobber (reg:CC FLAGS_REG))])
19460 (parallel [(set (reg:SI SP_REG)
19461 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19462 (clobber (reg:CC FLAGS_REG))])]
19463 "TARGET_STACK_PROBE"
19465 #ifdef CHECK_STACK_LIMIT
19466 if (GET_CODE (operands[1]) == CONST_INT
19467 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19468 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19472 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19475 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19479 (define_expand "builtin_setjmp_receiver"
19480 [(label_ref (match_operand 0 "" ""))]
19481 "!TARGET_64BIT && flag_pic"
19486 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19487 rtx label_rtx = gen_label_rtx ();
19488 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19489 xops[0] = xops[1] = picreg;
19490 xops[2] = gen_rtx_CONST (SImode,
19491 gen_rtx_MINUS (SImode,
19492 gen_rtx_LABEL_REF (SImode, label_rtx),
19493 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19494 ix86_expand_binary_operator (MINUS, SImode, xops);
19497 emit_insn (gen_set_got (pic_offset_table_rtx));
19501 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19504 [(set (match_operand 0 "register_operand" "")
19505 (match_operator 3 "promotable_binary_operator"
19506 [(match_operand 1 "register_operand" "")
19507 (match_operand 2 "aligned_operand" "")]))
19508 (clobber (reg:CC FLAGS_REG))]
19509 "! TARGET_PARTIAL_REG_STALL && reload_completed
19510 && ((GET_MODE (operands[0]) == HImode
19511 && ((!optimize_size && !TARGET_FAST_PREFIX)
19512 /* ??? next two lines just !satisfies_constraint_K (...) */
19513 || GET_CODE (operands[2]) != CONST_INT
19514 || satisfies_constraint_K (operands[2])))
19515 || (GET_MODE (operands[0]) == QImode
19516 && (TARGET_PROMOTE_QImode || optimize_size)))"
19517 [(parallel [(set (match_dup 0)
19518 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19519 (clobber (reg:CC FLAGS_REG))])]
19520 "operands[0] = gen_lowpart (SImode, operands[0]);
19521 operands[1] = gen_lowpart (SImode, operands[1]);
19522 if (GET_CODE (operands[3]) != ASHIFT)
19523 operands[2] = gen_lowpart (SImode, operands[2]);
19524 PUT_MODE (operands[3], SImode);")
19526 ; Promote the QImode tests, as i386 has encoding of the AND
19527 ; instruction with 32-bit sign-extended immediate and thus the
19528 ; instruction size is unchanged, except in the %eax case for
19529 ; which it is increased by one byte, hence the ! optimize_size.
19531 [(set (match_operand 0 "flags_reg_operand" "")
19532 (match_operator 2 "compare_operator"
19533 [(and (match_operand 3 "aligned_operand" "")
19534 (match_operand 4 "const_int_operand" ""))
19536 (set (match_operand 1 "register_operand" "")
19537 (and (match_dup 3) (match_dup 4)))]
19538 "! TARGET_PARTIAL_REG_STALL && reload_completed
19539 /* Ensure that the operand will remain sign-extended immediate. */
19540 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19542 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19543 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19544 [(parallel [(set (match_dup 0)
19545 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19548 (and:SI (match_dup 3) (match_dup 4)))])]
19551 = gen_int_mode (INTVAL (operands[4])
19552 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19553 operands[1] = gen_lowpart (SImode, operands[1]);
19554 operands[3] = gen_lowpart (SImode, operands[3]);
19557 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19558 ; the TEST instruction with 32-bit sign-extended immediate and thus
19559 ; the instruction size would at least double, which is not what we
19560 ; want even with ! optimize_size.
19562 [(set (match_operand 0 "flags_reg_operand" "")
19563 (match_operator 1 "compare_operator"
19564 [(and (match_operand:HI 2 "aligned_operand" "")
19565 (match_operand:HI 3 "const_int_operand" ""))
19567 "! TARGET_PARTIAL_REG_STALL && reload_completed
19568 /* Ensure that the operand will remain sign-extended immediate. */
19569 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19570 && ! TARGET_FAST_PREFIX
19571 && ! optimize_size"
19572 [(set (match_dup 0)
19573 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19577 = gen_int_mode (INTVAL (operands[3])
19578 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19579 operands[2] = gen_lowpart (SImode, operands[2]);
19583 [(set (match_operand 0 "register_operand" "")
19584 (neg (match_operand 1 "register_operand" "")))
19585 (clobber (reg:CC FLAGS_REG))]
19586 "! TARGET_PARTIAL_REG_STALL && reload_completed
19587 && (GET_MODE (operands[0]) == HImode
19588 || (GET_MODE (operands[0]) == QImode
19589 && (TARGET_PROMOTE_QImode || optimize_size)))"
19590 [(parallel [(set (match_dup 0)
19591 (neg:SI (match_dup 1)))
19592 (clobber (reg:CC FLAGS_REG))])]
19593 "operands[0] = gen_lowpart (SImode, operands[0]);
19594 operands[1] = gen_lowpart (SImode, operands[1]);")
19597 [(set (match_operand 0 "register_operand" "")
19598 (not (match_operand 1 "register_operand" "")))]
19599 "! TARGET_PARTIAL_REG_STALL && reload_completed
19600 && (GET_MODE (operands[0]) == HImode
19601 || (GET_MODE (operands[0]) == QImode
19602 && (TARGET_PROMOTE_QImode || optimize_size)))"
19603 [(set (match_dup 0)
19604 (not:SI (match_dup 1)))]
19605 "operands[0] = gen_lowpart (SImode, operands[0]);
19606 operands[1] = gen_lowpart (SImode, operands[1]);")
19609 [(set (match_operand 0 "register_operand" "")
19610 (if_then_else (match_operator 1 "comparison_operator"
19611 [(reg FLAGS_REG) (const_int 0)])
19612 (match_operand 2 "register_operand" "")
19613 (match_operand 3 "register_operand" "")))]
19614 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19615 && (GET_MODE (operands[0]) == HImode
19616 || (GET_MODE (operands[0]) == QImode
19617 && (TARGET_PROMOTE_QImode || optimize_size)))"
19618 [(set (match_dup 0)
19619 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19620 "operands[0] = gen_lowpart (SImode, operands[0]);
19621 operands[2] = gen_lowpart (SImode, operands[2]);
19622 operands[3] = gen_lowpart (SImode, operands[3]);")
19625 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19626 ;; transform a complex memory operation into two memory to register operations.
19628 ;; Don't push memory operands
19630 [(set (match_operand:SI 0 "push_operand" "")
19631 (match_operand:SI 1 "memory_operand" ""))
19632 (match_scratch:SI 2 "r")]
19633 "!optimize_size && !TARGET_PUSH_MEMORY
19634 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19635 [(set (match_dup 2) (match_dup 1))
19636 (set (match_dup 0) (match_dup 2))]
19640 [(set (match_operand:DI 0 "push_operand" "")
19641 (match_operand:DI 1 "memory_operand" ""))
19642 (match_scratch:DI 2 "r")]
19643 "!optimize_size && !TARGET_PUSH_MEMORY
19644 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19645 [(set (match_dup 2) (match_dup 1))
19646 (set (match_dup 0) (match_dup 2))]
19649 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19652 [(set (match_operand:SF 0 "push_operand" "")
19653 (match_operand:SF 1 "memory_operand" ""))
19654 (match_scratch:SF 2 "r")]
19655 "!optimize_size && !TARGET_PUSH_MEMORY
19656 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19657 [(set (match_dup 2) (match_dup 1))
19658 (set (match_dup 0) (match_dup 2))]
19662 [(set (match_operand:HI 0 "push_operand" "")
19663 (match_operand:HI 1 "memory_operand" ""))
19664 (match_scratch:HI 2 "r")]
19665 "!optimize_size && !TARGET_PUSH_MEMORY
19666 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19667 [(set (match_dup 2) (match_dup 1))
19668 (set (match_dup 0) (match_dup 2))]
19672 [(set (match_operand:QI 0 "push_operand" "")
19673 (match_operand:QI 1 "memory_operand" ""))
19674 (match_scratch:QI 2 "q")]
19675 "!optimize_size && !TARGET_PUSH_MEMORY
19676 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19677 [(set (match_dup 2) (match_dup 1))
19678 (set (match_dup 0) (match_dup 2))]
19681 ;; Don't move an immediate directly to memory when the instruction
19684 [(match_scratch:SI 1 "r")
19685 (set (match_operand:SI 0 "memory_operand" "")
19688 && ! TARGET_USE_MOV0
19689 && TARGET_SPLIT_LONG_MOVES
19690 && get_attr_length (insn) >= ix86_cost->large_insn
19691 && peep2_regno_dead_p (0, FLAGS_REG)"
19692 [(parallel [(set (match_dup 1) (const_int 0))
19693 (clobber (reg:CC FLAGS_REG))])
19694 (set (match_dup 0) (match_dup 1))]
19698 [(match_scratch:HI 1 "r")
19699 (set (match_operand:HI 0 "memory_operand" "")
19702 && ! TARGET_USE_MOV0
19703 && TARGET_SPLIT_LONG_MOVES
19704 && get_attr_length (insn) >= ix86_cost->large_insn
19705 && peep2_regno_dead_p (0, FLAGS_REG)"
19706 [(parallel [(set (match_dup 2) (const_int 0))
19707 (clobber (reg:CC FLAGS_REG))])
19708 (set (match_dup 0) (match_dup 1))]
19709 "operands[2] = gen_lowpart (SImode, operands[1]);")
19712 [(match_scratch:QI 1 "q")
19713 (set (match_operand:QI 0 "memory_operand" "")
19716 && ! TARGET_USE_MOV0
19717 && TARGET_SPLIT_LONG_MOVES
19718 && get_attr_length (insn) >= ix86_cost->large_insn
19719 && peep2_regno_dead_p (0, FLAGS_REG)"
19720 [(parallel [(set (match_dup 2) (const_int 0))
19721 (clobber (reg:CC FLAGS_REG))])
19722 (set (match_dup 0) (match_dup 1))]
19723 "operands[2] = gen_lowpart (SImode, operands[1]);")
19726 [(match_scratch:SI 2 "r")
19727 (set (match_operand:SI 0 "memory_operand" "")
19728 (match_operand:SI 1 "immediate_operand" ""))]
19730 && get_attr_length (insn) >= ix86_cost->large_insn
19731 && TARGET_SPLIT_LONG_MOVES"
19732 [(set (match_dup 2) (match_dup 1))
19733 (set (match_dup 0) (match_dup 2))]
19737 [(match_scratch:HI 2 "r")
19738 (set (match_operand:HI 0 "memory_operand" "")
19739 (match_operand:HI 1 "immediate_operand" ""))]
19740 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19741 && TARGET_SPLIT_LONG_MOVES"
19742 [(set (match_dup 2) (match_dup 1))
19743 (set (match_dup 0) (match_dup 2))]
19747 [(match_scratch:QI 2 "q")
19748 (set (match_operand:QI 0 "memory_operand" "")
19749 (match_operand:QI 1 "immediate_operand" ""))]
19750 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19751 && TARGET_SPLIT_LONG_MOVES"
19752 [(set (match_dup 2) (match_dup 1))
19753 (set (match_dup 0) (match_dup 2))]
19756 ;; Don't compare memory with zero, load and use a test instead.
19758 [(set (match_operand 0 "flags_reg_operand" "")
19759 (match_operator 1 "compare_operator"
19760 [(match_operand:SI 2 "memory_operand" "")
19762 (match_scratch:SI 3 "r")]
19763 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19764 [(set (match_dup 3) (match_dup 2))
19765 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19768 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19769 ;; Don't split NOTs with a displacement operand, because resulting XOR
19770 ;; will not be pairable anyway.
19772 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19773 ;; represented using a modRM byte. The XOR replacement is long decoded,
19774 ;; so this split helps here as well.
19776 ;; Note: Can't do this as a regular split because we can't get proper
19777 ;; lifetime information then.
19780 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19781 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19783 && peep2_regno_dead_p (0, FLAGS_REG)
19784 && ((TARGET_PENTIUM
19785 && (GET_CODE (operands[0]) != MEM
19786 || !memory_displacement_operand (operands[0], SImode)))
19787 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19788 [(parallel [(set (match_dup 0)
19789 (xor:SI (match_dup 1) (const_int -1)))
19790 (clobber (reg:CC FLAGS_REG))])]
19794 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19795 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19797 && peep2_regno_dead_p (0, FLAGS_REG)
19798 && ((TARGET_PENTIUM
19799 && (GET_CODE (operands[0]) != MEM
19800 || !memory_displacement_operand (operands[0], HImode)))
19801 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19802 [(parallel [(set (match_dup 0)
19803 (xor:HI (match_dup 1) (const_int -1)))
19804 (clobber (reg:CC FLAGS_REG))])]
19808 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19809 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19811 && peep2_regno_dead_p (0, FLAGS_REG)
19812 && ((TARGET_PENTIUM
19813 && (GET_CODE (operands[0]) != MEM
19814 || !memory_displacement_operand (operands[0], QImode)))
19815 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19816 [(parallel [(set (match_dup 0)
19817 (xor:QI (match_dup 1) (const_int -1)))
19818 (clobber (reg:CC FLAGS_REG))])]
19821 ;; Non pairable "test imm, reg" instructions can be translated to
19822 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19823 ;; byte opcode instead of two, have a short form for byte operands),
19824 ;; so do it for other CPUs as well. Given that the value was dead,
19825 ;; this should not create any new dependencies. Pass on the sub-word
19826 ;; versions if we're concerned about partial register stalls.
19829 [(set (match_operand 0 "flags_reg_operand" "")
19830 (match_operator 1 "compare_operator"
19831 [(and:SI (match_operand:SI 2 "register_operand" "")
19832 (match_operand:SI 3 "immediate_operand" ""))
19834 "ix86_match_ccmode (insn, CCNOmode)
19835 && (true_regnum (operands[2]) != 0
19836 || satisfies_constraint_K (operands[3]))
19837 && peep2_reg_dead_p (1, operands[2])"
19839 [(set (match_dup 0)
19840 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19843 (and:SI (match_dup 2) (match_dup 3)))])]
19846 ;; We don't need to handle HImode case, because it will be promoted to SImode
19847 ;; on ! TARGET_PARTIAL_REG_STALL
19850 [(set (match_operand 0 "flags_reg_operand" "")
19851 (match_operator 1 "compare_operator"
19852 [(and:QI (match_operand:QI 2 "register_operand" "")
19853 (match_operand:QI 3 "immediate_operand" ""))
19855 "! TARGET_PARTIAL_REG_STALL
19856 && ix86_match_ccmode (insn, CCNOmode)
19857 && true_regnum (operands[2]) != 0
19858 && peep2_reg_dead_p (1, operands[2])"
19860 [(set (match_dup 0)
19861 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19864 (and:QI (match_dup 2) (match_dup 3)))])]
19868 [(set (match_operand 0 "flags_reg_operand" "")
19869 (match_operator 1 "compare_operator"
19872 (match_operand 2 "ext_register_operand" "")
19875 (match_operand 3 "const_int_operand" ""))
19877 "! TARGET_PARTIAL_REG_STALL
19878 && ix86_match_ccmode (insn, CCNOmode)
19879 && true_regnum (operands[2]) != 0
19880 && peep2_reg_dead_p (1, operands[2])"
19881 [(parallel [(set (match_dup 0)
19890 (set (zero_extract:SI (match_dup 2)
19901 ;; Don't do logical operations with memory inputs.
19903 [(match_scratch:SI 2 "r")
19904 (parallel [(set (match_operand:SI 0 "register_operand" "")
19905 (match_operator:SI 3 "arith_or_logical_operator"
19907 (match_operand:SI 1 "memory_operand" "")]))
19908 (clobber (reg:CC FLAGS_REG))])]
19909 "! optimize_size && ! TARGET_READ_MODIFY"
19910 [(set (match_dup 2) (match_dup 1))
19911 (parallel [(set (match_dup 0)
19912 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19913 (clobber (reg:CC FLAGS_REG))])]
19917 [(match_scratch:SI 2 "r")
19918 (parallel [(set (match_operand:SI 0 "register_operand" "")
19919 (match_operator:SI 3 "arith_or_logical_operator"
19920 [(match_operand:SI 1 "memory_operand" "")
19922 (clobber (reg:CC FLAGS_REG))])]
19923 "! optimize_size && ! TARGET_READ_MODIFY"
19924 [(set (match_dup 2) (match_dup 1))
19925 (parallel [(set (match_dup 0)
19926 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19927 (clobber (reg:CC FLAGS_REG))])]
19930 ; Don't do logical operations with memory outputs
19932 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19933 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19934 ; the same decoder scheduling characteristics as the original.
19937 [(match_scratch:SI 2 "r")
19938 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19939 (match_operator:SI 3 "arith_or_logical_operator"
19941 (match_operand:SI 1 "nonmemory_operand" "")]))
19942 (clobber (reg:CC FLAGS_REG))])]
19943 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19944 [(set (match_dup 2) (match_dup 0))
19945 (parallel [(set (match_dup 2)
19946 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19947 (clobber (reg:CC FLAGS_REG))])
19948 (set (match_dup 0) (match_dup 2))]
19952 [(match_scratch:SI 2 "r")
19953 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19954 (match_operator:SI 3 "arith_or_logical_operator"
19955 [(match_operand:SI 1 "nonmemory_operand" "")
19957 (clobber (reg:CC FLAGS_REG))])]
19958 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19959 [(set (match_dup 2) (match_dup 0))
19960 (parallel [(set (match_dup 2)
19961 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19962 (clobber (reg:CC FLAGS_REG))])
19963 (set (match_dup 0) (match_dup 2))]
19966 ;; Attempt to always use XOR for zeroing registers.
19968 [(set (match_operand 0 "register_operand" "")
19969 (match_operand 1 "const0_operand" ""))]
19970 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19971 && (! TARGET_USE_MOV0 || optimize_size)
19972 && GENERAL_REG_P (operands[0])
19973 && peep2_regno_dead_p (0, FLAGS_REG)"
19974 [(parallel [(set (match_dup 0) (const_int 0))
19975 (clobber (reg:CC FLAGS_REG))])]
19977 operands[0] = gen_lowpart (word_mode, operands[0]);
19981 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19983 "(GET_MODE (operands[0]) == QImode
19984 || GET_MODE (operands[0]) == HImode)
19985 && (! TARGET_USE_MOV0 || optimize_size)
19986 && peep2_regno_dead_p (0, FLAGS_REG)"
19987 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19988 (clobber (reg:CC FLAGS_REG))])])
19990 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19992 [(set (match_operand 0 "register_operand" "")
19994 "(GET_MODE (operands[0]) == HImode
19995 || GET_MODE (operands[0]) == SImode
19996 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19997 && (optimize_size || TARGET_PENTIUM)
19998 && peep2_regno_dead_p (0, FLAGS_REG)"
19999 [(parallel [(set (match_dup 0) (const_int -1))
20000 (clobber (reg:CC FLAGS_REG))])]
20001 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20004 ;; Attempt to convert simple leas to adds. These can be created by
20007 [(set (match_operand:SI 0 "register_operand" "")
20008 (plus:SI (match_dup 0)
20009 (match_operand:SI 1 "nonmemory_operand" "")))]
20010 "peep2_regno_dead_p (0, FLAGS_REG)"
20011 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20012 (clobber (reg:CC FLAGS_REG))])]
20016 [(set (match_operand:SI 0 "register_operand" "")
20017 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20018 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20019 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20020 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20021 (clobber (reg:CC FLAGS_REG))])]
20022 "operands[2] = gen_lowpart (SImode, operands[2]);")
20025 [(set (match_operand:DI 0 "register_operand" "")
20026 (plus:DI (match_dup 0)
20027 (match_operand:DI 1 "x86_64_general_operand" "")))]
20028 "peep2_regno_dead_p (0, FLAGS_REG)"
20029 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20030 (clobber (reg:CC FLAGS_REG))])]
20034 [(set (match_operand:SI 0 "register_operand" "")
20035 (mult:SI (match_dup 0)
20036 (match_operand:SI 1 "const_int_operand" "")))]
20037 "exact_log2 (INTVAL (operands[1])) >= 0
20038 && peep2_regno_dead_p (0, FLAGS_REG)"
20039 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20040 (clobber (reg:CC FLAGS_REG))])]
20041 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20044 [(set (match_operand:DI 0 "register_operand" "")
20045 (mult:DI (match_dup 0)
20046 (match_operand:DI 1 "const_int_operand" "")))]
20047 "exact_log2 (INTVAL (operands[1])) >= 0
20048 && peep2_regno_dead_p (0, FLAGS_REG)"
20049 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20050 (clobber (reg:CC FLAGS_REG))])]
20051 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20054 [(set (match_operand:SI 0 "register_operand" "")
20055 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20056 (match_operand:DI 2 "const_int_operand" "")) 0))]
20057 "exact_log2 (INTVAL (operands[2])) >= 0
20058 && REGNO (operands[0]) == REGNO (operands[1])
20059 && peep2_regno_dead_p (0, FLAGS_REG)"
20060 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20061 (clobber (reg:CC FLAGS_REG))])]
20062 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20064 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20065 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20066 ;; many CPUs it is also faster, since special hardware to avoid esp
20067 ;; dependencies is present.
20069 ;; While some of these conversions may be done using splitters, we use peepholes
20070 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20072 ;; Convert prologue esp subtractions to push.
20073 ;; We need register to push. In order to keep verify_flow_info happy we have
20075 ;; - use scratch and clobber it in order to avoid dependencies
20076 ;; - use already live register
20077 ;; We can't use the second way right now, since there is no reliable way how to
20078 ;; verify that given register is live. First choice will also most likely in
20079 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20080 ;; call clobbered registers are dead. We may want to use base pointer as an
20081 ;; alternative when no register is available later.
20084 [(match_scratch:SI 0 "r")
20085 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20086 (clobber (reg:CC FLAGS_REG))
20087 (clobber (mem:BLK (scratch)))])]
20088 "optimize_size || !TARGET_SUB_ESP_4"
20089 [(clobber (match_dup 0))
20090 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20091 (clobber (mem:BLK (scratch)))])])
20094 [(match_scratch:SI 0 "r")
20095 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20096 (clobber (reg:CC FLAGS_REG))
20097 (clobber (mem:BLK (scratch)))])]
20098 "optimize_size || !TARGET_SUB_ESP_8"
20099 [(clobber (match_dup 0))
20100 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20101 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20102 (clobber (mem:BLK (scratch)))])])
20104 ;; Convert esp subtractions to push.
20106 [(match_scratch:SI 0 "r")
20107 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20108 (clobber (reg:CC FLAGS_REG))])]
20109 "optimize_size || !TARGET_SUB_ESP_4"
20110 [(clobber (match_dup 0))
20111 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20114 [(match_scratch:SI 0 "r")
20115 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20116 (clobber (reg:CC FLAGS_REG))])]
20117 "optimize_size || !TARGET_SUB_ESP_8"
20118 [(clobber (match_dup 0))
20119 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20120 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20122 ;; Convert epilogue deallocator to pop.
20124 [(match_scratch:SI 0 "r")
20125 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20126 (clobber (reg:CC FLAGS_REG))
20127 (clobber (mem:BLK (scratch)))])]
20128 "optimize_size || !TARGET_ADD_ESP_4"
20129 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20130 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20131 (clobber (mem:BLK (scratch)))])]
20134 ;; Two pops case is tricky, since pop causes dependency on destination register.
20135 ;; We use two registers if available.
20137 [(match_scratch:SI 0 "r")
20138 (match_scratch:SI 1 "r")
20139 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20140 (clobber (reg:CC FLAGS_REG))
20141 (clobber (mem:BLK (scratch)))])]
20142 "optimize_size || !TARGET_ADD_ESP_8"
20143 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20144 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20145 (clobber (mem:BLK (scratch)))])
20146 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20147 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20151 [(match_scratch:SI 0 "r")
20152 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20153 (clobber (reg:CC FLAGS_REG))
20154 (clobber (mem:BLK (scratch)))])]
20156 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20157 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20158 (clobber (mem:BLK (scratch)))])
20159 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20160 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20163 ;; Convert esp additions to pop.
20165 [(match_scratch:SI 0 "r")
20166 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20167 (clobber (reg:CC FLAGS_REG))])]
20169 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20170 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20173 ;; Two pops case is tricky, since pop causes dependency on destination register.
20174 ;; We use two registers if available.
20176 [(match_scratch:SI 0 "r")
20177 (match_scratch:SI 1 "r")
20178 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20179 (clobber (reg:CC FLAGS_REG))])]
20181 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20182 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20183 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20184 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20188 [(match_scratch:SI 0 "r")
20189 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20190 (clobber (reg:CC FLAGS_REG))])]
20192 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20193 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20194 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20195 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20198 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20199 ;; required and register dies. Similarly for 128 to plus -128.
20201 [(set (match_operand 0 "flags_reg_operand" "")
20202 (match_operator 1 "compare_operator"
20203 [(match_operand 2 "register_operand" "")
20204 (match_operand 3 "const_int_operand" "")]))]
20205 "(INTVAL (operands[3]) == -1
20206 || INTVAL (operands[3]) == 1
20207 || INTVAL (operands[3]) == 128)
20208 && ix86_match_ccmode (insn, CCGCmode)
20209 && peep2_reg_dead_p (1, operands[2])"
20210 [(parallel [(set (match_dup 0)
20211 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20212 (clobber (match_dup 2))])]
20216 [(match_scratch:DI 0 "r")
20217 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20218 (clobber (reg:CC FLAGS_REG))
20219 (clobber (mem:BLK (scratch)))])]
20220 "optimize_size || !TARGET_SUB_ESP_4"
20221 [(clobber (match_dup 0))
20222 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20223 (clobber (mem:BLK (scratch)))])])
20226 [(match_scratch:DI 0 "r")
20227 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20228 (clobber (reg:CC FLAGS_REG))
20229 (clobber (mem:BLK (scratch)))])]
20230 "optimize_size || !TARGET_SUB_ESP_8"
20231 [(clobber (match_dup 0))
20232 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20233 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20234 (clobber (mem:BLK (scratch)))])])
20236 ;; Convert esp subtractions to push.
20238 [(match_scratch:DI 0 "r")
20239 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20240 (clobber (reg:CC FLAGS_REG))])]
20241 "optimize_size || !TARGET_SUB_ESP_4"
20242 [(clobber (match_dup 0))
20243 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20246 [(match_scratch:DI 0 "r")
20247 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20248 (clobber (reg:CC FLAGS_REG))])]
20249 "optimize_size || !TARGET_SUB_ESP_8"
20250 [(clobber (match_dup 0))
20251 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20252 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20254 ;; Convert epilogue deallocator to pop.
20256 [(match_scratch:DI 0 "r")
20257 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20258 (clobber (reg:CC FLAGS_REG))
20259 (clobber (mem:BLK (scratch)))])]
20260 "optimize_size || !TARGET_ADD_ESP_4"
20261 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20262 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20263 (clobber (mem:BLK (scratch)))])]
20266 ;; Two pops case is tricky, since pop causes dependency on destination register.
20267 ;; We use two registers if available.
20269 [(match_scratch:DI 0 "r")
20270 (match_scratch:DI 1 "r")
20271 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20272 (clobber (reg:CC FLAGS_REG))
20273 (clobber (mem:BLK (scratch)))])]
20274 "optimize_size || !TARGET_ADD_ESP_8"
20275 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20276 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20277 (clobber (mem:BLK (scratch)))])
20278 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20279 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20283 [(match_scratch:DI 0 "r")
20284 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20285 (clobber (reg:CC FLAGS_REG))
20286 (clobber (mem:BLK (scratch)))])]
20288 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20289 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20290 (clobber (mem:BLK (scratch)))])
20291 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20292 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20295 ;; Convert esp additions to pop.
20297 [(match_scratch:DI 0 "r")
20298 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20299 (clobber (reg:CC FLAGS_REG))])]
20301 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20302 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20305 ;; Two pops case is tricky, since pop causes dependency on destination register.
20306 ;; We use two registers if available.
20308 [(match_scratch:DI 0 "r")
20309 (match_scratch:DI 1 "r")
20310 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20311 (clobber (reg:CC FLAGS_REG))])]
20313 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20314 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20315 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20316 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20320 [(match_scratch:DI 0 "r")
20321 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20322 (clobber (reg:CC FLAGS_REG))])]
20324 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20325 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20326 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20327 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20330 ;; Convert imul by three, five and nine into lea
20333 [(set (match_operand:SI 0 "register_operand" "")
20334 (mult:SI (match_operand:SI 1 "register_operand" "")
20335 (match_operand:SI 2 "const_int_operand" "")))
20336 (clobber (reg:CC FLAGS_REG))])]
20337 "INTVAL (operands[2]) == 3
20338 || INTVAL (operands[2]) == 5
20339 || INTVAL (operands[2]) == 9"
20340 [(set (match_dup 0)
20341 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20343 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20347 [(set (match_operand:SI 0 "register_operand" "")
20348 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20349 (match_operand:SI 2 "const_int_operand" "")))
20350 (clobber (reg:CC FLAGS_REG))])]
20352 && (INTVAL (operands[2]) == 3
20353 || INTVAL (operands[2]) == 5
20354 || INTVAL (operands[2]) == 9)"
20355 [(set (match_dup 0) (match_dup 1))
20357 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20359 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20363 [(set (match_operand:DI 0 "register_operand" "")
20364 (mult:DI (match_operand:DI 1 "register_operand" "")
20365 (match_operand:DI 2 "const_int_operand" "")))
20366 (clobber (reg:CC FLAGS_REG))])]
20368 && (INTVAL (operands[2]) == 3
20369 || INTVAL (operands[2]) == 5
20370 || INTVAL (operands[2]) == 9)"
20371 [(set (match_dup 0)
20372 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20374 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20378 [(set (match_operand:DI 0 "register_operand" "")
20379 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20380 (match_operand:DI 2 "const_int_operand" "")))
20381 (clobber (reg:CC FLAGS_REG))])]
20384 && (INTVAL (operands[2]) == 3
20385 || INTVAL (operands[2]) == 5
20386 || INTVAL (operands[2]) == 9)"
20387 [(set (match_dup 0) (match_dup 1))
20389 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20391 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20393 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20394 ;; imul $32bit_imm, reg, reg is direct decoded.
20396 [(match_scratch:DI 3 "r")
20397 (parallel [(set (match_operand:DI 0 "register_operand" "")
20398 (mult:DI (match_operand:DI 1 "memory_operand" "")
20399 (match_operand:DI 2 "immediate_operand" "")))
20400 (clobber (reg:CC FLAGS_REG))])]
20401 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20402 && !satisfies_constraint_K (operands[2])"
20403 [(set (match_dup 3) (match_dup 1))
20404 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20405 (clobber (reg:CC FLAGS_REG))])]
20409 [(match_scratch:SI 3 "r")
20410 (parallel [(set (match_operand:SI 0 "register_operand" "")
20411 (mult:SI (match_operand:SI 1 "memory_operand" "")
20412 (match_operand:SI 2 "immediate_operand" "")))
20413 (clobber (reg:CC FLAGS_REG))])]
20414 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20415 && !satisfies_constraint_K (operands[2])"
20416 [(set (match_dup 3) (match_dup 1))
20417 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20418 (clobber (reg:CC FLAGS_REG))])]
20422 [(match_scratch:SI 3 "r")
20423 (parallel [(set (match_operand:DI 0 "register_operand" "")
20425 (mult:SI (match_operand:SI 1 "memory_operand" "")
20426 (match_operand:SI 2 "immediate_operand" ""))))
20427 (clobber (reg:CC FLAGS_REG))])]
20428 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20429 && !satisfies_constraint_K (operands[2])"
20430 [(set (match_dup 3) (match_dup 1))
20431 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20432 (clobber (reg:CC FLAGS_REG))])]
20435 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20436 ;; Convert it into imul reg, reg
20437 ;; It would be better to force assembler to encode instruction using long
20438 ;; immediate, but there is apparently no way to do so.
20440 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20441 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20442 (match_operand:DI 2 "const_int_operand" "")))
20443 (clobber (reg:CC FLAGS_REG))])
20444 (match_scratch:DI 3 "r")]
20445 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20446 && satisfies_constraint_K (operands[2])"
20447 [(set (match_dup 3) (match_dup 2))
20448 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20449 (clobber (reg:CC FLAGS_REG))])]
20451 if (!rtx_equal_p (operands[0], operands[1]))
20452 emit_move_insn (operands[0], operands[1]);
20456 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20457 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20458 (match_operand:SI 2 "const_int_operand" "")))
20459 (clobber (reg:CC FLAGS_REG))])
20460 (match_scratch:SI 3 "r")]
20461 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20462 && satisfies_constraint_K (operands[2])"
20463 [(set (match_dup 3) (match_dup 2))
20464 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20465 (clobber (reg:CC FLAGS_REG))])]
20467 if (!rtx_equal_p (operands[0], operands[1]))
20468 emit_move_insn (operands[0], operands[1]);
20472 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20473 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20474 (match_operand:HI 2 "immediate_operand" "")))
20475 (clobber (reg:CC FLAGS_REG))])
20476 (match_scratch:HI 3 "r")]
20477 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20478 [(set (match_dup 3) (match_dup 2))
20479 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20480 (clobber (reg:CC FLAGS_REG))])]
20482 if (!rtx_equal_p (operands[0], operands[1]))
20483 emit_move_insn (operands[0], operands[1]);
20486 ;; After splitting up read-modify operations, array accesses with memory
20487 ;; operands might end up in form:
20489 ;; movl 4(%esp), %edx
20491 ;; instead of pre-splitting:
20493 ;; addl 4(%esp), %eax
20495 ;; movl 4(%esp), %edx
20496 ;; leal (%edx,%eax,4), %eax
20499 [(parallel [(set (match_operand 0 "register_operand" "")
20500 (ashift (match_operand 1 "register_operand" "")
20501 (match_operand 2 "const_int_operand" "")))
20502 (clobber (reg:CC FLAGS_REG))])
20503 (set (match_operand 3 "register_operand")
20504 (match_operand 4 "x86_64_general_operand" ""))
20505 (parallel [(set (match_operand 5 "register_operand" "")
20506 (plus (match_operand 6 "register_operand" "")
20507 (match_operand 7 "register_operand" "")))
20508 (clobber (reg:CC FLAGS_REG))])]
20509 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20510 /* Validate MODE for lea. */
20511 && ((!TARGET_PARTIAL_REG_STALL
20512 && (GET_MODE (operands[0]) == QImode
20513 || GET_MODE (operands[0]) == HImode))
20514 || GET_MODE (operands[0]) == SImode
20515 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20516 /* We reorder load and the shift. */
20517 && !rtx_equal_p (operands[1], operands[3])
20518 && !reg_overlap_mentioned_p (operands[0], operands[4])
20519 /* Last PLUS must consist of operand 0 and 3. */
20520 && !rtx_equal_p (operands[0], operands[3])
20521 && (rtx_equal_p (operands[3], operands[6])
20522 || rtx_equal_p (operands[3], operands[7]))
20523 && (rtx_equal_p (operands[0], operands[6])
20524 || rtx_equal_p (operands[0], operands[7]))
20525 /* The intermediate operand 0 must die or be same as output. */
20526 && (rtx_equal_p (operands[0], operands[5])
20527 || peep2_reg_dead_p (3, operands[0]))"
20528 [(set (match_dup 3) (match_dup 4))
20529 (set (match_dup 0) (match_dup 1))]
20531 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20532 int scale = 1 << INTVAL (operands[2]);
20533 rtx index = gen_lowpart (Pmode, operands[1]);
20534 rtx base = gen_lowpart (Pmode, operands[3]);
20535 rtx dest = gen_lowpart (mode, operands[5]);
20537 operands[1] = gen_rtx_PLUS (Pmode, base,
20538 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20540 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20541 operands[0] = dest;
20544 ;; Call-value patterns last so that the wildcard operand does not
20545 ;; disrupt insn-recog's switch tables.
20547 (define_insn "*call_value_pop_0"
20548 [(set (match_operand 0 "" "")
20549 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20550 (match_operand:SI 2 "" "")))
20551 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20552 (match_operand:SI 3 "immediate_operand" "")))]
20555 if (SIBLING_CALL_P (insn))
20558 return "call\t%P1";
20560 [(set_attr "type" "callv")])
20562 (define_insn "*call_value_pop_1"
20563 [(set (match_operand 0 "" "")
20564 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20565 (match_operand:SI 2 "" "")))
20566 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20567 (match_operand:SI 3 "immediate_operand" "i")))]
20570 if (constant_call_address_operand (operands[1], Pmode))
20572 if (SIBLING_CALL_P (insn))
20575 return "call\t%P1";
20577 if (SIBLING_CALL_P (insn))
20580 return "call\t%A1";
20582 [(set_attr "type" "callv")])
20584 (define_insn "*call_value_0"
20585 [(set (match_operand 0 "" "")
20586 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20587 (match_operand:SI 2 "" "")))]
20590 if (SIBLING_CALL_P (insn))
20593 return "call\t%P1";
20595 [(set_attr "type" "callv")])
20597 (define_insn "*call_value_0_rex64"
20598 [(set (match_operand 0 "" "")
20599 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20600 (match_operand:DI 2 "const_int_operand" "")))]
20603 if (SIBLING_CALL_P (insn))
20606 return "call\t%P1";
20608 [(set_attr "type" "callv")])
20610 (define_insn "*call_value_1"
20611 [(set (match_operand 0 "" "")
20612 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20613 (match_operand:SI 2 "" "")))]
20614 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20616 if (constant_call_address_operand (operands[1], Pmode))
20617 return "call\t%P1";
20618 return "call\t%A1";
20620 [(set_attr "type" "callv")])
20622 (define_insn "*sibcall_value_1"
20623 [(set (match_operand 0 "" "")
20624 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20625 (match_operand:SI 2 "" "")))]
20626 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20628 if (constant_call_address_operand (operands[1], Pmode))
20632 [(set_attr "type" "callv")])
20634 (define_insn "*call_value_1_rex64"
20635 [(set (match_operand 0 "" "")
20636 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20637 (match_operand:DI 2 "" "")))]
20638 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20640 if (constant_call_address_operand (operands[1], Pmode))
20641 return "call\t%P1";
20642 return "call\t%A1";
20644 [(set_attr "type" "callv")])
20646 (define_insn "*sibcall_value_1_rex64"
20647 [(set (match_operand 0 "" "")
20648 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20649 (match_operand:DI 2 "" "")))]
20650 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20652 [(set_attr "type" "callv")])
20654 (define_insn "*sibcall_value_1_rex64_v"
20655 [(set (match_operand 0 "" "")
20656 (call (mem:QI (reg:DI R11_REG))
20657 (match_operand:DI 1 "" "")))]
20658 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20660 [(set_attr "type" "callv")])
20662 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20663 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20664 ;; caught for use by garbage collectors and the like. Using an insn that
20665 ;; maps to SIGILL makes it more likely the program will rightfully die.
20666 ;; Keeping with tradition, "6" is in honor of #UD.
20667 (define_insn "trap"
20668 [(trap_if (const_int 1) (const_int 6))]
20670 { return ASM_SHORT "0x0b0f"; }
20671 [(set_attr "length" "2")])
20673 (define_expand "sse_prologue_save"
20674 [(parallel [(set (match_operand:BLK 0 "" "")
20675 (unspec:BLK [(reg:DI 22)
20682 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20683 (use (match_operand:DI 1 "register_operand" ""))
20684 (use (match_operand:DI 2 "immediate_operand" ""))
20685 (use (label_ref:DI (match_operand 3 "" "")))])]
20689 (define_insn "*sse_prologue_save_insn"
20690 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20691 (match_operand:DI 4 "const_int_operand" "n")))
20692 (unspec:BLK [(reg:DI 22)
20699 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20700 (use (match_operand:DI 1 "register_operand" "r"))
20701 (use (match_operand:DI 2 "const_int_operand" "i"))
20702 (use (label_ref:DI (match_operand 3 "" "X")))]
20704 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20705 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20709 operands[0] = gen_rtx_MEM (Pmode,
20710 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20711 output_asm_insn (\"jmp\\t%A1\", operands);
20712 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20714 operands[4] = adjust_address (operands[0], DImode, i*16);
20715 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20716 PUT_MODE (operands[4], TImode);
20717 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20718 output_asm_insn (\"rex\", operands);
20719 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20721 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20722 CODE_LABEL_NUMBER (operands[3]));
20726 [(set_attr "type" "other")
20727 (set_attr "length_immediate" "0")
20728 (set_attr "length_address" "0")
20729 (set_attr "length" "135")
20730 (set_attr "memory" "store")
20731 (set_attr "modrm" "0")
20732 (set_attr "mode" "DI")])
20734 (define_expand "prefetch"
20735 [(prefetch (match_operand 0 "address_operand" "")
20736 (match_operand:SI 1 "const_int_operand" "")
20737 (match_operand:SI 2 "const_int_operand" ""))]
20738 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20740 int rw = INTVAL (operands[1]);
20741 int locality = INTVAL (operands[2]);
20743 gcc_assert (rw == 0 || rw == 1);
20744 gcc_assert (locality >= 0 && locality <= 3);
20745 gcc_assert (GET_MODE (operands[0]) == Pmode
20746 || GET_MODE (operands[0]) == VOIDmode);
20748 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20749 supported by SSE counterpart or the SSE prefetch is not available
20750 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20752 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20753 operands[2] = GEN_INT (3);
20755 operands[1] = const0_rtx;
20758 (define_insn "*prefetch_sse"
20759 [(prefetch (match_operand:SI 0 "address_operand" "p")
20761 (match_operand:SI 1 "const_int_operand" ""))]
20762 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20764 static const char * const patterns[4] = {
20765 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20768 int locality = INTVAL (operands[1]);
20769 gcc_assert (locality >= 0 && locality <= 3);
20771 return patterns[locality];
20773 [(set_attr "type" "sse")
20774 (set_attr "memory" "none")])
20776 (define_insn "*prefetch_sse_rex"
20777 [(prefetch (match_operand:DI 0 "address_operand" "p")
20779 (match_operand:SI 1 "const_int_operand" ""))]
20780 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20782 static const char * const patterns[4] = {
20783 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20786 int locality = INTVAL (operands[1]);
20787 gcc_assert (locality >= 0 && locality <= 3);
20789 return patterns[locality];
20791 [(set_attr "type" "sse")
20792 (set_attr "memory" "none")])
20794 (define_insn "*prefetch_3dnow"
20795 [(prefetch (match_operand:SI 0 "address_operand" "p")
20796 (match_operand:SI 1 "const_int_operand" "n")
20798 "TARGET_3DNOW && !TARGET_64BIT"
20800 if (INTVAL (operands[1]) == 0)
20801 return "prefetch\t%a0";
20803 return "prefetchw\t%a0";
20805 [(set_attr "type" "mmx")
20806 (set_attr "memory" "none")])
20808 (define_insn "*prefetch_3dnow_rex"
20809 [(prefetch (match_operand:DI 0 "address_operand" "p")
20810 (match_operand:SI 1 "const_int_operand" "n")
20812 "TARGET_3DNOW && TARGET_64BIT"
20814 if (INTVAL (operands[1]) == 0)
20815 return "prefetch\t%a0";
20817 return "prefetchw\t%a0";
20819 [(set_attr "type" "mmx")
20820 (set_attr "memory" "none")])
20822 (define_expand "stack_protect_set"
20823 [(match_operand 0 "memory_operand" "")
20824 (match_operand 1 "memory_operand" "")]
20827 #ifdef TARGET_THREAD_SSP_OFFSET
20829 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20830 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20832 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20833 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20836 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20838 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20843 (define_insn "stack_protect_set_si"
20844 [(set (match_operand:SI 0 "memory_operand" "=m")
20845 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20846 (set (match_scratch:SI 2 "=&r") (const_int 0))
20847 (clobber (reg:CC FLAGS_REG))]
20849 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20850 [(set_attr "type" "multi")])
20852 (define_insn "stack_protect_set_di"
20853 [(set (match_operand:DI 0 "memory_operand" "=m")
20854 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20855 (set (match_scratch:DI 2 "=&r") (const_int 0))
20856 (clobber (reg:CC FLAGS_REG))]
20858 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20859 [(set_attr "type" "multi")])
20861 (define_insn "stack_tls_protect_set_si"
20862 [(set (match_operand:SI 0 "memory_operand" "=m")
20863 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20864 (set (match_scratch:SI 2 "=&r") (const_int 0))
20865 (clobber (reg:CC FLAGS_REG))]
20867 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20868 [(set_attr "type" "multi")])
20870 (define_insn "stack_tls_protect_set_di"
20871 [(set (match_operand:DI 0 "memory_operand" "=m")
20872 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20873 (set (match_scratch:DI 2 "=&r") (const_int 0))
20874 (clobber (reg:CC FLAGS_REG))]
20877 /* The kernel uses a different segment register for performance reasons; a
20878 system call would not have to trash the userspace segment register,
20879 which would be expensive */
20880 if (ix86_cmodel != CM_KERNEL)
20881 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20883 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20885 [(set_attr "type" "multi")])
20887 (define_expand "stack_protect_test"
20888 [(match_operand 0 "memory_operand" "")
20889 (match_operand 1 "memory_operand" "")
20890 (match_operand 2 "" "")]
20893 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20894 ix86_compare_op0 = operands[0];
20895 ix86_compare_op1 = operands[1];
20896 ix86_compare_emitted = flags;
20898 #ifdef TARGET_THREAD_SSP_OFFSET
20900 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20901 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20903 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20904 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20907 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20909 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20911 emit_jump_insn (gen_beq (operands[2]));
20915 (define_insn "stack_protect_test_si"
20916 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20917 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20918 (match_operand:SI 2 "memory_operand" "m")]
20920 (clobber (match_scratch:SI 3 "=&r"))]
20922 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20923 [(set_attr "type" "multi")])
20925 (define_insn "stack_protect_test_di"
20926 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20927 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20928 (match_operand:DI 2 "memory_operand" "m")]
20930 (clobber (match_scratch:DI 3 "=&r"))]
20932 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20933 [(set_attr "type" "multi")])
20935 (define_insn "stack_tls_protect_test_si"
20936 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20937 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20938 (match_operand:SI 2 "const_int_operand" "i")]
20939 UNSPEC_SP_TLS_TEST))
20940 (clobber (match_scratch:SI 3 "=r"))]
20942 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20943 [(set_attr "type" "multi")])
20945 (define_insn "stack_tls_protect_test_di"
20946 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20947 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20948 (match_operand:DI 2 "const_int_operand" "i")]
20949 UNSPEC_SP_TLS_TEST))
20950 (clobber (match_scratch:DI 3 "=r"))]
20953 /* The kernel uses a different segment register for performance reasons; a
20954 system call would not have to trash the userspace segment register,
20955 which would be expensive */
20956 if (ix86_cmodel != CM_KERNEL)
20957 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20959 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20961 [(set_attr "type" "multi")])
20965 (include "sync.md")