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
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)
73 (UNSPEC_TLS_LD_BASE 17)
75 ; Other random patterns
85 ; For SSE/MMX support:
86 (UNSPEC_FIX_NOTRUNC 30)
94 (UNSPEC_NOP 38) ; prevents combiner cleverness
105 ; Generic math support
107 (UNSPEC_IEEE_MIN 51) ; not commutative
108 (UNSPEC_IEEE_MAX 52) ; not commutative
121 (UNSPEC_FRNDINT_FLOOR 70)
122 (UNSPEC_FRNDINT_CEIL 71)
123 (UNSPEC_FRNDINT_TRUNC 72)
124 (UNSPEC_FRNDINT_MASK_PM 73)
125 (UNSPEC_FIST_FLOOR 74)
126 (UNSPEC_FIST_CEIL 75)
128 ; x87 Double output FP
129 (UNSPEC_SINCOS_COS 80)
130 (UNSPEC_SINCOS_SIN 81)
133 (UNSPEC_XTRACT_FRACT 84)
134 (UNSPEC_XTRACT_EXP 85)
135 (UNSPEC_FSCALE_FRACT 86)
136 (UNSPEC_FSCALE_EXP 87)
144 [(UNSPECV_BLOCKAGE 0)
145 (UNSPECV_STACK_PROBE 1)
154 (UNSPECV_CMPXCHG_1 10)
155 (UNSPECV_CMPXCHG_2 11)
160 ;; Registers by name.
169 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; In C guard expressions, put expressions which may be compile-time
173 ;; constants first. This allows for better optimization. For
174 ;; example, write "TARGET_64BIT && reload_completed", not
175 ;; "reload_completed && TARGET_64BIT".
178 ;; Processor type. This attribute must exactly match the processor_type
179 ;; enumeration in i386.h.
180 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
181 (const (symbol_ref "ix86_tune")))
183 ;; A basic instruction type. Refinements due to arguments to be
184 ;; provided in other attributes.
187 alu,alu1,negnot,imov,imovx,lea,
188 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
189 icmp,test,ibr,setcc,icmov,
190 push,pop,call,callv,leave,
192 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
193 sselog,sselog1,sseiadd,sseishft,sseimul,
194 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
195 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
196 (const_string "other"))
198 ;; Main data type used by the insn
200 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
201 (const_string "unknown"))
203 ;; The CPU unit operations uses.
204 (define_attr "unit" "integer,i387,sse,mmx,unknown"
205 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
206 (const_string "i387")
207 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
208 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
210 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
212 (eq_attr "type" "other")
213 (const_string "unknown")]
214 (const_string "integer")))
216 ;; The (bounding maximum) length of an instruction immediate.
217 (define_attr "length_immediate" ""
218 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
220 (eq_attr "unit" "i387,sse,mmx")
222 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
224 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
225 (eq_attr "type" "imov,test")
226 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
227 (eq_attr "type" "call")
228 (if_then_else (match_operand 0 "constant_call_address_operand" "")
231 (eq_attr "type" "callv")
232 (if_then_else (match_operand 1 "constant_call_address_operand" "")
235 ;; We don't know the size before shorten_branches. Expect
236 ;; the instruction to fit for better scheduling.
237 (eq_attr "type" "ibr")
240 (symbol_ref "/* Update immediate_length and other attributes! */
241 gcc_unreachable (),1")))
243 ;; The (bounding maximum) length of an instruction address.
244 (define_attr "length_address" ""
245 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
247 (and (eq_attr "type" "call")
248 (match_operand 0 "constant_call_address_operand" ""))
250 (and (eq_attr "type" "callv")
251 (match_operand 1 "constant_call_address_operand" ""))
254 (symbol_ref "ix86_attr_length_address_default (insn)")))
256 ;; Set when length prefix is used.
257 (define_attr "prefix_data16" ""
258 (if_then_else (ior (eq_attr "mode" "HI")
259 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
263 ;; Set when string REP prefix is used.
264 (define_attr "prefix_rep" ""
265 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
269 ;; Set when 0f opcode prefix is used.
270 (define_attr "prefix_0f" ""
272 (ior (eq_attr "type" "imovx,setcc,icmov")
273 (eq_attr "unit" "sse,mmx"))
277 ;; Set when REX opcode prefix is used.
278 (define_attr "prefix_rex" ""
279 (cond [(and (eq_attr "mode" "DI")
280 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
282 (and (eq_attr "mode" "QI")
283 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
292 ;; Set when modrm byte is used.
293 (define_attr "modrm" ""
294 (cond [(eq_attr "type" "str,cld,leave")
296 (eq_attr "unit" "i387")
298 (and (eq_attr "type" "incdec")
299 (ior (match_operand:SI 1 "register_operand" "")
300 (match_operand:HI 1 "register_operand" "")))
302 (and (eq_attr "type" "push")
303 (not (match_operand 1 "memory_operand" "")))
305 (and (eq_attr "type" "pop")
306 (not (match_operand 0 "memory_operand" "")))
308 (and (eq_attr "type" "imov")
309 (and (match_operand 0 "register_operand" "")
310 (match_operand 1 "immediate_operand" "")))
312 (and (eq_attr "type" "call")
313 (match_operand 0 "constant_call_address_operand" ""))
315 (and (eq_attr "type" "callv")
316 (match_operand 1 "constant_call_address_operand" ""))
321 ;; The (bounding maximum) length of an instruction in bytes.
322 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
323 ;; Later we may want to split them and compute proper length as for
325 (define_attr "length" ""
326 (cond [(eq_attr "type" "other,multi,fistp,frndint")
328 (eq_attr "type" "fcmp")
330 (eq_attr "unit" "i387")
332 (plus (attr "prefix_data16")
333 (attr "length_address")))]
334 (plus (plus (attr "modrm")
335 (plus (attr "prefix_0f")
336 (plus (attr "prefix_rex")
338 (plus (attr "prefix_rep")
339 (plus (attr "prefix_data16")
340 (plus (attr "length_immediate")
341 (attr "length_address")))))))
343 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
344 ;; `store' if there is a simple memory reference therein, or `unknown'
345 ;; if the instruction is complex.
347 (define_attr "memory" "none,load,store,both,unknown"
348 (cond [(eq_attr "type" "other,multi,str")
349 (const_string "unknown")
350 (eq_attr "type" "lea,fcmov,fpspc,cld")
351 (const_string "none")
352 (eq_attr "type" "fistp,leave")
353 (const_string "both")
354 (eq_attr "type" "frndint")
355 (const_string "load")
356 (eq_attr "type" "push")
357 (if_then_else (match_operand 1 "memory_operand" "")
358 (const_string "both")
359 (const_string "store"))
360 (eq_attr "type" "pop")
361 (if_then_else (match_operand 0 "memory_operand" "")
362 (const_string "both")
363 (const_string "load"))
364 (eq_attr "type" "setcc")
365 (if_then_else (match_operand 0 "memory_operand" "")
366 (const_string "store")
367 (const_string "none"))
368 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
369 (if_then_else (ior (match_operand 0 "memory_operand" "")
370 (match_operand 1 "memory_operand" ""))
371 (const_string "load")
372 (const_string "none"))
373 (eq_attr "type" "ibr")
374 (if_then_else (match_operand 0 "memory_operand" "")
375 (const_string "load")
376 (const_string "none"))
377 (eq_attr "type" "call")
378 (if_then_else (match_operand 0 "constant_call_address_operand" "")
379 (const_string "none")
380 (const_string "load"))
381 (eq_attr "type" "callv")
382 (if_then_else (match_operand 1 "constant_call_address_operand" "")
383 (const_string "none")
384 (const_string "load"))
385 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
386 (match_operand 1 "memory_operand" ""))
387 (const_string "both")
388 (and (match_operand 0 "memory_operand" "")
389 (match_operand 1 "memory_operand" ""))
390 (const_string "both")
391 (match_operand 0 "memory_operand" "")
392 (const_string "store")
393 (match_operand 1 "memory_operand" "")
394 (const_string "load")
396 "!alu1,negnot,ishift1,
397 imov,imovx,icmp,test,
399 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
400 mmx,mmxmov,mmxcmp,mmxcvt")
401 (match_operand 2 "memory_operand" ""))
402 (const_string "load")
403 (and (eq_attr "type" "icmov")
404 (match_operand 3 "memory_operand" ""))
405 (const_string "load")
407 (const_string "none")))
409 ;; Indicates if an instruction has both an immediate and a displacement.
411 (define_attr "imm_disp" "false,true,unknown"
412 (cond [(eq_attr "type" "other,multi")
413 (const_string "unknown")
414 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
415 (and (match_operand 0 "memory_displacement_operand" "")
416 (match_operand 1 "immediate_operand" "")))
417 (const_string "true")
418 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
419 (and (match_operand 0 "memory_displacement_operand" "")
420 (match_operand 2 "immediate_operand" "")))
421 (const_string "true")
423 (const_string "false")))
425 ;; Indicates if an FP operation has an integer source.
427 (define_attr "fp_int_src" "false,true"
428 (const_string "false"))
430 ;; Defines rounding mode of an FP operation.
432 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
433 (const_string "any"))
435 ;; Describe a user's asm statement.
436 (define_asm_attributes
437 [(set_attr "length" "128")
438 (set_attr "type" "multi")])
440 ;; All x87 floating point modes
441 (define_mode_macro X87MODEF [SF DF XF])
443 ;; All integer modes handled by x87 fisttp operator.
444 (define_mode_macro X87MODEI [HI SI DI])
446 ;; All integer modes handled by integer x87 operators.
447 (define_mode_macro X87MODEI12 [HI SI])
449 ;; All SSE floating point modes
450 (define_mode_macro SSEMODEF [SF DF])
452 ;; All integer modes handled by SSE cvtts?2si* operators.
453 (define_mode_macro SSEMODEI24 [SI DI])
456 ;; Scheduling descriptions
458 (include "pentium.md")
461 (include "athlon.md")
464 ;; Operand and operator predicates
466 (include "predicates.md")
469 ;; Compare instructions.
471 ;; All compare insns have expanders that save the operands away without
472 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
473 ;; after the cmp) will actually emit the cmpM.
475 (define_expand "cmpdi"
476 [(set (reg:CC FLAGS_REG)
477 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
478 (match_operand:DI 1 "x86_64_general_operand" "")))]
481 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
482 operands[0] = force_reg (DImode, operands[0]);
483 ix86_compare_op0 = operands[0];
484 ix86_compare_op1 = operands[1];
488 (define_expand "cmpsi"
489 [(set (reg:CC FLAGS_REG)
490 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
491 (match_operand:SI 1 "general_operand" "")))]
494 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
495 operands[0] = force_reg (SImode, operands[0]);
496 ix86_compare_op0 = operands[0];
497 ix86_compare_op1 = operands[1];
501 (define_expand "cmphi"
502 [(set (reg:CC FLAGS_REG)
503 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
504 (match_operand:HI 1 "general_operand" "")))]
507 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
508 operands[0] = force_reg (HImode, operands[0]);
509 ix86_compare_op0 = operands[0];
510 ix86_compare_op1 = operands[1];
514 (define_expand "cmpqi"
515 [(set (reg:CC FLAGS_REG)
516 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
517 (match_operand:QI 1 "general_operand" "")))]
520 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
521 operands[0] = force_reg (QImode, operands[0]);
522 ix86_compare_op0 = operands[0];
523 ix86_compare_op1 = operands[1];
527 (define_insn "cmpdi_ccno_1_rex64"
528 [(set (reg FLAGS_REG)
529 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
530 (match_operand:DI 1 "const0_operand" "n,n")))]
531 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
533 test{q}\t{%0, %0|%0, %0}
534 cmp{q}\t{%1, %0|%0, %1}"
535 [(set_attr "type" "test,icmp")
536 (set_attr "length_immediate" "0,1")
537 (set_attr "mode" "DI")])
539 (define_insn "*cmpdi_minus_1_rex64"
540 [(set (reg FLAGS_REG)
541 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
542 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
544 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
545 "cmp{q}\t{%1, %0|%0, %1}"
546 [(set_attr "type" "icmp")
547 (set_attr "mode" "DI")])
549 (define_expand "cmpdi_1_rex64"
550 [(set (reg:CC FLAGS_REG)
551 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
552 (match_operand:DI 1 "general_operand" "")))]
556 (define_insn "cmpdi_1_insn_rex64"
557 [(set (reg FLAGS_REG)
558 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
559 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
560 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
561 "cmp{q}\t{%1, %0|%0, %1}"
562 [(set_attr "type" "icmp")
563 (set_attr "mode" "DI")])
566 (define_insn "*cmpsi_ccno_1"
567 [(set (reg FLAGS_REG)
568 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
569 (match_operand:SI 1 "const0_operand" "n,n")))]
570 "ix86_match_ccmode (insn, CCNOmode)"
572 test{l}\t{%0, %0|%0, %0}
573 cmp{l}\t{%1, %0|%0, %1}"
574 [(set_attr "type" "test,icmp")
575 (set_attr "length_immediate" "0,1")
576 (set_attr "mode" "SI")])
578 (define_insn "*cmpsi_minus_1"
579 [(set (reg FLAGS_REG)
580 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
581 (match_operand:SI 1 "general_operand" "ri,mr"))
583 "ix86_match_ccmode (insn, CCGOCmode)"
584 "cmp{l}\t{%1, %0|%0, %1}"
585 [(set_attr "type" "icmp")
586 (set_attr "mode" "SI")])
588 (define_expand "cmpsi_1"
589 [(set (reg:CC FLAGS_REG)
590 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
591 (match_operand:SI 1 "general_operand" "ri,mr")))]
595 (define_insn "*cmpsi_1_insn"
596 [(set (reg FLAGS_REG)
597 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
598 (match_operand:SI 1 "general_operand" "ri,mr")))]
599 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
600 && ix86_match_ccmode (insn, CCmode)"
601 "cmp{l}\t{%1, %0|%0, %1}"
602 [(set_attr "type" "icmp")
603 (set_attr "mode" "SI")])
605 (define_insn "*cmphi_ccno_1"
606 [(set (reg FLAGS_REG)
607 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
608 (match_operand:HI 1 "const0_operand" "n,n")))]
609 "ix86_match_ccmode (insn, CCNOmode)"
611 test{w}\t{%0, %0|%0, %0}
612 cmp{w}\t{%1, %0|%0, %1}"
613 [(set_attr "type" "test,icmp")
614 (set_attr "length_immediate" "0,1")
615 (set_attr "mode" "HI")])
617 (define_insn "*cmphi_minus_1"
618 [(set (reg FLAGS_REG)
619 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
620 (match_operand:HI 1 "general_operand" "ri,mr"))
622 "ix86_match_ccmode (insn, CCGOCmode)"
623 "cmp{w}\t{%1, %0|%0, %1}"
624 [(set_attr "type" "icmp")
625 (set_attr "mode" "HI")])
627 (define_insn "*cmphi_1"
628 [(set (reg FLAGS_REG)
629 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
630 (match_operand:HI 1 "general_operand" "ri,mr")))]
631 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
632 && ix86_match_ccmode (insn, CCmode)"
633 "cmp{w}\t{%1, %0|%0, %1}"
634 [(set_attr "type" "icmp")
635 (set_attr "mode" "HI")])
637 (define_insn "*cmpqi_ccno_1"
638 [(set (reg FLAGS_REG)
639 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
640 (match_operand:QI 1 "const0_operand" "n,n")))]
641 "ix86_match_ccmode (insn, CCNOmode)"
643 test{b}\t{%0, %0|%0, %0}
644 cmp{b}\t{$0, %0|%0, 0}"
645 [(set_attr "type" "test,icmp")
646 (set_attr "length_immediate" "0,1")
647 (set_attr "mode" "QI")])
649 (define_insn "*cmpqi_1"
650 [(set (reg FLAGS_REG)
651 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
652 (match_operand:QI 1 "general_operand" "qi,mq")))]
653 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
654 && ix86_match_ccmode (insn, CCmode)"
655 "cmp{b}\t{%1, %0|%0, %1}"
656 [(set_attr "type" "icmp")
657 (set_attr "mode" "QI")])
659 (define_insn "*cmpqi_minus_1"
660 [(set (reg FLAGS_REG)
661 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
662 (match_operand:QI 1 "general_operand" "qi,mq"))
664 "ix86_match_ccmode (insn, CCGOCmode)"
665 "cmp{b}\t{%1, %0|%0, %1}"
666 [(set_attr "type" "icmp")
667 (set_attr "mode" "QI")])
669 (define_insn "*cmpqi_ext_1"
670 [(set (reg FLAGS_REG)
672 (match_operand:QI 0 "general_operand" "Qm")
675 (match_operand 1 "ext_register_operand" "Q")
678 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679 "cmp{b}\t{%h1, %0|%0, %h1}"
680 [(set_attr "type" "icmp")
681 (set_attr "mode" "QI")])
683 (define_insn "*cmpqi_ext_1_rex64"
684 [(set (reg FLAGS_REG)
686 (match_operand:QI 0 "register_operand" "Q")
689 (match_operand 1 "ext_register_operand" "Q")
692 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
693 "cmp{b}\t{%h1, %0|%0, %h1}"
694 [(set_attr "type" "icmp")
695 (set_attr "mode" "QI")])
697 (define_insn "*cmpqi_ext_2"
698 [(set (reg FLAGS_REG)
702 (match_operand 0 "ext_register_operand" "Q")
705 (match_operand:QI 1 "const0_operand" "n")))]
706 "ix86_match_ccmode (insn, CCNOmode)"
708 [(set_attr "type" "test")
709 (set_attr "length_immediate" "0")
710 (set_attr "mode" "QI")])
712 (define_expand "cmpqi_ext_3"
713 [(set (reg:CC FLAGS_REG)
717 (match_operand 0 "ext_register_operand" "")
720 (match_operand:QI 1 "general_operand" "")))]
724 (define_insn "cmpqi_ext_3_insn"
725 [(set (reg FLAGS_REG)
729 (match_operand 0 "ext_register_operand" "Q")
732 (match_operand:QI 1 "general_operand" "Qmn")))]
733 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734 "cmp{b}\t{%1, %h0|%h0, %1}"
735 [(set_attr "type" "icmp")
736 (set_attr "mode" "QI")])
738 (define_insn "cmpqi_ext_3_insn_rex64"
739 [(set (reg FLAGS_REG)
743 (match_operand 0 "ext_register_operand" "Q")
746 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
747 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
748 "cmp{b}\t{%1, %h0|%h0, %1}"
749 [(set_attr "type" "icmp")
750 (set_attr "mode" "QI")])
752 (define_insn "*cmpqi_ext_4"
753 [(set (reg FLAGS_REG)
757 (match_operand 0 "ext_register_operand" "Q")
762 (match_operand 1 "ext_register_operand" "Q")
765 "ix86_match_ccmode (insn, CCmode)"
766 "cmp{b}\t{%h1, %h0|%h0, %h1}"
767 [(set_attr "type" "icmp")
768 (set_attr "mode" "QI")])
770 ;; These implement float point compares.
771 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
772 ;; which would allow mix and match FP modes on the compares. Which is what
773 ;; the old patterns did, but with many more of them.
775 (define_expand "cmpxf"
776 [(set (reg:CC FLAGS_REG)
777 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
778 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
781 ix86_compare_op0 = operands[0];
782 ix86_compare_op1 = operands[1];
786 (define_expand "cmpdf"
787 [(set (reg:CC FLAGS_REG)
788 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
789 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
790 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
792 ix86_compare_op0 = operands[0];
793 ix86_compare_op1 = operands[1];
797 (define_expand "cmpsf"
798 [(set (reg:CC FLAGS_REG)
799 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
800 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
801 "TARGET_80387 || TARGET_SSE_MATH"
803 ix86_compare_op0 = operands[0];
804 ix86_compare_op1 = operands[1];
808 ;; FP compares, step 1:
809 ;; Set the FP condition codes.
811 ;; CCFPmode compare with exceptions
812 ;; CCFPUmode compare with no exceptions
814 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
815 ;; used to manage the reg stack popping would not be preserved.
817 (define_insn "*cmpfp_0"
818 [(set (match_operand:HI 0 "register_operand" "=a")
821 (match_operand 1 "register_operand" "f")
822 (match_operand 2 "const0_operand" "X"))]
825 && FLOAT_MODE_P (GET_MODE (operands[1]))
826 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
827 "* return output_fp_compare (insn, operands, 0, 0);"
828 [(set_attr "type" "multi")
829 (set_attr "unit" "i387")
831 (cond [(match_operand:SF 1 "" "")
833 (match_operand:DF 1 "" "")
836 (const_string "XF")))])
838 (define_insn "*cmpfp_sf"
839 [(set (match_operand:HI 0 "register_operand" "=a")
842 (match_operand:SF 1 "register_operand" "f")
843 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
846 "* return output_fp_compare (insn, operands, 0, 0);"
847 [(set_attr "type" "multi")
848 (set_attr "unit" "i387")
849 (set_attr "mode" "SF")])
851 (define_insn "*cmpfp_df"
852 [(set (match_operand:HI 0 "register_operand" "=a")
855 (match_operand:DF 1 "register_operand" "f")
856 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
859 "* return output_fp_compare (insn, operands, 0, 0);"
860 [(set_attr "type" "multi")
861 (set_attr "unit" "i387")
862 (set_attr "mode" "DF")])
864 (define_insn "*cmpfp_xf"
865 [(set (match_operand:HI 0 "register_operand" "=a")
868 (match_operand:XF 1 "register_operand" "f")
869 (match_operand:XF 2 "register_operand" "f"))]
872 "* return output_fp_compare (insn, operands, 0, 0);"
873 [(set_attr "type" "multi")
874 (set_attr "unit" "i387")
875 (set_attr "mode" "XF")])
877 (define_insn "*cmpfp_u"
878 [(set (match_operand:HI 0 "register_operand" "=a")
881 (match_operand 1 "register_operand" "f")
882 (match_operand 2 "register_operand" "f"))]
885 && FLOAT_MODE_P (GET_MODE (operands[1]))
886 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
887 "* return output_fp_compare (insn, operands, 0, 1);"
888 [(set_attr "type" "multi")
889 (set_attr "unit" "i387")
891 (cond [(match_operand:SF 1 "" "")
893 (match_operand:DF 1 "" "")
896 (const_string "XF")))])
898 (define_insn "*cmpfp_<mode>"
899 [(set (match_operand:HI 0 "register_operand" "=a")
902 (match_operand 1 "register_operand" "f")
903 (match_operator 3 "float_operator"
904 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
906 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
907 && FLOAT_MODE_P (GET_MODE (operands[1]))
908 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
909 "* return output_fp_compare (insn, operands, 0, 0);"
910 [(set_attr "type" "multi")
911 (set_attr "unit" "i387")
912 (set_attr "fp_int_src" "true")
913 (set_attr "mode" "<MODE>")])
915 ;; FP compares, step 2
916 ;; Move the fpsw to ax.
918 (define_insn "x86_fnstsw_1"
919 [(set (match_operand:HI 0 "register_operand" "=a")
920 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
923 [(set_attr "length" "2")
924 (set_attr "mode" "SI")
925 (set_attr "unit" "i387")])
927 ;; FP compares, step 3
928 ;; Get ax into flags, general case.
930 (define_insn "x86_sahf_1"
931 [(set (reg:CC FLAGS_REG)
932 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
935 [(set_attr "length" "1")
936 (set_attr "athlon_decode" "vector")
937 (set_attr "mode" "SI")])
939 ;; Pentium Pro can do steps 1 through 3 in one go.
941 (define_insn "*cmpfp_i_mixed"
942 [(set (reg:CCFP FLAGS_REG)
943 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
944 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
946 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
947 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
948 "* return output_fp_compare (insn, operands, 1, 0);"
949 [(set_attr "type" "fcmp,ssecomi")
951 (if_then_else (match_operand:SF 1 "" "")
953 (const_string "DF")))
954 (set_attr "athlon_decode" "vector")])
956 (define_insn "*cmpfp_i_sse"
957 [(set (reg:CCFP FLAGS_REG)
958 (compare:CCFP (match_operand 0 "register_operand" "x")
959 (match_operand 1 "nonimmediate_operand" "xm")))]
961 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963 "* return output_fp_compare (insn, operands, 1, 0);"
964 [(set_attr "type" "ssecomi")
966 (if_then_else (match_operand:SF 1 "" "")
968 (const_string "DF")))
969 (set_attr "athlon_decode" "vector")])
971 (define_insn "*cmpfp_i_i387"
972 [(set (reg:CCFP FLAGS_REG)
973 (compare:CCFP (match_operand 0 "register_operand" "f")
974 (match_operand 1 "register_operand" "f")))]
975 "TARGET_80387 && TARGET_CMOVE
976 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
977 && FLOAT_MODE_P (GET_MODE (operands[0]))
978 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
979 "* return output_fp_compare (insn, operands, 1, 0);"
980 [(set_attr "type" "fcmp")
982 (cond [(match_operand:SF 1 "" "")
984 (match_operand:DF 1 "" "")
987 (const_string "XF")))
988 (set_attr "athlon_decode" "vector")])
990 (define_insn "*cmpfp_iu_mixed"
991 [(set (reg:CCFPU FLAGS_REG)
992 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
993 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
995 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
996 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
997 "* return output_fp_compare (insn, operands, 1, 1);"
998 [(set_attr "type" "fcmp,ssecomi")
1000 (if_then_else (match_operand:SF 1 "" "")
1002 (const_string "DF")))
1003 (set_attr "athlon_decode" "vector")])
1005 (define_insn "*cmpfp_iu_sse"
1006 [(set (reg:CCFPU FLAGS_REG)
1007 (compare:CCFPU (match_operand 0 "register_operand" "x")
1008 (match_operand 1 "nonimmediate_operand" "xm")))]
1010 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1011 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1012 "* return output_fp_compare (insn, operands, 1, 1);"
1013 [(set_attr "type" "ssecomi")
1015 (if_then_else (match_operand:SF 1 "" "")
1017 (const_string "DF")))
1018 (set_attr "athlon_decode" "vector")])
1020 (define_insn "*cmpfp_iu_387"
1021 [(set (reg:CCFPU FLAGS_REG)
1022 (compare:CCFPU (match_operand 0 "register_operand" "f")
1023 (match_operand 1 "register_operand" "f")))]
1024 "TARGET_80387 && TARGET_CMOVE
1025 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1026 && FLOAT_MODE_P (GET_MODE (operands[0]))
1027 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1028 "* return output_fp_compare (insn, operands, 1, 1);"
1029 [(set_attr "type" "fcmp")
1031 (cond [(match_operand:SF 1 "" "")
1033 (match_operand:DF 1 "" "")
1036 (const_string "XF")))
1037 (set_attr "athlon_decode" "vector")])
1039 ;; Move instructions.
1041 ;; General case of fullword move.
1043 (define_expand "movsi"
1044 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1045 (match_operand:SI 1 "general_operand" ""))]
1047 "ix86_expand_move (SImode, operands); DONE;")
1049 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1052 ;; %%% We don't use a post-inc memory reference because x86 is not a
1053 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1054 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1055 ;; targets without our curiosities, and it is just as easy to represent
1056 ;; this differently.
1058 (define_insn "*pushsi2"
1059 [(set (match_operand:SI 0 "push_operand" "=<")
1060 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1063 [(set_attr "type" "push")
1064 (set_attr "mode" "SI")])
1066 ;; For 64BIT abi we always round up to 8 bytes.
1067 (define_insn "*pushsi2_rex64"
1068 [(set (match_operand:SI 0 "push_operand" "=X")
1069 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1072 [(set_attr "type" "push")
1073 (set_attr "mode" "SI")])
1075 (define_insn "*pushsi2_prologue"
1076 [(set (match_operand:SI 0 "push_operand" "=<")
1077 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1078 (clobber (mem:BLK (scratch)))]
1081 [(set_attr "type" "push")
1082 (set_attr "mode" "SI")])
1084 (define_insn "*popsi1_epilogue"
1085 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1086 (mem:SI (reg:SI SP_REG)))
1087 (set (reg:SI SP_REG)
1088 (plus:SI (reg:SI SP_REG) (const_int 4)))
1089 (clobber (mem:BLK (scratch)))]
1092 [(set_attr "type" "pop")
1093 (set_attr "mode" "SI")])
1095 (define_insn "popsi1"
1096 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1097 (mem:SI (reg:SI SP_REG)))
1098 (set (reg:SI SP_REG)
1099 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1102 [(set_attr "type" "pop")
1103 (set_attr "mode" "SI")])
1105 (define_insn "*movsi_xor"
1106 [(set (match_operand:SI 0 "register_operand" "=r")
1107 (match_operand:SI 1 "const0_operand" "i"))
1108 (clobber (reg:CC FLAGS_REG))]
1109 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1110 "xor{l}\t{%0, %0|%0, %0}"
1111 [(set_attr "type" "alu1")
1112 (set_attr "mode" "SI")
1113 (set_attr "length_immediate" "0")])
1115 (define_insn "*movsi_or"
1116 [(set (match_operand:SI 0 "register_operand" "=r")
1117 (match_operand:SI 1 "immediate_operand" "i"))
1118 (clobber (reg:CC FLAGS_REG))]
1120 && operands[1] == constm1_rtx
1121 && (TARGET_PENTIUM || optimize_size)"
1123 operands[1] = constm1_rtx;
1124 return "or{l}\t{%1, %0|%0, %1}";
1126 [(set_attr "type" "alu1")
1127 (set_attr "mode" "SI")
1128 (set_attr "length_immediate" "1")])
1130 (define_insn "*movsi_1"
1131 [(set (match_operand:SI 0 "nonimmediate_operand"
1132 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1133 (match_operand:SI 1 "general_operand"
1134 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1135 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1137 switch (get_attr_type (insn))
1140 if (get_attr_mode (insn) == MODE_TI)
1141 return "pxor\t%0, %0";
1142 return "xorps\t%0, %0";
1145 switch (get_attr_mode (insn))
1148 return "movdqa\t{%1, %0|%0, %1}";
1150 return "movaps\t{%1, %0|%0, %1}";
1152 return "movd\t{%1, %0|%0, %1}";
1154 return "movss\t{%1, %0|%0, %1}";
1160 return "pxor\t%0, %0";
1163 if (get_attr_mode (insn) == MODE_DI)
1164 return "movq\t{%1, %0|%0, %1}";
1165 return "movd\t{%1, %0|%0, %1}";
1168 return "lea{l}\t{%1, %0|%0, %1}";
1171 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1172 return "mov{l}\t{%1, %0|%0, %1}";
1176 (cond [(eq_attr "alternative" "2")
1177 (const_string "mmx")
1178 (eq_attr "alternative" "3,4,5")
1179 (const_string "mmxmov")
1180 (eq_attr "alternative" "6")
1181 (const_string "sselog1")
1182 (eq_attr "alternative" "7,8,9,10,11")
1183 (const_string "ssemov")
1184 (and (ne (symbol_ref "flag_pic") (const_int 0))
1185 (match_operand:SI 1 "symbolic_operand" ""))
1186 (const_string "lea")
1188 (const_string "imov")))
1190 (cond [(eq_attr "alternative" "2,3")
1192 (eq_attr "alternative" "6,7")
1194 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1195 (const_string "V4SF")
1196 (const_string "TI"))
1197 (and (eq_attr "alternative" "8,9,10,11")
1198 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1201 (const_string "SI")))])
1203 ;; Stores and loads of ax to arbitrary constant address.
1204 ;; We fake an second form of instruction to force reload to load address
1205 ;; into register when rax is not available
1206 (define_insn "*movabssi_1_rex64"
1207 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1208 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1209 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1211 movabs{l}\t{%1, %P0|%P0, %1}
1212 mov{l}\t{%1, %a0|%a0, %1}"
1213 [(set_attr "type" "imov")
1214 (set_attr "modrm" "0,*")
1215 (set_attr "length_address" "8,0")
1216 (set_attr "length_immediate" "0,*")
1217 (set_attr "memory" "store")
1218 (set_attr "mode" "SI")])
1220 (define_insn "*movabssi_2_rex64"
1221 [(set (match_operand:SI 0 "register_operand" "=a,r")
1222 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1223 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1225 movabs{l}\t{%P1, %0|%0, %P1}
1226 mov{l}\t{%a1, %0|%0, %a1}"
1227 [(set_attr "type" "imov")
1228 (set_attr "modrm" "0,*")
1229 (set_attr "length_address" "8,0")
1230 (set_attr "length_immediate" "0")
1231 (set_attr "memory" "load")
1232 (set_attr "mode" "SI")])
1234 (define_insn "*swapsi"
1235 [(set (match_operand:SI 0 "register_operand" "+r")
1236 (match_operand:SI 1 "register_operand" "+r"))
1241 [(set_attr "type" "imov")
1242 (set_attr "mode" "SI")
1243 (set_attr "pent_pair" "np")
1244 (set_attr "athlon_decode" "vector")])
1246 (define_expand "movhi"
1247 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1248 (match_operand:HI 1 "general_operand" ""))]
1250 "ix86_expand_move (HImode, operands); DONE;")
1252 (define_insn "*pushhi2"
1253 [(set (match_operand:HI 0 "push_operand" "=<,<")
1254 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1257 push{w}\t{|WORD PTR }%1
1259 [(set_attr "type" "push")
1260 (set_attr "mode" "HI")])
1262 ;; For 64BIT abi we always round up to 8 bytes.
1263 (define_insn "*pushhi2_rex64"
1264 [(set (match_operand:HI 0 "push_operand" "=X")
1265 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1268 [(set_attr "type" "push")
1269 (set_attr "mode" "QI")])
1271 (define_insn "*movhi_1"
1272 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1273 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1274 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1276 switch (get_attr_type (insn))
1279 /* movzwl is faster than movw on p2 due to partial word stalls,
1280 though not as fast as an aligned movl. */
1281 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1283 if (get_attr_mode (insn) == MODE_SI)
1284 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1286 return "mov{w}\t{%1, %0|%0, %1}";
1290 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1291 (const_string "imov")
1292 (and (eq_attr "alternative" "0")
1293 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1295 (eq (symbol_ref "TARGET_HIMODE_MATH")
1297 (const_string "imov")
1298 (and (eq_attr "alternative" "1,2")
1299 (match_operand:HI 1 "aligned_operand" ""))
1300 (const_string "imov")
1301 (and (ne (symbol_ref "TARGET_MOVX")
1303 (eq_attr "alternative" "0,2"))
1304 (const_string "imovx")
1306 (const_string "imov")))
1308 (cond [(eq_attr "type" "imovx")
1310 (and (eq_attr "alternative" "1,2")
1311 (match_operand:HI 1 "aligned_operand" ""))
1313 (and (eq_attr "alternative" "0")
1314 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1316 (eq (symbol_ref "TARGET_HIMODE_MATH")
1320 (const_string "HI")))])
1322 ;; Stores and loads of ax to arbitrary constant address.
1323 ;; We fake an second form of instruction to force reload to load address
1324 ;; into register when rax is not available
1325 (define_insn "*movabshi_1_rex64"
1326 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1327 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1328 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1330 movabs{w}\t{%1, %P0|%P0, %1}
1331 mov{w}\t{%1, %a0|%a0, %1}"
1332 [(set_attr "type" "imov")
1333 (set_attr "modrm" "0,*")
1334 (set_attr "length_address" "8,0")
1335 (set_attr "length_immediate" "0,*")
1336 (set_attr "memory" "store")
1337 (set_attr "mode" "HI")])
1339 (define_insn "*movabshi_2_rex64"
1340 [(set (match_operand:HI 0 "register_operand" "=a,r")
1341 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1342 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1344 movabs{w}\t{%P1, %0|%0, %P1}
1345 mov{w}\t{%a1, %0|%0, %a1}"
1346 [(set_attr "type" "imov")
1347 (set_attr "modrm" "0,*")
1348 (set_attr "length_address" "8,0")
1349 (set_attr "length_immediate" "0")
1350 (set_attr "memory" "load")
1351 (set_attr "mode" "HI")])
1353 (define_insn "*swaphi_1"
1354 [(set (match_operand:HI 0 "register_operand" "+r")
1355 (match_operand:HI 1 "register_operand" "+r"))
1358 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1360 [(set_attr "type" "imov")
1361 (set_attr "mode" "SI")
1362 (set_attr "pent_pair" "np")
1363 (set_attr "athlon_decode" "vector")])
1365 (define_insn "*swaphi_2"
1366 [(set (match_operand:HI 0 "register_operand" "+r")
1367 (match_operand:HI 1 "register_operand" "+r"))
1370 "TARGET_PARTIAL_REG_STALL"
1372 [(set_attr "type" "imov")
1373 (set_attr "mode" "HI")
1374 (set_attr "pent_pair" "np")
1375 (set_attr "athlon_decode" "vector")])
1377 (define_expand "movstricthi"
1378 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1379 (match_operand:HI 1 "general_operand" ""))]
1380 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1382 /* Don't generate memory->memory moves, go through a register */
1383 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1384 operands[1] = force_reg (HImode, operands[1]);
1387 (define_insn "*movstricthi_1"
1388 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1389 (match_operand:HI 1 "general_operand" "rn,m"))]
1390 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1391 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1392 "mov{w}\t{%1, %0|%0, %1}"
1393 [(set_attr "type" "imov")
1394 (set_attr "mode" "HI")])
1396 (define_insn "*movstricthi_xor"
1397 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1398 (match_operand:HI 1 "const0_operand" "i"))
1399 (clobber (reg:CC FLAGS_REG))]
1401 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1402 "xor{w}\t{%0, %0|%0, %0}"
1403 [(set_attr "type" "alu1")
1404 (set_attr "mode" "HI")
1405 (set_attr "length_immediate" "0")])
1407 (define_expand "movqi"
1408 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1409 (match_operand:QI 1 "general_operand" ""))]
1411 "ix86_expand_move (QImode, operands); DONE;")
1413 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1414 ;; "push a byte". But actually we use pushw, which has the effect
1415 ;; of rounding the amount pushed up to a halfword.
1417 (define_insn "*pushqi2"
1418 [(set (match_operand:QI 0 "push_operand" "=X,X")
1419 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1422 push{w}\t{|word ptr }%1
1424 [(set_attr "type" "push")
1425 (set_attr "mode" "HI")])
1427 ;; For 64BIT abi we always round up to 8 bytes.
1428 (define_insn "*pushqi2_rex64"
1429 [(set (match_operand:QI 0 "push_operand" "=X")
1430 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1433 [(set_attr "type" "push")
1434 (set_attr "mode" "QI")])
1436 ;; Situation is quite tricky about when to choose full sized (SImode) move
1437 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1438 ;; partial register dependency machines (such as AMD Athlon), where QImode
1439 ;; moves issue extra dependency and for partial register stalls machines
1440 ;; that don't use QImode patterns (and QImode move cause stall on the next
1443 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1444 ;; register stall machines with, where we use QImode instructions, since
1445 ;; partial register stall can be caused there. Then we use movzx.
1446 (define_insn "*movqi_1"
1447 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1448 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,m ,qn"))]
1449 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1451 switch (get_attr_type (insn))
1454 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1455 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1457 if (get_attr_mode (insn) == MODE_SI)
1458 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1460 return "mov{b}\t{%1, %0|%0, %1}";
1464 (cond [(eq_attr "alternative" "5")
1465 (const_string "imovx")
1466 (ne (symbol_ref "optimize_size") (const_int 0))
1467 (const_string "imov")
1468 (and (eq_attr "alternative" "3")
1469 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1471 (eq (symbol_ref "TARGET_QIMODE_MATH")
1473 (const_string "imov")
1474 (eq_attr "alternative" "3")
1475 (const_string "imovx")
1476 (and (ne (symbol_ref "TARGET_MOVX")
1478 (eq_attr "alternative" "2"))
1479 (const_string "imovx")
1481 (const_string "imov")))
1483 (cond [(eq_attr "alternative" "3,4,5")
1485 (eq_attr "alternative" "6")
1487 (eq_attr "type" "imovx")
1489 (and (eq_attr "type" "imov")
1490 (and (eq_attr "alternative" "0,1")
1491 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1494 ;; Avoid partial register stalls when not using QImode arithmetic
1495 (and (eq_attr "type" "imov")
1496 (and (eq_attr "alternative" "0,1")
1497 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1499 (eq (symbol_ref "TARGET_QIMODE_MATH")
1503 (const_string "QI")))])
1505 (define_expand "reload_outqi"
1506 [(parallel [(match_operand:QI 0 "" "=m")
1507 (match_operand:QI 1 "register_operand" "r")
1508 (match_operand:QI 2 "register_operand" "=&q")])]
1512 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1514 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1515 if (! q_regs_operand (op1, QImode))
1517 emit_insn (gen_movqi (op2, op1));
1520 emit_insn (gen_movqi (op0, op1));
1524 (define_insn "*swapqi_1"
1525 [(set (match_operand:QI 0 "register_operand" "+r")
1526 (match_operand:QI 1 "register_operand" "+r"))
1529 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1531 [(set_attr "type" "imov")
1532 (set_attr "mode" "SI")
1533 (set_attr "pent_pair" "np")
1534 (set_attr "athlon_decode" "vector")])
1536 (define_insn "*swapqi_2"
1537 [(set (match_operand:QI 0 "register_operand" "+q")
1538 (match_operand:QI 1 "register_operand" "+q"))
1541 "TARGET_PARTIAL_REG_STALL"
1543 [(set_attr "type" "imov")
1544 (set_attr "mode" "QI")
1545 (set_attr "pent_pair" "np")
1546 (set_attr "athlon_decode" "vector")])
1548 (define_expand "movstrictqi"
1549 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1550 (match_operand:QI 1 "general_operand" ""))]
1551 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1553 /* Don't generate memory->memory moves, go through a register. */
1554 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1555 operands[1] = force_reg (QImode, operands[1]);
1558 (define_insn "*movstrictqi_1"
1559 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1560 (match_operand:QI 1 "general_operand" "*qn,m"))]
1561 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1562 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1563 "mov{b}\t{%1, %0|%0, %1}"
1564 [(set_attr "type" "imov")
1565 (set_attr "mode" "QI")])
1567 (define_insn "*movstrictqi_xor"
1568 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1569 (match_operand:QI 1 "const0_operand" "i"))
1570 (clobber (reg:CC FLAGS_REG))]
1571 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1572 "xor{b}\t{%0, %0|%0, %0}"
1573 [(set_attr "type" "alu1")
1574 (set_attr "mode" "QI")
1575 (set_attr "length_immediate" "0")])
1577 (define_insn "*movsi_extv_1"
1578 [(set (match_operand:SI 0 "register_operand" "=R")
1579 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1583 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1584 [(set_attr "type" "imovx")
1585 (set_attr "mode" "SI")])
1587 (define_insn "*movhi_extv_1"
1588 [(set (match_operand:HI 0 "register_operand" "=R")
1589 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1593 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1594 [(set_attr "type" "imovx")
1595 (set_attr "mode" "SI")])
1597 (define_insn "*movqi_extv_1"
1598 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1599 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1604 switch (get_attr_type (insn))
1607 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1609 return "mov{b}\t{%h1, %0|%0, %h1}";
1613 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1614 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1615 (ne (symbol_ref "TARGET_MOVX")
1617 (const_string "imovx")
1618 (const_string "imov")))
1620 (if_then_else (eq_attr "type" "imovx")
1622 (const_string "QI")))])
1624 (define_insn "*movqi_extv_1_rex64"
1625 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1626 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1631 switch (get_attr_type (insn))
1634 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1636 return "mov{b}\t{%h1, %0|%0, %h1}";
1640 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1641 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1642 (ne (symbol_ref "TARGET_MOVX")
1644 (const_string "imovx")
1645 (const_string "imov")))
1647 (if_then_else (eq_attr "type" "imovx")
1649 (const_string "QI")))])
1651 ;; Stores and loads of ax to arbitrary constant address.
1652 ;; We fake an second form of instruction to force reload to load address
1653 ;; into register when rax is not available
1654 (define_insn "*movabsqi_1_rex64"
1655 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1656 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1657 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1659 movabs{b}\t{%1, %P0|%P0, %1}
1660 mov{b}\t{%1, %a0|%a0, %1}"
1661 [(set_attr "type" "imov")
1662 (set_attr "modrm" "0,*")
1663 (set_attr "length_address" "8,0")
1664 (set_attr "length_immediate" "0,*")
1665 (set_attr "memory" "store")
1666 (set_attr "mode" "QI")])
1668 (define_insn "*movabsqi_2_rex64"
1669 [(set (match_operand:QI 0 "register_operand" "=a,r")
1670 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1671 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1673 movabs{b}\t{%P1, %0|%0, %P1}
1674 mov{b}\t{%a1, %0|%0, %a1}"
1675 [(set_attr "type" "imov")
1676 (set_attr "modrm" "0,*")
1677 (set_attr "length_address" "8,0")
1678 (set_attr "length_immediate" "0")
1679 (set_attr "memory" "load")
1680 (set_attr "mode" "QI")])
1682 (define_insn "*movsi_extzv_1"
1683 [(set (match_operand:SI 0 "register_operand" "=R")
1684 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1688 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1689 [(set_attr "type" "imovx")
1690 (set_attr "mode" "SI")])
1692 (define_insn "*movqi_extzv_2"
1693 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1694 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1699 switch (get_attr_type (insn))
1702 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1704 return "mov{b}\t{%h1, %0|%0, %h1}";
1708 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1709 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1710 (ne (symbol_ref "TARGET_MOVX")
1712 (const_string "imovx")
1713 (const_string "imov")))
1715 (if_then_else (eq_attr "type" "imovx")
1717 (const_string "QI")))])
1719 (define_insn "*movqi_extzv_2_rex64"
1720 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1721 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1726 switch (get_attr_type (insn))
1729 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1731 return "mov{b}\t{%h1, %0|%0, %h1}";
1735 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1736 (ne (symbol_ref "TARGET_MOVX")
1738 (const_string "imovx")
1739 (const_string "imov")))
1741 (if_then_else (eq_attr "type" "imovx")
1743 (const_string "QI")))])
1745 (define_insn "movsi_insv_1"
1746 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1749 (match_operand:SI 1 "general_operand" "Qmn"))]
1751 "mov{b}\t{%b1, %h0|%h0, %b1}"
1752 [(set_attr "type" "imov")
1753 (set_attr "mode" "QI")])
1755 (define_insn "movdi_insv_1_rex64"
1756 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1759 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1761 "mov{b}\t{%b1, %h0|%h0, %b1}"
1762 [(set_attr "type" "imov")
1763 (set_attr "mode" "QI")])
1765 (define_insn "*movqi_insv_2"
1766 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1769 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1772 "mov{b}\t{%h1, %h0|%h0, %h1}"
1773 [(set_attr "type" "imov")
1774 (set_attr "mode" "QI")])
1776 (define_expand "movdi"
1777 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1778 (match_operand:DI 1 "general_operand" ""))]
1780 "ix86_expand_move (DImode, operands); DONE;")
1782 (define_insn "*pushdi"
1783 [(set (match_operand:DI 0 "push_operand" "=<")
1784 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1788 (define_insn "*pushdi2_rex64"
1789 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1790 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1795 [(set_attr "type" "push,multi")
1796 (set_attr "mode" "DI")])
1798 ;; Convert impossible pushes of immediate to existing instructions.
1799 ;; First try to get scratch register and go through it. In case this
1800 ;; fails, push sign extended lower part first and then overwrite
1801 ;; upper part by 32bit move.
1803 [(match_scratch:DI 2 "r")
1804 (set (match_operand:DI 0 "push_operand" "")
1805 (match_operand:DI 1 "immediate_operand" ""))]
1806 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1807 && !x86_64_immediate_operand (operands[1], DImode)"
1808 [(set (match_dup 2) (match_dup 1))
1809 (set (match_dup 0) (match_dup 2))]
1812 ;; We need to define this as both peepholer and splitter for case
1813 ;; peephole2 pass is not run.
1814 ;; "&& 1" is needed to keep it from matching the previous pattern.
1816 [(set (match_operand:DI 0 "push_operand" "")
1817 (match_operand:DI 1 "immediate_operand" ""))]
1818 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1819 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1820 [(set (match_dup 0) (match_dup 1))
1821 (set (match_dup 2) (match_dup 3))]
1822 "split_di (operands + 1, 1, operands + 2, operands + 3);
1823 operands[1] = gen_lowpart (DImode, operands[2]);
1824 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1829 [(set (match_operand:DI 0 "push_operand" "")
1830 (match_operand:DI 1 "immediate_operand" ""))]
1831 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1832 && !symbolic_operand (operands[1], DImode)
1833 && !x86_64_immediate_operand (operands[1], DImode)"
1834 [(set (match_dup 0) (match_dup 1))
1835 (set (match_dup 2) (match_dup 3))]
1836 "split_di (operands + 1, 1, operands + 2, operands + 3);
1837 operands[1] = gen_lowpart (DImode, operands[2]);
1838 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1842 (define_insn "*pushdi2_prologue_rex64"
1843 [(set (match_operand:DI 0 "push_operand" "=<")
1844 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1845 (clobber (mem:BLK (scratch)))]
1848 [(set_attr "type" "push")
1849 (set_attr "mode" "DI")])
1851 (define_insn "*popdi1_epilogue_rex64"
1852 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1853 (mem:DI (reg:DI SP_REG)))
1854 (set (reg:DI SP_REG)
1855 (plus:DI (reg:DI SP_REG) (const_int 8)))
1856 (clobber (mem:BLK (scratch)))]
1859 [(set_attr "type" "pop")
1860 (set_attr "mode" "DI")])
1862 (define_insn "popdi1"
1863 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1864 (mem:DI (reg:DI SP_REG)))
1865 (set (reg:DI SP_REG)
1866 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1869 [(set_attr "type" "pop")
1870 (set_attr "mode" "DI")])
1872 (define_insn "*movdi_xor_rex64"
1873 [(set (match_operand:DI 0 "register_operand" "=r")
1874 (match_operand:DI 1 "const0_operand" "i"))
1875 (clobber (reg:CC FLAGS_REG))]
1876 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1877 && reload_completed"
1878 "xor{l}\t{%k0, %k0|%k0, %k0}"
1879 [(set_attr "type" "alu1")
1880 (set_attr "mode" "SI")
1881 (set_attr "length_immediate" "0")])
1883 (define_insn "*movdi_or_rex64"
1884 [(set (match_operand:DI 0 "register_operand" "=r")
1885 (match_operand:DI 1 "const_int_operand" "i"))
1886 (clobber (reg:CC FLAGS_REG))]
1887 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1889 && operands[1] == constm1_rtx"
1891 operands[1] = constm1_rtx;
1892 return "or{q}\t{%1, %0|%0, %1}";
1894 [(set_attr "type" "alu1")
1895 (set_attr "mode" "DI")
1896 (set_attr "length_immediate" "1")])
1898 (define_insn "*movdi_2"
1899 [(set (match_operand:DI 0 "nonimmediate_operand"
1900 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1901 (match_operand:DI 1 "general_operand"
1902 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1903 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1908 movq\t{%1, %0|%0, %1}
1909 movq\t{%1, %0|%0, %1}
1911 movq\t{%1, %0|%0, %1}
1912 movdqa\t{%1, %0|%0, %1}
1913 movq\t{%1, %0|%0, %1}
1915 movlps\t{%1, %0|%0, %1}
1916 movaps\t{%1, %0|%0, %1}
1917 movlps\t{%1, %0|%0, %1}"
1918 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1919 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1922 [(set (match_operand:DI 0 "push_operand" "")
1923 (match_operand:DI 1 "general_operand" ""))]
1924 "!TARGET_64BIT && reload_completed
1925 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1927 "ix86_split_long_move (operands); DONE;")
1929 ;; %%% This multiword shite has got to go.
1931 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1932 (match_operand:DI 1 "general_operand" ""))]
1933 "!TARGET_64BIT && reload_completed
1934 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1935 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1937 "ix86_split_long_move (operands); DONE;")
1939 (define_insn "*movdi_1_rex64"
1940 [(set (match_operand:DI 0 "nonimmediate_operand"
1941 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1942 (match_operand:DI 1 "general_operand"
1943 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1944 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1946 switch (get_attr_type (insn))
1949 if (which_alternative == 13)
1950 return "movq2dq\t{%1, %0|%0, %1}";
1952 return "movdq2q\t{%1, %0|%0, %1}";
1954 if (get_attr_mode (insn) == MODE_TI)
1955 return "movdqa\t{%1, %0|%0, %1}";
1958 /* Moves from and into integer register is done using movd opcode with
1960 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1961 return "movd\t{%1, %0|%0, %1}";
1962 return "movq\t{%1, %0|%0, %1}";
1965 return "pxor\t%0, %0";
1969 return "lea{q}\t{%a1, %0|%0, %a1}";
1971 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1972 if (get_attr_mode (insn) == MODE_SI)
1973 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1974 else if (which_alternative == 2)
1975 return "movabs{q}\t{%1, %0|%0, %1}";
1977 return "mov{q}\t{%1, %0|%0, %1}";
1981 (cond [(eq_attr "alternative" "5")
1982 (const_string "mmx")
1983 (eq_attr "alternative" "6,7,8")
1984 (const_string "mmxmov")
1985 (eq_attr "alternative" "9")
1986 (const_string "sselog1")
1987 (eq_attr "alternative" "10,11,12")
1988 (const_string "ssemov")
1989 (eq_attr "alternative" "13,14")
1990 (const_string "ssecvt")
1991 (eq_attr "alternative" "4")
1992 (const_string "multi")
1993 (and (ne (symbol_ref "flag_pic") (const_int 0))
1994 (match_operand:DI 1 "symbolic_operand" ""))
1995 (const_string "lea")
1997 (const_string "imov")))
1998 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
1999 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2000 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2002 ;; Stores and loads of ax to arbitrary constant address.
2003 ;; We fake an second form of instruction to force reload to load address
2004 ;; into register when rax is not available
2005 (define_insn "*movabsdi_1_rex64"
2006 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2007 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2008 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2010 movabs{q}\t{%1, %P0|%P0, %1}
2011 mov{q}\t{%1, %a0|%a0, %1}"
2012 [(set_attr "type" "imov")
2013 (set_attr "modrm" "0,*")
2014 (set_attr "length_address" "8,0")
2015 (set_attr "length_immediate" "0,*")
2016 (set_attr "memory" "store")
2017 (set_attr "mode" "DI")])
2019 (define_insn "*movabsdi_2_rex64"
2020 [(set (match_operand:DI 0 "register_operand" "=a,r")
2021 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2022 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2024 movabs{q}\t{%P1, %0|%0, %P1}
2025 mov{q}\t{%a1, %0|%0, %a1}"
2026 [(set_attr "type" "imov")
2027 (set_attr "modrm" "0,*")
2028 (set_attr "length_address" "8,0")
2029 (set_attr "length_immediate" "0")
2030 (set_attr "memory" "load")
2031 (set_attr "mode" "DI")])
2033 ;; Convert impossible stores of immediate to existing instructions.
2034 ;; First try to get scratch register and go through it. In case this
2035 ;; fails, move by 32bit parts.
2037 [(match_scratch:DI 2 "r")
2038 (set (match_operand:DI 0 "memory_operand" "")
2039 (match_operand:DI 1 "immediate_operand" ""))]
2040 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2041 && !x86_64_immediate_operand (operands[1], DImode)"
2042 [(set (match_dup 2) (match_dup 1))
2043 (set (match_dup 0) (match_dup 2))]
2046 ;; We need to define this as both peepholer and splitter for case
2047 ;; peephole2 pass is not run.
2048 ;; "&& 1" is needed to keep it from matching the previous pattern.
2050 [(set (match_operand:DI 0 "memory_operand" "")
2051 (match_operand:DI 1 "immediate_operand" ""))]
2052 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2053 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2054 [(set (match_dup 2) (match_dup 3))
2055 (set (match_dup 4) (match_dup 5))]
2056 "split_di (operands, 2, operands + 2, operands + 4);")
2059 [(set (match_operand:DI 0 "memory_operand" "")
2060 (match_operand:DI 1 "immediate_operand" ""))]
2061 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2062 && !symbolic_operand (operands[1], DImode)
2063 && !x86_64_immediate_operand (operands[1], DImode)"
2064 [(set (match_dup 2) (match_dup 3))
2065 (set (match_dup 4) (match_dup 5))]
2066 "split_di (operands, 2, operands + 2, operands + 4);")
2068 (define_insn "*swapdi_rex64"
2069 [(set (match_operand:DI 0 "register_operand" "+r")
2070 (match_operand:DI 1 "register_operand" "+r"))
2075 [(set_attr "type" "imov")
2076 (set_attr "mode" "DI")
2077 (set_attr "pent_pair" "np")
2078 (set_attr "athlon_decode" "vector")])
2080 (define_expand "movti"
2081 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2082 (match_operand:TI 1 "nonimmediate_operand" ""))]
2083 "TARGET_SSE || TARGET_64BIT"
2086 ix86_expand_move (TImode, operands);
2088 ix86_expand_vector_move (TImode, operands);
2092 (define_insn "*movti_internal"
2093 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2094 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2095 "TARGET_SSE && !TARGET_64BIT
2096 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2098 switch (which_alternative)
2101 if (get_attr_mode (insn) == MODE_V4SF)
2102 return "xorps\t%0, %0";
2104 return "pxor\t%0, %0";
2107 if (get_attr_mode (insn) == MODE_V4SF)
2108 return "movaps\t{%1, %0|%0, %1}";
2110 return "movdqa\t{%1, %0|%0, %1}";
2115 [(set_attr "type" "ssemov,ssemov,ssemov")
2117 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2118 (const_string "V4SF")
2120 (eq_attr "alternative" "0,1")
2122 (ne (symbol_ref "optimize_size")
2124 (const_string "V4SF")
2125 (const_string "TI"))
2126 (eq_attr "alternative" "2")
2128 (ne (symbol_ref "optimize_size")
2130 (const_string "V4SF")
2131 (const_string "TI"))]
2132 (const_string "TI")))])
2134 (define_insn "*movti_rex64"
2135 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2136 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2138 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2140 switch (which_alternative)
2146 if (get_attr_mode (insn) == MODE_V4SF)
2147 return "xorps\t%0, %0";
2149 return "pxor\t%0, %0";
2152 if (get_attr_mode (insn) == MODE_V4SF)
2153 return "movaps\t{%1, %0|%0, %1}";
2155 return "movdqa\t{%1, %0|%0, %1}";
2160 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2162 (cond [(eq_attr "alternative" "2,3")
2164 (ne (symbol_ref "optimize_size")
2166 (const_string "V4SF")
2167 (const_string "TI"))
2168 (eq_attr "alternative" "4")
2170 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2172 (ne (symbol_ref "optimize_size")
2174 (const_string "V4SF")
2175 (const_string "TI"))]
2176 (const_string "DI")))])
2179 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2180 (match_operand:TI 1 "general_operand" ""))]
2181 "reload_completed && !SSE_REG_P (operands[0])
2182 && !SSE_REG_P (operands[1])"
2184 "ix86_split_long_move (operands); DONE;")
2186 (define_expand "movsf"
2187 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2188 (match_operand:SF 1 "general_operand" ""))]
2190 "ix86_expand_move (SFmode, operands); DONE;")
2192 (define_insn "*pushsf"
2193 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2194 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2197 /* Anything else should be already split before reg-stack. */
2198 gcc_assert (which_alternative == 1);
2199 return "push{l}\t%1";
2201 [(set_attr "type" "multi,push,multi")
2202 (set_attr "unit" "i387,*,*")
2203 (set_attr "mode" "SF,SI,SF")])
2205 (define_insn "*pushsf_rex64"
2206 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2207 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2210 /* Anything else should be already split before reg-stack. */
2211 gcc_assert (which_alternative == 1);
2212 return "push{q}\t%q1";
2214 [(set_attr "type" "multi,push,multi")
2215 (set_attr "unit" "i387,*,*")
2216 (set_attr "mode" "SF,DI,SF")])
2219 [(set (match_operand:SF 0 "push_operand" "")
2220 (match_operand:SF 1 "memory_operand" ""))]
2222 && GET_CODE (operands[1]) == MEM
2223 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2224 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2227 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2230 ;; %%% Kill this when call knows how to work this out.
2232 [(set (match_operand:SF 0 "push_operand" "")
2233 (match_operand:SF 1 "any_fp_register_operand" ""))]
2235 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2236 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2239 [(set (match_operand:SF 0 "push_operand" "")
2240 (match_operand:SF 1 "any_fp_register_operand" ""))]
2242 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2243 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2245 (define_insn "*movsf_1"
2246 [(set (match_operand:SF 0 "nonimmediate_operand"
2247 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2248 (match_operand:SF 1 "general_operand"
2249 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2250 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2251 && (reload_in_progress || reload_completed
2252 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2253 || GET_CODE (operands[1]) != CONST_DOUBLE
2254 || memory_operand (operands[0], SFmode))"
2256 switch (which_alternative)
2259 return output_387_reg_move (insn, operands);
2262 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2263 return "fstp%z0\t%y0";
2265 return "fst%z0\t%y0";
2268 return standard_80387_constant_opcode (operands[1]);
2272 return "mov{l}\t{%1, %0|%0, %1}";
2274 if (get_attr_mode (insn) == MODE_TI)
2275 return "pxor\t%0, %0";
2277 return "xorps\t%0, %0";
2279 if (get_attr_mode (insn) == MODE_V4SF)
2280 return "movaps\t{%1, %0|%0, %1}";
2282 return "movss\t{%1, %0|%0, %1}";
2285 return "movss\t{%1, %0|%0, %1}";
2289 return "movd\t{%1, %0|%0, %1}";
2292 return "movq\t{%1, %0|%0, %1}";
2298 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2300 (cond [(eq_attr "alternative" "3,4,9,10")
2302 (eq_attr "alternative" "5")
2304 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2306 (ne (symbol_ref "TARGET_SSE2")
2308 (eq (symbol_ref "optimize_size")
2311 (const_string "V4SF"))
2312 /* For architectures resolving dependencies on
2313 whole SSE registers use APS move to break dependency
2314 chains, otherwise use short move to avoid extra work.
2316 Do the same for architectures resolving dependencies on
2317 the parts. While in DF mode it is better to always handle
2318 just register parts, the SF mode is different due to lack
2319 of instructions to load just part of the register. It is
2320 better to maintain the whole registers in single format
2321 to avoid problems on using packed logical operations. */
2322 (eq_attr "alternative" "6")
2324 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2326 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2328 (const_string "V4SF")
2329 (const_string "SF"))
2330 (eq_attr "alternative" "11")
2331 (const_string "DI")]
2332 (const_string "SF")))])
2334 (define_insn "*swapsf"
2335 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2336 (match_operand:SF 1 "fp_register_operand" "+f"))
2339 "reload_completed || TARGET_80387"
2341 if (STACK_TOP_P (operands[0]))
2346 [(set_attr "type" "fxch")
2347 (set_attr "mode" "SF")])
2349 (define_expand "movdf"
2350 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2351 (match_operand:DF 1 "general_operand" ""))]
2353 "ix86_expand_move (DFmode, operands); DONE;")
2355 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2356 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2357 ;; On the average, pushdf using integers can be still shorter. Allow this
2358 ;; pattern for optimize_size too.
2360 (define_insn "*pushdf_nointeger"
2361 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2362 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2363 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2365 /* This insn should be already split before reg-stack. */
2368 [(set_attr "type" "multi")
2369 (set_attr "unit" "i387,*,*,*")
2370 (set_attr "mode" "DF,SI,SI,DF")])
2372 (define_insn "*pushdf_integer"
2373 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2374 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2375 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2377 /* This insn should be already split before reg-stack. */
2380 [(set_attr "type" "multi")
2381 (set_attr "unit" "i387,*,*")
2382 (set_attr "mode" "DF,SI,DF")])
2384 ;; %%% Kill this when call knows how to work this out.
2386 [(set (match_operand:DF 0 "push_operand" "")
2387 (match_operand:DF 1 "any_fp_register_operand" ""))]
2388 "!TARGET_64BIT && reload_completed"
2389 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2390 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2394 [(set (match_operand:DF 0 "push_operand" "")
2395 (match_operand:DF 1 "any_fp_register_operand" ""))]
2396 "TARGET_64BIT && reload_completed"
2397 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2398 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2402 [(set (match_operand:DF 0 "push_operand" "")
2403 (match_operand:DF 1 "general_operand" ""))]
2406 "ix86_split_long_move (operands); DONE;")
2408 ;; Moving is usually shorter when only FP registers are used. This separate
2409 ;; movdf pattern avoids the use of integer registers for FP operations
2410 ;; when optimizing for size.
2412 (define_insn "*movdf_nointeger"
2413 [(set (match_operand:DF 0 "nonimmediate_operand"
2414 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ")
2415 (match_operand:DF 1 "general_operand"
2416 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))]
2417 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2418 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2419 && (reload_in_progress || reload_completed
2420 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2421 || GET_CODE (operands[1]) != CONST_DOUBLE
2422 || memory_operand (operands[0], DFmode))"
2424 switch (which_alternative)
2427 return output_387_reg_move (insn, operands);
2430 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2431 return "fstp%z0\t%y0";
2433 return "fst%z0\t%y0";
2436 return standard_80387_constant_opcode (operands[1]);
2442 switch (get_attr_mode (insn))
2445 return "xorps\t%0, %0";
2447 return "xorpd\t%0, %0";
2449 return "pxor\t%0, %0";
2456 switch (get_attr_mode (insn))
2459 return "movaps\t{%1, %0|%0, %1}";
2461 return "movapd\t{%1, %0|%0, %1}";
2463 return "movdqa\t{%1, %0|%0, %1}";
2465 return "movq\t{%1, %0|%0, %1}";
2467 return "movsd\t{%1, %0|%0, %1}";
2469 return "movlpd\t{%1, %0|%0, %1}";
2471 return "movlps\t{%1, %0|%0, %1}";
2480 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2482 (cond [(eq_attr "alternative" "0,1,2")
2484 (eq_attr "alternative" "3,4")
2487 /* For SSE1, we have many fewer alternatives. */
2488 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2489 (cond [(eq_attr "alternative" "5,6")
2490 (const_string "V4SF")
2492 (const_string "V2SF"))
2494 /* xorps is one byte shorter. */
2495 (eq_attr "alternative" "5")
2496 (cond [(ne (symbol_ref "optimize_size")
2498 (const_string "V4SF")
2499 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2503 (const_string "V2DF"))
2505 /* For architectures resolving dependencies on
2506 whole SSE registers use APD move to break dependency
2507 chains, otherwise use short move to avoid extra work.
2509 movaps encodes one byte shorter. */
2510 (eq_attr "alternative" "6")
2512 [(ne (symbol_ref "optimize_size")
2514 (const_string "V4SF")
2515 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2517 (const_string "V2DF")
2519 (const_string "DF"))
2520 /* For architectures resolving dependencies on register
2521 parts we may avoid extra work to zero out upper part
2523 (eq_attr "alternative" "7")
2525 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2527 (const_string "V1DF")
2528 (const_string "DF"))
2530 (const_string "DF")))])
2532 (define_insn "*movdf_integer"
2533 [(set (match_operand:DF 0 "nonimmediate_operand"
2534 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2535 (match_operand:DF 1 "general_operand"
2536 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))]
2537 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2538 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2539 && (reload_in_progress || reload_completed
2540 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2541 || GET_CODE (operands[1]) != CONST_DOUBLE
2542 || memory_operand (operands[0], DFmode))"
2544 switch (which_alternative)
2547 return output_387_reg_move (insn, operands);
2550 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2551 return "fstp%z0\t%y0";
2553 return "fst%z0\t%y0";
2556 return standard_80387_constant_opcode (operands[1]);
2563 switch (get_attr_mode (insn))
2566 return "xorps\t%0, %0";
2568 return "xorpd\t%0, %0";
2570 return "pxor\t%0, %0";
2577 switch (get_attr_mode (insn))
2580 return "movaps\t{%1, %0|%0, %1}";
2582 return "movapd\t{%1, %0|%0, %1}";
2584 return "movdqa\t{%1, %0|%0, %1}";
2586 return "movq\t{%1, %0|%0, %1}";
2588 return "movsd\t{%1, %0|%0, %1}";
2590 return "movlpd\t{%1, %0|%0, %1}";
2592 return "movlps\t{%1, %0|%0, %1}";
2601 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2603 (cond [(eq_attr "alternative" "0,1,2")
2605 (eq_attr "alternative" "3,4")
2608 /* For SSE1, we have many fewer alternatives. */
2609 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2610 (cond [(eq_attr "alternative" "5,6")
2611 (const_string "V4SF")
2613 (const_string "V2SF"))
2615 /* xorps is one byte shorter. */
2616 (eq_attr "alternative" "5")
2617 (cond [(ne (symbol_ref "optimize_size")
2619 (const_string "V4SF")
2620 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2624 (const_string "V2DF"))
2626 /* For architectures resolving dependencies on
2627 whole SSE registers use APD move to break dependency
2628 chains, otherwise use short move to avoid extra work.
2630 movaps encodes one byte shorter. */
2631 (eq_attr "alternative" "6")
2633 [(ne (symbol_ref "optimize_size")
2635 (const_string "V4SF")
2636 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2638 (const_string "V2DF")
2640 (const_string "DF"))
2641 /* For architectures resolving dependencies on register
2642 parts we may avoid extra work to zero out upper part
2644 (eq_attr "alternative" "7")
2646 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2648 (const_string "V1DF")
2649 (const_string "DF"))
2651 (const_string "DF")))])
2654 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2655 (match_operand:DF 1 "general_operand" ""))]
2657 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2658 && ! (ANY_FP_REG_P (operands[0]) ||
2659 (GET_CODE (operands[0]) == SUBREG
2660 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2661 && ! (ANY_FP_REG_P (operands[1]) ||
2662 (GET_CODE (operands[1]) == SUBREG
2663 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2665 "ix86_split_long_move (operands); DONE;")
2667 (define_insn "*swapdf"
2668 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2669 (match_operand:DF 1 "fp_register_operand" "+f"))
2672 "reload_completed || TARGET_80387"
2674 if (STACK_TOP_P (operands[0]))
2679 [(set_attr "type" "fxch")
2680 (set_attr "mode" "DF")])
2682 (define_expand "movxf"
2683 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2684 (match_operand:XF 1 "general_operand" ""))]
2686 "ix86_expand_move (XFmode, operands); DONE;")
2688 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2689 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2690 ;; Pushing using integer instructions is longer except for constants
2691 ;; and direct memory references.
2692 ;; (assuming that any given constant is pushed only once, but this ought to be
2693 ;; handled elsewhere).
2695 (define_insn "*pushxf_nointeger"
2696 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2697 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2700 /* This insn should be already split before reg-stack. */
2703 [(set_attr "type" "multi")
2704 (set_attr "unit" "i387,*,*")
2705 (set_attr "mode" "XF,SI,SI")])
2707 (define_insn "*pushxf_integer"
2708 [(set (match_operand:XF 0 "push_operand" "=<,<")
2709 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2712 /* This insn should be already split before reg-stack. */
2715 [(set_attr "type" "multi")
2716 (set_attr "unit" "i387,*")
2717 (set_attr "mode" "XF,SI")])
2720 [(set (match_operand 0 "push_operand" "")
2721 (match_operand 1 "general_operand" ""))]
2723 && (GET_MODE (operands[0]) == XFmode
2724 || GET_MODE (operands[0]) == DFmode)
2725 && !ANY_FP_REG_P (operands[1])"
2727 "ix86_split_long_move (operands); DONE;")
2730 [(set (match_operand:XF 0 "push_operand" "")
2731 (match_operand:XF 1 "any_fp_register_operand" ""))]
2733 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2734 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2735 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2738 [(set (match_operand:XF 0 "push_operand" "")
2739 (match_operand:XF 1 "any_fp_register_operand" ""))]
2741 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2742 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2743 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2745 ;; Do not use integer registers when optimizing for size
2746 (define_insn "*movxf_nointeger"
2747 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2748 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2750 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2751 && (reload_in_progress || reload_completed
2752 || GET_CODE (operands[1]) != CONST_DOUBLE
2753 || memory_operand (operands[0], XFmode))"
2755 switch (which_alternative)
2758 return output_387_reg_move (insn, operands);
2761 /* There is no non-popping store to memory for XFmode. So if
2762 we need one, follow the store with a load. */
2763 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2764 return "fstp%z0\t%y0\;fld%z0\t%y0";
2766 return "fstp%z0\t%y0";
2769 return standard_80387_constant_opcode (operands[1]);
2777 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2778 (set_attr "mode" "XF,XF,XF,SI,SI")])
2780 (define_insn "*movxf_integer"
2781 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2782 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2784 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2785 && (reload_in_progress || reload_completed
2786 || GET_CODE (operands[1]) != CONST_DOUBLE
2787 || memory_operand (operands[0], XFmode))"
2789 switch (which_alternative)
2792 return output_387_reg_move (insn, operands);
2795 /* There is no non-popping store to memory for XFmode. So if
2796 we need one, follow the store with a load. */
2797 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2798 return "fstp%z0\t%y0\;fld%z0\t%y0";
2800 return "fstp%z0\t%y0";
2803 return standard_80387_constant_opcode (operands[1]);
2812 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2813 (set_attr "mode" "XF,XF,XF,SI,SI")])
2816 [(set (match_operand 0 "nonimmediate_operand" "")
2817 (match_operand 1 "general_operand" ""))]
2819 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2820 && GET_MODE (operands[0]) == XFmode
2821 && ! (ANY_FP_REG_P (operands[0]) ||
2822 (GET_CODE (operands[0]) == SUBREG
2823 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2824 && ! (ANY_FP_REG_P (operands[1]) ||
2825 (GET_CODE (operands[1]) == SUBREG
2826 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2828 "ix86_split_long_move (operands); DONE;")
2831 [(set (match_operand 0 "register_operand" "")
2832 (match_operand 1 "memory_operand" ""))]
2834 && GET_CODE (operands[1]) == MEM
2835 && (GET_MODE (operands[0]) == XFmode
2836 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2837 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2838 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2839 [(set (match_dup 0) (match_dup 1))]
2841 rtx c = get_pool_constant (XEXP (operands[1], 0));
2842 rtx r = operands[0];
2844 if (GET_CODE (r) == SUBREG)
2849 if (!standard_sse_constant_p (c))
2852 else if (FP_REG_P (r))
2854 if (!standard_80387_constant_p (c))
2857 else if (MMX_REG_P (r))
2863 (define_insn "swapxf"
2864 [(set (match_operand:XF 0 "register_operand" "+f")
2865 (match_operand:XF 1 "register_operand" "+f"))
2870 if (STACK_TOP_P (operands[0]))
2875 [(set_attr "type" "fxch")
2876 (set_attr "mode" "XF")])
2878 (define_expand "movtf"
2879 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2880 (match_operand:TF 1 "nonimmediate_operand" ""))]
2883 ix86_expand_move (TFmode, operands);
2887 (define_insn "*movtf_internal"
2888 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2889 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2891 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2893 switch (which_alternative)
2899 if (get_attr_mode (insn) == MODE_V4SF)
2900 return "xorps\t%0, %0";
2902 return "pxor\t%0, %0";
2905 if (get_attr_mode (insn) == MODE_V4SF)
2906 return "movaps\t{%1, %0|%0, %1}";
2908 return "movdqa\t{%1, %0|%0, %1}";
2913 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2915 (cond [(eq_attr "alternative" "2,3")
2917 (ne (symbol_ref "optimize_size")
2919 (const_string "V4SF")
2920 (const_string "TI"))
2921 (eq_attr "alternative" "4")
2923 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2925 (ne (symbol_ref "optimize_size")
2927 (const_string "V4SF")
2928 (const_string "TI"))]
2929 (const_string "DI")))])
2932 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2933 (match_operand:TF 1 "general_operand" ""))]
2934 "reload_completed && !SSE_REG_P (operands[0])
2935 && !SSE_REG_P (operands[1])"
2937 "ix86_split_long_move (operands); DONE;")
2939 ;; Zero extension instructions
2941 (define_expand "zero_extendhisi2"
2942 [(set (match_operand:SI 0 "register_operand" "")
2943 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2946 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2948 operands[1] = force_reg (HImode, operands[1]);
2949 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2954 (define_insn "zero_extendhisi2_and"
2955 [(set (match_operand:SI 0 "register_operand" "=r")
2956 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2957 (clobber (reg:CC FLAGS_REG))]
2958 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2960 [(set_attr "type" "alu1")
2961 (set_attr "mode" "SI")])
2964 [(set (match_operand:SI 0 "register_operand" "")
2965 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2966 (clobber (reg:CC FLAGS_REG))]
2967 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2968 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2969 (clobber (reg:CC FLAGS_REG))])]
2972 (define_insn "*zero_extendhisi2_movzwl"
2973 [(set (match_operand:SI 0 "register_operand" "=r")
2974 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2975 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2976 "movz{wl|x}\t{%1, %0|%0, %1}"
2977 [(set_attr "type" "imovx")
2978 (set_attr "mode" "SI")])
2980 (define_expand "zero_extendqihi2"
2982 [(set (match_operand:HI 0 "register_operand" "")
2983 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2984 (clobber (reg:CC FLAGS_REG))])]
2988 (define_insn "*zero_extendqihi2_and"
2989 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2990 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2991 (clobber (reg:CC FLAGS_REG))]
2992 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2994 [(set_attr "type" "alu1")
2995 (set_attr "mode" "HI")])
2997 (define_insn "*zero_extendqihi2_movzbw_and"
2998 [(set (match_operand:HI 0 "register_operand" "=r,r")
2999 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3000 (clobber (reg:CC FLAGS_REG))]
3001 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3003 [(set_attr "type" "imovx,alu1")
3004 (set_attr "mode" "HI")])
3006 (define_insn "*zero_extendqihi2_movzbw"
3007 [(set (match_operand:HI 0 "register_operand" "=r")
3008 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3009 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3010 "movz{bw|x}\t{%1, %0|%0, %1}"
3011 [(set_attr "type" "imovx")
3012 (set_attr "mode" "HI")])
3014 ;; For the movzbw case strip only the clobber
3016 [(set (match_operand:HI 0 "register_operand" "")
3017 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3018 (clobber (reg:CC FLAGS_REG))]
3020 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3021 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3022 [(set (match_operand:HI 0 "register_operand" "")
3023 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3025 ;; When source and destination does not overlap, clear destination
3026 ;; first and then do the movb
3028 [(set (match_operand:HI 0 "register_operand" "")
3029 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3030 (clobber (reg:CC FLAGS_REG))]
3032 && ANY_QI_REG_P (operands[0])
3033 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3034 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3035 [(set (match_dup 0) (const_int 0))
3036 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3037 "operands[2] = gen_lowpart (QImode, operands[0]);")
3039 ;; Rest is handled by single and.
3041 [(set (match_operand:HI 0 "register_operand" "")
3042 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3043 (clobber (reg:CC FLAGS_REG))]
3045 && true_regnum (operands[0]) == true_regnum (operands[1])"
3046 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3047 (clobber (reg:CC FLAGS_REG))])]
3050 (define_expand "zero_extendqisi2"
3052 [(set (match_operand:SI 0 "register_operand" "")
3053 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3054 (clobber (reg:CC FLAGS_REG))])]
3058 (define_insn "*zero_extendqisi2_and"
3059 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3060 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3061 (clobber (reg:CC FLAGS_REG))]
3062 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3064 [(set_attr "type" "alu1")
3065 (set_attr "mode" "SI")])
3067 (define_insn "*zero_extendqisi2_movzbw_and"
3068 [(set (match_operand:SI 0 "register_operand" "=r,r")
3069 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3070 (clobber (reg:CC FLAGS_REG))]
3071 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3073 [(set_attr "type" "imovx,alu1")
3074 (set_attr "mode" "SI")])
3076 (define_insn "*zero_extendqisi2_movzbw"
3077 [(set (match_operand:SI 0 "register_operand" "=r")
3078 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3079 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3080 "movz{bl|x}\t{%1, %0|%0, %1}"
3081 [(set_attr "type" "imovx")
3082 (set_attr "mode" "SI")])
3084 ;; For the movzbl case strip only the clobber
3086 [(set (match_operand:SI 0 "register_operand" "")
3087 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3088 (clobber (reg:CC FLAGS_REG))]
3090 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3091 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3093 (zero_extend:SI (match_dup 1)))])
3095 ;; When source and destination does not overlap, clear destination
3096 ;; first and then do the movb
3098 [(set (match_operand:SI 0 "register_operand" "")
3099 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3100 (clobber (reg:CC FLAGS_REG))]
3102 && ANY_QI_REG_P (operands[0])
3103 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3104 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3105 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3106 [(set (match_dup 0) (const_int 0))
3107 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3108 "operands[2] = gen_lowpart (QImode, operands[0]);")
3110 ;; Rest is handled by single and.
3112 [(set (match_operand:SI 0 "register_operand" "")
3113 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3114 (clobber (reg:CC FLAGS_REG))]
3116 && true_regnum (operands[0]) == true_regnum (operands[1])"
3117 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3118 (clobber (reg:CC FLAGS_REG))])]
3121 ;; %%% Kill me once multi-word ops are sane.
3122 (define_expand "zero_extendsidi2"
3123 [(set (match_operand:DI 0 "register_operand" "=r")
3124 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3128 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3133 (define_insn "zero_extendsidi2_32"
3134 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3135 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3136 (clobber (reg:CC FLAGS_REG))]
3142 movd\t{%1, %0|%0, %1}
3143 movd\t{%1, %0|%0, %1}"
3144 [(set_attr "mode" "SI,SI,SI,DI,TI")
3145 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3147 (define_insn "zero_extendsidi2_rex64"
3148 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3149 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3152 mov\t{%k1, %k0|%k0, %k1}
3154 movd\t{%1, %0|%0, %1}
3155 movd\t{%1, %0|%0, %1}"
3156 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3157 (set_attr "mode" "SI,DI,SI,SI")])
3160 [(set (match_operand:DI 0 "memory_operand" "")
3161 (zero_extend:DI (match_dup 0)))]
3163 [(set (match_dup 4) (const_int 0))]
3164 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3167 [(set (match_operand:DI 0 "register_operand" "")
3168 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3169 (clobber (reg:CC FLAGS_REG))]
3170 "!TARGET_64BIT && reload_completed
3171 && true_regnum (operands[0]) == true_regnum (operands[1])"
3172 [(set (match_dup 4) (const_int 0))]
3173 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3176 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3177 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3178 (clobber (reg:CC FLAGS_REG))]
3179 "!TARGET_64BIT && reload_completed
3180 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3181 [(set (match_dup 3) (match_dup 1))
3182 (set (match_dup 4) (const_int 0))]
3183 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3185 (define_insn "zero_extendhidi2"
3186 [(set (match_operand:DI 0 "register_operand" "=r,r")
3187 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3190 movz{wl|x}\t{%1, %k0|%k0, %1}
3191 movz{wq|x}\t{%1, %0|%0, %1}"
3192 [(set_attr "type" "imovx")
3193 (set_attr "mode" "SI,DI")])
3195 (define_insn "zero_extendqidi2"
3196 [(set (match_operand:DI 0 "register_operand" "=r,r")
3197 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3200 movz{bl|x}\t{%1, %k0|%k0, %1}
3201 movz{bq|x}\t{%1, %0|%0, %1}"
3202 [(set_attr "type" "imovx")
3203 (set_attr "mode" "SI,DI")])
3205 ;; Sign extension instructions
3207 (define_expand "extendsidi2"
3208 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3209 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3210 (clobber (reg:CC FLAGS_REG))
3211 (clobber (match_scratch:SI 2 ""))])]
3216 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3221 (define_insn "*extendsidi2_1"
3222 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3223 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3224 (clobber (reg:CC FLAGS_REG))
3225 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3229 (define_insn "extendsidi2_rex64"
3230 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3231 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3235 movs{lq|x}\t{%1,%0|%0, %1}"
3236 [(set_attr "type" "imovx")
3237 (set_attr "mode" "DI")
3238 (set_attr "prefix_0f" "0")
3239 (set_attr "modrm" "0,1")])
3241 (define_insn "extendhidi2"
3242 [(set (match_operand:DI 0 "register_operand" "=r")
3243 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3245 "movs{wq|x}\t{%1,%0|%0, %1}"
3246 [(set_attr "type" "imovx")
3247 (set_attr "mode" "DI")])
3249 (define_insn "extendqidi2"
3250 [(set (match_operand:DI 0 "register_operand" "=r")
3251 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3253 "movs{bq|x}\t{%1,%0|%0, %1}"
3254 [(set_attr "type" "imovx")
3255 (set_attr "mode" "DI")])
3257 ;; Extend to memory case when source register does die.
3259 [(set (match_operand:DI 0 "memory_operand" "")
3260 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3261 (clobber (reg:CC FLAGS_REG))
3262 (clobber (match_operand:SI 2 "register_operand" ""))]
3264 && dead_or_set_p (insn, operands[1])
3265 && !reg_mentioned_p (operands[1], operands[0]))"
3266 [(set (match_dup 3) (match_dup 1))
3267 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3268 (clobber (reg:CC FLAGS_REG))])
3269 (set (match_dup 4) (match_dup 1))]
3270 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3272 ;; Extend to memory case when source register does not die.
3274 [(set (match_operand:DI 0 "memory_operand" "")
3275 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3276 (clobber (reg:CC FLAGS_REG))
3277 (clobber (match_operand:SI 2 "register_operand" ""))]
3281 split_di (&operands[0], 1, &operands[3], &operands[4]);
3283 emit_move_insn (operands[3], operands[1]);
3285 /* Generate a cltd if possible and doing so it profitable. */
3286 if (true_regnum (operands[1]) == 0
3287 && true_regnum (operands[2]) == 1
3288 && (optimize_size || TARGET_USE_CLTD))
3290 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3294 emit_move_insn (operands[2], operands[1]);
3295 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3297 emit_move_insn (operands[4], operands[2]);
3301 ;; Extend to register case. Optimize case where source and destination
3302 ;; registers match and cases where we can use cltd.
3304 [(set (match_operand:DI 0 "register_operand" "")
3305 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3306 (clobber (reg:CC FLAGS_REG))
3307 (clobber (match_scratch:SI 2 ""))]
3311 split_di (&operands[0], 1, &operands[3], &operands[4]);
3313 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3314 emit_move_insn (operands[3], operands[1]);
3316 /* Generate a cltd if possible and doing so it profitable. */
3317 if (true_regnum (operands[3]) == 0
3318 && (optimize_size || TARGET_USE_CLTD))
3320 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3324 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3325 emit_move_insn (operands[4], operands[1]);
3327 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3331 (define_insn "extendhisi2"
3332 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3333 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3336 switch (get_attr_prefix_0f (insn))
3339 return "{cwtl|cwde}";
3341 return "movs{wl|x}\t{%1,%0|%0, %1}";
3344 [(set_attr "type" "imovx")
3345 (set_attr "mode" "SI")
3346 (set (attr "prefix_0f")
3347 ;; movsx is short decodable while cwtl is vector decoded.
3348 (if_then_else (and (eq_attr "cpu" "!k6")
3349 (eq_attr "alternative" "0"))
3351 (const_string "1")))
3353 (if_then_else (eq_attr "prefix_0f" "0")
3355 (const_string "1")))])
3357 (define_insn "*extendhisi2_zext"
3358 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3360 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3363 switch (get_attr_prefix_0f (insn))
3366 return "{cwtl|cwde}";
3368 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3371 [(set_attr "type" "imovx")
3372 (set_attr "mode" "SI")
3373 (set (attr "prefix_0f")
3374 ;; movsx is short decodable while cwtl is vector decoded.
3375 (if_then_else (and (eq_attr "cpu" "!k6")
3376 (eq_attr "alternative" "0"))
3378 (const_string "1")))
3380 (if_then_else (eq_attr "prefix_0f" "0")
3382 (const_string "1")))])
3384 (define_insn "extendqihi2"
3385 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3386 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3389 switch (get_attr_prefix_0f (insn))
3392 return "{cbtw|cbw}";
3394 return "movs{bw|x}\t{%1,%0|%0, %1}";
3397 [(set_attr "type" "imovx")
3398 (set_attr "mode" "HI")
3399 (set (attr "prefix_0f")
3400 ;; movsx is short decodable while cwtl is vector decoded.
3401 (if_then_else (and (eq_attr "cpu" "!k6")
3402 (eq_attr "alternative" "0"))
3404 (const_string "1")))
3406 (if_then_else (eq_attr "prefix_0f" "0")
3408 (const_string "1")))])
3410 (define_insn "extendqisi2"
3411 [(set (match_operand:SI 0 "register_operand" "=r")
3412 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3414 "movs{bl|x}\t{%1,%0|%0, %1}"
3415 [(set_attr "type" "imovx")
3416 (set_attr "mode" "SI")])
3418 (define_insn "*extendqisi2_zext"
3419 [(set (match_operand:DI 0 "register_operand" "=r")
3421 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3423 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3424 [(set_attr "type" "imovx")
3425 (set_attr "mode" "SI")])
3427 ;; Conversions between float and double.
3429 ;; These are all no-ops in the model used for the 80387. So just
3432 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3433 (define_insn "*dummy_extendsfdf2"
3434 [(set (match_operand:DF 0 "push_operand" "=<")
3435 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3440 [(set (match_operand:DF 0 "push_operand" "")
3441 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3443 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3444 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3447 [(set (match_operand:DF 0 "push_operand" "")
3448 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3450 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3451 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3453 (define_insn "*dummy_extendsfxf2"
3454 [(set (match_operand:XF 0 "push_operand" "=<")
3455 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3460 [(set (match_operand:XF 0 "push_operand" "")
3461 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3463 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3464 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3465 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3468 [(set (match_operand:XF 0 "push_operand" "")
3469 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3471 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3472 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3473 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3476 [(set (match_operand:XF 0 "push_operand" "")
3477 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3479 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3480 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3481 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3484 [(set (match_operand:XF 0 "push_operand" "")
3485 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3487 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3488 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3489 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3491 (define_expand "extendsfdf2"
3492 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3493 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3494 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3496 /* ??? Needed for compress_float_constant since all fp constants
3497 are LEGITIMATE_CONSTANT_P. */
3498 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3499 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3500 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3501 operands[1] = force_reg (SFmode, operands[1]);
3504 (define_insn "*extendsfdf2_mixed"
3505 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3506 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3507 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3508 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3510 switch (which_alternative)
3513 return output_387_reg_move (insn, operands);
3516 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3517 return "fstp%z0\t%y0";
3519 return "fst%z0\t%y0";
3522 return "cvtss2sd\t{%1, %0|%0, %1}";
3528 [(set_attr "type" "fmov,fmov,ssecvt")
3529 (set_attr "mode" "SF,XF,DF")])
3531 (define_insn "*extendsfdf2_sse"
3532 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3533 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3534 "TARGET_SSE2 && TARGET_SSE_MATH
3535 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3536 "cvtss2sd\t{%1, %0|%0, %1}"
3537 [(set_attr "type" "ssecvt")
3538 (set_attr "mode" "DF")])
3540 (define_insn "*extendsfdf2_i387"
3541 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3542 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3544 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3546 switch (which_alternative)
3549 return output_387_reg_move (insn, operands);
3552 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3553 return "fstp%z0\t%y0";
3555 return "fst%z0\t%y0";
3561 [(set_attr "type" "fmov")
3562 (set_attr "mode" "SF,XF")])
3564 (define_expand "extendsfxf2"
3565 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3566 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3569 /* ??? Needed for compress_float_constant since all fp constants
3570 are LEGITIMATE_CONSTANT_P. */
3571 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3572 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3573 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3574 operands[1] = force_reg (SFmode, operands[1]);
3577 (define_insn "*extendsfxf2_i387"
3578 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3579 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3581 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3583 switch (which_alternative)
3586 return output_387_reg_move (insn, operands);
3589 /* There is no non-popping store to memory for XFmode. So if
3590 we need one, follow the store with a load. */
3591 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3592 return "fstp%z0\t%y0";
3594 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3600 [(set_attr "type" "fmov")
3601 (set_attr "mode" "SF,XF")])
3603 (define_expand "extenddfxf2"
3604 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3605 (float_extend:XF (match_operand:DF 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)
3611 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3612 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3613 operands[1] = force_reg (DFmode, operands[1]);
3616 (define_insn "*extenddfxf2_i387"
3617 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3618 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3620 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3622 switch (which_alternative)
3625 return output_387_reg_move (insn, operands);
3628 /* There is no non-popping store to memory for XFmode. So if
3629 we need one, follow the store with a load. */
3630 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3631 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3633 return "fstp%z0\t%y0";
3639 [(set_attr "type" "fmov")
3640 (set_attr "mode" "DF,XF")])
3642 ;; %%% This seems bad bad news.
3643 ;; This cannot output into an f-reg because there is no way to be sure
3644 ;; of truncating in that case. Otherwise this is just like a simple move
3645 ;; insn. So we pretend we can output to a reg in order to get better
3646 ;; register preferencing, but we really use a stack slot.
3648 ;; Conversion from DFmode to SFmode.
3650 (define_expand "truncdfsf2"
3651 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3653 (match_operand:DF 1 "nonimmediate_operand" "")))]
3654 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3656 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3657 operands[1] = force_reg (DFmode, operands[1]);
3659 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3661 else if (flag_unsafe_math_optimizations)
3665 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3666 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3671 (define_expand "truncdfsf2_with_temp"
3672 [(parallel [(set (match_operand:SF 0 "" "")
3673 (float_truncate:SF (match_operand:DF 1 "" "")))
3674 (clobber (match_operand:SF 2 "" ""))])]
3677 (define_insn "*truncdfsf_fast_mixed"
3678 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3680 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3681 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3683 switch (which_alternative)
3686 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3687 return "fstp%z0\t%y0";
3689 return "fst%z0\t%y0";
3691 return output_387_reg_move (insn, operands);
3693 return "cvtsd2ss\t{%1, %0|%0, %1}";
3698 [(set_attr "type" "fmov,fmov,ssecvt")
3699 (set_attr "mode" "SF")])
3701 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3702 ;; because nothing we do here is unsafe.
3703 (define_insn "*truncdfsf_fast_sse"
3704 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3706 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3707 "TARGET_SSE2 && TARGET_SSE_MATH"
3708 "cvtsd2ss\t{%1, %0|%0, %1}"
3709 [(set_attr "type" "ssecvt")
3710 (set_attr "mode" "SF")])
3712 (define_insn "*truncdfsf_fast_i387"
3713 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3715 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3716 "TARGET_80387 && flag_unsafe_math_optimizations"
3717 "* return output_387_reg_move (insn, operands);"
3718 [(set_attr "type" "fmov")
3719 (set_attr "mode" "SF")])
3721 (define_insn "*truncdfsf_mixed"
3722 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3724 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3725 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3726 "TARGET_MIX_SSE_I387"
3728 switch (which_alternative)
3731 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3732 return "fstp%z0\t%y0";
3734 return "fst%z0\t%y0";
3738 return "cvtsd2ss\t{%1, %0|%0, %1}";
3743 [(set_attr "type" "fmov,multi,ssecvt")
3744 (set_attr "unit" "*,i387,*")
3745 (set_attr "mode" "SF")])
3747 (define_insn "*truncdfsf_i387"
3748 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3750 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3751 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3754 switch (which_alternative)
3757 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3758 return "fstp%z0\t%y0";
3760 return "fst%z0\t%y0";
3767 [(set_attr "type" "fmov,multi")
3768 (set_attr "unit" "*,i387")
3769 (set_attr "mode" "SF")])
3771 (define_insn "*truncdfsf2_i387_1"
3772 [(set (match_operand:SF 0 "memory_operand" "=m")
3774 (match_operand:DF 1 "register_operand" "f")))]
3776 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3777 && !TARGET_MIX_SSE_I387"
3779 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3780 return "fstp%z0\t%y0";
3782 return "fst%z0\t%y0";
3784 [(set_attr "type" "fmov")
3785 (set_attr "mode" "SF")])
3788 [(set (match_operand:SF 0 "register_operand" "")
3790 (match_operand:DF 1 "fp_register_operand" "")))
3791 (clobber (match_operand 2 "" ""))]
3793 [(set (match_dup 2) (match_dup 1))
3794 (set (match_dup 0) (match_dup 2))]
3796 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3799 ;; Conversion from XFmode to SFmode.
3801 (define_expand "truncxfsf2"
3802 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3804 (match_operand:XF 1 "register_operand" "")))
3805 (clobber (match_dup 2))])]
3808 if (flag_unsafe_math_optimizations)
3810 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3811 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3812 if (reg != operands[0])
3813 emit_move_insn (operands[0], reg);
3817 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3820 (define_insn "*truncxfsf2_mixed"
3821 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3823 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3824 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3825 "TARGET_MIX_SSE_I387"
3827 gcc_assert (!which_alternative);
3828 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3829 return "fstp%z0\t%y0";
3831 return "fst%z0\t%y0";
3833 [(set_attr "type" "fmov,multi,multi,multi")
3834 (set_attr "unit" "*,i387,i387,i387")
3835 (set_attr "mode" "SF")])
3837 (define_insn "truncxfsf2_i387_noop"
3838 [(set (match_operand:SF 0 "register_operand" "=f")
3839 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3840 "TARGET_80387 && flag_unsafe_math_optimizations"
3842 return output_387_reg_move (insn, operands);
3844 [(set_attr "type" "fmov")
3845 (set_attr "mode" "SF")])
3847 (define_insn "*truncxfsf2_i387"
3848 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3850 (match_operand:XF 1 "register_operand" "f,f,f")))
3851 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3854 gcc_assert (!which_alternative);
3855 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3856 return "fstp%z0\t%y0";
3858 return "fst%z0\t%y0";
3860 [(set_attr "type" "fmov,multi,multi")
3861 (set_attr "unit" "*,i387,i387")
3862 (set_attr "mode" "SF")])
3864 (define_insn "*truncxfsf2_i387_1"
3865 [(set (match_operand:SF 0 "memory_operand" "=m")
3867 (match_operand:XF 1 "register_operand" "f")))]
3870 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3871 return "fstp%z0\t%y0";
3873 return "fst%z0\t%y0";
3875 [(set_attr "type" "fmov")
3876 (set_attr "mode" "SF")])
3879 [(set (match_operand:SF 0 "register_operand" "")
3881 (match_operand:XF 1 "register_operand" "")))
3882 (clobber (match_operand:SF 2 "memory_operand" ""))]
3883 "TARGET_80387 && reload_completed"
3884 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3885 (set (match_dup 0) (match_dup 2))]
3889 [(set (match_operand:SF 0 "memory_operand" "")
3891 (match_operand:XF 1 "register_operand" "")))
3892 (clobber (match_operand:SF 2 "memory_operand" ""))]
3894 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3897 ;; Conversion from XFmode to DFmode.
3899 (define_expand "truncxfdf2"
3900 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3902 (match_operand:XF 1 "register_operand" "")))
3903 (clobber (match_dup 2))])]
3906 if (flag_unsafe_math_optimizations)
3908 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3909 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3910 if (reg != operands[0])
3911 emit_move_insn (operands[0], reg);
3915 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3918 (define_insn "*truncxfdf2_mixed"
3919 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3921 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3922 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3923 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3925 gcc_assert (!which_alternative);
3926 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3927 return "fstp%z0\t%y0";
3929 return "fst%z0\t%y0";
3931 [(set_attr "type" "fmov,multi,multi,multi")
3932 (set_attr "unit" "*,i387,i387,i387")
3933 (set_attr "mode" "DF")])
3935 (define_insn "truncxfdf2_i387_noop"
3936 [(set (match_operand:DF 0 "register_operand" "=f")
3937 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3938 "TARGET_80387 && flag_unsafe_math_optimizations"
3940 return output_387_reg_move (insn, operands);
3942 [(set_attr "type" "fmov")
3943 (set_attr "mode" "DF")])
3945 (define_insn "*truncxfdf2_i387"
3946 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3948 (match_operand:XF 1 "register_operand" "f,f,f")))
3949 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3952 gcc_assert (!which_alternative);
3953 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3954 return "fstp%z0\t%y0";
3956 return "fst%z0\t%y0";
3958 [(set_attr "type" "fmov,multi,multi")
3959 (set_attr "unit" "*,i387,i387")
3960 (set_attr "mode" "DF")])
3962 (define_insn "*truncxfdf2_i387_1"
3963 [(set (match_operand:DF 0 "memory_operand" "=m")
3965 (match_operand:XF 1 "register_operand" "f")))]
3968 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3969 return "fstp%z0\t%y0";
3971 return "fst%z0\t%y0";
3973 [(set_attr "type" "fmov")
3974 (set_attr "mode" "DF")])
3977 [(set (match_operand:DF 0 "register_operand" "")
3979 (match_operand:XF 1 "register_operand" "")))
3980 (clobber (match_operand:DF 2 "memory_operand" ""))]
3981 "TARGET_80387 && reload_completed"
3982 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3983 (set (match_dup 0) (match_dup 2))]
3987 [(set (match_operand:DF 0 "memory_operand" "")
3989 (match_operand:XF 1 "register_operand" "")))
3990 (clobber (match_operand:DF 2 "memory_operand" ""))]
3992 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3995 ;; Signed conversion to DImode.
3997 (define_expand "fix_truncxfdi2"
3998 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3999 (fix:DI (match_operand:XF 1 "register_operand" "")))
4000 (clobber (reg:CC FLAGS_REG))])]
4005 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4010 (define_expand "fix_trunc<mode>di2"
4011 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4012 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4013 (clobber (reg:CC FLAGS_REG))])]
4014 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4017 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4019 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4022 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4024 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4025 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4026 if (out != operands[0])
4027 emit_move_insn (operands[0], out);
4032 ;; Signed conversion to SImode.
4034 (define_expand "fix_truncxfsi2"
4035 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4036 (fix:SI (match_operand:XF 1 "register_operand" "")))
4037 (clobber (reg:CC FLAGS_REG))])]
4042 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4047 (define_expand "fix_trunc<mode>si2"
4048 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4049 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4050 (clobber (reg:CC FLAGS_REG))])]
4051 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4054 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4056 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4059 if (SSE_FLOAT_MODE_P (<MODE>mode))
4061 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4062 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4063 if (out != operands[0])
4064 emit_move_insn (operands[0], out);
4069 ;; Signed conversion to HImode.
4071 (define_expand "fix_trunc<mode>hi2"
4072 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4073 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4074 (clobber (reg:CC FLAGS_REG))])]
4076 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4080 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4085 ;; When SSE is available, it is always faster to use it!
4086 (define_insn "fix_truncsfdi_sse"
4087 [(set (match_operand:DI 0 "register_operand" "=r,r")
4088 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4089 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4090 "cvttss2si{q}\t{%1, %0|%0, %1}"
4091 [(set_attr "type" "sseicvt")
4092 (set_attr "mode" "SF")
4093 (set_attr "athlon_decode" "double,vector")])
4095 (define_insn "fix_truncdfdi_sse"
4096 [(set (match_operand:DI 0 "register_operand" "=r,r")
4097 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4098 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4099 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4100 [(set_attr "type" "sseicvt")
4101 (set_attr "mode" "DF")
4102 (set_attr "athlon_decode" "double,vector")])
4104 (define_insn "fix_truncsfsi_sse"
4105 [(set (match_operand:SI 0 "register_operand" "=r,r")
4106 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4107 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4108 "cvttss2si\t{%1, %0|%0, %1}"
4109 [(set_attr "type" "sseicvt")
4110 (set_attr "mode" "DF")
4111 (set_attr "athlon_decode" "double,vector")])
4113 (define_insn "fix_truncdfsi_sse"
4114 [(set (match_operand:SI 0 "register_operand" "=r,r")
4115 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4116 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4117 "cvttsd2si\t{%1, %0|%0, %1}"
4118 [(set_attr "type" "sseicvt")
4119 (set_attr "mode" "DF")
4120 (set_attr "athlon_decode" "double,vector")])
4122 ;; Avoid vector decoded forms of the instruction.
4124 [(match_scratch:DF 2 "Y")
4125 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4126 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4127 "TARGET_K8 && !optimize_size"
4128 [(set (match_dup 2) (match_dup 1))
4129 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4133 [(match_scratch:SF 2 "x")
4134 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4135 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4136 "TARGET_K8 && !optimize_size"
4137 [(set (match_dup 2) (match_dup 1))
4138 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4141 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4142 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4143 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4144 "TARGET_80387 && TARGET_FISTTP
4145 && FLOAT_MODE_P (GET_MODE (operands[1]))
4146 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4147 && (TARGET_64BIT || <MODE>mode != DImode))
4149 && !(reload_completed || reload_in_progress)"
4154 if (memory_operand (operands[0], VOIDmode))
4155 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4158 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4159 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4165 [(set_attr "type" "fisttp")
4166 (set_attr "mode" "<MODE>")])
4168 (define_insn "fix_trunc<mode>_i387_fisttp"
4169 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4170 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4171 (clobber (match_scratch:XF 2 "=&1f"))]
4172 "TARGET_80387 && TARGET_FISTTP
4173 && FLOAT_MODE_P (GET_MODE (operands[1]))
4174 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4175 && (TARGET_64BIT || <MODE>mode != DImode))
4176 && TARGET_SSE_MATH)"
4177 "* return output_fix_trunc (insn, operands, 1);"
4178 [(set_attr "type" "fisttp")
4179 (set_attr "mode" "<MODE>")])
4181 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4182 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4183 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4184 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4185 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4186 "TARGET_80387 && TARGET_FISTTP
4187 && FLOAT_MODE_P (GET_MODE (operands[1]))
4188 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4189 && (TARGET_64BIT || <MODE>mode != DImode))
4190 && TARGET_SSE_MATH)"
4192 [(set_attr "type" "fisttp")
4193 (set_attr "mode" "<MODE>")])
4196 [(set (match_operand:X87MODEI 0 "register_operand" "")
4197 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4198 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4199 (clobber (match_scratch 3 ""))]
4201 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4202 (clobber (match_dup 3))])
4203 (set (match_dup 0) (match_dup 2))]
4207 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4208 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4209 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4210 (clobber (match_scratch 3 ""))]
4212 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4213 (clobber (match_dup 3))])]
4216 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4217 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4218 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4219 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4220 ;; function in i386.c.
4221 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4222 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4223 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4224 (clobber (reg:CC FLAGS_REG))]
4225 "TARGET_80387 && !TARGET_FISTTP
4226 && FLOAT_MODE_P (GET_MODE (operands[1]))
4227 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4228 && (TARGET_64BIT || <MODE>mode != DImode))
4229 && !(reload_completed || reload_in_progress)"
4234 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4236 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4237 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4238 if (memory_operand (operands[0], VOIDmode))
4239 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4240 operands[2], operands[3]));
4243 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4244 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4245 operands[2], operands[3],
4250 [(set_attr "type" "fistp")
4251 (set_attr "i387_cw" "trunc")
4252 (set_attr "mode" "<MODE>")])
4254 (define_insn "fix_truncdi_i387"
4255 [(set (match_operand:DI 0 "memory_operand" "=m")
4256 (fix:DI (match_operand 1 "register_operand" "f")))
4257 (use (match_operand:HI 2 "memory_operand" "m"))
4258 (use (match_operand:HI 3 "memory_operand" "m"))
4259 (clobber (match_scratch:XF 4 "=&1f"))]
4260 "TARGET_80387 && !TARGET_FISTTP
4261 && FLOAT_MODE_P (GET_MODE (operands[1]))
4262 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4263 "* return output_fix_trunc (insn, operands, 0);"
4264 [(set_attr "type" "fistp")
4265 (set_attr "i387_cw" "trunc")
4266 (set_attr "mode" "DI")])
4268 (define_insn "fix_truncdi_i387_with_temp"
4269 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4270 (fix:DI (match_operand 1 "register_operand" "f,f")))
4271 (use (match_operand:HI 2 "memory_operand" "m,m"))
4272 (use (match_operand:HI 3 "memory_operand" "m,m"))
4273 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4274 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4275 "TARGET_80387 && !TARGET_FISTTP
4276 && FLOAT_MODE_P (GET_MODE (operands[1]))
4277 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4279 [(set_attr "type" "fistp")
4280 (set_attr "i387_cw" "trunc")
4281 (set_attr "mode" "DI")])
4284 [(set (match_operand:DI 0 "register_operand" "")
4285 (fix:DI (match_operand 1 "register_operand" "")))
4286 (use (match_operand:HI 2 "memory_operand" ""))
4287 (use (match_operand:HI 3 "memory_operand" ""))
4288 (clobber (match_operand:DI 4 "memory_operand" ""))
4289 (clobber (match_scratch 5 ""))]
4291 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4294 (clobber (match_dup 5))])
4295 (set (match_dup 0) (match_dup 4))]
4299 [(set (match_operand:DI 0 "memory_operand" "")
4300 (fix:DI (match_operand 1 "register_operand" "")))
4301 (use (match_operand:HI 2 "memory_operand" ""))
4302 (use (match_operand:HI 3 "memory_operand" ""))
4303 (clobber (match_operand:DI 4 "memory_operand" ""))
4304 (clobber (match_scratch 5 ""))]
4306 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4309 (clobber (match_dup 5))])]
4312 (define_insn "fix_trunc<mode>_i387"
4313 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4314 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4315 (use (match_operand:HI 2 "memory_operand" "m"))
4316 (use (match_operand:HI 3 "memory_operand" "m"))]
4317 "TARGET_80387 && !TARGET_FISTTP
4318 && FLOAT_MODE_P (GET_MODE (operands[1]))
4319 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4320 "* return output_fix_trunc (insn, operands, 0);"
4321 [(set_attr "type" "fistp")
4322 (set_attr "i387_cw" "trunc")
4323 (set_attr "mode" "<MODE>")])
4325 (define_insn "fix_trunc<mode>_i387_with_temp"
4326 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4327 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4328 (use (match_operand:HI 2 "memory_operand" "m,m"))
4329 (use (match_operand:HI 3 "memory_operand" "m,m"))
4330 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4331 "TARGET_80387 && !TARGET_FISTTP
4332 && FLOAT_MODE_P (GET_MODE (operands[1]))
4333 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4335 [(set_attr "type" "fistp")
4336 (set_attr "i387_cw" "trunc")
4337 (set_attr "mode" "<MODE>")])
4340 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4341 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4342 (use (match_operand:HI 2 "memory_operand" ""))
4343 (use (match_operand:HI 3 "memory_operand" ""))
4344 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4346 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4348 (use (match_dup 3))])
4349 (set (match_dup 0) (match_dup 4))]
4353 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4354 (fix:X87MODEI12 (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:X87MODEI12 4 "memory_operand" ""))]
4359 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4361 (use (match_dup 3))])]
4364 (define_insn "x86_fnstcw_1"
4365 [(set (match_operand:HI 0 "memory_operand" "=m")
4366 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4369 [(set_attr "length" "2")
4370 (set_attr "mode" "HI")
4371 (set_attr "unit" "i387")])
4373 (define_insn "x86_fldcw_1"
4374 [(set (reg:HI FPSR_REG)
4375 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4378 [(set_attr "length" "2")
4379 (set_attr "mode" "HI")
4380 (set_attr "unit" "i387")
4381 (set_attr "athlon_decode" "vector")])
4383 ;; Conversion between fixed point and floating point.
4385 ;; Even though we only accept memory inputs, the backend _really_
4386 ;; wants to be able to do this between registers.
4388 (define_expand "floathisf2"
4389 [(set (match_operand:SF 0 "register_operand" "")
4390 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4391 "TARGET_80387 || TARGET_SSE_MATH"
4393 if (TARGET_SSE_MATH)
4395 emit_insn (gen_floatsisf2 (operands[0],
4396 convert_to_mode (SImode, operands[1], 0)));
4401 (define_insn "*floathisf2_i387"
4402 [(set (match_operand:SF 0 "register_operand" "=f,f")
4403 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4404 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4408 [(set_attr "type" "fmov,multi")
4409 (set_attr "mode" "SF")
4410 (set_attr "unit" "*,i387")
4411 (set_attr "fp_int_src" "true")])
4413 (define_expand "floatsisf2"
4414 [(set (match_operand:SF 0 "register_operand" "")
4415 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4416 "TARGET_80387 || TARGET_SSE_MATH"
4419 (define_insn "*floatsisf2_mixed"
4420 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4421 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4422 "TARGET_MIX_SSE_I387"
4426 cvtsi2ss\t{%1, %0|%0, %1}
4427 cvtsi2ss\t{%1, %0|%0, %1}"
4428 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4429 (set_attr "mode" "SF")
4430 (set_attr "unit" "*,i387,*,*")
4431 (set_attr "athlon_decode" "*,*,vector,double")
4432 (set_attr "fp_int_src" "true")])
4434 (define_insn "*floatsisf2_sse"
4435 [(set (match_operand:SF 0 "register_operand" "=x,x")
4436 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4438 "cvtsi2ss\t{%1, %0|%0, %1}"
4439 [(set_attr "type" "sseicvt")
4440 (set_attr "mode" "SF")
4441 (set_attr "athlon_decode" "vector,double")
4442 (set_attr "fp_int_src" "true")])
4444 (define_insn "*floatsisf2_i387"
4445 [(set (match_operand:SF 0 "register_operand" "=f,f")
4446 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4451 [(set_attr "type" "fmov,multi")
4452 (set_attr "mode" "SF")
4453 (set_attr "unit" "*,i387")
4454 (set_attr "fp_int_src" "true")])
4456 (define_expand "floatdisf2"
4457 [(set (match_operand:SF 0 "register_operand" "")
4458 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4459 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4462 (define_insn "*floatdisf2_mixed"
4463 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4464 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4465 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4469 cvtsi2ss{q}\t{%1, %0|%0, %1}
4470 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4471 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4472 (set_attr "mode" "SF")
4473 (set_attr "unit" "*,i387,*,*")
4474 (set_attr "athlon_decode" "*,*,vector,double")
4475 (set_attr "fp_int_src" "true")])
4477 (define_insn "*floatdisf2_sse"
4478 [(set (match_operand:SF 0 "register_operand" "=x,x")
4479 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4480 "TARGET_64BIT && TARGET_SSE_MATH"
4481 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4482 [(set_attr "type" "sseicvt")
4483 (set_attr "mode" "SF")
4484 (set_attr "athlon_decode" "vector,double")
4485 (set_attr "fp_int_src" "true")])
4487 (define_insn "*floatdisf2_i387"
4488 [(set (match_operand:SF 0 "register_operand" "=f,f")
4489 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4494 [(set_attr "type" "fmov,multi")
4495 (set_attr "mode" "SF")
4496 (set_attr "unit" "*,i387")
4497 (set_attr "fp_int_src" "true")])
4499 (define_expand "floathidf2"
4500 [(set (match_operand:DF 0 "register_operand" "")
4501 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4502 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4504 if (TARGET_SSE2 && TARGET_SSE_MATH)
4506 emit_insn (gen_floatsidf2 (operands[0],
4507 convert_to_mode (SImode, operands[1], 0)));
4512 (define_insn "*floathidf2_i387"
4513 [(set (match_operand:DF 0 "register_operand" "=f,f")
4514 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4515 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4519 [(set_attr "type" "fmov,multi")
4520 (set_attr "mode" "DF")
4521 (set_attr "unit" "*,i387")
4522 (set_attr "fp_int_src" "true")])
4524 (define_expand "floatsidf2"
4525 [(set (match_operand:DF 0 "register_operand" "")
4526 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4527 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4530 (define_insn "*floatsidf2_mixed"
4531 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4532 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4533 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4537 cvtsi2sd\t{%1, %0|%0, %1}
4538 cvtsi2sd\t{%1, %0|%0, %1}"
4539 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4540 (set_attr "mode" "DF")
4541 (set_attr "unit" "*,i387,*,*")
4542 (set_attr "athlon_decode" "*,*,double,direct")
4543 (set_attr "fp_int_src" "true")])
4545 (define_insn "*floatsidf2_sse"
4546 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4547 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4548 "TARGET_SSE2 && TARGET_SSE_MATH"
4549 "cvtsi2sd\t{%1, %0|%0, %1}"
4550 [(set_attr "type" "sseicvt")
4551 (set_attr "mode" "DF")
4552 (set_attr "athlon_decode" "double,direct")
4553 (set_attr "fp_int_src" "true")])
4555 (define_insn "*floatsidf2_i387"
4556 [(set (match_operand:DF 0 "register_operand" "=f,f")
4557 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4562 [(set_attr "type" "fmov,multi")
4563 (set_attr "mode" "DF")
4564 (set_attr "unit" "*,i387")
4565 (set_attr "fp_int_src" "true")])
4567 (define_expand "floatdidf2"
4568 [(set (match_operand:DF 0 "register_operand" "")
4569 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4570 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4573 (define_insn "*floatdidf2_mixed"
4574 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4575 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4576 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4580 cvtsi2sd{q}\t{%1, %0|%0, %1}
4581 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4582 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4583 (set_attr "mode" "DF")
4584 (set_attr "unit" "*,i387,*,*")
4585 (set_attr "athlon_decode" "*,*,double,direct")
4586 (set_attr "fp_int_src" "true")])
4588 (define_insn "*floatdidf2_sse"
4589 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4590 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4591 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4592 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4593 [(set_attr "type" "sseicvt")
4594 (set_attr "mode" "DF")
4595 (set_attr "athlon_decode" "double,direct")
4596 (set_attr "fp_int_src" "true")])
4598 (define_insn "*floatdidf2_i387"
4599 [(set (match_operand:DF 0 "register_operand" "=f,f")
4600 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4605 [(set_attr "type" "fmov,multi")
4606 (set_attr "mode" "DF")
4607 (set_attr "unit" "*,i387")
4608 (set_attr "fp_int_src" "true")])
4610 (define_insn "floathixf2"
4611 [(set (match_operand:XF 0 "register_operand" "=f,f")
4612 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4617 [(set_attr "type" "fmov,multi")
4618 (set_attr "mode" "XF")
4619 (set_attr "unit" "*,i387")
4620 (set_attr "fp_int_src" "true")])
4622 (define_insn "floatsixf2"
4623 [(set (match_operand:XF 0 "register_operand" "=f,f")
4624 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4629 [(set_attr "type" "fmov,multi")
4630 (set_attr "mode" "XF")
4631 (set_attr "unit" "*,i387")
4632 (set_attr "fp_int_src" "true")])
4634 (define_insn "floatdixf2"
4635 [(set (match_operand:XF 0 "register_operand" "=f,f")
4636 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4641 [(set_attr "type" "fmov,multi")
4642 (set_attr "mode" "XF")
4643 (set_attr "unit" "*,i387")
4644 (set_attr "fp_int_src" "true")])
4646 ;; %%% Kill these when reload knows how to do it.
4648 [(set (match_operand 0 "fp_register_operand" "")
4649 (float (match_operand 1 "register_operand" "")))]
4652 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4655 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4656 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4657 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4658 ix86_free_from_memory (GET_MODE (operands[1]));
4662 (define_expand "floatunssisf2"
4663 [(use (match_operand:SF 0 "register_operand" ""))
4664 (use (match_operand:SI 1 "register_operand" ""))]
4665 "!TARGET_64BIT && TARGET_SSE_MATH"
4666 "x86_emit_floatuns (operands); DONE;")
4668 (define_expand "floatunsdisf2"
4669 [(use (match_operand:SF 0 "register_operand" ""))
4670 (use (match_operand:DI 1 "register_operand" ""))]
4671 "TARGET_64BIT && TARGET_SSE_MATH"
4672 "x86_emit_floatuns (operands); DONE;")
4674 (define_expand "floatunsdidf2"
4675 [(use (match_operand:DF 0 "register_operand" ""))
4676 (use (match_operand:DI 1 "register_operand" ""))]
4677 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4678 "x86_emit_floatuns (operands); DONE;")
4680 ;; SSE extract/set expanders
4685 ;; %%% splits for addsidi3
4686 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4687 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4688 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4690 (define_expand "adddi3"
4691 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4692 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4693 (match_operand:DI 2 "x86_64_general_operand" "")))
4694 (clobber (reg:CC FLAGS_REG))]
4696 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4698 (define_insn "*adddi3_1"
4699 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4700 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4701 (match_operand:DI 2 "general_operand" "roiF,riF")))
4702 (clobber (reg:CC FLAGS_REG))]
4703 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4707 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4708 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4709 (match_operand:DI 2 "general_operand" "")))
4710 (clobber (reg:CC FLAGS_REG))]
4711 "!TARGET_64BIT && reload_completed"
4712 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4714 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4715 (parallel [(set (match_dup 3)
4716 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4719 (clobber (reg:CC FLAGS_REG))])]
4720 "split_di (operands+0, 1, operands+0, operands+3);
4721 split_di (operands+1, 1, operands+1, operands+4);
4722 split_di (operands+2, 1, operands+2, operands+5);")
4724 (define_insn "adddi3_carry_rex64"
4725 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4726 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4727 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4728 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4729 (clobber (reg:CC FLAGS_REG))]
4730 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4731 "adc{q}\t{%2, %0|%0, %2}"
4732 [(set_attr "type" "alu")
4733 (set_attr "pent_pair" "pu")
4734 (set_attr "mode" "DI")])
4736 (define_insn "*adddi3_cc_rex64"
4737 [(set (reg:CC FLAGS_REG)
4738 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4739 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4741 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4742 (plus:DI (match_dup 1) (match_dup 2)))]
4743 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4744 "add{q}\t{%2, %0|%0, %2}"
4745 [(set_attr "type" "alu")
4746 (set_attr "mode" "DI")])
4748 (define_insn "addqi3_carry"
4749 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4750 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4751 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4752 (match_operand:QI 2 "general_operand" "qi,qm")))
4753 (clobber (reg:CC FLAGS_REG))]
4754 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4755 "adc{b}\t{%2, %0|%0, %2}"
4756 [(set_attr "type" "alu")
4757 (set_attr "pent_pair" "pu")
4758 (set_attr "mode" "QI")])
4760 (define_insn "addhi3_carry"
4761 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4762 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4763 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4764 (match_operand:HI 2 "general_operand" "ri,rm")))
4765 (clobber (reg:CC FLAGS_REG))]
4766 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4767 "adc{w}\t{%2, %0|%0, %2}"
4768 [(set_attr "type" "alu")
4769 (set_attr "pent_pair" "pu")
4770 (set_attr "mode" "HI")])
4772 (define_insn "addsi3_carry"
4773 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4774 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4775 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4776 (match_operand:SI 2 "general_operand" "ri,rm")))
4777 (clobber (reg:CC FLAGS_REG))]
4778 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4779 "adc{l}\t{%2, %0|%0, %2}"
4780 [(set_attr "type" "alu")
4781 (set_attr "pent_pair" "pu")
4782 (set_attr "mode" "SI")])
4784 (define_insn "*addsi3_carry_zext"
4785 [(set (match_operand:DI 0 "register_operand" "=r")
4787 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4788 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4789 (match_operand:SI 2 "general_operand" "rim"))))
4790 (clobber (reg:CC FLAGS_REG))]
4791 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4792 "adc{l}\t{%2, %k0|%k0, %2}"
4793 [(set_attr "type" "alu")
4794 (set_attr "pent_pair" "pu")
4795 (set_attr "mode" "SI")])
4797 (define_insn "*addsi3_cc"
4798 [(set (reg:CC FLAGS_REG)
4799 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4800 (match_operand:SI 2 "general_operand" "ri,rm")]
4802 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4803 (plus:SI (match_dup 1) (match_dup 2)))]
4804 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4805 "add{l}\t{%2, %0|%0, %2}"
4806 [(set_attr "type" "alu")
4807 (set_attr "mode" "SI")])
4809 (define_insn "addqi3_cc"
4810 [(set (reg:CC FLAGS_REG)
4811 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4812 (match_operand:QI 2 "general_operand" "qi,qm")]
4814 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4815 (plus:QI (match_dup 1) (match_dup 2)))]
4816 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4817 "add{b}\t{%2, %0|%0, %2}"
4818 [(set_attr "type" "alu")
4819 (set_attr "mode" "QI")])
4821 (define_expand "addsi3"
4822 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4823 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4824 (match_operand:SI 2 "general_operand" "")))
4825 (clobber (reg:CC FLAGS_REG))])]
4827 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4829 (define_insn "*lea_1"
4830 [(set (match_operand:SI 0 "register_operand" "=r")
4831 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4833 "lea{l}\t{%a1, %0|%0, %a1}"
4834 [(set_attr "type" "lea")
4835 (set_attr "mode" "SI")])
4837 (define_insn "*lea_1_rex64"
4838 [(set (match_operand:SI 0 "register_operand" "=r")
4839 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4841 "lea{l}\t{%a1, %0|%0, %a1}"
4842 [(set_attr "type" "lea")
4843 (set_attr "mode" "SI")])
4845 (define_insn "*lea_1_zext"
4846 [(set (match_operand:DI 0 "register_operand" "=r")
4848 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4850 "lea{l}\t{%a1, %k0|%k0, %a1}"
4851 [(set_attr "type" "lea")
4852 (set_attr "mode" "SI")])
4854 (define_insn "*lea_2_rex64"
4855 [(set (match_operand:DI 0 "register_operand" "=r")
4856 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4858 "lea{q}\t{%a1, %0|%0, %a1}"
4859 [(set_attr "type" "lea")
4860 (set_attr "mode" "DI")])
4862 ;; The lea patterns for non-Pmodes needs to be matched by several
4863 ;; insns converted to real lea by splitters.
4865 (define_insn_and_split "*lea_general_1"
4866 [(set (match_operand 0 "register_operand" "=r")
4867 (plus (plus (match_operand 1 "index_register_operand" "l")
4868 (match_operand 2 "register_operand" "r"))
4869 (match_operand 3 "immediate_operand" "i")))]
4870 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4871 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4872 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4873 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4874 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4875 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4876 || GET_MODE (operands[3]) == VOIDmode)"
4878 "&& reload_completed"
4882 operands[0] = gen_lowpart (SImode, operands[0]);
4883 operands[1] = gen_lowpart (Pmode, operands[1]);
4884 operands[2] = gen_lowpart (Pmode, operands[2]);
4885 operands[3] = gen_lowpart (Pmode, operands[3]);
4886 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4888 if (Pmode != SImode)
4889 pat = gen_rtx_SUBREG (SImode, pat, 0);
4890 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4893 [(set_attr "type" "lea")
4894 (set_attr "mode" "SI")])
4896 (define_insn_and_split "*lea_general_1_zext"
4897 [(set (match_operand:DI 0 "register_operand" "=r")
4899 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4900 (match_operand:SI 2 "register_operand" "r"))
4901 (match_operand:SI 3 "immediate_operand" "i"))))]
4904 "&& reload_completed"
4906 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4908 (match_dup 3)) 0)))]
4910 operands[1] = gen_lowpart (Pmode, operands[1]);
4911 operands[2] = gen_lowpart (Pmode, operands[2]);
4912 operands[3] = gen_lowpart (Pmode, operands[3]);
4914 [(set_attr "type" "lea")
4915 (set_attr "mode" "SI")])
4917 (define_insn_and_split "*lea_general_2"
4918 [(set (match_operand 0 "register_operand" "=r")
4919 (plus (mult (match_operand 1 "index_register_operand" "l")
4920 (match_operand 2 "const248_operand" "i"))
4921 (match_operand 3 "nonmemory_operand" "ri")))]
4922 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4923 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4924 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4925 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4926 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4927 || GET_MODE (operands[3]) == VOIDmode)"
4929 "&& reload_completed"
4933 operands[0] = gen_lowpart (SImode, operands[0]);
4934 operands[1] = gen_lowpart (Pmode, operands[1]);
4935 operands[3] = gen_lowpart (Pmode, operands[3]);
4936 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4938 if (Pmode != SImode)
4939 pat = gen_rtx_SUBREG (SImode, pat, 0);
4940 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4943 [(set_attr "type" "lea")
4944 (set_attr "mode" "SI")])
4946 (define_insn_and_split "*lea_general_2_zext"
4947 [(set (match_operand:DI 0 "register_operand" "=r")
4949 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
4950 (match_operand:SI 2 "const248_operand" "n"))
4951 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
4954 "&& reload_completed"
4956 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
4958 (match_dup 3)) 0)))]
4960 operands[1] = gen_lowpart (Pmode, operands[1]);
4961 operands[3] = gen_lowpart (Pmode, operands[3]);
4963 [(set_attr "type" "lea")
4964 (set_attr "mode" "SI")])
4966 (define_insn_and_split "*lea_general_3"
4967 [(set (match_operand 0 "register_operand" "=r")
4968 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
4969 (match_operand 2 "const248_operand" "i"))
4970 (match_operand 3 "register_operand" "r"))
4971 (match_operand 4 "immediate_operand" "i")))]
4972 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4973 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4974 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4975 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4976 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4978 "&& reload_completed"
4982 operands[0] = gen_lowpart (SImode, operands[0]);
4983 operands[1] = gen_lowpart (Pmode, operands[1]);
4984 operands[3] = gen_lowpart (Pmode, operands[3]);
4985 operands[4] = gen_lowpart (Pmode, operands[4]);
4986 pat = gen_rtx_PLUS (Pmode,
4987 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
4991 if (Pmode != SImode)
4992 pat = gen_rtx_SUBREG (SImode, pat, 0);
4993 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4996 [(set_attr "type" "lea")
4997 (set_attr "mode" "SI")])
4999 (define_insn_and_split "*lea_general_3_zext"
5000 [(set (match_operand:DI 0 "register_operand" "=r")
5002 (plus:SI (plus:SI (mult:SI
5003 (match_operand:SI 1 "index_register_operand" "l")
5004 (match_operand:SI 2 "const248_operand" "n"))
5005 (match_operand:SI 3 "register_operand" "r"))
5006 (match_operand:SI 4 "immediate_operand" "i"))))]
5009 "&& reload_completed"
5011 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5014 (match_dup 4)) 0)))]
5016 operands[1] = gen_lowpart (Pmode, operands[1]);
5017 operands[3] = gen_lowpart (Pmode, operands[3]);
5018 operands[4] = gen_lowpart (Pmode, operands[4]);
5020 [(set_attr "type" "lea")
5021 (set_attr "mode" "SI")])
5023 (define_insn "*adddi_1_rex64"
5024 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5025 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5026 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5027 (clobber (reg:CC FLAGS_REG))]
5028 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5030 switch (get_attr_type (insn))
5033 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5034 return "lea{q}\t{%a2, %0|%0, %a2}";
5037 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5038 if (operands[2] == const1_rtx)
5039 return "inc{q}\t%0";
5042 gcc_assert (operands[2] == constm1_rtx);
5043 return "dec{q}\t%0";
5047 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5049 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5050 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5051 if (GET_CODE (operands[2]) == CONST_INT
5052 /* Avoid overflows. */
5053 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5054 && (INTVAL (operands[2]) == 128
5055 || (INTVAL (operands[2]) < 0
5056 && INTVAL (operands[2]) != -128)))
5058 operands[2] = GEN_INT (-INTVAL (operands[2]));
5059 return "sub{q}\t{%2, %0|%0, %2}";
5061 return "add{q}\t{%2, %0|%0, %2}";
5065 (cond [(eq_attr "alternative" "2")
5066 (const_string "lea")
5067 ; Current assemblers are broken and do not allow @GOTOFF in
5068 ; ought but a memory context.
5069 (match_operand:DI 2 "pic_symbolic_operand" "")
5070 (const_string "lea")
5071 (match_operand:DI 2 "incdec_operand" "")
5072 (const_string "incdec")
5074 (const_string "alu")))
5075 (set_attr "mode" "DI")])
5077 ;; Convert lea to the lea pattern to avoid flags dependency.
5079 [(set (match_operand:DI 0 "register_operand" "")
5080 (plus:DI (match_operand:DI 1 "register_operand" "")
5081 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5082 (clobber (reg:CC FLAGS_REG))]
5083 "TARGET_64BIT && reload_completed
5084 && true_regnum (operands[0]) != true_regnum (operands[1])"
5086 (plus:DI (match_dup 1)
5090 (define_insn "*adddi_2_rex64"
5091 [(set (reg FLAGS_REG)
5093 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5094 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5096 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5097 (plus:DI (match_dup 1) (match_dup 2)))]
5098 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5099 && ix86_binary_operator_ok (PLUS, DImode, operands)
5100 /* Current assemblers are broken and do not allow @GOTOFF in
5101 ought but a memory context. */
5102 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5104 switch (get_attr_type (insn))
5107 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5108 if (operands[2] == const1_rtx)
5109 return "inc{q}\t%0";
5112 gcc_assert (operands[2] == constm1_rtx);
5113 return "dec{q}\t%0";
5117 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5118 /* ???? We ought to handle there the 32bit case too
5119 - do we need new constraint? */
5120 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5121 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5122 if (GET_CODE (operands[2]) == CONST_INT
5123 /* Avoid overflows. */
5124 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5125 && (INTVAL (operands[2]) == 128
5126 || (INTVAL (operands[2]) < 0
5127 && INTVAL (operands[2]) != -128)))
5129 operands[2] = GEN_INT (-INTVAL (operands[2]));
5130 return "sub{q}\t{%2, %0|%0, %2}";
5132 return "add{q}\t{%2, %0|%0, %2}";
5136 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5137 (const_string "incdec")
5138 (const_string "alu")))
5139 (set_attr "mode" "DI")])
5141 (define_insn "*adddi_3_rex64"
5142 [(set (reg FLAGS_REG)
5143 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5144 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5145 (clobber (match_scratch:DI 0 "=r"))]
5147 && ix86_match_ccmode (insn, CCZmode)
5148 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5149 /* Current assemblers are broken and do not allow @GOTOFF in
5150 ought but a memory context. */
5151 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5153 switch (get_attr_type (insn))
5156 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5157 if (operands[2] == const1_rtx)
5158 return "inc{q}\t%0";
5161 gcc_assert (operands[2] == constm1_rtx);
5162 return "dec{q}\t%0";
5166 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5167 /* ???? We ought to handle there the 32bit case too
5168 - do we need new constraint? */
5169 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5170 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5171 if (GET_CODE (operands[2]) == CONST_INT
5172 /* Avoid overflows. */
5173 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5174 && (INTVAL (operands[2]) == 128
5175 || (INTVAL (operands[2]) < 0
5176 && INTVAL (operands[2]) != -128)))
5178 operands[2] = GEN_INT (-INTVAL (operands[2]));
5179 return "sub{q}\t{%2, %0|%0, %2}";
5181 return "add{q}\t{%2, %0|%0, %2}";
5185 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5186 (const_string "incdec")
5187 (const_string "alu")))
5188 (set_attr "mode" "DI")])
5190 ; For comparisons against 1, -1 and 128, we may generate better code
5191 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5192 ; is matched then. We can't accept general immediate, because for
5193 ; case of overflows, the result is messed up.
5194 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5196 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5197 ; only for comparisons not depending on it.
5198 (define_insn "*adddi_4_rex64"
5199 [(set (reg FLAGS_REG)
5200 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5201 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5202 (clobber (match_scratch:DI 0 "=rm"))]
5204 && ix86_match_ccmode (insn, CCGCmode)"
5206 switch (get_attr_type (insn))
5209 if (operands[2] == constm1_rtx)
5210 return "inc{q}\t%0";
5213 gcc_assert (operands[2] == const1_rtx);
5214 return "dec{q}\t%0";
5218 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5219 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5220 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5221 if ((INTVAL (operands[2]) == -128
5222 || (INTVAL (operands[2]) > 0
5223 && INTVAL (operands[2]) != 128))
5224 /* Avoid overflows. */
5225 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5226 return "sub{q}\t{%2, %0|%0, %2}";
5227 operands[2] = GEN_INT (-INTVAL (operands[2]));
5228 return "add{q}\t{%2, %0|%0, %2}";
5232 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5233 (const_string "incdec")
5234 (const_string "alu")))
5235 (set_attr "mode" "DI")])
5237 (define_insn "*adddi_5_rex64"
5238 [(set (reg FLAGS_REG)
5240 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5241 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5243 (clobber (match_scratch:DI 0 "=r"))]
5245 && ix86_match_ccmode (insn, CCGOCmode)
5246 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5247 /* Current assemblers are broken and do not allow @GOTOFF in
5248 ought but a memory context. */
5249 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5251 switch (get_attr_type (insn))
5254 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5255 if (operands[2] == const1_rtx)
5256 return "inc{q}\t%0";
5259 gcc_assert (operands[2] == constm1_rtx);
5260 return "dec{q}\t%0";
5264 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5265 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5266 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5267 if (GET_CODE (operands[2]) == CONST_INT
5268 /* Avoid overflows. */
5269 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5270 && (INTVAL (operands[2]) == 128
5271 || (INTVAL (operands[2]) < 0
5272 && INTVAL (operands[2]) != -128)))
5274 operands[2] = GEN_INT (-INTVAL (operands[2]));
5275 return "sub{q}\t{%2, %0|%0, %2}";
5277 return "add{q}\t{%2, %0|%0, %2}";
5281 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5282 (const_string "incdec")
5283 (const_string "alu")))
5284 (set_attr "mode" "DI")])
5287 (define_insn "*addsi_1"
5288 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5289 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5290 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5291 (clobber (reg:CC FLAGS_REG))]
5292 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5294 switch (get_attr_type (insn))
5297 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5298 return "lea{l}\t{%a2, %0|%0, %a2}";
5301 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5302 if (operands[2] == const1_rtx)
5303 return "inc{l}\t%0";
5306 gcc_assert (operands[2] == constm1_rtx);
5307 return "dec{l}\t%0";
5311 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5313 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5314 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5315 if (GET_CODE (operands[2]) == CONST_INT
5316 && (INTVAL (operands[2]) == 128
5317 || (INTVAL (operands[2]) < 0
5318 && INTVAL (operands[2]) != -128)))
5320 operands[2] = GEN_INT (-INTVAL (operands[2]));
5321 return "sub{l}\t{%2, %0|%0, %2}";
5323 return "add{l}\t{%2, %0|%0, %2}";
5327 (cond [(eq_attr "alternative" "2")
5328 (const_string "lea")
5329 ; Current assemblers are broken and do not allow @GOTOFF in
5330 ; ought but a memory context.
5331 (match_operand:SI 2 "pic_symbolic_operand" "")
5332 (const_string "lea")
5333 (match_operand:SI 2 "incdec_operand" "")
5334 (const_string "incdec")
5336 (const_string "alu")))
5337 (set_attr "mode" "SI")])
5339 ;; Convert lea to the lea pattern to avoid flags dependency.
5341 [(set (match_operand 0 "register_operand" "")
5342 (plus (match_operand 1 "register_operand" "")
5343 (match_operand 2 "nonmemory_operand" "")))
5344 (clobber (reg:CC FLAGS_REG))]
5346 && true_regnum (operands[0]) != true_regnum (operands[1])"
5350 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5351 may confuse gen_lowpart. */
5352 if (GET_MODE (operands[0]) != Pmode)
5354 operands[1] = gen_lowpart (Pmode, operands[1]);
5355 operands[2] = gen_lowpart (Pmode, operands[2]);
5357 operands[0] = gen_lowpart (SImode, operands[0]);
5358 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5359 if (Pmode != SImode)
5360 pat = gen_rtx_SUBREG (SImode, pat, 0);
5361 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5365 ;; It may seem that nonimmediate operand is proper one for operand 1.
5366 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5367 ;; we take care in ix86_binary_operator_ok to not allow two memory
5368 ;; operands so proper swapping will be done in reload. This allow
5369 ;; patterns constructed from addsi_1 to match.
5370 (define_insn "addsi_1_zext"
5371 [(set (match_operand:DI 0 "register_operand" "=r,r")
5373 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5374 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5375 (clobber (reg:CC FLAGS_REG))]
5376 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5378 switch (get_attr_type (insn))
5381 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5382 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5385 if (operands[2] == const1_rtx)
5386 return "inc{l}\t%k0";
5389 gcc_assert (operands[2] == constm1_rtx);
5390 return "dec{l}\t%k0";
5394 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5395 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5396 if (GET_CODE (operands[2]) == CONST_INT
5397 && (INTVAL (operands[2]) == 128
5398 || (INTVAL (operands[2]) < 0
5399 && INTVAL (operands[2]) != -128)))
5401 operands[2] = GEN_INT (-INTVAL (operands[2]));
5402 return "sub{l}\t{%2, %k0|%k0, %2}";
5404 return "add{l}\t{%2, %k0|%k0, %2}";
5408 (cond [(eq_attr "alternative" "1")
5409 (const_string "lea")
5410 ; Current assemblers are broken and do not allow @GOTOFF in
5411 ; ought but a memory context.
5412 (match_operand:SI 2 "pic_symbolic_operand" "")
5413 (const_string "lea")
5414 (match_operand:SI 2 "incdec_operand" "")
5415 (const_string "incdec")
5417 (const_string "alu")))
5418 (set_attr "mode" "SI")])
5420 ;; Convert lea to the lea pattern to avoid flags dependency.
5422 [(set (match_operand:DI 0 "register_operand" "")
5424 (plus:SI (match_operand:SI 1 "register_operand" "")
5425 (match_operand:SI 2 "nonmemory_operand" ""))))
5426 (clobber (reg:CC FLAGS_REG))]
5427 "TARGET_64BIT && reload_completed
5428 && true_regnum (operands[0]) != true_regnum (operands[1])"
5430 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5432 operands[1] = gen_lowpart (Pmode, operands[1]);
5433 operands[2] = gen_lowpart (Pmode, operands[2]);
5436 (define_insn "*addsi_2"
5437 [(set (reg FLAGS_REG)
5439 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5440 (match_operand:SI 2 "general_operand" "rmni,rni"))
5442 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5443 (plus:SI (match_dup 1) (match_dup 2)))]
5444 "ix86_match_ccmode (insn, CCGOCmode)
5445 && ix86_binary_operator_ok (PLUS, SImode, operands)
5446 /* Current assemblers are broken and do not allow @GOTOFF in
5447 ought but a memory context. */
5448 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5450 switch (get_attr_type (insn))
5453 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5454 if (operands[2] == const1_rtx)
5455 return "inc{l}\t%0";
5458 gcc_assert (operands[2] == constm1_rtx);
5459 return "dec{l}\t%0";
5463 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5464 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5465 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5466 if (GET_CODE (operands[2]) == CONST_INT
5467 && (INTVAL (operands[2]) == 128
5468 || (INTVAL (operands[2]) < 0
5469 && INTVAL (operands[2]) != -128)))
5471 operands[2] = GEN_INT (-INTVAL (operands[2]));
5472 return "sub{l}\t{%2, %0|%0, %2}";
5474 return "add{l}\t{%2, %0|%0, %2}";
5478 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5479 (const_string "incdec")
5480 (const_string "alu")))
5481 (set_attr "mode" "SI")])
5483 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5484 (define_insn "*addsi_2_zext"
5485 [(set (reg FLAGS_REG)
5487 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5488 (match_operand:SI 2 "general_operand" "rmni"))
5490 (set (match_operand:DI 0 "register_operand" "=r")
5491 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5492 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5493 && ix86_binary_operator_ok (PLUS, SImode, operands)
5494 /* Current assemblers are broken and do not allow @GOTOFF in
5495 ought but a memory context. */
5496 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5498 switch (get_attr_type (insn))
5501 if (operands[2] == const1_rtx)
5502 return "inc{l}\t%k0";
5505 gcc_assert (operands[2] == constm1_rtx);
5506 return "dec{l}\t%k0";
5510 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5511 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5512 if (GET_CODE (operands[2]) == CONST_INT
5513 && (INTVAL (operands[2]) == 128
5514 || (INTVAL (operands[2]) < 0
5515 && INTVAL (operands[2]) != -128)))
5517 operands[2] = GEN_INT (-INTVAL (operands[2]));
5518 return "sub{l}\t{%2, %k0|%k0, %2}";
5520 return "add{l}\t{%2, %k0|%k0, %2}";
5524 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5525 (const_string "incdec")
5526 (const_string "alu")))
5527 (set_attr "mode" "SI")])
5529 (define_insn "*addsi_3"
5530 [(set (reg FLAGS_REG)
5531 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5532 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5533 (clobber (match_scratch:SI 0 "=r"))]
5534 "ix86_match_ccmode (insn, CCZmode)
5535 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5536 /* Current assemblers are broken and do not allow @GOTOFF in
5537 ought but a memory context. */
5538 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5540 switch (get_attr_type (insn))
5543 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5544 if (operands[2] == const1_rtx)
5545 return "inc{l}\t%0";
5548 gcc_assert (operands[2] == constm1_rtx);
5549 return "dec{l}\t%0";
5553 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5554 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5555 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5556 if (GET_CODE (operands[2]) == CONST_INT
5557 && (INTVAL (operands[2]) == 128
5558 || (INTVAL (operands[2]) < 0
5559 && INTVAL (operands[2]) != -128)))
5561 operands[2] = GEN_INT (-INTVAL (operands[2]));
5562 return "sub{l}\t{%2, %0|%0, %2}";
5564 return "add{l}\t{%2, %0|%0, %2}";
5568 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5569 (const_string "incdec")
5570 (const_string "alu")))
5571 (set_attr "mode" "SI")])
5573 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5574 (define_insn "*addsi_3_zext"
5575 [(set (reg FLAGS_REG)
5576 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5577 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5578 (set (match_operand:DI 0 "register_operand" "=r")
5579 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5580 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5581 && ix86_binary_operator_ok (PLUS, SImode, operands)
5582 /* Current assemblers are broken and do not allow @GOTOFF in
5583 ought but a memory context. */
5584 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5586 switch (get_attr_type (insn))
5589 if (operands[2] == const1_rtx)
5590 return "inc{l}\t%k0";
5593 gcc_assert (operands[2] == constm1_rtx);
5594 return "dec{l}\t%k0";
5598 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5599 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5600 if (GET_CODE (operands[2]) == CONST_INT
5601 && (INTVAL (operands[2]) == 128
5602 || (INTVAL (operands[2]) < 0
5603 && INTVAL (operands[2]) != -128)))
5605 operands[2] = GEN_INT (-INTVAL (operands[2]));
5606 return "sub{l}\t{%2, %k0|%k0, %2}";
5608 return "add{l}\t{%2, %k0|%k0, %2}";
5612 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5613 (const_string "incdec")
5614 (const_string "alu")))
5615 (set_attr "mode" "SI")])
5617 ; For comparisons against 1, -1 and 128, we may generate better code
5618 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5619 ; is matched then. We can't accept general immediate, because for
5620 ; case of overflows, the result is messed up.
5621 ; This pattern also don't hold of 0x80000000, since the value overflows
5623 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5624 ; only for comparisons not depending on it.
5625 (define_insn "*addsi_4"
5626 [(set (reg FLAGS_REG)
5627 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5628 (match_operand:SI 2 "const_int_operand" "n")))
5629 (clobber (match_scratch:SI 0 "=rm"))]
5630 "ix86_match_ccmode (insn, CCGCmode)
5631 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5633 switch (get_attr_type (insn))
5636 if (operands[2] == constm1_rtx)
5637 return "inc{l}\t%0";
5640 gcc_assert (operands[2] == const1_rtx);
5641 return "dec{l}\t%0";
5645 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5646 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5647 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5648 if ((INTVAL (operands[2]) == -128
5649 || (INTVAL (operands[2]) > 0
5650 && INTVAL (operands[2]) != 128)))
5651 return "sub{l}\t{%2, %0|%0, %2}";
5652 operands[2] = GEN_INT (-INTVAL (operands[2]));
5653 return "add{l}\t{%2, %0|%0, %2}";
5657 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5658 (const_string "incdec")
5659 (const_string "alu")))
5660 (set_attr "mode" "SI")])
5662 (define_insn "*addsi_5"
5663 [(set (reg FLAGS_REG)
5665 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5666 (match_operand:SI 2 "general_operand" "rmni"))
5668 (clobber (match_scratch:SI 0 "=r"))]
5669 "ix86_match_ccmode (insn, CCGOCmode)
5670 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5671 /* Current assemblers are broken and do not allow @GOTOFF in
5672 ought but a memory context. */
5673 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5675 switch (get_attr_type (insn))
5678 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5679 if (operands[2] == const1_rtx)
5680 return "inc{l}\t%0";
5683 gcc_assert (operands[2] == constm1_rtx);
5684 return "dec{l}\t%0";
5688 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5690 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5691 if (GET_CODE (operands[2]) == CONST_INT
5692 && (INTVAL (operands[2]) == 128
5693 || (INTVAL (operands[2]) < 0
5694 && INTVAL (operands[2]) != -128)))
5696 operands[2] = GEN_INT (-INTVAL (operands[2]));
5697 return "sub{l}\t{%2, %0|%0, %2}";
5699 return "add{l}\t{%2, %0|%0, %2}";
5703 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5704 (const_string "incdec")
5705 (const_string "alu")))
5706 (set_attr "mode" "SI")])
5708 (define_expand "addhi3"
5709 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5710 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5711 (match_operand:HI 2 "general_operand" "")))
5712 (clobber (reg:CC FLAGS_REG))])]
5713 "TARGET_HIMODE_MATH"
5714 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5716 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5717 ;; type optimizations enabled by define-splits. This is not important
5718 ;; for PII, and in fact harmful because of partial register stalls.
5720 (define_insn "*addhi_1_lea"
5721 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5722 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5723 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5724 (clobber (reg:CC FLAGS_REG))]
5725 "!TARGET_PARTIAL_REG_STALL
5726 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5728 switch (get_attr_type (insn))
5733 if (operands[2] == const1_rtx)
5734 return "inc{w}\t%0";
5737 gcc_assert (operands[2] == constm1_rtx);
5738 return "dec{w}\t%0";
5742 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5743 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5744 if (GET_CODE (operands[2]) == CONST_INT
5745 && (INTVAL (operands[2]) == 128
5746 || (INTVAL (operands[2]) < 0
5747 && INTVAL (operands[2]) != -128)))
5749 operands[2] = GEN_INT (-INTVAL (operands[2]));
5750 return "sub{w}\t{%2, %0|%0, %2}";
5752 return "add{w}\t{%2, %0|%0, %2}";
5756 (if_then_else (eq_attr "alternative" "2")
5757 (const_string "lea")
5758 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5759 (const_string "incdec")
5760 (const_string "alu"))))
5761 (set_attr "mode" "HI,HI,SI")])
5763 (define_insn "*addhi_1"
5764 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5765 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5766 (match_operand:HI 2 "general_operand" "ri,rm")))
5767 (clobber (reg:CC FLAGS_REG))]
5768 "TARGET_PARTIAL_REG_STALL
5769 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5771 switch (get_attr_type (insn))
5774 if (operands[2] == const1_rtx)
5775 return "inc{w}\t%0";
5778 gcc_assert (operands[2] == constm1_rtx);
5779 return "dec{w}\t%0";
5783 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5784 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5785 if (GET_CODE (operands[2]) == CONST_INT
5786 && (INTVAL (operands[2]) == 128
5787 || (INTVAL (operands[2]) < 0
5788 && INTVAL (operands[2]) != -128)))
5790 operands[2] = GEN_INT (-INTVAL (operands[2]));
5791 return "sub{w}\t{%2, %0|%0, %2}";
5793 return "add{w}\t{%2, %0|%0, %2}";
5797 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5798 (const_string "incdec")
5799 (const_string "alu")))
5800 (set_attr "mode" "HI")])
5802 (define_insn "*addhi_2"
5803 [(set (reg FLAGS_REG)
5805 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5806 (match_operand:HI 2 "general_operand" "rmni,rni"))
5808 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5809 (plus:HI (match_dup 1) (match_dup 2)))]
5810 "ix86_match_ccmode (insn, CCGOCmode)
5811 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5813 switch (get_attr_type (insn))
5816 if (operands[2] == const1_rtx)
5817 return "inc{w}\t%0";
5820 gcc_assert (operands[2] == constm1_rtx);
5821 return "dec{w}\t%0";
5825 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5826 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5827 if (GET_CODE (operands[2]) == CONST_INT
5828 && (INTVAL (operands[2]) == 128
5829 || (INTVAL (operands[2]) < 0
5830 && INTVAL (operands[2]) != -128)))
5832 operands[2] = GEN_INT (-INTVAL (operands[2]));
5833 return "sub{w}\t{%2, %0|%0, %2}";
5835 return "add{w}\t{%2, %0|%0, %2}";
5839 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5840 (const_string "incdec")
5841 (const_string "alu")))
5842 (set_attr "mode" "HI")])
5844 (define_insn "*addhi_3"
5845 [(set (reg FLAGS_REG)
5846 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5847 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5848 (clobber (match_scratch:HI 0 "=r"))]
5849 "ix86_match_ccmode (insn, CCZmode)
5850 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5852 switch (get_attr_type (insn))
5855 if (operands[2] == const1_rtx)
5856 return "inc{w}\t%0";
5859 gcc_assert (operands[2] == constm1_rtx);
5860 return "dec{w}\t%0";
5864 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5865 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5866 if (GET_CODE (operands[2]) == CONST_INT
5867 && (INTVAL (operands[2]) == 128
5868 || (INTVAL (operands[2]) < 0
5869 && INTVAL (operands[2]) != -128)))
5871 operands[2] = GEN_INT (-INTVAL (operands[2]));
5872 return "sub{w}\t{%2, %0|%0, %2}";
5874 return "add{w}\t{%2, %0|%0, %2}";
5878 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5879 (const_string "incdec")
5880 (const_string "alu")))
5881 (set_attr "mode" "HI")])
5883 ; See comments above addsi_4 for details.
5884 (define_insn "*addhi_4"
5885 [(set (reg FLAGS_REG)
5886 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5887 (match_operand:HI 2 "const_int_operand" "n")))
5888 (clobber (match_scratch:HI 0 "=rm"))]
5889 "ix86_match_ccmode (insn, CCGCmode)
5890 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5892 switch (get_attr_type (insn))
5895 if (operands[2] == constm1_rtx)
5896 return "inc{w}\t%0";
5899 gcc_assert (operands[2] == const1_rtx);
5900 return "dec{w}\t%0";
5904 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5905 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5906 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5907 if ((INTVAL (operands[2]) == -128
5908 || (INTVAL (operands[2]) > 0
5909 && INTVAL (operands[2]) != 128)))
5910 return "sub{w}\t{%2, %0|%0, %2}";
5911 operands[2] = GEN_INT (-INTVAL (operands[2]));
5912 return "add{w}\t{%2, %0|%0, %2}";
5916 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5917 (const_string "incdec")
5918 (const_string "alu")))
5919 (set_attr "mode" "SI")])
5922 (define_insn "*addhi_5"
5923 [(set (reg FLAGS_REG)
5925 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5926 (match_operand:HI 2 "general_operand" "rmni"))
5928 (clobber (match_scratch:HI 0 "=r"))]
5929 "ix86_match_ccmode (insn, CCGOCmode)
5930 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5932 switch (get_attr_type (insn))
5935 if (operands[2] == const1_rtx)
5936 return "inc{w}\t%0";
5939 gcc_assert (operands[2] == constm1_rtx);
5940 return "dec{w}\t%0";
5944 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5945 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5946 if (GET_CODE (operands[2]) == CONST_INT
5947 && (INTVAL (operands[2]) == 128
5948 || (INTVAL (operands[2]) < 0
5949 && INTVAL (operands[2]) != -128)))
5951 operands[2] = GEN_INT (-INTVAL (operands[2]));
5952 return "sub{w}\t{%2, %0|%0, %2}";
5954 return "add{w}\t{%2, %0|%0, %2}";
5958 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5959 (const_string "incdec")
5960 (const_string "alu")))
5961 (set_attr "mode" "HI")])
5963 (define_expand "addqi3"
5964 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5965 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5966 (match_operand:QI 2 "general_operand" "")))
5967 (clobber (reg:CC FLAGS_REG))])]
5968 "TARGET_QIMODE_MATH"
5969 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5971 ;; %%% Potential partial reg stall on alternative 2. What to do?
5972 (define_insn "*addqi_1_lea"
5973 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5974 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5975 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
5976 (clobber (reg:CC FLAGS_REG))]
5977 "!TARGET_PARTIAL_REG_STALL
5978 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5980 int widen = (which_alternative == 2);
5981 switch (get_attr_type (insn))
5986 if (operands[2] == const1_rtx)
5987 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5990 gcc_assert (operands[2] == constm1_rtx);
5991 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5995 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5996 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5997 if (GET_CODE (operands[2]) == CONST_INT
5998 && (INTVAL (operands[2]) == 128
5999 || (INTVAL (operands[2]) < 0
6000 && INTVAL (operands[2]) != -128)))
6002 operands[2] = GEN_INT (-INTVAL (operands[2]));
6004 return "sub{l}\t{%2, %k0|%k0, %2}";
6006 return "sub{b}\t{%2, %0|%0, %2}";
6009 return "add{l}\t{%k2, %k0|%k0, %k2}";
6011 return "add{b}\t{%2, %0|%0, %2}";
6015 (if_then_else (eq_attr "alternative" "3")
6016 (const_string "lea")
6017 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6018 (const_string "incdec")
6019 (const_string "alu"))))
6020 (set_attr "mode" "QI,QI,SI,SI")])
6022 (define_insn "*addqi_1"
6023 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6024 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6025 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6026 (clobber (reg:CC FLAGS_REG))]
6027 "TARGET_PARTIAL_REG_STALL
6028 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6030 int widen = (which_alternative == 2);
6031 switch (get_attr_type (insn))
6034 if (operands[2] == const1_rtx)
6035 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6038 gcc_assert (operands[2] == constm1_rtx);
6039 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6043 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6044 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6045 if (GET_CODE (operands[2]) == CONST_INT
6046 && (INTVAL (operands[2]) == 128
6047 || (INTVAL (operands[2]) < 0
6048 && INTVAL (operands[2]) != -128)))
6050 operands[2] = GEN_INT (-INTVAL (operands[2]));
6052 return "sub{l}\t{%2, %k0|%k0, %2}";
6054 return "sub{b}\t{%2, %0|%0, %2}";
6057 return "add{l}\t{%k2, %k0|%k0, %k2}";
6059 return "add{b}\t{%2, %0|%0, %2}";
6063 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6064 (const_string "incdec")
6065 (const_string "alu")))
6066 (set_attr "mode" "QI,QI,SI")])
6068 (define_insn "*addqi_1_slp"
6069 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6070 (plus:QI (match_dup 0)
6071 (match_operand:QI 1 "general_operand" "qn,qnm")))
6072 (clobber (reg:CC FLAGS_REG))]
6073 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6074 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6076 switch (get_attr_type (insn))
6079 if (operands[1] == const1_rtx)
6080 return "inc{b}\t%0";
6083 gcc_assert (operands[1] == constm1_rtx);
6084 return "dec{b}\t%0";
6088 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6089 if (GET_CODE (operands[1]) == CONST_INT
6090 && INTVAL (operands[1]) < 0)
6092 operands[1] = GEN_INT (-INTVAL (operands[1]));
6093 return "sub{b}\t{%1, %0|%0, %1}";
6095 return "add{b}\t{%1, %0|%0, %1}";
6099 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6100 (const_string "incdec")
6101 (const_string "alu1")))
6102 (set (attr "memory")
6103 (if_then_else (match_operand 1 "memory_operand" "")
6104 (const_string "load")
6105 (const_string "none")))
6106 (set_attr "mode" "QI")])
6108 (define_insn "*addqi_2"
6109 [(set (reg FLAGS_REG)
6111 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6112 (match_operand:QI 2 "general_operand" "qmni,qni"))
6114 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6115 (plus:QI (match_dup 1) (match_dup 2)))]
6116 "ix86_match_ccmode (insn, CCGOCmode)
6117 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6119 switch (get_attr_type (insn))
6122 if (operands[2] == const1_rtx)
6123 return "inc{b}\t%0";
6126 gcc_assert (operands[2] == constm1_rtx
6127 || (GET_CODE (operands[2]) == CONST_INT
6128 && INTVAL (operands[2]) == 255));
6129 return "dec{b}\t%0";
6133 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6134 if (GET_CODE (operands[2]) == CONST_INT
6135 && INTVAL (operands[2]) < 0)
6137 operands[2] = GEN_INT (-INTVAL (operands[2]));
6138 return "sub{b}\t{%2, %0|%0, %2}";
6140 return "add{b}\t{%2, %0|%0, %2}";
6144 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6145 (const_string "incdec")
6146 (const_string "alu")))
6147 (set_attr "mode" "QI")])
6149 (define_insn "*addqi_3"
6150 [(set (reg FLAGS_REG)
6151 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6152 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6153 (clobber (match_scratch:QI 0 "=q"))]
6154 "ix86_match_ccmode (insn, CCZmode)
6155 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6157 switch (get_attr_type (insn))
6160 if (operands[2] == const1_rtx)
6161 return "inc{b}\t%0";
6164 gcc_assert (operands[2] == constm1_rtx
6165 || (GET_CODE (operands[2]) == CONST_INT
6166 && INTVAL (operands[2]) == 255));
6167 return "dec{b}\t%0";
6171 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6172 if (GET_CODE (operands[2]) == CONST_INT
6173 && INTVAL (operands[2]) < 0)
6175 operands[2] = GEN_INT (-INTVAL (operands[2]));
6176 return "sub{b}\t{%2, %0|%0, %2}";
6178 return "add{b}\t{%2, %0|%0, %2}";
6182 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6183 (const_string "incdec")
6184 (const_string "alu")))
6185 (set_attr "mode" "QI")])
6187 ; See comments above addsi_4 for details.
6188 (define_insn "*addqi_4"
6189 [(set (reg FLAGS_REG)
6190 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6191 (match_operand:QI 2 "const_int_operand" "n")))
6192 (clobber (match_scratch:QI 0 "=qm"))]
6193 "ix86_match_ccmode (insn, CCGCmode)
6194 && (INTVAL (operands[2]) & 0xff) != 0x80"
6196 switch (get_attr_type (insn))
6199 if (operands[2] == constm1_rtx
6200 || (GET_CODE (operands[2]) == CONST_INT
6201 && INTVAL (operands[2]) == 255))
6202 return "inc{b}\t%0";
6205 gcc_assert (operands[2] == const1_rtx);
6206 return "dec{b}\t%0";
6210 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6211 if (INTVAL (operands[2]) < 0)
6213 operands[2] = GEN_INT (-INTVAL (operands[2]));
6214 return "add{b}\t{%2, %0|%0, %2}";
6216 return "sub{b}\t{%2, %0|%0, %2}";
6220 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6221 (const_string "incdec")
6222 (const_string "alu")))
6223 (set_attr "mode" "QI")])
6226 (define_insn "*addqi_5"
6227 [(set (reg FLAGS_REG)
6229 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6230 (match_operand:QI 2 "general_operand" "qmni"))
6232 (clobber (match_scratch:QI 0 "=q"))]
6233 "ix86_match_ccmode (insn, CCGOCmode)
6234 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6236 switch (get_attr_type (insn))
6239 if (operands[2] == const1_rtx)
6240 return "inc{b}\t%0";
6243 gcc_assert (operands[2] == constm1_rtx
6244 || (GET_CODE (operands[2]) == CONST_INT
6245 && INTVAL (operands[2]) == 255));
6246 return "dec{b}\t%0";
6250 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6251 if (GET_CODE (operands[2]) == CONST_INT
6252 && INTVAL (operands[2]) < 0)
6254 operands[2] = GEN_INT (-INTVAL (operands[2]));
6255 return "sub{b}\t{%2, %0|%0, %2}";
6257 return "add{b}\t{%2, %0|%0, %2}";
6261 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6262 (const_string "incdec")
6263 (const_string "alu")))
6264 (set_attr "mode" "QI")])
6267 (define_insn "addqi_ext_1"
6268 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6273 (match_operand 1 "ext_register_operand" "0")
6276 (match_operand:QI 2 "general_operand" "Qmn")))
6277 (clobber (reg:CC FLAGS_REG))]
6280 switch (get_attr_type (insn))
6283 if (operands[2] == const1_rtx)
6284 return "inc{b}\t%h0";
6287 gcc_assert (operands[2] == constm1_rtx
6288 || (GET_CODE (operands[2]) == CONST_INT
6289 && INTVAL (operands[2]) == 255));
6290 return "dec{b}\t%h0";
6294 return "add{b}\t{%2, %h0|%h0, %2}";
6298 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6299 (const_string "incdec")
6300 (const_string "alu")))
6301 (set_attr "mode" "QI")])
6303 (define_insn "*addqi_ext_1_rex64"
6304 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6309 (match_operand 1 "ext_register_operand" "0")
6312 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6313 (clobber (reg:CC FLAGS_REG))]
6316 switch (get_attr_type (insn))
6319 if (operands[2] == const1_rtx)
6320 return "inc{b}\t%h0";
6323 gcc_assert (operands[2] == constm1_rtx
6324 || (GET_CODE (operands[2]) == CONST_INT
6325 && INTVAL (operands[2]) == 255));
6326 return "dec{b}\t%h0";
6330 return "add{b}\t{%2, %h0|%h0, %2}";
6334 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6335 (const_string "incdec")
6336 (const_string "alu")))
6337 (set_attr "mode" "QI")])
6339 (define_insn "*addqi_ext_2"
6340 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6345 (match_operand 1 "ext_register_operand" "%0")
6349 (match_operand 2 "ext_register_operand" "Q")
6352 (clobber (reg:CC FLAGS_REG))]
6354 "add{b}\t{%h2, %h0|%h0, %h2}"
6355 [(set_attr "type" "alu")
6356 (set_attr "mode" "QI")])
6358 ;; The patterns that match these are at the end of this file.
6360 (define_expand "addxf3"
6361 [(set (match_operand:XF 0 "register_operand" "")
6362 (plus:XF (match_operand:XF 1 "register_operand" "")
6363 (match_operand:XF 2 "register_operand" "")))]
6367 (define_expand "adddf3"
6368 [(set (match_operand:DF 0 "register_operand" "")
6369 (plus:DF (match_operand:DF 1 "register_operand" "")
6370 (match_operand:DF 2 "nonimmediate_operand" "")))]
6371 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6374 (define_expand "addsf3"
6375 [(set (match_operand:SF 0 "register_operand" "")
6376 (plus:SF (match_operand:SF 1 "register_operand" "")
6377 (match_operand:SF 2 "nonimmediate_operand" "")))]
6378 "TARGET_80387 || TARGET_SSE_MATH"
6381 ;; Subtract instructions
6383 ;; %%% splits for subsidi3
6385 (define_expand "subdi3"
6386 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6387 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6388 (match_operand:DI 2 "x86_64_general_operand" "")))
6389 (clobber (reg:CC FLAGS_REG))])]
6391 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6393 (define_insn "*subdi3_1"
6394 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6395 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6396 (match_operand:DI 2 "general_operand" "roiF,riF")))
6397 (clobber (reg:CC FLAGS_REG))]
6398 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6402 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6403 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6404 (match_operand:DI 2 "general_operand" "")))
6405 (clobber (reg:CC FLAGS_REG))]
6406 "!TARGET_64BIT && reload_completed"
6407 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6408 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6409 (parallel [(set (match_dup 3)
6410 (minus:SI (match_dup 4)
6411 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6413 (clobber (reg:CC FLAGS_REG))])]
6414 "split_di (operands+0, 1, operands+0, operands+3);
6415 split_di (operands+1, 1, operands+1, operands+4);
6416 split_di (operands+2, 1, operands+2, operands+5);")
6418 (define_insn "subdi3_carry_rex64"
6419 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6420 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6421 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6422 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6423 (clobber (reg:CC FLAGS_REG))]
6424 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6425 "sbb{q}\t{%2, %0|%0, %2}"
6426 [(set_attr "type" "alu")
6427 (set_attr "pent_pair" "pu")
6428 (set_attr "mode" "DI")])
6430 (define_insn "*subdi_1_rex64"
6431 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6432 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6433 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6434 (clobber (reg:CC FLAGS_REG))]
6435 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6436 "sub{q}\t{%2, %0|%0, %2}"
6437 [(set_attr "type" "alu")
6438 (set_attr "mode" "DI")])
6440 (define_insn "*subdi_2_rex64"
6441 [(set (reg FLAGS_REG)
6443 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6444 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6446 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6447 (minus:DI (match_dup 1) (match_dup 2)))]
6448 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6449 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6450 "sub{q}\t{%2, %0|%0, %2}"
6451 [(set_attr "type" "alu")
6452 (set_attr "mode" "DI")])
6454 (define_insn "*subdi_3_rex63"
6455 [(set (reg FLAGS_REG)
6456 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6457 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6458 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6459 (minus:DI (match_dup 1) (match_dup 2)))]
6460 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6461 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6462 "sub{q}\t{%2, %0|%0, %2}"
6463 [(set_attr "type" "alu")
6464 (set_attr "mode" "DI")])
6466 (define_insn "subqi3_carry"
6467 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6468 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6469 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6470 (match_operand:QI 2 "general_operand" "qi,qm"))))
6471 (clobber (reg:CC FLAGS_REG))]
6472 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6473 "sbb{b}\t{%2, %0|%0, %2}"
6474 [(set_attr "type" "alu")
6475 (set_attr "pent_pair" "pu")
6476 (set_attr "mode" "QI")])
6478 (define_insn "subhi3_carry"
6479 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6480 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6481 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6482 (match_operand:HI 2 "general_operand" "ri,rm"))))
6483 (clobber (reg:CC FLAGS_REG))]
6484 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6485 "sbb{w}\t{%2, %0|%0, %2}"
6486 [(set_attr "type" "alu")
6487 (set_attr "pent_pair" "pu")
6488 (set_attr "mode" "HI")])
6490 (define_insn "subsi3_carry"
6491 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6492 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6493 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6494 (match_operand:SI 2 "general_operand" "ri,rm"))))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6497 "sbb{l}\t{%2, %0|%0, %2}"
6498 [(set_attr "type" "alu")
6499 (set_attr "pent_pair" "pu")
6500 (set_attr "mode" "SI")])
6502 (define_insn "subsi3_carry_zext"
6503 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6505 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6506 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6507 (match_operand:SI 2 "general_operand" "ri,rm")))))
6508 (clobber (reg:CC FLAGS_REG))]
6509 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6510 "sbb{l}\t{%2, %k0|%k0, %2}"
6511 [(set_attr "type" "alu")
6512 (set_attr "pent_pair" "pu")
6513 (set_attr "mode" "SI")])
6515 (define_expand "subsi3"
6516 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6517 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6518 (match_operand:SI 2 "general_operand" "")))
6519 (clobber (reg:CC FLAGS_REG))])]
6521 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6523 (define_insn "*subsi_1"
6524 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6525 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6526 (match_operand:SI 2 "general_operand" "ri,rm")))
6527 (clobber (reg:CC FLAGS_REG))]
6528 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6529 "sub{l}\t{%2, %0|%0, %2}"
6530 [(set_attr "type" "alu")
6531 (set_attr "mode" "SI")])
6533 (define_insn "*subsi_1_zext"
6534 [(set (match_operand:DI 0 "register_operand" "=r")
6536 (minus:SI (match_operand:SI 1 "register_operand" "0")
6537 (match_operand:SI 2 "general_operand" "rim"))))
6538 (clobber (reg:CC FLAGS_REG))]
6539 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6540 "sub{l}\t{%2, %k0|%k0, %2}"
6541 [(set_attr "type" "alu")
6542 (set_attr "mode" "SI")])
6544 (define_insn "*subsi_2"
6545 [(set (reg FLAGS_REG)
6547 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6548 (match_operand:SI 2 "general_operand" "ri,rm"))
6550 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6551 (minus:SI (match_dup 1) (match_dup 2)))]
6552 "ix86_match_ccmode (insn, CCGOCmode)
6553 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6554 "sub{l}\t{%2, %0|%0, %2}"
6555 [(set_attr "type" "alu")
6556 (set_attr "mode" "SI")])
6558 (define_insn "*subsi_2_zext"
6559 [(set (reg FLAGS_REG)
6561 (minus:SI (match_operand:SI 1 "register_operand" "0")
6562 (match_operand:SI 2 "general_operand" "rim"))
6564 (set (match_operand:DI 0 "register_operand" "=r")
6566 (minus:SI (match_dup 1)
6568 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6569 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6570 "sub{l}\t{%2, %k0|%k0, %2}"
6571 [(set_attr "type" "alu")
6572 (set_attr "mode" "SI")])
6574 (define_insn "*subsi_3"
6575 [(set (reg FLAGS_REG)
6576 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6577 (match_operand:SI 2 "general_operand" "ri,rm")))
6578 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6579 (minus:SI (match_dup 1) (match_dup 2)))]
6580 "ix86_match_ccmode (insn, CCmode)
6581 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6582 "sub{l}\t{%2, %0|%0, %2}"
6583 [(set_attr "type" "alu")
6584 (set_attr "mode" "SI")])
6586 (define_insn "*subsi_3_zext"
6587 [(set (reg FLAGS_REG)
6588 (compare (match_operand:SI 1 "register_operand" "0")
6589 (match_operand:SI 2 "general_operand" "rim")))
6590 (set (match_operand:DI 0 "register_operand" "=r")
6592 (minus:SI (match_dup 1)
6594 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6595 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6596 "sub{q}\t{%2, %0|%0, %2}"
6597 [(set_attr "type" "alu")
6598 (set_attr "mode" "DI")])
6600 (define_expand "subhi3"
6601 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6602 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6603 (match_operand:HI 2 "general_operand" "")))
6604 (clobber (reg:CC FLAGS_REG))])]
6605 "TARGET_HIMODE_MATH"
6606 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6608 (define_insn "*subhi_1"
6609 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6610 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6611 (match_operand:HI 2 "general_operand" "ri,rm")))
6612 (clobber (reg:CC FLAGS_REG))]
6613 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6614 "sub{w}\t{%2, %0|%0, %2}"
6615 [(set_attr "type" "alu")
6616 (set_attr "mode" "HI")])
6618 (define_insn "*subhi_2"
6619 [(set (reg FLAGS_REG)
6621 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6622 (match_operand:HI 2 "general_operand" "ri,rm"))
6624 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6625 (minus:HI (match_dup 1) (match_dup 2)))]
6626 "ix86_match_ccmode (insn, CCGOCmode)
6627 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6628 "sub{w}\t{%2, %0|%0, %2}"
6629 [(set_attr "type" "alu")
6630 (set_attr "mode" "HI")])
6632 (define_insn "*subhi_3"
6633 [(set (reg FLAGS_REG)
6634 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6635 (match_operand:HI 2 "general_operand" "ri,rm")))
6636 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6637 (minus:HI (match_dup 1) (match_dup 2)))]
6638 "ix86_match_ccmode (insn, CCmode)
6639 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6640 "sub{w}\t{%2, %0|%0, %2}"
6641 [(set_attr "type" "alu")
6642 (set_attr "mode" "HI")])
6644 (define_expand "subqi3"
6645 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6646 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6647 (match_operand:QI 2 "general_operand" "")))
6648 (clobber (reg:CC FLAGS_REG))])]
6649 "TARGET_QIMODE_MATH"
6650 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6652 (define_insn "*subqi_1"
6653 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6654 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6655 (match_operand:QI 2 "general_operand" "qn,qmn")))
6656 (clobber (reg:CC FLAGS_REG))]
6657 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6658 "sub{b}\t{%2, %0|%0, %2}"
6659 [(set_attr "type" "alu")
6660 (set_attr "mode" "QI")])
6662 (define_insn "*subqi_1_slp"
6663 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6664 (minus:QI (match_dup 0)
6665 (match_operand:QI 1 "general_operand" "qn,qmn")))
6666 (clobber (reg:CC FLAGS_REG))]
6667 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6668 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6669 "sub{b}\t{%1, %0|%0, %1}"
6670 [(set_attr "type" "alu1")
6671 (set_attr "mode" "QI")])
6673 (define_insn "*subqi_2"
6674 [(set (reg FLAGS_REG)
6676 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6677 (match_operand:QI 2 "general_operand" "qi,qm"))
6679 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6680 (minus:HI (match_dup 1) (match_dup 2)))]
6681 "ix86_match_ccmode (insn, CCGOCmode)
6682 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6683 "sub{b}\t{%2, %0|%0, %2}"
6684 [(set_attr "type" "alu")
6685 (set_attr "mode" "QI")])
6687 (define_insn "*subqi_3"
6688 [(set (reg FLAGS_REG)
6689 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6690 (match_operand:QI 2 "general_operand" "qi,qm")))
6691 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6692 (minus:HI (match_dup 1) (match_dup 2)))]
6693 "ix86_match_ccmode (insn, CCmode)
6694 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6695 "sub{b}\t{%2, %0|%0, %2}"
6696 [(set_attr "type" "alu")
6697 (set_attr "mode" "QI")])
6699 ;; The patterns that match these are at the end of this file.
6701 (define_expand "subxf3"
6702 [(set (match_operand:XF 0 "register_operand" "")
6703 (minus:XF (match_operand:XF 1 "register_operand" "")
6704 (match_operand:XF 2 "register_operand" "")))]
6708 (define_expand "subdf3"
6709 [(set (match_operand:DF 0 "register_operand" "")
6710 (minus:DF (match_operand:DF 1 "register_operand" "")
6711 (match_operand:DF 2 "nonimmediate_operand" "")))]
6712 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6715 (define_expand "subsf3"
6716 [(set (match_operand:SF 0 "register_operand" "")
6717 (minus:SF (match_operand:SF 1 "register_operand" "")
6718 (match_operand:SF 2 "nonimmediate_operand" "")))]
6719 "TARGET_80387 || TARGET_SSE_MATH"
6722 ;; Multiply instructions
6724 (define_expand "muldi3"
6725 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6726 (mult:DI (match_operand:DI 1 "register_operand" "")
6727 (match_operand:DI 2 "x86_64_general_operand" "")))
6728 (clobber (reg:CC FLAGS_REG))])]
6732 (define_insn "*muldi3_1_rex64"
6733 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6734 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6735 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6736 (clobber (reg:CC FLAGS_REG))]
6738 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6740 imul{q}\t{%2, %1, %0|%0, %1, %2}
6741 imul{q}\t{%2, %1, %0|%0, %1, %2}
6742 imul{q}\t{%2, %0|%0, %2}"
6743 [(set_attr "type" "imul")
6744 (set_attr "prefix_0f" "0,0,1")
6745 (set (attr "athlon_decode")
6746 (cond [(eq_attr "cpu" "athlon")
6747 (const_string "vector")
6748 (eq_attr "alternative" "1")
6749 (const_string "vector")
6750 (and (eq_attr "alternative" "2")
6751 (match_operand 1 "memory_operand" ""))
6752 (const_string "vector")]
6753 (const_string "direct")))
6754 (set_attr "mode" "DI")])
6756 (define_expand "mulsi3"
6757 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6758 (mult:SI (match_operand:SI 1 "register_operand" "")
6759 (match_operand:SI 2 "general_operand" "")))
6760 (clobber (reg:CC FLAGS_REG))])]
6764 (define_insn "*mulsi3_1"
6765 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6766 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6767 (match_operand:SI 2 "general_operand" "K,i,mr")))
6768 (clobber (reg:CC FLAGS_REG))]
6769 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6771 imul{l}\t{%2, %1, %0|%0, %1, %2}
6772 imul{l}\t{%2, %1, %0|%0, %1, %2}
6773 imul{l}\t{%2, %0|%0, %2}"
6774 [(set_attr "type" "imul")
6775 (set_attr "prefix_0f" "0,0,1")
6776 (set (attr "athlon_decode")
6777 (cond [(eq_attr "cpu" "athlon")
6778 (const_string "vector")
6779 (eq_attr "alternative" "1")
6780 (const_string "vector")
6781 (and (eq_attr "alternative" "2")
6782 (match_operand 1 "memory_operand" ""))
6783 (const_string "vector")]
6784 (const_string "direct")))
6785 (set_attr "mode" "SI")])
6787 (define_insn "*mulsi3_1_zext"
6788 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6790 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6791 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6792 (clobber (reg:CC FLAGS_REG))]
6794 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6796 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6797 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6798 imul{l}\t{%2, %k0|%k0, %2}"
6799 [(set_attr "type" "imul")
6800 (set_attr "prefix_0f" "0,0,1")
6801 (set (attr "athlon_decode")
6802 (cond [(eq_attr "cpu" "athlon")
6803 (const_string "vector")
6804 (eq_attr "alternative" "1")
6805 (const_string "vector")
6806 (and (eq_attr "alternative" "2")
6807 (match_operand 1 "memory_operand" ""))
6808 (const_string "vector")]
6809 (const_string "direct")))
6810 (set_attr "mode" "SI")])
6812 (define_expand "mulhi3"
6813 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6814 (mult:HI (match_operand:HI 1 "register_operand" "")
6815 (match_operand:HI 2 "general_operand" "")))
6816 (clobber (reg:CC FLAGS_REG))])]
6817 "TARGET_HIMODE_MATH"
6820 (define_insn "*mulhi3_1"
6821 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6822 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6823 (match_operand:HI 2 "general_operand" "K,i,mr")))
6824 (clobber (reg:CC FLAGS_REG))]
6825 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6827 imul{w}\t{%2, %1, %0|%0, %1, %2}
6828 imul{w}\t{%2, %1, %0|%0, %1, %2}
6829 imul{w}\t{%2, %0|%0, %2}"
6830 [(set_attr "type" "imul")
6831 (set_attr "prefix_0f" "0,0,1")
6832 (set (attr "athlon_decode")
6833 (cond [(eq_attr "cpu" "athlon")
6834 (const_string "vector")
6835 (eq_attr "alternative" "1,2")
6836 (const_string "vector")]
6837 (const_string "direct")))
6838 (set_attr "mode" "HI")])
6840 (define_expand "mulqi3"
6841 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6842 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6843 (match_operand:QI 2 "register_operand" "")))
6844 (clobber (reg:CC FLAGS_REG))])]
6845 "TARGET_QIMODE_MATH"
6848 (define_insn "*mulqi3_1"
6849 [(set (match_operand:QI 0 "register_operand" "=a")
6850 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6851 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6852 (clobber (reg:CC FLAGS_REG))]
6854 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6856 [(set_attr "type" "imul")
6857 (set_attr "length_immediate" "0")
6858 (set (attr "athlon_decode")
6859 (if_then_else (eq_attr "cpu" "athlon")
6860 (const_string "vector")
6861 (const_string "direct")))
6862 (set_attr "mode" "QI")])
6864 (define_expand "umulqihi3"
6865 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6866 (mult:HI (zero_extend:HI
6867 (match_operand:QI 1 "nonimmediate_operand" ""))
6869 (match_operand:QI 2 "register_operand" ""))))
6870 (clobber (reg:CC FLAGS_REG))])]
6871 "TARGET_QIMODE_MATH"
6874 (define_insn "*umulqihi3_1"
6875 [(set (match_operand:HI 0 "register_operand" "=a")
6876 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6877 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6878 (clobber (reg:CC FLAGS_REG))]
6880 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6882 [(set_attr "type" "imul")
6883 (set_attr "length_immediate" "0")
6884 (set (attr "athlon_decode")
6885 (if_then_else (eq_attr "cpu" "athlon")
6886 (const_string "vector")
6887 (const_string "direct")))
6888 (set_attr "mode" "QI")])
6890 (define_expand "mulqihi3"
6891 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6892 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6893 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6894 (clobber (reg:CC FLAGS_REG))])]
6895 "TARGET_QIMODE_MATH"
6898 (define_insn "*mulqihi3_insn"
6899 [(set (match_operand:HI 0 "register_operand" "=a")
6900 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6901 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6902 (clobber (reg:CC FLAGS_REG))]
6904 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6906 [(set_attr "type" "imul")
6907 (set_attr "length_immediate" "0")
6908 (set (attr "athlon_decode")
6909 (if_then_else (eq_attr "cpu" "athlon")
6910 (const_string "vector")
6911 (const_string "direct")))
6912 (set_attr "mode" "QI")])
6914 (define_expand "umulditi3"
6915 [(parallel [(set (match_operand:TI 0 "register_operand" "")
6916 (mult:TI (zero_extend:TI
6917 (match_operand:DI 1 "nonimmediate_operand" ""))
6919 (match_operand:DI 2 "register_operand" ""))))
6920 (clobber (reg:CC FLAGS_REG))])]
6924 (define_insn "*umulditi3_insn"
6925 [(set (match_operand:TI 0 "register_operand" "=A")
6926 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6927 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6928 (clobber (reg:CC FLAGS_REG))]
6930 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6932 [(set_attr "type" "imul")
6933 (set_attr "length_immediate" "0")
6934 (set (attr "athlon_decode")
6935 (if_then_else (eq_attr "cpu" "athlon")
6936 (const_string "vector")
6937 (const_string "double")))
6938 (set_attr "mode" "DI")])
6940 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6941 (define_expand "umulsidi3"
6942 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6943 (mult:DI (zero_extend:DI
6944 (match_operand:SI 1 "nonimmediate_operand" ""))
6946 (match_operand:SI 2 "register_operand" ""))))
6947 (clobber (reg:CC FLAGS_REG))])]
6951 (define_insn "*umulsidi3_insn"
6952 [(set (match_operand:DI 0 "register_operand" "=A")
6953 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6954 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6955 (clobber (reg:CC FLAGS_REG))]
6957 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6959 [(set_attr "type" "imul")
6960 (set_attr "length_immediate" "0")
6961 (set (attr "athlon_decode")
6962 (if_then_else (eq_attr "cpu" "athlon")
6963 (const_string "vector")
6964 (const_string "double")))
6965 (set_attr "mode" "SI")])
6967 (define_expand "mulditi3"
6968 [(parallel [(set (match_operand:TI 0 "register_operand" "")
6969 (mult:TI (sign_extend:TI
6970 (match_operand:DI 1 "nonimmediate_operand" ""))
6972 (match_operand:DI 2 "register_operand" ""))))
6973 (clobber (reg:CC FLAGS_REG))])]
6977 (define_insn "*mulditi3_insn"
6978 [(set (match_operand:TI 0 "register_operand" "=A")
6979 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6980 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6981 (clobber (reg:CC FLAGS_REG))]
6983 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6985 [(set_attr "type" "imul")
6986 (set_attr "length_immediate" "0")
6987 (set (attr "athlon_decode")
6988 (if_then_else (eq_attr "cpu" "athlon")
6989 (const_string "vector")
6990 (const_string "double")))
6991 (set_attr "mode" "DI")])
6993 (define_expand "mulsidi3"
6994 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6995 (mult:DI (sign_extend:DI
6996 (match_operand:SI 1 "nonimmediate_operand" ""))
6998 (match_operand:SI 2 "register_operand" ""))))
6999 (clobber (reg:CC FLAGS_REG))])]
7003 (define_insn "*mulsidi3_insn"
7004 [(set (match_operand:DI 0 "register_operand" "=A")
7005 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7006 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7007 (clobber (reg:CC FLAGS_REG))]
7009 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7011 [(set_attr "type" "imul")
7012 (set_attr "length_immediate" "0")
7013 (set (attr "athlon_decode")
7014 (if_then_else (eq_attr "cpu" "athlon")
7015 (const_string "vector")
7016 (const_string "double")))
7017 (set_attr "mode" "SI")])
7019 (define_expand "umuldi3_highpart"
7020 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7023 (mult:TI (zero_extend:TI
7024 (match_operand:DI 1 "nonimmediate_operand" ""))
7026 (match_operand:DI 2 "register_operand" "")))
7028 (clobber (match_scratch:DI 3 ""))
7029 (clobber (reg:CC FLAGS_REG))])]
7033 (define_insn "*umuldi3_highpart_rex64"
7034 [(set (match_operand:DI 0 "register_operand" "=d")
7037 (mult:TI (zero_extend:TI
7038 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7040 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7042 (clobber (match_scratch:DI 3 "=1"))
7043 (clobber (reg:CC FLAGS_REG))]
7045 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7047 [(set_attr "type" "imul")
7048 (set_attr "length_immediate" "0")
7049 (set (attr "athlon_decode")
7050 (if_then_else (eq_attr "cpu" "athlon")
7051 (const_string "vector")
7052 (const_string "double")))
7053 (set_attr "mode" "DI")])
7055 (define_expand "umulsi3_highpart"
7056 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7059 (mult:DI (zero_extend:DI
7060 (match_operand:SI 1 "nonimmediate_operand" ""))
7062 (match_operand:SI 2 "register_operand" "")))
7064 (clobber (match_scratch:SI 3 ""))
7065 (clobber (reg:CC FLAGS_REG))])]
7069 (define_insn "*umulsi3_highpart_insn"
7070 [(set (match_operand:SI 0 "register_operand" "=d")
7073 (mult:DI (zero_extend:DI
7074 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7076 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7078 (clobber (match_scratch:SI 3 "=1"))
7079 (clobber (reg:CC FLAGS_REG))]
7080 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7082 [(set_attr "type" "imul")
7083 (set_attr "length_immediate" "0")
7084 (set (attr "athlon_decode")
7085 (if_then_else (eq_attr "cpu" "athlon")
7086 (const_string "vector")
7087 (const_string "double")))
7088 (set_attr "mode" "SI")])
7090 (define_insn "*umulsi3_highpart_zext"
7091 [(set (match_operand:DI 0 "register_operand" "=d")
7092 (zero_extend:DI (truncate:SI
7094 (mult:DI (zero_extend:DI
7095 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7097 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7099 (clobber (match_scratch:SI 3 "=1"))
7100 (clobber (reg:CC FLAGS_REG))]
7102 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7104 [(set_attr "type" "imul")
7105 (set_attr "length_immediate" "0")
7106 (set (attr "athlon_decode")
7107 (if_then_else (eq_attr "cpu" "athlon")
7108 (const_string "vector")
7109 (const_string "double")))
7110 (set_attr "mode" "SI")])
7112 (define_expand "smuldi3_highpart"
7113 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7116 (mult:TI (sign_extend:TI
7117 (match_operand:DI 1 "nonimmediate_operand" ""))
7119 (match_operand:DI 2 "register_operand" "")))
7121 (clobber (match_scratch:DI 3 ""))
7122 (clobber (reg:CC FLAGS_REG))])]
7126 (define_insn "*smuldi3_highpart_rex64"
7127 [(set (match_operand:DI 0 "register_operand" "=d")
7130 (mult:TI (sign_extend:TI
7131 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7133 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7135 (clobber (match_scratch:DI 3 "=1"))
7136 (clobber (reg:CC FLAGS_REG))]
7138 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7140 [(set_attr "type" "imul")
7141 (set (attr "athlon_decode")
7142 (if_then_else (eq_attr "cpu" "athlon")
7143 (const_string "vector")
7144 (const_string "double")))
7145 (set_attr "mode" "DI")])
7147 (define_expand "smulsi3_highpart"
7148 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7151 (mult:DI (sign_extend:DI
7152 (match_operand:SI 1 "nonimmediate_operand" ""))
7154 (match_operand:SI 2 "register_operand" "")))
7156 (clobber (match_scratch:SI 3 ""))
7157 (clobber (reg:CC FLAGS_REG))])]
7161 (define_insn "*smulsi3_highpart_insn"
7162 [(set (match_operand:SI 0 "register_operand" "=d")
7165 (mult:DI (sign_extend:DI
7166 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7168 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7170 (clobber (match_scratch:SI 3 "=1"))
7171 (clobber (reg:CC FLAGS_REG))]
7172 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7174 [(set_attr "type" "imul")
7175 (set (attr "athlon_decode")
7176 (if_then_else (eq_attr "cpu" "athlon")
7177 (const_string "vector")
7178 (const_string "double")))
7179 (set_attr "mode" "SI")])
7181 (define_insn "*smulsi3_highpart_zext"
7182 [(set (match_operand:DI 0 "register_operand" "=d")
7183 (zero_extend:DI (truncate:SI
7185 (mult:DI (sign_extend:DI
7186 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7188 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7190 (clobber (match_scratch:SI 3 "=1"))
7191 (clobber (reg:CC FLAGS_REG))]
7193 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7195 [(set_attr "type" "imul")
7196 (set (attr "athlon_decode")
7197 (if_then_else (eq_attr "cpu" "athlon")
7198 (const_string "vector")
7199 (const_string "double")))
7200 (set_attr "mode" "SI")])
7202 ;; The patterns that match these are at the end of this file.
7204 (define_expand "mulxf3"
7205 [(set (match_operand:XF 0 "register_operand" "")
7206 (mult:XF (match_operand:XF 1 "register_operand" "")
7207 (match_operand:XF 2 "register_operand" "")))]
7211 (define_expand "muldf3"
7212 [(set (match_operand:DF 0 "register_operand" "")
7213 (mult:DF (match_operand:DF 1 "register_operand" "")
7214 (match_operand:DF 2 "nonimmediate_operand" "")))]
7215 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7218 (define_expand "mulsf3"
7219 [(set (match_operand:SF 0 "register_operand" "")
7220 (mult:SF (match_operand:SF 1 "register_operand" "")
7221 (match_operand:SF 2 "nonimmediate_operand" "")))]
7222 "TARGET_80387 || TARGET_SSE_MATH"
7225 ;; Divide instructions
7227 (define_insn "divqi3"
7228 [(set (match_operand:QI 0 "register_operand" "=a")
7229 (div:QI (match_operand:HI 1 "register_operand" "0")
7230 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7231 (clobber (reg:CC FLAGS_REG))]
7232 "TARGET_QIMODE_MATH"
7234 [(set_attr "type" "idiv")
7235 (set_attr "mode" "QI")])
7237 (define_insn "udivqi3"
7238 [(set (match_operand:QI 0 "register_operand" "=a")
7239 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7240 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7241 (clobber (reg:CC FLAGS_REG))]
7242 "TARGET_QIMODE_MATH"
7244 [(set_attr "type" "idiv")
7245 (set_attr "mode" "QI")])
7247 ;; The patterns that match these are at the end of this file.
7249 (define_expand "divxf3"
7250 [(set (match_operand:XF 0 "register_operand" "")
7251 (div:XF (match_operand:XF 1 "register_operand" "")
7252 (match_operand:XF 2 "register_operand" "")))]
7256 (define_expand "divdf3"
7257 [(set (match_operand:DF 0 "register_operand" "")
7258 (div:DF (match_operand:DF 1 "register_operand" "")
7259 (match_operand:DF 2 "nonimmediate_operand" "")))]
7260 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7263 (define_expand "divsf3"
7264 [(set (match_operand:SF 0 "register_operand" "")
7265 (div:SF (match_operand:SF 1 "register_operand" "")
7266 (match_operand:SF 2 "nonimmediate_operand" "")))]
7267 "TARGET_80387 || TARGET_SSE_MATH"
7270 ;; Remainder instructions.
7272 (define_expand "divmoddi4"
7273 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7274 (div:DI (match_operand:DI 1 "register_operand" "")
7275 (match_operand:DI 2 "nonimmediate_operand" "")))
7276 (set (match_operand:DI 3 "register_operand" "")
7277 (mod:DI (match_dup 1) (match_dup 2)))
7278 (clobber (reg:CC FLAGS_REG))])]
7282 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7283 ;; Penalize eax case slightly because it results in worse scheduling
7285 (define_insn "*divmoddi4_nocltd_rex64"
7286 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7287 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7288 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7289 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7290 (mod:DI (match_dup 2) (match_dup 3)))
7291 (clobber (reg:CC FLAGS_REG))]
7292 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7294 [(set_attr "type" "multi")])
7296 (define_insn "*divmoddi4_cltd_rex64"
7297 [(set (match_operand:DI 0 "register_operand" "=a")
7298 (div:DI (match_operand:DI 2 "register_operand" "a")
7299 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7300 (set (match_operand:DI 1 "register_operand" "=&d")
7301 (mod:DI (match_dup 2) (match_dup 3)))
7302 (clobber (reg:CC FLAGS_REG))]
7303 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7305 [(set_attr "type" "multi")])
7307 (define_insn "*divmoddi_noext_rex64"
7308 [(set (match_operand:DI 0 "register_operand" "=a")
7309 (div:DI (match_operand:DI 1 "register_operand" "0")
7310 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7311 (set (match_operand:DI 3 "register_operand" "=d")
7312 (mod:DI (match_dup 1) (match_dup 2)))
7313 (use (match_operand:DI 4 "register_operand" "3"))
7314 (clobber (reg:CC FLAGS_REG))]
7317 [(set_attr "type" "idiv")
7318 (set_attr "mode" "DI")])
7321 [(set (match_operand:DI 0 "register_operand" "")
7322 (div:DI (match_operand:DI 1 "register_operand" "")
7323 (match_operand:DI 2 "nonimmediate_operand" "")))
7324 (set (match_operand:DI 3 "register_operand" "")
7325 (mod:DI (match_dup 1) (match_dup 2)))
7326 (clobber (reg:CC FLAGS_REG))]
7327 "TARGET_64BIT && reload_completed"
7328 [(parallel [(set (match_dup 3)
7329 (ashiftrt:DI (match_dup 4) (const_int 63)))
7330 (clobber (reg:CC FLAGS_REG))])
7331 (parallel [(set (match_dup 0)
7332 (div:DI (reg:DI 0) (match_dup 2)))
7334 (mod:DI (reg:DI 0) (match_dup 2)))
7336 (clobber (reg:CC FLAGS_REG))])]
7338 /* Avoid use of cltd in favor of a mov+shift. */
7339 if (!TARGET_USE_CLTD && !optimize_size)
7341 if (true_regnum (operands[1]))
7342 emit_move_insn (operands[0], operands[1]);
7344 emit_move_insn (operands[3], operands[1]);
7345 operands[4] = operands[3];
7349 gcc_assert (!true_regnum (operands[1]));
7350 operands[4] = operands[1];
7355 (define_expand "divmodsi4"
7356 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7357 (div:SI (match_operand:SI 1 "register_operand" "")
7358 (match_operand:SI 2 "nonimmediate_operand" "")))
7359 (set (match_operand:SI 3 "register_operand" "")
7360 (mod:SI (match_dup 1) (match_dup 2)))
7361 (clobber (reg:CC FLAGS_REG))])]
7365 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7366 ;; Penalize eax case slightly because it results in worse scheduling
7368 (define_insn "*divmodsi4_nocltd"
7369 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7370 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7371 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7372 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7373 (mod:SI (match_dup 2) (match_dup 3)))
7374 (clobber (reg:CC FLAGS_REG))]
7375 "!optimize_size && !TARGET_USE_CLTD"
7377 [(set_attr "type" "multi")])
7379 (define_insn "*divmodsi4_cltd"
7380 [(set (match_operand:SI 0 "register_operand" "=a")
7381 (div:SI (match_operand:SI 2 "register_operand" "a")
7382 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7383 (set (match_operand:SI 1 "register_operand" "=&d")
7384 (mod:SI (match_dup 2) (match_dup 3)))
7385 (clobber (reg:CC FLAGS_REG))]
7386 "optimize_size || TARGET_USE_CLTD"
7388 [(set_attr "type" "multi")])
7390 (define_insn "*divmodsi_noext"
7391 [(set (match_operand:SI 0 "register_operand" "=a")
7392 (div:SI (match_operand:SI 1 "register_operand" "0")
7393 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7394 (set (match_operand:SI 3 "register_operand" "=d")
7395 (mod:SI (match_dup 1) (match_dup 2)))
7396 (use (match_operand:SI 4 "register_operand" "3"))
7397 (clobber (reg:CC FLAGS_REG))]
7400 [(set_attr "type" "idiv")
7401 (set_attr "mode" "SI")])
7404 [(set (match_operand:SI 0 "register_operand" "")
7405 (div:SI (match_operand:SI 1 "register_operand" "")
7406 (match_operand:SI 2 "nonimmediate_operand" "")))
7407 (set (match_operand:SI 3 "register_operand" "")
7408 (mod:SI (match_dup 1) (match_dup 2)))
7409 (clobber (reg:CC FLAGS_REG))]
7411 [(parallel [(set (match_dup 3)
7412 (ashiftrt:SI (match_dup 4) (const_int 31)))
7413 (clobber (reg:CC FLAGS_REG))])
7414 (parallel [(set (match_dup 0)
7415 (div:SI (reg:SI 0) (match_dup 2)))
7417 (mod:SI (reg:SI 0) (match_dup 2)))
7419 (clobber (reg:CC FLAGS_REG))])]
7421 /* Avoid use of cltd in favor of a mov+shift. */
7422 if (!TARGET_USE_CLTD && !optimize_size)
7424 if (true_regnum (operands[1]))
7425 emit_move_insn (operands[0], operands[1]);
7427 emit_move_insn (operands[3], operands[1]);
7428 operands[4] = operands[3];
7432 gcc_assert (!true_regnum (operands[1]));
7433 operands[4] = operands[1];
7437 (define_insn "divmodhi4"
7438 [(set (match_operand:HI 0 "register_operand" "=a")
7439 (div:HI (match_operand:HI 1 "register_operand" "0")
7440 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7441 (set (match_operand:HI 3 "register_operand" "=&d")
7442 (mod:HI (match_dup 1) (match_dup 2)))
7443 (clobber (reg:CC FLAGS_REG))]
7444 "TARGET_HIMODE_MATH"
7446 [(set_attr "type" "multi")
7447 (set_attr "length_immediate" "0")
7448 (set_attr "mode" "SI")])
7450 (define_insn "udivmoddi4"
7451 [(set (match_operand:DI 0 "register_operand" "=a")
7452 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7453 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7454 (set (match_operand:DI 3 "register_operand" "=&d")
7455 (umod:DI (match_dup 1) (match_dup 2)))
7456 (clobber (reg:CC FLAGS_REG))]
7458 "xor{q}\t%3, %3\;div{q}\t%2"
7459 [(set_attr "type" "multi")
7460 (set_attr "length_immediate" "0")
7461 (set_attr "mode" "DI")])
7463 (define_insn "*udivmoddi4_noext"
7464 [(set (match_operand:DI 0 "register_operand" "=a")
7465 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7466 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7467 (set (match_operand:DI 3 "register_operand" "=d")
7468 (umod:DI (match_dup 1) (match_dup 2)))
7470 (clobber (reg:CC FLAGS_REG))]
7473 [(set_attr "type" "idiv")
7474 (set_attr "mode" "DI")])
7477 [(set (match_operand:DI 0 "register_operand" "")
7478 (udiv:DI (match_operand:DI 1 "register_operand" "")
7479 (match_operand:DI 2 "nonimmediate_operand" "")))
7480 (set (match_operand:DI 3 "register_operand" "")
7481 (umod:DI (match_dup 1) (match_dup 2)))
7482 (clobber (reg:CC FLAGS_REG))]
7483 "TARGET_64BIT && reload_completed"
7484 [(set (match_dup 3) (const_int 0))
7485 (parallel [(set (match_dup 0)
7486 (udiv:DI (match_dup 1) (match_dup 2)))
7488 (umod:DI (match_dup 1) (match_dup 2)))
7490 (clobber (reg:CC FLAGS_REG))])]
7493 (define_insn "udivmodsi4"
7494 [(set (match_operand:SI 0 "register_operand" "=a")
7495 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7496 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7497 (set (match_operand:SI 3 "register_operand" "=&d")
7498 (umod:SI (match_dup 1) (match_dup 2)))
7499 (clobber (reg:CC FLAGS_REG))]
7501 "xor{l}\t%3, %3\;div{l}\t%2"
7502 [(set_attr "type" "multi")
7503 (set_attr "length_immediate" "0")
7504 (set_attr "mode" "SI")])
7506 (define_insn "*udivmodsi4_noext"
7507 [(set (match_operand:SI 0 "register_operand" "=a")
7508 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7509 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7510 (set (match_operand:SI 3 "register_operand" "=d")
7511 (umod:SI (match_dup 1) (match_dup 2)))
7513 (clobber (reg:CC FLAGS_REG))]
7516 [(set_attr "type" "idiv")
7517 (set_attr "mode" "SI")])
7520 [(set (match_operand:SI 0 "register_operand" "")
7521 (udiv:SI (match_operand:SI 1 "register_operand" "")
7522 (match_operand:SI 2 "nonimmediate_operand" "")))
7523 (set (match_operand:SI 3 "register_operand" "")
7524 (umod:SI (match_dup 1) (match_dup 2)))
7525 (clobber (reg:CC FLAGS_REG))]
7527 [(set (match_dup 3) (const_int 0))
7528 (parallel [(set (match_dup 0)
7529 (udiv:SI (match_dup 1) (match_dup 2)))
7531 (umod:SI (match_dup 1) (match_dup 2)))
7533 (clobber (reg:CC FLAGS_REG))])]
7536 (define_expand "udivmodhi4"
7537 [(set (match_dup 4) (const_int 0))
7538 (parallel [(set (match_operand:HI 0 "register_operand" "")
7539 (udiv:HI (match_operand:HI 1 "register_operand" "")
7540 (match_operand:HI 2 "nonimmediate_operand" "")))
7541 (set (match_operand:HI 3 "register_operand" "")
7542 (umod:HI (match_dup 1) (match_dup 2)))
7544 (clobber (reg:CC FLAGS_REG))])]
7545 "TARGET_HIMODE_MATH"
7546 "operands[4] = gen_reg_rtx (HImode);")
7548 (define_insn "*udivmodhi_noext"
7549 [(set (match_operand:HI 0 "register_operand" "=a")
7550 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7551 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7552 (set (match_operand:HI 3 "register_operand" "=d")
7553 (umod:HI (match_dup 1) (match_dup 2)))
7554 (use (match_operand:HI 4 "register_operand" "3"))
7555 (clobber (reg:CC FLAGS_REG))]
7558 [(set_attr "type" "idiv")
7559 (set_attr "mode" "HI")])
7561 ;; We cannot use div/idiv for double division, because it causes
7562 ;; "division by zero" on the overflow and that's not what we expect
7563 ;; from truncate. Because true (non truncating) double division is
7564 ;; never generated, we can't create this insn anyway.
7567 ; [(set (match_operand:SI 0 "register_operand" "=a")
7569 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7571 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7572 ; (set (match_operand:SI 3 "register_operand" "=d")
7574 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7575 ; (clobber (reg:CC FLAGS_REG))]
7577 ; "div{l}\t{%2, %0|%0, %2}"
7578 ; [(set_attr "type" "idiv")])
7580 ;;- Logical AND instructions
7582 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7583 ;; Note that this excludes ah.
7585 (define_insn "*testdi_1_rex64"
7586 [(set (reg FLAGS_REG)
7588 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7589 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7591 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7592 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7594 test{l}\t{%k1, %k0|%k0, %k1}
7595 test{l}\t{%k1, %k0|%k0, %k1}
7596 test{q}\t{%1, %0|%0, %1}
7597 test{q}\t{%1, %0|%0, %1}
7598 test{q}\t{%1, %0|%0, %1}"
7599 [(set_attr "type" "test")
7600 (set_attr "modrm" "0,1,0,1,1")
7601 (set_attr "mode" "SI,SI,DI,DI,DI")
7602 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7604 (define_insn "testsi_1"
7605 [(set (reg FLAGS_REG)
7607 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7608 (match_operand:SI 1 "general_operand" "in,in,rin"))
7610 "ix86_match_ccmode (insn, CCNOmode)
7611 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7612 "test{l}\t{%1, %0|%0, %1}"
7613 [(set_attr "type" "test")
7614 (set_attr "modrm" "0,1,1")
7615 (set_attr "mode" "SI")
7616 (set_attr "pent_pair" "uv,np,uv")])
7618 (define_expand "testsi_ccno_1"
7619 [(set (reg:CCNO FLAGS_REG)
7621 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7622 (match_operand:SI 1 "nonmemory_operand" ""))
7627 (define_insn "*testhi_1"
7628 [(set (reg FLAGS_REG)
7629 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7630 (match_operand:HI 1 "general_operand" "n,n,rn"))
7632 "ix86_match_ccmode (insn, CCNOmode)
7633 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7634 "test{w}\t{%1, %0|%0, %1}"
7635 [(set_attr "type" "test")
7636 (set_attr "modrm" "0,1,1")
7637 (set_attr "mode" "HI")
7638 (set_attr "pent_pair" "uv,np,uv")])
7640 (define_expand "testqi_ccz_1"
7641 [(set (reg:CCZ FLAGS_REG)
7642 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7643 (match_operand:QI 1 "nonmemory_operand" ""))
7648 (define_insn "*testqi_1_maybe_si"
7649 [(set (reg FLAGS_REG)
7652 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7653 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7655 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7656 && ix86_match_ccmode (insn,
7657 GET_CODE (operands[1]) == CONST_INT
7658 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7660 if (which_alternative == 3)
7662 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7663 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7664 return "test{l}\t{%1, %k0|%k0, %1}";
7666 return "test{b}\t{%1, %0|%0, %1}";
7668 [(set_attr "type" "test")
7669 (set_attr "modrm" "0,1,1,1")
7670 (set_attr "mode" "QI,QI,QI,SI")
7671 (set_attr "pent_pair" "uv,np,uv,np")])
7673 (define_insn "*testqi_1"
7674 [(set (reg FLAGS_REG)
7677 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7678 (match_operand:QI 1 "general_operand" "n,n,qn"))
7680 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7681 && ix86_match_ccmode (insn, CCNOmode)"
7682 "test{b}\t{%1, %0|%0, %1}"
7683 [(set_attr "type" "test")
7684 (set_attr "modrm" "0,1,1")
7685 (set_attr "mode" "QI")
7686 (set_attr "pent_pair" "uv,np,uv")])
7688 (define_expand "testqi_ext_ccno_0"
7689 [(set (reg:CCNO FLAGS_REG)
7693 (match_operand 0 "ext_register_operand" "")
7696 (match_operand 1 "const_int_operand" ""))
7701 (define_insn "*testqi_ext_0"
7702 [(set (reg FLAGS_REG)
7706 (match_operand 0 "ext_register_operand" "Q")
7709 (match_operand 1 "const_int_operand" "n"))
7711 "ix86_match_ccmode (insn, CCNOmode)"
7712 "test{b}\t{%1, %h0|%h0, %1}"
7713 [(set_attr "type" "test")
7714 (set_attr "mode" "QI")
7715 (set_attr "length_immediate" "1")
7716 (set_attr "pent_pair" "np")])
7718 (define_insn "*testqi_ext_1"
7719 [(set (reg FLAGS_REG)
7723 (match_operand 0 "ext_register_operand" "Q")
7727 (match_operand:QI 1 "general_operand" "Qm")))
7729 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7730 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7731 "test{b}\t{%1, %h0|%h0, %1}"
7732 [(set_attr "type" "test")
7733 (set_attr "mode" "QI")])
7735 (define_insn "*testqi_ext_1_rex64"
7736 [(set (reg FLAGS_REG)
7740 (match_operand 0 "ext_register_operand" "Q")
7744 (match_operand:QI 1 "register_operand" "Q")))
7746 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7747 "test{b}\t{%1, %h0|%h0, %1}"
7748 [(set_attr "type" "test")
7749 (set_attr "mode" "QI")])
7751 (define_insn "*testqi_ext_2"
7752 [(set (reg FLAGS_REG)
7756 (match_operand 0 "ext_register_operand" "Q")
7760 (match_operand 1 "ext_register_operand" "Q")
7764 "ix86_match_ccmode (insn, CCNOmode)"
7765 "test{b}\t{%h1, %h0|%h0, %h1}"
7766 [(set_attr "type" "test")
7767 (set_attr "mode" "QI")])
7769 ;; Combine likes to form bit extractions for some tests. Humor it.
7770 (define_insn "*testqi_ext_3"
7771 [(set (reg FLAGS_REG)
7772 (compare (zero_extract:SI
7773 (match_operand 0 "nonimmediate_operand" "rm")
7774 (match_operand:SI 1 "const_int_operand" "")
7775 (match_operand:SI 2 "const_int_operand" ""))
7777 "ix86_match_ccmode (insn, CCNOmode)
7778 && (GET_MODE (operands[0]) == SImode
7779 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7780 || GET_MODE (operands[0]) == HImode
7781 || GET_MODE (operands[0]) == QImode)"
7784 (define_insn "*testqi_ext_3_rex64"
7785 [(set (reg FLAGS_REG)
7786 (compare (zero_extract:DI
7787 (match_operand 0 "nonimmediate_operand" "rm")
7788 (match_operand:DI 1 "const_int_operand" "")
7789 (match_operand:DI 2 "const_int_operand" ""))
7792 && ix86_match_ccmode (insn, CCNOmode)
7793 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7794 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7795 /* Ensure that resulting mask is zero or sign extended operand. */
7796 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7797 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7798 && INTVAL (operands[1]) > 32))
7799 && (GET_MODE (operands[0]) == SImode
7800 || GET_MODE (operands[0]) == DImode
7801 || GET_MODE (operands[0]) == HImode
7802 || GET_MODE (operands[0]) == QImode)"
7806 [(set (match_operand 0 "flags_reg_operand" "")
7807 (match_operator 1 "compare_operator"
7809 (match_operand 2 "nonimmediate_operand" "")
7810 (match_operand 3 "const_int_operand" "")
7811 (match_operand 4 "const_int_operand" ""))
7813 "ix86_match_ccmode (insn, CCNOmode)"
7814 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7816 rtx val = operands[2];
7817 HOST_WIDE_INT len = INTVAL (operands[3]);
7818 HOST_WIDE_INT pos = INTVAL (operands[4]);
7820 enum machine_mode mode, submode;
7822 mode = GET_MODE (val);
7823 if (GET_CODE (val) == MEM)
7825 /* ??? Combine likes to put non-volatile mem extractions in QImode
7826 no matter the size of the test. So find a mode that works. */
7827 if (! MEM_VOLATILE_P (val))
7829 mode = smallest_mode_for_size (pos + len, MODE_INT);
7830 val = adjust_address (val, mode, 0);
7833 else if (GET_CODE (val) == SUBREG
7834 && (submode = GET_MODE (SUBREG_REG (val)),
7835 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7836 && pos + len <= GET_MODE_BITSIZE (submode))
7838 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7840 val = SUBREG_REG (val);
7842 else if (mode == HImode && pos + len <= 8)
7844 /* Small HImode tests can be converted to QImode. */
7846 val = gen_lowpart (QImode, val);
7849 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7850 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7852 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7855 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7856 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7857 ;; this is relatively important trick.
7858 ;; Do the conversion only post-reload to avoid limiting of the register class
7861 [(set (match_operand 0 "flags_reg_operand" "")
7862 (match_operator 1 "compare_operator"
7863 [(and (match_operand 2 "register_operand" "")
7864 (match_operand 3 "const_int_operand" ""))
7867 && QI_REG_P (operands[2])
7868 && GET_MODE (operands[2]) != QImode
7869 && ((ix86_match_ccmode (insn, CCZmode)
7870 && !(INTVAL (operands[3]) & ~(255 << 8)))
7871 || (ix86_match_ccmode (insn, CCNOmode)
7872 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7875 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7878 "operands[2] = gen_lowpart (SImode, operands[2]);
7879 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7882 [(set (match_operand 0 "flags_reg_operand" "")
7883 (match_operator 1 "compare_operator"
7884 [(and (match_operand 2 "nonimmediate_operand" "")
7885 (match_operand 3 "const_int_operand" ""))
7888 && GET_MODE (operands[2]) != QImode
7889 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7890 && ((ix86_match_ccmode (insn, CCZmode)
7891 && !(INTVAL (operands[3]) & ~255))
7892 || (ix86_match_ccmode (insn, CCNOmode)
7893 && !(INTVAL (operands[3]) & ~127)))"
7895 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7897 "operands[2] = gen_lowpart (QImode, operands[2]);
7898 operands[3] = gen_lowpart (QImode, operands[3]);")
7901 ;; %%% This used to optimize known byte-wide and operations to memory,
7902 ;; and sometimes to QImode registers. If this is considered useful,
7903 ;; it should be done with splitters.
7905 (define_expand "anddi3"
7906 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7907 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7908 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7909 (clobber (reg:CC FLAGS_REG))]
7911 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7913 (define_insn "*anddi_1_rex64"
7914 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7915 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7916 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7917 (clobber (reg:CC FLAGS_REG))]
7918 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7920 switch (get_attr_type (insn))
7924 enum machine_mode mode;
7926 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
7927 if (INTVAL (operands[2]) == 0xff)
7931 gcc_assert (INTVAL (operands[2]) == 0xffff);
7935 operands[1] = gen_lowpart (mode, operands[1]);
7937 return "movz{bq|x}\t{%1,%0|%0, %1}";
7939 return "movz{wq|x}\t{%1,%0|%0, %1}";
7943 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7944 if (get_attr_mode (insn) == MODE_SI)
7945 return "and{l}\t{%k2, %k0|%k0, %k2}";
7947 return "and{q}\t{%2, %0|%0, %2}";
7950 [(set_attr "type" "alu,alu,alu,imovx")
7951 (set_attr "length_immediate" "*,*,*,0")
7952 (set_attr "mode" "SI,DI,DI,DI")])
7954 (define_insn "*anddi_2"
7955 [(set (reg FLAGS_REG)
7956 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7957 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7959 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7960 (and:DI (match_dup 1) (match_dup 2)))]
7961 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7962 && ix86_binary_operator_ok (AND, DImode, operands)"
7964 and{l}\t{%k2, %k0|%k0, %k2}
7965 and{q}\t{%2, %0|%0, %2}
7966 and{q}\t{%2, %0|%0, %2}"
7967 [(set_attr "type" "alu")
7968 (set_attr "mode" "SI,DI,DI")])
7970 (define_expand "andsi3"
7971 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7972 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7973 (match_operand:SI 2 "general_operand" "")))
7974 (clobber (reg:CC FLAGS_REG))]
7976 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
7978 (define_insn "*andsi_1"
7979 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7980 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7981 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7982 (clobber (reg:CC FLAGS_REG))]
7983 "ix86_binary_operator_ok (AND, SImode, operands)"
7985 switch (get_attr_type (insn))
7989 enum machine_mode mode;
7991 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
7992 if (INTVAL (operands[2]) == 0xff)
7996 gcc_assert (INTVAL (operands[2]) == 0xffff);
8000 operands[1] = gen_lowpart (mode, operands[1]);
8002 return "movz{bl|x}\t{%1,%0|%0, %1}";
8004 return "movz{wl|x}\t{%1,%0|%0, %1}";
8008 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8009 return "and{l}\t{%2, %0|%0, %2}";
8012 [(set_attr "type" "alu,alu,imovx")
8013 (set_attr "length_immediate" "*,*,0")
8014 (set_attr "mode" "SI")])
8017 [(set (match_operand 0 "register_operand" "")
8019 (const_int -65536)))
8020 (clobber (reg:CC FLAGS_REG))]
8021 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8022 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8023 "operands[1] = gen_lowpart (HImode, operands[0]);")
8026 [(set (match_operand 0 "ext_register_operand" "")
8029 (clobber (reg:CC FLAGS_REG))]
8030 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8031 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8032 "operands[1] = gen_lowpart (QImode, operands[0]);")
8035 [(set (match_operand 0 "ext_register_operand" "")
8037 (const_int -65281)))
8038 (clobber (reg:CC FLAGS_REG))]
8039 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8040 [(parallel [(set (zero_extract:SI (match_dup 0)
8044 (zero_extract:SI (match_dup 0)
8047 (zero_extract:SI (match_dup 0)
8050 (clobber (reg:CC FLAGS_REG))])]
8051 "operands[0] = gen_lowpart (SImode, operands[0]);")
8053 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8054 (define_insn "*andsi_1_zext"
8055 [(set (match_operand:DI 0 "register_operand" "=r")
8057 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8058 (match_operand:SI 2 "general_operand" "rim"))))
8059 (clobber (reg:CC FLAGS_REG))]
8060 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8061 "and{l}\t{%2, %k0|%k0, %2}"
8062 [(set_attr "type" "alu")
8063 (set_attr "mode" "SI")])
8065 (define_insn "*andsi_2"
8066 [(set (reg FLAGS_REG)
8067 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8068 (match_operand:SI 2 "general_operand" "rim,ri"))
8070 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8071 (and:SI (match_dup 1) (match_dup 2)))]
8072 "ix86_match_ccmode (insn, CCNOmode)
8073 && ix86_binary_operator_ok (AND, SImode, operands)"
8074 "and{l}\t{%2, %0|%0, %2}"
8075 [(set_attr "type" "alu")
8076 (set_attr "mode" "SI")])
8078 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8079 (define_insn "*andsi_2_zext"
8080 [(set (reg FLAGS_REG)
8081 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8082 (match_operand:SI 2 "general_operand" "rim"))
8084 (set (match_operand:DI 0 "register_operand" "=r")
8085 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8086 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8087 && ix86_binary_operator_ok (AND, SImode, operands)"
8088 "and{l}\t{%2, %k0|%k0, %2}"
8089 [(set_attr "type" "alu")
8090 (set_attr "mode" "SI")])
8092 (define_expand "andhi3"
8093 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8094 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8095 (match_operand:HI 2 "general_operand" "")))
8096 (clobber (reg:CC FLAGS_REG))]
8097 "TARGET_HIMODE_MATH"
8098 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8100 (define_insn "*andhi_1"
8101 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8102 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8103 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8104 (clobber (reg:CC FLAGS_REG))]
8105 "ix86_binary_operator_ok (AND, HImode, operands)"
8107 switch (get_attr_type (insn))
8110 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8111 gcc_assert (INTVAL (operands[2]) == 0xff);
8112 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8115 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8117 return "and{w}\t{%2, %0|%0, %2}";
8120 [(set_attr "type" "alu,alu,imovx")
8121 (set_attr "length_immediate" "*,*,0")
8122 (set_attr "mode" "HI,HI,SI")])
8124 (define_insn "*andhi_2"
8125 [(set (reg FLAGS_REG)
8126 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8127 (match_operand:HI 2 "general_operand" "rim,ri"))
8129 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8130 (and:HI (match_dup 1) (match_dup 2)))]
8131 "ix86_match_ccmode (insn, CCNOmode)
8132 && ix86_binary_operator_ok (AND, HImode, operands)"
8133 "and{w}\t{%2, %0|%0, %2}"
8134 [(set_attr "type" "alu")
8135 (set_attr "mode" "HI")])
8137 (define_expand "andqi3"
8138 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8139 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8140 (match_operand:QI 2 "general_operand" "")))
8141 (clobber (reg:CC FLAGS_REG))]
8142 "TARGET_QIMODE_MATH"
8143 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8145 ;; %%% Potential partial reg stall on alternative 2. What to do?
8146 (define_insn "*andqi_1"
8147 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8148 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8149 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8150 (clobber (reg:CC FLAGS_REG))]
8151 "ix86_binary_operator_ok (AND, QImode, operands)"
8153 and{b}\t{%2, %0|%0, %2}
8154 and{b}\t{%2, %0|%0, %2}
8155 and{l}\t{%k2, %k0|%k0, %k2}"
8156 [(set_attr "type" "alu")
8157 (set_attr "mode" "QI,QI,SI")])
8159 (define_insn "*andqi_1_slp"
8160 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8161 (and:QI (match_dup 0)
8162 (match_operand:QI 1 "general_operand" "qi,qmi")))
8163 (clobber (reg:CC FLAGS_REG))]
8164 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8165 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8166 "and{b}\t{%1, %0|%0, %1}"
8167 [(set_attr "type" "alu1")
8168 (set_attr "mode" "QI")])
8170 (define_insn "*andqi_2_maybe_si"
8171 [(set (reg FLAGS_REG)
8173 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8174 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8176 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8177 (and:QI (match_dup 1) (match_dup 2)))]
8178 "ix86_binary_operator_ok (AND, QImode, operands)
8179 && ix86_match_ccmode (insn,
8180 GET_CODE (operands[2]) == CONST_INT
8181 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8183 if (which_alternative == 2)
8185 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8186 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8187 return "and{l}\t{%2, %k0|%k0, %2}";
8189 return "and{b}\t{%2, %0|%0, %2}";
8191 [(set_attr "type" "alu")
8192 (set_attr "mode" "QI,QI,SI")])
8194 (define_insn "*andqi_2"
8195 [(set (reg FLAGS_REG)
8197 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8198 (match_operand:QI 2 "general_operand" "qim,qi"))
8200 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8201 (and:QI (match_dup 1) (match_dup 2)))]
8202 "ix86_match_ccmode (insn, CCNOmode)
8203 && ix86_binary_operator_ok (AND, QImode, operands)"
8204 "and{b}\t{%2, %0|%0, %2}"
8205 [(set_attr "type" "alu")
8206 (set_attr "mode" "QI")])
8208 (define_insn "*andqi_2_slp"
8209 [(set (reg FLAGS_REG)
8211 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8212 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8214 (set (strict_low_part (match_dup 0))
8215 (and:QI (match_dup 0) (match_dup 1)))]
8216 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8217 && ix86_match_ccmode (insn, CCNOmode)
8218 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8219 "and{b}\t{%1, %0|%0, %1}"
8220 [(set_attr "type" "alu1")
8221 (set_attr "mode" "QI")])
8223 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8224 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8225 ;; for a QImode operand, which of course failed.
8227 (define_insn "andqi_ext_0"
8228 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8233 (match_operand 1 "ext_register_operand" "0")
8236 (match_operand 2 "const_int_operand" "n")))
8237 (clobber (reg:CC FLAGS_REG))]
8239 "and{b}\t{%2, %h0|%h0, %2}"
8240 [(set_attr "type" "alu")
8241 (set_attr "length_immediate" "1")
8242 (set_attr "mode" "QI")])
8244 ;; Generated by peephole translating test to and. This shows up
8245 ;; often in fp comparisons.
8247 (define_insn "*andqi_ext_0_cc"
8248 [(set (reg FLAGS_REG)
8252 (match_operand 1 "ext_register_operand" "0")
8255 (match_operand 2 "const_int_operand" "n"))
8257 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8266 "ix86_match_ccmode (insn, CCNOmode)"
8267 "and{b}\t{%2, %h0|%h0, %2}"
8268 [(set_attr "type" "alu")
8269 (set_attr "length_immediate" "1")
8270 (set_attr "mode" "QI")])
8272 (define_insn "*andqi_ext_1"
8273 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8278 (match_operand 1 "ext_register_operand" "0")
8282 (match_operand:QI 2 "general_operand" "Qm"))))
8283 (clobber (reg:CC FLAGS_REG))]
8285 "and{b}\t{%2, %h0|%h0, %2}"
8286 [(set_attr "type" "alu")
8287 (set_attr "length_immediate" "0")
8288 (set_attr "mode" "QI")])
8290 (define_insn "*andqi_ext_1_rex64"
8291 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8296 (match_operand 1 "ext_register_operand" "0")
8300 (match_operand 2 "ext_register_operand" "Q"))))
8301 (clobber (reg:CC FLAGS_REG))]
8303 "and{b}\t{%2, %h0|%h0, %2}"
8304 [(set_attr "type" "alu")
8305 (set_attr "length_immediate" "0")
8306 (set_attr "mode" "QI")])
8308 (define_insn "*andqi_ext_2"
8309 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8314 (match_operand 1 "ext_register_operand" "%0")
8318 (match_operand 2 "ext_register_operand" "Q")
8321 (clobber (reg:CC FLAGS_REG))]
8323 "and{b}\t{%h2, %h0|%h0, %h2}"
8324 [(set_attr "type" "alu")
8325 (set_attr "length_immediate" "0")
8326 (set_attr "mode" "QI")])
8328 ;; Convert wide AND instructions with immediate operand to shorter QImode
8329 ;; equivalents when possible.
8330 ;; Don't do the splitting with memory operands, since it introduces risk
8331 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8332 ;; for size, but that can (should?) be handled by generic code instead.
8334 [(set (match_operand 0 "register_operand" "")
8335 (and (match_operand 1 "register_operand" "")
8336 (match_operand 2 "const_int_operand" "")))
8337 (clobber (reg:CC FLAGS_REG))]
8339 && QI_REG_P (operands[0])
8340 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8341 && !(~INTVAL (operands[2]) & ~(255 << 8))
8342 && GET_MODE (operands[0]) != QImode"
8343 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8344 (and:SI (zero_extract:SI (match_dup 1)
8345 (const_int 8) (const_int 8))
8347 (clobber (reg:CC FLAGS_REG))])]
8348 "operands[0] = gen_lowpart (SImode, operands[0]);
8349 operands[1] = gen_lowpart (SImode, operands[1]);
8350 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8352 ;; Since AND can be encoded with sign extended immediate, this is only
8353 ;; profitable when 7th bit is not set.
8355 [(set (match_operand 0 "register_operand" "")
8356 (and (match_operand 1 "general_operand" "")
8357 (match_operand 2 "const_int_operand" "")))
8358 (clobber (reg:CC FLAGS_REG))]
8360 && ANY_QI_REG_P (operands[0])
8361 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8362 && !(~INTVAL (operands[2]) & ~255)
8363 && !(INTVAL (operands[2]) & 128)
8364 && GET_MODE (operands[0]) != QImode"
8365 [(parallel [(set (strict_low_part (match_dup 0))
8366 (and:QI (match_dup 1)
8368 (clobber (reg:CC FLAGS_REG))])]
8369 "operands[0] = gen_lowpart (QImode, operands[0]);
8370 operands[1] = gen_lowpart (QImode, operands[1]);
8371 operands[2] = gen_lowpart (QImode, operands[2]);")
8373 ;; Logical inclusive OR instructions
8375 ;; %%% This used to optimize known byte-wide and operations to memory.
8376 ;; If this is considered useful, it should be done with splitters.
8378 (define_expand "iordi3"
8379 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8380 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8381 (match_operand:DI 2 "x86_64_general_operand" "")))
8382 (clobber (reg:CC FLAGS_REG))]
8384 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8386 (define_insn "*iordi_1_rex64"
8387 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8388 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8389 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8390 (clobber (reg:CC FLAGS_REG))]
8392 && ix86_binary_operator_ok (IOR, DImode, operands)"
8393 "or{q}\t{%2, %0|%0, %2}"
8394 [(set_attr "type" "alu")
8395 (set_attr "mode" "DI")])
8397 (define_insn "*iordi_2_rex64"
8398 [(set (reg FLAGS_REG)
8399 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8400 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8402 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8403 (ior:DI (match_dup 1) (match_dup 2)))]
8405 && ix86_match_ccmode (insn, CCNOmode)
8406 && ix86_binary_operator_ok (IOR, DImode, operands)"
8407 "or{q}\t{%2, %0|%0, %2}"
8408 [(set_attr "type" "alu")
8409 (set_attr "mode" "DI")])
8411 (define_insn "*iordi_3_rex64"
8412 [(set (reg FLAGS_REG)
8413 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8414 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8416 (clobber (match_scratch:DI 0 "=r"))]
8418 && ix86_match_ccmode (insn, CCNOmode)
8419 && ix86_binary_operator_ok (IOR, DImode, operands)"
8420 "or{q}\t{%2, %0|%0, %2}"
8421 [(set_attr "type" "alu")
8422 (set_attr "mode" "DI")])
8425 (define_expand "iorsi3"
8426 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8427 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8428 (match_operand:SI 2 "general_operand" "")))
8429 (clobber (reg:CC FLAGS_REG))]
8431 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8433 (define_insn "*iorsi_1"
8434 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8435 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8436 (match_operand:SI 2 "general_operand" "ri,rmi")))
8437 (clobber (reg:CC FLAGS_REG))]
8438 "ix86_binary_operator_ok (IOR, SImode, operands)"
8439 "or{l}\t{%2, %0|%0, %2}"
8440 [(set_attr "type" "alu")
8441 (set_attr "mode" "SI")])
8443 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8444 (define_insn "*iorsi_1_zext"
8445 [(set (match_operand:DI 0 "register_operand" "=rm")
8447 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8448 (match_operand:SI 2 "general_operand" "rim"))))
8449 (clobber (reg:CC FLAGS_REG))]
8450 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8451 "or{l}\t{%2, %k0|%k0, %2}"
8452 [(set_attr "type" "alu")
8453 (set_attr "mode" "SI")])
8455 (define_insn "*iorsi_1_zext_imm"
8456 [(set (match_operand:DI 0 "register_operand" "=rm")
8457 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8458 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8459 (clobber (reg:CC FLAGS_REG))]
8461 "or{l}\t{%2, %k0|%k0, %2}"
8462 [(set_attr "type" "alu")
8463 (set_attr "mode" "SI")])
8465 (define_insn "*iorsi_2"
8466 [(set (reg FLAGS_REG)
8467 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8468 (match_operand:SI 2 "general_operand" "rim,ri"))
8470 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8471 (ior:SI (match_dup 1) (match_dup 2)))]
8472 "ix86_match_ccmode (insn, CCNOmode)
8473 && ix86_binary_operator_ok (IOR, SImode, operands)"
8474 "or{l}\t{%2, %0|%0, %2}"
8475 [(set_attr "type" "alu")
8476 (set_attr "mode" "SI")])
8478 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8479 ;; ??? Special case for immediate operand is missing - it is tricky.
8480 (define_insn "*iorsi_2_zext"
8481 [(set (reg FLAGS_REG)
8482 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8483 (match_operand:SI 2 "general_operand" "rim"))
8485 (set (match_operand:DI 0 "register_operand" "=r")
8486 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8487 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8488 && ix86_binary_operator_ok (IOR, SImode, operands)"
8489 "or{l}\t{%2, %k0|%k0, %2}"
8490 [(set_attr "type" "alu")
8491 (set_attr "mode" "SI")])
8493 (define_insn "*iorsi_2_zext_imm"
8494 [(set (reg FLAGS_REG)
8495 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8496 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8498 (set (match_operand:DI 0 "register_operand" "=r")
8499 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8500 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8501 && ix86_binary_operator_ok (IOR, SImode, operands)"
8502 "or{l}\t{%2, %k0|%k0, %2}"
8503 [(set_attr "type" "alu")
8504 (set_attr "mode" "SI")])
8506 (define_insn "*iorsi_3"
8507 [(set (reg FLAGS_REG)
8508 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8509 (match_operand:SI 2 "general_operand" "rim"))
8511 (clobber (match_scratch:SI 0 "=r"))]
8512 "ix86_match_ccmode (insn, CCNOmode)
8513 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8514 "or{l}\t{%2, %0|%0, %2}"
8515 [(set_attr "type" "alu")
8516 (set_attr "mode" "SI")])
8518 (define_expand "iorhi3"
8519 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8520 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8521 (match_operand:HI 2 "general_operand" "")))
8522 (clobber (reg:CC FLAGS_REG))]
8523 "TARGET_HIMODE_MATH"
8524 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8526 (define_insn "*iorhi_1"
8527 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8528 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8529 (match_operand:HI 2 "general_operand" "rmi,ri")))
8530 (clobber (reg:CC FLAGS_REG))]
8531 "ix86_binary_operator_ok (IOR, HImode, operands)"
8532 "or{w}\t{%2, %0|%0, %2}"
8533 [(set_attr "type" "alu")
8534 (set_attr "mode" "HI")])
8536 (define_insn "*iorhi_2"
8537 [(set (reg FLAGS_REG)
8538 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8539 (match_operand:HI 2 "general_operand" "rim,ri"))
8541 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8542 (ior:HI (match_dup 1) (match_dup 2)))]
8543 "ix86_match_ccmode (insn, CCNOmode)
8544 && ix86_binary_operator_ok (IOR, HImode, operands)"
8545 "or{w}\t{%2, %0|%0, %2}"
8546 [(set_attr "type" "alu")
8547 (set_attr "mode" "HI")])
8549 (define_insn "*iorhi_3"
8550 [(set (reg FLAGS_REG)
8551 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8552 (match_operand:HI 2 "general_operand" "rim"))
8554 (clobber (match_scratch:HI 0 "=r"))]
8555 "ix86_match_ccmode (insn, CCNOmode)
8556 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8557 "or{w}\t{%2, %0|%0, %2}"
8558 [(set_attr "type" "alu")
8559 (set_attr "mode" "HI")])
8561 (define_expand "iorqi3"
8562 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8563 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8564 (match_operand:QI 2 "general_operand" "")))
8565 (clobber (reg:CC FLAGS_REG))]
8566 "TARGET_QIMODE_MATH"
8567 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8569 ;; %%% Potential partial reg stall on alternative 2. What to do?
8570 (define_insn "*iorqi_1"
8571 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8572 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8573 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8574 (clobber (reg:CC FLAGS_REG))]
8575 "ix86_binary_operator_ok (IOR, QImode, operands)"
8577 or{b}\t{%2, %0|%0, %2}
8578 or{b}\t{%2, %0|%0, %2}
8579 or{l}\t{%k2, %k0|%k0, %k2}"
8580 [(set_attr "type" "alu")
8581 (set_attr "mode" "QI,QI,SI")])
8583 (define_insn "*iorqi_1_slp"
8584 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8585 (ior:QI (match_dup 0)
8586 (match_operand:QI 1 "general_operand" "qmi,qi")))
8587 (clobber (reg:CC FLAGS_REG))]
8588 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8589 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8590 "or{b}\t{%1, %0|%0, %1}"
8591 [(set_attr "type" "alu1")
8592 (set_attr "mode" "QI")])
8594 (define_insn "*iorqi_2"
8595 [(set (reg FLAGS_REG)
8596 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8597 (match_operand:QI 2 "general_operand" "qim,qi"))
8599 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8600 (ior:QI (match_dup 1) (match_dup 2)))]
8601 "ix86_match_ccmode (insn, CCNOmode)
8602 && ix86_binary_operator_ok (IOR, QImode, operands)"
8603 "or{b}\t{%2, %0|%0, %2}"
8604 [(set_attr "type" "alu")
8605 (set_attr "mode" "QI")])
8607 (define_insn "*iorqi_2_slp"
8608 [(set (reg FLAGS_REG)
8609 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8610 (match_operand:QI 1 "general_operand" "qim,qi"))
8612 (set (strict_low_part (match_dup 0))
8613 (ior:QI (match_dup 0) (match_dup 1)))]
8614 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8615 && ix86_match_ccmode (insn, CCNOmode)
8616 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8617 "or{b}\t{%1, %0|%0, %1}"
8618 [(set_attr "type" "alu1")
8619 (set_attr "mode" "QI")])
8621 (define_insn "*iorqi_3"
8622 [(set (reg FLAGS_REG)
8623 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8624 (match_operand:QI 2 "general_operand" "qim"))
8626 (clobber (match_scratch:QI 0 "=q"))]
8627 "ix86_match_ccmode (insn, CCNOmode)
8628 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8629 "or{b}\t{%2, %0|%0, %2}"
8630 [(set_attr "type" "alu")
8631 (set_attr "mode" "QI")])
8633 (define_insn "iorqi_ext_0"
8634 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8639 (match_operand 1 "ext_register_operand" "0")
8642 (match_operand 2 "const_int_operand" "n")))
8643 (clobber (reg:CC FLAGS_REG))]
8644 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8645 "or{b}\t{%2, %h0|%h0, %2}"
8646 [(set_attr "type" "alu")
8647 (set_attr "length_immediate" "1")
8648 (set_attr "mode" "QI")])
8650 (define_insn "*iorqi_ext_1"
8651 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8656 (match_operand 1 "ext_register_operand" "0")
8660 (match_operand:QI 2 "general_operand" "Qm"))))
8661 (clobber (reg:CC FLAGS_REG))]
8663 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8664 "or{b}\t{%2, %h0|%h0, %2}"
8665 [(set_attr "type" "alu")
8666 (set_attr "length_immediate" "0")
8667 (set_attr "mode" "QI")])
8669 (define_insn "*iorqi_ext_1_rex64"
8670 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8675 (match_operand 1 "ext_register_operand" "0")
8679 (match_operand 2 "ext_register_operand" "Q"))))
8680 (clobber (reg:CC FLAGS_REG))]
8682 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8683 "or{b}\t{%2, %h0|%h0, %2}"
8684 [(set_attr "type" "alu")
8685 (set_attr "length_immediate" "0")
8686 (set_attr "mode" "QI")])
8688 (define_insn "*iorqi_ext_2"
8689 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8693 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8696 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8699 (clobber (reg:CC FLAGS_REG))]
8700 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8701 "ior{b}\t{%h2, %h0|%h0, %h2}"
8702 [(set_attr "type" "alu")
8703 (set_attr "length_immediate" "0")
8704 (set_attr "mode" "QI")])
8707 [(set (match_operand 0 "register_operand" "")
8708 (ior (match_operand 1 "register_operand" "")
8709 (match_operand 2 "const_int_operand" "")))
8710 (clobber (reg:CC FLAGS_REG))]
8712 && QI_REG_P (operands[0])
8713 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8714 && !(INTVAL (operands[2]) & ~(255 << 8))
8715 && GET_MODE (operands[0]) != QImode"
8716 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8717 (ior:SI (zero_extract:SI (match_dup 1)
8718 (const_int 8) (const_int 8))
8720 (clobber (reg:CC FLAGS_REG))])]
8721 "operands[0] = gen_lowpart (SImode, operands[0]);
8722 operands[1] = gen_lowpart (SImode, operands[1]);
8723 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8725 ;; Since OR can be encoded with sign extended immediate, this is only
8726 ;; profitable when 7th bit is set.
8728 [(set (match_operand 0 "register_operand" "")
8729 (ior (match_operand 1 "general_operand" "")
8730 (match_operand 2 "const_int_operand" "")))
8731 (clobber (reg:CC FLAGS_REG))]
8733 && ANY_QI_REG_P (operands[0])
8734 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8735 && !(INTVAL (operands[2]) & ~255)
8736 && (INTVAL (operands[2]) & 128)
8737 && GET_MODE (operands[0]) != QImode"
8738 [(parallel [(set (strict_low_part (match_dup 0))
8739 (ior:QI (match_dup 1)
8741 (clobber (reg:CC FLAGS_REG))])]
8742 "operands[0] = gen_lowpart (QImode, operands[0]);
8743 operands[1] = gen_lowpart (QImode, operands[1]);
8744 operands[2] = gen_lowpart (QImode, operands[2]);")
8746 ;; Logical XOR instructions
8748 ;; %%% This used to optimize known byte-wide and operations to memory.
8749 ;; If this is considered useful, it should be done with splitters.
8751 (define_expand "xordi3"
8752 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8753 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8754 (match_operand:DI 2 "x86_64_general_operand" "")))
8755 (clobber (reg:CC FLAGS_REG))]
8757 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8759 (define_insn "*xordi_1_rex64"
8760 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8761 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8762 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8763 (clobber (reg:CC FLAGS_REG))]
8765 && ix86_binary_operator_ok (XOR, DImode, operands)"
8767 xor{q}\t{%2, %0|%0, %2}
8768 xor{q}\t{%2, %0|%0, %2}"
8769 [(set_attr "type" "alu")
8770 (set_attr "mode" "DI,DI")])
8772 (define_insn "*xordi_2_rex64"
8773 [(set (reg FLAGS_REG)
8774 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8775 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8777 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8778 (xor:DI (match_dup 1) (match_dup 2)))]
8780 && ix86_match_ccmode (insn, CCNOmode)
8781 && ix86_binary_operator_ok (XOR, DImode, operands)"
8783 xor{q}\t{%2, %0|%0, %2}
8784 xor{q}\t{%2, %0|%0, %2}"
8785 [(set_attr "type" "alu")
8786 (set_attr "mode" "DI,DI")])
8788 (define_insn "*xordi_3_rex64"
8789 [(set (reg FLAGS_REG)
8790 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8791 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8793 (clobber (match_scratch:DI 0 "=r"))]
8795 && ix86_match_ccmode (insn, CCNOmode)
8796 && ix86_binary_operator_ok (XOR, DImode, operands)"
8797 "xor{q}\t{%2, %0|%0, %2}"
8798 [(set_attr "type" "alu")
8799 (set_attr "mode" "DI")])
8801 (define_expand "xorsi3"
8802 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8803 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8804 (match_operand:SI 2 "general_operand" "")))
8805 (clobber (reg:CC FLAGS_REG))]
8807 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8809 (define_insn "*xorsi_1"
8810 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8811 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8812 (match_operand:SI 2 "general_operand" "ri,rm")))
8813 (clobber (reg:CC FLAGS_REG))]
8814 "ix86_binary_operator_ok (XOR, SImode, operands)"
8815 "xor{l}\t{%2, %0|%0, %2}"
8816 [(set_attr "type" "alu")
8817 (set_attr "mode" "SI")])
8819 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8820 ;; Add speccase for immediates
8821 (define_insn "*xorsi_1_zext"
8822 [(set (match_operand:DI 0 "register_operand" "=r")
8824 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8825 (match_operand:SI 2 "general_operand" "rim"))))
8826 (clobber (reg:CC FLAGS_REG))]
8827 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8828 "xor{l}\t{%2, %k0|%k0, %2}"
8829 [(set_attr "type" "alu")
8830 (set_attr "mode" "SI")])
8832 (define_insn "*xorsi_1_zext_imm"
8833 [(set (match_operand:DI 0 "register_operand" "=r")
8834 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8835 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8836 (clobber (reg:CC FLAGS_REG))]
8837 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8838 "xor{l}\t{%2, %k0|%k0, %2}"
8839 [(set_attr "type" "alu")
8840 (set_attr "mode" "SI")])
8842 (define_insn "*xorsi_2"
8843 [(set (reg FLAGS_REG)
8844 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8845 (match_operand:SI 2 "general_operand" "rim,ri"))
8847 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8848 (xor:SI (match_dup 1) (match_dup 2)))]
8849 "ix86_match_ccmode (insn, CCNOmode)
8850 && ix86_binary_operator_ok (XOR, SImode, operands)"
8851 "xor{l}\t{%2, %0|%0, %2}"
8852 [(set_attr "type" "alu")
8853 (set_attr "mode" "SI")])
8855 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8856 ;; ??? Special case for immediate operand is missing - it is tricky.
8857 (define_insn "*xorsi_2_zext"
8858 [(set (reg FLAGS_REG)
8859 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8860 (match_operand:SI 2 "general_operand" "rim"))
8862 (set (match_operand:DI 0 "register_operand" "=r")
8863 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8864 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8865 && ix86_binary_operator_ok (XOR, SImode, operands)"
8866 "xor{l}\t{%2, %k0|%k0, %2}"
8867 [(set_attr "type" "alu")
8868 (set_attr "mode" "SI")])
8870 (define_insn "*xorsi_2_zext_imm"
8871 [(set (reg FLAGS_REG)
8872 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8873 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8875 (set (match_operand:DI 0 "register_operand" "=r")
8876 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8877 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8878 && ix86_binary_operator_ok (XOR, SImode, operands)"
8879 "xor{l}\t{%2, %k0|%k0, %2}"
8880 [(set_attr "type" "alu")
8881 (set_attr "mode" "SI")])
8883 (define_insn "*xorsi_3"
8884 [(set (reg FLAGS_REG)
8885 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8886 (match_operand:SI 2 "general_operand" "rim"))
8888 (clobber (match_scratch:SI 0 "=r"))]
8889 "ix86_match_ccmode (insn, CCNOmode)
8890 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8891 "xor{l}\t{%2, %0|%0, %2}"
8892 [(set_attr "type" "alu")
8893 (set_attr "mode" "SI")])
8895 (define_expand "xorhi3"
8896 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8897 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8898 (match_operand:HI 2 "general_operand" "")))
8899 (clobber (reg:CC FLAGS_REG))]
8900 "TARGET_HIMODE_MATH"
8901 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8903 (define_insn "*xorhi_1"
8904 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8905 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8906 (match_operand:HI 2 "general_operand" "rmi,ri")))
8907 (clobber (reg:CC FLAGS_REG))]
8908 "ix86_binary_operator_ok (XOR, HImode, operands)"
8909 "xor{w}\t{%2, %0|%0, %2}"
8910 [(set_attr "type" "alu")
8911 (set_attr "mode" "HI")])
8913 (define_insn "*xorhi_2"
8914 [(set (reg FLAGS_REG)
8915 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8916 (match_operand:HI 2 "general_operand" "rim,ri"))
8918 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8919 (xor:HI (match_dup 1) (match_dup 2)))]
8920 "ix86_match_ccmode (insn, CCNOmode)
8921 && ix86_binary_operator_ok (XOR, HImode, operands)"
8922 "xor{w}\t{%2, %0|%0, %2}"
8923 [(set_attr "type" "alu")
8924 (set_attr "mode" "HI")])
8926 (define_insn "*xorhi_3"
8927 [(set (reg FLAGS_REG)
8928 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8929 (match_operand:HI 2 "general_operand" "rim"))
8931 (clobber (match_scratch:HI 0 "=r"))]
8932 "ix86_match_ccmode (insn, CCNOmode)
8933 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8934 "xor{w}\t{%2, %0|%0, %2}"
8935 [(set_attr "type" "alu")
8936 (set_attr "mode" "HI")])
8938 (define_expand "xorqi3"
8939 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8940 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8941 (match_operand:QI 2 "general_operand" "")))
8942 (clobber (reg:CC FLAGS_REG))]
8943 "TARGET_QIMODE_MATH"
8944 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8946 ;; %%% Potential partial reg stall on alternative 2. What to do?
8947 (define_insn "*xorqi_1"
8948 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8949 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8950 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8951 (clobber (reg:CC FLAGS_REG))]
8952 "ix86_binary_operator_ok (XOR, QImode, operands)"
8954 xor{b}\t{%2, %0|%0, %2}
8955 xor{b}\t{%2, %0|%0, %2}
8956 xor{l}\t{%k2, %k0|%k0, %k2}"
8957 [(set_attr "type" "alu")
8958 (set_attr "mode" "QI,QI,SI")])
8960 (define_insn "*xorqi_1_slp"
8961 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8962 (xor:QI (match_dup 0)
8963 (match_operand:QI 1 "general_operand" "qi,qmi")))
8964 (clobber (reg:CC FLAGS_REG))]
8965 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8966 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8967 "xor{b}\t{%1, %0|%0, %1}"
8968 [(set_attr "type" "alu1")
8969 (set_attr "mode" "QI")])
8971 (define_insn "xorqi_ext_0"
8972 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8977 (match_operand 1 "ext_register_operand" "0")
8980 (match_operand 2 "const_int_operand" "n")))
8981 (clobber (reg:CC FLAGS_REG))]
8982 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8983 "xor{b}\t{%2, %h0|%h0, %2}"
8984 [(set_attr "type" "alu")
8985 (set_attr "length_immediate" "1")
8986 (set_attr "mode" "QI")])
8988 (define_insn "*xorqi_ext_1"
8989 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8994 (match_operand 1 "ext_register_operand" "0")
8998 (match_operand:QI 2 "general_operand" "Qm"))))
8999 (clobber (reg:CC FLAGS_REG))]
9001 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9002 "xor{b}\t{%2, %h0|%h0, %2}"
9003 [(set_attr "type" "alu")
9004 (set_attr "length_immediate" "0")
9005 (set_attr "mode" "QI")])
9007 (define_insn "*xorqi_ext_1_rex64"
9008 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9013 (match_operand 1 "ext_register_operand" "0")
9017 (match_operand 2 "ext_register_operand" "Q"))))
9018 (clobber (reg:CC FLAGS_REG))]
9020 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9021 "xor{b}\t{%2, %h0|%h0, %2}"
9022 [(set_attr "type" "alu")
9023 (set_attr "length_immediate" "0")
9024 (set_attr "mode" "QI")])
9026 (define_insn "*xorqi_ext_2"
9027 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9031 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9034 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9037 (clobber (reg:CC FLAGS_REG))]
9038 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9039 "xor{b}\t{%h2, %h0|%h0, %h2}"
9040 [(set_attr "type" "alu")
9041 (set_attr "length_immediate" "0")
9042 (set_attr "mode" "QI")])
9044 (define_insn "*xorqi_cc_1"
9045 [(set (reg FLAGS_REG)
9047 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9048 (match_operand:QI 2 "general_operand" "qim,qi"))
9050 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9051 (xor:QI (match_dup 1) (match_dup 2)))]
9052 "ix86_match_ccmode (insn, CCNOmode)
9053 && ix86_binary_operator_ok (XOR, QImode, operands)"
9054 "xor{b}\t{%2, %0|%0, %2}"
9055 [(set_attr "type" "alu")
9056 (set_attr "mode" "QI")])
9058 (define_insn "*xorqi_2_slp"
9059 [(set (reg FLAGS_REG)
9060 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9061 (match_operand:QI 1 "general_operand" "qim,qi"))
9063 (set (strict_low_part (match_dup 0))
9064 (xor:QI (match_dup 0) (match_dup 1)))]
9065 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9066 && ix86_match_ccmode (insn, CCNOmode)
9067 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9068 "xor{b}\t{%1, %0|%0, %1}"
9069 [(set_attr "type" "alu1")
9070 (set_attr "mode" "QI")])
9072 (define_insn "*xorqi_cc_2"
9073 [(set (reg FLAGS_REG)
9075 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9076 (match_operand:QI 2 "general_operand" "qim"))
9078 (clobber (match_scratch:QI 0 "=q"))]
9079 "ix86_match_ccmode (insn, CCNOmode)
9080 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9081 "xor{b}\t{%2, %0|%0, %2}"
9082 [(set_attr "type" "alu")
9083 (set_attr "mode" "QI")])
9085 (define_insn "*xorqi_cc_ext_1"
9086 [(set (reg FLAGS_REG)
9090 (match_operand 1 "ext_register_operand" "0")
9093 (match_operand:QI 2 "general_operand" "qmn"))
9095 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9099 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9101 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9102 "xor{b}\t{%2, %h0|%h0, %2}"
9103 [(set_attr "type" "alu")
9104 (set_attr "mode" "QI")])
9106 (define_insn "*xorqi_cc_ext_1_rex64"
9107 [(set (reg FLAGS_REG)
9111 (match_operand 1 "ext_register_operand" "0")
9114 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9116 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9120 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9122 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9123 "xor{b}\t{%2, %h0|%h0, %2}"
9124 [(set_attr "type" "alu")
9125 (set_attr "mode" "QI")])
9127 (define_expand "xorqi_cc_ext_1"
9129 (set (reg:CCNO FLAGS_REG)
9133 (match_operand 1 "ext_register_operand" "")
9136 (match_operand:QI 2 "general_operand" ""))
9138 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9142 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9148 [(set (match_operand 0 "register_operand" "")
9149 (xor (match_operand 1 "register_operand" "")
9150 (match_operand 2 "const_int_operand" "")))
9151 (clobber (reg:CC FLAGS_REG))]
9153 && QI_REG_P (operands[0])
9154 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9155 && !(INTVAL (operands[2]) & ~(255 << 8))
9156 && GET_MODE (operands[0]) != QImode"
9157 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9158 (xor:SI (zero_extract:SI (match_dup 1)
9159 (const_int 8) (const_int 8))
9161 (clobber (reg:CC FLAGS_REG))])]
9162 "operands[0] = gen_lowpart (SImode, operands[0]);
9163 operands[1] = gen_lowpart (SImode, operands[1]);
9164 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9166 ;; Since XOR can be encoded with sign extended immediate, this is only
9167 ;; profitable when 7th bit is set.
9169 [(set (match_operand 0 "register_operand" "")
9170 (xor (match_operand 1 "general_operand" "")
9171 (match_operand 2 "const_int_operand" "")))
9172 (clobber (reg:CC FLAGS_REG))]
9174 && ANY_QI_REG_P (operands[0])
9175 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9176 && !(INTVAL (operands[2]) & ~255)
9177 && (INTVAL (operands[2]) & 128)
9178 && GET_MODE (operands[0]) != QImode"
9179 [(parallel [(set (strict_low_part (match_dup 0))
9180 (xor:QI (match_dup 1)
9182 (clobber (reg:CC FLAGS_REG))])]
9183 "operands[0] = gen_lowpart (QImode, operands[0]);
9184 operands[1] = gen_lowpart (QImode, operands[1]);
9185 operands[2] = gen_lowpart (QImode, operands[2]);")
9187 ;; Negation instructions
9189 (define_expand "negdi2"
9190 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9191 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9192 (clobber (reg:CC FLAGS_REG))])]
9194 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9196 (define_insn "*negdi2_1"
9197 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9198 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9199 (clobber (reg:CC FLAGS_REG))]
9201 && ix86_unary_operator_ok (NEG, DImode, operands)"
9205 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9206 (neg:DI (match_operand:DI 1 "general_operand" "")))
9207 (clobber (reg:CC FLAGS_REG))]
9208 "!TARGET_64BIT && reload_completed"
9210 [(set (reg:CCZ FLAGS_REG)
9211 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9212 (set (match_dup 0) (neg:SI (match_dup 2)))])
9215 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9218 (clobber (reg:CC FLAGS_REG))])
9221 (neg:SI (match_dup 1)))
9222 (clobber (reg:CC FLAGS_REG))])]
9223 "split_di (operands+1, 1, operands+2, operands+3);
9224 split_di (operands+0, 1, operands+0, operands+1);")
9226 (define_insn "*negdi2_1_rex64"
9227 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9228 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9229 (clobber (reg:CC FLAGS_REG))]
9230 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9232 [(set_attr "type" "negnot")
9233 (set_attr "mode" "DI")])
9235 ;; The problem with neg is that it does not perform (compare x 0),
9236 ;; it really performs (compare 0 x), which leaves us with the zero
9237 ;; flag being the only useful item.
9239 (define_insn "*negdi2_cmpz_rex64"
9240 [(set (reg:CCZ FLAGS_REG)
9241 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9243 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9244 (neg:DI (match_dup 1)))]
9245 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9247 [(set_attr "type" "negnot")
9248 (set_attr "mode" "DI")])
9251 (define_expand "negsi2"
9252 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9253 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9254 (clobber (reg:CC FLAGS_REG))])]
9256 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9258 (define_insn "*negsi2_1"
9259 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9260 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9261 (clobber (reg:CC FLAGS_REG))]
9262 "ix86_unary_operator_ok (NEG, SImode, operands)"
9264 [(set_attr "type" "negnot")
9265 (set_attr "mode" "SI")])
9267 ;; Combine is quite creative about this pattern.
9268 (define_insn "*negsi2_1_zext"
9269 [(set (match_operand:DI 0 "register_operand" "=r")
9270 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9273 (clobber (reg:CC FLAGS_REG))]
9274 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9276 [(set_attr "type" "negnot")
9277 (set_attr "mode" "SI")])
9279 ;; The problem with neg is that it does not perform (compare x 0),
9280 ;; it really performs (compare 0 x), which leaves us with the zero
9281 ;; flag being the only useful item.
9283 (define_insn "*negsi2_cmpz"
9284 [(set (reg:CCZ FLAGS_REG)
9285 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9287 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9288 (neg:SI (match_dup 1)))]
9289 "ix86_unary_operator_ok (NEG, SImode, operands)"
9291 [(set_attr "type" "negnot")
9292 (set_attr "mode" "SI")])
9294 (define_insn "*negsi2_cmpz_zext"
9295 [(set (reg:CCZ FLAGS_REG)
9296 (compare:CCZ (lshiftrt:DI
9298 (match_operand:DI 1 "register_operand" "0")
9302 (set (match_operand:DI 0 "register_operand" "=r")
9303 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9306 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9308 [(set_attr "type" "negnot")
9309 (set_attr "mode" "SI")])
9311 (define_expand "neghi2"
9312 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9313 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9314 (clobber (reg:CC FLAGS_REG))])]
9315 "TARGET_HIMODE_MATH"
9316 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9318 (define_insn "*neghi2_1"
9319 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9320 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9321 (clobber (reg:CC FLAGS_REG))]
9322 "ix86_unary_operator_ok (NEG, HImode, operands)"
9324 [(set_attr "type" "negnot")
9325 (set_attr "mode" "HI")])
9327 (define_insn "*neghi2_cmpz"
9328 [(set (reg:CCZ FLAGS_REG)
9329 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9331 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9332 (neg:HI (match_dup 1)))]
9333 "ix86_unary_operator_ok (NEG, HImode, operands)"
9335 [(set_attr "type" "negnot")
9336 (set_attr "mode" "HI")])
9338 (define_expand "negqi2"
9339 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9340 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9341 (clobber (reg:CC FLAGS_REG))])]
9342 "TARGET_QIMODE_MATH"
9343 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9345 (define_insn "*negqi2_1"
9346 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9347 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9348 (clobber (reg:CC FLAGS_REG))]
9349 "ix86_unary_operator_ok (NEG, QImode, operands)"
9351 [(set_attr "type" "negnot")
9352 (set_attr "mode" "QI")])
9354 (define_insn "*negqi2_cmpz"
9355 [(set (reg:CCZ FLAGS_REG)
9356 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9358 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9359 (neg:QI (match_dup 1)))]
9360 "ix86_unary_operator_ok (NEG, QImode, operands)"
9362 [(set_attr "type" "negnot")
9363 (set_attr "mode" "QI")])
9365 ;; Changing of sign for FP values is doable using integer unit too.
9367 (define_expand "negsf2"
9368 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9369 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9370 "TARGET_80387 || TARGET_SSE_MATH"
9371 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9373 (define_expand "abssf2"
9374 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9375 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9376 "TARGET_80387 || TARGET_SSE_MATH"
9377 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9379 (define_insn "*absnegsf2_mixed"
9380 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#f,x#f,f#x,rm")
9381 (match_operator:SF 3 "absneg_operator"
9382 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#f,0 ,0")]))
9383 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9384 (clobber (reg:CC FLAGS_REG))]
9385 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9386 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9389 (define_insn "*absnegsf2_sse"
9390 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9391 (match_operator:SF 3 "absneg_operator"
9392 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9393 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9394 (clobber (reg:CC FLAGS_REG))]
9396 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9399 (define_insn "*absnegsf2_i387"
9400 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9401 (match_operator:SF 3 "absneg_operator"
9402 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9403 (use (match_operand 2 "" ""))
9404 (clobber (reg:CC FLAGS_REG))]
9405 "TARGET_80387 && !TARGET_SSE_MATH
9406 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9409 (define_expand "copysignsf3"
9410 [(match_operand:SF 0 "register_operand" "")
9411 (match_operand:SF 1 "nonmemory_operand" "")
9412 (match_operand:SF 2 "register_operand" "")]
9415 ix86_expand_copysign (operands);
9419 (define_insn_and_split "copysignsf3_const"
9420 [(set (match_operand:SF 0 "register_operand" "=x")
9422 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9423 (match_operand:SF 2 "register_operand" "0")
9424 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9428 "&& reload_completed"
9431 ix86_split_copysign_const (operands);
9435 (define_insn "copysignsf3_var"
9436 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9438 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9439 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9440 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9441 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9443 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9448 [(set (match_operand:SF 0 "register_operand" "")
9450 [(match_operand:SF 2 "register_operand" "")
9451 (match_operand:SF 3 "register_operand" "")
9452 (match_operand:V4SF 4 "" "")
9453 (match_operand:V4SF 5 "" "")]
9455 (clobber (match_scratch:V4SF 1 ""))]
9456 "TARGET_SSE_MATH && reload_completed"
9459 ix86_split_copysign_var (operands);
9463 (define_expand "negdf2"
9464 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9465 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9466 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9467 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9469 (define_expand "absdf2"
9470 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9471 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9472 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9473 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9475 (define_insn "*absnegdf2_mixed"
9476 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,f#Y,rm")
9477 (match_operator:DF 3 "absneg_operator"
9478 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#f,0 ,0")]))
9479 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9480 (clobber (reg:CC FLAGS_REG))]
9481 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9482 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9485 (define_insn "*absnegdf2_sse"
9486 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9487 (match_operator:DF 3 "absneg_operator"
9488 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9489 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X"))
9490 (clobber (reg:CC FLAGS_REG))]
9491 "TARGET_SSE2 && TARGET_SSE_MATH
9492 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9495 (define_insn "*absnegdf2_i387"
9496 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9497 (match_operator:DF 3 "absneg_operator"
9498 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9499 (use (match_operand 2 "" ""))
9500 (clobber (reg:CC FLAGS_REG))]
9501 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9502 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9505 (define_expand "copysigndf3"
9506 [(match_operand:DF 0 "register_operand" "")
9507 (match_operand:DF 1 "nonmemory_operand" "")
9508 (match_operand:DF 2 "register_operand" "")]
9509 "TARGET_SSE2 && TARGET_SSE_MATH"
9511 ix86_expand_copysign (operands);
9515 (define_insn_and_split "copysigndf3_const"
9516 [(set (match_operand:DF 0 "register_operand" "=x")
9518 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9519 (match_operand:DF 2 "register_operand" "0")
9520 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9522 "TARGET_SSE2 && TARGET_SSE_MATH"
9524 "&& reload_completed"
9527 ix86_split_copysign_const (operands);
9531 (define_insn "copysigndf3_var"
9532 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9534 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9535 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9536 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9537 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9539 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9540 "TARGET_SSE2 && TARGET_SSE_MATH"
9544 [(set (match_operand:DF 0 "register_operand" "")
9546 [(match_operand:DF 2 "register_operand" "")
9547 (match_operand:DF 3 "register_operand" "")
9548 (match_operand:V2DF 4 "" "")
9549 (match_operand:V2DF 5 "" "")]
9551 (clobber (match_scratch:V2DF 1 ""))]
9552 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9555 ix86_split_copysign_var (operands);
9559 (define_expand "negxf2"
9560 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9561 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9563 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9565 (define_expand "absxf2"
9566 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9567 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9569 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9571 (define_insn "*absnegxf2_i387"
9572 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9573 (match_operator:XF 3 "absneg_operator"
9574 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9575 (use (match_operand 2 "" ""))
9576 (clobber (reg:CC FLAGS_REG))]
9578 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9581 ;; Splitters for fp abs and neg.
9584 [(set (match_operand 0 "fp_register_operand" "")
9585 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9586 (use (match_operand 2 "" ""))
9587 (clobber (reg:CC FLAGS_REG))]
9589 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9592 [(set (match_operand 0 "register_operand" "")
9593 (match_operator 3 "absneg_operator"
9594 [(match_operand 1 "register_operand" "")]))
9595 (use (match_operand 2 "nonimmediate_operand" ""))
9596 (clobber (reg:CC FLAGS_REG))]
9597 "reload_completed && SSE_REG_P (operands[0])"
9598 [(set (match_dup 0) (match_dup 3))]
9600 enum machine_mode mode = GET_MODE (operands[0]);
9601 enum machine_mode vmode = GET_MODE (operands[2]);
9604 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9605 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9606 if (operands_match_p (operands[0], operands[2]))
9609 operands[1] = operands[2];
9612 if (GET_CODE (operands[3]) == ABS)
9613 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9615 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9620 [(set (match_operand:SF 0 "register_operand" "")
9621 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9622 (use (match_operand:V4SF 2 "" ""))
9623 (clobber (reg:CC FLAGS_REG))]
9625 [(parallel [(set (match_dup 0) (match_dup 1))
9626 (clobber (reg:CC FLAGS_REG))])]
9629 operands[0] = gen_lowpart (SImode, operands[0]);
9630 if (GET_CODE (operands[1]) == ABS)
9632 tmp = gen_int_mode (0x7fffffff, SImode);
9633 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9637 tmp = gen_int_mode (0x80000000, SImode);
9638 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9644 [(set (match_operand:DF 0 "register_operand" "")
9645 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9646 (use (match_operand 2 "" ""))
9647 (clobber (reg:CC FLAGS_REG))]
9649 [(parallel [(set (match_dup 0) (match_dup 1))
9650 (clobber (reg:CC FLAGS_REG))])]
9655 tmp = gen_lowpart (DImode, operands[0]);
9656 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9659 if (GET_CODE (operands[1]) == ABS)
9662 tmp = gen_rtx_NOT (DImode, tmp);
9666 operands[0] = gen_highpart (SImode, operands[0]);
9667 if (GET_CODE (operands[1]) == ABS)
9669 tmp = gen_int_mode (0x7fffffff, SImode);
9670 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9674 tmp = gen_int_mode (0x80000000, SImode);
9675 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9682 [(set (match_operand:XF 0 "register_operand" "")
9683 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9684 (use (match_operand 2 "" ""))
9685 (clobber (reg:CC FLAGS_REG))]
9687 [(parallel [(set (match_dup 0) (match_dup 1))
9688 (clobber (reg:CC FLAGS_REG))])]
9691 operands[0] = gen_rtx_REG (SImode,
9692 true_regnum (operands[0])
9693 + (TARGET_64BIT ? 1 : 2));
9694 if (GET_CODE (operands[1]) == ABS)
9696 tmp = GEN_INT (0x7fff);
9697 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9701 tmp = GEN_INT (0x8000);
9702 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9708 [(set (match_operand 0 "memory_operand" "")
9709 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9710 (use (match_operand 2 "" ""))
9711 (clobber (reg:CC FLAGS_REG))]
9713 [(parallel [(set (match_dup 0) (match_dup 1))
9714 (clobber (reg:CC FLAGS_REG))])]
9716 enum machine_mode mode = GET_MODE (operands[0]);
9717 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9720 operands[0] = adjust_address (operands[0], QImode, size - 1);
9721 if (GET_CODE (operands[1]) == ABS)
9723 tmp = gen_int_mode (0x7f, QImode);
9724 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9728 tmp = gen_int_mode (0x80, QImode);
9729 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9734 ;; Conditionalize these after reload. If they match before reload, we
9735 ;; lose the clobber and ability to use integer instructions.
9737 (define_insn "*negsf2_1"
9738 [(set (match_operand:SF 0 "register_operand" "=f")
9739 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9740 "TARGET_80387 && reload_completed"
9742 [(set_attr "type" "fsgn")
9743 (set_attr "mode" "SF")])
9745 (define_insn "*negdf2_1"
9746 [(set (match_operand:DF 0 "register_operand" "=f")
9747 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9748 "TARGET_80387 && reload_completed"
9750 [(set_attr "type" "fsgn")
9751 (set_attr "mode" "DF")])
9753 (define_insn "*negxf2_1"
9754 [(set (match_operand:XF 0 "register_operand" "=f")
9755 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9756 "TARGET_80387 && reload_completed"
9758 [(set_attr "type" "fsgn")
9759 (set_attr "mode" "XF")])
9761 (define_insn "*abssf2_1"
9762 [(set (match_operand:SF 0 "register_operand" "=f")
9763 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9764 "TARGET_80387 && reload_completed"
9766 [(set_attr "type" "fsgn")
9767 (set_attr "mode" "SF")])
9769 (define_insn "*absdf2_1"
9770 [(set (match_operand:DF 0 "register_operand" "=f")
9771 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9772 "TARGET_80387 && reload_completed"
9774 [(set_attr "type" "fsgn")
9775 (set_attr "mode" "DF")])
9777 (define_insn "*absxf2_1"
9778 [(set (match_operand:XF 0 "register_operand" "=f")
9779 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9780 "TARGET_80387 && reload_completed"
9782 [(set_attr "type" "fsgn")
9783 (set_attr "mode" "DF")])
9785 (define_insn "*negextendsfdf2"
9786 [(set (match_operand:DF 0 "register_operand" "=f")
9787 (neg:DF (float_extend:DF
9788 (match_operand:SF 1 "register_operand" "0"))))]
9789 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9791 [(set_attr "type" "fsgn")
9792 (set_attr "mode" "DF")])
9794 (define_insn "*negextenddfxf2"
9795 [(set (match_operand:XF 0 "register_operand" "=f")
9796 (neg:XF (float_extend:XF
9797 (match_operand:DF 1 "register_operand" "0"))))]
9800 [(set_attr "type" "fsgn")
9801 (set_attr "mode" "XF")])
9803 (define_insn "*negextendsfxf2"
9804 [(set (match_operand:XF 0 "register_operand" "=f")
9805 (neg:XF (float_extend:XF
9806 (match_operand:SF 1 "register_operand" "0"))))]
9809 [(set_attr "type" "fsgn")
9810 (set_attr "mode" "XF")])
9812 (define_insn "*absextendsfdf2"
9813 [(set (match_operand:DF 0 "register_operand" "=f")
9814 (abs:DF (float_extend:DF
9815 (match_operand:SF 1 "register_operand" "0"))))]
9816 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9818 [(set_attr "type" "fsgn")
9819 (set_attr "mode" "DF")])
9821 (define_insn "*absextenddfxf2"
9822 [(set (match_operand:XF 0 "register_operand" "=f")
9823 (abs:XF (float_extend:XF
9824 (match_operand:DF 1 "register_operand" "0"))))]
9827 [(set_attr "type" "fsgn")
9828 (set_attr "mode" "XF")])
9830 (define_insn "*absextendsfxf2"
9831 [(set (match_operand:XF 0 "register_operand" "=f")
9832 (abs:XF (float_extend:XF
9833 (match_operand:SF 1 "register_operand" "0"))))]
9836 [(set_attr "type" "fsgn")
9837 (set_attr "mode" "XF")])
9839 ;; One complement instructions
9841 (define_expand "one_cmpldi2"
9842 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9843 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9845 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9847 (define_insn "*one_cmpldi2_1_rex64"
9848 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9849 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9850 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9852 [(set_attr "type" "negnot")
9853 (set_attr "mode" "DI")])
9855 (define_insn "*one_cmpldi2_2_rex64"
9856 [(set (reg FLAGS_REG)
9857 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9859 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9860 (not:DI (match_dup 1)))]
9861 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9862 && ix86_unary_operator_ok (NOT, DImode, operands)"
9864 [(set_attr "type" "alu1")
9865 (set_attr "mode" "DI")])
9868 [(set (match_operand 0 "flags_reg_operand" "")
9869 (match_operator 2 "compare_operator"
9870 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9872 (set (match_operand:DI 1 "nonimmediate_operand" "")
9873 (not:DI (match_dup 3)))]
9874 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9875 [(parallel [(set (match_dup 0)
9877 [(xor:DI (match_dup 3) (const_int -1))
9880 (xor:DI (match_dup 3) (const_int -1)))])]
9883 (define_expand "one_cmplsi2"
9884 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9885 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9887 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9889 (define_insn "*one_cmplsi2_1"
9890 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9891 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9892 "ix86_unary_operator_ok (NOT, SImode, operands)"
9894 [(set_attr "type" "negnot")
9895 (set_attr "mode" "SI")])
9897 ;; ??? Currently never generated - xor is used instead.
9898 (define_insn "*one_cmplsi2_1_zext"
9899 [(set (match_operand:DI 0 "register_operand" "=r")
9900 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9901 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9903 [(set_attr "type" "negnot")
9904 (set_attr "mode" "SI")])
9906 (define_insn "*one_cmplsi2_2"
9907 [(set (reg FLAGS_REG)
9908 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9910 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9911 (not:SI (match_dup 1)))]
9912 "ix86_match_ccmode (insn, CCNOmode)
9913 && ix86_unary_operator_ok (NOT, SImode, operands)"
9915 [(set_attr "type" "alu1")
9916 (set_attr "mode" "SI")])
9919 [(set (match_operand 0 "flags_reg_operand" "")
9920 (match_operator 2 "compare_operator"
9921 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9923 (set (match_operand:SI 1 "nonimmediate_operand" "")
9924 (not:SI (match_dup 3)))]
9925 "ix86_match_ccmode (insn, CCNOmode)"
9926 [(parallel [(set (match_dup 0)
9927 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9930 (xor:SI (match_dup 3) (const_int -1)))])]
9933 ;; ??? Currently never generated - xor is used instead.
9934 (define_insn "*one_cmplsi2_2_zext"
9935 [(set (reg FLAGS_REG)
9936 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9938 (set (match_operand:DI 0 "register_operand" "=r")
9939 (zero_extend:DI (not:SI (match_dup 1))))]
9940 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9941 && ix86_unary_operator_ok (NOT, SImode, operands)"
9943 [(set_attr "type" "alu1")
9944 (set_attr "mode" "SI")])
9947 [(set (match_operand 0 "flags_reg_operand" "")
9948 (match_operator 2 "compare_operator"
9949 [(not:SI (match_operand:SI 3 "register_operand" ""))
9951 (set (match_operand:DI 1 "register_operand" "")
9952 (zero_extend:DI (not:SI (match_dup 3))))]
9953 "ix86_match_ccmode (insn, CCNOmode)"
9954 [(parallel [(set (match_dup 0)
9955 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9958 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9961 (define_expand "one_cmplhi2"
9962 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9963 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9964 "TARGET_HIMODE_MATH"
9965 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9967 (define_insn "*one_cmplhi2_1"
9968 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9969 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9970 "ix86_unary_operator_ok (NOT, HImode, operands)"
9972 [(set_attr "type" "negnot")
9973 (set_attr "mode" "HI")])
9975 (define_insn "*one_cmplhi2_2"
9976 [(set (reg FLAGS_REG)
9977 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9979 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9980 (not:HI (match_dup 1)))]
9981 "ix86_match_ccmode (insn, CCNOmode)
9982 && ix86_unary_operator_ok (NEG, HImode, operands)"
9984 [(set_attr "type" "alu1")
9985 (set_attr "mode" "HI")])
9988 [(set (match_operand 0 "flags_reg_operand" "")
9989 (match_operator 2 "compare_operator"
9990 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
9992 (set (match_operand:HI 1 "nonimmediate_operand" "")
9993 (not:HI (match_dup 3)))]
9994 "ix86_match_ccmode (insn, CCNOmode)"
9995 [(parallel [(set (match_dup 0)
9996 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
9999 (xor:HI (match_dup 3) (const_int -1)))])]
10002 ;; %%% Potential partial reg stall on alternative 1. What to do?
10003 (define_expand "one_cmplqi2"
10004 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10005 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10006 "TARGET_QIMODE_MATH"
10007 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10009 (define_insn "*one_cmplqi2_1"
10010 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10011 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10012 "ix86_unary_operator_ok (NOT, QImode, operands)"
10016 [(set_attr "type" "negnot")
10017 (set_attr "mode" "QI,SI")])
10019 (define_insn "*one_cmplqi2_2"
10020 [(set (reg FLAGS_REG)
10021 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10023 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10024 (not:QI (match_dup 1)))]
10025 "ix86_match_ccmode (insn, CCNOmode)
10026 && ix86_unary_operator_ok (NOT, QImode, operands)"
10028 [(set_attr "type" "alu1")
10029 (set_attr "mode" "QI")])
10032 [(set (match_operand 0 "flags_reg_operand" "")
10033 (match_operator 2 "compare_operator"
10034 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10036 (set (match_operand:QI 1 "nonimmediate_operand" "")
10037 (not:QI (match_dup 3)))]
10038 "ix86_match_ccmode (insn, CCNOmode)"
10039 [(parallel [(set (match_dup 0)
10040 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10043 (xor:QI (match_dup 3) (const_int -1)))])]
10046 ;; Arithmetic shift instructions
10048 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10049 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10050 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10051 ;; from the assembler input.
10053 ;; This instruction shifts the target reg/mem as usual, but instead of
10054 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10055 ;; is a left shift double, bits are taken from the high order bits of
10056 ;; reg, else if the insn is a shift right double, bits are taken from the
10057 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10058 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10060 ;; Since sh[lr]d does not change the `reg' operand, that is done
10061 ;; separately, making all shifts emit pairs of shift double and normal
10062 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10063 ;; support a 63 bit shift, each shift where the count is in a reg expands
10064 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10066 ;; If the shift count is a constant, we need never emit more than one
10067 ;; shift pair, instead using moves and sign extension for counts greater
10070 (define_expand "ashldi3"
10071 [(set (match_operand:DI 0 "shiftdi_operand" "")
10072 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10073 (match_operand:QI 2 "nonmemory_operand" "")))]
10075 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10077 (define_insn "*ashldi3_1_rex64"
10078 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10079 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10080 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10081 (clobber (reg:CC FLAGS_REG))]
10082 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10084 switch (get_attr_type (insn))
10087 gcc_assert (operands[2] == const1_rtx);
10088 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10089 return "add{q}\t{%0, %0|%0, %0}";
10092 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10093 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10094 operands[1] = gen_rtx_MULT (DImode, operands[1],
10095 GEN_INT (1 << INTVAL (operands[2])));
10096 return "lea{q}\t{%a1, %0|%0, %a1}";
10099 if (REG_P (operands[2]))
10100 return "sal{q}\t{%b2, %0|%0, %b2}";
10101 else if (operands[2] == const1_rtx
10102 && (TARGET_SHIFT1 || optimize_size))
10103 return "sal{q}\t%0";
10105 return "sal{q}\t{%2, %0|%0, %2}";
10108 [(set (attr "type")
10109 (cond [(eq_attr "alternative" "1")
10110 (const_string "lea")
10111 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10113 (match_operand 0 "register_operand" ""))
10114 (match_operand 2 "const1_operand" ""))
10115 (const_string "alu")
10117 (const_string "ishift")))
10118 (set_attr "mode" "DI")])
10120 ;; Convert lea to the lea pattern to avoid flags dependency.
10122 [(set (match_operand:DI 0 "register_operand" "")
10123 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10124 (match_operand:QI 2 "immediate_operand" "")))
10125 (clobber (reg:CC FLAGS_REG))]
10126 "TARGET_64BIT && reload_completed
10127 && true_regnum (operands[0]) != true_regnum (operands[1])"
10128 [(set (match_dup 0)
10129 (mult:DI (match_dup 1)
10131 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10133 ;; This pattern can't accept a variable shift count, since shifts by
10134 ;; zero don't affect the flags. We assume that shifts by constant
10135 ;; zero are optimized away.
10136 (define_insn "*ashldi3_cmp_rex64"
10137 [(set (reg FLAGS_REG)
10139 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10140 (match_operand:QI 2 "immediate_operand" "e"))
10142 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10143 (ashift:DI (match_dup 1) (match_dup 2)))]
10144 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10145 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10147 switch (get_attr_type (insn))
10150 gcc_assert (operands[2] == const1_rtx);
10151 return "add{q}\t{%0, %0|%0, %0}";
10154 if (REG_P (operands[2]))
10155 return "sal{q}\t{%b2, %0|%0, %b2}";
10156 else if (operands[2] == const1_rtx
10157 && (TARGET_SHIFT1 || optimize_size))
10158 return "sal{q}\t%0";
10160 return "sal{q}\t{%2, %0|%0, %2}";
10163 [(set (attr "type")
10164 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10166 (match_operand 0 "register_operand" ""))
10167 (match_operand 2 "const1_operand" ""))
10168 (const_string "alu")
10170 (const_string "ishift")))
10171 (set_attr "mode" "DI")])
10173 (define_insn "*ashldi3_1"
10174 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10175 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10176 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10177 (clobber (reg:CC FLAGS_REG))]
10180 [(set_attr "type" "multi")])
10182 ;; By default we don't ask for a scratch register, because when DImode
10183 ;; values are manipulated, registers are already at a premium. But if
10184 ;; we have one handy, we won't turn it away.
10186 [(match_scratch:SI 3 "r")
10187 (parallel [(set (match_operand:DI 0 "register_operand" "")
10188 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10189 (match_operand:QI 2 "nonmemory_operand" "")))
10190 (clobber (reg:CC FLAGS_REG))])
10192 "!TARGET_64BIT && TARGET_CMOVE"
10194 "ix86_split_ashldi (operands, operands[3]); DONE;")
10197 [(set (match_operand:DI 0 "register_operand" "")
10198 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10199 (match_operand:QI 2 "nonmemory_operand" "")))
10200 (clobber (reg:CC FLAGS_REG))]
10201 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10203 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10205 (define_insn "x86_shld_1"
10206 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10207 (ior:SI (ashift:SI (match_dup 0)
10208 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10209 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10210 (minus:QI (const_int 32) (match_dup 2)))))
10211 (clobber (reg:CC FLAGS_REG))]
10214 shld{l}\t{%2, %1, %0|%0, %1, %2}
10215 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10216 [(set_attr "type" "ishift")
10217 (set_attr "prefix_0f" "1")
10218 (set_attr "mode" "SI")
10219 (set_attr "pent_pair" "np")
10220 (set_attr "athlon_decode" "vector")])
10222 (define_expand "x86_shift_adj_1"
10223 [(set (reg:CCZ FLAGS_REG)
10224 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10227 (set (match_operand:SI 0 "register_operand" "")
10228 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10229 (match_operand:SI 1 "register_operand" "")
10232 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10233 (match_operand:SI 3 "register_operand" "r")
10238 (define_expand "x86_shift_adj_2"
10239 [(use (match_operand:SI 0 "register_operand" ""))
10240 (use (match_operand:SI 1 "register_operand" ""))
10241 (use (match_operand:QI 2 "register_operand" ""))]
10244 rtx label = gen_label_rtx ();
10247 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10249 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10250 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10251 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10252 gen_rtx_LABEL_REF (VOIDmode, label),
10254 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10255 JUMP_LABEL (tmp) = label;
10257 emit_move_insn (operands[0], operands[1]);
10258 ix86_expand_clear (operands[1]);
10260 emit_label (label);
10261 LABEL_NUSES (label) = 1;
10266 (define_expand "ashlsi3"
10267 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10268 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10269 (match_operand:QI 2 "nonmemory_operand" "")))
10270 (clobber (reg:CC FLAGS_REG))]
10272 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10274 (define_insn "*ashlsi3_1"
10275 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10276 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10277 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10278 (clobber (reg:CC FLAGS_REG))]
10279 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10281 switch (get_attr_type (insn))
10284 gcc_assert (operands[2] == const1_rtx);
10285 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10286 return "add{l}\t{%0, %0|%0, %0}";
10292 if (REG_P (operands[2]))
10293 return "sal{l}\t{%b2, %0|%0, %b2}";
10294 else if (operands[2] == const1_rtx
10295 && (TARGET_SHIFT1 || optimize_size))
10296 return "sal{l}\t%0";
10298 return "sal{l}\t{%2, %0|%0, %2}";
10301 [(set (attr "type")
10302 (cond [(eq_attr "alternative" "1")
10303 (const_string "lea")
10304 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10306 (match_operand 0 "register_operand" ""))
10307 (match_operand 2 "const1_operand" ""))
10308 (const_string "alu")
10310 (const_string "ishift")))
10311 (set_attr "mode" "SI")])
10313 ;; Convert lea to the lea pattern to avoid flags dependency.
10315 [(set (match_operand 0 "register_operand" "")
10316 (ashift (match_operand 1 "index_register_operand" "")
10317 (match_operand:QI 2 "const_int_operand" "")))
10318 (clobber (reg:CC FLAGS_REG))]
10320 && true_regnum (operands[0]) != true_regnum (operands[1])
10321 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10325 enum machine_mode mode = GET_MODE (operands[0]);
10327 if (GET_MODE_SIZE (mode) < 4)
10328 operands[0] = gen_lowpart (SImode, operands[0]);
10330 operands[1] = gen_lowpart (Pmode, operands[1]);
10331 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10333 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10334 if (Pmode != SImode)
10335 pat = gen_rtx_SUBREG (SImode, pat, 0);
10336 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10340 ;; Rare case of shifting RSP is handled by generating move and shift
10342 [(set (match_operand 0 "register_operand" "")
10343 (ashift (match_operand 1 "register_operand" "")
10344 (match_operand:QI 2 "const_int_operand" "")))
10345 (clobber (reg:CC FLAGS_REG))]
10347 && true_regnum (operands[0]) != true_regnum (operands[1])"
10351 emit_move_insn (operands[1], operands[0]);
10352 pat = gen_rtx_SET (VOIDmode, operands[0],
10353 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10354 operands[0], operands[2]));
10355 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10356 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10360 (define_insn "*ashlsi3_1_zext"
10361 [(set (match_operand:DI 0 "register_operand" "=r,r")
10362 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10363 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10364 (clobber (reg:CC FLAGS_REG))]
10365 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10367 switch (get_attr_type (insn))
10370 gcc_assert (operands[2] == const1_rtx);
10371 return "add{l}\t{%k0, %k0|%k0, %k0}";
10377 if (REG_P (operands[2]))
10378 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10379 else if (operands[2] == const1_rtx
10380 && (TARGET_SHIFT1 || optimize_size))
10381 return "sal{l}\t%k0";
10383 return "sal{l}\t{%2, %k0|%k0, %2}";
10386 [(set (attr "type")
10387 (cond [(eq_attr "alternative" "1")
10388 (const_string "lea")
10389 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10391 (match_operand 2 "const1_operand" ""))
10392 (const_string "alu")
10394 (const_string "ishift")))
10395 (set_attr "mode" "SI")])
10397 ;; Convert lea to the lea pattern to avoid flags dependency.
10399 [(set (match_operand:DI 0 "register_operand" "")
10400 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10401 (match_operand:QI 2 "const_int_operand" ""))))
10402 (clobber (reg:CC FLAGS_REG))]
10403 "TARGET_64BIT && reload_completed
10404 && true_regnum (operands[0]) != true_regnum (operands[1])"
10405 [(set (match_dup 0) (zero_extend:DI
10406 (subreg:SI (mult:SI (match_dup 1)
10407 (match_dup 2)) 0)))]
10409 operands[1] = gen_lowpart (Pmode, operands[1]);
10410 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10413 ;; This pattern can't accept a variable shift count, since shifts by
10414 ;; zero don't affect the flags. We assume that shifts by constant
10415 ;; zero are optimized away.
10416 (define_insn "*ashlsi3_cmp"
10417 [(set (reg FLAGS_REG)
10419 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10420 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10422 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10423 (ashift:SI (match_dup 1) (match_dup 2)))]
10424 "ix86_match_ccmode (insn, CCGOCmode)
10425 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10427 switch (get_attr_type (insn))
10430 gcc_assert (operands[2] == const1_rtx);
10431 return "add{l}\t{%0, %0|%0, %0}";
10434 if (REG_P (operands[2]))
10435 return "sal{l}\t{%b2, %0|%0, %b2}";
10436 else if (operands[2] == const1_rtx
10437 && (TARGET_SHIFT1 || optimize_size))
10438 return "sal{l}\t%0";
10440 return "sal{l}\t{%2, %0|%0, %2}";
10443 [(set (attr "type")
10444 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10446 (match_operand 0 "register_operand" ""))
10447 (match_operand 2 "const1_operand" ""))
10448 (const_string "alu")
10450 (const_string "ishift")))
10451 (set_attr "mode" "SI")])
10453 (define_insn "*ashlsi3_cmp_zext"
10454 [(set (reg FLAGS_REG)
10456 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10457 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10459 (set (match_operand:DI 0 "register_operand" "=r")
10460 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10461 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10462 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10464 switch (get_attr_type (insn))
10467 gcc_assert (operands[2] == const1_rtx);
10468 return "add{l}\t{%k0, %k0|%k0, %k0}";
10471 if (REG_P (operands[2]))
10472 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10473 else if (operands[2] == const1_rtx
10474 && (TARGET_SHIFT1 || optimize_size))
10475 return "sal{l}\t%k0";
10477 return "sal{l}\t{%2, %k0|%k0, %2}";
10480 [(set (attr "type")
10481 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10483 (match_operand 2 "const1_operand" ""))
10484 (const_string "alu")
10486 (const_string "ishift")))
10487 (set_attr "mode" "SI")])
10489 (define_expand "ashlhi3"
10490 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10491 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10492 (match_operand:QI 2 "nonmemory_operand" "")))
10493 (clobber (reg:CC FLAGS_REG))]
10494 "TARGET_HIMODE_MATH"
10495 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10497 (define_insn "*ashlhi3_1_lea"
10498 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10499 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10500 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10501 (clobber (reg:CC FLAGS_REG))]
10502 "!TARGET_PARTIAL_REG_STALL
10503 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10505 switch (get_attr_type (insn))
10510 gcc_assert (operands[2] == const1_rtx);
10511 return "add{w}\t{%0, %0|%0, %0}";
10514 if (REG_P (operands[2]))
10515 return "sal{w}\t{%b2, %0|%0, %b2}";
10516 else if (operands[2] == const1_rtx
10517 && (TARGET_SHIFT1 || optimize_size))
10518 return "sal{w}\t%0";
10520 return "sal{w}\t{%2, %0|%0, %2}";
10523 [(set (attr "type")
10524 (cond [(eq_attr "alternative" "1")
10525 (const_string "lea")
10526 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10528 (match_operand 0 "register_operand" ""))
10529 (match_operand 2 "const1_operand" ""))
10530 (const_string "alu")
10532 (const_string "ishift")))
10533 (set_attr "mode" "HI,SI")])
10535 (define_insn "*ashlhi3_1"
10536 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10537 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10538 (match_operand:QI 2 "nonmemory_operand" "cI")))
10539 (clobber (reg:CC FLAGS_REG))]
10540 "TARGET_PARTIAL_REG_STALL
10541 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10543 switch (get_attr_type (insn))
10546 gcc_assert (operands[2] == const1_rtx);
10547 return "add{w}\t{%0, %0|%0, %0}";
10550 if (REG_P (operands[2]))
10551 return "sal{w}\t{%b2, %0|%0, %b2}";
10552 else if (operands[2] == const1_rtx
10553 && (TARGET_SHIFT1 || optimize_size))
10554 return "sal{w}\t%0";
10556 return "sal{w}\t{%2, %0|%0, %2}";
10559 [(set (attr "type")
10560 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10562 (match_operand 0 "register_operand" ""))
10563 (match_operand 2 "const1_operand" ""))
10564 (const_string "alu")
10566 (const_string "ishift")))
10567 (set_attr "mode" "HI")])
10569 ;; This pattern can't accept a variable shift count, since shifts by
10570 ;; zero don't affect the flags. We assume that shifts by constant
10571 ;; zero are optimized away.
10572 (define_insn "*ashlhi3_cmp"
10573 [(set (reg FLAGS_REG)
10575 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10576 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10578 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10579 (ashift:HI (match_dup 1) (match_dup 2)))]
10580 "ix86_match_ccmode (insn, CCGOCmode)
10581 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10583 switch (get_attr_type (insn))
10586 gcc_assert (operands[2] == const1_rtx);
10587 return "add{w}\t{%0, %0|%0, %0}";
10590 if (REG_P (operands[2]))
10591 return "sal{w}\t{%b2, %0|%0, %b2}";
10592 else if (operands[2] == const1_rtx
10593 && (TARGET_SHIFT1 || optimize_size))
10594 return "sal{w}\t%0";
10596 return "sal{w}\t{%2, %0|%0, %2}";
10599 [(set (attr "type")
10600 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10602 (match_operand 0 "register_operand" ""))
10603 (match_operand 2 "const1_operand" ""))
10604 (const_string "alu")
10606 (const_string "ishift")))
10607 (set_attr "mode" "HI")])
10609 (define_expand "ashlqi3"
10610 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10611 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10612 (match_operand:QI 2 "nonmemory_operand" "")))
10613 (clobber (reg:CC FLAGS_REG))]
10614 "TARGET_QIMODE_MATH"
10615 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10617 ;; %%% Potential partial reg stall on alternative 2. What to do?
10619 (define_insn "*ashlqi3_1_lea"
10620 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10621 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10622 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10623 (clobber (reg:CC FLAGS_REG))]
10624 "!TARGET_PARTIAL_REG_STALL
10625 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10627 switch (get_attr_type (insn))
10632 gcc_assert (operands[2] == const1_rtx);
10633 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10634 return "add{l}\t{%k0, %k0|%k0, %k0}";
10636 return "add{b}\t{%0, %0|%0, %0}";
10639 if (REG_P (operands[2]))
10641 if (get_attr_mode (insn) == MODE_SI)
10642 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10644 return "sal{b}\t{%b2, %0|%0, %b2}";
10646 else if (operands[2] == const1_rtx
10647 && (TARGET_SHIFT1 || optimize_size))
10649 if (get_attr_mode (insn) == MODE_SI)
10650 return "sal{l}\t%0";
10652 return "sal{b}\t%0";
10656 if (get_attr_mode (insn) == MODE_SI)
10657 return "sal{l}\t{%2, %k0|%k0, %2}";
10659 return "sal{b}\t{%2, %0|%0, %2}";
10663 [(set (attr "type")
10664 (cond [(eq_attr "alternative" "2")
10665 (const_string "lea")
10666 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10668 (match_operand 0 "register_operand" ""))
10669 (match_operand 2 "const1_operand" ""))
10670 (const_string "alu")
10672 (const_string "ishift")))
10673 (set_attr "mode" "QI,SI,SI")])
10675 (define_insn "*ashlqi3_1"
10676 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10677 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10678 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10679 (clobber (reg:CC FLAGS_REG))]
10680 "TARGET_PARTIAL_REG_STALL
10681 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10683 switch (get_attr_type (insn))
10686 gcc_assert (operands[2] == const1_rtx);
10687 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10688 return "add{l}\t{%k0, %k0|%k0, %k0}";
10690 return "add{b}\t{%0, %0|%0, %0}";
10693 if (REG_P (operands[2]))
10695 if (get_attr_mode (insn) == MODE_SI)
10696 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10698 return "sal{b}\t{%b2, %0|%0, %b2}";
10700 else if (operands[2] == const1_rtx
10701 && (TARGET_SHIFT1 || optimize_size))
10703 if (get_attr_mode (insn) == MODE_SI)
10704 return "sal{l}\t%0";
10706 return "sal{b}\t%0";
10710 if (get_attr_mode (insn) == MODE_SI)
10711 return "sal{l}\t{%2, %k0|%k0, %2}";
10713 return "sal{b}\t{%2, %0|%0, %2}";
10717 [(set (attr "type")
10718 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10720 (match_operand 0 "register_operand" ""))
10721 (match_operand 2 "const1_operand" ""))
10722 (const_string "alu")
10724 (const_string "ishift")))
10725 (set_attr "mode" "QI,SI")])
10727 ;; This pattern can't accept a variable shift count, since shifts by
10728 ;; zero don't affect the flags. We assume that shifts by constant
10729 ;; zero are optimized away.
10730 (define_insn "*ashlqi3_cmp"
10731 [(set (reg FLAGS_REG)
10733 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10734 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10736 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10737 (ashift:QI (match_dup 1) (match_dup 2)))]
10738 "ix86_match_ccmode (insn, CCGOCmode)
10739 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10741 switch (get_attr_type (insn))
10744 gcc_assert (operands[2] == const1_rtx);
10745 return "add{b}\t{%0, %0|%0, %0}";
10748 if (REG_P (operands[2]))
10749 return "sal{b}\t{%b2, %0|%0, %b2}";
10750 else if (operands[2] == const1_rtx
10751 && (TARGET_SHIFT1 || optimize_size))
10752 return "sal{b}\t%0";
10754 return "sal{b}\t{%2, %0|%0, %2}";
10757 [(set (attr "type")
10758 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10760 (match_operand 0 "register_operand" ""))
10761 (match_operand 2 "const1_operand" ""))
10762 (const_string "alu")
10764 (const_string "ishift")))
10765 (set_attr "mode" "QI")])
10767 ;; See comment above `ashldi3' about how this works.
10769 (define_expand "ashrdi3"
10770 [(set (match_operand:DI 0 "shiftdi_operand" "")
10771 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10772 (match_operand:QI 2 "nonmemory_operand" "")))]
10774 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10776 (define_insn "*ashrdi3_63_rex64"
10777 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10778 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10779 (match_operand:DI 2 "const_int_operand" "i,i")))
10780 (clobber (reg:CC FLAGS_REG))]
10781 "TARGET_64BIT && INTVAL (operands[2]) == 63
10782 && (TARGET_USE_CLTD || optimize_size)
10783 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10786 sar{q}\t{%2, %0|%0, %2}"
10787 [(set_attr "type" "imovx,ishift")
10788 (set_attr "prefix_0f" "0,*")
10789 (set_attr "length_immediate" "0,*")
10790 (set_attr "modrm" "0,1")
10791 (set_attr "mode" "DI")])
10793 (define_insn "*ashrdi3_1_one_bit_rex64"
10794 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10795 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10796 (match_operand:QI 2 "const1_operand" "")))
10797 (clobber (reg:CC FLAGS_REG))]
10798 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10799 && (TARGET_SHIFT1 || optimize_size)"
10801 [(set_attr "type" "ishift")
10802 (set (attr "length")
10803 (if_then_else (match_operand:DI 0 "register_operand" "")
10805 (const_string "*")))])
10807 (define_insn "*ashrdi3_1_rex64"
10808 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10809 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10810 (match_operand:QI 2 "nonmemory_operand" "J,c")))
10811 (clobber (reg:CC FLAGS_REG))]
10812 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10814 sar{q}\t{%2, %0|%0, %2}
10815 sar{q}\t{%b2, %0|%0, %b2}"
10816 [(set_attr "type" "ishift")
10817 (set_attr "mode" "DI")])
10819 ;; This pattern can't accept a variable shift count, since shifts by
10820 ;; zero don't affect the flags. We assume that shifts by constant
10821 ;; zero are optimized away.
10822 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10823 [(set (reg FLAGS_REG)
10825 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10826 (match_operand:QI 2 "const1_operand" ""))
10828 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10829 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10830 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10831 && (TARGET_SHIFT1 || optimize_size)
10832 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10834 [(set_attr "type" "ishift")
10835 (set (attr "length")
10836 (if_then_else (match_operand:DI 0 "register_operand" "")
10838 (const_string "*")))])
10840 ;; This pattern can't accept a variable shift count, since shifts by
10841 ;; zero don't affect the flags. We assume that shifts by constant
10842 ;; zero are optimized away.
10843 (define_insn "*ashrdi3_cmp_rex64"
10844 [(set (reg FLAGS_REG)
10846 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10847 (match_operand:QI 2 "const_int_operand" "n"))
10849 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10850 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10851 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10852 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10853 "sar{q}\t{%2, %0|%0, %2}"
10854 [(set_attr "type" "ishift")
10855 (set_attr "mode" "DI")])
10857 (define_insn "*ashrdi3_1"
10858 [(set (match_operand:DI 0 "register_operand" "=r")
10859 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10860 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10861 (clobber (reg:CC FLAGS_REG))]
10864 [(set_attr "type" "multi")])
10866 ;; By default we don't ask for a scratch register, because when DImode
10867 ;; values are manipulated, registers are already at a premium. But if
10868 ;; we have one handy, we won't turn it away.
10870 [(match_scratch:SI 3 "r")
10871 (parallel [(set (match_operand:DI 0 "register_operand" "")
10872 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10873 (match_operand:QI 2 "nonmemory_operand" "")))
10874 (clobber (reg:CC FLAGS_REG))])
10876 "!TARGET_64BIT && TARGET_CMOVE"
10878 "ix86_split_ashrdi (operands, operands[3]); DONE;")
10881 [(set (match_operand:DI 0 "register_operand" "")
10882 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10883 (match_operand:QI 2 "nonmemory_operand" "")))
10884 (clobber (reg:CC FLAGS_REG))]
10885 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10887 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10889 (define_insn "x86_shrd_1"
10890 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10891 (ior:SI (ashiftrt:SI (match_dup 0)
10892 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10893 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10894 (minus:QI (const_int 32) (match_dup 2)))))
10895 (clobber (reg:CC FLAGS_REG))]
10898 shrd{l}\t{%2, %1, %0|%0, %1, %2}
10899 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10900 [(set_attr "type" "ishift")
10901 (set_attr "prefix_0f" "1")
10902 (set_attr "pent_pair" "np")
10903 (set_attr "mode" "SI")])
10905 (define_expand "x86_shift_adj_3"
10906 [(use (match_operand:SI 0 "register_operand" ""))
10907 (use (match_operand:SI 1 "register_operand" ""))
10908 (use (match_operand:QI 2 "register_operand" ""))]
10911 rtx label = gen_label_rtx ();
10914 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10916 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10917 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10918 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10919 gen_rtx_LABEL_REF (VOIDmode, label),
10921 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10922 JUMP_LABEL (tmp) = label;
10924 emit_move_insn (operands[0], operands[1]);
10925 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10927 emit_label (label);
10928 LABEL_NUSES (label) = 1;
10933 (define_insn "ashrsi3_31"
10934 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10935 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10936 (match_operand:SI 2 "const_int_operand" "i,i")))
10937 (clobber (reg:CC FLAGS_REG))]
10938 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10939 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10942 sar{l}\t{%2, %0|%0, %2}"
10943 [(set_attr "type" "imovx,ishift")
10944 (set_attr "prefix_0f" "0,*")
10945 (set_attr "length_immediate" "0,*")
10946 (set_attr "modrm" "0,1")
10947 (set_attr "mode" "SI")])
10949 (define_insn "*ashrsi3_31_zext"
10950 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10951 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10952 (match_operand:SI 2 "const_int_operand" "i,i"))))
10953 (clobber (reg:CC FLAGS_REG))]
10954 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10955 && INTVAL (operands[2]) == 31
10956 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10959 sar{l}\t{%2, %k0|%k0, %2}"
10960 [(set_attr "type" "imovx,ishift")
10961 (set_attr "prefix_0f" "0,*")
10962 (set_attr "length_immediate" "0,*")
10963 (set_attr "modrm" "0,1")
10964 (set_attr "mode" "SI")])
10966 (define_expand "ashrsi3"
10967 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10968 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10969 (match_operand:QI 2 "nonmemory_operand" "")))
10970 (clobber (reg:CC FLAGS_REG))]
10972 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10974 (define_insn "*ashrsi3_1_one_bit"
10975 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10976 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10977 (match_operand:QI 2 "const1_operand" "")))
10978 (clobber (reg:CC FLAGS_REG))]
10979 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10980 && (TARGET_SHIFT1 || optimize_size)"
10982 [(set_attr "type" "ishift")
10983 (set (attr "length")
10984 (if_then_else (match_operand:SI 0 "register_operand" "")
10986 (const_string "*")))])
10988 (define_insn "*ashrsi3_1_one_bit_zext"
10989 [(set (match_operand:DI 0 "register_operand" "=r")
10990 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10991 (match_operand:QI 2 "const1_operand" ""))))
10992 (clobber (reg:CC FLAGS_REG))]
10993 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10994 && (TARGET_SHIFT1 || optimize_size)"
10996 [(set_attr "type" "ishift")
10997 (set_attr "length" "2")])
10999 (define_insn "*ashrsi3_1"
11000 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11001 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11002 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11003 (clobber (reg:CC FLAGS_REG))]
11004 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11006 sar{l}\t{%2, %0|%0, %2}
11007 sar{l}\t{%b2, %0|%0, %b2}"
11008 [(set_attr "type" "ishift")
11009 (set_attr "mode" "SI")])
11011 (define_insn "*ashrsi3_1_zext"
11012 [(set (match_operand:DI 0 "register_operand" "=r,r")
11013 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11014 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11015 (clobber (reg:CC FLAGS_REG))]
11016 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11018 sar{l}\t{%2, %k0|%k0, %2}
11019 sar{l}\t{%b2, %k0|%k0, %b2}"
11020 [(set_attr "type" "ishift")
11021 (set_attr "mode" "SI")])
11023 ;; This pattern can't accept a variable shift count, since shifts by
11024 ;; zero don't affect the flags. We assume that shifts by constant
11025 ;; zero are optimized away.
11026 (define_insn "*ashrsi3_one_bit_cmp"
11027 [(set (reg FLAGS_REG)
11029 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11030 (match_operand:QI 2 "const1_operand" ""))
11032 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11033 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11034 "ix86_match_ccmode (insn, CCGOCmode)
11035 && (TARGET_SHIFT1 || optimize_size)
11036 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11038 [(set_attr "type" "ishift")
11039 (set (attr "length")
11040 (if_then_else (match_operand:SI 0 "register_operand" "")
11042 (const_string "*")))])
11044 (define_insn "*ashrsi3_one_bit_cmp_zext"
11045 [(set (reg FLAGS_REG)
11047 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11048 (match_operand:QI 2 "const1_operand" ""))
11050 (set (match_operand:DI 0 "register_operand" "=r")
11051 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11052 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11053 && (TARGET_SHIFT1 || optimize_size)
11054 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11056 [(set_attr "type" "ishift")
11057 (set_attr "length" "2")])
11059 ;; This pattern can't accept a variable shift count, since shifts by
11060 ;; zero don't affect the flags. We assume that shifts by constant
11061 ;; zero are optimized away.
11062 (define_insn "*ashrsi3_cmp"
11063 [(set (reg FLAGS_REG)
11065 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11066 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11068 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11069 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11070 "ix86_match_ccmode (insn, CCGOCmode)
11071 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11072 "sar{l}\t{%2, %0|%0, %2}"
11073 [(set_attr "type" "ishift")
11074 (set_attr "mode" "SI")])
11076 (define_insn "*ashrsi3_cmp_zext"
11077 [(set (reg FLAGS_REG)
11079 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11080 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11082 (set (match_operand:DI 0 "register_operand" "=r")
11083 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11084 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11085 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11086 "sar{l}\t{%2, %k0|%k0, %2}"
11087 [(set_attr "type" "ishift")
11088 (set_attr "mode" "SI")])
11090 (define_expand "ashrhi3"
11091 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11092 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11093 (match_operand:QI 2 "nonmemory_operand" "")))
11094 (clobber (reg:CC FLAGS_REG))]
11095 "TARGET_HIMODE_MATH"
11096 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11098 (define_insn "*ashrhi3_1_one_bit"
11099 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11100 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11101 (match_operand:QI 2 "const1_operand" "")))
11102 (clobber (reg:CC FLAGS_REG))]
11103 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11104 && (TARGET_SHIFT1 || optimize_size)"
11106 [(set_attr "type" "ishift")
11107 (set (attr "length")
11108 (if_then_else (match_operand 0 "register_operand" "")
11110 (const_string "*")))])
11112 (define_insn "*ashrhi3_1"
11113 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11114 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11115 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11116 (clobber (reg:CC FLAGS_REG))]
11117 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11119 sar{w}\t{%2, %0|%0, %2}
11120 sar{w}\t{%b2, %0|%0, %b2}"
11121 [(set_attr "type" "ishift")
11122 (set_attr "mode" "HI")])
11124 ;; This pattern can't accept a variable shift count, since shifts by
11125 ;; zero don't affect the flags. We assume that shifts by constant
11126 ;; zero are optimized away.
11127 (define_insn "*ashrhi3_one_bit_cmp"
11128 [(set (reg FLAGS_REG)
11130 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11131 (match_operand:QI 2 "const1_operand" ""))
11133 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11134 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11135 "ix86_match_ccmode (insn, CCGOCmode)
11136 && (TARGET_SHIFT1 || optimize_size)
11137 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11139 [(set_attr "type" "ishift")
11140 (set (attr "length")
11141 (if_then_else (match_operand 0 "register_operand" "")
11143 (const_string "*")))])
11145 ;; This pattern can't accept a variable shift count, since shifts by
11146 ;; zero don't affect the flags. We assume that shifts by constant
11147 ;; zero are optimized away.
11148 (define_insn "*ashrhi3_cmp"
11149 [(set (reg FLAGS_REG)
11151 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11152 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11154 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11155 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11156 "ix86_match_ccmode (insn, CCGOCmode)
11157 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11158 "sar{w}\t{%2, %0|%0, %2}"
11159 [(set_attr "type" "ishift")
11160 (set_attr "mode" "HI")])
11162 (define_expand "ashrqi3"
11163 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11164 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11165 (match_operand:QI 2 "nonmemory_operand" "")))
11166 (clobber (reg:CC FLAGS_REG))]
11167 "TARGET_QIMODE_MATH"
11168 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11170 (define_insn "*ashrqi3_1_one_bit"
11171 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11172 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11173 (match_operand:QI 2 "const1_operand" "")))
11174 (clobber (reg:CC FLAGS_REG))]
11175 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11176 && (TARGET_SHIFT1 || optimize_size)"
11178 [(set_attr "type" "ishift")
11179 (set (attr "length")
11180 (if_then_else (match_operand 0 "register_operand" "")
11182 (const_string "*")))])
11184 (define_insn "*ashrqi3_1_one_bit_slp"
11185 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11186 (ashiftrt:QI (match_dup 0)
11187 (match_operand:QI 1 "const1_operand" "")))
11188 (clobber (reg:CC FLAGS_REG))]
11189 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11190 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11191 && (TARGET_SHIFT1 || optimize_size)"
11193 [(set_attr "type" "ishift1")
11194 (set (attr "length")
11195 (if_then_else (match_operand 0 "register_operand" "")
11197 (const_string "*")))])
11199 (define_insn "*ashrqi3_1"
11200 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11201 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11202 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11203 (clobber (reg:CC FLAGS_REG))]
11204 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11206 sar{b}\t{%2, %0|%0, %2}
11207 sar{b}\t{%b2, %0|%0, %b2}"
11208 [(set_attr "type" "ishift")
11209 (set_attr "mode" "QI")])
11211 (define_insn "*ashrqi3_1_slp"
11212 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11213 (ashiftrt:QI (match_dup 0)
11214 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11215 (clobber (reg:CC FLAGS_REG))]
11216 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11217 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11219 sar{b}\t{%1, %0|%0, %1}
11220 sar{b}\t{%b1, %0|%0, %b1}"
11221 [(set_attr "type" "ishift1")
11222 (set_attr "mode" "QI")])
11224 ;; This pattern can't accept a variable shift count, since shifts by
11225 ;; zero don't affect the flags. We assume that shifts by constant
11226 ;; zero are optimized away.
11227 (define_insn "*ashrqi3_one_bit_cmp"
11228 [(set (reg FLAGS_REG)
11230 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11231 (match_operand:QI 2 "const1_operand" "I"))
11233 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11234 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11235 "ix86_match_ccmode (insn, CCGOCmode)
11236 && (TARGET_SHIFT1 || optimize_size)
11237 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11239 [(set_attr "type" "ishift")
11240 (set (attr "length")
11241 (if_then_else (match_operand 0 "register_operand" "")
11243 (const_string "*")))])
11245 ;; This pattern can't accept a variable shift count, since shifts by
11246 ;; zero don't affect the flags. We assume that shifts by constant
11247 ;; zero are optimized away.
11248 (define_insn "*ashrqi3_cmp"
11249 [(set (reg FLAGS_REG)
11251 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11252 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11254 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11255 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11256 "ix86_match_ccmode (insn, CCGOCmode)
11257 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11258 "sar{b}\t{%2, %0|%0, %2}"
11259 [(set_attr "type" "ishift")
11260 (set_attr "mode" "QI")])
11262 ;; Logical shift instructions
11264 ;; See comment above `ashldi3' about how this works.
11266 (define_expand "lshrdi3"
11267 [(set (match_operand:DI 0 "shiftdi_operand" "")
11268 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11269 (match_operand:QI 2 "nonmemory_operand" "")))]
11271 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11273 (define_insn "*lshrdi3_1_one_bit_rex64"
11274 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11275 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11276 (match_operand:QI 2 "const1_operand" "")))
11277 (clobber (reg:CC FLAGS_REG))]
11278 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11279 && (TARGET_SHIFT1 || optimize_size)"
11281 [(set_attr "type" "ishift")
11282 (set (attr "length")
11283 (if_then_else (match_operand:DI 0 "register_operand" "")
11285 (const_string "*")))])
11287 (define_insn "*lshrdi3_1_rex64"
11288 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11289 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11290 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11291 (clobber (reg:CC FLAGS_REG))]
11292 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11294 shr{q}\t{%2, %0|%0, %2}
11295 shr{q}\t{%b2, %0|%0, %b2}"
11296 [(set_attr "type" "ishift")
11297 (set_attr "mode" "DI")])
11299 ;; This pattern can't accept a variable shift count, since shifts by
11300 ;; zero don't affect the flags. We assume that shifts by constant
11301 ;; zero are optimized away.
11302 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11303 [(set (reg FLAGS_REG)
11305 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11306 (match_operand:QI 2 "const1_operand" ""))
11308 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11309 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11310 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11311 && (TARGET_SHIFT1 || optimize_size)
11312 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11314 [(set_attr "type" "ishift")
11315 (set (attr "length")
11316 (if_then_else (match_operand:DI 0 "register_operand" "")
11318 (const_string "*")))])
11320 ;; This pattern can't accept a variable shift count, since shifts by
11321 ;; zero don't affect the flags. We assume that shifts by constant
11322 ;; zero are optimized away.
11323 (define_insn "*lshrdi3_cmp_rex64"
11324 [(set (reg FLAGS_REG)
11326 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11327 (match_operand:QI 2 "const_int_operand" "e"))
11329 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11330 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11331 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11332 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11333 "shr{q}\t{%2, %0|%0, %2}"
11334 [(set_attr "type" "ishift")
11335 (set_attr "mode" "DI")])
11337 (define_insn "*lshrdi3_1"
11338 [(set (match_operand:DI 0 "register_operand" "=r")
11339 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11340 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11341 (clobber (reg:CC FLAGS_REG))]
11344 [(set_attr "type" "multi")])
11346 ;; By default we don't ask for a scratch register, because when DImode
11347 ;; values are manipulated, registers are already at a premium. But if
11348 ;; we have one handy, we won't turn it away.
11350 [(match_scratch:SI 3 "r")
11351 (parallel [(set (match_operand:DI 0 "register_operand" "")
11352 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11353 (match_operand:QI 2 "nonmemory_operand" "")))
11354 (clobber (reg:CC FLAGS_REG))])
11356 "!TARGET_64BIT && TARGET_CMOVE"
11358 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11361 [(set (match_operand:DI 0 "register_operand" "")
11362 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11363 (match_operand:QI 2 "nonmemory_operand" "")))
11364 (clobber (reg:CC FLAGS_REG))]
11365 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11367 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11369 (define_expand "lshrsi3"
11370 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11371 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11372 (match_operand:QI 2 "nonmemory_operand" "")))
11373 (clobber (reg:CC FLAGS_REG))]
11375 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11377 (define_insn "*lshrsi3_1_one_bit"
11378 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11379 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11380 (match_operand:QI 2 "const1_operand" "")))
11381 (clobber (reg:CC FLAGS_REG))]
11382 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11383 && (TARGET_SHIFT1 || optimize_size)"
11385 [(set_attr "type" "ishift")
11386 (set (attr "length")
11387 (if_then_else (match_operand:SI 0 "register_operand" "")
11389 (const_string "*")))])
11391 (define_insn "*lshrsi3_1_one_bit_zext"
11392 [(set (match_operand:DI 0 "register_operand" "=r")
11393 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11394 (match_operand:QI 2 "const1_operand" "")))
11395 (clobber (reg:CC FLAGS_REG))]
11396 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11397 && (TARGET_SHIFT1 || optimize_size)"
11399 [(set_attr "type" "ishift")
11400 (set_attr "length" "2")])
11402 (define_insn "*lshrsi3_1"
11403 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11404 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11405 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11406 (clobber (reg:CC FLAGS_REG))]
11407 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11409 shr{l}\t{%2, %0|%0, %2}
11410 shr{l}\t{%b2, %0|%0, %b2}"
11411 [(set_attr "type" "ishift")
11412 (set_attr "mode" "SI")])
11414 (define_insn "*lshrsi3_1_zext"
11415 [(set (match_operand:DI 0 "register_operand" "=r,r")
11417 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11418 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11419 (clobber (reg:CC FLAGS_REG))]
11420 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11422 shr{l}\t{%2, %k0|%k0, %2}
11423 shr{l}\t{%b2, %k0|%k0, %b2}"
11424 [(set_attr "type" "ishift")
11425 (set_attr "mode" "SI")])
11427 ;; This pattern can't accept a variable shift count, since shifts by
11428 ;; zero don't affect the flags. We assume that shifts by constant
11429 ;; zero are optimized away.
11430 (define_insn "*lshrsi3_one_bit_cmp"
11431 [(set (reg FLAGS_REG)
11433 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11434 (match_operand:QI 2 "const1_operand" ""))
11436 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11437 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11438 "ix86_match_ccmode (insn, CCGOCmode)
11439 && (TARGET_SHIFT1 || optimize_size)
11440 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11442 [(set_attr "type" "ishift")
11443 (set (attr "length")
11444 (if_then_else (match_operand:SI 0 "register_operand" "")
11446 (const_string "*")))])
11448 (define_insn "*lshrsi3_cmp_one_bit_zext"
11449 [(set (reg FLAGS_REG)
11451 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11452 (match_operand:QI 2 "const1_operand" ""))
11454 (set (match_operand:DI 0 "register_operand" "=r")
11455 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11456 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11457 && (TARGET_SHIFT1 || optimize_size)
11458 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11460 [(set_attr "type" "ishift")
11461 (set_attr "length" "2")])
11463 ;; This pattern can't accept a variable shift count, since shifts by
11464 ;; zero don't affect the flags. We assume that shifts by constant
11465 ;; zero are optimized away.
11466 (define_insn "*lshrsi3_cmp"
11467 [(set (reg FLAGS_REG)
11469 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11470 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11472 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11473 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11474 "ix86_match_ccmode (insn, CCGOCmode)
11475 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11476 "shr{l}\t{%2, %0|%0, %2}"
11477 [(set_attr "type" "ishift")
11478 (set_attr "mode" "SI")])
11480 (define_insn "*lshrsi3_cmp_zext"
11481 [(set (reg FLAGS_REG)
11483 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11484 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11486 (set (match_operand:DI 0 "register_operand" "=r")
11487 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11488 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11489 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11490 "shr{l}\t{%2, %k0|%k0, %2}"
11491 [(set_attr "type" "ishift")
11492 (set_attr "mode" "SI")])
11494 (define_expand "lshrhi3"
11495 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11496 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11497 (match_operand:QI 2 "nonmemory_operand" "")))
11498 (clobber (reg:CC FLAGS_REG))]
11499 "TARGET_HIMODE_MATH"
11500 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11502 (define_insn "*lshrhi3_1_one_bit"
11503 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11504 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11505 (match_operand:QI 2 "const1_operand" "")))
11506 (clobber (reg:CC FLAGS_REG))]
11507 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11508 && (TARGET_SHIFT1 || optimize_size)"
11510 [(set_attr "type" "ishift")
11511 (set (attr "length")
11512 (if_then_else (match_operand 0 "register_operand" "")
11514 (const_string "*")))])
11516 (define_insn "*lshrhi3_1"
11517 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11518 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11519 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11520 (clobber (reg:CC FLAGS_REG))]
11521 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11523 shr{w}\t{%2, %0|%0, %2}
11524 shr{w}\t{%b2, %0|%0, %b2}"
11525 [(set_attr "type" "ishift")
11526 (set_attr "mode" "HI")])
11528 ;; This pattern can't accept a variable shift count, since shifts by
11529 ;; zero don't affect the flags. We assume that shifts by constant
11530 ;; zero are optimized away.
11531 (define_insn "*lshrhi3_one_bit_cmp"
11532 [(set (reg FLAGS_REG)
11534 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11535 (match_operand:QI 2 "const1_operand" ""))
11537 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11538 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11539 "ix86_match_ccmode (insn, CCGOCmode)
11540 && (TARGET_SHIFT1 || optimize_size)
11541 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11543 [(set_attr "type" "ishift")
11544 (set (attr "length")
11545 (if_then_else (match_operand:SI 0 "register_operand" "")
11547 (const_string "*")))])
11549 ;; This pattern can't accept a variable shift count, since shifts by
11550 ;; zero don't affect the flags. We assume that shifts by constant
11551 ;; zero are optimized away.
11552 (define_insn "*lshrhi3_cmp"
11553 [(set (reg FLAGS_REG)
11555 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11556 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11558 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11559 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11560 "ix86_match_ccmode (insn, CCGOCmode)
11561 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11562 "shr{w}\t{%2, %0|%0, %2}"
11563 [(set_attr "type" "ishift")
11564 (set_attr "mode" "HI")])
11566 (define_expand "lshrqi3"
11567 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11568 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11569 (match_operand:QI 2 "nonmemory_operand" "")))
11570 (clobber (reg:CC FLAGS_REG))]
11571 "TARGET_QIMODE_MATH"
11572 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11574 (define_insn "*lshrqi3_1_one_bit"
11575 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11576 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11577 (match_operand:QI 2 "const1_operand" "")))
11578 (clobber (reg:CC FLAGS_REG))]
11579 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11580 && (TARGET_SHIFT1 || optimize_size)"
11582 [(set_attr "type" "ishift")
11583 (set (attr "length")
11584 (if_then_else (match_operand 0 "register_operand" "")
11586 (const_string "*")))])
11588 (define_insn "*lshrqi3_1_one_bit_slp"
11589 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11590 (lshiftrt:QI (match_dup 0)
11591 (match_operand:QI 1 "const1_operand" "")))
11592 (clobber (reg:CC FLAGS_REG))]
11593 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11594 && (TARGET_SHIFT1 || optimize_size)"
11596 [(set_attr "type" "ishift1")
11597 (set (attr "length")
11598 (if_then_else (match_operand 0 "register_operand" "")
11600 (const_string "*")))])
11602 (define_insn "*lshrqi3_1"
11603 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11604 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11605 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11606 (clobber (reg:CC FLAGS_REG))]
11607 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11609 shr{b}\t{%2, %0|%0, %2}
11610 shr{b}\t{%b2, %0|%0, %b2}"
11611 [(set_attr "type" "ishift")
11612 (set_attr "mode" "QI")])
11614 (define_insn "*lshrqi3_1_slp"
11615 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11616 (lshiftrt:QI (match_dup 0)
11617 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11618 (clobber (reg:CC FLAGS_REG))]
11619 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11620 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11622 shr{b}\t{%1, %0|%0, %1}
11623 shr{b}\t{%b1, %0|%0, %b1}"
11624 [(set_attr "type" "ishift1")
11625 (set_attr "mode" "QI")])
11627 ;; This pattern can't accept a variable shift count, since shifts by
11628 ;; zero don't affect the flags. We assume that shifts by constant
11629 ;; zero are optimized away.
11630 (define_insn "*lshrqi2_one_bit_cmp"
11631 [(set (reg FLAGS_REG)
11633 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11634 (match_operand:QI 2 "const1_operand" ""))
11636 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11637 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11638 "ix86_match_ccmode (insn, CCGOCmode)
11639 && (TARGET_SHIFT1 || optimize_size)
11640 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11642 [(set_attr "type" "ishift")
11643 (set (attr "length")
11644 (if_then_else (match_operand:SI 0 "register_operand" "")
11646 (const_string "*")))])
11648 ;; This pattern can't accept a variable shift count, since shifts by
11649 ;; zero don't affect the flags. We assume that shifts by constant
11650 ;; zero are optimized away.
11651 (define_insn "*lshrqi2_cmp"
11652 [(set (reg FLAGS_REG)
11654 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11655 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11657 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11658 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11659 "ix86_match_ccmode (insn, CCGOCmode)
11660 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11661 "shr{b}\t{%2, %0|%0, %2}"
11662 [(set_attr "type" "ishift")
11663 (set_attr "mode" "QI")])
11665 ;; Rotate instructions
11667 (define_expand "rotldi3"
11668 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11669 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11670 (match_operand:QI 2 "nonmemory_operand" "")))
11671 (clobber (reg:CC FLAGS_REG))]
11673 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11675 (define_insn "*rotlsi3_1_one_bit_rex64"
11676 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11677 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11678 (match_operand:QI 2 "const1_operand" "")))
11679 (clobber (reg:CC FLAGS_REG))]
11680 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11681 && (TARGET_SHIFT1 || optimize_size)"
11683 [(set_attr "type" "rotate")
11684 (set (attr "length")
11685 (if_then_else (match_operand:DI 0 "register_operand" "")
11687 (const_string "*")))])
11689 (define_insn "*rotldi3_1_rex64"
11690 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11691 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11692 (match_operand:QI 2 "nonmemory_operand" "e,c")))
11693 (clobber (reg:CC FLAGS_REG))]
11694 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11696 rol{q}\t{%2, %0|%0, %2}
11697 rol{q}\t{%b2, %0|%0, %b2}"
11698 [(set_attr "type" "rotate")
11699 (set_attr "mode" "DI")])
11701 (define_expand "rotlsi3"
11702 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11703 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11704 (match_operand:QI 2 "nonmemory_operand" "")))
11705 (clobber (reg:CC FLAGS_REG))]
11707 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11709 (define_insn "*rotlsi3_1_one_bit"
11710 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11711 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11712 (match_operand:QI 2 "const1_operand" "")))
11713 (clobber (reg:CC FLAGS_REG))]
11714 "ix86_binary_operator_ok (ROTATE, SImode, operands)
11715 && (TARGET_SHIFT1 || optimize_size)"
11717 [(set_attr "type" "rotate")
11718 (set (attr "length")
11719 (if_then_else (match_operand:SI 0 "register_operand" "")
11721 (const_string "*")))])
11723 (define_insn "*rotlsi3_1_one_bit_zext"
11724 [(set (match_operand:DI 0 "register_operand" "=r")
11726 (rotate:SI (match_operand:SI 1 "register_operand" "0")
11727 (match_operand:QI 2 "const1_operand" ""))))
11728 (clobber (reg:CC FLAGS_REG))]
11729 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11730 && (TARGET_SHIFT1 || optimize_size)"
11732 [(set_attr "type" "rotate")
11733 (set_attr "length" "2")])
11735 (define_insn "*rotlsi3_1"
11736 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11737 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11738 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11739 (clobber (reg:CC FLAGS_REG))]
11740 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11742 rol{l}\t{%2, %0|%0, %2}
11743 rol{l}\t{%b2, %0|%0, %b2}"
11744 [(set_attr "type" "rotate")
11745 (set_attr "mode" "SI")])
11747 (define_insn "*rotlsi3_1_zext"
11748 [(set (match_operand:DI 0 "register_operand" "=r,r")
11750 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11751 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11752 (clobber (reg:CC FLAGS_REG))]
11753 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11755 rol{l}\t{%2, %k0|%k0, %2}
11756 rol{l}\t{%b2, %k0|%k0, %b2}"
11757 [(set_attr "type" "rotate")
11758 (set_attr "mode" "SI")])
11760 (define_expand "rotlhi3"
11761 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11762 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11763 (match_operand:QI 2 "nonmemory_operand" "")))
11764 (clobber (reg:CC FLAGS_REG))]
11765 "TARGET_HIMODE_MATH"
11766 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11768 (define_insn "*rotlhi3_1_one_bit"
11769 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11770 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11771 (match_operand:QI 2 "const1_operand" "")))
11772 (clobber (reg:CC FLAGS_REG))]
11773 "ix86_binary_operator_ok (ROTATE, HImode, operands)
11774 && (TARGET_SHIFT1 || optimize_size)"
11776 [(set_attr "type" "rotate")
11777 (set (attr "length")
11778 (if_then_else (match_operand 0 "register_operand" "")
11780 (const_string "*")))])
11782 (define_insn "*rotlhi3_1"
11783 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11784 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11785 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11786 (clobber (reg:CC FLAGS_REG))]
11787 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11789 rol{w}\t{%2, %0|%0, %2}
11790 rol{w}\t{%b2, %0|%0, %b2}"
11791 [(set_attr "type" "rotate")
11792 (set_attr "mode" "HI")])
11794 (define_expand "rotlqi3"
11795 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11796 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11797 (match_operand:QI 2 "nonmemory_operand" "")))
11798 (clobber (reg:CC FLAGS_REG))]
11799 "TARGET_QIMODE_MATH"
11800 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11802 (define_insn "*rotlqi3_1_one_bit_slp"
11803 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11804 (rotate:QI (match_dup 0)
11805 (match_operand:QI 1 "const1_operand" "")))
11806 (clobber (reg:CC FLAGS_REG))]
11807 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11808 && (TARGET_SHIFT1 || optimize_size)"
11810 [(set_attr "type" "rotate1")
11811 (set (attr "length")
11812 (if_then_else (match_operand 0 "register_operand" "")
11814 (const_string "*")))])
11816 (define_insn "*rotlqi3_1_one_bit"
11817 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11818 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11819 (match_operand:QI 2 "const1_operand" "")))
11820 (clobber (reg:CC FLAGS_REG))]
11821 "ix86_binary_operator_ok (ROTATE, QImode, operands)
11822 && (TARGET_SHIFT1 || optimize_size)"
11824 [(set_attr "type" "rotate")
11825 (set (attr "length")
11826 (if_then_else (match_operand 0 "register_operand" "")
11828 (const_string "*")))])
11830 (define_insn "*rotlqi3_1_slp"
11831 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11832 (rotate:QI (match_dup 0)
11833 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11834 (clobber (reg:CC FLAGS_REG))]
11835 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11836 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11838 rol{b}\t{%1, %0|%0, %1}
11839 rol{b}\t{%b1, %0|%0, %b1}"
11840 [(set_attr "type" "rotate1")
11841 (set_attr "mode" "QI")])
11843 (define_insn "*rotlqi3_1"
11844 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11845 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11846 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11847 (clobber (reg:CC FLAGS_REG))]
11848 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11850 rol{b}\t{%2, %0|%0, %2}
11851 rol{b}\t{%b2, %0|%0, %b2}"
11852 [(set_attr "type" "rotate")
11853 (set_attr "mode" "QI")])
11855 (define_expand "rotrdi3"
11856 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11857 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11858 (match_operand:QI 2 "nonmemory_operand" "")))
11859 (clobber (reg:CC FLAGS_REG))]
11861 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11863 (define_insn "*rotrdi3_1_one_bit_rex64"
11864 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11865 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11866 (match_operand:QI 2 "const1_operand" "")))
11867 (clobber (reg:CC FLAGS_REG))]
11868 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11869 && (TARGET_SHIFT1 || optimize_size)"
11871 [(set_attr "type" "rotate")
11872 (set (attr "length")
11873 (if_then_else (match_operand:DI 0 "register_operand" "")
11875 (const_string "*")))])
11877 (define_insn "*rotrdi3_1_rex64"
11878 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11879 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11880 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11881 (clobber (reg:CC FLAGS_REG))]
11882 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11884 ror{q}\t{%2, %0|%0, %2}
11885 ror{q}\t{%b2, %0|%0, %b2}"
11886 [(set_attr "type" "rotate")
11887 (set_attr "mode" "DI")])
11889 (define_expand "rotrsi3"
11890 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11891 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11892 (match_operand:QI 2 "nonmemory_operand" "")))
11893 (clobber (reg:CC FLAGS_REG))]
11895 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11897 (define_insn "*rotrsi3_1_one_bit"
11898 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11899 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11900 (match_operand:QI 2 "const1_operand" "")))
11901 (clobber (reg:CC FLAGS_REG))]
11902 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11903 && (TARGET_SHIFT1 || optimize_size)"
11905 [(set_attr "type" "rotate")
11906 (set (attr "length")
11907 (if_then_else (match_operand:SI 0 "register_operand" "")
11909 (const_string "*")))])
11911 (define_insn "*rotrsi3_1_one_bit_zext"
11912 [(set (match_operand:DI 0 "register_operand" "=r")
11914 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11915 (match_operand:QI 2 "const1_operand" ""))))
11916 (clobber (reg:CC FLAGS_REG))]
11917 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11918 && (TARGET_SHIFT1 || optimize_size)"
11920 [(set_attr "type" "rotate")
11921 (set (attr "length")
11922 (if_then_else (match_operand:SI 0 "register_operand" "")
11924 (const_string "*")))])
11926 (define_insn "*rotrsi3_1"
11927 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11928 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11929 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11930 (clobber (reg:CC FLAGS_REG))]
11931 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11933 ror{l}\t{%2, %0|%0, %2}
11934 ror{l}\t{%b2, %0|%0, %b2}"
11935 [(set_attr "type" "rotate")
11936 (set_attr "mode" "SI")])
11938 (define_insn "*rotrsi3_1_zext"
11939 [(set (match_operand:DI 0 "register_operand" "=r,r")
11941 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11942 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11943 (clobber (reg:CC FLAGS_REG))]
11944 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11946 ror{l}\t{%2, %k0|%k0, %2}
11947 ror{l}\t{%b2, %k0|%k0, %b2}"
11948 [(set_attr "type" "rotate")
11949 (set_attr "mode" "SI")])
11951 (define_expand "rotrhi3"
11952 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11953 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11954 (match_operand:QI 2 "nonmemory_operand" "")))
11955 (clobber (reg:CC FLAGS_REG))]
11956 "TARGET_HIMODE_MATH"
11957 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11959 (define_insn "*rotrhi3_one_bit"
11960 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11961 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11962 (match_operand:QI 2 "const1_operand" "")))
11963 (clobber (reg:CC FLAGS_REG))]
11964 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11965 && (TARGET_SHIFT1 || optimize_size)"
11967 [(set_attr "type" "rotate")
11968 (set (attr "length")
11969 (if_then_else (match_operand 0 "register_operand" "")
11971 (const_string "*")))])
11973 (define_insn "*rotrhi3"
11974 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11975 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11976 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11977 (clobber (reg:CC FLAGS_REG))]
11978 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11980 ror{w}\t{%2, %0|%0, %2}
11981 ror{w}\t{%b2, %0|%0, %b2}"
11982 [(set_attr "type" "rotate")
11983 (set_attr "mode" "HI")])
11985 (define_expand "rotrqi3"
11986 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11987 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
11988 (match_operand:QI 2 "nonmemory_operand" "")))
11989 (clobber (reg:CC FLAGS_REG))]
11990 "TARGET_QIMODE_MATH"
11991 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
11993 (define_insn "*rotrqi3_1_one_bit"
11994 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11995 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11996 (match_operand:QI 2 "const1_operand" "")))
11997 (clobber (reg:CC FLAGS_REG))]
11998 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
11999 && (TARGET_SHIFT1 || optimize_size)"
12001 [(set_attr "type" "rotate")
12002 (set (attr "length")
12003 (if_then_else (match_operand 0 "register_operand" "")
12005 (const_string "*")))])
12007 (define_insn "*rotrqi3_1_one_bit_slp"
12008 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12009 (rotatert:QI (match_dup 0)
12010 (match_operand:QI 1 "const1_operand" "")))
12011 (clobber (reg:CC FLAGS_REG))]
12012 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12013 && (TARGET_SHIFT1 || optimize_size)"
12015 [(set_attr "type" "rotate1")
12016 (set (attr "length")
12017 (if_then_else (match_operand 0 "register_operand" "")
12019 (const_string "*")))])
12021 (define_insn "*rotrqi3_1"
12022 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12023 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12024 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12025 (clobber (reg:CC FLAGS_REG))]
12026 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12028 ror{b}\t{%2, %0|%0, %2}
12029 ror{b}\t{%b2, %0|%0, %b2}"
12030 [(set_attr "type" "rotate")
12031 (set_attr "mode" "QI")])
12033 (define_insn "*rotrqi3_1_slp"
12034 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12035 (rotatert:QI (match_dup 0)
12036 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12037 (clobber (reg:CC FLAGS_REG))]
12038 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12039 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12041 ror{b}\t{%1, %0|%0, %1}
12042 ror{b}\t{%b1, %0|%0, %b1}"
12043 [(set_attr "type" "rotate1")
12044 (set_attr "mode" "QI")])
12046 ;; Bit set / bit test instructions
12048 (define_expand "extv"
12049 [(set (match_operand:SI 0 "register_operand" "")
12050 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12051 (match_operand:SI 2 "immediate_operand" "")
12052 (match_operand:SI 3 "immediate_operand" "")))]
12055 /* Handle extractions from %ah et al. */
12056 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12059 /* From mips.md: extract_bit_field doesn't verify that our source
12060 matches the predicate, so check it again here. */
12061 if (! ext_register_operand (operands[1], VOIDmode))
12065 (define_expand "extzv"
12066 [(set (match_operand:SI 0 "register_operand" "")
12067 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12068 (match_operand:SI 2 "immediate_operand" "")
12069 (match_operand:SI 3 "immediate_operand" "")))]
12072 /* Handle extractions from %ah et al. */
12073 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12076 /* From mips.md: extract_bit_field doesn't verify that our source
12077 matches the predicate, so check it again here. */
12078 if (! ext_register_operand (operands[1], VOIDmode))
12082 (define_expand "insv"
12083 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12084 (match_operand 1 "immediate_operand" "")
12085 (match_operand 2 "immediate_operand" ""))
12086 (match_operand 3 "register_operand" ""))]
12089 /* Handle extractions from %ah et al. */
12090 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12093 /* From mips.md: insert_bit_field doesn't verify that our source
12094 matches the predicate, so check it again here. */
12095 if (! ext_register_operand (operands[0], VOIDmode))
12099 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12101 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12106 ;; %%% bts, btr, btc, bt.
12107 ;; In general these instructions are *slow* when applied to memory,
12108 ;; since they enforce atomic operation. When applied to registers,
12109 ;; it depends on the cpu implementation. They're never faster than
12110 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12111 ;; no point. But in 64-bit, we can't hold the relevant immediates
12112 ;; within the instruction itself, so operating on bits in the high
12113 ;; 32-bits of a register becomes easier.
12115 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12116 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12117 ;; negdf respectively, so they can never be disabled entirely.
12119 (define_insn "*btsq"
12120 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12122 (match_operand:DI 1 "const_0_to_63_operand" ""))
12124 (clobber (reg:CC FLAGS_REG))]
12125 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12127 [(set_attr "type" "alu1")])
12129 (define_insn "*btrq"
12130 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12132 (match_operand:DI 1 "const_0_to_63_operand" ""))
12134 (clobber (reg:CC FLAGS_REG))]
12135 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12137 [(set_attr "type" "alu1")])
12139 (define_insn "*btcq"
12140 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12142 (match_operand:DI 1 "const_0_to_63_operand" ""))
12143 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12144 (clobber (reg:CC FLAGS_REG))]
12145 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12147 [(set_attr "type" "alu1")])
12149 ;; Allow Nocona to avoid these instructions if a register is available.
12152 [(match_scratch:DI 2 "r")
12153 (parallel [(set (zero_extract:DI
12154 (match_operand:DI 0 "register_operand" "")
12156 (match_operand:DI 1 "const_0_to_63_operand" ""))
12158 (clobber (reg:CC FLAGS_REG))])]
12159 "TARGET_64BIT && !TARGET_USE_BT"
12162 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12165 if (HOST_BITS_PER_WIDE_INT >= 64)
12166 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12167 else if (i < HOST_BITS_PER_WIDE_INT)
12168 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12170 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12172 op1 = immed_double_const (lo, hi, DImode);
12175 emit_move_insn (operands[2], op1);
12179 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12184 [(match_scratch:DI 2 "r")
12185 (parallel [(set (zero_extract:DI
12186 (match_operand:DI 0 "register_operand" "")
12188 (match_operand:DI 1 "const_0_to_63_operand" ""))
12190 (clobber (reg:CC FLAGS_REG))])]
12191 "TARGET_64BIT && !TARGET_USE_BT"
12194 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12197 if (HOST_BITS_PER_WIDE_INT >= 64)
12198 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12199 else if (i < HOST_BITS_PER_WIDE_INT)
12200 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12202 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12204 op1 = immed_double_const (~lo, ~hi, DImode);
12207 emit_move_insn (operands[2], op1);
12211 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12216 [(match_scratch:DI 2 "r")
12217 (parallel [(set (zero_extract:DI
12218 (match_operand:DI 0 "register_operand" "")
12220 (match_operand:DI 1 "const_0_to_63_operand" ""))
12221 (not:DI (zero_extract:DI
12222 (match_dup 0) (const_int 1) (match_dup 1))))
12223 (clobber (reg:CC FLAGS_REG))])]
12224 "TARGET_64BIT && !TARGET_USE_BT"
12227 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12230 if (HOST_BITS_PER_WIDE_INT >= 64)
12231 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12232 else if (i < HOST_BITS_PER_WIDE_INT)
12233 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12235 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12237 op1 = immed_double_const (lo, hi, DImode);
12240 emit_move_insn (operands[2], op1);
12244 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12248 ;; Store-flag instructions.
12250 ;; For all sCOND expanders, also expand the compare or test insn that
12251 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12253 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12254 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12255 ;; way, which can later delete the movzx if only QImode is needed.
12257 (define_expand "seq"
12258 [(set (match_operand:QI 0 "register_operand" "")
12259 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12261 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12263 (define_expand "sne"
12264 [(set (match_operand:QI 0 "register_operand" "")
12265 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12267 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12269 (define_expand "sgt"
12270 [(set (match_operand:QI 0 "register_operand" "")
12271 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12273 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12275 (define_expand "sgtu"
12276 [(set (match_operand:QI 0 "register_operand" "")
12277 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12279 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12281 (define_expand "slt"
12282 [(set (match_operand:QI 0 "register_operand" "")
12283 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12285 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12287 (define_expand "sltu"
12288 [(set (match_operand:QI 0 "register_operand" "")
12289 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12291 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12293 (define_expand "sge"
12294 [(set (match_operand:QI 0 "register_operand" "")
12295 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12297 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12299 (define_expand "sgeu"
12300 [(set (match_operand:QI 0 "register_operand" "")
12301 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12303 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12305 (define_expand "sle"
12306 [(set (match_operand:QI 0 "register_operand" "")
12307 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12309 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12311 (define_expand "sleu"
12312 [(set (match_operand:QI 0 "register_operand" "")
12313 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12315 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12317 (define_expand "sunordered"
12318 [(set (match_operand:QI 0 "register_operand" "")
12319 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12320 "TARGET_80387 || TARGET_SSE"
12321 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12323 (define_expand "sordered"
12324 [(set (match_operand:QI 0 "register_operand" "")
12325 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12327 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12329 (define_expand "suneq"
12330 [(set (match_operand:QI 0 "register_operand" "")
12331 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12332 "TARGET_80387 || TARGET_SSE"
12333 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12335 (define_expand "sunge"
12336 [(set (match_operand:QI 0 "register_operand" "")
12337 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12338 "TARGET_80387 || TARGET_SSE"
12339 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12341 (define_expand "sungt"
12342 [(set (match_operand:QI 0 "register_operand" "")
12343 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12344 "TARGET_80387 || TARGET_SSE"
12345 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12347 (define_expand "sunle"
12348 [(set (match_operand:QI 0 "register_operand" "")
12349 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12350 "TARGET_80387 || TARGET_SSE"
12351 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12353 (define_expand "sunlt"
12354 [(set (match_operand:QI 0 "register_operand" "")
12355 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12356 "TARGET_80387 || TARGET_SSE"
12357 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12359 (define_expand "sltgt"
12360 [(set (match_operand:QI 0 "register_operand" "")
12361 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12362 "TARGET_80387 || TARGET_SSE"
12363 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12365 (define_insn "*setcc_1"
12366 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12367 (match_operator:QI 1 "ix86_comparison_operator"
12368 [(reg FLAGS_REG) (const_int 0)]))]
12371 [(set_attr "type" "setcc")
12372 (set_attr "mode" "QI")])
12374 (define_insn "*setcc_2"
12375 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12376 (match_operator:QI 1 "ix86_comparison_operator"
12377 [(reg FLAGS_REG) (const_int 0)]))]
12380 [(set_attr "type" "setcc")
12381 (set_attr "mode" "QI")])
12383 ;; In general it is not safe to assume too much about CCmode registers,
12384 ;; so simplify-rtx stops when it sees a second one. Under certain
12385 ;; conditions this is safe on x86, so help combine not create
12392 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12393 (ne:QI (match_operator 1 "ix86_comparison_operator"
12394 [(reg FLAGS_REG) (const_int 0)])
12397 [(set (match_dup 0) (match_dup 1))]
12399 PUT_MODE (operands[1], QImode);
12403 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12404 (ne:QI (match_operator 1 "ix86_comparison_operator"
12405 [(reg FLAGS_REG) (const_int 0)])
12408 [(set (match_dup 0) (match_dup 1))]
12410 PUT_MODE (operands[1], QImode);
12414 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12415 (eq:QI (match_operator 1 "ix86_comparison_operator"
12416 [(reg FLAGS_REG) (const_int 0)])
12419 [(set (match_dup 0) (match_dup 1))]
12421 rtx new_op1 = copy_rtx (operands[1]);
12422 operands[1] = new_op1;
12423 PUT_MODE (new_op1, QImode);
12424 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12425 GET_MODE (XEXP (new_op1, 0))));
12427 /* Make sure that (a) the CCmode we have for the flags is strong
12428 enough for the reversed compare or (b) we have a valid FP compare. */
12429 if (! ix86_comparison_operator (new_op1, VOIDmode))
12434 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12435 (eq:QI (match_operator 1 "ix86_comparison_operator"
12436 [(reg FLAGS_REG) (const_int 0)])
12439 [(set (match_dup 0) (match_dup 1))]
12441 rtx new_op1 = copy_rtx (operands[1]);
12442 operands[1] = new_op1;
12443 PUT_MODE (new_op1, QImode);
12444 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12445 GET_MODE (XEXP (new_op1, 0))));
12447 /* Make sure that (a) the CCmode we have for the flags is strong
12448 enough for the reversed compare or (b) we have a valid FP compare. */
12449 if (! ix86_comparison_operator (new_op1, VOIDmode))
12453 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12454 ;; subsequent logical operations are used to imitate conditional moves.
12455 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12458 (define_insn "*sse_setccsf"
12459 [(set (match_operand:SF 0 "register_operand" "=x")
12460 (match_operator:SF 1 "sse_comparison_operator"
12461 [(match_operand:SF 2 "register_operand" "0")
12462 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12464 "cmp%D1ss\t{%3, %0|%0, %3}"
12465 [(set_attr "type" "ssecmp")
12466 (set_attr "mode" "SF")])
12468 (define_insn "*sse_setccdf"
12469 [(set (match_operand:DF 0 "register_operand" "=Y")
12470 (match_operator:DF 1 "sse_comparison_operator"
12471 [(match_operand:DF 2 "register_operand" "0")
12472 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12474 "cmp%D1sd\t{%3, %0|%0, %3}"
12475 [(set_attr "type" "ssecmp")
12476 (set_attr "mode" "DF")])
12478 ;; Basic conditional jump instructions.
12479 ;; We ignore the overflow flag for signed branch instructions.
12481 ;; For all bCOND expanders, also expand the compare or test insn that
12482 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12484 (define_expand "beq"
12486 (if_then_else (match_dup 1)
12487 (label_ref (match_operand 0 "" ""))
12490 "ix86_expand_branch (EQ, operands[0]); DONE;")
12492 (define_expand "bne"
12494 (if_then_else (match_dup 1)
12495 (label_ref (match_operand 0 "" ""))
12498 "ix86_expand_branch (NE, operands[0]); DONE;")
12500 (define_expand "bgt"
12502 (if_then_else (match_dup 1)
12503 (label_ref (match_operand 0 "" ""))
12506 "ix86_expand_branch (GT, operands[0]); DONE;")
12508 (define_expand "bgtu"
12510 (if_then_else (match_dup 1)
12511 (label_ref (match_operand 0 "" ""))
12514 "ix86_expand_branch (GTU, operands[0]); DONE;")
12516 (define_expand "blt"
12518 (if_then_else (match_dup 1)
12519 (label_ref (match_operand 0 "" ""))
12522 "ix86_expand_branch (LT, operands[0]); DONE;")
12524 (define_expand "bltu"
12526 (if_then_else (match_dup 1)
12527 (label_ref (match_operand 0 "" ""))
12530 "ix86_expand_branch (LTU, operands[0]); DONE;")
12532 (define_expand "bge"
12534 (if_then_else (match_dup 1)
12535 (label_ref (match_operand 0 "" ""))
12538 "ix86_expand_branch (GE, operands[0]); DONE;")
12540 (define_expand "bgeu"
12542 (if_then_else (match_dup 1)
12543 (label_ref (match_operand 0 "" ""))
12546 "ix86_expand_branch (GEU, operands[0]); DONE;")
12548 (define_expand "ble"
12550 (if_then_else (match_dup 1)
12551 (label_ref (match_operand 0 "" ""))
12554 "ix86_expand_branch (LE, operands[0]); DONE;")
12556 (define_expand "bleu"
12558 (if_then_else (match_dup 1)
12559 (label_ref (match_operand 0 "" ""))
12562 "ix86_expand_branch (LEU, operands[0]); DONE;")
12564 (define_expand "bunordered"
12566 (if_then_else (match_dup 1)
12567 (label_ref (match_operand 0 "" ""))
12569 "TARGET_80387 || TARGET_SSE_MATH"
12570 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12572 (define_expand "bordered"
12574 (if_then_else (match_dup 1)
12575 (label_ref (match_operand 0 "" ""))
12577 "TARGET_80387 || TARGET_SSE_MATH"
12578 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12580 (define_expand "buneq"
12582 (if_then_else (match_dup 1)
12583 (label_ref (match_operand 0 "" ""))
12585 "TARGET_80387 || TARGET_SSE_MATH"
12586 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12588 (define_expand "bunge"
12590 (if_then_else (match_dup 1)
12591 (label_ref (match_operand 0 "" ""))
12593 "TARGET_80387 || TARGET_SSE_MATH"
12594 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12596 (define_expand "bungt"
12598 (if_then_else (match_dup 1)
12599 (label_ref (match_operand 0 "" ""))
12601 "TARGET_80387 || TARGET_SSE_MATH"
12602 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12604 (define_expand "bunle"
12606 (if_then_else (match_dup 1)
12607 (label_ref (match_operand 0 "" ""))
12609 "TARGET_80387 || TARGET_SSE_MATH"
12610 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12612 (define_expand "bunlt"
12614 (if_then_else (match_dup 1)
12615 (label_ref (match_operand 0 "" ""))
12617 "TARGET_80387 || TARGET_SSE_MATH"
12618 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12620 (define_expand "bltgt"
12622 (if_then_else (match_dup 1)
12623 (label_ref (match_operand 0 "" ""))
12625 "TARGET_80387 || TARGET_SSE_MATH"
12626 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12628 (define_insn "*jcc_1"
12630 (if_then_else (match_operator 1 "ix86_comparison_operator"
12631 [(reg FLAGS_REG) (const_int 0)])
12632 (label_ref (match_operand 0 "" ""))
12636 [(set_attr "type" "ibr")
12637 (set_attr "modrm" "0")
12638 (set (attr "length")
12639 (if_then_else (and (ge (minus (match_dup 0) (pc))
12641 (lt (minus (match_dup 0) (pc))
12646 (define_insn "*jcc_2"
12648 (if_then_else (match_operator 1 "ix86_comparison_operator"
12649 [(reg FLAGS_REG) (const_int 0)])
12651 (label_ref (match_operand 0 "" ""))))]
12654 [(set_attr "type" "ibr")
12655 (set_attr "modrm" "0")
12656 (set (attr "length")
12657 (if_then_else (and (ge (minus (match_dup 0) (pc))
12659 (lt (minus (match_dup 0) (pc))
12664 ;; In general it is not safe to assume too much about CCmode registers,
12665 ;; so simplify-rtx stops when it sees a second one. Under certain
12666 ;; conditions this is safe on x86, so help combine not create
12674 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12675 [(reg FLAGS_REG) (const_int 0)])
12677 (label_ref (match_operand 1 "" ""))
12681 (if_then_else (match_dup 0)
12682 (label_ref (match_dup 1))
12685 PUT_MODE (operands[0], VOIDmode);
12690 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12691 [(reg FLAGS_REG) (const_int 0)])
12693 (label_ref (match_operand 1 "" ""))
12697 (if_then_else (match_dup 0)
12698 (label_ref (match_dup 1))
12701 rtx new_op0 = copy_rtx (operands[0]);
12702 operands[0] = new_op0;
12703 PUT_MODE (new_op0, VOIDmode);
12704 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12705 GET_MODE (XEXP (new_op0, 0))));
12707 /* Make sure that (a) the CCmode we have for the flags is strong
12708 enough for the reversed compare or (b) we have a valid FP compare. */
12709 if (! ix86_comparison_operator (new_op0, VOIDmode))
12713 ;; Define combination compare-and-branch fp compare instructions to use
12714 ;; during early optimization. Splitting the operation apart early makes
12715 ;; for bad code when we want to reverse the operation.
12717 (define_insn "*fp_jcc_1_mixed"
12719 (if_then_else (match_operator 0 "comparison_operator"
12720 [(match_operand 1 "register_operand" "f#x,x#f")
12721 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12722 (label_ref (match_operand 3 "" ""))
12724 (clobber (reg:CCFP FPSR_REG))
12725 (clobber (reg:CCFP FLAGS_REG))]
12726 "TARGET_MIX_SSE_I387
12727 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12728 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12729 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12732 (define_insn "*fp_jcc_1_sse"
12734 (if_then_else (match_operator 0 "comparison_operator"
12735 [(match_operand 1 "register_operand" "x")
12736 (match_operand 2 "nonimmediate_operand" "xm")])
12737 (label_ref (match_operand 3 "" ""))
12739 (clobber (reg:CCFP FPSR_REG))
12740 (clobber (reg:CCFP FLAGS_REG))]
12742 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12743 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12744 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12747 (define_insn "*fp_jcc_1_387"
12749 (if_then_else (match_operator 0 "comparison_operator"
12750 [(match_operand 1 "register_operand" "f")
12751 (match_operand 2 "register_operand" "f")])
12752 (label_ref (match_operand 3 "" ""))
12754 (clobber (reg:CCFP FPSR_REG))
12755 (clobber (reg:CCFP FLAGS_REG))]
12756 "TARGET_CMOVE && TARGET_80387
12757 && FLOAT_MODE_P (GET_MODE (operands[1]))
12758 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12759 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12762 (define_insn "*fp_jcc_2_mixed"
12764 (if_then_else (match_operator 0 "comparison_operator"
12765 [(match_operand 1 "register_operand" "f#x,x#f")
12766 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12768 (label_ref (match_operand 3 "" ""))))
12769 (clobber (reg:CCFP FPSR_REG))
12770 (clobber (reg:CCFP FLAGS_REG))]
12771 "TARGET_MIX_SSE_I387
12772 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12773 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12774 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12777 (define_insn "*fp_jcc_2_sse"
12779 (if_then_else (match_operator 0 "comparison_operator"
12780 [(match_operand 1 "register_operand" "x")
12781 (match_operand 2 "nonimmediate_operand" "xm")])
12783 (label_ref (match_operand 3 "" ""))))
12784 (clobber (reg:CCFP FPSR_REG))
12785 (clobber (reg:CCFP FLAGS_REG))]
12787 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12788 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12789 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12792 (define_insn "*fp_jcc_2_387"
12794 (if_then_else (match_operator 0 "comparison_operator"
12795 [(match_operand 1 "register_operand" "f")
12796 (match_operand 2 "register_operand" "f")])
12798 (label_ref (match_operand 3 "" ""))))
12799 (clobber (reg:CCFP FPSR_REG))
12800 (clobber (reg:CCFP FLAGS_REG))]
12801 "TARGET_CMOVE && TARGET_80387
12802 && FLOAT_MODE_P (GET_MODE (operands[1]))
12803 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12804 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12807 (define_insn "*fp_jcc_3_387"
12809 (if_then_else (match_operator 0 "comparison_operator"
12810 [(match_operand 1 "register_operand" "f")
12811 (match_operand 2 "nonimmediate_operand" "fm")])
12812 (label_ref (match_operand 3 "" ""))
12814 (clobber (reg:CCFP FPSR_REG))
12815 (clobber (reg:CCFP FLAGS_REG))
12816 (clobber (match_scratch:HI 4 "=a"))]
12818 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12819 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12820 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12821 && SELECT_CC_MODE (GET_CODE (operands[0]),
12822 operands[1], operands[2]) == CCFPmode
12823 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12826 (define_insn "*fp_jcc_4_387"
12828 (if_then_else (match_operator 0 "comparison_operator"
12829 [(match_operand 1 "register_operand" "f")
12830 (match_operand 2 "nonimmediate_operand" "fm")])
12832 (label_ref (match_operand 3 "" ""))))
12833 (clobber (reg:CCFP FPSR_REG))
12834 (clobber (reg:CCFP FLAGS_REG))
12835 (clobber (match_scratch:HI 4 "=a"))]
12837 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12838 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12839 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12840 && SELECT_CC_MODE (GET_CODE (operands[0]),
12841 operands[1], operands[2]) == CCFPmode
12842 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12845 (define_insn "*fp_jcc_5_387"
12847 (if_then_else (match_operator 0 "comparison_operator"
12848 [(match_operand 1 "register_operand" "f")
12849 (match_operand 2 "register_operand" "f")])
12850 (label_ref (match_operand 3 "" ""))
12852 (clobber (reg:CCFP FPSR_REG))
12853 (clobber (reg:CCFP FLAGS_REG))
12854 (clobber (match_scratch:HI 4 "=a"))]
12856 && FLOAT_MODE_P (GET_MODE (operands[1]))
12857 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12858 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12861 (define_insn "*fp_jcc_6_387"
12863 (if_then_else (match_operator 0 "comparison_operator"
12864 [(match_operand 1 "register_operand" "f")
12865 (match_operand 2 "register_operand" "f")])
12867 (label_ref (match_operand 3 "" ""))))
12868 (clobber (reg:CCFP FPSR_REG))
12869 (clobber (reg:CCFP FLAGS_REG))
12870 (clobber (match_scratch:HI 4 "=a"))]
12872 && FLOAT_MODE_P (GET_MODE (operands[1]))
12873 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12874 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12877 (define_insn "*fp_jcc_7_387"
12879 (if_then_else (match_operator 0 "comparison_operator"
12880 [(match_operand 1 "register_operand" "f")
12881 (match_operand 2 "const0_operand" "X")])
12882 (label_ref (match_operand 3 "" ""))
12884 (clobber (reg:CCFP FPSR_REG))
12885 (clobber (reg:CCFP FLAGS_REG))
12886 (clobber (match_scratch:HI 4 "=a"))]
12888 && FLOAT_MODE_P (GET_MODE (operands[1]))
12889 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12890 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12891 && SELECT_CC_MODE (GET_CODE (operands[0]),
12892 operands[1], operands[2]) == CCFPmode
12893 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12896 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
12897 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12898 ;; with a precedence over other operators and is always put in the first
12899 ;; place. Swap condition and operands to match ficom instruction.
12901 (define_insn "*fp_jcc_8<mode>_387"
12903 (if_then_else (match_operator 0 "comparison_operator"
12904 [(match_operator 1 "float_operator"
12905 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
12906 (match_operand 3 "register_operand" "f,f")])
12907 (label_ref (match_operand 4 "" ""))
12909 (clobber (reg:CCFP FPSR_REG))
12910 (clobber (reg:CCFP FLAGS_REG))
12911 (clobber (match_scratch:HI 5 "=a,a"))]
12912 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
12913 && FLOAT_MODE_P (GET_MODE (operands[3]))
12914 && GET_MODE (operands[1]) == GET_MODE (operands[3])
12915 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12916 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12917 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12922 (if_then_else (match_operator 0 "comparison_operator"
12923 [(match_operand 1 "register_operand" "")
12924 (match_operand 2 "nonimmediate_operand" "")])
12925 (match_operand 3 "" "")
12926 (match_operand 4 "" "")))
12927 (clobber (reg:CCFP FPSR_REG))
12928 (clobber (reg:CCFP FLAGS_REG))]
12932 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12933 operands[3], operands[4], NULL_RTX, NULL_RTX);
12939 (if_then_else (match_operator 0 "comparison_operator"
12940 [(match_operand 1 "register_operand" "")
12941 (match_operand 2 "general_operand" "")])
12942 (match_operand 3 "" "")
12943 (match_operand 4 "" "")))
12944 (clobber (reg:CCFP FPSR_REG))
12945 (clobber (reg:CCFP FLAGS_REG))
12946 (clobber (match_scratch:HI 5 "=a"))]
12950 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12951 operands[3], operands[4], operands[5], NULL_RTX);
12957 (if_then_else (match_operator 0 "comparison_operator"
12958 [(match_operator 1 "float_operator"
12959 [(match_operand:X87MODEI12 2 "memory_operand" "")])
12960 (match_operand 3 "register_operand" "")])
12961 (match_operand 4 "" "")
12962 (match_operand 5 "" "")))
12963 (clobber (reg:CCFP FPSR_REG))
12964 (clobber (reg:CCFP FLAGS_REG))
12965 (clobber (match_scratch:HI 6 "=a"))]
12969 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12970 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12971 operands[3], operands[7],
12972 operands[4], operands[5], operands[6], NULL_RTX);
12976 ;; %%% Kill this when reload knows how to do it.
12979 (if_then_else (match_operator 0 "comparison_operator"
12980 [(match_operator 1 "float_operator"
12981 [(match_operand:X87MODEI12 2 "register_operand" "")])
12982 (match_operand 3 "register_operand" "")])
12983 (match_operand 4 "" "")
12984 (match_operand 5 "" "")))
12985 (clobber (reg:CCFP FPSR_REG))
12986 (clobber (reg:CCFP FLAGS_REG))
12987 (clobber (match_scratch:HI 6 "=a"))]
12991 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12992 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
12993 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12994 operands[3], operands[7],
12995 operands[4], operands[5], operands[6], operands[2]);
12999 ;; Unconditional and other jump instructions
13001 (define_insn "jump"
13003 (label_ref (match_operand 0 "" "")))]
13006 [(set_attr "type" "ibr")
13007 (set (attr "length")
13008 (if_then_else (and (ge (minus (match_dup 0) (pc))
13010 (lt (minus (match_dup 0) (pc))
13014 (set_attr "modrm" "0")])
13016 (define_expand "indirect_jump"
13017 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13021 (define_insn "*indirect_jump"
13022 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13025 [(set_attr "type" "ibr")
13026 (set_attr "length_immediate" "0")])
13028 (define_insn "*indirect_jump_rtx64"
13029 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13032 [(set_attr "type" "ibr")
13033 (set_attr "length_immediate" "0")])
13035 (define_expand "tablejump"
13036 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13037 (use (label_ref (match_operand 1 "" "")))])]
13040 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13041 relative. Convert the relative address to an absolute address. */
13045 enum rtx_code code;
13051 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13053 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13057 op1 = pic_offset_table_rtx;
13062 op0 = pic_offset_table_rtx;
13066 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13071 (define_insn "*tablejump_1"
13072 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13073 (use (label_ref (match_operand 1 "" "")))]
13076 [(set_attr "type" "ibr")
13077 (set_attr "length_immediate" "0")])
13079 (define_insn "*tablejump_1_rtx64"
13080 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13081 (use (label_ref (match_operand 1 "" "")))]
13084 [(set_attr "type" "ibr")
13085 (set_attr "length_immediate" "0")])
13087 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13090 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13091 (set (match_operand:QI 1 "register_operand" "")
13092 (match_operator:QI 2 "ix86_comparison_operator"
13093 [(reg FLAGS_REG) (const_int 0)]))
13094 (set (match_operand 3 "q_regs_operand" "")
13095 (zero_extend (match_dup 1)))]
13096 "(peep2_reg_dead_p (3, operands[1])
13097 || operands_match_p (operands[1], operands[3]))
13098 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13099 [(set (match_dup 4) (match_dup 0))
13100 (set (strict_low_part (match_dup 5))
13103 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13104 operands[5] = gen_lowpart (QImode, operands[3]);
13105 ix86_expand_clear (operands[3]);
13108 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13111 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13112 (set (match_operand:QI 1 "register_operand" "")
13113 (match_operator:QI 2 "ix86_comparison_operator"
13114 [(reg FLAGS_REG) (const_int 0)]))
13115 (parallel [(set (match_operand 3 "q_regs_operand" "")
13116 (zero_extend (match_dup 1)))
13117 (clobber (reg:CC FLAGS_REG))])]
13118 "(peep2_reg_dead_p (3, operands[1])
13119 || operands_match_p (operands[1], operands[3]))
13120 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13121 [(set (match_dup 4) (match_dup 0))
13122 (set (strict_low_part (match_dup 5))
13125 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13126 operands[5] = gen_lowpart (QImode, operands[3]);
13127 ix86_expand_clear (operands[3]);
13130 ;; Call instructions.
13132 ;; The predicates normally associated with named expanders are not properly
13133 ;; checked for calls. This is a bug in the generic code, but it isn't that
13134 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13136 ;; Call subroutine returning no value.
13138 (define_expand "call_pop"
13139 [(parallel [(call (match_operand:QI 0 "" "")
13140 (match_operand:SI 1 "" ""))
13141 (set (reg:SI SP_REG)
13142 (plus:SI (reg:SI SP_REG)
13143 (match_operand:SI 3 "" "")))])]
13146 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13150 (define_insn "*call_pop_0"
13151 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13152 (match_operand:SI 1 "" ""))
13153 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13154 (match_operand:SI 2 "immediate_operand" "")))]
13157 if (SIBLING_CALL_P (insn))
13160 return "call\t%P0";
13162 [(set_attr "type" "call")])
13164 (define_insn "*call_pop_1"
13165 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13166 (match_operand:SI 1 "" ""))
13167 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13168 (match_operand:SI 2 "immediate_operand" "i")))]
13171 if (constant_call_address_operand (operands[0], Pmode))
13173 if (SIBLING_CALL_P (insn))
13176 return "call\t%P0";
13178 if (SIBLING_CALL_P (insn))
13181 return "call\t%A0";
13183 [(set_attr "type" "call")])
13185 (define_expand "call"
13186 [(call (match_operand:QI 0 "" "")
13187 (match_operand 1 "" ""))
13188 (use (match_operand 2 "" ""))]
13191 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13195 (define_expand "sibcall"
13196 [(call (match_operand:QI 0 "" "")
13197 (match_operand 1 "" ""))
13198 (use (match_operand 2 "" ""))]
13201 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13205 (define_insn "*call_0"
13206 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13207 (match_operand 1 "" ""))]
13210 if (SIBLING_CALL_P (insn))
13213 return "call\t%P0";
13215 [(set_attr "type" "call")])
13217 (define_insn "*call_1"
13218 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13219 (match_operand 1 "" ""))]
13220 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13222 if (constant_call_address_operand (operands[0], Pmode))
13223 return "call\t%P0";
13224 return "call\t%A0";
13226 [(set_attr "type" "call")])
13228 (define_insn "*sibcall_1"
13229 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13230 (match_operand 1 "" ""))]
13231 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13233 if (constant_call_address_operand (operands[0], Pmode))
13237 [(set_attr "type" "call")])
13239 (define_insn "*call_1_rex64"
13240 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13241 (match_operand 1 "" ""))]
13242 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13244 if (constant_call_address_operand (operands[0], Pmode))
13245 return "call\t%P0";
13246 return "call\t%A0";
13248 [(set_attr "type" "call")])
13250 (define_insn "*sibcall_1_rex64"
13251 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13252 (match_operand 1 "" ""))]
13253 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13255 [(set_attr "type" "call")])
13257 (define_insn "*sibcall_1_rex64_v"
13258 [(call (mem:QI (reg:DI 40))
13259 (match_operand 0 "" ""))]
13260 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13262 [(set_attr "type" "call")])
13265 ;; Call subroutine, returning value in operand 0
13267 (define_expand "call_value_pop"
13268 [(parallel [(set (match_operand 0 "" "")
13269 (call (match_operand:QI 1 "" "")
13270 (match_operand:SI 2 "" "")))
13271 (set (reg:SI SP_REG)
13272 (plus:SI (reg:SI SP_REG)
13273 (match_operand:SI 4 "" "")))])]
13276 ix86_expand_call (operands[0], operands[1], operands[2],
13277 operands[3], operands[4], 0);
13281 (define_expand "call_value"
13282 [(set (match_operand 0 "" "")
13283 (call (match_operand:QI 1 "" "")
13284 (match_operand:SI 2 "" "")))
13285 (use (match_operand:SI 3 "" ""))]
13286 ;; Operand 2 not used on the i386.
13289 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13293 (define_expand "sibcall_value"
13294 [(set (match_operand 0 "" "")
13295 (call (match_operand:QI 1 "" "")
13296 (match_operand:SI 2 "" "")))
13297 (use (match_operand:SI 3 "" ""))]
13298 ;; Operand 2 not used on the i386.
13301 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13305 ;; Call subroutine returning any type.
13307 (define_expand "untyped_call"
13308 [(parallel [(call (match_operand 0 "" "")
13310 (match_operand 1 "" "")
13311 (match_operand 2 "" "")])]
13316 /* In order to give reg-stack an easier job in validating two
13317 coprocessor registers as containing a possible return value,
13318 simply pretend the untyped call returns a complex long double
13321 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13322 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13323 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13326 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13328 rtx set = XVECEXP (operands[2], 0, i);
13329 emit_move_insn (SET_DEST (set), SET_SRC (set));
13332 /* The optimizer does not know that the call sets the function value
13333 registers we stored in the result block. We avoid problems by
13334 claiming that all hard registers are used and clobbered at this
13336 emit_insn (gen_blockage (const0_rtx));
13341 ;; Prologue and epilogue instructions
13343 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13344 ;; all of memory. This blocks insns from being moved across this point.
13346 (define_insn "blockage"
13347 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13350 [(set_attr "length" "0")])
13352 ;; Insn emitted into the body of a function to return from a function.
13353 ;; This is only done if the function's epilogue is known to be simple.
13354 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13356 (define_expand "return"
13358 "ix86_can_use_return_insn_p ()"
13360 if (current_function_pops_args)
13362 rtx popc = GEN_INT (current_function_pops_args);
13363 emit_jump_insn (gen_return_pop_internal (popc));
13368 (define_insn "return_internal"
13372 [(set_attr "length" "1")
13373 (set_attr "length_immediate" "0")
13374 (set_attr "modrm" "0")])
13376 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13377 ;; instruction Athlon and K8 have.
13379 (define_insn "return_internal_long"
13381 (unspec [(const_int 0)] UNSPEC_REP)]
13384 [(set_attr "length" "1")
13385 (set_attr "length_immediate" "0")
13386 (set_attr "prefix_rep" "1")
13387 (set_attr "modrm" "0")])
13389 (define_insn "return_pop_internal"
13391 (use (match_operand:SI 0 "const_int_operand" ""))]
13394 [(set_attr "length" "3")
13395 (set_attr "length_immediate" "2")
13396 (set_attr "modrm" "0")])
13398 (define_insn "return_indirect_internal"
13400 (use (match_operand:SI 0 "register_operand" "r"))]
13403 [(set_attr "type" "ibr")
13404 (set_attr "length_immediate" "0")])
13410 [(set_attr "length" "1")
13411 (set_attr "length_immediate" "0")
13412 (set_attr "modrm" "0")])
13414 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13415 ;; branch prediction penalty for the third jump in a 16-byte
13418 (define_insn "align"
13419 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13422 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13423 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13425 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13426 The align insn is used to avoid 3 jump instructions in the row to improve
13427 branch prediction and the benefits hardly outweight the cost of extra 8
13428 nops on the average inserted by full alignment pseudo operation. */
13432 [(set_attr "length" "16")])
13434 (define_expand "prologue"
13437 "ix86_expand_prologue (); DONE;")
13439 (define_insn "set_got"
13440 [(set (match_operand:SI 0 "register_operand" "=r")
13441 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13442 (clobber (reg:CC FLAGS_REG))]
13444 { return output_set_got (operands[0]); }
13445 [(set_attr "type" "multi")
13446 (set_attr "length" "12")])
13448 (define_expand "epilogue"
13451 "ix86_expand_epilogue (1); DONE;")
13453 (define_expand "sibcall_epilogue"
13456 "ix86_expand_epilogue (0); DONE;")
13458 (define_expand "eh_return"
13459 [(use (match_operand 0 "register_operand" ""))]
13462 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13464 /* Tricky bit: we write the address of the handler to which we will
13465 be returning into someone else's stack frame, one word below the
13466 stack address we wish to restore. */
13467 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13468 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13469 tmp = gen_rtx_MEM (Pmode, tmp);
13470 emit_move_insn (tmp, ra);
13472 if (Pmode == SImode)
13473 emit_jump_insn (gen_eh_return_si (sa));
13475 emit_jump_insn (gen_eh_return_di (sa));
13480 (define_insn_and_split "eh_return_si"
13482 (unspec [(match_operand:SI 0 "register_operand" "c")]
13483 UNSPEC_EH_RETURN))]
13488 "ix86_expand_epilogue (2); DONE;")
13490 (define_insn_and_split "eh_return_di"
13492 (unspec [(match_operand:DI 0 "register_operand" "c")]
13493 UNSPEC_EH_RETURN))]
13498 "ix86_expand_epilogue (2); DONE;")
13500 (define_insn "leave"
13501 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13502 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13503 (clobber (mem:BLK (scratch)))]
13506 [(set_attr "type" "leave")])
13508 (define_insn "leave_rex64"
13509 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13510 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13511 (clobber (mem:BLK (scratch)))]
13514 [(set_attr "type" "leave")])
13516 (define_expand "ffssi2"
13518 [(set (match_operand:SI 0 "register_operand" "")
13519 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13520 (clobber (match_scratch:SI 2 ""))
13521 (clobber (reg:CC FLAGS_REG))])]
13525 (define_insn_and_split "*ffs_cmove"
13526 [(set (match_operand:SI 0 "register_operand" "=r")
13527 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13528 (clobber (match_scratch:SI 2 "=&r"))
13529 (clobber (reg:CC FLAGS_REG))]
13532 "&& reload_completed"
13533 [(set (match_dup 2) (const_int -1))
13534 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13535 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13536 (set (match_dup 0) (if_then_else:SI
13537 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13540 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13541 (clobber (reg:CC FLAGS_REG))])]
13544 (define_insn_and_split "*ffs_no_cmove"
13545 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13546 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13547 (clobber (match_scratch:SI 2 "=&q"))
13548 (clobber (reg:CC FLAGS_REG))]
13552 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13553 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13554 (set (strict_low_part (match_dup 3))
13555 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13556 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13557 (clobber (reg:CC FLAGS_REG))])
13558 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13559 (clobber (reg:CC FLAGS_REG))])
13560 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13561 (clobber (reg:CC FLAGS_REG))])]
13563 operands[3] = gen_lowpart (QImode, operands[2]);
13564 ix86_expand_clear (operands[2]);
13567 (define_insn "*ffssi_1"
13568 [(set (reg:CCZ FLAGS_REG)
13569 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13571 (set (match_operand:SI 0 "register_operand" "=r")
13572 (ctz:SI (match_dup 1)))]
13574 "bsf{l}\t{%1, %0|%0, %1}"
13575 [(set_attr "prefix_0f" "1")])
13577 (define_expand "ffsdi2"
13579 [(set (match_operand:DI 0 "register_operand" "")
13580 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13581 (clobber (match_scratch:DI 2 ""))
13582 (clobber (reg:CC FLAGS_REG))])]
13583 "TARGET_64BIT && TARGET_CMOVE"
13586 (define_insn_and_split "*ffs_rex64"
13587 [(set (match_operand:DI 0 "register_operand" "=r")
13588 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13589 (clobber (match_scratch:DI 2 "=&r"))
13590 (clobber (reg:CC FLAGS_REG))]
13591 "TARGET_64BIT && TARGET_CMOVE"
13593 "&& reload_completed"
13594 [(set (match_dup 2) (const_int -1))
13595 (parallel [(set (reg:CCZ FLAGS_REG)
13596 (compare:CCZ (match_dup 1) (const_int 0)))
13597 (set (match_dup 0) (ctz:DI (match_dup 1)))])
13598 (set (match_dup 0) (if_then_else:DI
13599 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13602 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13603 (clobber (reg:CC FLAGS_REG))])]
13606 (define_insn "*ffsdi_1"
13607 [(set (reg:CCZ FLAGS_REG)
13608 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13610 (set (match_operand:DI 0 "register_operand" "=r")
13611 (ctz:DI (match_dup 1)))]
13613 "bsf{q}\t{%1, %0|%0, %1}"
13614 [(set_attr "prefix_0f" "1")])
13616 (define_insn "ctzsi2"
13617 [(set (match_operand:SI 0 "register_operand" "=r")
13618 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13619 (clobber (reg:CC FLAGS_REG))]
13621 "bsf{l}\t{%1, %0|%0, %1}"
13622 [(set_attr "prefix_0f" "1")])
13624 (define_insn "ctzdi2"
13625 [(set (match_operand:DI 0 "register_operand" "=r")
13626 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13627 (clobber (reg:CC FLAGS_REG))]
13629 "bsf{q}\t{%1, %0|%0, %1}"
13630 [(set_attr "prefix_0f" "1")])
13632 (define_expand "clzsi2"
13634 [(set (match_operand:SI 0 "register_operand" "")
13635 (minus:SI (const_int 31)
13636 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13637 (clobber (reg:CC FLAGS_REG))])
13639 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13640 (clobber (reg:CC FLAGS_REG))])]
13644 (define_insn "*bsr"
13645 [(set (match_operand:SI 0 "register_operand" "=r")
13646 (minus:SI (const_int 31)
13647 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13648 (clobber (reg:CC FLAGS_REG))]
13650 "bsr{l}\t{%1, %0|%0, %1}"
13651 [(set_attr "prefix_0f" "1")])
13653 (define_expand "clzdi2"
13655 [(set (match_operand:DI 0 "register_operand" "")
13656 (minus:DI (const_int 63)
13657 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13658 (clobber (reg:CC FLAGS_REG))])
13660 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13661 (clobber (reg:CC FLAGS_REG))])]
13665 (define_insn "*bsr_rex64"
13666 [(set (match_operand:DI 0 "register_operand" "=r")
13667 (minus:DI (const_int 63)
13668 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13669 (clobber (reg:CC FLAGS_REG))]
13671 "bsr{q}\t{%1, %0|%0, %1}"
13672 [(set_attr "prefix_0f" "1")])
13674 ;; Thread-local storage patterns for ELF.
13676 ;; Note that these code sequences must appear exactly as shown
13677 ;; in order to allow linker relaxation.
13679 (define_insn "*tls_global_dynamic_32_gnu"
13680 [(set (match_operand:SI 0 "register_operand" "=a")
13681 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13682 (match_operand:SI 2 "tls_symbolic_operand" "")
13683 (match_operand:SI 3 "call_insn_operand" "")]
13685 (clobber (match_scratch:SI 4 "=d"))
13686 (clobber (match_scratch:SI 5 "=c"))
13687 (clobber (reg:CC FLAGS_REG))]
13688 "!TARGET_64BIT && TARGET_GNU_TLS"
13689 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13690 [(set_attr "type" "multi")
13691 (set_attr "length" "12")])
13693 (define_insn "*tls_global_dynamic_32_sun"
13694 [(set (match_operand:SI 0 "register_operand" "=a")
13695 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13696 (match_operand:SI 2 "tls_symbolic_operand" "")
13697 (match_operand:SI 3 "call_insn_operand" "")]
13699 (clobber (match_scratch:SI 4 "=d"))
13700 (clobber (match_scratch:SI 5 "=c"))
13701 (clobber (reg:CC FLAGS_REG))]
13702 "!TARGET_64BIT && TARGET_SUN_TLS"
13703 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13704 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13705 [(set_attr "type" "multi")
13706 (set_attr "length" "14")])
13708 (define_expand "tls_global_dynamic_32"
13709 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13712 (match_operand:SI 1 "tls_symbolic_operand" "")
13715 (clobber (match_scratch:SI 4 ""))
13716 (clobber (match_scratch:SI 5 ""))
13717 (clobber (reg:CC FLAGS_REG))])]
13721 operands[2] = pic_offset_table_rtx;
13724 operands[2] = gen_reg_rtx (Pmode);
13725 emit_insn (gen_set_got (operands[2]));
13727 operands[3] = ix86_tls_get_addr ();
13730 (define_insn "*tls_global_dynamic_64"
13731 [(set (match_operand:DI 0 "register_operand" "=a")
13732 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13733 (match_operand:DI 3 "" "")))
13734 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13737 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13738 [(set_attr "type" "multi")
13739 (set_attr "length" "16")])
13741 (define_expand "tls_global_dynamic_64"
13742 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13743 (call (mem:QI (match_dup 2)) (const_int 0)))
13744 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13748 operands[2] = ix86_tls_get_addr ();
13751 (define_insn "*tls_local_dynamic_base_32_gnu"
13752 [(set (match_operand:SI 0 "register_operand" "=a")
13753 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13754 (match_operand:SI 2 "call_insn_operand" "")]
13755 UNSPEC_TLS_LD_BASE))
13756 (clobber (match_scratch:SI 3 "=d"))
13757 (clobber (match_scratch:SI 4 "=c"))
13758 (clobber (reg:CC FLAGS_REG))]
13759 "!TARGET_64BIT && TARGET_GNU_TLS"
13760 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13761 [(set_attr "type" "multi")
13762 (set_attr "length" "11")])
13764 (define_insn "*tls_local_dynamic_base_32_sun"
13765 [(set (match_operand:SI 0 "register_operand" "=a")
13766 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13767 (match_operand:SI 2 "call_insn_operand" "")]
13768 UNSPEC_TLS_LD_BASE))
13769 (clobber (match_scratch:SI 3 "=d"))
13770 (clobber (match_scratch:SI 4 "=c"))
13771 (clobber (reg:CC FLAGS_REG))]
13772 "!TARGET_64BIT && TARGET_SUN_TLS"
13773 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13774 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13775 [(set_attr "type" "multi")
13776 (set_attr "length" "13")])
13778 (define_expand "tls_local_dynamic_base_32"
13779 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13780 (unspec:SI [(match_dup 1) (match_dup 2)]
13781 UNSPEC_TLS_LD_BASE))
13782 (clobber (match_scratch:SI 3 ""))
13783 (clobber (match_scratch:SI 4 ""))
13784 (clobber (reg:CC FLAGS_REG))])]
13788 operands[1] = pic_offset_table_rtx;
13791 operands[1] = gen_reg_rtx (Pmode);
13792 emit_insn (gen_set_got (operands[1]));
13794 operands[2] = ix86_tls_get_addr ();
13797 (define_insn "*tls_local_dynamic_base_64"
13798 [(set (match_operand:DI 0 "register_operand" "=a")
13799 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13800 (match_operand:DI 2 "" "")))
13801 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13803 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13804 [(set_attr "type" "multi")
13805 (set_attr "length" "12")])
13807 (define_expand "tls_local_dynamic_base_64"
13808 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13809 (call (mem:QI (match_dup 1)) (const_int 0)))
13810 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13813 operands[1] = ix86_tls_get_addr ();
13816 ;; Local dynamic of a single variable is a lose. Show combine how
13817 ;; to convert that back to global dynamic.
13819 (define_insn_and_split "*tls_local_dynamic_32_once"
13820 [(set (match_operand:SI 0 "register_operand" "=a")
13821 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13822 (match_operand:SI 2 "call_insn_operand" "")]
13823 UNSPEC_TLS_LD_BASE)
13824 (const:SI (unspec:SI
13825 [(match_operand:SI 3 "tls_symbolic_operand" "")]
13827 (clobber (match_scratch:SI 4 "=d"))
13828 (clobber (match_scratch:SI 5 "=c"))
13829 (clobber (reg:CC FLAGS_REG))]
13833 [(parallel [(set (match_dup 0)
13834 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13836 (clobber (match_dup 4))
13837 (clobber (match_dup 5))
13838 (clobber (reg:CC FLAGS_REG))])]
13841 ;; Load and add the thread base pointer from %gs:0.
13843 (define_insn "*load_tp_si"
13844 [(set (match_operand:SI 0 "register_operand" "=r")
13845 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13847 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13848 [(set_attr "type" "imov")
13849 (set_attr "modrm" "0")
13850 (set_attr "length" "7")
13851 (set_attr "memory" "load")
13852 (set_attr "imm_disp" "false")])
13854 (define_insn "*add_tp_si"
13855 [(set (match_operand:SI 0 "register_operand" "=r")
13856 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13857 (match_operand:SI 1 "register_operand" "0")))
13858 (clobber (reg:CC FLAGS_REG))]
13860 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13861 [(set_attr "type" "alu")
13862 (set_attr "modrm" "0")
13863 (set_attr "length" "7")
13864 (set_attr "memory" "load")
13865 (set_attr "imm_disp" "false")])
13867 (define_insn "*load_tp_di"
13868 [(set (match_operand:DI 0 "register_operand" "=r")
13869 (unspec:DI [(const_int 0)] UNSPEC_TP))]
13871 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13872 [(set_attr "type" "imov")
13873 (set_attr "modrm" "0")
13874 (set_attr "length" "7")
13875 (set_attr "memory" "load")
13876 (set_attr "imm_disp" "false")])
13878 (define_insn "*add_tp_di"
13879 [(set (match_operand:DI 0 "register_operand" "=r")
13880 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
13881 (match_operand:DI 1 "register_operand" "0")))
13882 (clobber (reg:CC FLAGS_REG))]
13884 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13885 [(set_attr "type" "alu")
13886 (set_attr "modrm" "0")
13887 (set_attr "length" "7")
13888 (set_attr "memory" "load")
13889 (set_attr "imm_disp" "false")])
13891 ;; These patterns match the binary 387 instructions for addM3, subM3,
13892 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13893 ;; SFmode. The first is the normal insn, the second the same insn but
13894 ;; with one operand a conversion, and the third the same insn but with
13895 ;; the other operand a conversion. The conversion may be SFmode or
13896 ;; SImode if the target mode DFmode, but only SImode if the target mode
13899 ;; Gcc is slightly more smart about handling normal two address instructions
13900 ;; so use special patterns for add and mull.
13902 (define_insn "*fop_sf_comm_mixed"
13903 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13904 (match_operator:SF 3 "binary_fp_operator"
13905 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
13906 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13907 "TARGET_MIX_SSE_I387
13908 && COMMUTATIVE_ARITH_P (operands[3])
13909 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13910 "* return output_387_binary_op (insn, operands);"
13911 [(set (attr "type")
13912 (if_then_else (eq_attr "alternative" "1")
13913 (if_then_else (match_operand:SF 3 "mult_operator" "")
13914 (const_string "ssemul")
13915 (const_string "sseadd"))
13916 (if_then_else (match_operand:SF 3 "mult_operator" "")
13917 (const_string "fmul")
13918 (const_string "fop"))))
13919 (set_attr "mode" "SF")])
13921 (define_insn "*fop_sf_comm_sse"
13922 [(set (match_operand:SF 0 "register_operand" "=x")
13923 (match_operator:SF 3 "binary_fp_operator"
13924 [(match_operand:SF 1 "nonimmediate_operand" "%0")
13925 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13927 && COMMUTATIVE_ARITH_P (operands[3])
13928 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13929 "* return output_387_binary_op (insn, operands);"
13930 [(set (attr "type")
13931 (if_then_else (match_operand:SF 3 "mult_operator" "")
13932 (const_string "ssemul")
13933 (const_string "sseadd")))
13934 (set_attr "mode" "SF")])
13936 (define_insn "*fop_sf_comm_i387"
13937 [(set (match_operand:SF 0 "register_operand" "=f")
13938 (match_operator:SF 3 "binary_fp_operator"
13939 [(match_operand:SF 1 "nonimmediate_operand" "%0")
13940 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
13942 && COMMUTATIVE_ARITH_P (operands[3])
13943 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13944 "* return output_387_binary_op (insn, operands);"
13945 [(set (attr "type")
13946 (if_then_else (match_operand:SF 3 "mult_operator" "")
13947 (const_string "fmul")
13948 (const_string "fop")))
13949 (set_attr "mode" "SF")])
13951 (define_insn "*fop_sf_1_mixed"
13952 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
13953 (match_operator:SF 3 "binary_fp_operator"
13954 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
13955 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
13956 "TARGET_MIX_SSE_I387
13957 && !COMMUTATIVE_ARITH_P (operands[3])
13958 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13959 "* return output_387_binary_op (insn, operands);"
13960 [(set (attr "type")
13961 (cond [(and (eq_attr "alternative" "2")
13962 (match_operand:SF 3 "mult_operator" ""))
13963 (const_string "ssemul")
13964 (and (eq_attr "alternative" "2")
13965 (match_operand:SF 3 "div_operator" ""))
13966 (const_string "ssediv")
13967 (eq_attr "alternative" "2")
13968 (const_string "sseadd")
13969 (match_operand:SF 3 "mult_operator" "")
13970 (const_string "fmul")
13971 (match_operand:SF 3 "div_operator" "")
13972 (const_string "fdiv")
13974 (const_string "fop")))
13975 (set_attr "mode" "SF")])
13977 (define_insn "*fop_sf_1_sse"
13978 [(set (match_operand:SF 0 "register_operand" "=x")
13979 (match_operator:SF 3 "binary_fp_operator"
13980 [(match_operand:SF 1 "register_operand" "0")
13981 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13983 && !COMMUTATIVE_ARITH_P (operands[3])"
13984 "* return output_387_binary_op (insn, operands);"
13985 [(set (attr "type")
13986 (cond [(match_operand:SF 3 "mult_operator" "")
13987 (const_string "ssemul")
13988 (match_operand:SF 3 "div_operator" "")
13989 (const_string "ssediv")
13991 (const_string "sseadd")))
13992 (set_attr "mode" "SF")])
13994 ;; This pattern is not fully shadowed by the pattern above.
13995 (define_insn "*fop_sf_1_i387"
13996 [(set (match_operand:SF 0 "register_operand" "=f,f")
13997 (match_operator:SF 3 "binary_fp_operator"
13998 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
13999 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14000 "TARGET_80387 && !TARGET_SSE_MATH
14001 && !COMMUTATIVE_ARITH_P (operands[3])
14002 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14003 "* return output_387_binary_op (insn, operands);"
14004 [(set (attr "type")
14005 (cond [(match_operand:SF 3 "mult_operator" "")
14006 (const_string "fmul")
14007 (match_operand:SF 3 "div_operator" "")
14008 (const_string "fdiv")
14010 (const_string "fop")))
14011 (set_attr "mode" "SF")])
14013 ;; ??? Add SSE splitters for these!
14014 (define_insn "*fop_sf_2<mode>_i387"
14015 [(set (match_operand:SF 0 "register_operand" "=f,f")
14016 (match_operator:SF 3 "binary_fp_operator"
14017 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14018 (match_operand:SF 2 "register_operand" "0,0")]))]
14019 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14020 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14021 [(set (attr "type")
14022 (cond [(match_operand:SF 3 "mult_operator" "")
14023 (const_string "fmul")
14024 (match_operand:SF 3 "div_operator" "")
14025 (const_string "fdiv")
14027 (const_string "fop")))
14028 (set_attr "fp_int_src" "true")
14029 (set_attr "mode" "<MODE>")])
14031 (define_insn "*fop_sf_3<mode>_i387"
14032 [(set (match_operand:SF 0 "register_operand" "=f,f")
14033 (match_operator:SF 3 "binary_fp_operator"
14034 [(match_operand:SF 1 "register_operand" "0,0")
14035 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14036 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14037 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14038 [(set (attr "type")
14039 (cond [(match_operand:SF 3 "mult_operator" "")
14040 (const_string "fmul")
14041 (match_operand:SF 3 "div_operator" "")
14042 (const_string "fdiv")
14044 (const_string "fop")))
14045 (set_attr "fp_int_src" "true")
14046 (set_attr "mode" "<MODE>")])
14048 (define_insn "*fop_df_comm_mixed"
14049 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14050 (match_operator:DF 3 "binary_fp_operator"
14051 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14052 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14053 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14054 && COMMUTATIVE_ARITH_P (operands[3])
14055 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14056 "* return output_387_binary_op (insn, operands);"
14057 [(set (attr "type")
14058 (if_then_else (eq_attr "alternative" "1")
14059 (if_then_else (match_operand:SF 3 "mult_operator" "")
14060 (const_string "ssemul")
14061 (const_string "sseadd"))
14062 (if_then_else (match_operand:SF 3 "mult_operator" "")
14063 (const_string "fmul")
14064 (const_string "fop"))))
14065 (set_attr "mode" "DF")])
14067 (define_insn "*fop_df_comm_sse"
14068 [(set (match_operand:DF 0 "register_operand" "=Y")
14069 (match_operator:DF 3 "binary_fp_operator"
14070 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14071 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14072 "TARGET_SSE2 && TARGET_SSE_MATH
14073 && COMMUTATIVE_ARITH_P (operands[3])
14074 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14075 "* return output_387_binary_op (insn, operands);"
14076 [(set (attr "type")
14077 (if_then_else (match_operand:SF 3 "mult_operator" "")
14078 (const_string "ssemul")
14079 (const_string "sseadd")))
14080 (set_attr "mode" "DF")])
14082 (define_insn "*fop_df_comm_i387"
14083 [(set (match_operand:DF 0 "register_operand" "=f")
14084 (match_operator:DF 3 "binary_fp_operator"
14085 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14086 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14088 && COMMUTATIVE_ARITH_P (operands[3])
14089 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14090 "* return output_387_binary_op (insn, operands);"
14091 [(set (attr "type")
14092 (if_then_else (match_operand:SF 3 "mult_operator" "")
14093 (const_string "fmul")
14094 (const_string "fop")))
14095 (set_attr "mode" "DF")])
14097 (define_insn "*fop_df_1_mixed"
14098 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14099 (match_operator:DF 3 "binary_fp_operator"
14100 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14101 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14102 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14103 && !COMMUTATIVE_ARITH_P (operands[3])
14104 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14105 "* return output_387_binary_op (insn, operands);"
14106 [(set (attr "type")
14107 (cond [(and (eq_attr "alternative" "2")
14108 (match_operand:SF 3 "mult_operator" ""))
14109 (const_string "ssemul")
14110 (and (eq_attr "alternative" "2")
14111 (match_operand:SF 3 "div_operator" ""))
14112 (const_string "ssediv")
14113 (eq_attr "alternative" "2")
14114 (const_string "sseadd")
14115 (match_operand:DF 3 "mult_operator" "")
14116 (const_string "fmul")
14117 (match_operand:DF 3 "div_operator" "")
14118 (const_string "fdiv")
14120 (const_string "fop")))
14121 (set_attr "mode" "DF")])
14123 (define_insn "*fop_df_1_sse"
14124 [(set (match_operand:DF 0 "register_operand" "=Y")
14125 (match_operator:DF 3 "binary_fp_operator"
14126 [(match_operand:DF 1 "register_operand" "0")
14127 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14128 "TARGET_SSE2 && TARGET_SSE_MATH
14129 && !COMMUTATIVE_ARITH_P (operands[3])"
14130 "* return output_387_binary_op (insn, operands);"
14131 [(set_attr "mode" "DF")
14133 (cond [(match_operand:SF 3 "mult_operator" "")
14134 (const_string "ssemul")
14135 (match_operand:SF 3 "div_operator" "")
14136 (const_string "ssediv")
14138 (const_string "sseadd")))])
14140 ;; This pattern is not fully shadowed by the pattern above.
14141 (define_insn "*fop_df_1_i387"
14142 [(set (match_operand:DF 0 "register_operand" "=f,f")
14143 (match_operator:DF 3 "binary_fp_operator"
14144 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14145 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14146 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14147 && !COMMUTATIVE_ARITH_P (operands[3])
14148 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14149 "* return output_387_binary_op (insn, operands);"
14150 [(set (attr "type")
14151 (cond [(match_operand:DF 3 "mult_operator" "")
14152 (const_string "fmul")
14153 (match_operand:DF 3 "div_operator" "")
14154 (const_string "fdiv")
14156 (const_string "fop")))
14157 (set_attr "mode" "DF")])
14159 ;; ??? Add SSE splitters for these!
14160 (define_insn "*fop_df_2<mode>_i387"
14161 [(set (match_operand:DF 0 "register_operand" "=f,f")
14162 (match_operator:DF 3 "binary_fp_operator"
14163 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14164 (match_operand:DF 2 "register_operand" "0,0")]))]
14165 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14166 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14167 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14168 [(set (attr "type")
14169 (cond [(match_operand:DF 3 "mult_operator" "")
14170 (const_string "fmul")
14171 (match_operand:DF 3 "div_operator" "")
14172 (const_string "fdiv")
14174 (const_string "fop")))
14175 (set_attr "fp_int_src" "true")
14176 (set_attr "mode" "<MODE>")])
14178 (define_insn "*fop_df_3<mode>_i387"
14179 [(set (match_operand:DF 0 "register_operand" "=f,f")
14180 (match_operator:DF 3 "binary_fp_operator"
14181 [(match_operand:DF 1 "register_operand" "0,0")
14182 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14183 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14184 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14185 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14186 [(set (attr "type")
14187 (cond [(match_operand:DF 3 "mult_operator" "")
14188 (const_string "fmul")
14189 (match_operand:DF 3 "div_operator" "")
14190 (const_string "fdiv")
14192 (const_string "fop")))
14193 (set_attr "fp_int_src" "true")
14194 (set_attr "mode" "<MODE>")])
14196 (define_insn "*fop_df_4_i387"
14197 [(set (match_operand:DF 0 "register_operand" "=f,f")
14198 (match_operator:DF 3 "binary_fp_operator"
14199 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14200 (match_operand:DF 2 "register_operand" "0,f")]))]
14201 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14202 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14203 "* return output_387_binary_op (insn, operands);"
14204 [(set (attr "type")
14205 (cond [(match_operand:DF 3 "mult_operator" "")
14206 (const_string "fmul")
14207 (match_operand:DF 3 "div_operator" "")
14208 (const_string "fdiv")
14210 (const_string "fop")))
14211 (set_attr "mode" "SF")])
14213 (define_insn "*fop_df_5_i387"
14214 [(set (match_operand:DF 0 "register_operand" "=f,f")
14215 (match_operator:DF 3 "binary_fp_operator"
14216 [(match_operand:DF 1 "register_operand" "0,f")
14218 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14219 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14220 "* return output_387_binary_op (insn, operands);"
14221 [(set (attr "type")
14222 (cond [(match_operand:DF 3 "mult_operator" "")
14223 (const_string "fmul")
14224 (match_operand:DF 3 "div_operator" "")
14225 (const_string "fdiv")
14227 (const_string "fop")))
14228 (set_attr "mode" "SF")])
14230 (define_insn "*fop_df_6_i387"
14231 [(set (match_operand:DF 0 "register_operand" "=f,f")
14232 (match_operator:DF 3 "binary_fp_operator"
14234 (match_operand:SF 1 "register_operand" "0,f"))
14236 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14237 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14238 "* return output_387_binary_op (insn, operands);"
14239 [(set (attr "type")
14240 (cond [(match_operand:DF 3 "mult_operator" "")
14241 (const_string "fmul")
14242 (match_operand:DF 3 "div_operator" "")
14243 (const_string "fdiv")
14245 (const_string "fop")))
14246 (set_attr "mode" "SF")])
14248 (define_insn "*fop_xf_comm_i387"
14249 [(set (match_operand:XF 0 "register_operand" "=f")
14250 (match_operator:XF 3 "binary_fp_operator"
14251 [(match_operand:XF 1 "register_operand" "%0")
14252 (match_operand:XF 2 "register_operand" "f")]))]
14254 && COMMUTATIVE_ARITH_P (operands[3])"
14255 "* return output_387_binary_op (insn, operands);"
14256 [(set (attr "type")
14257 (if_then_else (match_operand:XF 3 "mult_operator" "")
14258 (const_string "fmul")
14259 (const_string "fop")))
14260 (set_attr "mode" "XF")])
14262 (define_insn "*fop_xf_1_i387"
14263 [(set (match_operand:XF 0 "register_operand" "=f,f")
14264 (match_operator:XF 3 "binary_fp_operator"
14265 [(match_operand:XF 1 "register_operand" "0,f")
14266 (match_operand:XF 2 "register_operand" "f,0")]))]
14268 && !COMMUTATIVE_ARITH_P (operands[3])"
14269 "* return output_387_binary_op (insn, operands);"
14270 [(set (attr "type")
14271 (cond [(match_operand:XF 3 "mult_operator" "")
14272 (const_string "fmul")
14273 (match_operand:XF 3 "div_operator" "")
14274 (const_string "fdiv")
14276 (const_string "fop")))
14277 (set_attr "mode" "XF")])
14279 (define_insn "*fop_xf_2<mode>_i387"
14280 [(set (match_operand:XF 0 "register_operand" "=f,f")
14281 (match_operator:XF 3 "binary_fp_operator"
14282 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14283 (match_operand:XF 2 "register_operand" "0,0")]))]
14284 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14285 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14286 [(set (attr "type")
14287 (cond [(match_operand:XF 3 "mult_operator" "")
14288 (const_string "fmul")
14289 (match_operand:XF 3 "div_operator" "")
14290 (const_string "fdiv")
14292 (const_string "fop")))
14293 (set_attr "fp_int_src" "true")
14294 (set_attr "mode" "<MODE>")])
14296 (define_insn "*fop_xf_3<mode>_i387"
14297 [(set (match_operand:XF 0 "register_operand" "=f,f")
14298 (match_operator:XF 3 "binary_fp_operator"
14299 [(match_operand:XF 1 "register_operand" "0,0")
14300 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14301 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14302 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14303 [(set (attr "type")
14304 (cond [(match_operand:XF 3 "mult_operator" "")
14305 (const_string "fmul")
14306 (match_operand:XF 3 "div_operator" "")
14307 (const_string "fdiv")
14309 (const_string "fop")))
14310 (set_attr "fp_int_src" "true")
14311 (set_attr "mode" "<MODE>")])
14313 (define_insn "*fop_xf_4_i387"
14314 [(set (match_operand:XF 0 "register_operand" "=f,f")
14315 (match_operator:XF 3 "binary_fp_operator"
14316 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14317 (match_operand:XF 2 "register_operand" "0,f")]))]
14319 "* return output_387_binary_op (insn, operands);"
14320 [(set (attr "type")
14321 (cond [(match_operand:XF 3 "mult_operator" "")
14322 (const_string "fmul")
14323 (match_operand:XF 3 "div_operator" "")
14324 (const_string "fdiv")
14326 (const_string "fop")))
14327 (set_attr "mode" "SF")])
14329 (define_insn "*fop_xf_5_i387"
14330 [(set (match_operand:XF 0 "register_operand" "=f,f")
14331 (match_operator:XF 3 "binary_fp_operator"
14332 [(match_operand:XF 1 "register_operand" "0,f")
14334 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14336 "* return output_387_binary_op (insn, operands);"
14337 [(set (attr "type")
14338 (cond [(match_operand:XF 3 "mult_operator" "")
14339 (const_string "fmul")
14340 (match_operand:XF 3 "div_operator" "")
14341 (const_string "fdiv")
14343 (const_string "fop")))
14344 (set_attr "mode" "SF")])
14346 (define_insn "*fop_xf_6_i387"
14347 [(set (match_operand:XF 0 "register_operand" "=f,f")
14348 (match_operator:XF 3 "binary_fp_operator"
14350 (match_operand 1 "register_operand" "0,f"))
14352 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14354 "* return output_387_binary_op (insn, operands);"
14355 [(set (attr "type")
14356 (cond [(match_operand:XF 3 "mult_operator" "")
14357 (const_string "fmul")
14358 (match_operand:XF 3 "div_operator" "")
14359 (const_string "fdiv")
14361 (const_string "fop")))
14362 (set_attr "mode" "SF")])
14365 [(set (match_operand 0 "register_operand" "")
14366 (match_operator 3 "binary_fp_operator"
14367 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14368 (match_operand 2 "register_operand" "")]))]
14369 "TARGET_80387 && reload_completed
14370 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14373 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14374 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14375 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14376 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14377 GET_MODE (operands[3]),
14380 ix86_free_from_memory (GET_MODE (operands[1]));
14385 [(set (match_operand 0 "register_operand" "")
14386 (match_operator 3 "binary_fp_operator"
14387 [(match_operand 1 "register_operand" "")
14388 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14389 "TARGET_80387 && reload_completed
14390 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14393 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14394 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14395 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14396 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14397 GET_MODE (operands[3]),
14400 ix86_free_from_memory (GET_MODE (operands[2]));
14404 ;; FPU special functions.
14406 (define_expand "sqrtsf2"
14407 [(set (match_operand:SF 0 "register_operand" "")
14408 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14409 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14411 if (!TARGET_SSE_MATH)
14412 operands[1] = force_reg (SFmode, operands[1]);
14415 (define_insn "*sqrtsf2_mixed"
14416 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14417 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14418 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14421 sqrtss\t{%1, %0|%0, %1}"
14422 [(set_attr "type" "fpspc,sse")
14423 (set_attr "mode" "SF,SF")
14424 (set_attr "athlon_decode" "direct,*")])
14426 (define_insn "*sqrtsf2_sse"
14427 [(set (match_operand:SF 0 "register_operand" "=x")
14428 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14430 "sqrtss\t{%1, %0|%0, %1}"
14431 [(set_attr "type" "sse")
14432 (set_attr "mode" "SF")
14433 (set_attr "athlon_decode" "*")])
14435 (define_insn "*sqrtsf2_i387"
14436 [(set (match_operand:SF 0 "register_operand" "=f")
14437 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14438 "TARGET_USE_FANCY_MATH_387"
14440 [(set_attr "type" "fpspc")
14441 (set_attr "mode" "SF")
14442 (set_attr "athlon_decode" "direct")])
14444 (define_expand "sqrtdf2"
14445 [(set (match_operand:DF 0 "register_operand" "")
14446 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14447 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14449 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14450 operands[1] = force_reg (DFmode, operands[1]);
14453 (define_insn "*sqrtdf2_mixed"
14454 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14455 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14456 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14459 sqrtsd\t{%1, %0|%0, %1}"
14460 [(set_attr "type" "fpspc,sse")
14461 (set_attr "mode" "DF,DF")
14462 (set_attr "athlon_decode" "direct,*")])
14464 (define_insn "*sqrtdf2_sse"
14465 [(set (match_operand:DF 0 "register_operand" "=Y")
14466 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14467 "TARGET_SSE2 && TARGET_SSE_MATH"
14468 "sqrtsd\t{%1, %0|%0, %1}"
14469 [(set_attr "type" "sse")
14470 (set_attr "mode" "DF")
14471 (set_attr "athlon_decode" "*")])
14473 (define_insn "*sqrtdf2_i387"
14474 [(set (match_operand:DF 0 "register_operand" "=f")
14475 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14476 "TARGET_USE_FANCY_MATH_387"
14478 [(set_attr "type" "fpspc")
14479 (set_attr "mode" "DF")
14480 (set_attr "athlon_decode" "direct")])
14482 (define_insn "*sqrtextendsfdf2_i387"
14483 [(set (match_operand:DF 0 "register_operand" "=f")
14484 (sqrt:DF (float_extend:DF
14485 (match_operand:SF 1 "register_operand" "0"))))]
14486 "TARGET_USE_FANCY_MATH_387
14487 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14489 [(set_attr "type" "fpspc")
14490 (set_attr "mode" "DF")
14491 (set_attr "athlon_decode" "direct")])
14493 (define_insn "sqrtxf2"
14494 [(set (match_operand:XF 0 "register_operand" "=f")
14495 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14496 "TARGET_USE_FANCY_MATH_387
14497 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14499 [(set_attr "type" "fpspc")
14500 (set_attr "mode" "XF")
14501 (set_attr "athlon_decode" "direct")])
14503 (define_insn "*sqrtextendsfxf2_i387"
14504 [(set (match_operand:XF 0 "register_operand" "=f")
14505 (sqrt:XF (float_extend:XF
14506 (match_operand:SF 1 "register_operand" "0"))))]
14507 "TARGET_USE_FANCY_MATH_387"
14509 [(set_attr "type" "fpspc")
14510 (set_attr "mode" "XF")
14511 (set_attr "athlon_decode" "direct")])
14513 (define_insn "*sqrtextenddfxf2_i387"
14514 [(set (match_operand:XF 0 "register_operand" "=f")
14515 (sqrt:XF (float_extend:XF
14516 (match_operand:DF 1 "register_operand" "0"))))]
14517 "TARGET_USE_FANCY_MATH_387"
14519 [(set_attr "type" "fpspc")
14520 (set_attr "mode" "XF")
14521 (set_attr "athlon_decode" "direct")])
14523 (define_insn "fpremxf4"
14524 [(set (match_operand:XF 0 "register_operand" "=f")
14525 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14526 (match_operand:XF 3 "register_operand" "1")]
14528 (set (match_operand:XF 1 "register_operand" "=u")
14529 (unspec:XF [(match_dup 2) (match_dup 3)]
14531 (set (reg:CCFP FPSR_REG)
14532 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14533 "TARGET_USE_FANCY_MATH_387
14534 && flag_unsafe_math_optimizations"
14536 [(set_attr "type" "fpspc")
14537 (set_attr "mode" "XF")])
14539 (define_expand "fmodsf3"
14540 [(use (match_operand:SF 0 "register_operand" ""))
14541 (use (match_operand:SF 1 "register_operand" ""))
14542 (use (match_operand:SF 2 "register_operand" ""))]
14543 "TARGET_USE_FANCY_MATH_387
14544 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14545 && flag_unsafe_math_optimizations"
14547 rtx label = gen_label_rtx ();
14549 rtx op1 = gen_reg_rtx (XFmode);
14550 rtx op2 = gen_reg_rtx (XFmode);
14552 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14553 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14555 emit_label (label);
14557 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14558 ix86_emit_fp_unordered_jump (label);
14560 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14564 (define_expand "fmoddf3"
14565 [(use (match_operand:DF 0 "register_operand" ""))
14566 (use (match_operand:DF 1 "register_operand" ""))
14567 (use (match_operand:DF 2 "register_operand" ""))]
14568 "TARGET_USE_FANCY_MATH_387
14569 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14570 && flag_unsafe_math_optimizations"
14572 rtx label = gen_label_rtx ();
14574 rtx op1 = gen_reg_rtx (XFmode);
14575 rtx op2 = gen_reg_rtx (XFmode);
14577 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14578 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14580 emit_label (label);
14582 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14583 ix86_emit_fp_unordered_jump (label);
14585 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14589 (define_expand "fmodxf3"
14590 [(use (match_operand:XF 0 "register_operand" ""))
14591 (use (match_operand:XF 1 "register_operand" ""))
14592 (use (match_operand:XF 2 "register_operand" ""))]
14593 "TARGET_USE_FANCY_MATH_387
14594 && flag_unsafe_math_optimizations"
14596 rtx label = gen_label_rtx ();
14598 emit_label (label);
14600 emit_insn (gen_fpremxf4 (operands[1], operands[2],
14601 operands[1], operands[2]));
14602 ix86_emit_fp_unordered_jump (label);
14604 emit_move_insn (operands[0], operands[1]);
14608 (define_insn "fprem1xf4"
14609 [(set (match_operand:XF 0 "register_operand" "=f")
14610 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14611 (match_operand:XF 3 "register_operand" "1")]
14613 (set (match_operand:XF 1 "register_operand" "=u")
14614 (unspec:XF [(match_dup 2) (match_dup 3)]
14616 (set (reg:CCFP FPSR_REG)
14617 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14618 "TARGET_USE_FANCY_MATH_387
14619 && flag_unsafe_math_optimizations"
14621 [(set_attr "type" "fpspc")
14622 (set_attr "mode" "XF")])
14624 (define_expand "dremsf3"
14625 [(use (match_operand:SF 0 "register_operand" ""))
14626 (use (match_operand:SF 1 "register_operand" ""))
14627 (use (match_operand:SF 2 "register_operand" ""))]
14628 "TARGET_USE_FANCY_MATH_387
14629 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14630 && flag_unsafe_math_optimizations"
14632 rtx label = gen_label_rtx ();
14634 rtx op1 = gen_reg_rtx (XFmode);
14635 rtx op2 = gen_reg_rtx (XFmode);
14637 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14638 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14640 emit_label (label);
14642 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14643 ix86_emit_fp_unordered_jump (label);
14645 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14649 (define_expand "dremdf3"
14650 [(use (match_operand:DF 0 "register_operand" ""))
14651 (use (match_operand:DF 1 "register_operand" ""))
14652 (use (match_operand:DF 2 "register_operand" ""))]
14653 "TARGET_USE_FANCY_MATH_387
14654 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14655 && flag_unsafe_math_optimizations"
14657 rtx label = gen_label_rtx ();
14659 rtx op1 = gen_reg_rtx (XFmode);
14660 rtx op2 = gen_reg_rtx (XFmode);
14662 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14663 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14665 emit_label (label);
14667 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14668 ix86_emit_fp_unordered_jump (label);
14670 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14674 (define_expand "dremxf3"
14675 [(use (match_operand:XF 0 "register_operand" ""))
14676 (use (match_operand:XF 1 "register_operand" ""))
14677 (use (match_operand:XF 2 "register_operand" ""))]
14678 "TARGET_USE_FANCY_MATH_387
14679 && flag_unsafe_math_optimizations"
14681 rtx label = gen_label_rtx ();
14683 emit_label (label);
14685 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14686 operands[1], operands[2]));
14687 ix86_emit_fp_unordered_jump (label);
14689 emit_move_insn (operands[0], operands[1]);
14693 (define_insn "*sindf2"
14694 [(set (match_operand:DF 0 "register_operand" "=f")
14695 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14696 "TARGET_USE_FANCY_MATH_387
14697 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14698 && flag_unsafe_math_optimizations"
14700 [(set_attr "type" "fpspc")
14701 (set_attr "mode" "DF")])
14703 (define_insn "*sinsf2"
14704 [(set (match_operand:SF 0 "register_operand" "=f")
14705 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14706 "TARGET_USE_FANCY_MATH_387
14707 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14708 && flag_unsafe_math_optimizations"
14710 [(set_attr "type" "fpspc")
14711 (set_attr "mode" "SF")])
14713 (define_insn "*sinextendsfdf2"
14714 [(set (match_operand:DF 0 "register_operand" "=f")
14715 (unspec:DF [(float_extend:DF
14716 (match_operand:SF 1 "register_operand" "0"))]
14718 "TARGET_USE_FANCY_MATH_387
14719 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14720 && flag_unsafe_math_optimizations"
14722 [(set_attr "type" "fpspc")
14723 (set_attr "mode" "DF")])
14725 (define_insn "*sinxf2"
14726 [(set (match_operand:XF 0 "register_operand" "=f")
14727 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14728 "TARGET_USE_FANCY_MATH_387
14729 && flag_unsafe_math_optimizations"
14731 [(set_attr "type" "fpspc")
14732 (set_attr "mode" "XF")])
14734 (define_insn "*cosdf2"
14735 [(set (match_operand:DF 0 "register_operand" "=f")
14736 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14737 "TARGET_USE_FANCY_MATH_387
14738 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14739 && flag_unsafe_math_optimizations"
14741 [(set_attr "type" "fpspc")
14742 (set_attr "mode" "DF")])
14744 (define_insn "*cossf2"
14745 [(set (match_operand:SF 0 "register_operand" "=f")
14746 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14747 "TARGET_USE_FANCY_MATH_387
14748 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14749 && flag_unsafe_math_optimizations"
14751 [(set_attr "type" "fpspc")
14752 (set_attr "mode" "SF")])
14754 (define_insn "*cosextendsfdf2"
14755 [(set (match_operand:DF 0 "register_operand" "=f")
14756 (unspec:DF [(float_extend:DF
14757 (match_operand:SF 1 "register_operand" "0"))]
14759 "TARGET_USE_FANCY_MATH_387
14760 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14761 && flag_unsafe_math_optimizations"
14763 [(set_attr "type" "fpspc")
14764 (set_attr "mode" "DF")])
14766 (define_insn "*cosxf2"
14767 [(set (match_operand:XF 0 "register_operand" "=f")
14768 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14769 "TARGET_USE_FANCY_MATH_387
14770 && flag_unsafe_math_optimizations"
14772 [(set_attr "type" "fpspc")
14773 (set_attr "mode" "XF")])
14775 ;; With sincos pattern defined, sin and cos builtin function will be
14776 ;; expanded to sincos pattern with one of its outputs left unused.
14777 ;; Cse pass will detected, if two sincos patterns can be combined,
14778 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14779 ;; depending on the unused output.
14781 (define_insn "sincosdf3"
14782 [(set (match_operand:DF 0 "register_operand" "=f")
14783 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14784 UNSPEC_SINCOS_COS))
14785 (set (match_operand:DF 1 "register_operand" "=u")
14786 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14787 "TARGET_USE_FANCY_MATH_387
14788 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14789 && flag_unsafe_math_optimizations"
14791 [(set_attr "type" "fpspc")
14792 (set_attr "mode" "DF")])
14795 [(set (match_operand:DF 0 "register_operand" "")
14796 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14797 UNSPEC_SINCOS_COS))
14798 (set (match_operand:DF 1 "register_operand" "")
14799 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14800 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14801 && !reload_completed && !reload_in_progress"
14802 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14806 [(set (match_operand:DF 0 "register_operand" "")
14807 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14808 UNSPEC_SINCOS_COS))
14809 (set (match_operand:DF 1 "register_operand" "")
14810 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14811 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14812 && !reload_completed && !reload_in_progress"
14813 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14816 (define_insn "sincossf3"
14817 [(set (match_operand:SF 0 "register_operand" "=f")
14818 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14819 UNSPEC_SINCOS_COS))
14820 (set (match_operand:SF 1 "register_operand" "=u")
14821 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14822 "TARGET_USE_FANCY_MATH_387
14823 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14824 && flag_unsafe_math_optimizations"
14826 [(set_attr "type" "fpspc")
14827 (set_attr "mode" "SF")])
14830 [(set (match_operand:SF 0 "register_operand" "")
14831 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14832 UNSPEC_SINCOS_COS))
14833 (set (match_operand:SF 1 "register_operand" "")
14834 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14835 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14836 && !reload_completed && !reload_in_progress"
14837 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14841 [(set (match_operand:SF 0 "register_operand" "")
14842 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14843 UNSPEC_SINCOS_COS))
14844 (set (match_operand:SF 1 "register_operand" "")
14845 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14846 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14847 && !reload_completed && !reload_in_progress"
14848 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
14851 (define_insn "*sincosextendsfdf3"
14852 [(set (match_operand:DF 0 "register_operand" "=f")
14853 (unspec:DF [(float_extend:DF
14854 (match_operand:SF 2 "register_operand" "0"))]
14855 UNSPEC_SINCOS_COS))
14856 (set (match_operand:DF 1 "register_operand" "=u")
14857 (unspec:DF [(float_extend:DF
14858 (match_dup 2))] UNSPEC_SINCOS_SIN))]
14859 "TARGET_USE_FANCY_MATH_387
14860 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14861 && flag_unsafe_math_optimizations"
14863 [(set_attr "type" "fpspc")
14864 (set_attr "mode" "DF")])
14867 [(set (match_operand:DF 0 "register_operand" "")
14868 (unspec:DF [(float_extend:DF
14869 (match_operand:SF 2 "register_operand" ""))]
14870 UNSPEC_SINCOS_COS))
14871 (set (match_operand:DF 1 "register_operand" "")
14872 (unspec:DF [(float_extend:DF
14873 (match_dup 2))] UNSPEC_SINCOS_SIN))]
14874 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14875 && !reload_completed && !reload_in_progress"
14876 [(set (match_dup 1) (unspec:DF [(float_extend:DF
14877 (match_dup 2))] UNSPEC_SIN))]
14881 [(set (match_operand:DF 0 "register_operand" "")
14882 (unspec:DF [(float_extend:DF
14883 (match_operand:SF 2 "register_operand" ""))]
14884 UNSPEC_SINCOS_COS))
14885 (set (match_operand:DF 1 "register_operand" "")
14886 (unspec:DF [(float_extend:DF
14887 (match_dup 2))] UNSPEC_SINCOS_SIN))]
14888 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14889 && !reload_completed && !reload_in_progress"
14890 [(set (match_dup 0) (unspec:DF [(float_extend:DF
14891 (match_dup 2))] UNSPEC_COS))]
14894 (define_insn "sincosxf3"
14895 [(set (match_operand:XF 0 "register_operand" "=f")
14896 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14897 UNSPEC_SINCOS_COS))
14898 (set (match_operand:XF 1 "register_operand" "=u")
14899 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14900 "TARGET_USE_FANCY_MATH_387
14901 && flag_unsafe_math_optimizations"
14903 [(set_attr "type" "fpspc")
14904 (set_attr "mode" "XF")])
14907 [(set (match_operand:XF 0 "register_operand" "")
14908 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14909 UNSPEC_SINCOS_COS))
14910 (set (match_operand:XF 1 "register_operand" "")
14911 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14912 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14913 && !reload_completed && !reload_in_progress"
14914 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
14918 [(set (match_operand:XF 0 "register_operand" "")
14919 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14920 UNSPEC_SINCOS_COS))
14921 (set (match_operand:XF 1 "register_operand" "")
14922 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14923 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14924 && !reload_completed && !reload_in_progress"
14925 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
14928 (define_insn "*tandf3_1"
14929 [(set (match_operand:DF 0 "register_operand" "=f")
14930 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14932 (set (match_operand:DF 1 "register_operand" "=u")
14933 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
14934 "TARGET_USE_FANCY_MATH_387
14935 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14936 && flag_unsafe_math_optimizations"
14938 [(set_attr "type" "fpspc")
14939 (set_attr "mode" "DF")])
14941 ;; optimize sequence: fptan
14944 ;; into fptan insn.
14947 [(parallel[(set (match_operand:DF 0 "register_operand" "")
14948 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14950 (set (match_operand:DF 1 "register_operand" "")
14951 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
14953 (match_operand:DF 3 "immediate_operand" ""))]
14954 "standard_80387_constant_p (operands[3]) == 2"
14955 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
14956 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
14959 (define_expand "tandf2"
14960 [(parallel [(set (match_dup 2)
14961 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
14963 (set (match_operand:DF 0 "register_operand" "")
14964 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
14965 "TARGET_USE_FANCY_MATH_387
14966 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14967 && flag_unsafe_math_optimizations"
14969 operands[2] = gen_reg_rtx (DFmode);
14972 (define_insn "*tansf3_1"
14973 [(set (match_operand:SF 0 "register_operand" "=f")
14974 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14976 (set (match_operand:SF 1 "register_operand" "=u")
14977 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
14978 "TARGET_USE_FANCY_MATH_387
14979 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14980 && flag_unsafe_math_optimizations"
14982 [(set_attr "type" "fpspc")
14983 (set_attr "mode" "SF")])
14985 ;; optimize sequence: fptan
14988 ;; into fptan insn.
14991 [(parallel[(set (match_operand:SF 0 "register_operand" "")
14992 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14994 (set (match_operand:SF 1 "register_operand" "")
14995 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
14997 (match_operand:SF 3 "immediate_operand" ""))]
14998 "standard_80387_constant_p (operands[3]) == 2"
14999 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15000 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15003 (define_expand "tansf2"
15004 [(parallel [(set (match_dup 2)
15005 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15007 (set (match_operand:SF 0 "register_operand" "")
15008 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15009 "TARGET_USE_FANCY_MATH_387
15010 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15011 && flag_unsafe_math_optimizations"
15013 operands[2] = gen_reg_rtx (SFmode);
15016 (define_insn "*tanxf3_1"
15017 [(set (match_operand:XF 0 "register_operand" "=f")
15018 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15020 (set (match_operand:XF 1 "register_operand" "=u")
15021 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15022 "TARGET_USE_FANCY_MATH_387
15023 && flag_unsafe_math_optimizations"
15025 [(set_attr "type" "fpspc")
15026 (set_attr "mode" "XF")])
15028 ;; optimize sequence: fptan
15031 ;; into fptan insn.
15034 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15035 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15037 (set (match_operand:XF 1 "register_operand" "")
15038 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15040 (match_operand:XF 3 "immediate_operand" ""))]
15041 "standard_80387_constant_p (operands[3]) == 2"
15042 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15043 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15046 (define_expand "tanxf2"
15047 [(parallel [(set (match_dup 2)
15048 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15050 (set (match_operand:XF 0 "register_operand" "")
15051 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15052 "TARGET_USE_FANCY_MATH_387
15053 && flag_unsafe_math_optimizations"
15055 operands[2] = gen_reg_rtx (XFmode);
15058 (define_insn "atan2df3_1"
15059 [(set (match_operand:DF 0 "register_operand" "=f")
15060 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15061 (match_operand:DF 1 "register_operand" "u")]
15063 (clobber (match_scratch:DF 3 "=1"))]
15064 "TARGET_USE_FANCY_MATH_387
15065 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15066 && flag_unsafe_math_optimizations"
15068 [(set_attr "type" "fpspc")
15069 (set_attr "mode" "DF")])
15071 (define_expand "atan2df3"
15072 [(use (match_operand:DF 0 "register_operand" ""))
15073 (use (match_operand:DF 2 "register_operand" ""))
15074 (use (match_operand:DF 1 "register_operand" ""))]
15075 "TARGET_USE_FANCY_MATH_387
15076 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15077 && flag_unsafe_math_optimizations"
15079 rtx copy = gen_reg_rtx (DFmode);
15080 emit_move_insn (copy, operands[1]);
15081 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15085 (define_expand "atandf2"
15086 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15087 (unspec:DF [(match_dup 2)
15088 (match_operand:DF 1 "register_operand" "")]
15090 (clobber (match_scratch:DF 3 ""))])]
15091 "TARGET_USE_FANCY_MATH_387
15092 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15093 && flag_unsafe_math_optimizations"
15095 operands[2] = gen_reg_rtx (DFmode);
15096 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15099 (define_insn "atan2sf3_1"
15100 [(set (match_operand:SF 0 "register_operand" "=f")
15101 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15102 (match_operand:SF 1 "register_operand" "u")]
15104 (clobber (match_scratch:SF 3 "=1"))]
15105 "TARGET_USE_FANCY_MATH_387
15106 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15107 && flag_unsafe_math_optimizations"
15109 [(set_attr "type" "fpspc")
15110 (set_attr "mode" "SF")])
15112 (define_expand "atan2sf3"
15113 [(use (match_operand:SF 0 "register_operand" ""))
15114 (use (match_operand:SF 2 "register_operand" ""))
15115 (use (match_operand:SF 1 "register_operand" ""))]
15116 "TARGET_USE_FANCY_MATH_387
15117 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15118 && flag_unsafe_math_optimizations"
15120 rtx copy = gen_reg_rtx (SFmode);
15121 emit_move_insn (copy, operands[1]);
15122 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15126 (define_expand "atansf2"
15127 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15128 (unspec:SF [(match_dup 2)
15129 (match_operand:SF 1 "register_operand" "")]
15131 (clobber (match_scratch:SF 3 ""))])]
15132 "TARGET_USE_FANCY_MATH_387
15133 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15134 && flag_unsafe_math_optimizations"
15136 operands[2] = gen_reg_rtx (SFmode);
15137 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15140 (define_insn "atan2xf3_1"
15141 [(set (match_operand:XF 0 "register_operand" "=f")
15142 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15143 (match_operand:XF 1 "register_operand" "u")]
15145 (clobber (match_scratch:XF 3 "=1"))]
15146 "TARGET_USE_FANCY_MATH_387
15147 && flag_unsafe_math_optimizations"
15149 [(set_attr "type" "fpspc")
15150 (set_attr "mode" "XF")])
15152 (define_expand "atan2xf3"
15153 [(use (match_operand:XF 0 "register_operand" ""))
15154 (use (match_operand:XF 2 "register_operand" ""))
15155 (use (match_operand:XF 1 "register_operand" ""))]
15156 "TARGET_USE_FANCY_MATH_387
15157 && flag_unsafe_math_optimizations"
15159 rtx copy = gen_reg_rtx (XFmode);
15160 emit_move_insn (copy, operands[1]);
15161 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15165 (define_expand "atanxf2"
15166 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15167 (unspec:XF [(match_dup 2)
15168 (match_operand:XF 1 "register_operand" "")]
15170 (clobber (match_scratch:XF 3 ""))])]
15171 "TARGET_USE_FANCY_MATH_387
15172 && flag_unsafe_math_optimizations"
15174 operands[2] = gen_reg_rtx (XFmode);
15175 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15178 (define_expand "asindf2"
15179 [(set (match_dup 2)
15180 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15181 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15182 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15183 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15184 (parallel [(set (match_dup 7)
15185 (unspec:XF [(match_dup 6) (match_dup 2)]
15187 (clobber (match_scratch:XF 8 ""))])
15188 (set (match_operand:DF 0 "register_operand" "")
15189 (float_truncate:DF (match_dup 7)))]
15190 "TARGET_USE_FANCY_MATH_387
15191 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15192 && flag_unsafe_math_optimizations"
15196 for (i=2; i<8; i++)
15197 operands[i] = gen_reg_rtx (XFmode);
15199 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15202 (define_expand "asinsf2"
15203 [(set (match_dup 2)
15204 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15205 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15206 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15207 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15208 (parallel [(set (match_dup 7)
15209 (unspec:XF [(match_dup 6) (match_dup 2)]
15211 (clobber (match_scratch:XF 8 ""))])
15212 (set (match_operand:SF 0 "register_operand" "")
15213 (float_truncate:SF (match_dup 7)))]
15214 "TARGET_USE_FANCY_MATH_387
15215 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15216 && flag_unsafe_math_optimizations"
15220 for (i=2; i<8; i++)
15221 operands[i] = gen_reg_rtx (XFmode);
15223 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15226 (define_expand "asinxf2"
15227 [(set (match_dup 2)
15228 (mult:XF (match_operand:XF 1 "register_operand" "")
15230 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15231 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15232 (parallel [(set (match_operand:XF 0 "register_operand" "")
15233 (unspec:XF [(match_dup 5) (match_dup 1)]
15235 (clobber (match_scratch:XF 6 ""))])]
15236 "TARGET_USE_FANCY_MATH_387
15237 && flag_unsafe_math_optimizations"
15241 for (i=2; i<6; i++)
15242 operands[i] = gen_reg_rtx (XFmode);
15244 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15247 (define_expand "acosdf2"
15248 [(set (match_dup 2)
15249 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15250 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15251 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15252 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15253 (parallel [(set (match_dup 7)
15254 (unspec:XF [(match_dup 2) (match_dup 6)]
15256 (clobber (match_scratch:XF 8 ""))])
15257 (set (match_operand:DF 0 "register_operand" "")
15258 (float_truncate:DF (match_dup 7)))]
15259 "TARGET_USE_FANCY_MATH_387
15260 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15261 && flag_unsafe_math_optimizations"
15265 for (i=2; i<8; i++)
15266 operands[i] = gen_reg_rtx (XFmode);
15268 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15271 (define_expand "acossf2"
15272 [(set (match_dup 2)
15273 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15274 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15275 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15276 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15277 (parallel [(set (match_dup 7)
15278 (unspec:XF [(match_dup 2) (match_dup 6)]
15280 (clobber (match_scratch:XF 8 ""))])
15281 (set (match_operand:SF 0 "register_operand" "")
15282 (float_truncate:SF (match_dup 7)))]
15283 "TARGET_USE_FANCY_MATH_387
15284 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15285 && flag_unsafe_math_optimizations"
15289 for (i=2; i<8; i++)
15290 operands[i] = gen_reg_rtx (XFmode);
15292 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15295 (define_expand "acosxf2"
15296 [(set (match_dup 2)
15297 (mult:XF (match_operand:XF 1 "register_operand" "")
15299 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15300 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15301 (parallel [(set (match_operand:XF 0 "register_operand" "")
15302 (unspec:XF [(match_dup 1) (match_dup 5)]
15304 (clobber (match_scratch:XF 6 ""))])]
15305 "TARGET_USE_FANCY_MATH_387
15306 && flag_unsafe_math_optimizations"
15310 for (i=2; i<6; i++)
15311 operands[i] = gen_reg_rtx (XFmode);
15313 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15316 (define_insn "fyl2x_xf3"
15317 [(set (match_operand:XF 0 "register_operand" "=f")
15318 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15319 (match_operand:XF 1 "register_operand" "u")]
15321 (clobber (match_scratch:XF 3 "=1"))]
15322 "TARGET_USE_FANCY_MATH_387
15323 && flag_unsafe_math_optimizations"
15325 [(set_attr "type" "fpspc")
15326 (set_attr "mode" "XF")])
15328 (define_expand "logsf2"
15329 [(set (match_dup 2)
15330 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15331 (parallel [(set (match_dup 4)
15332 (unspec:XF [(match_dup 2)
15333 (match_dup 3)] UNSPEC_FYL2X))
15334 (clobber (match_scratch:XF 5 ""))])
15335 (set (match_operand:SF 0 "register_operand" "")
15336 (float_truncate:SF (match_dup 4)))]
15337 "TARGET_USE_FANCY_MATH_387
15338 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15339 && flag_unsafe_math_optimizations"
15343 operands[2] = gen_reg_rtx (XFmode);
15344 operands[3] = gen_reg_rtx (XFmode);
15345 operands[4] = gen_reg_rtx (XFmode);
15347 temp = standard_80387_constant_rtx (4); /* fldln2 */
15348 emit_move_insn (operands[3], temp);
15351 (define_expand "logdf2"
15352 [(set (match_dup 2)
15353 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15354 (parallel [(set (match_dup 4)
15355 (unspec:XF [(match_dup 2)
15356 (match_dup 3)] UNSPEC_FYL2X))
15357 (clobber (match_scratch:XF 5 ""))])
15358 (set (match_operand:DF 0 "register_operand" "")
15359 (float_truncate:DF (match_dup 4)))]
15360 "TARGET_USE_FANCY_MATH_387
15361 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15362 && flag_unsafe_math_optimizations"
15366 operands[2] = gen_reg_rtx (XFmode);
15367 operands[3] = gen_reg_rtx (XFmode);
15368 operands[4] = gen_reg_rtx (XFmode);
15370 temp = standard_80387_constant_rtx (4); /* fldln2 */
15371 emit_move_insn (operands[3], temp);
15374 (define_expand "logxf2"
15375 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15376 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15377 (match_dup 2)] UNSPEC_FYL2X))
15378 (clobber (match_scratch:XF 3 ""))])]
15379 "TARGET_USE_FANCY_MATH_387
15380 && flag_unsafe_math_optimizations"
15384 operands[2] = gen_reg_rtx (XFmode);
15385 temp = standard_80387_constant_rtx (4); /* fldln2 */
15386 emit_move_insn (operands[2], temp);
15389 (define_expand "log10sf2"
15390 [(set (match_dup 2)
15391 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15392 (parallel [(set (match_dup 4)
15393 (unspec:XF [(match_dup 2)
15394 (match_dup 3)] UNSPEC_FYL2X))
15395 (clobber (match_scratch:XF 5 ""))])
15396 (set (match_operand:SF 0 "register_operand" "")
15397 (float_truncate:SF (match_dup 4)))]
15398 "TARGET_USE_FANCY_MATH_387
15399 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15400 && flag_unsafe_math_optimizations"
15404 operands[2] = gen_reg_rtx (XFmode);
15405 operands[3] = gen_reg_rtx (XFmode);
15406 operands[4] = gen_reg_rtx (XFmode);
15408 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15409 emit_move_insn (operands[3], temp);
15412 (define_expand "log10df2"
15413 [(set (match_dup 2)
15414 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15415 (parallel [(set (match_dup 4)
15416 (unspec:XF [(match_dup 2)
15417 (match_dup 3)] UNSPEC_FYL2X))
15418 (clobber (match_scratch:XF 5 ""))])
15419 (set (match_operand:DF 0 "register_operand" "")
15420 (float_truncate:DF (match_dup 4)))]
15421 "TARGET_USE_FANCY_MATH_387
15422 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15423 && flag_unsafe_math_optimizations"
15427 operands[2] = gen_reg_rtx (XFmode);
15428 operands[3] = gen_reg_rtx (XFmode);
15429 operands[4] = gen_reg_rtx (XFmode);
15431 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15432 emit_move_insn (operands[3], temp);
15435 (define_expand "log10xf2"
15436 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15437 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15438 (match_dup 2)] UNSPEC_FYL2X))
15439 (clobber (match_scratch:XF 3 ""))])]
15440 "TARGET_USE_FANCY_MATH_387
15441 && flag_unsafe_math_optimizations"
15445 operands[2] = gen_reg_rtx (XFmode);
15446 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15447 emit_move_insn (operands[2], temp);
15450 (define_expand "log2sf2"
15451 [(set (match_dup 2)
15452 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15453 (parallel [(set (match_dup 4)
15454 (unspec:XF [(match_dup 2)
15455 (match_dup 3)] UNSPEC_FYL2X))
15456 (clobber (match_scratch:XF 5 ""))])
15457 (set (match_operand:SF 0 "register_operand" "")
15458 (float_truncate:SF (match_dup 4)))]
15459 "TARGET_USE_FANCY_MATH_387
15460 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15461 && flag_unsafe_math_optimizations"
15463 operands[2] = gen_reg_rtx (XFmode);
15464 operands[3] = gen_reg_rtx (XFmode);
15465 operands[4] = gen_reg_rtx (XFmode);
15467 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15470 (define_expand "log2df2"
15471 [(set (match_dup 2)
15472 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15473 (parallel [(set (match_dup 4)
15474 (unspec:XF [(match_dup 2)
15475 (match_dup 3)] UNSPEC_FYL2X))
15476 (clobber (match_scratch:XF 5 ""))])
15477 (set (match_operand:DF 0 "register_operand" "")
15478 (float_truncate:DF (match_dup 4)))]
15479 "TARGET_USE_FANCY_MATH_387
15480 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15481 && flag_unsafe_math_optimizations"
15483 operands[2] = gen_reg_rtx (XFmode);
15484 operands[3] = gen_reg_rtx (XFmode);
15485 operands[4] = gen_reg_rtx (XFmode);
15487 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15490 (define_expand "log2xf2"
15491 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15492 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15493 (match_dup 2)] UNSPEC_FYL2X))
15494 (clobber (match_scratch:XF 3 ""))])]
15495 "TARGET_USE_FANCY_MATH_387
15496 && flag_unsafe_math_optimizations"
15498 operands[2] = gen_reg_rtx (XFmode);
15499 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15502 (define_insn "fyl2xp1_xf3"
15503 [(set (match_operand:XF 0 "register_operand" "=f")
15504 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15505 (match_operand:XF 1 "register_operand" "u")]
15507 (clobber (match_scratch:XF 3 "=1"))]
15508 "TARGET_USE_FANCY_MATH_387
15509 && flag_unsafe_math_optimizations"
15511 [(set_attr "type" "fpspc")
15512 (set_attr "mode" "XF")])
15514 (define_expand "log1psf2"
15515 [(use (match_operand:SF 0 "register_operand" ""))
15516 (use (match_operand:SF 1 "register_operand" ""))]
15517 "TARGET_USE_FANCY_MATH_387
15518 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15519 && flag_unsafe_math_optimizations"
15521 rtx op0 = gen_reg_rtx (XFmode);
15522 rtx op1 = gen_reg_rtx (XFmode);
15524 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15525 ix86_emit_i387_log1p (op0, op1);
15526 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15530 (define_expand "log1pdf2"
15531 [(use (match_operand:DF 0 "register_operand" ""))
15532 (use (match_operand:DF 1 "register_operand" ""))]
15533 "TARGET_USE_FANCY_MATH_387
15534 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15535 && flag_unsafe_math_optimizations"
15537 rtx op0 = gen_reg_rtx (XFmode);
15538 rtx op1 = gen_reg_rtx (XFmode);
15540 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15541 ix86_emit_i387_log1p (op0, op1);
15542 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15546 (define_expand "log1pxf2"
15547 [(use (match_operand:XF 0 "register_operand" ""))
15548 (use (match_operand:XF 1 "register_operand" ""))]
15549 "TARGET_USE_FANCY_MATH_387
15550 && flag_unsafe_math_optimizations"
15552 ix86_emit_i387_log1p (operands[0], operands[1]);
15556 (define_insn "*fxtractxf3"
15557 [(set (match_operand:XF 0 "register_operand" "=f")
15558 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15559 UNSPEC_XTRACT_FRACT))
15560 (set (match_operand:XF 1 "register_operand" "=u")
15561 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15562 "TARGET_USE_FANCY_MATH_387
15563 && flag_unsafe_math_optimizations"
15565 [(set_attr "type" "fpspc")
15566 (set_attr "mode" "XF")])
15568 (define_expand "logbsf2"
15569 [(set (match_dup 2)
15570 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15571 (parallel [(set (match_dup 3)
15572 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15574 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15575 (set (match_operand:SF 0 "register_operand" "")
15576 (float_truncate:SF (match_dup 4)))]
15577 "TARGET_USE_FANCY_MATH_387
15578 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15579 && flag_unsafe_math_optimizations"
15581 operands[2] = gen_reg_rtx (XFmode);
15582 operands[3] = gen_reg_rtx (XFmode);
15583 operands[4] = gen_reg_rtx (XFmode);
15586 (define_expand "logbdf2"
15587 [(set (match_dup 2)
15588 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15589 (parallel [(set (match_dup 3)
15590 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15592 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15593 (set (match_operand:DF 0 "register_operand" "")
15594 (float_truncate:DF (match_dup 4)))]
15595 "TARGET_USE_FANCY_MATH_387
15596 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15597 && flag_unsafe_math_optimizations"
15599 operands[2] = gen_reg_rtx (XFmode);
15600 operands[3] = gen_reg_rtx (XFmode);
15601 operands[4] = gen_reg_rtx (XFmode);
15604 (define_expand "logbxf2"
15605 [(parallel [(set (match_dup 2)
15606 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15607 UNSPEC_XTRACT_FRACT))
15608 (set (match_operand:XF 0 "register_operand" "")
15609 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15610 "TARGET_USE_FANCY_MATH_387
15611 && flag_unsafe_math_optimizations"
15613 operands[2] = gen_reg_rtx (XFmode);
15616 (define_expand "ilogbsi2"
15617 [(parallel [(set (match_dup 2)
15618 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15619 UNSPEC_XTRACT_FRACT))
15620 (set (match_operand:XF 3 "register_operand" "")
15621 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15622 (parallel [(set (match_operand:SI 0 "register_operand" "")
15623 (fix:SI (match_dup 3)))
15624 (clobber (reg:CC FLAGS_REG))])]
15625 "TARGET_USE_FANCY_MATH_387
15626 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15627 && flag_unsafe_math_optimizations"
15629 operands[2] = gen_reg_rtx (XFmode);
15630 operands[3] = gen_reg_rtx (XFmode);
15633 (define_insn "*f2xm1xf2"
15634 [(set (match_operand:XF 0 "register_operand" "=f")
15635 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15637 "TARGET_USE_FANCY_MATH_387
15638 && flag_unsafe_math_optimizations"
15640 [(set_attr "type" "fpspc")
15641 (set_attr "mode" "XF")])
15643 (define_insn "*fscalexf4"
15644 [(set (match_operand:XF 0 "register_operand" "=f")
15645 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15646 (match_operand:XF 3 "register_operand" "1")]
15647 UNSPEC_FSCALE_FRACT))
15648 (set (match_operand:XF 1 "register_operand" "=u")
15649 (unspec:XF [(match_dup 2) (match_dup 3)]
15650 UNSPEC_FSCALE_EXP))]
15651 "TARGET_USE_FANCY_MATH_387
15652 && flag_unsafe_math_optimizations"
15654 [(set_attr "type" "fpspc")
15655 (set_attr "mode" "XF")])
15657 (define_expand "expsf2"
15658 [(set (match_dup 2)
15659 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15660 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15661 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15662 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15663 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15664 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15665 (parallel [(set (match_dup 10)
15666 (unspec:XF [(match_dup 9) (match_dup 5)]
15667 UNSPEC_FSCALE_FRACT))
15668 (set (match_dup 11)
15669 (unspec:XF [(match_dup 9) (match_dup 5)]
15670 UNSPEC_FSCALE_EXP))])
15671 (set (match_operand:SF 0 "register_operand" "")
15672 (float_truncate:SF (match_dup 10)))]
15673 "TARGET_USE_FANCY_MATH_387
15674 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15675 && flag_unsafe_math_optimizations"
15680 for (i=2; i<12; i++)
15681 operands[i] = gen_reg_rtx (XFmode);
15682 temp = standard_80387_constant_rtx (5); /* fldl2e */
15683 emit_move_insn (operands[3], temp);
15684 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15687 (define_expand "expdf2"
15688 [(set (match_dup 2)
15689 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15690 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15691 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15692 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15693 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15694 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15695 (parallel [(set (match_dup 10)
15696 (unspec:XF [(match_dup 9) (match_dup 5)]
15697 UNSPEC_FSCALE_FRACT))
15698 (set (match_dup 11)
15699 (unspec:XF [(match_dup 9) (match_dup 5)]
15700 UNSPEC_FSCALE_EXP))])
15701 (set (match_operand:DF 0 "register_operand" "")
15702 (float_truncate:DF (match_dup 10)))]
15703 "TARGET_USE_FANCY_MATH_387
15704 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15705 && flag_unsafe_math_optimizations"
15710 for (i=2; i<12; i++)
15711 operands[i] = gen_reg_rtx (XFmode);
15712 temp = standard_80387_constant_rtx (5); /* fldl2e */
15713 emit_move_insn (operands[3], temp);
15714 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15717 (define_expand "expxf2"
15718 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15720 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15721 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15722 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15723 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15724 (parallel [(set (match_operand:XF 0 "register_operand" "")
15725 (unspec:XF [(match_dup 8) (match_dup 4)]
15726 UNSPEC_FSCALE_FRACT))
15728 (unspec:XF [(match_dup 8) (match_dup 4)]
15729 UNSPEC_FSCALE_EXP))])]
15730 "TARGET_USE_FANCY_MATH_387
15731 && flag_unsafe_math_optimizations"
15736 for (i=2; i<10; i++)
15737 operands[i] = gen_reg_rtx (XFmode);
15738 temp = standard_80387_constant_rtx (5); /* fldl2e */
15739 emit_move_insn (operands[2], temp);
15740 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15743 (define_expand "exp10sf2"
15744 [(set (match_dup 2)
15745 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15746 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15747 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15748 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15749 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15750 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15751 (parallel [(set (match_dup 10)
15752 (unspec:XF [(match_dup 9) (match_dup 5)]
15753 UNSPEC_FSCALE_FRACT))
15754 (set (match_dup 11)
15755 (unspec:XF [(match_dup 9) (match_dup 5)]
15756 UNSPEC_FSCALE_EXP))])
15757 (set (match_operand:SF 0 "register_operand" "")
15758 (float_truncate:SF (match_dup 10)))]
15759 "TARGET_USE_FANCY_MATH_387
15760 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15761 && flag_unsafe_math_optimizations"
15766 for (i=2; i<12; i++)
15767 operands[i] = gen_reg_rtx (XFmode);
15768 temp = standard_80387_constant_rtx (6); /* fldl2t */
15769 emit_move_insn (operands[3], temp);
15770 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15773 (define_expand "exp10df2"
15774 [(set (match_dup 2)
15775 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15776 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15777 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15778 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15779 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15780 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15781 (parallel [(set (match_dup 10)
15782 (unspec:XF [(match_dup 9) (match_dup 5)]
15783 UNSPEC_FSCALE_FRACT))
15784 (set (match_dup 11)
15785 (unspec:XF [(match_dup 9) (match_dup 5)]
15786 UNSPEC_FSCALE_EXP))])
15787 (set (match_operand:DF 0 "register_operand" "")
15788 (float_truncate:DF (match_dup 10)))]
15789 "TARGET_USE_FANCY_MATH_387
15790 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15791 && flag_unsafe_math_optimizations"
15796 for (i=2; i<12; i++)
15797 operands[i] = gen_reg_rtx (XFmode);
15798 temp = standard_80387_constant_rtx (6); /* fldl2t */
15799 emit_move_insn (operands[3], temp);
15800 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15803 (define_expand "exp10xf2"
15804 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15806 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15807 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15808 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15809 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15810 (parallel [(set (match_operand:XF 0 "register_operand" "")
15811 (unspec:XF [(match_dup 8) (match_dup 4)]
15812 UNSPEC_FSCALE_FRACT))
15814 (unspec:XF [(match_dup 8) (match_dup 4)]
15815 UNSPEC_FSCALE_EXP))])]
15816 "TARGET_USE_FANCY_MATH_387
15817 && flag_unsafe_math_optimizations"
15822 for (i=2; i<10; i++)
15823 operands[i] = gen_reg_rtx (XFmode);
15824 temp = standard_80387_constant_rtx (6); /* fldl2t */
15825 emit_move_insn (operands[2], temp);
15826 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15829 (define_expand "exp2sf2"
15830 [(set (match_dup 2)
15831 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15832 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15833 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15834 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15835 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15836 (parallel [(set (match_dup 8)
15837 (unspec:XF [(match_dup 7) (match_dup 3)]
15838 UNSPEC_FSCALE_FRACT))
15840 (unspec:XF [(match_dup 7) (match_dup 3)]
15841 UNSPEC_FSCALE_EXP))])
15842 (set (match_operand:SF 0 "register_operand" "")
15843 (float_truncate:SF (match_dup 8)))]
15844 "TARGET_USE_FANCY_MATH_387
15845 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15846 && flag_unsafe_math_optimizations"
15850 for (i=2; i<10; i++)
15851 operands[i] = gen_reg_rtx (XFmode);
15852 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15855 (define_expand "exp2df2"
15856 [(set (match_dup 2)
15857 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15858 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15859 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15860 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15861 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15862 (parallel [(set (match_dup 8)
15863 (unspec:XF [(match_dup 7) (match_dup 3)]
15864 UNSPEC_FSCALE_FRACT))
15866 (unspec:XF [(match_dup 7) (match_dup 3)]
15867 UNSPEC_FSCALE_EXP))])
15868 (set (match_operand:DF 0 "register_operand" "")
15869 (float_truncate:DF (match_dup 8)))]
15870 "TARGET_USE_FANCY_MATH_387
15871 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15872 && flag_unsafe_math_optimizations"
15876 for (i=2; i<10; i++)
15877 operands[i] = gen_reg_rtx (XFmode);
15878 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15881 (define_expand "exp2xf2"
15882 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
15883 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15884 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15885 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15886 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15887 (parallel [(set (match_operand:XF 0 "register_operand" "")
15888 (unspec:XF [(match_dup 7) (match_dup 3)]
15889 UNSPEC_FSCALE_FRACT))
15891 (unspec:XF [(match_dup 7) (match_dup 3)]
15892 UNSPEC_FSCALE_EXP))])]
15893 "TARGET_USE_FANCY_MATH_387
15894 && flag_unsafe_math_optimizations"
15898 for (i=2; i<9; i++)
15899 operands[i] = gen_reg_rtx (XFmode);
15900 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15903 (define_expand "expm1df2"
15904 [(set (match_dup 2)
15905 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15906 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15907 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15908 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15909 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15910 (parallel [(set (match_dup 8)
15911 (unspec:XF [(match_dup 7) (match_dup 5)]
15912 UNSPEC_FSCALE_FRACT))
15914 (unspec:XF [(match_dup 7) (match_dup 5)]
15915 UNSPEC_FSCALE_EXP))])
15916 (parallel [(set (match_dup 11)
15917 (unspec:XF [(match_dup 10) (match_dup 9)]
15918 UNSPEC_FSCALE_FRACT))
15919 (set (match_dup 12)
15920 (unspec:XF [(match_dup 10) (match_dup 9)]
15921 UNSPEC_FSCALE_EXP))])
15922 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
15923 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
15924 (set (match_operand:DF 0 "register_operand" "")
15925 (float_truncate:DF (match_dup 14)))]
15926 "TARGET_USE_FANCY_MATH_387
15927 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15928 && flag_unsafe_math_optimizations"
15933 for (i=2; i<15; i++)
15934 operands[i] = gen_reg_rtx (XFmode);
15935 temp = standard_80387_constant_rtx (5); /* fldl2e */
15936 emit_move_insn (operands[3], temp);
15937 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
15940 (define_expand "expm1sf2"
15941 [(set (match_dup 2)
15942 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15943 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15944 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15945 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15946 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15947 (parallel [(set (match_dup 8)
15948 (unspec:XF [(match_dup 7) (match_dup 5)]
15949 UNSPEC_FSCALE_FRACT))
15951 (unspec:XF [(match_dup 7) (match_dup 5)]
15952 UNSPEC_FSCALE_EXP))])
15953 (parallel [(set (match_dup 11)
15954 (unspec:XF [(match_dup 10) (match_dup 9)]
15955 UNSPEC_FSCALE_FRACT))
15956 (set (match_dup 12)
15957 (unspec:XF [(match_dup 10) (match_dup 9)]
15958 UNSPEC_FSCALE_EXP))])
15959 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
15960 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
15961 (set (match_operand:SF 0 "register_operand" "")
15962 (float_truncate:SF (match_dup 14)))]
15963 "TARGET_USE_FANCY_MATH_387
15964 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15965 && flag_unsafe_math_optimizations"
15970 for (i=2; i<15; i++)
15971 operands[i] = gen_reg_rtx (XFmode);
15972 temp = standard_80387_constant_rtx (5); /* fldl2e */
15973 emit_move_insn (operands[3], temp);
15974 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
15977 (define_expand "expm1xf2"
15978 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15980 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15981 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15982 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15983 (parallel [(set (match_dup 7)
15984 (unspec:XF [(match_dup 6) (match_dup 4)]
15985 UNSPEC_FSCALE_FRACT))
15987 (unspec:XF [(match_dup 6) (match_dup 4)]
15988 UNSPEC_FSCALE_EXP))])
15989 (parallel [(set (match_dup 10)
15990 (unspec:XF [(match_dup 9) (match_dup 8)]
15991 UNSPEC_FSCALE_FRACT))
15992 (set (match_dup 11)
15993 (unspec:XF [(match_dup 9) (match_dup 8)]
15994 UNSPEC_FSCALE_EXP))])
15995 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
15996 (set (match_operand:XF 0 "register_operand" "")
15997 (plus:XF (match_dup 12) (match_dup 7)))]
15998 "TARGET_USE_FANCY_MATH_387
15999 && flag_unsafe_math_optimizations"
16004 for (i=2; i<13; i++)
16005 operands[i] = gen_reg_rtx (XFmode);
16006 temp = standard_80387_constant_rtx (5); /* fldl2e */
16007 emit_move_insn (operands[2], temp);
16008 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16011 (define_expand "ldexpdf3"
16012 [(set (match_dup 3)
16013 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16015 (float:XF (match_operand:SI 2 "register_operand" "")))
16016 (parallel [(set (match_dup 5)
16017 (unspec:XF [(match_dup 3) (match_dup 4)]
16018 UNSPEC_FSCALE_FRACT))
16020 (unspec:XF [(match_dup 3) (match_dup 4)]
16021 UNSPEC_FSCALE_EXP))])
16022 (set (match_operand:DF 0 "register_operand" "")
16023 (float_truncate:DF (match_dup 5)))]
16024 "TARGET_USE_FANCY_MATH_387
16025 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16026 && flag_unsafe_math_optimizations"
16030 for (i=3; i<7; i++)
16031 operands[i] = gen_reg_rtx (XFmode);
16034 (define_expand "ldexpsf3"
16035 [(set (match_dup 3)
16036 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16038 (float:XF (match_operand:SI 2 "register_operand" "")))
16039 (parallel [(set (match_dup 5)
16040 (unspec:XF [(match_dup 3) (match_dup 4)]
16041 UNSPEC_FSCALE_FRACT))
16043 (unspec:XF [(match_dup 3) (match_dup 4)]
16044 UNSPEC_FSCALE_EXP))])
16045 (set (match_operand:SF 0 "register_operand" "")
16046 (float_truncate:SF (match_dup 5)))]
16047 "TARGET_USE_FANCY_MATH_387
16048 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16049 && flag_unsafe_math_optimizations"
16053 for (i=3; i<7; i++)
16054 operands[i] = gen_reg_rtx (XFmode);
16057 (define_expand "ldexpxf3"
16058 [(set (match_dup 3)
16059 (float:XF (match_operand:SI 2 "register_operand" "")))
16060 (parallel [(set (match_operand:XF 0 " register_operand" "")
16061 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16063 UNSPEC_FSCALE_FRACT))
16065 (unspec:XF [(match_dup 1) (match_dup 3)]
16066 UNSPEC_FSCALE_EXP))])]
16067 "TARGET_USE_FANCY_MATH_387
16068 && flag_unsafe_math_optimizations"
16072 for (i=3; i<5; i++)
16073 operands[i] = gen_reg_rtx (XFmode);
16077 (define_insn "frndintxf2"
16078 [(set (match_operand:XF 0 "register_operand" "=f")
16079 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16081 "TARGET_USE_FANCY_MATH_387
16082 && flag_unsafe_math_optimizations"
16084 [(set_attr "type" "fpspc")
16085 (set_attr "mode" "XF")])
16087 (define_expand "rintdf2"
16088 [(use (match_operand:DF 0 "register_operand" ""))
16089 (use (match_operand:DF 1 "register_operand" ""))]
16090 "TARGET_USE_FANCY_MATH_387
16091 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16092 && flag_unsafe_math_optimizations"
16094 rtx op0 = gen_reg_rtx (XFmode);
16095 rtx op1 = gen_reg_rtx (XFmode);
16097 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16098 emit_insn (gen_frndintxf2 (op0, op1));
16100 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16104 (define_expand "rintsf2"
16105 [(use (match_operand:SF 0 "register_operand" ""))
16106 (use (match_operand:SF 1 "register_operand" ""))]
16107 "TARGET_USE_FANCY_MATH_387
16108 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16109 && flag_unsafe_math_optimizations"
16111 rtx op0 = gen_reg_rtx (XFmode);
16112 rtx op1 = gen_reg_rtx (XFmode);
16114 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16115 emit_insn (gen_frndintxf2 (op0, op1));
16117 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16121 (define_expand "rintxf2"
16122 [(use (match_operand:XF 0 "register_operand" ""))
16123 (use (match_operand:XF 1 "register_operand" ""))]
16124 "TARGET_USE_FANCY_MATH_387
16125 && flag_unsafe_math_optimizations"
16127 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16131 (define_insn "fistdi2"
16132 [(set (match_operand:DI 0 "memory_operand" "=m")
16133 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16135 (clobber (match_scratch:XF 2 "=&1f"))]
16136 "TARGET_USE_FANCY_MATH_387
16137 && flag_unsafe_math_optimizations"
16138 "* return output_fix_trunc (insn, operands, 0);"
16139 [(set_attr "type" "fpspc")
16140 (set_attr "mode" "DI")])
16142 (define_insn "fistdi2_with_temp"
16143 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16144 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16146 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16147 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16148 "TARGET_USE_FANCY_MATH_387
16149 && flag_unsafe_math_optimizations"
16151 [(set_attr "type" "fpspc")
16152 (set_attr "mode" "DI")])
16155 [(set (match_operand:DI 0 "register_operand" "")
16156 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16158 (clobber (match_operand:DI 2 "memory_operand" ""))
16159 (clobber (match_scratch 3 ""))]
16161 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16162 (clobber (match_dup 3))])
16163 (set (match_dup 0) (match_dup 2))]
16167 [(set (match_operand:DI 0 "memory_operand" "")
16168 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16170 (clobber (match_operand:DI 2 "memory_operand" ""))
16171 (clobber (match_scratch 3 ""))]
16173 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16174 (clobber (match_dup 3))])]
16177 (define_insn "fist<mode>2"
16178 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16179 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16181 "TARGET_USE_FANCY_MATH_387
16182 && flag_unsafe_math_optimizations"
16183 "* return output_fix_trunc (insn, operands, 0);"
16184 [(set_attr "type" "fpspc")
16185 (set_attr "mode" "<MODE>")])
16187 (define_insn "fist<mode>2_with_temp"
16188 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16189 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16191 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
16192 "TARGET_USE_FANCY_MATH_387
16193 && flag_unsafe_math_optimizations"
16195 [(set_attr "type" "fpspc")
16196 (set_attr "mode" "<MODE>")])
16199 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16200 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16202 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16204 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16206 (set (match_dup 0) (match_dup 2))]
16210 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16211 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16213 (clobber (match_scratch 2 ""))]
16215 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16219 (define_expand "lrint<mode>2"
16220 [(use (match_operand:X87MODEI 0 "nonimmediate_operand" ""))
16221 (use (match_operand:XF 1 "register_operand" ""))]
16222 "TARGET_USE_FANCY_MATH_387
16223 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16224 && flag_unsafe_math_optimizations"
16226 if (memory_operand (operands[0], VOIDmode))
16227 emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
16230 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16231 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16237 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16238 (define_insn_and_split "frndintxf2_floor"
16239 [(set (match_operand:XF 0 "register_operand" "=f")
16240 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16241 UNSPEC_FRNDINT_FLOOR))
16242 (clobber (reg:CC FLAGS_REG))]
16243 "TARGET_USE_FANCY_MATH_387
16244 && flag_unsafe_math_optimizations
16245 && !(reload_completed || reload_in_progress)"
16250 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16252 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16253 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16255 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16256 operands[2], operands[3]));
16259 [(set_attr "type" "frndint")
16260 (set_attr "i387_cw" "floor")
16261 (set_attr "mode" "XF")])
16263 (define_insn "frndintxf2_floor_i387"
16264 [(set (match_operand:XF 0 "register_operand" "=f")
16265 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16266 UNSPEC_FRNDINT_FLOOR))
16267 (use (match_operand:HI 2 "memory_operand" "m"))
16268 (use (match_operand:HI 3 "memory_operand" "m"))]
16269 "TARGET_USE_FANCY_MATH_387
16270 && flag_unsafe_math_optimizations"
16271 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16272 [(set_attr "type" "frndint")
16273 (set_attr "i387_cw" "floor")
16274 (set_attr "mode" "XF")])
16276 (define_expand "floorxf2"
16277 [(use (match_operand:XF 0 "register_operand" ""))
16278 (use (match_operand:XF 1 "register_operand" ""))]
16279 "TARGET_USE_FANCY_MATH_387
16280 && flag_unsafe_math_optimizations"
16282 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16286 (define_expand "floordf2"
16287 [(use (match_operand:DF 0 "register_operand" ""))
16288 (use (match_operand:DF 1 "register_operand" ""))]
16289 "TARGET_USE_FANCY_MATH_387
16290 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16291 && flag_unsafe_math_optimizations"
16293 rtx op0 = gen_reg_rtx (XFmode);
16294 rtx op1 = gen_reg_rtx (XFmode);
16296 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16297 emit_insn (gen_frndintxf2_floor (op0, op1));
16299 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16303 (define_expand "floorsf2"
16304 [(use (match_operand:SF 0 "register_operand" ""))
16305 (use (match_operand:SF 1 "register_operand" ""))]
16306 "TARGET_USE_FANCY_MATH_387
16307 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16308 && flag_unsafe_math_optimizations"
16310 rtx op0 = gen_reg_rtx (XFmode);
16311 rtx op1 = gen_reg_rtx (XFmode);
16313 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16314 emit_insn (gen_frndintxf2_floor (op0, op1));
16316 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16320 (define_insn_and_split "*fist<mode>2_floor_1"
16321 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16322 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16323 UNSPEC_FIST_FLOOR))
16324 (clobber (reg:CC FLAGS_REG))]
16325 "TARGET_USE_FANCY_MATH_387
16326 && flag_unsafe_math_optimizations
16327 && !(reload_completed || reload_in_progress)"
16332 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16334 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16335 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16336 if (memory_operand (operands[0], VOIDmode))
16337 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16338 operands[2], operands[3]));
16341 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16342 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16343 operands[2], operands[3],
16348 [(set_attr "type" "fistp")
16349 (set_attr "i387_cw" "floor")
16350 (set_attr "mode" "<MODE>")])
16352 (define_insn "fistdi2_floor"
16353 [(set (match_operand:DI 0 "memory_operand" "=m")
16354 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16355 UNSPEC_FIST_FLOOR))
16356 (use (match_operand:HI 2 "memory_operand" "m"))
16357 (use (match_operand:HI 3 "memory_operand" "m"))
16358 (clobber (match_scratch:XF 4 "=&1f"))]
16359 "TARGET_USE_FANCY_MATH_387
16360 && flag_unsafe_math_optimizations"
16361 "* return output_fix_trunc (insn, operands, 0);"
16362 [(set_attr "type" "fistp")
16363 (set_attr "i387_cw" "floor")
16364 (set_attr "mode" "DI")])
16366 (define_insn "fistdi2_floor_with_temp"
16367 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16368 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16369 UNSPEC_FIST_FLOOR))
16370 (use (match_operand:HI 2 "memory_operand" "m,m"))
16371 (use (match_operand:HI 3 "memory_operand" "m,m"))
16372 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16373 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16374 "TARGET_USE_FANCY_MATH_387
16375 && flag_unsafe_math_optimizations"
16377 [(set_attr "type" "fistp")
16378 (set_attr "i387_cw" "floor")
16379 (set_attr "mode" "DI")])
16382 [(set (match_operand:DI 0 "register_operand" "")
16383 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16384 UNSPEC_FIST_FLOOR))
16385 (use (match_operand:HI 2 "memory_operand" ""))
16386 (use (match_operand:HI 3 "memory_operand" ""))
16387 (clobber (match_operand:DI 4 "memory_operand" ""))
16388 (clobber (match_scratch 5 ""))]
16390 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16391 (use (match_dup 2))
16392 (use (match_dup 3))
16393 (clobber (match_dup 5))])
16394 (set (match_dup 0) (match_dup 4))]
16398 [(set (match_operand:DI 0 "memory_operand" "")
16399 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16400 UNSPEC_FIST_FLOOR))
16401 (use (match_operand:HI 2 "memory_operand" ""))
16402 (use (match_operand:HI 3 "memory_operand" ""))
16403 (clobber (match_operand:DI 4 "memory_operand" ""))
16404 (clobber (match_scratch 5 ""))]
16406 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16407 (use (match_dup 2))
16408 (use (match_dup 3))
16409 (clobber (match_dup 5))])]
16412 (define_insn "fist<mode>2_floor"
16413 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16414 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16415 UNSPEC_FIST_FLOOR))
16416 (use (match_operand:HI 2 "memory_operand" "m"))
16417 (use (match_operand:HI 3 "memory_operand" "m"))]
16418 "TARGET_USE_FANCY_MATH_387
16419 && flag_unsafe_math_optimizations"
16420 "* return output_fix_trunc (insn, operands, 0);"
16421 [(set_attr "type" "fistp")
16422 (set_attr "i387_cw" "floor")
16423 (set_attr "mode" "<MODE>")])
16425 (define_insn "fist<mode>2_floor_with_temp"
16426 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16427 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16428 UNSPEC_FIST_FLOOR))
16429 (use (match_operand:HI 2 "memory_operand" "m,m"))
16430 (use (match_operand:HI 3 "memory_operand" "m,m"))
16431 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16432 "TARGET_USE_FANCY_MATH_387
16433 && flag_unsafe_math_optimizations"
16435 [(set_attr "type" "fistp")
16436 (set_attr "i387_cw" "floor")
16437 (set_attr "mode" "<MODE>")])
16440 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16441 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16442 UNSPEC_FIST_FLOOR))
16443 (use (match_operand:HI 2 "memory_operand" ""))
16444 (use (match_operand:HI 3 "memory_operand" ""))
16445 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16447 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16448 UNSPEC_FIST_FLOOR))
16449 (use (match_dup 2))
16450 (use (match_dup 3))])
16451 (set (match_dup 0) (match_dup 4))]
16455 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16456 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16457 UNSPEC_FIST_FLOOR))
16458 (use (match_operand:HI 2 "memory_operand" ""))
16459 (use (match_operand:HI 3 "memory_operand" ""))
16460 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16462 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16463 UNSPEC_FIST_FLOOR))
16464 (use (match_dup 2))
16465 (use (match_dup 3))])]
16468 (define_expand "lfloor<mode>2"
16469 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16470 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16471 UNSPEC_FIST_FLOOR))
16472 (clobber (reg:CC FLAGS_REG))])]
16473 "TARGET_USE_FANCY_MATH_387
16474 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16475 && flag_unsafe_math_optimizations"
16478 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16479 (define_insn_and_split "frndintxf2_ceil"
16480 [(set (match_operand:XF 0 "register_operand" "=f")
16481 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16482 UNSPEC_FRNDINT_CEIL))
16483 (clobber (reg:CC FLAGS_REG))]
16484 "TARGET_USE_FANCY_MATH_387
16485 && flag_unsafe_math_optimizations
16486 && !(reload_completed || reload_in_progress)"
16491 ix86_optimize_mode_switching[I387_CEIL] = 1;
16493 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16494 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16496 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16497 operands[2], operands[3]));
16500 [(set_attr "type" "frndint")
16501 (set_attr "i387_cw" "ceil")
16502 (set_attr "mode" "XF")])
16504 (define_insn "frndintxf2_ceil_i387"
16505 [(set (match_operand:XF 0 "register_operand" "=f")
16506 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16507 UNSPEC_FRNDINT_CEIL))
16508 (use (match_operand:HI 2 "memory_operand" "m"))
16509 (use (match_operand:HI 3 "memory_operand" "m"))]
16510 "TARGET_USE_FANCY_MATH_387
16511 && flag_unsafe_math_optimizations"
16512 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16513 [(set_attr "type" "frndint")
16514 (set_attr "i387_cw" "ceil")
16515 (set_attr "mode" "XF")])
16517 (define_expand "ceilxf2"
16518 [(use (match_operand:XF 0 "register_operand" ""))
16519 (use (match_operand:XF 1 "register_operand" ""))]
16520 "TARGET_USE_FANCY_MATH_387
16521 && flag_unsafe_math_optimizations"
16523 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16527 (define_expand "ceildf2"
16528 [(use (match_operand:DF 0 "register_operand" ""))
16529 (use (match_operand:DF 1 "register_operand" ""))]
16530 "TARGET_USE_FANCY_MATH_387
16531 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16532 && flag_unsafe_math_optimizations"
16534 rtx op0 = gen_reg_rtx (XFmode);
16535 rtx op1 = gen_reg_rtx (XFmode);
16537 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16538 emit_insn (gen_frndintxf2_ceil (op0, op1));
16540 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16544 (define_expand "ceilsf2"
16545 [(use (match_operand:SF 0 "register_operand" ""))
16546 (use (match_operand:SF 1 "register_operand" ""))]
16547 "TARGET_USE_FANCY_MATH_387
16548 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16549 && flag_unsafe_math_optimizations"
16551 rtx op0 = gen_reg_rtx (XFmode);
16552 rtx op1 = gen_reg_rtx (XFmode);
16554 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16555 emit_insn (gen_frndintxf2_ceil (op0, op1));
16557 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16561 (define_insn_and_split "*fist<mode>2_ceil_1"
16562 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16563 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16565 (clobber (reg:CC FLAGS_REG))]
16566 "TARGET_USE_FANCY_MATH_387
16567 && flag_unsafe_math_optimizations
16568 && !(reload_completed || reload_in_progress)"
16573 ix86_optimize_mode_switching[I387_CEIL] = 1;
16575 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16576 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16577 if (memory_operand (operands[0], VOIDmode))
16578 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16579 operands[2], operands[3]));
16582 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16583 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16584 operands[2], operands[3],
16589 [(set_attr "type" "fistp")
16590 (set_attr "i387_cw" "ceil")
16591 (set_attr "mode" "<MODE>")])
16593 (define_insn "fistdi2_ceil"
16594 [(set (match_operand:DI 0 "memory_operand" "=m")
16595 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16597 (use (match_operand:HI 2 "memory_operand" "m"))
16598 (use (match_operand:HI 3 "memory_operand" "m"))
16599 (clobber (match_scratch:XF 4 "=&1f"))]
16600 "TARGET_USE_FANCY_MATH_387
16601 && flag_unsafe_math_optimizations"
16602 "* return output_fix_trunc (insn, operands, 0);"
16603 [(set_attr "type" "fistp")
16604 (set_attr "i387_cw" "ceil")
16605 (set_attr "mode" "DI")])
16607 (define_insn "fistdi2_ceil_with_temp"
16608 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16609 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16611 (use (match_operand:HI 2 "memory_operand" "m,m"))
16612 (use (match_operand:HI 3 "memory_operand" "m,m"))
16613 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16614 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16615 "TARGET_USE_FANCY_MATH_387
16616 && flag_unsafe_math_optimizations"
16618 [(set_attr "type" "fistp")
16619 (set_attr "i387_cw" "ceil")
16620 (set_attr "mode" "DI")])
16623 [(set (match_operand:DI 0 "register_operand" "")
16624 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16626 (use (match_operand:HI 2 "memory_operand" ""))
16627 (use (match_operand:HI 3 "memory_operand" ""))
16628 (clobber (match_operand:DI 4 "memory_operand" ""))
16629 (clobber (match_scratch 5 ""))]
16631 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16632 (use (match_dup 2))
16633 (use (match_dup 3))
16634 (clobber (match_dup 5))])
16635 (set (match_dup 0) (match_dup 4))]
16639 [(set (match_operand:DI 0 "memory_operand" "")
16640 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16642 (use (match_operand:HI 2 "memory_operand" ""))
16643 (use (match_operand:HI 3 "memory_operand" ""))
16644 (clobber (match_operand:DI 4 "memory_operand" ""))
16645 (clobber (match_scratch 5 ""))]
16647 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16648 (use (match_dup 2))
16649 (use (match_dup 3))
16650 (clobber (match_dup 5))])]
16653 (define_insn "fist<mode>2_ceil"
16654 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16655 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16657 (use (match_operand:HI 2 "memory_operand" "m"))
16658 (use (match_operand:HI 3 "memory_operand" "m"))]
16659 "TARGET_USE_FANCY_MATH_387
16660 && flag_unsafe_math_optimizations"
16661 "* return output_fix_trunc (insn, operands, 0);"
16662 [(set_attr "type" "fistp")
16663 (set_attr "i387_cw" "ceil")
16664 (set_attr "mode" "<MODE>")])
16666 (define_insn "fist<mode>2_ceil_with_temp"
16667 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16668 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16670 (use (match_operand:HI 2 "memory_operand" "m,m"))
16671 (use (match_operand:HI 3 "memory_operand" "m,m"))
16672 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16673 "TARGET_USE_FANCY_MATH_387
16674 && flag_unsafe_math_optimizations"
16676 [(set_attr "type" "fistp")
16677 (set_attr "i387_cw" "ceil")
16678 (set_attr "mode" "<MODE>")])
16681 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16682 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16684 (use (match_operand:HI 2 "memory_operand" ""))
16685 (use (match_operand:HI 3 "memory_operand" ""))
16686 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16688 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16690 (use (match_dup 2))
16691 (use (match_dup 3))])
16692 (set (match_dup 0) (match_dup 4))]
16696 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16697 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16699 (use (match_operand:HI 2 "memory_operand" ""))
16700 (use (match_operand:HI 3 "memory_operand" ""))
16701 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16703 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16705 (use (match_dup 2))
16706 (use (match_dup 3))])]
16709 (define_expand "lceil<mode>2"
16710 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16711 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16713 (clobber (reg:CC FLAGS_REG))])]
16714 "TARGET_USE_FANCY_MATH_387
16715 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16716 && flag_unsafe_math_optimizations"
16719 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16720 (define_insn_and_split "frndintxf2_trunc"
16721 [(set (match_operand:XF 0 "register_operand" "=f")
16722 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16723 UNSPEC_FRNDINT_TRUNC))
16724 (clobber (reg:CC FLAGS_REG))]
16725 "TARGET_USE_FANCY_MATH_387
16726 && flag_unsafe_math_optimizations
16727 && !(reload_completed || reload_in_progress)"
16732 ix86_optimize_mode_switching[I387_TRUNC] = 1;
16734 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16735 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
16737 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
16738 operands[2], operands[3]));
16741 [(set_attr "type" "frndint")
16742 (set_attr "i387_cw" "trunc")
16743 (set_attr "mode" "XF")])
16745 (define_insn "frndintxf2_trunc_i387"
16746 [(set (match_operand:XF 0 "register_operand" "=f")
16747 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16748 UNSPEC_FRNDINT_TRUNC))
16749 (use (match_operand:HI 2 "memory_operand" "m"))
16750 (use (match_operand:HI 3 "memory_operand" "m"))]
16751 "TARGET_USE_FANCY_MATH_387
16752 && flag_unsafe_math_optimizations"
16753 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16754 [(set_attr "type" "frndint")
16755 (set_attr "i387_cw" "trunc")
16756 (set_attr "mode" "XF")])
16758 (define_expand "btruncxf2"
16759 [(use (match_operand:XF 0 "register_operand" ""))
16760 (use (match_operand:XF 1 "register_operand" ""))]
16761 "TARGET_USE_FANCY_MATH_387
16762 && flag_unsafe_math_optimizations"
16764 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
16768 (define_expand "btruncdf2"
16769 [(use (match_operand:DF 0 "register_operand" ""))
16770 (use (match_operand:DF 1 "register_operand" ""))]
16771 "TARGET_USE_FANCY_MATH_387
16772 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16773 && flag_unsafe_math_optimizations"
16775 rtx op0 = gen_reg_rtx (XFmode);
16776 rtx op1 = gen_reg_rtx (XFmode);
16778 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16779 emit_insn (gen_frndintxf2_trunc (op0, op1));
16781 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16785 (define_expand "btruncsf2"
16786 [(use (match_operand:SF 0 "register_operand" ""))
16787 (use (match_operand:SF 1 "register_operand" ""))]
16788 "TARGET_USE_FANCY_MATH_387
16789 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16790 && flag_unsafe_math_optimizations"
16792 rtx op0 = gen_reg_rtx (XFmode);
16793 rtx op1 = gen_reg_rtx (XFmode);
16795 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16796 emit_insn (gen_frndintxf2_trunc (op0, op1));
16798 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16802 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16803 (define_insn_and_split "frndintxf2_mask_pm"
16804 [(set (match_operand:XF 0 "register_operand" "=f")
16805 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16806 UNSPEC_FRNDINT_MASK_PM))
16807 (clobber (reg:CC FLAGS_REG))]
16808 "TARGET_USE_FANCY_MATH_387
16809 && flag_unsafe_math_optimizations
16810 && !(reload_completed || reload_in_progress)"
16815 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16817 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16818 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16820 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16821 operands[2], operands[3]));
16824 [(set_attr "type" "frndint")
16825 (set_attr "i387_cw" "mask_pm")
16826 (set_attr "mode" "XF")])
16828 (define_insn "frndintxf2_mask_pm_i387"
16829 [(set (match_operand:XF 0 "register_operand" "=f")
16830 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16831 UNSPEC_FRNDINT_MASK_PM))
16832 (use (match_operand:HI 2 "memory_operand" "m"))
16833 (use (match_operand:HI 3 "memory_operand" "m"))]
16834 "TARGET_USE_FANCY_MATH_387
16835 && flag_unsafe_math_optimizations"
16836 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16837 [(set_attr "type" "frndint")
16838 (set_attr "i387_cw" "mask_pm")
16839 (set_attr "mode" "XF")])
16841 (define_expand "nearbyintxf2"
16842 [(use (match_operand:XF 0 "register_operand" ""))
16843 (use (match_operand:XF 1 "register_operand" ""))]
16844 "TARGET_USE_FANCY_MATH_387
16845 && flag_unsafe_math_optimizations"
16847 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
16852 (define_expand "nearbyintdf2"
16853 [(use (match_operand:DF 0 "register_operand" ""))
16854 (use (match_operand:DF 1 "register_operand" ""))]
16855 "TARGET_USE_FANCY_MATH_387
16856 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16857 && flag_unsafe_math_optimizations"
16859 rtx op0 = gen_reg_rtx (XFmode);
16860 rtx op1 = gen_reg_rtx (XFmode);
16862 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16863 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16865 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16869 (define_expand "nearbyintsf2"
16870 [(use (match_operand:SF 0 "register_operand" ""))
16871 (use (match_operand:SF 1 "register_operand" ""))]
16872 "TARGET_USE_FANCY_MATH_387
16873 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16874 && flag_unsafe_math_optimizations"
16876 rtx op0 = gen_reg_rtx (XFmode);
16877 rtx op1 = gen_reg_rtx (XFmode);
16879 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16880 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16882 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16887 ;; Block operation instructions
16890 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16893 [(set_attr "type" "cld")])
16895 (define_expand "movmemsi"
16896 [(use (match_operand:BLK 0 "memory_operand" ""))
16897 (use (match_operand:BLK 1 "memory_operand" ""))
16898 (use (match_operand:SI 2 "nonmemory_operand" ""))
16899 (use (match_operand:SI 3 "const_int_operand" ""))]
16900 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16902 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16908 (define_expand "movmemdi"
16909 [(use (match_operand:BLK 0 "memory_operand" ""))
16910 (use (match_operand:BLK 1 "memory_operand" ""))
16911 (use (match_operand:DI 2 "nonmemory_operand" ""))
16912 (use (match_operand:DI 3 "const_int_operand" ""))]
16915 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16921 ;; Most CPUs don't like single string operations
16922 ;; Handle this case here to simplify previous expander.
16924 (define_expand "strmov"
16925 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16926 (set (match_operand 1 "memory_operand" "") (match_dup 4))
16927 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16928 (clobber (reg:CC FLAGS_REG))])
16929 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16930 (clobber (reg:CC FLAGS_REG))])]
16933 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16935 /* If .md ever supports :P for Pmode, these can be directly
16936 in the pattern above. */
16937 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16938 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16940 if (TARGET_SINGLE_STRINGOP || optimize_size)
16942 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16943 operands[2], operands[3],
16944 operands[5], operands[6]));
16948 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16951 (define_expand "strmov_singleop"
16952 [(parallel [(set (match_operand 1 "memory_operand" "")
16953 (match_operand 3 "memory_operand" ""))
16954 (set (match_operand 0 "register_operand" "")
16955 (match_operand 4 "" ""))
16956 (set (match_operand 2 "register_operand" "")
16957 (match_operand 5 "" ""))
16958 (use (reg:SI DIRFLAG_REG))])]
16959 "TARGET_SINGLE_STRINGOP || optimize_size"
16962 (define_insn "*strmovdi_rex_1"
16963 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16964 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16965 (set (match_operand:DI 0 "register_operand" "=D")
16966 (plus:DI (match_dup 2)
16968 (set (match_operand:DI 1 "register_operand" "=S")
16969 (plus:DI (match_dup 3)
16971 (use (reg:SI DIRFLAG_REG))]
16972 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16974 [(set_attr "type" "str")
16975 (set_attr "mode" "DI")
16976 (set_attr "memory" "both")])
16978 (define_insn "*strmovsi_1"
16979 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16980 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16981 (set (match_operand:SI 0 "register_operand" "=D")
16982 (plus:SI (match_dup 2)
16984 (set (match_operand:SI 1 "register_operand" "=S")
16985 (plus:SI (match_dup 3)
16987 (use (reg:SI DIRFLAG_REG))]
16988 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16990 [(set_attr "type" "str")
16991 (set_attr "mode" "SI")
16992 (set_attr "memory" "both")])
16994 (define_insn "*strmovsi_rex_1"
16995 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16996 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16997 (set (match_operand:DI 0 "register_operand" "=D")
16998 (plus:DI (match_dup 2)
17000 (set (match_operand:DI 1 "register_operand" "=S")
17001 (plus:DI (match_dup 3)
17003 (use (reg:SI DIRFLAG_REG))]
17004 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17006 [(set_attr "type" "str")
17007 (set_attr "mode" "SI")
17008 (set_attr "memory" "both")])
17010 (define_insn "*strmovhi_1"
17011 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17012 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17013 (set (match_operand:SI 0 "register_operand" "=D")
17014 (plus:SI (match_dup 2)
17016 (set (match_operand:SI 1 "register_operand" "=S")
17017 (plus:SI (match_dup 3)
17019 (use (reg:SI DIRFLAG_REG))]
17020 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17022 [(set_attr "type" "str")
17023 (set_attr "memory" "both")
17024 (set_attr "mode" "HI")])
17026 (define_insn "*strmovhi_rex_1"
17027 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17028 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17029 (set (match_operand:DI 0 "register_operand" "=D")
17030 (plus:DI (match_dup 2)
17032 (set (match_operand:DI 1 "register_operand" "=S")
17033 (plus:DI (match_dup 3)
17035 (use (reg:SI DIRFLAG_REG))]
17036 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17038 [(set_attr "type" "str")
17039 (set_attr "memory" "both")
17040 (set_attr "mode" "HI")])
17042 (define_insn "*strmovqi_1"
17043 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17044 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17045 (set (match_operand:SI 0 "register_operand" "=D")
17046 (plus:SI (match_dup 2)
17048 (set (match_operand:SI 1 "register_operand" "=S")
17049 (plus:SI (match_dup 3)
17051 (use (reg:SI DIRFLAG_REG))]
17052 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17054 [(set_attr "type" "str")
17055 (set_attr "memory" "both")
17056 (set_attr "mode" "QI")])
17058 (define_insn "*strmovqi_rex_1"
17059 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17060 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17061 (set (match_operand:DI 0 "register_operand" "=D")
17062 (plus:DI (match_dup 2)
17064 (set (match_operand:DI 1 "register_operand" "=S")
17065 (plus:DI (match_dup 3)
17067 (use (reg:SI DIRFLAG_REG))]
17068 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17070 [(set_attr "type" "str")
17071 (set_attr "memory" "both")
17072 (set_attr "mode" "QI")])
17074 (define_expand "rep_mov"
17075 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17076 (set (match_operand 0 "register_operand" "")
17077 (match_operand 5 "" ""))
17078 (set (match_operand 2 "register_operand" "")
17079 (match_operand 6 "" ""))
17080 (set (match_operand 1 "memory_operand" "")
17081 (match_operand 3 "memory_operand" ""))
17082 (use (match_dup 4))
17083 (use (reg:SI DIRFLAG_REG))])]
17087 (define_insn "*rep_movdi_rex64"
17088 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17089 (set (match_operand:DI 0 "register_operand" "=D")
17090 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17092 (match_operand:DI 3 "register_operand" "0")))
17093 (set (match_operand:DI 1 "register_operand" "=S")
17094 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17095 (match_operand:DI 4 "register_operand" "1")))
17096 (set (mem:BLK (match_dup 3))
17097 (mem:BLK (match_dup 4)))
17098 (use (match_dup 5))
17099 (use (reg:SI DIRFLAG_REG))]
17101 "{rep\;movsq|rep movsq}"
17102 [(set_attr "type" "str")
17103 (set_attr "prefix_rep" "1")
17104 (set_attr "memory" "both")
17105 (set_attr "mode" "DI")])
17107 (define_insn "*rep_movsi"
17108 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17109 (set (match_operand:SI 0 "register_operand" "=D")
17110 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17112 (match_operand:SI 3 "register_operand" "0")))
17113 (set (match_operand:SI 1 "register_operand" "=S")
17114 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17115 (match_operand:SI 4 "register_operand" "1")))
17116 (set (mem:BLK (match_dup 3))
17117 (mem:BLK (match_dup 4)))
17118 (use (match_dup 5))
17119 (use (reg:SI DIRFLAG_REG))]
17121 "{rep\;movsl|rep movsd}"
17122 [(set_attr "type" "str")
17123 (set_attr "prefix_rep" "1")
17124 (set_attr "memory" "both")
17125 (set_attr "mode" "SI")])
17127 (define_insn "*rep_movsi_rex64"
17128 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17129 (set (match_operand:DI 0 "register_operand" "=D")
17130 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17132 (match_operand:DI 3 "register_operand" "0")))
17133 (set (match_operand:DI 1 "register_operand" "=S")
17134 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17135 (match_operand:DI 4 "register_operand" "1")))
17136 (set (mem:BLK (match_dup 3))
17137 (mem:BLK (match_dup 4)))
17138 (use (match_dup 5))
17139 (use (reg:SI DIRFLAG_REG))]
17141 "{rep\;movsl|rep movsd}"
17142 [(set_attr "type" "str")
17143 (set_attr "prefix_rep" "1")
17144 (set_attr "memory" "both")
17145 (set_attr "mode" "SI")])
17147 (define_insn "*rep_movqi"
17148 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17149 (set (match_operand:SI 0 "register_operand" "=D")
17150 (plus:SI (match_operand:SI 3 "register_operand" "0")
17151 (match_operand:SI 5 "register_operand" "2")))
17152 (set (match_operand:SI 1 "register_operand" "=S")
17153 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17154 (set (mem:BLK (match_dup 3))
17155 (mem:BLK (match_dup 4)))
17156 (use (match_dup 5))
17157 (use (reg:SI DIRFLAG_REG))]
17159 "{rep\;movsb|rep movsb}"
17160 [(set_attr "type" "str")
17161 (set_attr "prefix_rep" "1")
17162 (set_attr "memory" "both")
17163 (set_attr "mode" "SI")])
17165 (define_insn "*rep_movqi_rex64"
17166 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17167 (set (match_operand:DI 0 "register_operand" "=D")
17168 (plus:DI (match_operand:DI 3 "register_operand" "0")
17169 (match_operand:DI 5 "register_operand" "2")))
17170 (set (match_operand:DI 1 "register_operand" "=S")
17171 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17172 (set (mem:BLK (match_dup 3))
17173 (mem:BLK (match_dup 4)))
17174 (use (match_dup 5))
17175 (use (reg:SI DIRFLAG_REG))]
17177 "{rep\;movsb|rep movsb}"
17178 [(set_attr "type" "str")
17179 (set_attr "prefix_rep" "1")
17180 (set_attr "memory" "both")
17181 (set_attr "mode" "SI")])
17183 (define_expand "clrmemsi"
17184 [(use (match_operand:BLK 0 "memory_operand" ""))
17185 (use (match_operand:SI 1 "nonmemory_operand" ""))
17186 (use (match_operand 2 "const_int_operand" ""))]
17189 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17195 (define_expand "clrmemdi"
17196 [(use (match_operand:BLK 0 "memory_operand" ""))
17197 (use (match_operand:DI 1 "nonmemory_operand" ""))
17198 (use (match_operand 2 "const_int_operand" ""))]
17201 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17207 ;; Most CPUs don't like single string operations
17208 ;; Handle this case here to simplify previous expander.
17210 (define_expand "strset"
17211 [(set (match_operand 1 "memory_operand" "")
17212 (match_operand 2 "register_operand" ""))
17213 (parallel [(set (match_operand 0 "register_operand" "")
17215 (clobber (reg:CC FLAGS_REG))])]
17218 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17219 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17221 /* If .md ever supports :P for Pmode, this can be directly
17222 in the pattern above. */
17223 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17224 GEN_INT (GET_MODE_SIZE (GET_MODE
17226 if (TARGET_SINGLE_STRINGOP || optimize_size)
17228 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17234 (define_expand "strset_singleop"
17235 [(parallel [(set (match_operand 1 "memory_operand" "")
17236 (match_operand 2 "register_operand" ""))
17237 (set (match_operand 0 "register_operand" "")
17238 (match_operand 3 "" ""))
17239 (use (reg:SI DIRFLAG_REG))])]
17240 "TARGET_SINGLE_STRINGOP || optimize_size"
17243 (define_insn "*strsetdi_rex_1"
17244 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17245 (match_operand:DI 2 "register_operand" "a"))
17246 (set (match_operand:DI 0 "register_operand" "=D")
17247 (plus:DI (match_dup 1)
17249 (use (reg:SI DIRFLAG_REG))]
17250 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17252 [(set_attr "type" "str")
17253 (set_attr "memory" "store")
17254 (set_attr "mode" "DI")])
17256 (define_insn "*strsetsi_1"
17257 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17258 (match_operand:SI 2 "register_operand" "a"))
17259 (set (match_operand:SI 0 "register_operand" "=D")
17260 (plus:SI (match_dup 1)
17262 (use (reg:SI DIRFLAG_REG))]
17263 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17265 [(set_attr "type" "str")
17266 (set_attr "memory" "store")
17267 (set_attr "mode" "SI")])
17269 (define_insn "*strsetsi_rex_1"
17270 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17271 (match_operand:SI 2 "register_operand" "a"))
17272 (set (match_operand:DI 0 "register_operand" "=D")
17273 (plus:DI (match_dup 1)
17275 (use (reg:SI DIRFLAG_REG))]
17276 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17278 [(set_attr "type" "str")
17279 (set_attr "memory" "store")
17280 (set_attr "mode" "SI")])
17282 (define_insn "*strsethi_1"
17283 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17284 (match_operand:HI 2 "register_operand" "a"))
17285 (set (match_operand:SI 0 "register_operand" "=D")
17286 (plus:SI (match_dup 1)
17288 (use (reg:SI DIRFLAG_REG))]
17289 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17291 [(set_attr "type" "str")
17292 (set_attr "memory" "store")
17293 (set_attr "mode" "HI")])
17295 (define_insn "*strsethi_rex_1"
17296 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17297 (match_operand:HI 2 "register_operand" "a"))
17298 (set (match_operand:DI 0 "register_operand" "=D")
17299 (plus:DI (match_dup 1)
17301 (use (reg:SI DIRFLAG_REG))]
17302 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17304 [(set_attr "type" "str")
17305 (set_attr "memory" "store")
17306 (set_attr "mode" "HI")])
17308 (define_insn "*strsetqi_1"
17309 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17310 (match_operand:QI 2 "register_operand" "a"))
17311 (set (match_operand:SI 0 "register_operand" "=D")
17312 (plus:SI (match_dup 1)
17314 (use (reg:SI DIRFLAG_REG))]
17315 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17317 [(set_attr "type" "str")
17318 (set_attr "memory" "store")
17319 (set_attr "mode" "QI")])
17321 (define_insn "*strsetqi_rex_1"
17322 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17323 (match_operand:QI 2 "register_operand" "a"))
17324 (set (match_operand:DI 0 "register_operand" "=D")
17325 (plus:DI (match_dup 1)
17327 (use (reg:SI DIRFLAG_REG))]
17328 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17330 [(set_attr "type" "str")
17331 (set_attr "memory" "store")
17332 (set_attr "mode" "QI")])
17334 (define_expand "rep_stos"
17335 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17336 (set (match_operand 0 "register_operand" "")
17337 (match_operand 4 "" ""))
17338 (set (match_operand 2 "memory_operand" "") (const_int 0))
17339 (use (match_operand 3 "register_operand" ""))
17340 (use (match_dup 1))
17341 (use (reg:SI DIRFLAG_REG))])]
17345 (define_insn "*rep_stosdi_rex64"
17346 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17347 (set (match_operand:DI 0 "register_operand" "=D")
17348 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17350 (match_operand:DI 3 "register_operand" "0")))
17351 (set (mem:BLK (match_dup 3))
17353 (use (match_operand:DI 2 "register_operand" "a"))
17354 (use (match_dup 4))
17355 (use (reg:SI DIRFLAG_REG))]
17357 "{rep\;stosq|rep stosq}"
17358 [(set_attr "type" "str")
17359 (set_attr "prefix_rep" "1")
17360 (set_attr "memory" "store")
17361 (set_attr "mode" "DI")])
17363 (define_insn "*rep_stossi"
17364 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17365 (set (match_operand:SI 0 "register_operand" "=D")
17366 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17368 (match_operand:SI 3 "register_operand" "0")))
17369 (set (mem:BLK (match_dup 3))
17371 (use (match_operand:SI 2 "register_operand" "a"))
17372 (use (match_dup 4))
17373 (use (reg:SI DIRFLAG_REG))]
17375 "{rep\;stosl|rep stosd}"
17376 [(set_attr "type" "str")
17377 (set_attr "prefix_rep" "1")
17378 (set_attr "memory" "store")
17379 (set_attr "mode" "SI")])
17381 (define_insn "*rep_stossi_rex64"
17382 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17383 (set (match_operand:DI 0 "register_operand" "=D")
17384 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17386 (match_operand:DI 3 "register_operand" "0")))
17387 (set (mem:BLK (match_dup 3))
17389 (use (match_operand:SI 2 "register_operand" "a"))
17390 (use (match_dup 4))
17391 (use (reg:SI DIRFLAG_REG))]
17393 "{rep\;stosl|rep stosd}"
17394 [(set_attr "type" "str")
17395 (set_attr "prefix_rep" "1")
17396 (set_attr "memory" "store")
17397 (set_attr "mode" "SI")])
17399 (define_insn "*rep_stosqi"
17400 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17401 (set (match_operand:SI 0 "register_operand" "=D")
17402 (plus:SI (match_operand:SI 3 "register_operand" "0")
17403 (match_operand:SI 4 "register_operand" "1")))
17404 (set (mem:BLK (match_dup 3))
17406 (use (match_operand:QI 2 "register_operand" "a"))
17407 (use (match_dup 4))
17408 (use (reg:SI DIRFLAG_REG))]
17410 "{rep\;stosb|rep stosb}"
17411 [(set_attr "type" "str")
17412 (set_attr "prefix_rep" "1")
17413 (set_attr "memory" "store")
17414 (set_attr "mode" "QI")])
17416 (define_insn "*rep_stosqi_rex64"
17417 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17418 (set (match_operand:DI 0 "register_operand" "=D")
17419 (plus:DI (match_operand:DI 3 "register_operand" "0")
17420 (match_operand:DI 4 "register_operand" "1")))
17421 (set (mem:BLK (match_dup 3))
17423 (use (match_operand:QI 2 "register_operand" "a"))
17424 (use (match_dup 4))
17425 (use (reg:SI DIRFLAG_REG))]
17427 "{rep\;stosb|rep stosb}"
17428 [(set_attr "type" "str")
17429 (set_attr "prefix_rep" "1")
17430 (set_attr "memory" "store")
17431 (set_attr "mode" "QI")])
17433 (define_expand "cmpstrsi"
17434 [(set (match_operand:SI 0 "register_operand" "")
17435 (compare:SI (match_operand:BLK 1 "general_operand" "")
17436 (match_operand:BLK 2 "general_operand" "")))
17437 (use (match_operand 3 "general_operand" ""))
17438 (use (match_operand 4 "immediate_operand" ""))]
17439 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17441 rtx addr1, addr2, out, outlow, count, countreg, align;
17443 /* Can't use this if the user has appropriated esi or edi. */
17444 if (global_regs[4] || global_regs[5])
17448 if (GET_CODE (out) != REG)
17449 out = gen_reg_rtx (SImode);
17451 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17452 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17453 if (addr1 != XEXP (operands[1], 0))
17454 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17455 if (addr2 != XEXP (operands[2], 0))
17456 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17458 count = operands[3];
17459 countreg = ix86_zero_extend_to_Pmode (count);
17461 /* %%% Iff we are testing strict equality, we can use known alignment
17462 to good advantage. This may be possible with combine, particularly
17463 once cc0 is dead. */
17464 align = operands[4];
17466 emit_insn (gen_cld ());
17467 if (GET_CODE (count) == CONST_INT)
17469 if (INTVAL (count) == 0)
17471 emit_move_insn (operands[0], const0_rtx);
17474 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17475 operands[1], operands[2]));
17480 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17482 emit_insn (gen_cmpsi_1 (countreg, countreg));
17483 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17484 operands[1], operands[2]));
17487 outlow = gen_lowpart (QImode, out);
17488 emit_insn (gen_cmpintqi (outlow));
17489 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17491 if (operands[0] != out)
17492 emit_move_insn (operands[0], out);
17497 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17499 (define_expand "cmpintqi"
17500 [(set (match_dup 1)
17501 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17503 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17504 (parallel [(set (match_operand:QI 0 "register_operand" "")
17505 (minus:QI (match_dup 1)
17507 (clobber (reg:CC FLAGS_REG))])]
17509 "operands[1] = gen_reg_rtx (QImode);
17510 operands[2] = gen_reg_rtx (QImode);")
17512 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17513 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17515 (define_expand "cmpstrqi_nz_1"
17516 [(parallel [(set (reg:CC FLAGS_REG)
17517 (compare:CC (match_operand 4 "memory_operand" "")
17518 (match_operand 5 "memory_operand" "")))
17519 (use (match_operand 2 "register_operand" ""))
17520 (use (match_operand:SI 3 "immediate_operand" ""))
17521 (use (reg:SI DIRFLAG_REG))
17522 (clobber (match_operand 0 "register_operand" ""))
17523 (clobber (match_operand 1 "register_operand" ""))
17524 (clobber (match_dup 2))])]
17528 (define_insn "*cmpstrqi_nz_1"
17529 [(set (reg:CC FLAGS_REG)
17530 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17531 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17532 (use (match_operand:SI 6 "register_operand" "2"))
17533 (use (match_operand:SI 3 "immediate_operand" "i"))
17534 (use (reg:SI DIRFLAG_REG))
17535 (clobber (match_operand:SI 0 "register_operand" "=S"))
17536 (clobber (match_operand:SI 1 "register_operand" "=D"))
17537 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17540 [(set_attr "type" "str")
17541 (set_attr "mode" "QI")
17542 (set_attr "prefix_rep" "1")])
17544 (define_insn "*cmpstrqi_nz_rex_1"
17545 [(set (reg:CC FLAGS_REG)
17546 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17547 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17548 (use (match_operand:DI 6 "register_operand" "2"))
17549 (use (match_operand:SI 3 "immediate_operand" "i"))
17550 (use (reg:SI DIRFLAG_REG))
17551 (clobber (match_operand:DI 0 "register_operand" "=S"))
17552 (clobber (match_operand:DI 1 "register_operand" "=D"))
17553 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17556 [(set_attr "type" "str")
17557 (set_attr "mode" "QI")
17558 (set_attr "prefix_rep" "1")])
17560 ;; The same, but the count is not known to not be zero.
17562 (define_expand "cmpstrqi_1"
17563 [(parallel [(set (reg:CC FLAGS_REG)
17564 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17566 (compare:CC (match_operand 4 "memory_operand" "")
17567 (match_operand 5 "memory_operand" ""))
17569 (use (match_operand:SI 3 "immediate_operand" ""))
17570 (use (reg:CC FLAGS_REG))
17571 (use (reg:SI DIRFLAG_REG))
17572 (clobber (match_operand 0 "register_operand" ""))
17573 (clobber (match_operand 1 "register_operand" ""))
17574 (clobber (match_dup 2))])]
17578 (define_insn "*cmpstrqi_1"
17579 [(set (reg:CC FLAGS_REG)
17580 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17582 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17583 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17585 (use (match_operand:SI 3 "immediate_operand" "i"))
17586 (use (reg:CC FLAGS_REG))
17587 (use (reg:SI DIRFLAG_REG))
17588 (clobber (match_operand:SI 0 "register_operand" "=S"))
17589 (clobber (match_operand:SI 1 "register_operand" "=D"))
17590 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17593 [(set_attr "type" "str")
17594 (set_attr "mode" "QI")
17595 (set_attr "prefix_rep" "1")])
17597 (define_insn "*cmpstrqi_rex_1"
17598 [(set (reg:CC FLAGS_REG)
17599 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17601 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17602 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17604 (use (match_operand:SI 3 "immediate_operand" "i"))
17605 (use (reg:CC FLAGS_REG))
17606 (use (reg:SI DIRFLAG_REG))
17607 (clobber (match_operand:DI 0 "register_operand" "=S"))
17608 (clobber (match_operand:DI 1 "register_operand" "=D"))
17609 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17612 [(set_attr "type" "str")
17613 (set_attr "mode" "QI")
17614 (set_attr "prefix_rep" "1")])
17616 (define_expand "strlensi"
17617 [(set (match_operand:SI 0 "register_operand" "")
17618 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17619 (match_operand:QI 2 "immediate_operand" "")
17620 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17623 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17629 (define_expand "strlendi"
17630 [(set (match_operand:DI 0 "register_operand" "")
17631 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17632 (match_operand:QI 2 "immediate_operand" "")
17633 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17636 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17642 (define_expand "strlenqi_1"
17643 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17644 (use (reg:SI DIRFLAG_REG))
17645 (clobber (match_operand 1 "register_operand" ""))
17646 (clobber (reg:CC FLAGS_REG))])]
17650 (define_insn "*strlenqi_1"
17651 [(set (match_operand:SI 0 "register_operand" "=&c")
17652 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17653 (match_operand:QI 2 "register_operand" "a")
17654 (match_operand:SI 3 "immediate_operand" "i")
17655 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17656 (use (reg:SI DIRFLAG_REG))
17657 (clobber (match_operand:SI 1 "register_operand" "=D"))
17658 (clobber (reg:CC FLAGS_REG))]
17661 [(set_attr "type" "str")
17662 (set_attr "mode" "QI")
17663 (set_attr "prefix_rep" "1")])
17665 (define_insn "*strlenqi_rex_1"
17666 [(set (match_operand:DI 0 "register_operand" "=&c")
17667 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17668 (match_operand:QI 2 "register_operand" "a")
17669 (match_operand:DI 3 "immediate_operand" "i")
17670 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17671 (use (reg:SI DIRFLAG_REG))
17672 (clobber (match_operand:DI 1 "register_operand" "=D"))
17673 (clobber (reg:CC FLAGS_REG))]
17676 [(set_attr "type" "str")
17677 (set_attr "mode" "QI")
17678 (set_attr "prefix_rep" "1")])
17680 ;; Peephole optimizations to clean up after cmpstr*. This should be
17681 ;; handled in combine, but it is not currently up to the task.
17682 ;; When used for their truth value, the cmpstr* expanders generate
17691 ;; The intermediate three instructions are unnecessary.
17693 ;; This one handles cmpstr*_nz_1...
17696 (set (reg:CC FLAGS_REG)
17697 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17698 (mem:BLK (match_operand 5 "register_operand" ""))))
17699 (use (match_operand 6 "register_operand" ""))
17700 (use (match_operand:SI 3 "immediate_operand" ""))
17701 (use (reg:SI DIRFLAG_REG))
17702 (clobber (match_operand 0 "register_operand" ""))
17703 (clobber (match_operand 1 "register_operand" ""))
17704 (clobber (match_operand 2 "register_operand" ""))])
17705 (set (match_operand:QI 7 "register_operand" "")
17706 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17707 (set (match_operand:QI 8 "register_operand" "")
17708 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17709 (set (reg FLAGS_REG)
17710 (compare (match_dup 7) (match_dup 8)))
17712 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17714 (set (reg:CC FLAGS_REG)
17715 (compare:CC (mem:BLK (match_dup 4))
17716 (mem:BLK (match_dup 5))))
17717 (use (match_dup 6))
17718 (use (match_dup 3))
17719 (use (reg:SI DIRFLAG_REG))
17720 (clobber (match_dup 0))
17721 (clobber (match_dup 1))
17722 (clobber (match_dup 2))])]
17725 ;; ...and this one handles cmpstr*_1.
17728 (set (reg:CC FLAGS_REG)
17729 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17731 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17732 (mem:BLK (match_operand 5 "register_operand" "")))
17734 (use (match_operand:SI 3 "immediate_operand" ""))
17735 (use (reg:CC FLAGS_REG))
17736 (use (reg:SI DIRFLAG_REG))
17737 (clobber (match_operand 0 "register_operand" ""))
17738 (clobber (match_operand 1 "register_operand" ""))
17739 (clobber (match_operand 2 "register_operand" ""))])
17740 (set (match_operand:QI 7 "register_operand" "")
17741 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17742 (set (match_operand:QI 8 "register_operand" "")
17743 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17744 (set (reg FLAGS_REG)
17745 (compare (match_dup 7) (match_dup 8)))
17747 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17749 (set (reg:CC FLAGS_REG)
17750 (if_then_else:CC (ne (match_dup 6)
17752 (compare:CC (mem:BLK (match_dup 4))
17753 (mem:BLK (match_dup 5)))
17755 (use (match_dup 3))
17756 (use (reg:CC FLAGS_REG))
17757 (use (reg:SI DIRFLAG_REG))
17758 (clobber (match_dup 0))
17759 (clobber (match_dup 1))
17760 (clobber (match_dup 2))])]
17765 ;; Conditional move instructions.
17767 (define_expand "movdicc"
17768 [(set (match_operand:DI 0 "register_operand" "")
17769 (if_then_else:DI (match_operand 1 "comparison_operator" "")
17770 (match_operand:DI 2 "general_operand" "")
17771 (match_operand:DI 3 "general_operand" "")))]
17773 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17775 (define_insn "x86_movdicc_0_m1_rex64"
17776 [(set (match_operand:DI 0 "register_operand" "=r")
17777 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17780 (clobber (reg:CC FLAGS_REG))]
17783 ; Since we don't have the proper number of operands for an alu insn,
17784 ; fill in all the blanks.
17785 [(set_attr "type" "alu")
17786 (set_attr "pent_pair" "pu")
17787 (set_attr "memory" "none")
17788 (set_attr "imm_disp" "false")
17789 (set_attr "mode" "DI")
17790 (set_attr "length_immediate" "0")])
17792 (define_insn "*movdicc_c_rex64"
17793 [(set (match_operand:DI 0 "register_operand" "=r,r")
17794 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17795 [(reg FLAGS_REG) (const_int 0)])
17796 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17797 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17798 "TARGET_64BIT && TARGET_CMOVE
17799 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17801 cmov%O2%C1\t{%2, %0|%0, %2}
17802 cmov%O2%c1\t{%3, %0|%0, %3}"
17803 [(set_attr "type" "icmov")
17804 (set_attr "mode" "DI")])
17806 (define_expand "movsicc"
17807 [(set (match_operand:SI 0 "register_operand" "")
17808 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17809 (match_operand:SI 2 "general_operand" "")
17810 (match_operand:SI 3 "general_operand" "")))]
17812 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17814 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17815 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17816 ;; So just document what we're doing explicitly.
17818 (define_insn "x86_movsicc_0_m1"
17819 [(set (match_operand:SI 0 "register_operand" "=r")
17820 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17823 (clobber (reg:CC FLAGS_REG))]
17826 ; Since we don't have the proper number of operands for an alu insn,
17827 ; fill in all the blanks.
17828 [(set_attr "type" "alu")
17829 (set_attr "pent_pair" "pu")
17830 (set_attr "memory" "none")
17831 (set_attr "imm_disp" "false")
17832 (set_attr "mode" "SI")
17833 (set_attr "length_immediate" "0")])
17835 (define_insn "*movsicc_noc"
17836 [(set (match_operand:SI 0 "register_operand" "=r,r")
17837 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17838 [(reg FLAGS_REG) (const_int 0)])
17839 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17840 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17842 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17844 cmov%O2%C1\t{%2, %0|%0, %2}
17845 cmov%O2%c1\t{%3, %0|%0, %3}"
17846 [(set_attr "type" "icmov")
17847 (set_attr "mode" "SI")])
17849 (define_expand "movhicc"
17850 [(set (match_operand:HI 0 "register_operand" "")
17851 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17852 (match_operand:HI 2 "general_operand" "")
17853 (match_operand:HI 3 "general_operand" "")))]
17854 "TARGET_HIMODE_MATH"
17855 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17857 (define_insn "*movhicc_noc"
17858 [(set (match_operand:HI 0 "register_operand" "=r,r")
17859 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17860 [(reg FLAGS_REG) (const_int 0)])
17861 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17862 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17864 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17866 cmov%O2%C1\t{%2, %0|%0, %2}
17867 cmov%O2%c1\t{%3, %0|%0, %3}"
17868 [(set_attr "type" "icmov")
17869 (set_attr "mode" "HI")])
17871 (define_expand "movqicc"
17872 [(set (match_operand:QI 0 "register_operand" "")
17873 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17874 (match_operand:QI 2 "general_operand" "")
17875 (match_operand:QI 3 "general_operand" "")))]
17876 "TARGET_QIMODE_MATH"
17877 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17879 (define_insn_and_split "*movqicc_noc"
17880 [(set (match_operand:QI 0 "register_operand" "=r,r")
17881 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17882 [(match_operand 4 "flags_reg_operand" "")
17884 (match_operand:QI 2 "register_operand" "r,0")
17885 (match_operand:QI 3 "register_operand" "0,r")))]
17886 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17888 "&& reload_completed"
17889 [(set (match_dup 0)
17890 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17893 "operands[0] = gen_lowpart (SImode, operands[0]);
17894 operands[2] = gen_lowpart (SImode, operands[2]);
17895 operands[3] = gen_lowpart (SImode, operands[3]);"
17896 [(set_attr "type" "icmov")
17897 (set_attr "mode" "SI")])
17899 (define_expand "movsfcc"
17900 [(set (match_operand:SF 0 "register_operand" "")
17901 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17902 (match_operand:SF 2 "register_operand" "")
17903 (match_operand:SF 3 "register_operand" "")))]
17904 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17905 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17907 (define_insn "*movsfcc_1_387"
17908 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17909 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17910 [(reg FLAGS_REG) (const_int 0)])
17911 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17912 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17913 "TARGET_80387 && TARGET_CMOVE
17914 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17916 fcmov%F1\t{%2, %0|%0, %2}
17917 fcmov%f1\t{%3, %0|%0, %3}
17918 cmov%O2%C1\t{%2, %0|%0, %2}
17919 cmov%O2%c1\t{%3, %0|%0, %3}"
17920 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17921 (set_attr "mode" "SF,SF,SI,SI")])
17923 (define_expand "movdfcc"
17924 [(set (match_operand:DF 0 "register_operand" "")
17925 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17926 (match_operand:DF 2 "register_operand" "")
17927 (match_operand:DF 3 "register_operand" "")))]
17928 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17929 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17931 (define_insn "*movdfcc_1"
17932 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17933 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17934 [(reg FLAGS_REG) (const_int 0)])
17935 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17936 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17937 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17938 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17940 fcmov%F1\t{%2, %0|%0, %2}
17941 fcmov%f1\t{%3, %0|%0, %3}
17944 [(set_attr "type" "fcmov,fcmov,multi,multi")
17945 (set_attr "mode" "DF")])
17947 (define_insn "*movdfcc_1_rex64"
17948 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17949 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17950 [(reg FLAGS_REG) (const_int 0)])
17951 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17952 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17953 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17954 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17956 fcmov%F1\t{%2, %0|%0, %2}
17957 fcmov%f1\t{%3, %0|%0, %3}
17958 cmov%O2%C1\t{%2, %0|%0, %2}
17959 cmov%O2%c1\t{%3, %0|%0, %3}"
17960 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17961 (set_attr "mode" "DF")])
17964 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17965 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17966 [(match_operand 4 "flags_reg_operand" "")
17968 (match_operand:DF 2 "nonimmediate_operand" "")
17969 (match_operand:DF 3 "nonimmediate_operand" "")))]
17970 "!TARGET_64BIT && reload_completed"
17971 [(set (match_dup 2)
17972 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17976 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17979 "split_di (operands+2, 1, operands+5, operands+6);
17980 split_di (operands+3, 1, operands+7, operands+8);
17981 split_di (operands, 1, operands+2, operands+3);")
17983 (define_expand "movxfcc"
17984 [(set (match_operand:XF 0 "register_operand" "")
17985 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17986 (match_operand:XF 2 "register_operand" "")
17987 (match_operand:XF 3 "register_operand" "")))]
17988 "TARGET_80387 && TARGET_CMOVE"
17989 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17991 (define_insn "*movxfcc_1"
17992 [(set (match_operand:XF 0 "register_operand" "=f,f")
17993 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17994 [(reg FLAGS_REG) (const_int 0)])
17995 (match_operand:XF 2 "register_operand" "f,0")
17996 (match_operand:XF 3 "register_operand" "0,f")))]
17997 "TARGET_80387 && TARGET_CMOVE"
17999 fcmov%F1\t{%2, %0|%0, %2}
18000 fcmov%f1\t{%3, %0|%0, %3}"
18001 [(set_attr "type" "fcmov")
18002 (set_attr "mode" "XF")])
18004 ;; These versions of the min/max patterns are intentionally ignorant of
18005 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18006 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18007 ;; are undefined in this condition, we're certain this is correct.
18009 (define_insn "sminsf3"
18010 [(set (match_operand:SF 0 "register_operand" "=x")
18011 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18012 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18014 "minss\t{%2, %0|%0, %2}"
18015 [(set_attr "type" "sseadd")
18016 (set_attr "mode" "SF")])
18018 (define_insn "smaxsf3"
18019 [(set (match_operand:SF 0 "register_operand" "=x")
18020 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18021 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18023 "maxss\t{%2, %0|%0, %2}"
18024 [(set_attr "type" "sseadd")
18025 (set_attr "mode" "SF")])
18027 (define_insn "smindf3"
18028 [(set (match_operand:DF 0 "register_operand" "=x")
18029 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18030 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18031 "TARGET_SSE2 && TARGET_SSE_MATH"
18032 "minsd\t{%2, %0|%0, %2}"
18033 [(set_attr "type" "sseadd")
18034 (set_attr "mode" "DF")])
18036 (define_insn "smaxdf3"
18037 [(set (match_operand:DF 0 "register_operand" "=x")
18038 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18039 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18040 "TARGET_SSE2 && TARGET_SSE_MATH"
18041 "maxsd\t{%2, %0|%0, %2}"
18042 [(set_attr "type" "sseadd")
18043 (set_attr "mode" "DF")])
18045 ;; These versions of the min/max patterns implement exactly the operations
18046 ;; min = (op1 < op2 ? op1 : op2)
18047 ;; max = (!(op1 < op2) ? op1 : op2)
18048 ;; Their operands are not commutative, and thus they may be used in the
18049 ;; presence of -0.0 and NaN.
18051 (define_insn "*ieee_sminsf3"
18052 [(set (match_operand:SF 0 "register_operand" "=x")
18053 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18054 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18057 "minss\t{%2, %0|%0, %2}"
18058 [(set_attr "type" "sseadd")
18059 (set_attr "mode" "SF")])
18061 (define_insn "*ieee_smaxsf3"
18062 [(set (match_operand:SF 0 "register_operand" "=x")
18063 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18064 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18067 "maxss\t{%2, %0|%0, %2}"
18068 [(set_attr "type" "sseadd")
18069 (set_attr "mode" "SF")])
18071 (define_insn "*ieee_smindf3"
18072 [(set (match_operand:DF 0 "register_operand" "=x")
18073 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18074 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18076 "TARGET_SSE2 && TARGET_SSE_MATH"
18077 "minsd\t{%2, %0|%0, %2}"
18078 [(set_attr "type" "sseadd")
18079 (set_attr "mode" "DF")])
18081 (define_insn "*ieee_smaxdf3"
18082 [(set (match_operand:DF 0 "register_operand" "=x")
18083 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18084 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18086 "TARGET_SSE2 && TARGET_SSE_MATH"
18087 "maxsd\t{%2, %0|%0, %2}"
18088 [(set_attr "type" "sseadd")
18089 (set_attr "mode" "DF")])
18091 ;; Conditional addition patterns
18092 (define_expand "addqicc"
18093 [(match_operand:QI 0 "register_operand" "")
18094 (match_operand 1 "comparison_operator" "")
18095 (match_operand:QI 2 "register_operand" "")
18096 (match_operand:QI 3 "const_int_operand" "")]
18098 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18100 (define_expand "addhicc"
18101 [(match_operand:HI 0 "register_operand" "")
18102 (match_operand 1 "comparison_operator" "")
18103 (match_operand:HI 2 "register_operand" "")
18104 (match_operand:HI 3 "const_int_operand" "")]
18106 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18108 (define_expand "addsicc"
18109 [(match_operand:SI 0 "register_operand" "")
18110 (match_operand 1 "comparison_operator" "")
18111 (match_operand:SI 2 "register_operand" "")
18112 (match_operand:SI 3 "const_int_operand" "")]
18114 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18116 (define_expand "adddicc"
18117 [(match_operand:DI 0 "register_operand" "")
18118 (match_operand 1 "comparison_operator" "")
18119 (match_operand:DI 2 "register_operand" "")
18120 (match_operand:DI 3 "const_int_operand" "")]
18122 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18125 ;; Misc patterns (?)
18127 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18128 ;; Otherwise there will be nothing to keep
18130 ;; [(set (reg ebp) (reg esp))]
18131 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18132 ;; (clobber (eflags)]
18133 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18135 ;; in proper program order.
18136 (define_insn "pro_epilogue_adjust_stack_1"
18137 [(set (match_operand:SI 0 "register_operand" "=r,r")
18138 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18139 (match_operand:SI 2 "immediate_operand" "i,i")))
18140 (clobber (reg:CC FLAGS_REG))
18141 (clobber (mem:BLK (scratch)))]
18144 switch (get_attr_type (insn))
18147 return "mov{l}\t{%1, %0|%0, %1}";
18150 if (GET_CODE (operands[2]) == CONST_INT
18151 && (INTVAL (operands[2]) == 128
18152 || (INTVAL (operands[2]) < 0
18153 && INTVAL (operands[2]) != -128)))
18155 operands[2] = GEN_INT (-INTVAL (operands[2]));
18156 return "sub{l}\t{%2, %0|%0, %2}";
18158 return "add{l}\t{%2, %0|%0, %2}";
18161 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18162 return "lea{l}\t{%a2, %0|%0, %a2}";
18165 gcc_unreachable ();
18168 [(set (attr "type")
18169 (cond [(eq_attr "alternative" "0")
18170 (const_string "alu")
18171 (match_operand:SI 2 "const0_operand" "")
18172 (const_string "imov")
18174 (const_string "lea")))
18175 (set_attr "mode" "SI")])
18177 (define_insn "pro_epilogue_adjust_stack_rex64"
18178 [(set (match_operand:DI 0 "register_operand" "=r,r")
18179 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18180 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18181 (clobber (reg:CC FLAGS_REG))
18182 (clobber (mem:BLK (scratch)))]
18185 switch (get_attr_type (insn))
18188 return "mov{q}\t{%1, %0|%0, %1}";
18191 if (GET_CODE (operands[2]) == CONST_INT
18192 /* Avoid overflows. */
18193 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18194 && (INTVAL (operands[2]) == 128
18195 || (INTVAL (operands[2]) < 0
18196 && INTVAL (operands[2]) != -128)))
18198 operands[2] = GEN_INT (-INTVAL (operands[2]));
18199 return "sub{q}\t{%2, %0|%0, %2}";
18201 return "add{q}\t{%2, %0|%0, %2}";
18204 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18205 return "lea{q}\t{%a2, %0|%0, %a2}";
18208 gcc_unreachable ();
18211 [(set (attr "type")
18212 (cond [(eq_attr "alternative" "0")
18213 (const_string "alu")
18214 (match_operand:DI 2 "const0_operand" "")
18215 (const_string "imov")
18217 (const_string "lea")))
18218 (set_attr "mode" "DI")])
18220 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18221 [(set (match_operand:DI 0 "register_operand" "=r,r")
18222 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18223 (match_operand:DI 3 "immediate_operand" "i,i")))
18224 (use (match_operand:DI 2 "register_operand" "r,r"))
18225 (clobber (reg:CC FLAGS_REG))
18226 (clobber (mem:BLK (scratch)))]
18229 switch (get_attr_type (insn))
18232 return "add{q}\t{%2, %0|%0, %2}";
18235 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18236 return "lea{q}\t{%a2, %0|%0, %a2}";
18239 gcc_unreachable ();
18242 [(set_attr "type" "alu,lea")
18243 (set_attr "mode" "DI")])
18245 (define_expand "allocate_stack_worker"
18246 [(match_operand:SI 0 "register_operand" "")]
18247 "TARGET_STACK_PROBE"
18249 if (reload_completed)
18252 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18254 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18259 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18261 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18266 (define_insn "allocate_stack_worker_1"
18267 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18268 UNSPECV_STACK_PROBE)
18269 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18270 (clobber (match_scratch:SI 1 "=0"))
18271 (clobber (reg:CC FLAGS_REG))]
18272 "!TARGET_64BIT && TARGET_STACK_PROBE"
18274 [(set_attr "type" "multi")
18275 (set_attr "length" "5")])
18277 (define_expand "allocate_stack_worker_postreload"
18278 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18279 UNSPECV_STACK_PROBE)
18280 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18281 (clobber (match_dup 0))
18282 (clobber (reg:CC FLAGS_REG))])]
18286 (define_insn "allocate_stack_worker_rex64"
18287 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18288 UNSPECV_STACK_PROBE)
18289 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18290 (clobber (match_scratch:DI 1 "=0"))
18291 (clobber (reg:CC FLAGS_REG))]
18292 "TARGET_64BIT && TARGET_STACK_PROBE"
18294 [(set_attr "type" "multi")
18295 (set_attr "length" "5")])
18297 (define_expand "allocate_stack_worker_rex64_postreload"
18298 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18299 UNSPECV_STACK_PROBE)
18300 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18301 (clobber (match_dup 0))
18302 (clobber (reg:CC FLAGS_REG))])]
18306 (define_expand "allocate_stack"
18307 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18308 (minus:SI (reg:SI SP_REG)
18309 (match_operand:SI 1 "general_operand" "")))
18310 (clobber (reg:CC FLAGS_REG))])
18311 (parallel [(set (reg:SI SP_REG)
18312 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18313 (clobber (reg:CC FLAGS_REG))])]
18314 "TARGET_STACK_PROBE"
18316 #ifdef CHECK_STACK_LIMIT
18317 if (GET_CODE (operands[1]) == CONST_INT
18318 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18319 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18323 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18326 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18330 (define_expand "builtin_setjmp_receiver"
18331 [(label_ref (match_operand 0 "" ""))]
18332 "!TARGET_64BIT && flag_pic"
18334 emit_insn (gen_set_got (pic_offset_table_rtx));
18338 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18341 [(set (match_operand 0 "register_operand" "")
18342 (match_operator 3 "promotable_binary_operator"
18343 [(match_operand 1 "register_operand" "")
18344 (match_operand 2 "aligned_operand" "")]))
18345 (clobber (reg:CC FLAGS_REG))]
18346 "! TARGET_PARTIAL_REG_STALL && reload_completed
18347 && ((GET_MODE (operands[0]) == HImode
18348 && ((!optimize_size && !TARGET_FAST_PREFIX)
18349 || GET_CODE (operands[2]) != CONST_INT
18350 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18351 || (GET_MODE (operands[0]) == QImode
18352 && (TARGET_PROMOTE_QImode || optimize_size)))"
18353 [(parallel [(set (match_dup 0)
18354 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18355 (clobber (reg:CC FLAGS_REG))])]
18356 "operands[0] = gen_lowpart (SImode, operands[0]);
18357 operands[1] = gen_lowpart (SImode, operands[1]);
18358 if (GET_CODE (operands[3]) != ASHIFT)
18359 operands[2] = gen_lowpart (SImode, operands[2]);
18360 PUT_MODE (operands[3], SImode);")
18362 ; Promote the QImode tests, as i386 has encoding of the AND
18363 ; instruction with 32-bit sign-extended immediate and thus the
18364 ; instruction size is unchanged, except in the %eax case for
18365 ; which it is increased by one byte, hence the ! optimize_size.
18367 [(set (match_operand 0 "flags_reg_operand" "")
18368 (match_operator 2 "compare_operator"
18369 [(and (match_operand 3 "aligned_operand" "")
18370 (match_operand 4 "const_int_operand" ""))
18372 (set (match_operand 1 "register_operand" "")
18373 (and (match_dup 3) (match_dup 4)))]
18374 "! TARGET_PARTIAL_REG_STALL && reload_completed
18375 /* Ensure that the operand will remain sign-extended immediate. */
18376 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18378 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18379 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18380 [(parallel [(set (match_dup 0)
18381 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18384 (and:SI (match_dup 3) (match_dup 4)))])]
18387 = gen_int_mode (INTVAL (operands[4])
18388 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18389 operands[1] = gen_lowpart (SImode, operands[1]);
18390 operands[3] = gen_lowpart (SImode, operands[3]);
18393 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18394 ; the TEST instruction with 32-bit sign-extended immediate and thus
18395 ; the instruction size would at least double, which is not what we
18396 ; want even with ! optimize_size.
18398 [(set (match_operand 0 "flags_reg_operand" "")
18399 (match_operator 1 "compare_operator"
18400 [(and (match_operand:HI 2 "aligned_operand" "")
18401 (match_operand:HI 3 "const_int_operand" ""))
18403 "! TARGET_PARTIAL_REG_STALL && reload_completed
18404 /* Ensure that the operand will remain sign-extended immediate. */
18405 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18406 && ! TARGET_FAST_PREFIX
18407 && ! optimize_size"
18408 [(set (match_dup 0)
18409 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18413 = gen_int_mode (INTVAL (operands[3])
18414 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18415 operands[2] = gen_lowpart (SImode, operands[2]);
18419 [(set (match_operand 0 "register_operand" "")
18420 (neg (match_operand 1 "register_operand" "")))
18421 (clobber (reg:CC FLAGS_REG))]
18422 "! TARGET_PARTIAL_REG_STALL && reload_completed
18423 && (GET_MODE (operands[0]) == HImode
18424 || (GET_MODE (operands[0]) == QImode
18425 && (TARGET_PROMOTE_QImode || optimize_size)))"
18426 [(parallel [(set (match_dup 0)
18427 (neg:SI (match_dup 1)))
18428 (clobber (reg:CC FLAGS_REG))])]
18429 "operands[0] = gen_lowpart (SImode, operands[0]);
18430 operands[1] = gen_lowpart (SImode, operands[1]);")
18433 [(set (match_operand 0 "register_operand" "")
18434 (not (match_operand 1 "register_operand" "")))]
18435 "! TARGET_PARTIAL_REG_STALL && reload_completed
18436 && (GET_MODE (operands[0]) == HImode
18437 || (GET_MODE (operands[0]) == QImode
18438 && (TARGET_PROMOTE_QImode || optimize_size)))"
18439 [(set (match_dup 0)
18440 (not:SI (match_dup 1)))]
18441 "operands[0] = gen_lowpart (SImode, operands[0]);
18442 operands[1] = gen_lowpart (SImode, operands[1]);")
18445 [(set (match_operand 0 "register_operand" "")
18446 (if_then_else (match_operator 1 "comparison_operator"
18447 [(reg FLAGS_REG) (const_int 0)])
18448 (match_operand 2 "register_operand" "")
18449 (match_operand 3 "register_operand" "")))]
18450 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18451 && (GET_MODE (operands[0]) == HImode
18452 || (GET_MODE (operands[0]) == QImode
18453 && (TARGET_PROMOTE_QImode || optimize_size)))"
18454 [(set (match_dup 0)
18455 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18456 "operands[0] = gen_lowpart (SImode, operands[0]);
18457 operands[2] = gen_lowpart (SImode, operands[2]);
18458 operands[3] = gen_lowpart (SImode, operands[3]);")
18461 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18462 ;; transform a complex memory operation into two memory to register operations.
18464 ;; Don't push memory operands
18466 [(set (match_operand:SI 0 "push_operand" "")
18467 (match_operand:SI 1 "memory_operand" ""))
18468 (match_scratch:SI 2 "r")]
18469 "! optimize_size && ! TARGET_PUSH_MEMORY"
18470 [(set (match_dup 2) (match_dup 1))
18471 (set (match_dup 0) (match_dup 2))]
18475 [(set (match_operand:DI 0 "push_operand" "")
18476 (match_operand:DI 1 "memory_operand" ""))
18477 (match_scratch:DI 2 "r")]
18478 "! optimize_size && ! TARGET_PUSH_MEMORY"
18479 [(set (match_dup 2) (match_dup 1))
18480 (set (match_dup 0) (match_dup 2))]
18483 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18486 [(set (match_operand:SF 0 "push_operand" "")
18487 (match_operand:SF 1 "memory_operand" ""))
18488 (match_scratch:SF 2 "r")]
18489 "! optimize_size && ! TARGET_PUSH_MEMORY"
18490 [(set (match_dup 2) (match_dup 1))
18491 (set (match_dup 0) (match_dup 2))]
18495 [(set (match_operand:HI 0 "push_operand" "")
18496 (match_operand:HI 1 "memory_operand" ""))
18497 (match_scratch:HI 2 "r")]
18498 "! optimize_size && ! TARGET_PUSH_MEMORY"
18499 [(set (match_dup 2) (match_dup 1))
18500 (set (match_dup 0) (match_dup 2))]
18504 [(set (match_operand:QI 0 "push_operand" "")
18505 (match_operand:QI 1 "memory_operand" ""))
18506 (match_scratch:QI 2 "q")]
18507 "! optimize_size && ! TARGET_PUSH_MEMORY"
18508 [(set (match_dup 2) (match_dup 1))
18509 (set (match_dup 0) (match_dup 2))]
18512 ;; Don't move an immediate directly to memory when the instruction
18515 [(match_scratch:SI 1 "r")
18516 (set (match_operand:SI 0 "memory_operand" "")
18519 && ! TARGET_USE_MOV0
18520 && TARGET_SPLIT_LONG_MOVES
18521 && get_attr_length (insn) >= ix86_cost->large_insn
18522 && peep2_regno_dead_p (0, FLAGS_REG)"
18523 [(parallel [(set (match_dup 1) (const_int 0))
18524 (clobber (reg:CC FLAGS_REG))])
18525 (set (match_dup 0) (match_dup 1))]
18529 [(match_scratch:HI 1 "r")
18530 (set (match_operand:HI 0 "memory_operand" "")
18533 && ! TARGET_USE_MOV0
18534 && TARGET_SPLIT_LONG_MOVES
18535 && get_attr_length (insn) >= ix86_cost->large_insn
18536 && peep2_regno_dead_p (0, FLAGS_REG)"
18537 [(parallel [(set (match_dup 2) (const_int 0))
18538 (clobber (reg:CC FLAGS_REG))])
18539 (set (match_dup 0) (match_dup 1))]
18540 "operands[2] = gen_lowpart (SImode, operands[1]);")
18543 [(match_scratch:QI 1 "q")
18544 (set (match_operand:QI 0 "memory_operand" "")
18547 && ! TARGET_USE_MOV0
18548 && TARGET_SPLIT_LONG_MOVES
18549 && get_attr_length (insn) >= ix86_cost->large_insn
18550 && peep2_regno_dead_p (0, FLAGS_REG)"
18551 [(parallel [(set (match_dup 2) (const_int 0))
18552 (clobber (reg:CC FLAGS_REG))])
18553 (set (match_dup 0) (match_dup 1))]
18554 "operands[2] = gen_lowpart (SImode, operands[1]);")
18557 [(match_scratch:SI 2 "r")
18558 (set (match_operand:SI 0 "memory_operand" "")
18559 (match_operand:SI 1 "immediate_operand" ""))]
18561 && get_attr_length (insn) >= ix86_cost->large_insn
18562 && TARGET_SPLIT_LONG_MOVES"
18563 [(set (match_dup 2) (match_dup 1))
18564 (set (match_dup 0) (match_dup 2))]
18568 [(match_scratch:HI 2 "r")
18569 (set (match_operand:HI 0 "memory_operand" "")
18570 (match_operand:HI 1 "immediate_operand" ""))]
18571 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18572 && TARGET_SPLIT_LONG_MOVES"
18573 [(set (match_dup 2) (match_dup 1))
18574 (set (match_dup 0) (match_dup 2))]
18578 [(match_scratch:QI 2 "q")
18579 (set (match_operand:QI 0 "memory_operand" "")
18580 (match_operand:QI 1 "immediate_operand" ""))]
18581 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18582 && TARGET_SPLIT_LONG_MOVES"
18583 [(set (match_dup 2) (match_dup 1))
18584 (set (match_dup 0) (match_dup 2))]
18587 ;; Don't compare memory with zero, load and use a test instead.
18589 [(set (match_operand 0 "flags_reg_operand" "")
18590 (match_operator 1 "compare_operator"
18591 [(match_operand:SI 2 "memory_operand" "")
18593 (match_scratch:SI 3 "r")]
18594 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18595 [(set (match_dup 3) (match_dup 2))
18596 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18599 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18600 ;; Don't split NOTs with a displacement operand, because resulting XOR
18601 ;; will not be pairable anyway.
18603 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18604 ;; represented using a modRM byte. The XOR replacement is long decoded,
18605 ;; so this split helps here as well.
18607 ;; Note: Can't do this as a regular split because we can't get proper
18608 ;; lifetime information then.
18611 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18612 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18614 && peep2_regno_dead_p (0, FLAGS_REG)
18615 && ((TARGET_PENTIUM
18616 && (GET_CODE (operands[0]) != MEM
18617 || !memory_displacement_operand (operands[0], SImode)))
18618 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18619 [(parallel [(set (match_dup 0)
18620 (xor:SI (match_dup 1) (const_int -1)))
18621 (clobber (reg:CC FLAGS_REG))])]
18625 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18626 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18628 && peep2_regno_dead_p (0, FLAGS_REG)
18629 && ((TARGET_PENTIUM
18630 && (GET_CODE (operands[0]) != MEM
18631 || !memory_displacement_operand (operands[0], HImode)))
18632 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18633 [(parallel [(set (match_dup 0)
18634 (xor:HI (match_dup 1) (const_int -1)))
18635 (clobber (reg:CC FLAGS_REG))])]
18639 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18640 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18642 && peep2_regno_dead_p (0, FLAGS_REG)
18643 && ((TARGET_PENTIUM
18644 && (GET_CODE (operands[0]) != MEM
18645 || !memory_displacement_operand (operands[0], QImode)))
18646 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18647 [(parallel [(set (match_dup 0)
18648 (xor:QI (match_dup 1) (const_int -1)))
18649 (clobber (reg:CC FLAGS_REG))])]
18652 ;; Non pairable "test imm, reg" instructions can be translated to
18653 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18654 ;; byte opcode instead of two, have a short form for byte operands),
18655 ;; so do it for other CPUs as well. Given that the value was dead,
18656 ;; this should not create any new dependencies. Pass on the sub-word
18657 ;; versions if we're concerned about partial register stalls.
18660 [(set (match_operand 0 "flags_reg_operand" "")
18661 (match_operator 1 "compare_operator"
18662 [(and:SI (match_operand:SI 2 "register_operand" "")
18663 (match_operand:SI 3 "immediate_operand" ""))
18665 "ix86_match_ccmode (insn, CCNOmode)
18666 && (true_regnum (operands[2]) != 0
18667 || (GET_CODE (operands[3]) == CONST_INT
18668 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18669 && peep2_reg_dead_p (1, operands[2])"
18671 [(set (match_dup 0)
18672 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18675 (and:SI (match_dup 2) (match_dup 3)))])]
18678 ;; We don't need to handle HImode case, because it will be promoted to SImode
18679 ;; on ! TARGET_PARTIAL_REG_STALL
18682 [(set (match_operand 0 "flags_reg_operand" "")
18683 (match_operator 1 "compare_operator"
18684 [(and:QI (match_operand:QI 2 "register_operand" "")
18685 (match_operand:QI 3 "immediate_operand" ""))
18687 "! TARGET_PARTIAL_REG_STALL
18688 && ix86_match_ccmode (insn, CCNOmode)
18689 && true_regnum (operands[2]) != 0
18690 && peep2_reg_dead_p (1, operands[2])"
18692 [(set (match_dup 0)
18693 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18696 (and:QI (match_dup 2) (match_dup 3)))])]
18700 [(set (match_operand 0 "flags_reg_operand" "")
18701 (match_operator 1 "compare_operator"
18704 (match_operand 2 "ext_register_operand" "")
18707 (match_operand 3 "const_int_operand" ""))
18709 "! TARGET_PARTIAL_REG_STALL
18710 && ix86_match_ccmode (insn, CCNOmode)
18711 && true_regnum (operands[2]) != 0
18712 && peep2_reg_dead_p (1, operands[2])"
18713 [(parallel [(set (match_dup 0)
18722 (set (zero_extract:SI (match_dup 2)
18733 ;; Don't do logical operations with memory inputs.
18735 [(match_scratch:SI 2 "r")
18736 (parallel [(set (match_operand:SI 0 "register_operand" "")
18737 (match_operator:SI 3 "arith_or_logical_operator"
18739 (match_operand:SI 1 "memory_operand" "")]))
18740 (clobber (reg:CC FLAGS_REG))])]
18741 "! optimize_size && ! TARGET_READ_MODIFY"
18742 [(set (match_dup 2) (match_dup 1))
18743 (parallel [(set (match_dup 0)
18744 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18745 (clobber (reg:CC FLAGS_REG))])]
18749 [(match_scratch:SI 2 "r")
18750 (parallel [(set (match_operand:SI 0 "register_operand" "")
18751 (match_operator:SI 3 "arith_or_logical_operator"
18752 [(match_operand:SI 1 "memory_operand" "")
18754 (clobber (reg:CC FLAGS_REG))])]
18755 "! optimize_size && ! TARGET_READ_MODIFY"
18756 [(set (match_dup 2) (match_dup 1))
18757 (parallel [(set (match_dup 0)
18758 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18759 (clobber (reg:CC FLAGS_REG))])]
18762 ; Don't do logical operations with memory outputs
18764 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18765 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18766 ; the same decoder scheduling characteristics as the original.
18769 [(match_scratch:SI 2 "r")
18770 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18771 (match_operator:SI 3 "arith_or_logical_operator"
18773 (match_operand:SI 1 "nonmemory_operand" "")]))
18774 (clobber (reg:CC FLAGS_REG))])]
18775 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18776 [(set (match_dup 2) (match_dup 0))
18777 (parallel [(set (match_dup 2)
18778 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18779 (clobber (reg:CC FLAGS_REG))])
18780 (set (match_dup 0) (match_dup 2))]
18784 [(match_scratch:SI 2 "r")
18785 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18786 (match_operator:SI 3 "arith_or_logical_operator"
18787 [(match_operand:SI 1 "nonmemory_operand" "")
18789 (clobber (reg:CC FLAGS_REG))])]
18790 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18791 [(set (match_dup 2) (match_dup 0))
18792 (parallel [(set (match_dup 2)
18793 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18794 (clobber (reg:CC FLAGS_REG))])
18795 (set (match_dup 0) (match_dup 2))]
18798 ;; Attempt to always use XOR for zeroing registers.
18800 [(set (match_operand 0 "register_operand" "")
18801 (match_operand 1 "const0_operand" ""))]
18802 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18803 && (! TARGET_USE_MOV0 || optimize_size)
18804 && GENERAL_REG_P (operands[0])
18805 && peep2_regno_dead_p (0, FLAGS_REG)"
18806 [(parallel [(set (match_dup 0) (const_int 0))
18807 (clobber (reg:CC FLAGS_REG))])]
18809 operands[0] = gen_lowpart (word_mode, operands[0]);
18813 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18815 "(GET_MODE (operands[0]) == QImode
18816 || GET_MODE (operands[0]) == HImode)
18817 && (! TARGET_USE_MOV0 || optimize_size)
18818 && peep2_regno_dead_p (0, FLAGS_REG)"
18819 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18820 (clobber (reg:CC FLAGS_REG))])])
18822 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18824 [(set (match_operand 0 "register_operand" "")
18826 "(GET_MODE (operands[0]) == HImode
18827 || GET_MODE (operands[0]) == SImode
18828 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18829 && (optimize_size || TARGET_PENTIUM)
18830 && peep2_regno_dead_p (0, FLAGS_REG)"
18831 [(parallel [(set (match_dup 0) (const_int -1))
18832 (clobber (reg:CC FLAGS_REG))])]
18833 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18836 ;; Attempt to convert simple leas to adds. These can be created by
18839 [(set (match_operand:SI 0 "register_operand" "")
18840 (plus:SI (match_dup 0)
18841 (match_operand:SI 1 "nonmemory_operand" "")))]
18842 "peep2_regno_dead_p (0, FLAGS_REG)"
18843 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18844 (clobber (reg:CC FLAGS_REG))])]
18848 [(set (match_operand:SI 0 "register_operand" "")
18849 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18850 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18851 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18852 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18853 (clobber (reg:CC FLAGS_REG))])]
18854 "operands[2] = gen_lowpart (SImode, operands[2]);")
18857 [(set (match_operand:DI 0 "register_operand" "")
18858 (plus:DI (match_dup 0)
18859 (match_operand:DI 1 "x86_64_general_operand" "")))]
18860 "peep2_regno_dead_p (0, FLAGS_REG)"
18861 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18862 (clobber (reg:CC FLAGS_REG))])]
18866 [(set (match_operand:SI 0 "register_operand" "")
18867 (mult:SI (match_dup 0)
18868 (match_operand:SI 1 "const_int_operand" "")))]
18869 "exact_log2 (INTVAL (operands[1])) >= 0
18870 && peep2_regno_dead_p (0, FLAGS_REG)"
18871 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18872 (clobber (reg:CC FLAGS_REG))])]
18873 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18876 [(set (match_operand:DI 0 "register_operand" "")
18877 (mult:DI (match_dup 0)
18878 (match_operand:DI 1 "const_int_operand" "")))]
18879 "exact_log2 (INTVAL (operands[1])) >= 0
18880 && peep2_regno_dead_p (0, FLAGS_REG)"
18881 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18882 (clobber (reg:CC FLAGS_REG))])]
18883 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18886 [(set (match_operand:SI 0 "register_operand" "")
18887 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18888 (match_operand:DI 2 "const_int_operand" "")) 0))]
18889 "exact_log2 (INTVAL (operands[2])) >= 0
18890 && REGNO (operands[0]) == REGNO (operands[1])
18891 && peep2_regno_dead_p (0, FLAGS_REG)"
18892 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18893 (clobber (reg:CC FLAGS_REG))])]
18894 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18896 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18897 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18898 ;; many CPUs it is also faster, since special hardware to avoid esp
18899 ;; dependencies is present.
18901 ;; While some of these conversions may be done using splitters, we use peepholes
18902 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18904 ;; Convert prologue esp subtractions to push.
18905 ;; We need register to push. In order to keep verify_flow_info happy we have
18907 ;; - use scratch and clobber it in order to avoid dependencies
18908 ;; - use already live register
18909 ;; We can't use the second way right now, since there is no reliable way how to
18910 ;; verify that given register is live. First choice will also most likely in
18911 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18912 ;; call clobbered registers are dead. We may want to use base pointer as an
18913 ;; alternative when no register is available later.
18916 [(match_scratch:SI 0 "r")
18917 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18918 (clobber (reg:CC FLAGS_REG))
18919 (clobber (mem:BLK (scratch)))])]
18920 "optimize_size || !TARGET_SUB_ESP_4"
18921 [(clobber (match_dup 0))
18922 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18923 (clobber (mem:BLK (scratch)))])])
18926 [(match_scratch:SI 0 "r")
18927 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18928 (clobber (reg:CC FLAGS_REG))
18929 (clobber (mem:BLK (scratch)))])]
18930 "optimize_size || !TARGET_SUB_ESP_8"
18931 [(clobber (match_dup 0))
18932 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18933 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18934 (clobber (mem:BLK (scratch)))])])
18936 ;; Convert esp subtractions to push.
18938 [(match_scratch:SI 0 "r")
18939 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18940 (clobber (reg:CC FLAGS_REG))])]
18941 "optimize_size || !TARGET_SUB_ESP_4"
18942 [(clobber (match_dup 0))
18943 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18946 [(match_scratch:SI 0 "r")
18947 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18948 (clobber (reg:CC FLAGS_REG))])]
18949 "optimize_size || !TARGET_SUB_ESP_8"
18950 [(clobber (match_dup 0))
18951 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18952 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18954 ;; Convert epilogue deallocator to pop.
18956 [(match_scratch:SI 0 "r")
18957 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18958 (clobber (reg:CC FLAGS_REG))
18959 (clobber (mem:BLK (scratch)))])]
18960 "optimize_size || !TARGET_ADD_ESP_4"
18961 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18962 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18963 (clobber (mem:BLK (scratch)))])]
18966 ;; Two pops case is tricky, since pop causes dependency on destination register.
18967 ;; We use two registers if available.
18969 [(match_scratch:SI 0 "r")
18970 (match_scratch:SI 1 "r")
18971 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18972 (clobber (reg:CC FLAGS_REG))
18973 (clobber (mem:BLK (scratch)))])]
18974 "optimize_size || !TARGET_ADD_ESP_8"
18975 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18976 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18977 (clobber (mem:BLK (scratch)))])
18978 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18979 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18983 [(match_scratch:SI 0 "r")
18984 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18985 (clobber (reg:CC FLAGS_REG))
18986 (clobber (mem:BLK (scratch)))])]
18988 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18989 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18990 (clobber (mem:BLK (scratch)))])
18991 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18992 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18995 ;; Convert esp additions to pop.
18997 [(match_scratch:SI 0 "r")
18998 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18999 (clobber (reg:CC FLAGS_REG))])]
19001 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19002 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19005 ;; Two pops case is tricky, since pop causes dependency on destination register.
19006 ;; We use two registers if available.
19008 [(match_scratch:SI 0 "r")
19009 (match_scratch:SI 1 "r")
19010 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19011 (clobber (reg:CC FLAGS_REG))])]
19013 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19014 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19015 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19016 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19020 [(match_scratch:SI 0 "r")
19021 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19022 (clobber (reg:CC FLAGS_REG))])]
19024 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19025 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19026 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19027 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19030 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19031 ;; required and register dies. Similarly for 128 to plus -128.
19033 [(set (match_operand 0 "flags_reg_operand" "")
19034 (match_operator 1 "compare_operator"
19035 [(match_operand 2 "register_operand" "")
19036 (match_operand 3 "const_int_operand" "")]))]
19037 "(INTVAL (operands[3]) == -1
19038 || INTVAL (operands[3]) == 1
19039 || INTVAL (operands[3]) == 128)
19040 && ix86_match_ccmode (insn, CCGCmode)
19041 && peep2_reg_dead_p (1, operands[2])"
19042 [(parallel [(set (match_dup 0)
19043 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19044 (clobber (match_dup 2))])]
19048 [(match_scratch:DI 0 "r")
19049 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19050 (clobber (reg:CC FLAGS_REG))
19051 (clobber (mem:BLK (scratch)))])]
19052 "optimize_size || !TARGET_SUB_ESP_4"
19053 [(clobber (match_dup 0))
19054 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19055 (clobber (mem:BLK (scratch)))])])
19058 [(match_scratch:DI 0 "r")
19059 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19060 (clobber (reg:CC FLAGS_REG))
19061 (clobber (mem:BLK (scratch)))])]
19062 "optimize_size || !TARGET_SUB_ESP_8"
19063 [(clobber (match_dup 0))
19064 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19065 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19066 (clobber (mem:BLK (scratch)))])])
19068 ;; Convert esp subtractions to push.
19070 [(match_scratch:DI 0 "r")
19071 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19072 (clobber (reg:CC FLAGS_REG))])]
19073 "optimize_size || !TARGET_SUB_ESP_4"
19074 [(clobber (match_dup 0))
19075 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19078 [(match_scratch:DI 0 "r")
19079 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19080 (clobber (reg:CC FLAGS_REG))])]
19081 "optimize_size || !TARGET_SUB_ESP_8"
19082 [(clobber (match_dup 0))
19083 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19084 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19086 ;; Convert epilogue deallocator to pop.
19088 [(match_scratch:DI 0 "r")
19089 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19090 (clobber (reg:CC FLAGS_REG))
19091 (clobber (mem:BLK (scratch)))])]
19092 "optimize_size || !TARGET_ADD_ESP_4"
19093 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19094 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19095 (clobber (mem:BLK (scratch)))])]
19098 ;; Two pops case is tricky, since pop causes dependency on destination register.
19099 ;; We use two registers if available.
19101 [(match_scratch:DI 0 "r")
19102 (match_scratch:DI 1 "r")
19103 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19104 (clobber (reg:CC FLAGS_REG))
19105 (clobber (mem:BLK (scratch)))])]
19106 "optimize_size || !TARGET_ADD_ESP_8"
19107 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19108 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19109 (clobber (mem:BLK (scratch)))])
19110 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19111 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19115 [(match_scratch:DI 0 "r")
19116 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19117 (clobber (reg:CC FLAGS_REG))
19118 (clobber (mem:BLK (scratch)))])]
19120 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19121 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19122 (clobber (mem:BLK (scratch)))])
19123 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19124 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19127 ;; Convert esp additions to pop.
19129 [(match_scratch:DI 0 "r")
19130 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19131 (clobber (reg:CC FLAGS_REG))])]
19133 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19134 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19137 ;; Two pops case is tricky, since pop causes dependency on destination register.
19138 ;; We use two registers if available.
19140 [(match_scratch:DI 0 "r")
19141 (match_scratch:DI 1 "r")
19142 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19143 (clobber (reg:CC FLAGS_REG))])]
19145 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19146 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19147 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19148 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19152 [(match_scratch:DI 0 "r")
19153 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19154 (clobber (reg:CC FLAGS_REG))])]
19156 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19157 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19158 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19159 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19162 ;; Convert imul by three, five and nine into lea
19165 [(set (match_operand:SI 0 "register_operand" "")
19166 (mult:SI (match_operand:SI 1 "register_operand" "")
19167 (match_operand:SI 2 "const_int_operand" "")))
19168 (clobber (reg:CC FLAGS_REG))])]
19169 "INTVAL (operands[2]) == 3
19170 || INTVAL (operands[2]) == 5
19171 || INTVAL (operands[2]) == 9"
19172 [(set (match_dup 0)
19173 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19175 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19179 [(set (match_operand:SI 0 "register_operand" "")
19180 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19181 (match_operand:SI 2 "const_int_operand" "")))
19182 (clobber (reg:CC FLAGS_REG))])]
19184 && (INTVAL (operands[2]) == 3
19185 || INTVAL (operands[2]) == 5
19186 || INTVAL (operands[2]) == 9)"
19187 [(set (match_dup 0) (match_dup 1))
19189 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19191 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19195 [(set (match_operand:DI 0 "register_operand" "")
19196 (mult:DI (match_operand:DI 1 "register_operand" "")
19197 (match_operand:DI 2 "const_int_operand" "")))
19198 (clobber (reg:CC FLAGS_REG))])]
19200 && (INTVAL (operands[2]) == 3
19201 || INTVAL (operands[2]) == 5
19202 || INTVAL (operands[2]) == 9)"
19203 [(set (match_dup 0)
19204 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19206 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19210 [(set (match_operand:DI 0 "register_operand" "")
19211 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19212 (match_operand:DI 2 "const_int_operand" "")))
19213 (clobber (reg:CC FLAGS_REG))])]
19216 && (INTVAL (operands[2]) == 3
19217 || INTVAL (operands[2]) == 5
19218 || INTVAL (operands[2]) == 9)"
19219 [(set (match_dup 0) (match_dup 1))
19221 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19223 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19225 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19226 ;; imul $32bit_imm, reg, reg is direct decoded.
19228 [(match_scratch:DI 3 "r")
19229 (parallel [(set (match_operand:DI 0 "register_operand" "")
19230 (mult:DI (match_operand:DI 1 "memory_operand" "")
19231 (match_operand:DI 2 "immediate_operand" "")))
19232 (clobber (reg:CC FLAGS_REG))])]
19233 "TARGET_K8 && !optimize_size
19234 && (GET_CODE (operands[2]) != CONST_INT
19235 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19236 [(set (match_dup 3) (match_dup 1))
19237 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19238 (clobber (reg:CC FLAGS_REG))])]
19242 [(match_scratch:SI 3 "r")
19243 (parallel [(set (match_operand:SI 0 "register_operand" "")
19244 (mult:SI (match_operand:SI 1 "memory_operand" "")
19245 (match_operand:SI 2 "immediate_operand" "")))
19246 (clobber (reg:CC FLAGS_REG))])]
19247 "TARGET_K8 && !optimize_size
19248 && (GET_CODE (operands[2]) != CONST_INT
19249 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19250 [(set (match_dup 3) (match_dup 1))
19251 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19252 (clobber (reg:CC FLAGS_REG))])]
19256 [(match_scratch:SI 3 "r")
19257 (parallel [(set (match_operand:DI 0 "register_operand" "")
19259 (mult:SI (match_operand:SI 1 "memory_operand" "")
19260 (match_operand:SI 2 "immediate_operand" ""))))
19261 (clobber (reg:CC FLAGS_REG))])]
19262 "TARGET_K8 && !optimize_size
19263 && (GET_CODE (operands[2]) != CONST_INT
19264 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19265 [(set (match_dup 3) (match_dup 1))
19266 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19267 (clobber (reg:CC FLAGS_REG))])]
19270 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19271 ;; Convert it into imul reg, reg
19272 ;; It would be better to force assembler to encode instruction using long
19273 ;; immediate, but there is apparently no way to do so.
19275 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19276 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19277 (match_operand:DI 2 "const_int_operand" "")))
19278 (clobber (reg:CC FLAGS_REG))])
19279 (match_scratch:DI 3 "r")]
19280 "TARGET_K8 && !optimize_size
19281 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19282 [(set (match_dup 3) (match_dup 2))
19283 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19284 (clobber (reg:CC FLAGS_REG))])]
19286 if (!rtx_equal_p (operands[0], operands[1]))
19287 emit_move_insn (operands[0], operands[1]);
19291 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19292 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19293 (match_operand:SI 2 "const_int_operand" "")))
19294 (clobber (reg:CC FLAGS_REG))])
19295 (match_scratch:SI 3 "r")]
19296 "TARGET_K8 && !optimize_size
19297 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19298 [(set (match_dup 3) (match_dup 2))
19299 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19300 (clobber (reg:CC FLAGS_REG))])]
19302 if (!rtx_equal_p (operands[0], operands[1]))
19303 emit_move_insn (operands[0], operands[1]);
19307 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19308 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19309 (match_operand:HI 2 "immediate_operand" "")))
19310 (clobber (reg:CC FLAGS_REG))])
19311 (match_scratch:HI 3 "r")]
19312 "TARGET_K8 && !optimize_size"
19313 [(set (match_dup 3) (match_dup 2))
19314 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19315 (clobber (reg:CC FLAGS_REG))])]
19317 if (!rtx_equal_p (operands[0], operands[1]))
19318 emit_move_insn (operands[0], operands[1]);
19321 ;; Call-value patterns last so that the wildcard operand does not
19322 ;; disrupt insn-recog's switch tables.
19324 (define_insn "*call_value_pop_0"
19325 [(set (match_operand 0 "" "")
19326 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19327 (match_operand:SI 2 "" "")))
19328 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19329 (match_operand:SI 3 "immediate_operand" "")))]
19332 if (SIBLING_CALL_P (insn))
19335 return "call\t%P1";
19337 [(set_attr "type" "callv")])
19339 (define_insn "*call_value_pop_1"
19340 [(set (match_operand 0 "" "")
19341 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19342 (match_operand:SI 2 "" "")))
19343 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19344 (match_operand:SI 3 "immediate_operand" "i")))]
19347 if (constant_call_address_operand (operands[1], Pmode))
19349 if (SIBLING_CALL_P (insn))
19352 return "call\t%P1";
19354 if (SIBLING_CALL_P (insn))
19357 return "call\t%A1";
19359 [(set_attr "type" "callv")])
19361 (define_insn "*call_value_0"
19362 [(set (match_operand 0 "" "")
19363 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19364 (match_operand:SI 2 "" "")))]
19367 if (SIBLING_CALL_P (insn))
19370 return "call\t%P1";
19372 [(set_attr "type" "callv")])
19374 (define_insn "*call_value_0_rex64"
19375 [(set (match_operand 0 "" "")
19376 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19377 (match_operand:DI 2 "const_int_operand" "")))]
19380 if (SIBLING_CALL_P (insn))
19383 return "call\t%P1";
19385 [(set_attr "type" "callv")])
19387 (define_insn "*call_value_1"
19388 [(set (match_operand 0 "" "")
19389 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19390 (match_operand:SI 2 "" "")))]
19391 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19393 if (constant_call_address_operand (operands[1], Pmode))
19394 return "call\t%P1";
19395 return "call\t%A1";
19397 [(set_attr "type" "callv")])
19399 (define_insn "*sibcall_value_1"
19400 [(set (match_operand 0 "" "")
19401 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19402 (match_operand:SI 2 "" "")))]
19403 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19405 if (constant_call_address_operand (operands[1], Pmode))
19409 [(set_attr "type" "callv")])
19411 (define_insn "*call_value_1_rex64"
19412 [(set (match_operand 0 "" "")
19413 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19414 (match_operand:DI 2 "" "")))]
19415 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19417 if (constant_call_address_operand (operands[1], Pmode))
19418 return "call\t%P1";
19419 return "call\t%A1";
19421 [(set_attr "type" "callv")])
19423 (define_insn "*sibcall_value_1_rex64"
19424 [(set (match_operand 0 "" "")
19425 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19426 (match_operand:DI 2 "" "")))]
19427 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19429 [(set_attr "type" "callv")])
19431 (define_insn "*sibcall_value_1_rex64_v"
19432 [(set (match_operand 0 "" "")
19433 (call (mem:QI (reg:DI 40))
19434 (match_operand:DI 1 "" "")))]
19435 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19437 [(set_attr "type" "callv")])
19439 (define_insn "trap"
19440 [(trap_if (const_int 1) (const_int 5))]
19444 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19445 ;;; for the sake of bounds checking. By emitting bounds checks as
19446 ;;; conditional traps rather than as conditional jumps around
19447 ;;; unconditional traps we avoid introducing spurious basic-block
19448 ;;; boundaries and facilitate elimination of redundant checks. In
19449 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19452 ;;; FIXME: Static branch prediction rules for ix86 are such that
19453 ;;; forward conditional branches predict as untaken. As implemented
19454 ;;; below, pseudo conditional traps violate that rule. We should use
19455 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19456 ;;; section loaded at the end of the text segment and branch forward
19457 ;;; there on bounds-failure, and then jump back immediately (in case
19458 ;;; the system chooses to ignore bounds violations, or to report
19459 ;;; violations and continue execution).
19461 (define_expand "conditional_trap"
19462 [(trap_if (match_operator 0 "comparison_operator"
19463 [(match_dup 2) (const_int 0)])
19464 (match_operand 1 "const_int_operand" ""))]
19467 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19468 ix86_expand_compare (GET_CODE (operands[0]),
19474 (define_insn "*conditional_trap_1"
19475 [(trap_if (match_operator 0 "comparison_operator"
19476 [(reg FLAGS_REG) (const_int 0)])
19477 (match_operand 1 "const_int_operand" ""))]
19480 operands[2] = gen_label_rtx ();
19481 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19482 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19483 CODE_LABEL_NUMBER (operands[2]));
19487 (define_expand "sse_prologue_save"
19488 [(parallel [(set (match_operand:BLK 0 "" "")
19489 (unspec:BLK [(reg:DI 21)
19496 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19497 (use (match_operand:DI 1 "register_operand" ""))
19498 (use (match_operand:DI 2 "immediate_operand" ""))
19499 (use (label_ref:DI (match_operand 3 "" "")))])]
19503 (define_insn "*sse_prologue_save_insn"
19504 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19505 (match_operand:DI 4 "const_int_operand" "n")))
19506 (unspec:BLK [(reg:DI 21)
19513 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19514 (use (match_operand:DI 1 "register_operand" "r"))
19515 (use (match_operand:DI 2 "const_int_operand" "i"))
19516 (use (label_ref:DI (match_operand 3 "" "X")))]
19518 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19519 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19523 operands[0] = gen_rtx_MEM (Pmode,
19524 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19525 output_asm_insn (\"jmp\\t%A1\", operands);
19526 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19528 operands[4] = adjust_address (operands[0], DImode, i*16);
19529 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19530 PUT_MODE (operands[4], TImode);
19531 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19532 output_asm_insn (\"rex\", operands);
19533 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19535 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19536 CODE_LABEL_NUMBER (operands[3]));
19540 [(set_attr "type" "other")
19541 (set_attr "length_immediate" "0")
19542 (set_attr "length_address" "0")
19543 (set_attr "length" "135")
19544 (set_attr "memory" "store")
19545 (set_attr "modrm" "0")
19546 (set_attr "mode" "DI")])
19548 (define_expand "prefetch"
19549 [(prefetch (match_operand 0 "address_operand" "")
19550 (match_operand:SI 1 "const_int_operand" "")
19551 (match_operand:SI 2 "const_int_operand" ""))]
19552 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19554 int rw = INTVAL (operands[1]);
19555 int locality = INTVAL (operands[2]);
19557 gcc_assert (rw == 0 || rw == 1);
19558 gcc_assert (locality >= 0 && locality <= 3);
19559 gcc_assert (GET_MODE (operands[0]) == Pmode
19560 || GET_MODE (operands[0]) == VOIDmode);
19562 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19563 supported by SSE counterpart or the SSE prefetch is not available
19564 (K6 machines). Otherwise use SSE prefetch as it allows specifying
19566 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19567 operands[2] = GEN_INT (3);
19569 operands[1] = const0_rtx;
19572 (define_insn "*prefetch_sse"
19573 [(prefetch (match_operand:SI 0 "address_operand" "p")
19575 (match_operand:SI 1 "const_int_operand" ""))]
19576 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19578 static const char * const patterns[4] = {
19579 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19582 int locality = INTVAL (operands[1]);
19583 gcc_assert (locality >= 0 && locality <= 3);
19585 return patterns[locality];
19587 [(set_attr "type" "sse")
19588 (set_attr "memory" "none")])
19590 (define_insn "*prefetch_sse_rex"
19591 [(prefetch (match_operand:DI 0 "address_operand" "p")
19593 (match_operand:SI 1 "const_int_operand" ""))]
19594 "TARGET_PREFETCH_SSE && TARGET_64BIT"
19596 static const char * const patterns[4] = {
19597 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19600 int locality = INTVAL (operands[1]);
19601 gcc_assert (locality >= 0 && locality <= 3);
19603 return patterns[locality];
19605 [(set_attr "type" "sse")
19606 (set_attr "memory" "none")])
19608 (define_insn "*prefetch_3dnow"
19609 [(prefetch (match_operand:SI 0 "address_operand" "p")
19610 (match_operand:SI 1 "const_int_operand" "n")
19612 "TARGET_3DNOW && !TARGET_64BIT"
19614 if (INTVAL (operands[1]) == 0)
19615 return "prefetch\t%a0";
19617 return "prefetchw\t%a0";
19619 [(set_attr "type" "mmx")
19620 (set_attr "memory" "none")])
19622 (define_insn "*prefetch_3dnow_rex"
19623 [(prefetch (match_operand:DI 0 "address_operand" "p")
19624 (match_operand:SI 1 "const_int_operand" "n")
19626 "TARGET_3DNOW && TARGET_64BIT"
19628 if (INTVAL (operands[1]) == 0)
19629 return "prefetch\t%a0";
19631 return "prefetchw\t%a0";
19633 [(set_attr "type" "mmx")
19634 (set_attr "memory" "none")])
19638 (include "sync.md")