1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 30)
98 (UNSPEC_NOP 38) ; prevents combiner cleverness
109 ; Generic math support
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
125 (UNSPEC_FRNDINT_FLOOR 70)
126 (UNSPEC_FRNDINT_CEIL 71)
127 (UNSPEC_FRNDINT_TRUNC 72)
128 (UNSPEC_FRNDINT_MASK_PM 73)
129 (UNSPEC_FIST_FLOOR 74)
130 (UNSPEC_FIST_CEIL 75)
132 ; x87 Double output FP
133 (UNSPEC_SINCOS_COS 80)
134 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
149 (UNSPEC_SP_TLS_SET 102)
150 (UNSPEC_SP_TLS_TEST 103)
154 [(UNSPECV_BLOCKAGE 0)
155 (UNSPECV_STACK_PROBE 1)
164 (UNSPECV_CMPXCHG_1 10)
165 (UNSPECV_CMPXCHG_2 11)
170 ;; Registers by name.
179 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
182 ;; In C guard expressions, put expressions which may be compile-time
183 ;; constants first. This allows for better optimization. For
184 ;; example, write "TARGET_64BIT && reload_completed", not
185 ;; "reload_completed && TARGET_64BIT".
188 ;; Processor type. This attribute must exactly match the processor_type
189 ;; enumeration in i386.h.
190 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona,generic32,generic64"
191 (const (symbol_ref "ix86_tune")))
193 ;; A basic instruction type. Refinements due to arguments to be
194 ;; provided in other attributes.
197 alu,alu1,negnot,imov,imovx,lea,
198 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
199 icmp,test,ibr,setcc,icmov,
200 push,pop,call,callv,leave,
202 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
203 sselog,sselog1,sseiadd,sseishft,sseimul,
204 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
205 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
206 (const_string "other"))
208 ;; Main data type used by the insn
210 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
211 (const_string "unknown"))
213 ;; The CPU unit operations uses.
214 (define_attr "unit" "integer,i387,sse,mmx,unknown"
215 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
216 (const_string "i387")
217 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
218 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
220 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
222 (eq_attr "type" "other")
223 (const_string "unknown")]
224 (const_string "integer")))
226 ;; The (bounding maximum) length of an instruction immediate.
227 (define_attr "length_immediate" ""
228 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
230 (eq_attr "unit" "i387,sse,mmx")
232 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
234 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
235 (eq_attr "type" "imov,test")
236 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
237 (eq_attr "type" "call")
238 (if_then_else (match_operand 0 "constant_call_address_operand" "")
241 (eq_attr "type" "callv")
242 (if_then_else (match_operand 1 "constant_call_address_operand" "")
245 ;; We don't know the size before shorten_branches. Expect
246 ;; the instruction to fit for better scheduling.
247 (eq_attr "type" "ibr")
250 (symbol_ref "/* Update immediate_length and other attributes! */
251 gcc_unreachable (),1")))
253 ;; The (bounding maximum) length of an instruction address.
254 (define_attr "length_address" ""
255 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
257 (and (eq_attr "type" "call")
258 (match_operand 0 "constant_call_address_operand" ""))
260 (and (eq_attr "type" "callv")
261 (match_operand 1 "constant_call_address_operand" ""))
264 (symbol_ref "ix86_attr_length_address_default (insn)")))
266 ;; Set when length prefix is used.
267 (define_attr "prefix_data16" ""
268 (if_then_else (ior (eq_attr "mode" "HI")
269 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
273 ;; Set when string REP prefix is used.
274 (define_attr "prefix_rep" ""
275 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
279 ;; Set when 0f opcode prefix is used.
280 (define_attr "prefix_0f" ""
282 (ior (eq_attr "type" "imovx,setcc,icmov")
283 (eq_attr "unit" "sse,mmx"))
287 ;; Set when REX opcode prefix is used.
288 (define_attr "prefix_rex" ""
289 (cond [(and (eq_attr "mode" "DI")
290 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
292 (and (eq_attr "mode" "QI")
293 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
296 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
302 ;; Set when modrm byte is used.
303 (define_attr "modrm" ""
304 (cond [(eq_attr "type" "str,cld,leave")
306 (eq_attr "unit" "i387")
308 (and (eq_attr "type" "incdec")
309 (ior (match_operand:SI 1 "register_operand" "")
310 (match_operand:HI 1 "register_operand" "")))
312 (and (eq_attr "type" "push")
313 (not (match_operand 1 "memory_operand" "")))
315 (and (eq_attr "type" "pop")
316 (not (match_operand 0 "memory_operand" "")))
318 (and (eq_attr "type" "imov")
319 (ior (and (match_operand 0 "register_operand" "")
320 (match_operand 1 "immediate_operand" ""))
321 (ior (and (match_operand 0 "ax_reg_operand" "")
322 (match_operand 1 "memory_displacement_only_operand" ""))
323 (and (match_operand 0 "memory_displacement_only_operand" "")
324 (match_operand 1 "ax_reg_operand" "")))))
326 (and (eq_attr "type" "call")
327 (match_operand 0 "constant_call_address_operand" ""))
329 (and (eq_attr "type" "callv")
330 (match_operand 1 "constant_call_address_operand" ""))
335 ;; The (bounding maximum) length of an instruction in bytes.
336 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
337 ;; Later we may want to split them and compute proper length as for
339 (define_attr "length" ""
340 (cond [(eq_attr "type" "other,multi,fistp,frndint")
342 (eq_attr "type" "fcmp")
344 (eq_attr "unit" "i387")
346 (plus (attr "prefix_data16")
347 (attr "length_address")))]
348 (plus (plus (attr "modrm")
349 (plus (attr "prefix_0f")
350 (plus (attr "prefix_rex")
352 (plus (attr "prefix_rep")
353 (plus (attr "prefix_data16")
354 (plus (attr "length_immediate")
355 (attr "length_address")))))))
357 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
358 ;; `store' if there is a simple memory reference therein, or `unknown'
359 ;; if the instruction is complex.
361 (define_attr "memory" "none,load,store,both,unknown"
362 (cond [(eq_attr "type" "other,multi,str")
363 (const_string "unknown")
364 (eq_attr "type" "lea,fcmov,fpspc,cld")
365 (const_string "none")
366 (eq_attr "type" "fistp,leave")
367 (const_string "both")
368 (eq_attr "type" "frndint")
369 (const_string "load")
370 (eq_attr "type" "push")
371 (if_then_else (match_operand 1 "memory_operand" "")
372 (const_string "both")
373 (const_string "store"))
374 (eq_attr "type" "pop")
375 (if_then_else (match_operand 0 "memory_operand" "")
376 (const_string "both")
377 (const_string "load"))
378 (eq_attr "type" "setcc")
379 (if_then_else (match_operand 0 "memory_operand" "")
380 (const_string "store")
381 (const_string "none"))
382 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
383 (if_then_else (ior (match_operand 0 "memory_operand" "")
384 (match_operand 1 "memory_operand" ""))
385 (const_string "load")
386 (const_string "none"))
387 (eq_attr "type" "ibr")
388 (if_then_else (match_operand 0 "memory_operand" "")
389 (const_string "load")
390 (const_string "none"))
391 (eq_attr "type" "call")
392 (if_then_else (match_operand 0 "constant_call_address_operand" "")
393 (const_string "none")
394 (const_string "load"))
395 (eq_attr "type" "callv")
396 (if_then_else (match_operand 1 "constant_call_address_operand" "")
397 (const_string "none")
398 (const_string "load"))
399 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
400 (match_operand 1 "memory_operand" ""))
401 (const_string "both")
402 (and (match_operand 0 "memory_operand" "")
403 (match_operand 1 "memory_operand" ""))
404 (const_string "both")
405 (match_operand 0 "memory_operand" "")
406 (const_string "store")
407 (match_operand 1 "memory_operand" "")
408 (const_string "load")
410 "!alu1,negnot,ishift1,
411 imov,imovx,icmp,test,
413 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
414 mmx,mmxmov,mmxcmp,mmxcvt")
415 (match_operand 2 "memory_operand" ""))
416 (const_string "load")
417 (and (eq_attr "type" "icmov")
418 (match_operand 3 "memory_operand" ""))
419 (const_string "load")
421 (const_string "none")))
423 ;; Indicates if an instruction has both an immediate and a displacement.
425 (define_attr "imm_disp" "false,true,unknown"
426 (cond [(eq_attr "type" "other,multi")
427 (const_string "unknown")
428 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
429 (and (match_operand 0 "memory_displacement_operand" "")
430 (match_operand 1 "immediate_operand" "")))
431 (const_string "true")
432 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
433 (and (match_operand 0 "memory_displacement_operand" "")
434 (match_operand 2 "immediate_operand" "")))
435 (const_string "true")
437 (const_string "false")))
439 ;; Indicates if an FP operation has an integer source.
441 (define_attr "fp_int_src" "false,true"
442 (const_string "false"))
444 ;; Defines rounding mode of an FP operation.
446 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
447 (const_string "any"))
449 ;; Describe a user's asm statement.
450 (define_asm_attributes
451 [(set_attr "length" "128")
452 (set_attr "type" "multi")])
454 ;; All x87 floating point modes
455 (define_mode_macro X87MODEF [SF DF XF])
457 ;; All integer modes handled by x87 fisttp operator.
458 (define_mode_macro X87MODEI [HI SI DI])
460 ;; All integer modes handled by integer x87 operators.
461 (define_mode_macro X87MODEI12 [HI SI])
463 ;; All SSE floating point modes
464 (define_mode_macro SSEMODEF [SF DF])
466 ;; All integer modes handled by SSE cvtts?2si* operators.
467 (define_mode_macro SSEMODEI24 [SI DI])
470 ;; Scheduling descriptions
472 (include "pentium.md")
475 (include "athlon.md")
478 ;; Operand and operator predicates and constraints
480 (include "predicates.md")
481 (include "constraints.md")
484 ;; Compare instructions.
486 ;; All compare insns have expanders that save the operands away without
487 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
488 ;; after the cmp) will actually emit the cmpM.
490 (define_expand "cmpti"
491 [(set (reg:CC FLAGS_REG)
492 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
493 (match_operand:TI 1 "x86_64_general_operand" "")))]
496 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
497 operands[0] = force_reg (TImode, operands[0]);
498 ix86_compare_op0 = operands[0];
499 ix86_compare_op1 = operands[1];
503 (define_expand "cmpdi"
504 [(set (reg:CC FLAGS_REG)
505 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
506 (match_operand:DI 1 "x86_64_general_operand" "")))]
509 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
510 operands[0] = force_reg (DImode, operands[0]);
511 ix86_compare_op0 = operands[0];
512 ix86_compare_op1 = operands[1];
516 (define_expand "cmpsi"
517 [(set (reg:CC FLAGS_REG)
518 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
519 (match_operand:SI 1 "general_operand" "")))]
522 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
523 operands[0] = force_reg (SImode, operands[0]);
524 ix86_compare_op0 = operands[0];
525 ix86_compare_op1 = operands[1];
529 (define_expand "cmphi"
530 [(set (reg:CC FLAGS_REG)
531 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
532 (match_operand:HI 1 "general_operand" "")))]
535 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
536 operands[0] = force_reg (HImode, operands[0]);
537 ix86_compare_op0 = operands[0];
538 ix86_compare_op1 = operands[1];
542 (define_expand "cmpqi"
543 [(set (reg:CC FLAGS_REG)
544 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
545 (match_operand:QI 1 "general_operand" "")))]
548 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
549 operands[0] = force_reg (QImode, operands[0]);
550 ix86_compare_op0 = operands[0];
551 ix86_compare_op1 = operands[1];
555 (define_insn "cmpdi_ccno_1_rex64"
556 [(set (reg FLAGS_REG)
557 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
558 (match_operand:DI 1 "const0_operand" "n,n")))]
559 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
561 test{q}\t{%0, %0|%0, %0}
562 cmp{q}\t{%1, %0|%0, %1}"
563 [(set_attr "type" "test,icmp")
564 (set_attr "length_immediate" "0,1")
565 (set_attr "mode" "DI")])
567 (define_insn "*cmpdi_minus_1_rex64"
568 [(set (reg FLAGS_REG)
569 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
570 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
572 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
573 "cmp{q}\t{%1, %0|%0, %1}"
574 [(set_attr "type" "icmp")
575 (set_attr "mode" "DI")])
577 (define_expand "cmpdi_1_rex64"
578 [(set (reg:CC FLAGS_REG)
579 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
580 (match_operand:DI 1 "general_operand" "")))]
584 (define_insn "cmpdi_1_insn_rex64"
585 [(set (reg FLAGS_REG)
586 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
587 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
588 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
589 "cmp{q}\t{%1, %0|%0, %1}"
590 [(set_attr "type" "icmp")
591 (set_attr "mode" "DI")])
594 (define_insn "*cmpsi_ccno_1"
595 [(set (reg FLAGS_REG)
596 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
597 (match_operand:SI 1 "const0_operand" "n,n")))]
598 "ix86_match_ccmode (insn, CCNOmode)"
600 test{l}\t{%0, %0|%0, %0}
601 cmp{l}\t{%1, %0|%0, %1}"
602 [(set_attr "type" "test,icmp")
603 (set_attr "length_immediate" "0,1")
604 (set_attr "mode" "SI")])
606 (define_insn "*cmpsi_minus_1"
607 [(set (reg FLAGS_REG)
608 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
609 (match_operand:SI 1 "general_operand" "ri,mr"))
611 "ix86_match_ccmode (insn, CCGOCmode)"
612 "cmp{l}\t{%1, %0|%0, %1}"
613 [(set_attr "type" "icmp")
614 (set_attr "mode" "SI")])
616 (define_expand "cmpsi_1"
617 [(set (reg:CC FLAGS_REG)
618 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
619 (match_operand:SI 1 "general_operand" "ri,mr")))]
623 (define_insn "*cmpsi_1_insn"
624 [(set (reg FLAGS_REG)
625 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
626 (match_operand:SI 1 "general_operand" "ri,mr")))]
627 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
628 && ix86_match_ccmode (insn, CCmode)"
629 "cmp{l}\t{%1, %0|%0, %1}"
630 [(set_attr "type" "icmp")
631 (set_attr "mode" "SI")])
633 (define_insn "*cmphi_ccno_1"
634 [(set (reg FLAGS_REG)
635 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
636 (match_operand:HI 1 "const0_operand" "n,n")))]
637 "ix86_match_ccmode (insn, CCNOmode)"
639 test{w}\t{%0, %0|%0, %0}
640 cmp{w}\t{%1, %0|%0, %1}"
641 [(set_attr "type" "test,icmp")
642 (set_attr "length_immediate" "0,1")
643 (set_attr "mode" "HI")])
645 (define_insn "*cmphi_minus_1"
646 [(set (reg FLAGS_REG)
647 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
648 (match_operand:HI 1 "general_operand" "ri,mr"))
650 "ix86_match_ccmode (insn, CCGOCmode)"
651 "cmp{w}\t{%1, %0|%0, %1}"
652 [(set_attr "type" "icmp")
653 (set_attr "mode" "HI")])
655 (define_insn "*cmphi_1"
656 [(set (reg FLAGS_REG)
657 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
658 (match_operand:HI 1 "general_operand" "ri,mr")))]
659 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
660 && ix86_match_ccmode (insn, CCmode)"
661 "cmp{w}\t{%1, %0|%0, %1}"
662 [(set_attr "type" "icmp")
663 (set_attr "mode" "HI")])
665 (define_insn "*cmpqi_ccno_1"
666 [(set (reg FLAGS_REG)
667 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
668 (match_operand:QI 1 "const0_operand" "n,n")))]
669 "ix86_match_ccmode (insn, CCNOmode)"
671 test{b}\t{%0, %0|%0, %0}
672 cmp{b}\t{$0, %0|%0, 0}"
673 [(set_attr "type" "test,icmp")
674 (set_attr "length_immediate" "0,1")
675 (set_attr "mode" "QI")])
677 (define_insn "*cmpqi_1"
678 [(set (reg FLAGS_REG)
679 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
680 (match_operand:QI 1 "general_operand" "qi,mq")))]
681 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
682 && ix86_match_ccmode (insn, CCmode)"
683 "cmp{b}\t{%1, %0|%0, %1}"
684 [(set_attr "type" "icmp")
685 (set_attr "mode" "QI")])
687 (define_insn "*cmpqi_minus_1"
688 [(set (reg FLAGS_REG)
689 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
690 (match_operand:QI 1 "general_operand" "qi,mq"))
692 "ix86_match_ccmode (insn, CCGOCmode)"
693 "cmp{b}\t{%1, %0|%0, %1}"
694 [(set_attr "type" "icmp")
695 (set_attr "mode" "QI")])
697 (define_insn "*cmpqi_ext_1"
698 [(set (reg FLAGS_REG)
700 (match_operand:QI 0 "general_operand" "Qm")
703 (match_operand 1 "ext_register_operand" "Q")
706 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
707 "cmp{b}\t{%h1, %0|%0, %h1}"
708 [(set_attr "type" "icmp")
709 (set_attr "mode" "QI")])
711 (define_insn "*cmpqi_ext_1_rex64"
712 [(set (reg FLAGS_REG)
714 (match_operand:QI 0 "register_operand" "Q")
717 (match_operand 1 "ext_register_operand" "Q")
720 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721 "cmp{b}\t{%h1, %0|%0, %h1}"
722 [(set_attr "type" "icmp")
723 (set_attr "mode" "QI")])
725 (define_insn "*cmpqi_ext_2"
726 [(set (reg FLAGS_REG)
730 (match_operand 0 "ext_register_operand" "Q")
733 (match_operand:QI 1 "const0_operand" "n")))]
734 "ix86_match_ccmode (insn, CCNOmode)"
736 [(set_attr "type" "test")
737 (set_attr "length_immediate" "0")
738 (set_attr "mode" "QI")])
740 (define_expand "cmpqi_ext_3"
741 [(set (reg:CC FLAGS_REG)
745 (match_operand 0 "ext_register_operand" "")
748 (match_operand:QI 1 "general_operand" "")))]
752 (define_insn "cmpqi_ext_3_insn"
753 [(set (reg FLAGS_REG)
757 (match_operand 0 "ext_register_operand" "Q")
760 (match_operand:QI 1 "general_operand" "Qmn")))]
761 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
762 "cmp{b}\t{%1, %h0|%h0, %1}"
763 [(set_attr "type" "icmp")
764 (set_attr "mode" "QI")])
766 (define_insn "cmpqi_ext_3_insn_rex64"
767 [(set (reg FLAGS_REG)
771 (match_operand 0 "ext_register_operand" "Q")
774 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
775 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776 "cmp{b}\t{%1, %h0|%h0, %1}"
777 [(set_attr "type" "icmp")
778 (set_attr "mode" "QI")])
780 (define_insn "*cmpqi_ext_4"
781 [(set (reg FLAGS_REG)
785 (match_operand 0 "ext_register_operand" "Q")
790 (match_operand 1 "ext_register_operand" "Q")
793 "ix86_match_ccmode (insn, CCmode)"
794 "cmp{b}\t{%h1, %h0|%h0, %h1}"
795 [(set_attr "type" "icmp")
796 (set_attr "mode" "QI")])
798 ;; These implement float point compares.
799 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
800 ;; which would allow mix and match FP modes on the compares. Which is what
801 ;; the old patterns did, but with many more of them.
803 (define_expand "cmpxf"
804 [(set (reg:CC FLAGS_REG)
805 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
806 (match_operand:XF 1 "nonmemory_operand" "")))]
809 ix86_compare_op0 = operands[0];
810 ix86_compare_op1 = operands[1];
814 (define_expand "cmpdf"
815 [(set (reg:CC FLAGS_REG)
816 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
817 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
818 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
820 ix86_compare_op0 = operands[0];
821 ix86_compare_op1 = operands[1];
825 (define_expand "cmpsf"
826 [(set (reg:CC FLAGS_REG)
827 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
828 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
829 "TARGET_80387 || TARGET_SSE_MATH"
831 ix86_compare_op0 = operands[0];
832 ix86_compare_op1 = operands[1];
836 ;; FP compares, step 1:
837 ;; Set the FP condition codes.
839 ;; CCFPmode compare with exceptions
840 ;; CCFPUmode compare with no exceptions
842 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
843 ;; used to manage the reg stack popping would not be preserved.
845 (define_insn "*cmpfp_0"
846 [(set (match_operand:HI 0 "register_operand" "=a")
849 (match_operand 1 "register_operand" "f")
850 (match_operand 2 "const0_operand" "X"))]
853 && FLOAT_MODE_P (GET_MODE (operands[1]))
854 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
855 "* return output_fp_compare (insn, operands, 0, 0);"
856 [(set_attr "type" "multi")
857 (set_attr "unit" "i387")
859 (cond [(match_operand:SF 1 "" "")
861 (match_operand:DF 1 "" "")
864 (const_string "XF")))])
866 (define_insn "*cmpfp_sf"
867 [(set (match_operand:HI 0 "register_operand" "=a")
870 (match_operand:SF 1 "register_operand" "f")
871 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
874 "* return output_fp_compare (insn, operands, 0, 0);"
875 [(set_attr "type" "multi")
876 (set_attr "unit" "i387")
877 (set_attr "mode" "SF")])
879 (define_insn "*cmpfp_df"
880 [(set (match_operand:HI 0 "register_operand" "=a")
883 (match_operand:DF 1 "register_operand" "f")
884 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
887 "* return output_fp_compare (insn, operands, 0, 0);"
888 [(set_attr "type" "multi")
889 (set_attr "unit" "i387")
890 (set_attr "mode" "DF")])
892 (define_insn "*cmpfp_xf"
893 [(set (match_operand:HI 0 "register_operand" "=a")
896 (match_operand:XF 1 "register_operand" "f")
897 (match_operand:XF 2 "register_operand" "f"))]
900 "* return output_fp_compare (insn, operands, 0, 0);"
901 [(set_attr "type" "multi")
902 (set_attr "unit" "i387")
903 (set_attr "mode" "XF")])
905 (define_insn "*cmpfp_u"
906 [(set (match_operand:HI 0 "register_operand" "=a")
909 (match_operand 1 "register_operand" "f")
910 (match_operand 2 "register_operand" "f"))]
913 && FLOAT_MODE_P (GET_MODE (operands[1]))
914 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
915 "* return output_fp_compare (insn, operands, 0, 1);"
916 [(set_attr "type" "multi")
917 (set_attr "unit" "i387")
919 (cond [(match_operand:SF 1 "" "")
921 (match_operand:DF 1 "" "")
924 (const_string "XF")))])
926 (define_insn "*cmpfp_<mode>"
927 [(set (match_operand:HI 0 "register_operand" "=a")
930 (match_operand 1 "register_operand" "f")
931 (match_operator 3 "float_operator"
932 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
934 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
935 && FLOAT_MODE_P (GET_MODE (operands[1]))
936 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
937 "* return output_fp_compare (insn, operands, 0, 0);"
938 [(set_attr "type" "multi")
939 (set_attr "unit" "i387")
940 (set_attr "fp_int_src" "true")
941 (set_attr "mode" "<MODE>")])
943 ;; FP compares, step 2
944 ;; Move the fpsw to ax.
946 (define_insn "x86_fnstsw_1"
947 [(set (match_operand:HI 0 "register_operand" "=a")
948 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
951 [(set_attr "length" "2")
952 (set_attr "mode" "SI")
953 (set_attr "unit" "i387")])
955 ;; FP compares, step 3
956 ;; Get ax into flags, general case.
958 (define_insn "x86_sahf_1"
959 [(set (reg:CC FLAGS_REG)
960 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
963 [(set_attr "length" "1")
964 (set_attr "athlon_decode" "vector")
965 (set_attr "mode" "SI")])
967 ;; Pentium Pro can do steps 1 through 3 in one go.
969 (define_insn "*cmpfp_i_mixed"
970 [(set (reg:CCFP FLAGS_REG)
971 (compare:CCFP (match_operand 0 "register_operand" "f,x")
972 (match_operand 1 "nonimmediate_operand" "f,xm")))]
974 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
975 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
976 "* return output_fp_compare (insn, operands, 1, 0);"
977 [(set_attr "type" "fcmp,ssecomi")
979 (if_then_else (match_operand:SF 1 "" "")
981 (const_string "DF")))
982 (set_attr "athlon_decode" "vector")])
984 (define_insn "*cmpfp_i_sse"
985 [(set (reg:CCFP FLAGS_REG)
986 (compare:CCFP (match_operand 0 "register_operand" "x")
987 (match_operand 1 "nonimmediate_operand" "xm")))]
989 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991 "* return output_fp_compare (insn, operands, 1, 0);"
992 [(set_attr "type" "ssecomi")
994 (if_then_else (match_operand:SF 1 "" "")
996 (const_string "DF")))
997 (set_attr "athlon_decode" "vector")])
999 (define_insn "*cmpfp_i_i387"
1000 [(set (reg:CCFP FLAGS_REG)
1001 (compare:CCFP (match_operand 0 "register_operand" "f")
1002 (match_operand 1 "register_operand" "f")))]
1003 "TARGET_80387 && TARGET_CMOVE
1004 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1005 && FLOAT_MODE_P (GET_MODE (operands[0]))
1006 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007 "* return output_fp_compare (insn, operands, 1, 0);"
1008 [(set_attr "type" "fcmp")
1010 (cond [(match_operand:SF 1 "" "")
1012 (match_operand:DF 1 "" "")
1015 (const_string "XF")))
1016 (set_attr "athlon_decode" "vector")])
1018 (define_insn "*cmpfp_iu_mixed"
1019 [(set (reg:CCFPU FLAGS_REG)
1020 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1021 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1022 "TARGET_MIX_SSE_I387
1023 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025 "* return output_fp_compare (insn, operands, 1, 1);"
1026 [(set_attr "type" "fcmp,ssecomi")
1028 (if_then_else (match_operand:SF 1 "" "")
1030 (const_string "DF")))
1031 (set_attr "athlon_decode" "vector")])
1033 (define_insn "*cmpfp_iu_sse"
1034 [(set (reg:CCFPU FLAGS_REG)
1035 (compare:CCFPU (match_operand 0 "register_operand" "x")
1036 (match_operand 1 "nonimmediate_operand" "xm")))]
1038 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040 "* return output_fp_compare (insn, operands, 1, 1);"
1041 [(set_attr "type" "ssecomi")
1043 (if_then_else (match_operand:SF 1 "" "")
1045 (const_string "DF")))
1046 (set_attr "athlon_decode" "vector")])
1048 (define_insn "*cmpfp_iu_387"
1049 [(set (reg:CCFPU FLAGS_REG)
1050 (compare:CCFPU (match_operand 0 "register_operand" "f")
1051 (match_operand 1 "register_operand" "f")))]
1052 "TARGET_80387 && TARGET_CMOVE
1053 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1054 && FLOAT_MODE_P (GET_MODE (operands[0]))
1055 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1056 "* return output_fp_compare (insn, operands, 1, 1);"
1057 [(set_attr "type" "fcmp")
1059 (cond [(match_operand:SF 1 "" "")
1061 (match_operand:DF 1 "" "")
1064 (const_string "XF")))
1065 (set_attr "athlon_decode" "vector")])
1067 ;; Move instructions.
1069 ;; General case of fullword move.
1071 (define_expand "movsi"
1072 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1073 (match_operand:SI 1 "general_operand" ""))]
1075 "ix86_expand_move (SImode, operands); DONE;")
1077 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1080 ;; %%% We don't use a post-inc memory reference because x86 is not a
1081 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1082 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1083 ;; targets without our curiosities, and it is just as easy to represent
1084 ;; this differently.
1086 (define_insn "*pushsi2"
1087 [(set (match_operand:SI 0 "push_operand" "=<")
1088 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1091 [(set_attr "type" "push")
1092 (set_attr "mode" "SI")])
1094 ;; For 64BIT abi we always round up to 8 bytes.
1095 (define_insn "*pushsi2_rex64"
1096 [(set (match_operand:SI 0 "push_operand" "=X")
1097 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1100 [(set_attr "type" "push")
1101 (set_attr "mode" "SI")])
1103 (define_insn "*pushsi2_prologue"
1104 [(set (match_operand:SI 0 "push_operand" "=<")
1105 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1106 (clobber (mem:BLK (scratch)))]
1109 [(set_attr "type" "push")
1110 (set_attr "mode" "SI")])
1112 (define_insn "*popsi1_epilogue"
1113 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114 (mem:SI (reg:SI SP_REG)))
1115 (set (reg:SI SP_REG)
1116 (plus:SI (reg:SI SP_REG) (const_int 4)))
1117 (clobber (mem:BLK (scratch)))]
1120 [(set_attr "type" "pop")
1121 (set_attr "mode" "SI")])
1123 (define_insn "popsi1"
1124 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1125 (mem:SI (reg:SI SP_REG)))
1126 (set (reg:SI SP_REG)
1127 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1130 [(set_attr "type" "pop")
1131 (set_attr "mode" "SI")])
1133 (define_insn "*movsi_xor"
1134 [(set (match_operand:SI 0 "register_operand" "=r")
1135 (match_operand:SI 1 "const0_operand" "i"))
1136 (clobber (reg:CC FLAGS_REG))]
1137 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1138 "xor{l}\t{%0, %0|%0, %0}"
1139 [(set_attr "type" "alu1")
1140 (set_attr "mode" "SI")
1141 (set_attr "length_immediate" "0")])
1143 (define_insn "*movsi_or"
1144 [(set (match_operand:SI 0 "register_operand" "=r")
1145 (match_operand:SI 1 "immediate_operand" "i"))
1146 (clobber (reg:CC FLAGS_REG))]
1148 && operands[1] == constm1_rtx
1149 && (TARGET_PENTIUM || optimize_size)"
1151 operands[1] = constm1_rtx;
1152 return "or{l}\t{%1, %0|%0, %1}";
1154 [(set_attr "type" "alu1")
1155 (set_attr "mode" "SI")
1156 (set_attr "length_immediate" "1")])
1158 (define_insn "*movsi_1"
1159 [(set (match_operand:SI 0 "nonimmediate_operand"
1160 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1161 (match_operand:SI 1 "general_operand"
1162 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1163 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1165 switch (get_attr_type (insn))
1168 if (get_attr_mode (insn) == MODE_TI)
1169 return "pxor\t%0, %0";
1170 return "xorps\t%0, %0";
1173 switch (get_attr_mode (insn))
1176 return "movdqa\t{%1, %0|%0, %1}";
1178 return "movaps\t{%1, %0|%0, %1}";
1180 return "movd\t{%1, %0|%0, %1}";
1182 return "movss\t{%1, %0|%0, %1}";
1188 return "pxor\t%0, %0";
1191 if (get_attr_mode (insn) == MODE_DI)
1192 return "movq\t{%1, %0|%0, %1}";
1193 return "movd\t{%1, %0|%0, %1}";
1196 return "lea{l}\t{%1, %0|%0, %1}";
1199 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1200 return "mov{l}\t{%1, %0|%0, %1}";
1204 (cond [(eq_attr "alternative" "2")
1205 (const_string "mmxadd")
1206 (eq_attr "alternative" "3,4,5")
1207 (const_string "mmxmov")
1208 (eq_attr "alternative" "6")
1209 (const_string "sselog1")
1210 (eq_attr "alternative" "7,8,9,10,11")
1211 (const_string "ssemov")
1212 (match_operand:DI 1 "pic_32bit_operand" "")
1213 (const_string "lea")
1215 (const_string "imov")))
1217 (cond [(eq_attr "alternative" "2,3")
1219 (eq_attr "alternative" "6,7")
1221 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1222 (const_string "V4SF")
1223 (const_string "TI"))
1224 (and (eq_attr "alternative" "8,9,10,11")
1225 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1228 (const_string "SI")))])
1230 ;; Stores and loads of ax to arbitrary constant address.
1231 ;; We fake an second form of instruction to force reload to load address
1232 ;; into register when rax is not available
1233 (define_insn "*movabssi_1_rex64"
1234 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1235 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1236 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1238 movabs{l}\t{%1, %P0|%P0, %1}
1239 mov{l}\t{%1, %a0|%a0, %1}"
1240 [(set_attr "type" "imov")
1241 (set_attr "modrm" "0,*")
1242 (set_attr "length_address" "8,0")
1243 (set_attr "length_immediate" "0,*")
1244 (set_attr "memory" "store")
1245 (set_attr "mode" "SI")])
1247 (define_insn "*movabssi_2_rex64"
1248 [(set (match_operand:SI 0 "register_operand" "=a,r")
1249 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1250 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1252 movabs{l}\t{%P1, %0|%0, %P1}
1253 mov{l}\t{%a1, %0|%0, %a1}"
1254 [(set_attr "type" "imov")
1255 (set_attr "modrm" "0,*")
1256 (set_attr "length_address" "8,0")
1257 (set_attr "length_immediate" "0")
1258 (set_attr "memory" "load")
1259 (set_attr "mode" "SI")])
1261 (define_insn "*swapsi"
1262 [(set (match_operand:SI 0 "register_operand" "+r")
1263 (match_operand:SI 1 "register_operand" "+r"))
1268 [(set_attr "type" "imov")
1269 (set_attr "mode" "SI")
1270 (set_attr "pent_pair" "np")
1271 (set_attr "athlon_decode" "vector")])
1273 (define_expand "movhi"
1274 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1275 (match_operand:HI 1 "general_operand" ""))]
1277 "ix86_expand_move (HImode, operands); DONE;")
1279 (define_insn "*pushhi2"
1280 [(set (match_operand:HI 0 "push_operand" "=X")
1281 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1284 [(set_attr "type" "push")
1285 (set_attr "mode" "SI")])
1287 ;; For 64BIT abi we always round up to 8 bytes.
1288 (define_insn "*pushhi2_rex64"
1289 [(set (match_operand:HI 0 "push_operand" "=X")
1290 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1293 [(set_attr "type" "push")
1294 (set_attr "mode" "DI")])
1296 (define_insn "*movhi_1"
1297 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1298 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1299 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1301 switch (get_attr_type (insn))
1304 /* movzwl is faster than movw on p2 due to partial word stalls,
1305 though not as fast as an aligned movl. */
1306 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1308 if (get_attr_mode (insn) == MODE_SI)
1309 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1311 return "mov{w}\t{%1, %0|%0, %1}";
1315 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1316 (const_string "imov")
1317 (and (eq_attr "alternative" "0")
1318 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1320 (eq (symbol_ref "TARGET_HIMODE_MATH")
1322 (const_string "imov")
1323 (and (eq_attr "alternative" "1,2")
1324 (match_operand:HI 1 "aligned_operand" ""))
1325 (const_string "imov")
1326 (and (ne (symbol_ref "TARGET_MOVX")
1328 (eq_attr "alternative" "0,2"))
1329 (const_string "imovx")
1331 (const_string "imov")))
1333 (cond [(eq_attr "type" "imovx")
1335 (and (eq_attr "alternative" "1,2")
1336 (match_operand:HI 1 "aligned_operand" ""))
1338 (and (eq_attr "alternative" "0")
1339 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1341 (eq (symbol_ref "TARGET_HIMODE_MATH")
1345 (const_string "HI")))])
1347 ;; Stores and loads of ax to arbitrary constant address.
1348 ;; We fake an second form of instruction to force reload to load address
1349 ;; into register when rax is not available
1350 (define_insn "*movabshi_1_rex64"
1351 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1352 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1353 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1355 movabs{w}\t{%1, %P0|%P0, %1}
1356 mov{w}\t{%1, %a0|%a0, %1}"
1357 [(set_attr "type" "imov")
1358 (set_attr "modrm" "0,*")
1359 (set_attr "length_address" "8,0")
1360 (set_attr "length_immediate" "0,*")
1361 (set_attr "memory" "store")
1362 (set_attr "mode" "HI")])
1364 (define_insn "*movabshi_2_rex64"
1365 [(set (match_operand:HI 0 "register_operand" "=a,r")
1366 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1367 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1369 movabs{w}\t{%P1, %0|%0, %P1}
1370 mov{w}\t{%a1, %0|%0, %a1}"
1371 [(set_attr "type" "imov")
1372 (set_attr "modrm" "0,*")
1373 (set_attr "length_address" "8,0")
1374 (set_attr "length_immediate" "0")
1375 (set_attr "memory" "load")
1376 (set_attr "mode" "HI")])
1378 (define_insn "*swaphi_1"
1379 [(set (match_operand:HI 0 "register_operand" "+r")
1380 (match_operand:HI 1 "register_operand" "+r"))
1383 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1385 [(set_attr "type" "imov")
1386 (set_attr "mode" "SI")
1387 (set_attr "pent_pair" "np")
1388 (set_attr "athlon_decode" "vector")])
1390 (define_insn "*swaphi_2"
1391 [(set (match_operand:HI 0 "register_operand" "+r")
1392 (match_operand:HI 1 "register_operand" "+r"))
1395 "TARGET_PARTIAL_REG_STALL"
1397 [(set_attr "type" "imov")
1398 (set_attr "mode" "HI")
1399 (set_attr "pent_pair" "np")
1400 (set_attr "athlon_decode" "vector")])
1402 (define_expand "movstricthi"
1403 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1404 (match_operand:HI 1 "general_operand" ""))]
1405 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1407 /* Don't generate memory->memory moves, go through a register */
1408 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1409 operands[1] = force_reg (HImode, operands[1]);
1412 (define_insn "*movstricthi_1"
1413 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1414 (match_operand:HI 1 "general_operand" "rn,m"))]
1415 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1416 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1417 "mov{w}\t{%1, %0|%0, %1}"
1418 [(set_attr "type" "imov")
1419 (set_attr "mode" "HI")])
1421 (define_insn "*movstricthi_xor"
1422 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1423 (match_operand:HI 1 "const0_operand" "i"))
1424 (clobber (reg:CC FLAGS_REG))]
1426 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1427 "xor{w}\t{%0, %0|%0, %0}"
1428 [(set_attr "type" "alu1")
1429 (set_attr "mode" "HI")
1430 (set_attr "length_immediate" "0")])
1432 (define_expand "movqi"
1433 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1434 (match_operand:QI 1 "general_operand" ""))]
1436 "ix86_expand_move (QImode, operands); DONE;")
1438 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1439 ;; "push a byte". But actually we use pushl, which has the effect
1440 ;; of rounding the amount pushed up to a word.
1442 (define_insn "*pushqi2"
1443 [(set (match_operand:QI 0 "push_operand" "=X")
1444 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1447 [(set_attr "type" "push")
1448 (set_attr "mode" "SI")])
1450 ;; For 64BIT abi we always round up to 8 bytes.
1451 (define_insn "*pushqi2_rex64"
1452 [(set (match_operand:QI 0 "push_operand" "=X")
1453 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1456 [(set_attr "type" "push")
1457 (set_attr "mode" "DI")])
1459 ;; Situation is quite tricky about when to choose full sized (SImode) move
1460 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1461 ;; partial register dependency machines (such as AMD Athlon), where QImode
1462 ;; moves issue extra dependency and for partial register stalls machines
1463 ;; that don't use QImode patterns (and QImode move cause stall on the next
1466 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1467 ;; register stall machines with, where we use QImode instructions, since
1468 ;; partial register stall can be caused there. Then we use movzx.
1469 (define_insn "*movqi_1"
1470 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1471 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1472 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1474 switch (get_attr_type (insn))
1477 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1478 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1480 if (get_attr_mode (insn) == MODE_SI)
1481 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1483 return "mov{b}\t{%1, %0|%0, %1}";
1487 (cond [(and (eq_attr "alternative" "5")
1488 (not (match_operand:QI 1 "aligned_operand" "")))
1489 (const_string "imovx")
1490 (ne (symbol_ref "optimize_size") (const_int 0))
1491 (const_string "imov")
1492 (and (eq_attr "alternative" "3")
1493 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1495 (eq (symbol_ref "TARGET_QIMODE_MATH")
1497 (const_string "imov")
1498 (eq_attr "alternative" "3,5")
1499 (const_string "imovx")
1500 (and (ne (symbol_ref "TARGET_MOVX")
1502 (eq_attr "alternative" "2"))
1503 (const_string "imovx")
1505 (const_string "imov")))
1507 (cond [(eq_attr "alternative" "3,4,5")
1509 (eq_attr "alternative" "6")
1511 (eq_attr "type" "imovx")
1513 (and (eq_attr "type" "imov")
1514 (and (eq_attr "alternative" "0,1")
1515 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1517 (and (eq (symbol_ref "optimize_size")
1519 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1522 ;; Avoid partial register stalls when not using QImode arithmetic
1523 (and (eq_attr "type" "imov")
1524 (and (eq_attr "alternative" "0,1")
1525 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1527 (eq (symbol_ref "TARGET_QIMODE_MATH")
1531 (const_string "QI")))])
1533 (define_expand "reload_outqi"
1534 [(parallel [(match_operand:QI 0 "" "=m")
1535 (match_operand:QI 1 "register_operand" "r")
1536 (match_operand:QI 2 "register_operand" "=&q")])]
1540 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1542 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1543 if (! q_regs_operand (op1, QImode))
1545 emit_insn (gen_movqi (op2, op1));
1548 emit_insn (gen_movqi (op0, op1));
1552 (define_insn "*swapqi_1"
1553 [(set (match_operand:QI 0 "register_operand" "+r")
1554 (match_operand:QI 1 "register_operand" "+r"))
1557 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1559 [(set_attr "type" "imov")
1560 (set_attr "mode" "SI")
1561 (set_attr "pent_pair" "np")
1562 (set_attr "athlon_decode" "vector")])
1564 (define_insn "*swapqi_2"
1565 [(set (match_operand:QI 0 "register_operand" "+q")
1566 (match_operand:QI 1 "register_operand" "+q"))
1569 "TARGET_PARTIAL_REG_STALL"
1571 [(set_attr "type" "imov")
1572 (set_attr "mode" "QI")
1573 (set_attr "pent_pair" "np")
1574 (set_attr "athlon_decode" "vector")])
1576 (define_expand "movstrictqi"
1577 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1578 (match_operand:QI 1 "general_operand" ""))]
1579 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1581 /* Don't generate memory->memory moves, go through a register. */
1582 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1583 operands[1] = force_reg (QImode, operands[1]);
1586 (define_insn "*movstrictqi_1"
1587 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1588 (match_operand:QI 1 "general_operand" "*qn,m"))]
1589 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1590 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1591 "mov{b}\t{%1, %0|%0, %1}"
1592 [(set_attr "type" "imov")
1593 (set_attr "mode" "QI")])
1595 (define_insn "*movstrictqi_xor"
1596 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1597 (match_operand:QI 1 "const0_operand" "i"))
1598 (clobber (reg:CC FLAGS_REG))]
1599 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1600 "xor{b}\t{%0, %0|%0, %0}"
1601 [(set_attr "type" "alu1")
1602 (set_attr "mode" "QI")
1603 (set_attr "length_immediate" "0")])
1605 (define_insn "*movsi_extv_1"
1606 [(set (match_operand:SI 0 "register_operand" "=R")
1607 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1611 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1612 [(set_attr "type" "imovx")
1613 (set_attr "mode" "SI")])
1615 (define_insn "*movhi_extv_1"
1616 [(set (match_operand:HI 0 "register_operand" "=R")
1617 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1621 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1622 [(set_attr "type" "imovx")
1623 (set_attr "mode" "SI")])
1625 (define_insn "*movqi_extv_1"
1626 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1627 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1632 switch (get_attr_type (insn))
1635 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1637 return "mov{b}\t{%h1, %0|%0, %h1}";
1641 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1642 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1643 (ne (symbol_ref "TARGET_MOVX")
1645 (const_string "imovx")
1646 (const_string "imov")))
1648 (if_then_else (eq_attr "type" "imovx")
1650 (const_string "QI")))])
1652 (define_insn "*movqi_extv_1_rex64"
1653 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1654 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1659 switch (get_attr_type (insn))
1662 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1664 return "mov{b}\t{%h1, %0|%0, %h1}";
1668 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1669 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1670 (ne (symbol_ref "TARGET_MOVX")
1672 (const_string "imovx")
1673 (const_string "imov")))
1675 (if_then_else (eq_attr "type" "imovx")
1677 (const_string "QI")))])
1679 ;; Stores and loads of ax to arbitrary constant address.
1680 ;; We fake an second form of instruction to force reload to load address
1681 ;; into register when rax is not available
1682 (define_insn "*movabsqi_1_rex64"
1683 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1684 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1685 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1687 movabs{b}\t{%1, %P0|%P0, %1}
1688 mov{b}\t{%1, %a0|%a0, %1}"
1689 [(set_attr "type" "imov")
1690 (set_attr "modrm" "0,*")
1691 (set_attr "length_address" "8,0")
1692 (set_attr "length_immediate" "0,*")
1693 (set_attr "memory" "store")
1694 (set_attr "mode" "QI")])
1696 (define_insn "*movabsqi_2_rex64"
1697 [(set (match_operand:QI 0 "register_operand" "=a,r")
1698 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1699 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1701 movabs{b}\t{%P1, %0|%0, %P1}
1702 mov{b}\t{%a1, %0|%0, %a1}"
1703 [(set_attr "type" "imov")
1704 (set_attr "modrm" "0,*")
1705 (set_attr "length_address" "8,0")
1706 (set_attr "length_immediate" "0")
1707 (set_attr "memory" "load")
1708 (set_attr "mode" "QI")])
1710 (define_insn "*movdi_extzv_1"
1711 [(set (match_operand:DI 0 "register_operand" "=R")
1712 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1716 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1717 [(set_attr "type" "imovx")
1718 (set_attr "mode" "DI")])
1720 (define_insn "*movsi_extzv_1"
1721 [(set (match_operand:SI 0 "register_operand" "=R")
1722 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1726 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1727 [(set_attr "type" "imovx")
1728 (set_attr "mode" "SI")])
1730 (define_insn "*movqi_extzv_2"
1731 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1732 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1737 switch (get_attr_type (insn))
1740 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1742 return "mov{b}\t{%h1, %0|%0, %h1}";
1746 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1747 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1748 (ne (symbol_ref "TARGET_MOVX")
1750 (const_string "imovx")
1751 (const_string "imov")))
1753 (if_then_else (eq_attr "type" "imovx")
1755 (const_string "QI")))])
1757 (define_insn "*movqi_extzv_2_rex64"
1758 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1759 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1764 switch (get_attr_type (insn))
1767 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1769 return "mov{b}\t{%h1, %0|%0, %h1}";
1773 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774 (ne (symbol_ref "TARGET_MOVX")
1776 (const_string "imovx")
1777 (const_string "imov")))
1779 (if_then_else (eq_attr "type" "imovx")
1781 (const_string "QI")))])
1783 (define_insn "movsi_insv_1"
1784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1787 (match_operand:SI 1 "general_operand" "Qmn"))]
1789 "mov{b}\t{%b1, %h0|%h0, %b1}"
1790 [(set_attr "type" "imov")
1791 (set_attr "mode" "QI")])
1793 (define_insn "movdi_insv_1_rex64"
1794 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1797 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1799 "mov{b}\t{%b1, %h0|%h0, %b1}"
1800 [(set_attr "type" "imov")
1801 (set_attr "mode" "QI")])
1803 (define_insn "*movqi_insv_2"
1804 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1807 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1810 "mov{b}\t{%h1, %h0|%h0, %h1}"
1811 [(set_attr "type" "imov")
1812 (set_attr "mode" "QI")])
1814 (define_expand "movdi"
1815 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1816 (match_operand:DI 1 "general_operand" ""))]
1818 "ix86_expand_move (DImode, operands); DONE;")
1820 (define_insn "*pushdi"
1821 [(set (match_operand:DI 0 "push_operand" "=<")
1822 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1826 (define_insn "*pushdi2_rex64"
1827 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1828 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1833 [(set_attr "type" "push,multi")
1834 (set_attr "mode" "DI")])
1836 ;; Convert impossible pushes of immediate to existing instructions.
1837 ;; First try to get scratch register and go through it. In case this
1838 ;; fails, push sign extended lower part first and then overwrite
1839 ;; upper part by 32bit move.
1841 [(match_scratch:DI 2 "r")
1842 (set (match_operand:DI 0 "push_operand" "")
1843 (match_operand:DI 1 "immediate_operand" ""))]
1844 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1845 && !x86_64_immediate_operand (operands[1], DImode)"
1846 [(set (match_dup 2) (match_dup 1))
1847 (set (match_dup 0) (match_dup 2))]
1850 ;; We need to define this as both peepholer and splitter for case
1851 ;; peephole2 pass is not run.
1852 ;; "&& 1" is needed to keep it from matching the previous pattern.
1854 [(set (match_operand:DI 0 "push_operand" "")
1855 (match_operand:DI 1 "immediate_operand" ""))]
1856 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1857 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1858 [(set (match_dup 0) (match_dup 1))
1859 (set (match_dup 2) (match_dup 3))]
1860 "split_di (operands + 1, 1, operands + 2, operands + 3);
1861 operands[1] = gen_lowpart (DImode, operands[2]);
1862 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1867 [(set (match_operand:DI 0 "push_operand" "")
1868 (match_operand:DI 1 "immediate_operand" ""))]
1869 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1870 ? flow2_completed : reload_completed)
1871 && !symbolic_operand (operands[1], DImode)
1872 && !x86_64_immediate_operand (operands[1], DImode)"
1873 [(set (match_dup 0) (match_dup 1))
1874 (set (match_dup 2) (match_dup 3))]
1875 "split_di (operands + 1, 1, operands + 2, operands + 3);
1876 operands[1] = gen_lowpart (DImode, operands[2]);
1877 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1881 (define_insn "*pushdi2_prologue_rex64"
1882 [(set (match_operand:DI 0 "push_operand" "=<")
1883 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1884 (clobber (mem:BLK (scratch)))]
1887 [(set_attr "type" "push")
1888 (set_attr "mode" "DI")])
1890 (define_insn "*popdi1_epilogue_rex64"
1891 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1892 (mem:DI (reg:DI SP_REG)))
1893 (set (reg:DI SP_REG)
1894 (plus:DI (reg:DI SP_REG) (const_int 8)))
1895 (clobber (mem:BLK (scratch)))]
1898 [(set_attr "type" "pop")
1899 (set_attr "mode" "DI")])
1901 (define_insn "popdi1"
1902 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1903 (mem:DI (reg:DI SP_REG)))
1904 (set (reg:DI SP_REG)
1905 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1908 [(set_attr "type" "pop")
1909 (set_attr "mode" "DI")])
1911 (define_insn "*movdi_xor_rex64"
1912 [(set (match_operand:DI 0 "register_operand" "=r")
1913 (match_operand:DI 1 "const0_operand" "i"))
1914 (clobber (reg:CC FLAGS_REG))]
1915 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1916 && reload_completed"
1917 "xor{l}\t{%k0, %k0|%k0, %k0}"
1918 [(set_attr "type" "alu1")
1919 (set_attr "mode" "SI")
1920 (set_attr "length_immediate" "0")])
1922 (define_insn "*movdi_or_rex64"
1923 [(set (match_operand:DI 0 "register_operand" "=r")
1924 (match_operand:DI 1 "const_int_operand" "i"))
1925 (clobber (reg:CC FLAGS_REG))]
1926 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1928 && operands[1] == constm1_rtx"
1930 operands[1] = constm1_rtx;
1931 return "or{q}\t{%1, %0|%0, %1}";
1933 [(set_attr "type" "alu1")
1934 (set_attr "mode" "DI")
1935 (set_attr "length_immediate" "1")])
1937 (define_insn "*movdi_2"
1938 [(set (match_operand:DI 0 "nonimmediate_operand"
1939 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1940 (match_operand:DI 1 "general_operand"
1941 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1942 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1947 movq\t{%1, %0|%0, %1}
1948 movq\t{%1, %0|%0, %1}
1950 movq\t{%1, %0|%0, %1}
1951 movdqa\t{%1, %0|%0, %1}
1952 movq\t{%1, %0|%0, %1}
1954 movlps\t{%1, %0|%0, %1}
1955 movaps\t{%1, %0|%0, %1}
1956 movlps\t{%1, %0|%0, %1}"
1957 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1958 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1961 [(set (match_operand:DI 0 "push_operand" "")
1962 (match_operand:DI 1 "general_operand" ""))]
1963 "!TARGET_64BIT && reload_completed
1964 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1966 "ix86_split_long_move (operands); DONE;")
1968 ;; %%% This multiword shite has got to go.
1970 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1971 (match_operand:DI 1 "general_operand" ""))]
1972 "!TARGET_64BIT && reload_completed
1973 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1974 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1976 "ix86_split_long_move (operands); DONE;")
1978 (define_insn "*movdi_1_rex64"
1979 [(set (match_operand:DI 0 "nonimmediate_operand"
1980 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1981 (match_operand:DI 1 "general_operand"
1982 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1983 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1985 switch (get_attr_type (insn))
1988 if (which_alternative == 13)
1989 return "movq2dq\t{%1, %0|%0, %1}";
1991 return "movdq2q\t{%1, %0|%0, %1}";
1993 if (get_attr_mode (insn) == MODE_TI)
1994 return "movdqa\t{%1, %0|%0, %1}";
1997 /* Moves from and into integer register is done using movd opcode with
1999 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2000 return "movd\t{%1, %0|%0, %1}";
2001 return "movq\t{%1, %0|%0, %1}";
2004 return "pxor\t%0, %0";
2008 return "lea{q}\t{%a1, %0|%0, %a1}";
2010 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2011 if (get_attr_mode (insn) == MODE_SI)
2012 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2013 else if (which_alternative == 2)
2014 return "movabs{q}\t{%1, %0|%0, %1}";
2016 return "mov{q}\t{%1, %0|%0, %1}";
2020 (cond [(eq_attr "alternative" "5")
2021 (const_string "mmxadd")
2022 (eq_attr "alternative" "6,7,8")
2023 (const_string "mmxmov")
2024 (eq_attr "alternative" "9")
2025 (const_string "sselog1")
2026 (eq_attr "alternative" "10,11,12")
2027 (const_string "ssemov")
2028 (eq_attr "alternative" "13,14")
2029 (const_string "ssecvt")
2030 (eq_attr "alternative" "4")
2031 (const_string "multi")
2032 (match_operand:DI 1 "pic_32bit_operand" "")
2033 (const_string "lea")
2035 (const_string "imov")))
2036 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2037 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2038 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2040 ;; Stores and loads of ax to arbitrary constant address.
2041 ;; We fake an second form of instruction to force reload to load address
2042 ;; into register when rax is not available
2043 (define_insn "*movabsdi_1_rex64"
2044 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2045 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2046 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2048 movabs{q}\t{%1, %P0|%P0, %1}
2049 mov{q}\t{%1, %a0|%a0, %1}"
2050 [(set_attr "type" "imov")
2051 (set_attr "modrm" "0,*")
2052 (set_attr "length_address" "8,0")
2053 (set_attr "length_immediate" "0,*")
2054 (set_attr "memory" "store")
2055 (set_attr "mode" "DI")])
2057 (define_insn "*movabsdi_2_rex64"
2058 [(set (match_operand:DI 0 "register_operand" "=a,r")
2059 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2060 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2062 movabs{q}\t{%P1, %0|%0, %P1}
2063 mov{q}\t{%a1, %0|%0, %a1}"
2064 [(set_attr "type" "imov")
2065 (set_attr "modrm" "0,*")
2066 (set_attr "length_address" "8,0")
2067 (set_attr "length_immediate" "0")
2068 (set_attr "memory" "load")
2069 (set_attr "mode" "DI")])
2071 ;; Convert impossible stores of immediate to existing instructions.
2072 ;; First try to get scratch register and go through it. In case this
2073 ;; fails, move by 32bit parts.
2075 [(match_scratch:DI 2 "r")
2076 (set (match_operand:DI 0 "memory_operand" "")
2077 (match_operand:DI 1 "immediate_operand" ""))]
2078 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2079 && !x86_64_immediate_operand (operands[1], DImode)"
2080 [(set (match_dup 2) (match_dup 1))
2081 (set (match_dup 0) (match_dup 2))]
2084 ;; We need to define this as both peepholer and splitter for case
2085 ;; peephole2 pass is not run.
2086 ;; "&& 1" is needed to keep it from matching the previous pattern.
2088 [(set (match_operand:DI 0 "memory_operand" "")
2089 (match_operand:DI 1 "immediate_operand" ""))]
2090 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2091 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2092 [(set (match_dup 2) (match_dup 3))
2093 (set (match_dup 4) (match_dup 5))]
2094 "split_di (operands, 2, operands + 2, operands + 4);")
2097 [(set (match_operand:DI 0 "memory_operand" "")
2098 (match_operand:DI 1 "immediate_operand" ""))]
2099 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2100 ? flow2_completed : reload_completed)
2101 && !symbolic_operand (operands[1], DImode)
2102 && !x86_64_immediate_operand (operands[1], DImode)"
2103 [(set (match_dup 2) (match_dup 3))
2104 (set (match_dup 4) (match_dup 5))]
2105 "split_di (operands, 2, operands + 2, operands + 4);")
2107 (define_insn "*swapdi_rex64"
2108 [(set (match_operand:DI 0 "register_operand" "+r")
2109 (match_operand:DI 1 "register_operand" "+r"))
2114 [(set_attr "type" "imov")
2115 (set_attr "mode" "DI")
2116 (set_attr "pent_pair" "np")
2117 (set_attr "athlon_decode" "vector")])
2119 (define_expand "movti"
2120 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2121 (match_operand:TI 1 "nonimmediate_operand" ""))]
2122 "TARGET_SSE || TARGET_64BIT"
2125 ix86_expand_move (TImode, operands);
2127 ix86_expand_vector_move (TImode, operands);
2131 (define_insn "*movti_internal"
2132 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2133 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2134 "TARGET_SSE && !TARGET_64BIT
2135 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2137 switch (which_alternative)
2140 if (get_attr_mode (insn) == MODE_V4SF)
2141 return "xorps\t%0, %0";
2143 return "pxor\t%0, %0";
2146 if (get_attr_mode (insn) == MODE_V4SF)
2147 return "movaps\t{%1, %0|%0, %1}";
2149 return "movdqa\t{%1, %0|%0, %1}";
2154 [(set_attr "type" "sselog1,ssemov,ssemov")
2156 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2157 (ne (symbol_ref "optimize_size") (const_int 0)))
2158 (const_string "V4SF")
2159 (and (eq_attr "alternative" "2")
2160 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2162 (const_string "V4SF")]
2163 (const_string "TI")))])
2165 (define_insn "*movti_rex64"
2166 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2167 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2169 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2171 switch (which_alternative)
2177 if (get_attr_mode (insn) == MODE_V4SF)
2178 return "xorps\t%0, %0";
2180 return "pxor\t%0, %0";
2183 if (get_attr_mode (insn) == MODE_V4SF)
2184 return "movaps\t{%1, %0|%0, %1}";
2186 return "movdqa\t{%1, %0|%0, %1}";
2191 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2193 (cond [(eq_attr "alternative" "2,3")
2195 (ne (symbol_ref "optimize_size")
2197 (const_string "V4SF")
2198 (const_string "TI"))
2199 (eq_attr "alternative" "4")
2201 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2203 (ne (symbol_ref "optimize_size")
2205 (const_string "V4SF")
2206 (const_string "TI"))]
2207 (const_string "DI")))])
2210 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2211 (match_operand:TI 1 "general_operand" ""))]
2212 "reload_completed && !SSE_REG_P (operands[0])
2213 && !SSE_REG_P (operands[1])"
2215 "ix86_split_long_move (operands); DONE;")
2217 (define_expand "movsf"
2218 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2219 (match_operand:SF 1 "general_operand" ""))]
2221 "ix86_expand_move (SFmode, operands); DONE;")
2223 (define_insn "*pushsf"
2224 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2225 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2228 /* Anything else should be already split before reg-stack. */
2229 gcc_assert (which_alternative == 1);
2230 return "push{l}\t%1";
2232 [(set_attr "type" "multi,push,multi")
2233 (set_attr "unit" "i387,*,*")
2234 (set_attr "mode" "SF,SI,SF")])
2236 (define_insn "*pushsf_rex64"
2237 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2238 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2241 /* Anything else should be already split before reg-stack. */
2242 gcc_assert (which_alternative == 1);
2243 return "push{q}\t%q1";
2245 [(set_attr "type" "multi,push,multi")
2246 (set_attr "unit" "i387,*,*")
2247 (set_attr "mode" "SF,DI,SF")])
2250 [(set (match_operand:SF 0 "push_operand" "")
2251 (match_operand:SF 1 "memory_operand" ""))]
2253 && GET_CODE (operands[1]) == MEM
2254 && constant_pool_reference_p (operands[1])"
2257 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2260 ;; %%% Kill this when call knows how to work this out.
2262 [(set (match_operand:SF 0 "push_operand" "")
2263 (match_operand:SF 1 "any_fp_register_operand" ""))]
2265 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2266 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2269 [(set (match_operand:SF 0 "push_operand" "")
2270 (match_operand:SF 1 "any_fp_register_operand" ""))]
2272 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2273 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2275 (define_insn "*movsf_1"
2276 [(set (match_operand:SF 0 "nonimmediate_operand"
2277 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2278 (match_operand:SF 1 "general_operand"
2279 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2280 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2281 && (reload_in_progress || reload_completed
2282 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2283 || GET_CODE (operands[1]) != CONST_DOUBLE
2284 || memory_operand (operands[0], SFmode))"
2286 switch (which_alternative)
2289 return output_387_reg_move (insn, operands);
2292 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2293 return "fstp%z0\t%y0";
2295 return "fst%z0\t%y0";
2298 return standard_80387_constant_opcode (operands[1]);
2302 return "mov{l}\t{%1, %0|%0, %1}";
2304 if (get_attr_mode (insn) == MODE_TI)
2305 return "pxor\t%0, %0";
2307 return "xorps\t%0, %0";
2309 if (get_attr_mode (insn) == MODE_V4SF)
2310 return "movaps\t{%1, %0|%0, %1}";
2312 return "movss\t{%1, %0|%0, %1}";
2315 return "movss\t{%1, %0|%0, %1}";
2319 return "movd\t{%1, %0|%0, %1}";
2322 return "movq\t{%1, %0|%0, %1}";
2328 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2330 (cond [(eq_attr "alternative" "3,4,9,10")
2332 (eq_attr "alternative" "5")
2334 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2336 (ne (symbol_ref "TARGET_SSE2")
2338 (eq (symbol_ref "optimize_size")
2341 (const_string "V4SF"))
2342 /* For architectures resolving dependencies on
2343 whole SSE registers use APS move to break dependency
2344 chains, otherwise use short move to avoid extra work.
2346 Do the same for architectures resolving dependencies on
2347 the parts. While in DF mode it is better to always handle
2348 just register parts, the SF mode is different due to lack
2349 of instructions to load just part of the register. It is
2350 better to maintain the whole registers in single format
2351 to avoid problems on using packed logical operations. */
2352 (eq_attr "alternative" "6")
2354 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2356 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2358 (const_string "V4SF")
2359 (const_string "SF"))
2360 (eq_attr "alternative" "11")
2361 (const_string "DI")]
2362 (const_string "SF")))])
2364 (define_insn "*swapsf"
2365 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2366 (match_operand:SF 1 "fp_register_operand" "+f"))
2369 "reload_completed || TARGET_80387"
2371 if (STACK_TOP_P (operands[0]))
2376 [(set_attr "type" "fxch")
2377 (set_attr "mode" "SF")])
2379 (define_expand "movdf"
2380 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2381 (match_operand:DF 1 "general_operand" ""))]
2383 "ix86_expand_move (DFmode, operands); DONE;")
2385 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2386 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2387 ;; On the average, pushdf using integers can be still shorter. Allow this
2388 ;; pattern for optimize_size too.
2390 (define_insn "*pushdf_nointeger"
2391 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2392 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2393 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2395 /* This insn should be already split before reg-stack. */
2398 [(set_attr "type" "multi")
2399 (set_attr "unit" "i387,*,*,*")
2400 (set_attr "mode" "DF,SI,SI,DF")])
2402 (define_insn "*pushdf_integer"
2403 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2404 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2405 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2407 /* This insn should be already split before reg-stack. */
2410 [(set_attr "type" "multi")
2411 (set_attr "unit" "i387,*,*")
2412 (set_attr "mode" "DF,SI,DF")])
2414 ;; %%% Kill this when call knows how to work this out.
2416 [(set (match_operand:DF 0 "push_operand" "")
2417 (match_operand:DF 1 "any_fp_register_operand" ""))]
2418 "!TARGET_64BIT && reload_completed"
2419 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2420 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2424 [(set (match_operand:DF 0 "push_operand" "")
2425 (match_operand:DF 1 "any_fp_register_operand" ""))]
2426 "TARGET_64BIT && reload_completed"
2427 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2428 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2432 [(set (match_operand:DF 0 "push_operand" "")
2433 (match_operand:DF 1 "general_operand" ""))]
2436 "ix86_split_long_move (operands); DONE;")
2438 ;; Moving is usually shorter when only FP registers are used. This separate
2439 ;; movdf pattern avoids the use of integer registers for FP operations
2440 ;; when optimizing for size.
2442 (define_insn "*movdf_nointeger"
2443 [(set (match_operand:DF 0 "nonimmediate_operand"
2444 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2445 (match_operand:DF 1 "general_operand"
2446 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2447 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2448 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2449 && (reload_in_progress || reload_completed
2450 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2451 || GET_CODE (operands[1]) != CONST_DOUBLE
2452 || memory_operand (operands[0], DFmode))"
2454 switch (which_alternative)
2457 return output_387_reg_move (insn, operands);
2460 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2461 return "fstp%z0\t%y0";
2463 return "fst%z0\t%y0";
2466 return standard_80387_constant_opcode (operands[1]);
2472 switch (get_attr_mode (insn))
2475 return "xorps\t%0, %0";
2477 return "xorpd\t%0, %0";
2479 return "pxor\t%0, %0";
2486 switch (get_attr_mode (insn))
2489 return "movaps\t{%1, %0|%0, %1}";
2491 return "movapd\t{%1, %0|%0, %1}";
2493 return "movdqa\t{%1, %0|%0, %1}";
2495 return "movq\t{%1, %0|%0, %1}";
2497 return "movsd\t{%1, %0|%0, %1}";
2499 return "movlpd\t{%1, %0|%0, %1}";
2501 return "movlps\t{%1, %0|%0, %1}";
2510 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2512 (cond [(eq_attr "alternative" "0,1,2")
2514 (eq_attr "alternative" "3,4")
2517 /* For SSE1, we have many fewer alternatives. */
2518 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2519 (cond [(eq_attr "alternative" "5,6")
2520 (const_string "V4SF")
2522 (const_string "V2SF"))
2524 /* xorps is one byte shorter. */
2525 (eq_attr "alternative" "5")
2526 (cond [(ne (symbol_ref "optimize_size")
2528 (const_string "V4SF")
2529 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2533 (const_string "V2DF"))
2535 /* For architectures resolving dependencies on
2536 whole SSE registers use APD move to break dependency
2537 chains, otherwise use short move to avoid extra work.
2539 movaps encodes one byte shorter. */
2540 (eq_attr "alternative" "6")
2542 [(ne (symbol_ref "optimize_size")
2544 (const_string "V4SF")
2545 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2547 (const_string "V2DF")
2549 (const_string "DF"))
2550 /* For architectures resolving dependencies on register
2551 parts we may avoid extra work to zero out upper part
2553 (eq_attr "alternative" "7")
2555 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2557 (const_string "V1DF")
2558 (const_string "DF"))
2560 (const_string "DF")))])
2562 (define_insn "*movdf_integer"
2563 [(set (match_operand:DF 0 "nonimmediate_operand"
2564 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2565 (match_operand:DF 1 "general_operand"
2566 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2567 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2568 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2569 && (reload_in_progress || reload_completed
2570 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2571 || GET_CODE (operands[1]) != CONST_DOUBLE
2572 || memory_operand (operands[0], DFmode))"
2574 switch (which_alternative)
2577 return output_387_reg_move (insn, operands);
2580 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2581 return "fstp%z0\t%y0";
2583 return "fst%z0\t%y0";
2586 return standard_80387_constant_opcode (operands[1]);
2593 switch (get_attr_mode (insn))
2596 return "xorps\t%0, %0";
2598 return "xorpd\t%0, %0";
2600 return "pxor\t%0, %0";
2607 switch (get_attr_mode (insn))
2610 return "movaps\t{%1, %0|%0, %1}";
2612 return "movapd\t{%1, %0|%0, %1}";
2614 return "movdqa\t{%1, %0|%0, %1}";
2616 return "movq\t{%1, %0|%0, %1}";
2618 return "movsd\t{%1, %0|%0, %1}";
2620 return "movlpd\t{%1, %0|%0, %1}";
2622 return "movlps\t{%1, %0|%0, %1}";
2631 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2633 (cond [(eq_attr "alternative" "0,1,2")
2635 (eq_attr "alternative" "3,4")
2638 /* For SSE1, we have many fewer alternatives. */
2639 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2640 (cond [(eq_attr "alternative" "5,6")
2641 (const_string "V4SF")
2643 (const_string "V2SF"))
2645 /* xorps is one byte shorter. */
2646 (eq_attr "alternative" "5")
2647 (cond [(ne (symbol_ref "optimize_size")
2649 (const_string "V4SF")
2650 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2654 (const_string "V2DF"))
2656 /* For architectures resolving dependencies on
2657 whole SSE registers use APD move to break dependency
2658 chains, otherwise use short move to avoid extra work.
2660 movaps encodes one byte shorter. */
2661 (eq_attr "alternative" "6")
2663 [(ne (symbol_ref "optimize_size")
2665 (const_string "V4SF")
2666 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2668 (const_string "V2DF")
2670 (const_string "DF"))
2671 /* For architectures resolving dependencies on register
2672 parts we may avoid extra work to zero out upper part
2674 (eq_attr "alternative" "7")
2676 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2678 (const_string "V1DF")
2679 (const_string "DF"))
2681 (const_string "DF")))])
2684 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2685 (match_operand:DF 1 "general_operand" ""))]
2687 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2688 && ! (ANY_FP_REG_P (operands[0]) ||
2689 (GET_CODE (operands[0]) == SUBREG
2690 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2691 && ! (ANY_FP_REG_P (operands[1]) ||
2692 (GET_CODE (operands[1]) == SUBREG
2693 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2695 "ix86_split_long_move (operands); DONE;")
2697 (define_insn "*swapdf"
2698 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2699 (match_operand:DF 1 "fp_register_operand" "+f"))
2702 "reload_completed || TARGET_80387"
2704 if (STACK_TOP_P (operands[0]))
2709 [(set_attr "type" "fxch")
2710 (set_attr "mode" "DF")])
2712 (define_expand "movxf"
2713 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2714 (match_operand:XF 1 "general_operand" ""))]
2716 "ix86_expand_move (XFmode, operands); DONE;")
2718 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2719 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2720 ;; Pushing using integer instructions is longer except for constants
2721 ;; and direct memory references.
2722 ;; (assuming that any given constant is pushed only once, but this ought to be
2723 ;; handled elsewhere).
2725 (define_insn "*pushxf_nointeger"
2726 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2727 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2730 /* This insn should be already split before reg-stack. */
2733 [(set_attr "type" "multi")
2734 (set_attr "unit" "i387,*,*")
2735 (set_attr "mode" "XF,SI,SI")])
2737 (define_insn "*pushxf_integer"
2738 [(set (match_operand:XF 0 "push_operand" "=<,<")
2739 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2742 /* This insn should be already split before reg-stack. */
2745 [(set_attr "type" "multi")
2746 (set_attr "unit" "i387,*")
2747 (set_attr "mode" "XF,SI")])
2750 [(set (match_operand 0 "push_operand" "")
2751 (match_operand 1 "general_operand" ""))]
2753 && (GET_MODE (operands[0]) == XFmode
2754 || GET_MODE (operands[0]) == DFmode)
2755 && !ANY_FP_REG_P (operands[1])"
2757 "ix86_split_long_move (operands); DONE;")
2760 [(set (match_operand:XF 0 "push_operand" "")
2761 (match_operand:XF 1 "any_fp_register_operand" ""))]
2763 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2764 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2765 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2768 [(set (match_operand:XF 0 "push_operand" "")
2769 (match_operand:XF 1 "any_fp_register_operand" ""))]
2771 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2772 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2773 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2775 ;; Do not use integer registers when optimizing for size
2776 (define_insn "*movxf_nointeger"
2777 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2778 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2780 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2781 && (reload_in_progress || reload_completed
2782 || GET_CODE (operands[1]) != CONST_DOUBLE
2783 || memory_operand (operands[0], XFmode))"
2785 switch (which_alternative)
2788 return output_387_reg_move (insn, operands);
2791 /* There is no non-popping store to memory for XFmode. So if
2792 we need one, follow the store with a load. */
2793 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2794 return "fstp%z0\t%y0\;fld%z0\t%y0";
2796 return "fstp%z0\t%y0";
2799 return standard_80387_constant_opcode (operands[1]);
2807 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2808 (set_attr "mode" "XF,XF,XF,SI,SI")])
2810 (define_insn "*movxf_integer"
2811 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2812 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2814 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2815 && (reload_in_progress || reload_completed
2816 || GET_CODE (operands[1]) != CONST_DOUBLE
2817 || memory_operand (operands[0], XFmode))"
2819 switch (which_alternative)
2822 return output_387_reg_move (insn, operands);
2825 /* There is no non-popping store to memory for XFmode. So if
2826 we need one, follow the store with a load. */
2827 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2828 return "fstp%z0\t%y0\;fld%z0\t%y0";
2830 return "fstp%z0\t%y0";
2833 return standard_80387_constant_opcode (operands[1]);
2842 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2843 (set_attr "mode" "XF,XF,XF,SI,SI")])
2846 [(set (match_operand 0 "nonimmediate_operand" "")
2847 (match_operand 1 "general_operand" ""))]
2849 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2850 && GET_MODE (operands[0]) == XFmode
2851 && ! (ANY_FP_REG_P (operands[0]) ||
2852 (GET_CODE (operands[0]) == SUBREG
2853 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2854 && ! (ANY_FP_REG_P (operands[1]) ||
2855 (GET_CODE (operands[1]) == SUBREG
2856 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2858 "ix86_split_long_move (operands); DONE;")
2861 [(set (match_operand 0 "register_operand" "")
2862 (match_operand 1 "memory_operand" ""))]
2864 && GET_CODE (operands[1]) == MEM
2865 && (GET_MODE (operands[0]) == XFmode
2866 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2867 && constant_pool_reference_p (operands[1])"
2868 [(set (match_dup 0) (match_dup 1))]
2870 rtx c = avoid_constant_pool_reference (operands[1]);
2871 rtx r = operands[0];
2873 if (GET_CODE (r) == SUBREG)
2878 if (!standard_sse_constant_p (c))
2881 else if (FP_REG_P (r))
2883 if (!standard_80387_constant_p (c))
2886 else if (MMX_REG_P (r))
2892 (define_insn "swapxf"
2893 [(set (match_operand:XF 0 "register_operand" "+f")
2894 (match_operand:XF 1 "register_operand" "+f"))
2899 if (STACK_TOP_P (operands[0]))
2904 [(set_attr "type" "fxch")
2905 (set_attr "mode" "XF")])
2907 (define_expand "movtf"
2908 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2909 (match_operand:TF 1 "nonimmediate_operand" ""))]
2912 ix86_expand_move (TFmode, operands);
2916 (define_insn "*movtf_internal"
2917 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2918 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2920 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2922 switch (which_alternative)
2928 if (get_attr_mode (insn) == MODE_V4SF)
2929 return "xorps\t%0, %0";
2931 return "pxor\t%0, %0";
2934 if (get_attr_mode (insn) == MODE_V4SF)
2935 return "movaps\t{%1, %0|%0, %1}";
2937 return "movdqa\t{%1, %0|%0, %1}";
2942 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2944 (cond [(eq_attr "alternative" "2,3")
2946 (ne (symbol_ref "optimize_size")
2948 (const_string "V4SF")
2949 (const_string "TI"))
2950 (eq_attr "alternative" "4")
2952 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2954 (ne (symbol_ref "optimize_size")
2956 (const_string "V4SF")
2957 (const_string "TI"))]
2958 (const_string "DI")))])
2961 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2962 (match_operand:TF 1 "general_operand" ""))]
2963 "reload_completed && !SSE_REG_P (operands[0])
2964 && !SSE_REG_P (operands[1])"
2966 "ix86_split_long_move (operands); DONE;")
2968 ;; Zero extension instructions
2970 (define_expand "zero_extendhisi2"
2971 [(set (match_operand:SI 0 "register_operand" "")
2972 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2975 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2977 operands[1] = force_reg (HImode, operands[1]);
2978 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2983 (define_insn "zero_extendhisi2_and"
2984 [(set (match_operand:SI 0 "register_operand" "=r")
2985 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2986 (clobber (reg:CC FLAGS_REG))]
2987 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2989 [(set_attr "type" "alu1")
2990 (set_attr "mode" "SI")])
2993 [(set (match_operand:SI 0 "register_operand" "")
2994 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2995 (clobber (reg:CC FLAGS_REG))]
2996 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2998 (clobber (reg:CC FLAGS_REG))])]
3001 (define_insn "*zero_extendhisi2_movzwl"
3002 [(set (match_operand:SI 0 "register_operand" "=r")
3003 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3004 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3005 "movz{wl|x}\t{%1, %0|%0, %1}"
3006 [(set_attr "type" "imovx")
3007 (set_attr "mode" "SI")])
3009 (define_expand "zero_extendqihi2"
3011 [(set (match_operand:HI 0 "register_operand" "")
3012 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3013 (clobber (reg:CC FLAGS_REG))])]
3017 (define_insn "*zero_extendqihi2_and"
3018 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3019 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3020 (clobber (reg:CC FLAGS_REG))]
3021 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3023 [(set_attr "type" "alu1")
3024 (set_attr "mode" "HI")])
3026 (define_insn "*zero_extendqihi2_movzbw_and"
3027 [(set (match_operand:HI 0 "register_operand" "=r,r")
3028 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3029 (clobber (reg:CC FLAGS_REG))]
3030 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3032 [(set_attr "type" "imovx,alu1")
3033 (set_attr "mode" "HI")])
3035 ; zero extend to SImode here to avoid partial register stalls
3036 (define_insn "*zero_extendqihi2_movzbl"
3037 [(set (match_operand:HI 0 "register_operand" "=r")
3038 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3039 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3040 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3041 [(set_attr "type" "imovx")
3042 (set_attr "mode" "SI")])
3044 ;; For the movzbw case strip only the clobber
3046 [(set (match_operand:HI 0 "register_operand" "")
3047 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3048 (clobber (reg:CC FLAGS_REG))]
3050 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3051 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3052 [(set (match_operand:HI 0 "register_operand" "")
3053 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3055 ;; When source and destination does not overlap, clear destination
3056 ;; first and then do the movb
3058 [(set (match_operand:HI 0 "register_operand" "")
3059 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3060 (clobber (reg:CC FLAGS_REG))]
3062 && ANY_QI_REG_P (operands[0])
3063 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3064 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3065 [(set (match_dup 0) (const_int 0))
3066 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3067 "operands[2] = gen_lowpart (QImode, operands[0]);")
3069 ;; Rest is handled by single and.
3071 [(set (match_operand:HI 0 "register_operand" "")
3072 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3073 (clobber (reg:CC FLAGS_REG))]
3075 && true_regnum (operands[0]) == true_regnum (operands[1])"
3076 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3077 (clobber (reg:CC FLAGS_REG))])]
3080 (define_expand "zero_extendqisi2"
3082 [(set (match_operand:SI 0 "register_operand" "")
3083 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3084 (clobber (reg:CC FLAGS_REG))])]
3088 (define_insn "*zero_extendqisi2_and"
3089 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3090 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3091 (clobber (reg:CC FLAGS_REG))]
3092 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3094 [(set_attr "type" "alu1")
3095 (set_attr "mode" "SI")])
3097 (define_insn "*zero_extendqisi2_movzbw_and"
3098 [(set (match_operand:SI 0 "register_operand" "=r,r")
3099 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3100 (clobber (reg:CC FLAGS_REG))]
3101 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3103 [(set_attr "type" "imovx,alu1")
3104 (set_attr "mode" "SI")])
3106 (define_insn "*zero_extendqisi2_movzbw"
3107 [(set (match_operand:SI 0 "register_operand" "=r")
3108 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3109 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3110 "movz{bl|x}\t{%1, %0|%0, %1}"
3111 [(set_attr "type" "imovx")
3112 (set_attr "mode" "SI")])
3114 ;; For the movzbl case strip only the clobber
3116 [(set (match_operand:SI 0 "register_operand" "")
3117 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3118 (clobber (reg:CC FLAGS_REG))]
3120 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3121 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3123 (zero_extend:SI (match_dup 1)))])
3125 ;; When source and destination does not overlap, clear destination
3126 ;; first and then do the movb
3128 [(set (match_operand:SI 0 "register_operand" "")
3129 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3130 (clobber (reg:CC FLAGS_REG))]
3132 && ANY_QI_REG_P (operands[0])
3133 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3134 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3135 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3136 [(set (match_dup 0) (const_int 0))
3137 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3138 "operands[2] = gen_lowpart (QImode, operands[0]);")
3140 ;; Rest is handled by single and.
3142 [(set (match_operand:SI 0 "register_operand" "")
3143 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3144 (clobber (reg:CC FLAGS_REG))]
3146 && true_regnum (operands[0]) == true_regnum (operands[1])"
3147 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3148 (clobber (reg:CC FLAGS_REG))])]
3151 ;; %%% Kill me once multi-word ops are sane.
3152 (define_expand "zero_extendsidi2"
3153 [(set (match_operand:DI 0 "register_operand" "=r")
3154 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3158 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3163 (define_insn "zero_extendsidi2_32"
3164 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3165 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3166 (clobber (reg:CC FLAGS_REG))]
3172 movd\t{%1, %0|%0, %1}
3173 movd\t{%1, %0|%0, %1}"
3174 [(set_attr "mode" "SI,SI,SI,DI,TI")
3175 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3177 (define_insn "zero_extendsidi2_rex64"
3178 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3179 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3182 mov\t{%k1, %k0|%k0, %k1}
3184 movd\t{%1, %0|%0, %1}
3185 movd\t{%1, %0|%0, %1}"
3186 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3187 (set_attr "mode" "SI,DI,SI,SI")])
3190 [(set (match_operand:DI 0 "memory_operand" "")
3191 (zero_extend:DI (match_dup 0)))]
3193 [(set (match_dup 4) (const_int 0))]
3194 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3197 [(set (match_operand:DI 0 "register_operand" "")
3198 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3199 (clobber (reg:CC FLAGS_REG))]
3200 "!TARGET_64BIT && reload_completed
3201 && true_regnum (operands[0]) == true_regnum (operands[1])"
3202 [(set (match_dup 4) (const_int 0))]
3203 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3206 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3207 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3208 (clobber (reg:CC FLAGS_REG))]
3209 "!TARGET_64BIT && reload_completed
3210 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3211 [(set (match_dup 3) (match_dup 1))
3212 (set (match_dup 4) (const_int 0))]
3213 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3215 (define_insn "zero_extendhidi2"
3216 [(set (match_operand:DI 0 "register_operand" "=r")
3217 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3219 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3220 [(set_attr "type" "imovx")
3221 (set_attr "mode" "DI")])
3223 (define_insn "zero_extendqidi2"
3224 [(set (match_operand:DI 0 "register_operand" "=r")
3225 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3227 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3228 [(set_attr "type" "imovx")
3229 (set_attr "mode" "DI")])
3231 ;; Sign extension instructions
3233 (define_expand "extendsidi2"
3234 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3235 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3236 (clobber (reg:CC FLAGS_REG))
3237 (clobber (match_scratch:SI 2 ""))])]
3242 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3247 (define_insn "*extendsidi2_1"
3248 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3249 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3250 (clobber (reg:CC FLAGS_REG))
3251 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3255 (define_insn "extendsidi2_rex64"
3256 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3257 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3261 movs{lq|x}\t{%1,%0|%0, %1}"
3262 [(set_attr "type" "imovx")
3263 (set_attr "mode" "DI")
3264 (set_attr "prefix_0f" "0")
3265 (set_attr "modrm" "0,1")])
3267 (define_insn "extendhidi2"
3268 [(set (match_operand:DI 0 "register_operand" "=r")
3269 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3271 "movs{wq|x}\t{%1,%0|%0, %1}"
3272 [(set_attr "type" "imovx")
3273 (set_attr "mode" "DI")])
3275 (define_insn "extendqidi2"
3276 [(set (match_operand:DI 0 "register_operand" "=r")
3277 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3279 "movs{bq|x}\t{%1,%0|%0, %1}"
3280 [(set_attr "type" "imovx")
3281 (set_attr "mode" "DI")])
3283 ;; Extend to memory case when source register does die.
3285 [(set (match_operand:DI 0 "memory_operand" "")
3286 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3287 (clobber (reg:CC FLAGS_REG))
3288 (clobber (match_operand:SI 2 "register_operand" ""))]
3290 && dead_or_set_p (insn, operands[1])
3291 && !reg_mentioned_p (operands[1], operands[0]))"
3292 [(set (match_dup 3) (match_dup 1))
3293 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3294 (clobber (reg:CC FLAGS_REG))])
3295 (set (match_dup 4) (match_dup 1))]
3296 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3298 ;; Extend to memory case when source register does not die.
3300 [(set (match_operand:DI 0 "memory_operand" "")
3301 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3302 (clobber (reg:CC FLAGS_REG))
3303 (clobber (match_operand:SI 2 "register_operand" ""))]
3307 split_di (&operands[0], 1, &operands[3], &operands[4]);
3309 emit_move_insn (operands[3], operands[1]);
3311 /* Generate a cltd if possible and doing so it profitable. */
3312 if (true_regnum (operands[1]) == 0
3313 && true_regnum (operands[2]) == 1
3314 && (optimize_size || TARGET_USE_CLTD))
3316 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3320 emit_move_insn (operands[2], operands[1]);
3321 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3323 emit_move_insn (operands[4], operands[2]);
3327 ;; Extend to register case. Optimize case where source and destination
3328 ;; registers match and cases where we can use cltd.
3330 [(set (match_operand:DI 0 "register_operand" "")
3331 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3332 (clobber (reg:CC FLAGS_REG))
3333 (clobber (match_scratch:SI 2 ""))]
3337 split_di (&operands[0], 1, &operands[3], &operands[4]);
3339 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3340 emit_move_insn (operands[3], operands[1]);
3342 /* Generate a cltd if possible and doing so it profitable. */
3343 if (true_regnum (operands[3]) == 0
3344 && (optimize_size || TARGET_USE_CLTD))
3346 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3350 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3351 emit_move_insn (operands[4], operands[1]);
3353 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3357 (define_insn "extendhisi2"
3358 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3359 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3362 switch (get_attr_prefix_0f (insn))
3365 return "{cwtl|cwde}";
3367 return "movs{wl|x}\t{%1,%0|%0, %1}";
3370 [(set_attr "type" "imovx")
3371 (set_attr "mode" "SI")
3372 (set (attr "prefix_0f")
3373 ;; movsx is short decodable while cwtl is vector decoded.
3374 (if_then_else (and (eq_attr "cpu" "!k6")
3375 (eq_attr "alternative" "0"))
3377 (const_string "1")))
3379 (if_then_else (eq_attr "prefix_0f" "0")
3381 (const_string "1")))])
3383 (define_insn "*extendhisi2_zext"
3384 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3386 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3389 switch (get_attr_prefix_0f (insn))
3392 return "{cwtl|cwde}";
3394 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3397 [(set_attr "type" "imovx")
3398 (set_attr "mode" "SI")
3399 (set (attr "prefix_0f")
3400 ;; movsx is short decodable while cwtl is vector decoded.
3401 (if_then_else (and (eq_attr "cpu" "!k6")
3402 (eq_attr "alternative" "0"))
3404 (const_string "1")))
3406 (if_then_else (eq_attr "prefix_0f" "0")
3408 (const_string "1")))])
3410 (define_insn "extendqihi2"
3411 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3412 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3415 switch (get_attr_prefix_0f (insn))
3418 return "{cbtw|cbw}";
3420 return "movs{bw|x}\t{%1,%0|%0, %1}";
3423 [(set_attr "type" "imovx")
3424 (set_attr "mode" "HI")
3425 (set (attr "prefix_0f")
3426 ;; movsx is short decodable while cwtl is vector decoded.
3427 (if_then_else (and (eq_attr "cpu" "!k6")
3428 (eq_attr "alternative" "0"))
3430 (const_string "1")))
3432 (if_then_else (eq_attr "prefix_0f" "0")
3434 (const_string "1")))])
3436 (define_insn "extendqisi2"
3437 [(set (match_operand:SI 0 "register_operand" "=r")
3438 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3440 "movs{bl|x}\t{%1,%0|%0, %1}"
3441 [(set_attr "type" "imovx")
3442 (set_attr "mode" "SI")])
3444 (define_insn "*extendqisi2_zext"
3445 [(set (match_operand:DI 0 "register_operand" "=r")
3447 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3449 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3450 [(set_attr "type" "imovx")
3451 (set_attr "mode" "SI")])
3453 ;; Conversions between float and double.
3455 ;; These are all no-ops in the model used for the 80387. So just
3458 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3459 (define_insn "*dummy_extendsfdf2"
3460 [(set (match_operand:DF 0 "push_operand" "=<")
3461 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3466 [(set (match_operand:DF 0 "push_operand" "")
3467 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3469 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3470 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3473 [(set (match_operand:DF 0 "push_operand" "")
3474 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3476 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3477 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3479 (define_insn "*dummy_extendsfxf2"
3480 [(set (match_operand:XF 0 "push_operand" "=<")
3481 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3486 [(set (match_operand:XF 0 "push_operand" "")
3487 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3489 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3490 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3491 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3494 [(set (match_operand:XF 0 "push_operand" "")
3495 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3497 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3498 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3499 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3502 [(set (match_operand:XF 0 "push_operand" "")
3503 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3505 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3506 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3507 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3510 [(set (match_operand:XF 0 "push_operand" "")
3511 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3513 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3514 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3515 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3517 (define_expand "extendsfdf2"
3518 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3519 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3520 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3522 /* ??? Needed for compress_float_constant since all fp constants
3523 are LEGITIMATE_CONSTANT_P. */
3524 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3526 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3527 && standard_80387_constant_p (operands[1]) > 0)
3529 operands[1] = simplify_const_unary_operation
3530 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3531 emit_move_insn_1 (operands[0], operands[1]);
3534 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3538 (define_insn "*extendsfdf2_mixed"
3539 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3540 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3541 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3543 switch (which_alternative)
3546 return output_387_reg_move (insn, operands);
3549 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3550 return "fstp%z0\t%y0";
3552 return "fst%z0\t%y0";
3555 return "cvtss2sd\t{%1, %0|%0, %1}";
3561 [(set_attr "type" "fmov,fmov,ssecvt")
3562 (set_attr "mode" "SF,XF,DF")])
3564 (define_insn "*extendsfdf2_sse"
3565 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3566 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3567 "TARGET_SSE2 && TARGET_SSE_MATH"
3568 "cvtss2sd\t{%1, %0|%0, %1}"
3569 [(set_attr "type" "ssecvt")
3570 (set_attr "mode" "DF")])
3572 (define_insn "*extendsfdf2_i387"
3573 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3574 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3577 switch (which_alternative)
3580 return output_387_reg_move (insn, operands);
3583 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3584 return "fstp%z0\t%y0";
3586 return "fst%z0\t%y0";
3592 [(set_attr "type" "fmov")
3593 (set_attr "mode" "SF,XF")])
3595 (define_expand "extendsfxf2"
3596 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3597 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3600 /* ??? Needed for compress_float_constant since all fp constants
3601 are LEGITIMATE_CONSTANT_P. */
3602 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3604 if (standard_80387_constant_p (operands[1]) > 0)
3606 operands[1] = simplify_const_unary_operation
3607 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3608 emit_move_insn_1 (operands[0], operands[1]);
3611 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3615 (define_insn "*extendsfxf2_i387"
3616 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3617 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3620 switch (which_alternative)
3623 return output_387_reg_move (insn, operands);
3626 /* There is no non-popping store to memory for XFmode. So if
3627 we need one, follow the store with a load. */
3628 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3629 return "fstp%z0\t%y0";
3631 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3637 [(set_attr "type" "fmov")
3638 (set_attr "mode" "SF,XF")])
3640 (define_expand "extenddfxf2"
3641 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3642 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3645 /* ??? Needed for compress_float_constant since all fp constants
3646 are LEGITIMATE_CONSTANT_P. */
3647 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3649 if (standard_80387_constant_p (operands[1]) > 0)
3651 operands[1] = simplify_const_unary_operation
3652 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3653 emit_move_insn_1 (operands[0], operands[1]);
3656 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3660 (define_insn "*extenddfxf2_i387"
3661 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3662 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3665 switch (which_alternative)
3668 return output_387_reg_move (insn, operands);
3671 /* There is no non-popping store to memory for XFmode. So if
3672 we need one, follow the store with a load. */
3673 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3674 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3676 return "fstp%z0\t%y0";
3682 [(set_attr "type" "fmov")
3683 (set_attr "mode" "DF,XF")])
3685 ;; %%% This seems bad bad news.
3686 ;; This cannot output into an f-reg because there is no way to be sure
3687 ;; of truncating in that case. Otherwise this is just like a simple move
3688 ;; insn. So we pretend we can output to a reg in order to get better
3689 ;; register preferencing, but we really use a stack slot.
3691 ;; Conversion from DFmode to SFmode.
3693 (define_expand "truncdfsf2"
3694 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3696 (match_operand:DF 1 "nonimmediate_operand" "")))]
3697 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3699 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3701 else if (flag_unsafe_math_optimizations)
3705 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3706 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3711 (define_expand "truncdfsf2_with_temp"
3712 [(parallel [(set (match_operand:SF 0 "" "")
3713 (float_truncate:SF (match_operand:DF 1 "" "")))
3714 (clobber (match_operand:SF 2 "" ""))])]
3717 (define_insn "*truncdfsf_fast_mixed"
3718 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3720 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3721 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3723 switch (which_alternative)
3726 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3727 return "fstp%z0\t%y0";
3729 return "fst%z0\t%y0";
3731 return output_387_reg_move (insn, operands);
3733 return "cvtsd2ss\t{%1, %0|%0, %1}";
3738 [(set_attr "type" "fmov,fmov,ssecvt")
3739 (set_attr "mode" "SF")])
3741 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3742 ;; because nothing we do here is unsafe.
3743 (define_insn "*truncdfsf_fast_sse"
3744 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3746 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3747 "TARGET_SSE2 && TARGET_SSE_MATH"
3748 "cvtsd2ss\t{%1, %0|%0, %1}"
3749 [(set_attr "type" "ssecvt")
3750 (set_attr "mode" "SF")])
3752 (define_insn "*truncdfsf_fast_i387"
3753 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3755 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3756 "TARGET_80387 && flag_unsafe_math_optimizations"
3757 "* return output_387_reg_move (insn, operands);"
3758 [(set_attr "type" "fmov")
3759 (set_attr "mode" "SF")])
3761 (define_insn "*truncdfsf_mixed"
3762 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3764 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3765 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3766 "TARGET_MIX_SSE_I387"
3768 switch (which_alternative)
3771 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3772 return "fstp%z0\t%y0";
3774 return "fst%z0\t%y0";
3778 return "cvtsd2ss\t{%1, %0|%0, %1}";
3783 [(set_attr "type" "fmov,multi,ssecvt")
3784 (set_attr "unit" "*,i387,*")
3785 (set_attr "mode" "SF")])
3787 (define_insn "*truncdfsf_i387"
3788 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3790 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3791 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3794 switch (which_alternative)
3797 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3798 return "fstp%z0\t%y0";
3800 return "fst%z0\t%y0";
3807 [(set_attr "type" "fmov,multi")
3808 (set_attr "unit" "*,i387")
3809 (set_attr "mode" "SF")])
3811 (define_insn "*truncdfsf2_i387_1"
3812 [(set (match_operand:SF 0 "memory_operand" "=m")
3814 (match_operand:DF 1 "register_operand" "f")))]
3816 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3817 && !TARGET_MIX_SSE_I387"
3819 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3820 return "fstp%z0\t%y0";
3822 return "fst%z0\t%y0";
3824 [(set_attr "type" "fmov")
3825 (set_attr "mode" "SF")])
3828 [(set (match_operand:SF 0 "register_operand" "")
3830 (match_operand:DF 1 "fp_register_operand" "")))
3831 (clobber (match_operand 2 "" ""))]
3833 [(set (match_dup 2) (match_dup 1))
3834 (set (match_dup 0) (match_dup 2))]
3836 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3839 ;; Conversion from XFmode to SFmode.
3841 (define_expand "truncxfsf2"
3842 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3844 (match_operand:XF 1 "register_operand" "")))
3845 (clobber (match_dup 2))])]
3848 if (flag_unsafe_math_optimizations)
3850 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3851 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3852 if (reg != operands[0])
3853 emit_move_insn (operands[0], reg);
3857 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3860 (define_insn "*truncxfsf2_mixed"
3861 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3863 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3864 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3865 "TARGET_MIX_SSE_I387"
3867 gcc_assert (!which_alternative);
3868 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3869 return "fstp%z0\t%y0";
3871 return "fst%z0\t%y0";
3873 [(set_attr "type" "fmov,multi,multi,multi")
3874 (set_attr "unit" "*,i387,i387,i387")
3875 (set_attr "mode" "SF")])
3877 (define_insn "truncxfsf2_i387_noop"
3878 [(set (match_operand:SF 0 "register_operand" "=f")
3879 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3880 "TARGET_80387 && flag_unsafe_math_optimizations"
3882 return output_387_reg_move (insn, operands);
3884 [(set_attr "type" "fmov")
3885 (set_attr "mode" "SF")])
3887 (define_insn "*truncxfsf2_i387"
3888 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3890 (match_operand:XF 1 "register_operand" "f,f,f")))
3891 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3894 gcc_assert (!which_alternative);
3895 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3896 return "fstp%z0\t%y0";
3898 return "fst%z0\t%y0";
3900 [(set_attr "type" "fmov,multi,multi")
3901 (set_attr "unit" "*,i387,i387")
3902 (set_attr "mode" "SF")])
3904 (define_insn "*truncxfsf2_i387_1"
3905 [(set (match_operand:SF 0 "memory_operand" "=m")
3907 (match_operand:XF 1 "register_operand" "f")))]
3910 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3911 return "fstp%z0\t%y0";
3913 return "fst%z0\t%y0";
3915 [(set_attr "type" "fmov")
3916 (set_attr "mode" "SF")])
3919 [(set (match_operand:SF 0 "register_operand" "")
3921 (match_operand:XF 1 "register_operand" "")))
3922 (clobber (match_operand:SF 2 "memory_operand" ""))]
3923 "TARGET_80387 && reload_completed"
3924 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3925 (set (match_dup 0) (match_dup 2))]
3929 [(set (match_operand:SF 0 "memory_operand" "")
3931 (match_operand:XF 1 "register_operand" "")))
3932 (clobber (match_operand:SF 2 "memory_operand" ""))]
3934 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3937 ;; Conversion from XFmode to DFmode.
3939 (define_expand "truncxfdf2"
3940 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3942 (match_operand:XF 1 "register_operand" "")))
3943 (clobber (match_dup 2))])]
3946 if (flag_unsafe_math_optimizations)
3948 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3949 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3950 if (reg != operands[0])
3951 emit_move_insn (operands[0], reg);
3955 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3958 (define_insn "*truncxfdf2_mixed"
3959 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3961 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3962 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3963 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3965 gcc_assert (!which_alternative);
3966 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3967 return "fstp%z0\t%y0";
3969 return "fst%z0\t%y0";
3971 [(set_attr "type" "fmov,multi,multi,multi")
3972 (set_attr "unit" "*,i387,i387,i387")
3973 (set_attr "mode" "DF")])
3975 (define_insn "truncxfdf2_i387_noop"
3976 [(set (match_operand:DF 0 "register_operand" "=f")
3977 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3978 "TARGET_80387 && flag_unsafe_math_optimizations"
3980 return output_387_reg_move (insn, operands);
3982 [(set_attr "type" "fmov")
3983 (set_attr "mode" "DF")])
3985 (define_insn "*truncxfdf2_i387"
3986 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
3988 (match_operand:XF 1 "register_operand" "f,f,f")))
3989 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3992 gcc_assert (!which_alternative);
3993 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3994 return "fstp%z0\t%y0";
3996 return "fst%z0\t%y0";
3998 [(set_attr "type" "fmov,multi,multi")
3999 (set_attr "unit" "*,i387,i387")
4000 (set_attr "mode" "DF")])
4002 (define_insn "*truncxfdf2_i387_1"
4003 [(set (match_operand:DF 0 "memory_operand" "=m")
4005 (match_operand:XF 1 "register_operand" "f")))]
4008 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4009 return "fstp%z0\t%y0";
4011 return "fst%z0\t%y0";
4013 [(set_attr "type" "fmov")
4014 (set_attr "mode" "DF")])
4017 [(set (match_operand:DF 0 "register_operand" "")
4019 (match_operand:XF 1 "register_operand" "")))
4020 (clobber (match_operand:DF 2 "memory_operand" ""))]
4021 "TARGET_80387 && reload_completed"
4022 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4023 (set (match_dup 0) (match_dup 2))]
4027 [(set (match_operand:DF 0 "memory_operand" "")
4029 (match_operand:XF 1 "register_operand" "")))
4030 (clobber (match_operand:DF 2 "memory_operand" ""))]
4032 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4035 ;; Signed conversion to DImode.
4037 (define_expand "fix_truncxfdi2"
4038 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4039 (fix:DI (match_operand:XF 1 "register_operand" "")))
4040 (clobber (reg:CC FLAGS_REG))])]
4045 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4050 (define_expand "fix_trunc<mode>di2"
4051 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4052 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4053 (clobber (reg:CC FLAGS_REG))])]
4054 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4057 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4059 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4062 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4064 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4065 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4066 if (out != operands[0])
4067 emit_move_insn (operands[0], out);
4072 ;; Signed conversion to SImode.
4074 (define_expand "fix_truncxfsi2"
4075 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4076 (fix:SI (match_operand:XF 1 "register_operand" "")))
4077 (clobber (reg:CC FLAGS_REG))])]
4082 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4087 (define_expand "fix_trunc<mode>si2"
4088 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4089 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4090 (clobber (reg:CC FLAGS_REG))])]
4091 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4094 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4096 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4099 if (SSE_FLOAT_MODE_P (<MODE>mode))
4101 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4102 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4103 if (out != operands[0])
4104 emit_move_insn (operands[0], out);
4109 ;; Signed conversion to HImode.
4111 (define_expand "fix_trunc<mode>hi2"
4112 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4113 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4114 (clobber (reg:CC FLAGS_REG))])]
4116 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4120 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4125 ;; When SSE is available, it is always faster to use it!
4126 (define_insn "fix_truncsfdi_sse"
4127 [(set (match_operand:DI 0 "register_operand" "=r,r")
4128 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4129 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4130 "cvttss2si{q}\t{%1, %0|%0, %1}"
4131 [(set_attr "type" "sseicvt")
4132 (set_attr "mode" "SF")
4133 (set_attr "athlon_decode" "double,vector")])
4135 (define_insn "fix_truncdfdi_sse"
4136 [(set (match_operand:DI 0 "register_operand" "=r,r")
4137 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4138 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4139 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4140 [(set_attr "type" "sseicvt")
4141 (set_attr "mode" "DF")
4142 (set_attr "athlon_decode" "double,vector")])
4144 (define_insn "fix_truncsfsi_sse"
4145 [(set (match_operand:SI 0 "register_operand" "=r,r")
4146 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4147 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4148 "cvttss2si\t{%1, %0|%0, %1}"
4149 [(set_attr "type" "sseicvt")
4150 (set_attr "mode" "DF")
4151 (set_attr "athlon_decode" "double,vector")])
4153 (define_insn "fix_truncdfsi_sse"
4154 [(set (match_operand:SI 0 "register_operand" "=r,r")
4155 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4156 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4157 "cvttsd2si\t{%1, %0|%0, %1}"
4158 [(set_attr "type" "sseicvt")
4159 (set_attr "mode" "DF")
4160 (set_attr "athlon_decode" "double,vector")])
4162 ;; Avoid vector decoded forms of the instruction.
4164 [(match_scratch:DF 2 "Y")
4165 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4166 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4167 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4168 [(set (match_dup 2) (match_dup 1))
4169 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4173 [(match_scratch:SF 2 "x")
4174 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4175 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4176 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4177 [(set (match_dup 2) (match_dup 1))
4178 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4181 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4182 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4183 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4185 && FLOAT_MODE_P (GET_MODE (operands[1]))
4186 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4187 && (TARGET_64BIT || <MODE>mode != DImode))
4189 && !(reload_completed || reload_in_progress)"
4194 if (memory_operand (operands[0], VOIDmode))
4195 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4198 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4199 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4205 [(set_attr "type" "fisttp")
4206 (set_attr "mode" "<MODE>")])
4208 (define_insn "fix_trunc<mode>_i387_fisttp"
4209 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4210 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4211 (clobber (match_scratch:XF 2 "=&1f"))]
4213 && FLOAT_MODE_P (GET_MODE (operands[1]))
4214 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4215 && (TARGET_64BIT || <MODE>mode != DImode))
4216 && TARGET_SSE_MATH)"
4217 "* return output_fix_trunc (insn, operands, 1);"
4218 [(set_attr "type" "fisttp")
4219 (set_attr "mode" "<MODE>")])
4221 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4222 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4223 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4224 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4225 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4227 && FLOAT_MODE_P (GET_MODE (operands[1]))
4228 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4229 && (TARGET_64BIT || <MODE>mode != DImode))
4230 && TARGET_SSE_MATH)"
4232 [(set_attr "type" "fisttp")
4233 (set_attr "mode" "<MODE>")])
4236 [(set (match_operand:X87MODEI 0 "register_operand" "")
4237 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4238 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4239 (clobber (match_scratch 3 ""))]
4241 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4242 (clobber (match_dup 3))])
4243 (set (match_dup 0) (match_dup 2))]
4247 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4248 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4249 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4250 (clobber (match_scratch 3 ""))]
4252 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4253 (clobber (match_dup 3))])]
4256 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4257 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4258 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4259 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4260 ;; function in i386.c.
4261 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4262 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4263 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4264 (clobber (reg:CC FLAGS_REG))]
4265 "TARGET_80387 && !TARGET_FISTTP
4266 && FLOAT_MODE_P (GET_MODE (operands[1]))
4267 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4268 && (TARGET_64BIT || <MODE>mode != DImode))
4269 && !(reload_completed || reload_in_progress)"
4274 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4276 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4277 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4278 if (memory_operand (operands[0], VOIDmode))
4279 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4280 operands[2], operands[3]));
4283 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4284 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4285 operands[2], operands[3],
4290 [(set_attr "type" "fistp")
4291 (set_attr "i387_cw" "trunc")
4292 (set_attr "mode" "<MODE>")])
4294 (define_insn "fix_truncdi_i387"
4295 [(set (match_operand:DI 0 "memory_operand" "=m")
4296 (fix:DI (match_operand 1 "register_operand" "f")))
4297 (use (match_operand:HI 2 "memory_operand" "m"))
4298 (use (match_operand:HI 3 "memory_operand" "m"))
4299 (clobber (match_scratch:XF 4 "=&1f"))]
4300 "TARGET_80387 && !TARGET_FISTTP
4301 && FLOAT_MODE_P (GET_MODE (operands[1]))
4302 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4303 "* return output_fix_trunc (insn, operands, 0);"
4304 [(set_attr "type" "fistp")
4305 (set_attr "i387_cw" "trunc")
4306 (set_attr "mode" "DI")])
4308 (define_insn "fix_truncdi_i387_with_temp"
4309 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4310 (fix:DI (match_operand 1 "register_operand" "f,f")))
4311 (use (match_operand:HI 2 "memory_operand" "m,m"))
4312 (use (match_operand:HI 3 "memory_operand" "m,m"))
4313 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4314 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4315 "TARGET_80387 && !TARGET_FISTTP
4316 && FLOAT_MODE_P (GET_MODE (operands[1]))
4317 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4319 [(set_attr "type" "fistp")
4320 (set_attr "i387_cw" "trunc")
4321 (set_attr "mode" "DI")])
4324 [(set (match_operand:DI 0 "register_operand" "")
4325 (fix:DI (match_operand 1 "register_operand" "")))
4326 (use (match_operand:HI 2 "memory_operand" ""))
4327 (use (match_operand:HI 3 "memory_operand" ""))
4328 (clobber (match_operand:DI 4 "memory_operand" ""))
4329 (clobber (match_scratch 5 ""))]
4331 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4334 (clobber (match_dup 5))])
4335 (set (match_dup 0) (match_dup 4))]
4339 [(set (match_operand:DI 0 "memory_operand" "")
4340 (fix:DI (match_operand 1 "register_operand" "")))
4341 (use (match_operand:HI 2 "memory_operand" ""))
4342 (use (match_operand:HI 3 "memory_operand" ""))
4343 (clobber (match_operand:DI 4 "memory_operand" ""))
4344 (clobber (match_scratch 5 ""))]
4346 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4349 (clobber (match_dup 5))])]
4352 (define_insn "fix_trunc<mode>_i387"
4353 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4354 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4355 (use (match_operand:HI 2 "memory_operand" "m"))
4356 (use (match_operand:HI 3 "memory_operand" "m"))]
4357 "TARGET_80387 && !TARGET_FISTTP
4358 && FLOAT_MODE_P (GET_MODE (operands[1]))
4359 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4360 "* return output_fix_trunc (insn, operands, 0);"
4361 [(set_attr "type" "fistp")
4362 (set_attr "i387_cw" "trunc")
4363 (set_attr "mode" "<MODE>")])
4365 (define_insn "fix_trunc<mode>_i387_with_temp"
4366 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4367 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4368 (use (match_operand:HI 2 "memory_operand" "m,m"))
4369 (use (match_operand:HI 3 "memory_operand" "m,m"))
4370 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4371 "TARGET_80387 && !TARGET_FISTTP
4372 && FLOAT_MODE_P (GET_MODE (operands[1]))
4373 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4375 [(set_attr "type" "fistp")
4376 (set_attr "i387_cw" "trunc")
4377 (set_attr "mode" "<MODE>")])
4380 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4381 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4382 (use (match_operand:HI 2 "memory_operand" ""))
4383 (use (match_operand:HI 3 "memory_operand" ""))
4384 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4386 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4388 (use (match_dup 3))])
4389 (set (match_dup 0) (match_dup 4))]
4393 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4394 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4395 (use (match_operand:HI 2 "memory_operand" ""))
4396 (use (match_operand:HI 3 "memory_operand" ""))
4397 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4399 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4401 (use (match_dup 3))])]
4404 (define_insn "x86_fnstcw_1"
4405 [(set (match_operand:HI 0 "memory_operand" "=m")
4406 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4409 [(set_attr "length" "2")
4410 (set_attr "mode" "HI")
4411 (set_attr "unit" "i387")])
4413 (define_insn "x86_fldcw_1"
4414 [(set (reg:HI FPSR_REG)
4415 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4418 [(set_attr "length" "2")
4419 (set_attr "mode" "HI")
4420 (set_attr "unit" "i387")
4421 (set_attr "athlon_decode" "vector")])
4423 ;; Conversion between fixed point and floating point.
4425 ;; Even though we only accept memory inputs, the backend _really_
4426 ;; wants to be able to do this between registers.
4428 (define_expand "floathisf2"
4429 [(set (match_operand:SF 0 "register_operand" "")
4430 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4431 "TARGET_80387 || TARGET_SSE_MATH"
4433 if (TARGET_SSE_MATH)
4435 emit_insn (gen_floatsisf2 (operands[0],
4436 convert_to_mode (SImode, operands[1], 0)));
4441 (define_insn "*floathisf2_i387"
4442 [(set (match_operand:SF 0 "register_operand" "=f,f")
4443 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4444 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4448 [(set_attr "type" "fmov,multi")
4449 (set_attr "mode" "SF")
4450 (set_attr "unit" "*,i387")
4451 (set_attr "fp_int_src" "true")])
4453 (define_expand "floatsisf2"
4454 [(set (match_operand:SF 0 "register_operand" "")
4455 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4456 "TARGET_80387 || TARGET_SSE_MATH"
4459 (define_insn "*floatsisf2_mixed"
4460 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4461 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4462 "TARGET_MIX_SSE_I387"
4466 cvtsi2ss\t{%1, %0|%0, %1}
4467 cvtsi2ss\t{%1, %0|%0, %1}"
4468 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4469 (set_attr "mode" "SF")
4470 (set_attr "unit" "*,i387,*,*")
4471 (set_attr "athlon_decode" "*,*,vector,double")
4472 (set_attr "fp_int_src" "true")])
4474 (define_insn "*floatsisf2_sse"
4475 [(set (match_operand:SF 0 "register_operand" "=x,x")
4476 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4478 "cvtsi2ss\t{%1, %0|%0, %1}"
4479 [(set_attr "type" "sseicvt")
4480 (set_attr "mode" "SF")
4481 (set_attr "athlon_decode" "vector,double")
4482 (set_attr "fp_int_src" "true")])
4484 (define_insn "*floatsisf2_i387"
4485 [(set (match_operand:SF 0 "register_operand" "=f,f")
4486 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4491 [(set_attr "type" "fmov,multi")
4492 (set_attr "mode" "SF")
4493 (set_attr "unit" "*,i387")
4494 (set_attr "fp_int_src" "true")])
4496 (define_expand "floatdisf2"
4497 [(set (match_operand:SF 0 "register_operand" "")
4498 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4499 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4502 (define_insn "*floatdisf2_mixed"
4503 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4504 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4505 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4509 cvtsi2ss{q}\t{%1, %0|%0, %1}
4510 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4511 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4512 (set_attr "mode" "SF")
4513 (set_attr "unit" "*,i387,*,*")
4514 (set_attr "athlon_decode" "*,*,vector,double")
4515 (set_attr "fp_int_src" "true")])
4517 (define_insn "*floatdisf2_sse"
4518 [(set (match_operand:SF 0 "register_operand" "=x,x")
4519 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4520 "TARGET_64BIT && TARGET_SSE_MATH"
4521 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4522 [(set_attr "type" "sseicvt")
4523 (set_attr "mode" "SF")
4524 (set_attr "athlon_decode" "vector,double")
4525 (set_attr "fp_int_src" "true")])
4527 (define_insn "*floatdisf2_i387"
4528 [(set (match_operand:SF 0 "register_operand" "=f,f")
4529 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4534 [(set_attr "type" "fmov,multi")
4535 (set_attr "mode" "SF")
4536 (set_attr "unit" "*,i387")
4537 (set_attr "fp_int_src" "true")])
4539 (define_expand "floathidf2"
4540 [(set (match_operand:DF 0 "register_operand" "")
4541 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4542 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4544 if (TARGET_SSE2 && TARGET_SSE_MATH)
4546 emit_insn (gen_floatsidf2 (operands[0],
4547 convert_to_mode (SImode, operands[1], 0)));
4552 (define_insn "*floathidf2_i387"
4553 [(set (match_operand:DF 0 "register_operand" "=f,f")
4554 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4555 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4559 [(set_attr "type" "fmov,multi")
4560 (set_attr "mode" "DF")
4561 (set_attr "unit" "*,i387")
4562 (set_attr "fp_int_src" "true")])
4564 (define_expand "floatsidf2"
4565 [(set (match_operand:DF 0 "register_operand" "")
4566 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4567 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4570 (define_insn "*floatsidf2_mixed"
4571 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4572 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4573 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4577 cvtsi2sd\t{%1, %0|%0, %1}
4578 cvtsi2sd\t{%1, %0|%0, %1}"
4579 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4580 (set_attr "mode" "DF")
4581 (set_attr "unit" "*,i387,*,*")
4582 (set_attr "athlon_decode" "*,*,double,direct")
4583 (set_attr "fp_int_src" "true")])
4585 (define_insn "*floatsidf2_sse"
4586 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4587 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4588 "TARGET_SSE2 && TARGET_SSE_MATH"
4589 "cvtsi2sd\t{%1, %0|%0, %1}"
4590 [(set_attr "type" "sseicvt")
4591 (set_attr "mode" "DF")
4592 (set_attr "athlon_decode" "double,direct")
4593 (set_attr "fp_int_src" "true")])
4595 (define_insn "*floatsidf2_i387"
4596 [(set (match_operand:DF 0 "register_operand" "=f,f")
4597 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4602 [(set_attr "type" "fmov,multi")
4603 (set_attr "mode" "DF")
4604 (set_attr "unit" "*,i387")
4605 (set_attr "fp_int_src" "true")])
4607 (define_expand "floatdidf2"
4608 [(set (match_operand:DF 0 "register_operand" "")
4609 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4610 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4613 (define_insn "*floatdidf2_mixed"
4614 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4615 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4616 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4620 cvtsi2sd{q}\t{%1, %0|%0, %1}
4621 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4622 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4623 (set_attr "mode" "DF")
4624 (set_attr "unit" "*,i387,*,*")
4625 (set_attr "athlon_decode" "*,*,double,direct")
4626 (set_attr "fp_int_src" "true")])
4628 (define_insn "*floatdidf2_sse"
4629 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4630 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4631 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4632 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4633 [(set_attr "type" "sseicvt")
4634 (set_attr "mode" "DF")
4635 (set_attr "athlon_decode" "double,direct")
4636 (set_attr "fp_int_src" "true")])
4638 (define_insn "*floatdidf2_i387"
4639 [(set (match_operand:DF 0 "register_operand" "=f,f")
4640 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4645 [(set_attr "type" "fmov,multi")
4646 (set_attr "mode" "DF")
4647 (set_attr "unit" "*,i387")
4648 (set_attr "fp_int_src" "true")])
4650 (define_insn "floathixf2"
4651 [(set (match_operand:XF 0 "register_operand" "=f,f")
4652 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4657 [(set_attr "type" "fmov,multi")
4658 (set_attr "mode" "XF")
4659 (set_attr "unit" "*,i387")
4660 (set_attr "fp_int_src" "true")])
4662 (define_insn "floatsixf2"
4663 [(set (match_operand:XF 0 "register_operand" "=f,f")
4664 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4669 [(set_attr "type" "fmov,multi")
4670 (set_attr "mode" "XF")
4671 (set_attr "unit" "*,i387")
4672 (set_attr "fp_int_src" "true")])
4674 (define_insn "floatdixf2"
4675 [(set (match_operand:XF 0 "register_operand" "=f,f")
4676 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4681 [(set_attr "type" "fmov,multi")
4682 (set_attr "mode" "XF")
4683 (set_attr "unit" "*,i387")
4684 (set_attr "fp_int_src" "true")])
4686 ;; %%% Kill these when reload knows how to do it.
4688 [(set (match_operand 0 "fp_register_operand" "")
4689 (float (match_operand 1 "register_operand" "")))]
4692 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4695 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4696 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4697 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4698 ix86_free_from_memory (GET_MODE (operands[1]));
4702 (define_expand "floatunssisf2"
4703 [(use (match_operand:SF 0 "register_operand" ""))
4704 (use (match_operand:SI 1 "register_operand" ""))]
4705 "!TARGET_64BIT && TARGET_SSE_MATH"
4706 "x86_emit_floatuns (operands); DONE;")
4708 (define_expand "floatunsdisf2"
4709 [(use (match_operand:SF 0 "register_operand" ""))
4710 (use (match_operand:DI 1 "register_operand" ""))]
4711 "TARGET_64BIT && TARGET_SSE_MATH"
4712 "x86_emit_floatuns (operands); DONE;")
4714 (define_expand "floatunsdidf2"
4715 [(use (match_operand:DF 0 "register_operand" ""))
4716 (use (match_operand:DI 1 "register_operand" ""))]
4717 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4718 "x86_emit_floatuns (operands); DONE;")
4720 ;; SSE extract/set expanders
4725 ;; %%% splits for addditi3
4727 (define_expand "addti3"
4728 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4729 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4730 (match_operand:TI 2 "x86_64_general_operand" "")))
4731 (clobber (reg:CC FLAGS_REG))]
4733 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4735 (define_insn "*addti3_1"
4736 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4737 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4738 (match_operand:TI 2 "general_operand" "roiF,riF")))
4739 (clobber (reg:CC FLAGS_REG))]
4740 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4744 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4745 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4746 (match_operand:TI 2 "general_operand" "")))
4747 (clobber (reg:CC FLAGS_REG))]
4748 "TARGET_64BIT && reload_completed"
4749 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4751 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4752 (parallel [(set (match_dup 3)
4753 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4756 (clobber (reg:CC FLAGS_REG))])]
4757 "split_ti (operands+0, 1, operands+0, operands+3);
4758 split_ti (operands+1, 1, operands+1, operands+4);
4759 split_ti (operands+2, 1, operands+2, operands+5);")
4761 ;; %%% splits for addsidi3
4762 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4763 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4764 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4766 (define_expand "adddi3"
4767 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4768 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4769 (match_operand:DI 2 "x86_64_general_operand" "")))
4770 (clobber (reg:CC FLAGS_REG))]
4772 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4774 (define_insn "*adddi3_1"
4775 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4776 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4777 (match_operand:DI 2 "general_operand" "roiF,riF")))
4778 (clobber (reg:CC FLAGS_REG))]
4779 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4783 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4784 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4785 (match_operand:DI 2 "general_operand" "")))
4786 (clobber (reg:CC FLAGS_REG))]
4787 "!TARGET_64BIT && reload_completed"
4788 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4790 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4791 (parallel [(set (match_dup 3)
4792 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4795 (clobber (reg:CC FLAGS_REG))])]
4796 "split_di (operands+0, 1, operands+0, operands+3);
4797 split_di (operands+1, 1, operands+1, operands+4);
4798 split_di (operands+2, 1, operands+2, operands+5);")
4800 (define_insn "adddi3_carry_rex64"
4801 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4802 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4803 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4804 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4805 (clobber (reg:CC FLAGS_REG))]
4806 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4807 "adc{q}\t{%2, %0|%0, %2}"
4808 [(set_attr "type" "alu")
4809 (set_attr "pent_pair" "pu")
4810 (set_attr "mode" "DI")])
4812 (define_insn "*adddi3_cc_rex64"
4813 [(set (reg:CC FLAGS_REG)
4814 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4815 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4817 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4818 (plus:DI (match_dup 1) (match_dup 2)))]
4819 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4820 "add{q}\t{%2, %0|%0, %2}"
4821 [(set_attr "type" "alu")
4822 (set_attr "mode" "DI")])
4824 (define_insn "addqi3_carry"
4825 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4826 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4827 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4828 (match_operand:QI 2 "general_operand" "qi,qm")))
4829 (clobber (reg:CC FLAGS_REG))]
4830 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4831 "adc{b}\t{%2, %0|%0, %2}"
4832 [(set_attr "type" "alu")
4833 (set_attr "pent_pair" "pu")
4834 (set_attr "mode" "QI")])
4836 (define_insn "addhi3_carry"
4837 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4838 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4839 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4840 (match_operand:HI 2 "general_operand" "ri,rm")))
4841 (clobber (reg:CC FLAGS_REG))]
4842 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4843 "adc{w}\t{%2, %0|%0, %2}"
4844 [(set_attr "type" "alu")
4845 (set_attr "pent_pair" "pu")
4846 (set_attr "mode" "HI")])
4848 (define_insn "addsi3_carry"
4849 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4850 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4851 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4852 (match_operand:SI 2 "general_operand" "ri,rm")))
4853 (clobber (reg:CC FLAGS_REG))]
4854 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4855 "adc{l}\t{%2, %0|%0, %2}"
4856 [(set_attr "type" "alu")
4857 (set_attr "pent_pair" "pu")
4858 (set_attr "mode" "SI")])
4860 (define_insn "*addsi3_carry_zext"
4861 [(set (match_operand:DI 0 "register_operand" "=r")
4863 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4864 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4865 (match_operand:SI 2 "general_operand" "rim"))))
4866 (clobber (reg:CC FLAGS_REG))]
4867 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4868 "adc{l}\t{%2, %k0|%k0, %2}"
4869 [(set_attr "type" "alu")
4870 (set_attr "pent_pair" "pu")
4871 (set_attr "mode" "SI")])
4873 (define_insn "*addsi3_cc"
4874 [(set (reg:CC FLAGS_REG)
4875 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4876 (match_operand:SI 2 "general_operand" "ri,rm")]
4878 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4879 (plus:SI (match_dup 1) (match_dup 2)))]
4880 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4881 "add{l}\t{%2, %0|%0, %2}"
4882 [(set_attr "type" "alu")
4883 (set_attr "mode" "SI")])
4885 (define_insn "addqi3_cc"
4886 [(set (reg:CC FLAGS_REG)
4887 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4888 (match_operand:QI 2 "general_operand" "qi,qm")]
4890 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4891 (plus:QI (match_dup 1) (match_dup 2)))]
4892 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4893 "add{b}\t{%2, %0|%0, %2}"
4894 [(set_attr "type" "alu")
4895 (set_attr "mode" "QI")])
4897 (define_expand "addsi3"
4898 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4899 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4900 (match_operand:SI 2 "general_operand" "")))
4901 (clobber (reg:CC FLAGS_REG))])]
4903 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4905 (define_insn "*lea_1"
4906 [(set (match_operand:SI 0 "register_operand" "=r")
4907 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4909 "lea{l}\t{%a1, %0|%0, %a1}"
4910 [(set_attr "type" "lea")
4911 (set_attr "mode" "SI")])
4913 (define_insn "*lea_1_rex64"
4914 [(set (match_operand:SI 0 "register_operand" "=r")
4915 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4917 "lea{l}\t{%a1, %0|%0, %a1}"
4918 [(set_attr "type" "lea")
4919 (set_attr "mode" "SI")])
4921 (define_insn "*lea_1_zext"
4922 [(set (match_operand:DI 0 "register_operand" "=r")
4924 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4926 "lea{l}\t{%a1, %k0|%k0, %a1}"
4927 [(set_attr "type" "lea")
4928 (set_attr "mode" "SI")])
4930 (define_insn "*lea_2_rex64"
4931 [(set (match_operand:DI 0 "register_operand" "=r")
4932 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4934 "lea{q}\t{%a1, %0|%0, %a1}"
4935 [(set_attr "type" "lea")
4936 (set_attr "mode" "DI")])
4938 ;; The lea patterns for non-Pmodes needs to be matched by several
4939 ;; insns converted to real lea by splitters.
4941 (define_insn_and_split "*lea_general_1"
4942 [(set (match_operand 0 "register_operand" "=r")
4943 (plus (plus (match_operand 1 "index_register_operand" "l")
4944 (match_operand 2 "register_operand" "r"))
4945 (match_operand 3 "immediate_operand" "i")))]
4946 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4947 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4948 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4949 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4950 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4951 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4952 || GET_MODE (operands[3]) == VOIDmode)"
4954 "&& reload_completed"
4958 operands[0] = gen_lowpart (SImode, operands[0]);
4959 operands[1] = gen_lowpart (Pmode, operands[1]);
4960 operands[2] = gen_lowpart (Pmode, operands[2]);
4961 operands[3] = gen_lowpart (Pmode, operands[3]);
4962 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4964 if (Pmode != SImode)
4965 pat = gen_rtx_SUBREG (SImode, pat, 0);
4966 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4969 [(set_attr "type" "lea")
4970 (set_attr "mode" "SI")])
4972 (define_insn_and_split "*lea_general_1_zext"
4973 [(set (match_operand:DI 0 "register_operand" "=r")
4975 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4976 (match_operand:SI 2 "register_operand" "r"))
4977 (match_operand:SI 3 "immediate_operand" "i"))))]
4980 "&& reload_completed"
4982 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4984 (match_dup 3)) 0)))]
4986 operands[1] = gen_lowpart (Pmode, operands[1]);
4987 operands[2] = gen_lowpart (Pmode, operands[2]);
4988 operands[3] = gen_lowpart (Pmode, operands[3]);
4990 [(set_attr "type" "lea")
4991 (set_attr "mode" "SI")])
4993 (define_insn_and_split "*lea_general_2"
4994 [(set (match_operand 0 "register_operand" "=r")
4995 (plus (mult (match_operand 1 "index_register_operand" "l")
4996 (match_operand 2 "const248_operand" "i"))
4997 (match_operand 3 "nonmemory_operand" "ri")))]
4998 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4999 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5000 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5001 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5002 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5003 || GET_MODE (operands[3]) == VOIDmode)"
5005 "&& reload_completed"
5009 operands[0] = gen_lowpart (SImode, operands[0]);
5010 operands[1] = gen_lowpart (Pmode, operands[1]);
5011 operands[3] = gen_lowpart (Pmode, operands[3]);
5012 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5014 if (Pmode != SImode)
5015 pat = gen_rtx_SUBREG (SImode, pat, 0);
5016 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5019 [(set_attr "type" "lea")
5020 (set_attr "mode" "SI")])
5022 (define_insn_and_split "*lea_general_2_zext"
5023 [(set (match_operand:DI 0 "register_operand" "=r")
5025 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5026 (match_operand:SI 2 "const248_operand" "n"))
5027 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5030 "&& reload_completed"
5032 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5034 (match_dup 3)) 0)))]
5036 operands[1] = gen_lowpart (Pmode, operands[1]);
5037 operands[3] = gen_lowpart (Pmode, operands[3]);
5039 [(set_attr "type" "lea")
5040 (set_attr "mode" "SI")])
5042 (define_insn_and_split "*lea_general_3"
5043 [(set (match_operand 0 "register_operand" "=r")
5044 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5045 (match_operand 2 "const248_operand" "i"))
5046 (match_operand 3 "register_operand" "r"))
5047 (match_operand 4 "immediate_operand" "i")))]
5048 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5049 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5050 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5051 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5052 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5054 "&& reload_completed"
5058 operands[0] = gen_lowpart (SImode, operands[0]);
5059 operands[1] = gen_lowpart (Pmode, operands[1]);
5060 operands[3] = gen_lowpart (Pmode, operands[3]);
5061 operands[4] = gen_lowpart (Pmode, operands[4]);
5062 pat = gen_rtx_PLUS (Pmode,
5063 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5067 if (Pmode != SImode)
5068 pat = gen_rtx_SUBREG (SImode, pat, 0);
5069 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5072 [(set_attr "type" "lea")
5073 (set_attr "mode" "SI")])
5075 (define_insn_and_split "*lea_general_3_zext"
5076 [(set (match_operand:DI 0 "register_operand" "=r")
5078 (plus:SI (plus:SI (mult:SI
5079 (match_operand:SI 1 "index_register_operand" "l")
5080 (match_operand:SI 2 "const248_operand" "n"))
5081 (match_operand:SI 3 "register_operand" "r"))
5082 (match_operand:SI 4 "immediate_operand" "i"))))]
5085 "&& reload_completed"
5087 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5090 (match_dup 4)) 0)))]
5092 operands[1] = gen_lowpart (Pmode, operands[1]);
5093 operands[3] = gen_lowpart (Pmode, operands[3]);
5094 operands[4] = gen_lowpart (Pmode, operands[4]);
5096 [(set_attr "type" "lea")
5097 (set_attr "mode" "SI")])
5099 (define_insn "*adddi_1_rex64"
5100 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5101 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5102 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5103 (clobber (reg:CC FLAGS_REG))]
5104 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5106 switch (get_attr_type (insn))
5109 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5110 return "lea{q}\t{%a2, %0|%0, %a2}";
5113 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5114 if (operands[2] == const1_rtx)
5115 return "inc{q}\t%0";
5118 gcc_assert (operands[2] == constm1_rtx);
5119 return "dec{q}\t%0";
5123 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5125 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5126 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5127 if (GET_CODE (operands[2]) == CONST_INT
5128 /* Avoid overflows. */
5129 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5130 && (INTVAL (operands[2]) == 128
5131 || (INTVAL (operands[2]) < 0
5132 && INTVAL (operands[2]) != -128)))
5134 operands[2] = GEN_INT (-INTVAL (operands[2]));
5135 return "sub{q}\t{%2, %0|%0, %2}";
5137 return "add{q}\t{%2, %0|%0, %2}";
5141 (cond [(eq_attr "alternative" "2")
5142 (const_string "lea")
5143 ; Current assemblers are broken and do not allow @GOTOFF in
5144 ; ought but a memory context.
5145 (match_operand:DI 2 "pic_symbolic_operand" "")
5146 (const_string "lea")
5147 (match_operand:DI 2 "incdec_operand" "")
5148 (const_string "incdec")
5150 (const_string "alu")))
5151 (set_attr "mode" "DI")])
5153 ;; Convert lea to the lea pattern to avoid flags dependency.
5155 [(set (match_operand:DI 0 "register_operand" "")
5156 (plus:DI (match_operand:DI 1 "register_operand" "")
5157 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5158 (clobber (reg:CC FLAGS_REG))]
5159 "TARGET_64BIT && reload_completed
5160 && true_regnum (operands[0]) != true_regnum (operands[1])"
5162 (plus:DI (match_dup 1)
5166 (define_insn "*adddi_2_rex64"
5167 [(set (reg FLAGS_REG)
5169 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5170 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5172 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5173 (plus:DI (match_dup 1) (match_dup 2)))]
5174 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5175 && ix86_binary_operator_ok (PLUS, DImode, operands)
5176 /* Current assemblers are broken and do not allow @GOTOFF in
5177 ought but a memory context. */
5178 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5180 switch (get_attr_type (insn))
5183 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5184 if (operands[2] == const1_rtx)
5185 return "inc{q}\t%0";
5188 gcc_assert (operands[2] == constm1_rtx);
5189 return "dec{q}\t%0";
5193 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5194 /* ???? We ought to handle there the 32bit case too
5195 - do we need new constraint? */
5196 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5197 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5198 if (GET_CODE (operands[2]) == CONST_INT
5199 /* Avoid overflows. */
5200 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5201 && (INTVAL (operands[2]) == 128
5202 || (INTVAL (operands[2]) < 0
5203 && INTVAL (operands[2]) != -128)))
5205 operands[2] = GEN_INT (-INTVAL (operands[2]));
5206 return "sub{q}\t{%2, %0|%0, %2}";
5208 return "add{q}\t{%2, %0|%0, %2}";
5212 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5213 (const_string "incdec")
5214 (const_string "alu")))
5215 (set_attr "mode" "DI")])
5217 (define_insn "*adddi_3_rex64"
5218 [(set (reg FLAGS_REG)
5219 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5220 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5221 (clobber (match_scratch:DI 0 "=r"))]
5223 && ix86_match_ccmode (insn, CCZmode)
5224 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5225 /* Current assemblers are broken and do not allow @GOTOFF in
5226 ought but a memory context. */
5227 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5229 switch (get_attr_type (insn))
5232 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5233 if (operands[2] == const1_rtx)
5234 return "inc{q}\t%0";
5237 gcc_assert (operands[2] == constm1_rtx);
5238 return "dec{q}\t%0";
5242 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5243 /* ???? We ought to handle there the 32bit case too
5244 - do we need new constraint? */
5245 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5246 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5247 if (GET_CODE (operands[2]) == CONST_INT
5248 /* Avoid overflows. */
5249 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5250 && (INTVAL (operands[2]) == 128
5251 || (INTVAL (operands[2]) < 0
5252 && INTVAL (operands[2]) != -128)))
5254 operands[2] = GEN_INT (-INTVAL (operands[2]));
5255 return "sub{q}\t{%2, %0|%0, %2}";
5257 return "add{q}\t{%2, %0|%0, %2}";
5261 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5262 (const_string "incdec")
5263 (const_string "alu")))
5264 (set_attr "mode" "DI")])
5266 ; For comparisons against 1, -1 and 128, we may generate better code
5267 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5268 ; is matched then. We can't accept general immediate, because for
5269 ; case of overflows, the result is messed up.
5270 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5272 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5273 ; only for comparisons not depending on it.
5274 (define_insn "*adddi_4_rex64"
5275 [(set (reg FLAGS_REG)
5276 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5277 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5278 (clobber (match_scratch:DI 0 "=rm"))]
5280 && ix86_match_ccmode (insn, CCGCmode)"
5282 switch (get_attr_type (insn))
5285 if (operands[2] == constm1_rtx)
5286 return "inc{q}\t%0";
5289 gcc_assert (operands[2] == const1_rtx);
5290 return "dec{q}\t%0";
5294 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5295 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5296 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5297 if ((INTVAL (operands[2]) == -128
5298 || (INTVAL (operands[2]) > 0
5299 && INTVAL (operands[2]) != 128))
5300 /* Avoid overflows. */
5301 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5302 return "sub{q}\t{%2, %0|%0, %2}";
5303 operands[2] = GEN_INT (-INTVAL (operands[2]));
5304 return "add{q}\t{%2, %0|%0, %2}";
5308 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5309 (const_string "incdec")
5310 (const_string "alu")))
5311 (set_attr "mode" "DI")])
5313 (define_insn "*adddi_5_rex64"
5314 [(set (reg FLAGS_REG)
5316 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5317 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5319 (clobber (match_scratch:DI 0 "=r"))]
5321 && ix86_match_ccmode (insn, CCGOCmode)
5322 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5323 /* Current assemblers are broken and do not allow @GOTOFF in
5324 ought but a memory context. */
5325 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5327 switch (get_attr_type (insn))
5330 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5331 if (operands[2] == const1_rtx)
5332 return "inc{q}\t%0";
5335 gcc_assert (operands[2] == constm1_rtx);
5336 return "dec{q}\t%0";
5340 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5341 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5342 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5343 if (GET_CODE (operands[2]) == CONST_INT
5344 /* Avoid overflows. */
5345 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5346 && (INTVAL (operands[2]) == 128
5347 || (INTVAL (operands[2]) < 0
5348 && INTVAL (operands[2]) != -128)))
5350 operands[2] = GEN_INT (-INTVAL (operands[2]));
5351 return "sub{q}\t{%2, %0|%0, %2}";
5353 return "add{q}\t{%2, %0|%0, %2}";
5357 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5358 (const_string "incdec")
5359 (const_string "alu")))
5360 (set_attr "mode" "DI")])
5363 (define_insn "*addsi_1"
5364 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5365 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5366 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5367 (clobber (reg:CC FLAGS_REG))]
5368 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5370 switch (get_attr_type (insn))
5373 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5374 return "lea{l}\t{%a2, %0|%0, %a2}";
5377 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5378 if (operands[2] == const1_rtx)
5379 return "inc{l}\t%0";
5382 gcc_assert (operands[2] == constm1_rtx);
5383 return "dec{l}\t%0";
5387 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5389 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5390 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5391 if (GET_CODE (operands[2]) == CONST_INT
5392 && (INTVAL (operands[2]) == 128
5393 || (INTVAL (operands[2]) < 0
5394 && INTVAL (operands[2]) != -128)))
5396 operands[2] = GEN_INT (-INTVAL (operands[2]));
5397 return "sub{l}\t{%2, %0|%0, %2}";
5399 return "add{l}\t{%2, %0|%0, %2}";
5403 (cond [(eq_attr "alternative" "2")
5404 (const_string "lea")
5405 ; Current assemblers are broken and do not allow @GOTOFF in
5406 ; ought but a memory context.
5407 (match_operand:SI 2 "pic_symbolic_operand" "")
5408 (const_string "lea")
5409 (match_operand:SI 2 "incdec_operand" "")
5410 (const_string "incdec")
5412 (const_string "alu")))
5413 (set_attr "mode" "SI")])
5415 ;; Convert lea to the lea pattern to avoid flags dependency.
5417 [(set (match_operand 0 "register_operand" "")
5418 (plus (match_operand 1 "register_operand" "")
5419 (match_operand 2 "nonmemory_operand" "")))
5420 (clobber (reg:CC FLAGS_REG))]
5422 && true_regnum (operands[0]) != true_regnum (operands[1])"
5426 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5427 may confuse gen_lowpart. */
5428 if (GET_MODE (operands[0]) != Pmode)
5430 operands[1] = gen_lowpart (Pmode, operands[1]);
5431 operands[2] = gen_lowpart (Pmode, operands[2]);
5433 operands[0] = gen_lowpart (SImode, operands[0]);
5434 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5435 if (Pmode != SImode)
5436 pat = gen_rtx_SUBREG (SImode, pat, 0);
5437 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5441 ;; It may seem that nonimmediate operand is proper one for operand 1.
5442 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5443 ;; we take care in ix86_binary_operator_ok to not allow two memory
5444 ;; operands so proper swapping will be done in reload. This allow
5445 ;; patterns constructed from addsi_1 to match.
5446 (define_insn "addsi_1_zext"
5447 [(set (match_operand:DI 0 "register_operand" "=r,r")
5449 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5450 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5451 (clobber (reg:CC FLAGS_REG))]
5452 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5454 switch (get_attr_type (insn))
5457 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5458 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5461 if (operands[2] == const1_rtx)
5462 return "inc{l}\t%k0";
5465 gcc_assert (operands[2] == constm1_rtx);
5466 return "dec{l}\t%k0";
5470 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5471 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5472 if (GET_CODE (operands[2]) == CONST_INT
5473 && (INTVAL (operands[2]) == 128
5474 || (INTVAL (operands[2]) < 0
5475 && INTVAL (operands[2]) != -128)))
5477 operands[2] = GEN_INT (-INTVAL (operands[2]));
5478 return "sub{l}\t{%2, %k0|%k0, %2}";
5480 return "add{l}\t{%2, %k0|%k0, %2}";
5484 (cond [(eq_attr "alternative" "1")
5485 (const_string "lea")
5486 ; Current assemblers are broken and do not allow @GOTOFF in
5487 ; ought but a memory context.
5488 (match_operand:SI 2 "pic_symbolic_operand" "")
5489 (const_string "lea")
5490 (match_operand:SI 2 "incdec_operand" "")
5491 (const_string "incdec")
5493 (const_string "alu")))
5494 (set_attr "mode" "SI")])
5496 ;; Convert lea to the lea pattern to avoid flags dependency.
5498 [(set (match_operand:DI 0 "register_operand" "")
5500 (plus:SI (match_operand:SI 1 "register_operand" "")
5501 (match_operand:SI 2 "nonmemory_operand" ""))))
5502 (clobber (reg:CC FLAGS_REG))]
5503 "TARGET_64BIT && reload_completed
5504 && true_regnum (operands[0]) != true_regnum (operands[1])"
5506 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5508 operands[1] = gen_lowpart (Pmode, operands[1]);
5509 operands[2] = gen_lowpart (Pmode, operands[2]);
5512 (define_insn "*addsi_2"
5513 [(set (reg FLAGS_REG)
5515 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5516 (match_operand:SI 2 "general_operand" "rmni,rni"))
5518 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5519 (plus:SI (match_dup 1) (match_dup 2)))]
5520 "ix86_match_ccmode (insn, CCGOCmode)
5521 && ix86_binary_operator_ok (PLUS, SImode, operands)
5522 /* Current assemblers are broken and do not allow @GOTOFF in
5523 ought but a memory context. */
5524 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5526 switch (get_attr_type (insn))
5529 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5530 if (operands[2] == const1_rtx)
5531 return "inc{l}\t%0";
5534 gcc_assert (operands[2] == constm1_rtx);
5535 return "dec{l}\t%0";
5539 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5540 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5541 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5542 if (GET_CODE (operands[2]) == CONST_INT
5543 && (INTVAL (operands[2]) == 128
5544 || (INTVAL (operands[2]) < 0
5545 && INTVAL (operands[2]) != -128)))
5547 operands[2] = GEN_INT (-INTVAL (operands[2]));
5548 return "sub{l}\t{%2, %0|%0, %2}";
5550 return "add{l}\t{%2, %0|%0, %2}";
5554 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5555 (const_string "incdec")
5556 (const_string "alu")))
5557 (set_attr "mode" "SI")])
5559 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5560 (define_insn "*addsi_2_zext"
5561 [(set (reg FLAGS_REG)
5563 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5564 (match_operand:SI 2 "general_operand" "rmni"))
5566 (set (match_operand:DI 0 "register_operand" "=r")
5567 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5568 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5569 && ix86_binary_operator_ok (PLUS, SImode, operands)
5570 /* Current assemblers are broken and do not allow @GOTOFF in
5571 ought but a memory context. */
5572 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5574 switch (get_attr_type (insn))
5577 if (operands[2] == const1_rtx)
5578 return "inc{l}\t%k0";
5581 gcc_assert (operands[2] == constm1_rtx);
5582 return "dec{l}\t%k0";
5586 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5587 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5588 if (GET_CODE (operands[2]) == CONST_INT
5589 && (INTVAL (operands[2]) == 128
5590 || (INTVAL (operands[2]) < 0
5591 && INTVAL (operands[2]) != -128)))
5593 operands[2] = GEN_INT (-INTVAL (operands[2]));
5594 return "sub{l}\t{%2, %k0|%k0, %2}";
5596 return "add{l}\t{%2, %k0|%k0, %2}";
5600 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5601 (const_string "incdec")
5602 (const_string "alu")))
5603 (set_attr "mode" "SI")])
5605 (define_insn "*addsi_3"
5606 [(set (reg FLAGS_REG)
5607 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5608 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5609 (clobber (match_scratch:SI 0 "=r"))]
5610 "ix86_match_ccmode (insn, CCZmode)
5611 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5612 /* Current assemblers are broken and do not allow @GOTOFF in
5613 ought but a memory context. */
5614 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5616 switch (get_attr_type (insn))
5619 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5620 if (operands[2] == const1_rtx)
5621 return "inc{l}\t%0";
5624 gcc_assert (operands[2] == constm1_rtx);
5625 return "dec{l}\t%0";
5629 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5630 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5631 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5632 if (GET_CODE (operands[2]) == CONST_INT
5633 && (INTVAL (operands[2]) == 128
5634 || (INTVAL (operands[2]) < 0
5635 && INTVAL (operands[2]) != -128)))
5637 operands[2] = GEN_INT (-INTVAL (operands[2]));
5638 return "sub{l}\t{%2, %0|%0, %2}";
5640 return "add{l}\t{%2, %0|%0, %2}";
5644 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5645 (const_string "incdec")
5646 (const_string "alu")))
5647 (set_attr "mode" "SI")])
5649 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5650 (define_insn "*addsi_3_zext"
5651 [(set (reg FLAGS_REG)
5652 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5653 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5654 (set (match_operand:DI 0 "register_operand" "=r")
5655 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5656 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5657 && ix86_binary_operator_ok (PLUS, SImode, operands)
5658 /* Current assemblers are broken and do not allow @GOTOFF in
5659 ought but a memory context. */
5660 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5662 switch (get_attr_type (insn))
5665 if (operands[2] == const1_rtx)
5666 return "inc{l}\t%k0";
5669 gcc_assert (operands[2] == constm1_rtx);
5670 return "dec{l}\t%k0";
5674 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5675 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5676 if (GET_CODE (operands[2]) == CONST_INT
5677 && (INTVAL (operands[2]) == 128
5678 || (INTVAL (operands[2]) < 0
5679 && INTVAL (operands[2]) != -128)))
5681 operands[2] = GEN_INT (-INTVAL (operands[2]));
5682 return "sub{l}\t{%2, %k0|%k0, %2}";
5684 return "add{l}\t{%2, %k0|%k0, %2}";
5688 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5689 (const_string "incdec")
5690 (const_string "alu")))
5691 (set_attr "mode" "SI")])
5693 ; For comparisons against 1, -1 and 128, we may generate better code
5694 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5695 ; is matched then. We can't accept general immediate, because for
5696 ; case of overflows, the result is messed up.
5697 ; This pattern also don't hold of 0x80000000, since the value overflows
5699 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5700 ; only for comparisons not depending on it.
5701 (define_insn "*addsi_4"
5702 [(set (reg FLAGS_REG)
5703 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5704 (match_operand:SI 2 "const_int_operand" "n")))
5705 (clobber (match_scratch:SI 0 "=rm"))]
5706 "ix86_match_ccmode (insn, CCGCmode)
5707 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5709 switch (get_attr_type (insn))
5712 if (operands[2] == constm1_rtx)
5713 return "inc{l}\t%0";
5716 gcc_assert (operands[2] == const1_rtx);
5717 return "dec{l}\t%0";
5721 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5722 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5723 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5724 if ((INTVAL (operands[2]) == -128
5725 || (INTVAL (operands[2]) > 0
5726 && INTVAL (operands[2]) != 128)))
5727 return "sub{l}\t{%2, %0|%0, %2}";
5728 operands[2] = GEN_INT (-INTVAL (operands[2]));
5729 return "add{l}\t{%2, %0|%0, %2}";
5733 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5734 (const_string "incdec")
5735 (const_string "alu")))
5736 (set_attr "mode" "SI")])
5738 (define_insn "*addsi_5"
5739 [(set (reg FLAGS_REG)
5741 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5742 (match_operand:SI 2 "general_operand" "rmni"))
5744 (clobber (match_scratch:SI 0 "=r"))]
5745 "ix86_match_ccmode (insn, CCGOCmode)
5746 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5747 /* Current assemblers are broken and do not allow @GOTOFF in
5748 ought but a memory context. */
5749 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5751 switch (get_attr_type (insn))
5754 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5755 if (operands[2] == const1_rtx)
5756 return "inc{l}\t%0";
5759 gcc_assert (operands[2] == constm1_rtx);
5760 return "dec{l}\t%0";
5764 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5765 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5766 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5767 if (GET_CODE (operands[2]) == CONST_INT
5768 && (INTVAL (operands[2]) == 128
5769 || (INTVAL (operands[2]) < 0
5770 && INTVAL (operands[2]) != -128)))
5772 operands[2] = GEN_INT (-INTVAL (operands[2]));
5773 return "sub{l}\t{%2, %0|%0, %2}";
5775 return "add{l}\t{%2, %0|%0, %2}";
5779 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5780 (const_string "incdec")
5781 (const_string "alu")))
5782 (set_attr "mode" "SI")])
5784 (define_expand "addhi3"
5785 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5786 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5787 (match_operand:HI 2 "general_operand" "")))
5788 (clobber (reg:CC FLAGS_REG))])]
5789 "TARGET_HIMODE_MATH"
5790 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5792 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5793 ;; type optimizations enabled by define-splits. This is not important
5794 ;; for PII, and in fact harmful because of partial register stalls.
5796 (define_insn "*addhi_1_lea"
5797 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5798 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5799 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5800 (clobber (reg:CC FLAGS_REG))]
5801 "!TARGET_PARTIAL_REG_STALL
5802 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5804 switch (get_attr_type (insn))
5809 if (operands[2] == const1_rtx)
5810 return "inc{w}\t%0";
5813 gcc_assert (operands[2] == constm1_rtx);
5814 return "dec{w}\t%0";
5818 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5819 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5820 if (GET_CODE (operands[2]) == CONST_INT
5821 && (INTVAL (operands[2]) == 128
5822 || (INTVAL (operands[2]) < 0
5823 && INTVAL (operands[2]) != -128)))
5825 operands[2] = GEN_INT (-INTVAL (operands[2]));
5826 return "sub{w}\t{%2, %0|%0, %2}";
5828 return "add{w}\t{%2, %0|%0, %2}";
5832 (if_then_else (eq_attr "alternative" "2")
5833 (const_string "lea")
5834 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5835 (const_string "incdec")
5836 (const_string "alu"))))
5837 (set_attr "mode" "HI,HI,SI")])
5839 (define_insn "*addhi_1"
5840 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5841 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5842 (match_operand:HI 2 "general_operand" "ri,rm")))
5843 (clobber (reg:CC FLAGS_REG))]
5844 "TARGET_PARTIAL_REG_STALL
5845 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5847 switch (get_attr_type (insn))
5850 if (operands[2] == const1_rtx)
5851 return "inc{w}\t%0";
5854 gcc_assert (operands[2] == constm1_rtx);
5855 return "dec{w}\t%0";
5859 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5860 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5861 if (GET_CODE (operands[2]) == CONST_INT
5862 && (INTVAL (operands[2]) == 128
5863 || (INTVAL (operands[2]) < 0
5864 && INTVAL (operands[2]) != -128)))
5866 operands[2] = GEN_INT (-INTVAL (operands[2]));
5867 return "sub{w}\t{%2, %0|%0, %2}";
5869 return "add{w}\t{%2, %0|%0, %2}";
5873 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5874 (const_string "incdec")
5875 (const_string "alu")))
5876 (set_attr "mode" "HI")])
5878 (define_insn "*addhi_2"
5879 [(set (reg FLAGS_REG)
5881 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5882 (match_operand:HI 2 "general_operand" "rmni,rni"))
5884 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5885 (plus:HI (match_dup 1) (match_dup 2)))]
5886 "ix86_match_ccmode (insn, CCGOCmode)
5887 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5889 switch (get_attr_type (insn))
5892 if (operands[2] == const1_rtx)
5893 return "inc{w}\t%0";
5896 gcc_assert (operands[2] == constm1_rtx);
5897 return "dec{w}\t%0";
5901 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5902 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5903 if (GET_CODE (operands[2]) == CONST_INT
5904 && (INTVAL (operands[2]) == 128
5905 || (INTVAL (operands[2]) < 0
5906 && INTVAL (operands[2]) != -128)))
5908 operands[2] = GEN_INT (-INTVAL (operands[2]));
5909 return "sub{w}\t{%2, %0|%0, %2}";
5911 return "add{w}\t{%2, %0|%0, %2}";
5915 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5916 (const_string "incdec")
5917 (const_string "alu")))
5918 (set_attr "mode" "HI")])
5920 (define_insn "*addhi_3"
5921 [(set (reg FLAGS_REG)
5922 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5923 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5924 (clobber (match_scratch:HI 0 "=r"))]
5925 "ix86_match_ccmode (insn, CCZmode)
5926 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5928 switch (get_attr_type (insn))
5931 if (operands[2] == const1_rtx)
5932 return "inc{w}\t%0";
5935 gcc_assert (operands[2] == constm1_rtx);
5936 return "dec{w}\t%0";
5940 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5941 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5942 if (GET_CODE (operands[2]) == CONST_INT
5943 && (INTVAL (operands[2]) == 128
5944 || (INTVAL (operands[2]) < 0
5945 && INTVAL (operands[2]) != -128)))
5947 operands[2] = GEN_INT (-INTVAL (operands[2]));
5948 return "sub{w}\t{%2, %0|%0, %2}";
5950 return "add{w}\t{%2, %0|%0, %2}";
5954 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5955 (const_string "incdec")
5956 (const_string "alu")))
5957 (set_attr "mode" "HI")])
5959 ; See comments above addsi_4 for details.
5960 (define_insn "*addhi_4"
5961 [(set (reg FLAGS_REG)
5962 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5963 (match_operand:HI 2 "const_int_operand" "n")))
5964 (clobber (match_scratch:HI 0 "=rm"))]
5965 "ix86_match_ccmode (insn, CCGCmode)
5966 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5968 switch (get_attr_type (insn))
5971 if (operands[2] == constm1_rtx)
5972 return "inc{w}\t%0";
5975 gcc_assert (operands[2] == const1_rtx);
5976 return "dec{w}\t%0";
5980 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5981 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5982 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5983 if ((INTVAL (operands[2]) == -128
5984 || (INTVAL (operands[2]) > 0
5985 && INTVAL (operands[2]) != 128)))
5986 return "sub{w}\t{%2, %0|%0, %2}";
5987 operands[2] = GEN_INT (-INTVAL (operands[2]));
5988 return "add{w}\t{%2, %0|%0, %2}";
5992 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5993 (const_string "incdec")
5994 (const_string "alu")))
5995 (set_attr "mode" "SI")])
5998 (define_insn "*addhi_5"
5999 [(set (reg FLAGS_REG)
6001 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6002 (match_operand:HI 2 "general_operand" "rmni"))
6004 (clobber (match_scratch:HI 0 "=r"))]
6005 "ix86_match_ccmode (insn, CCGOCmode)
6006 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6008 switch (get_attr_type (insn))
6011 if (operands[2] == const1_rtx)
6012 return "inc{w}\t%0";
6015 gcc_assert (operands[2] == constm1_rtx);
6016 return "dec{w}\t%0";
6020 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6021 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6022 if (GET_CODE (operands[2]) == CONST_INT
6023 && (INTVAL (operands[2]) == 128
6024 || (INTVAL (operands[2]) < 0
6025 && INTVAL (operands[2]) != -128)))
6027 operands[2] = GEN_INT (-INTVAL (operands[2]));
6028 return "sub{w}\t{%2, %0|%0, %2}";
6030 return "add{w}\t{%2, %0|%0, %2}";
6034 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6035 (const_string "incdec")
6036 (const_string "alu")))
6037 (set_attr "mode" "HI")])
6039 (define_expand "addqi3"
6040 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6041 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6042 (match_operand:QI 2 "general_operand" "")))
6043 (clobber (reg:CC FLAGS_REG))])]
6044 "TARGET_QIMODE_MATH"
6045 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6047 ;; %%% Potential partial reg stall on alternative 2. What to do?
6048 (define_insn "*addqi_1_lea"
6049 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6050 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6051 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6052 (clobber (reg:CC FLAGS_REG))]
6053 "!TARGET_PARTIAL_REG_STALL
6054 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6056 int widen = (which_alternative == 2);
6057 switch (get_attr_type (insn))
6062 if (operands[2] == const1_rtx)
6063 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6066 gcc_assert (operands[2] == constm1_rtx);
6067 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6071 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6072 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6073 if (GET_CODE (operands[2]) == CONST_INT
6074 && (INTVAL (operands[2]) == 128
6075 || (INTVAL (operands[2]) < 0
6076 && INTVAL (operands[2]) != -128)))
6078 operands[2] = GEN_INT (-INTVAL (operands[2]));
6080 return "sub{l}\t{%2, %k0|%k0, %2}";
6082 return "sub{b}\t{%2, %0|%0, %2}";
6085 return "add{l}\t{%k2, %k0|%k0, %k2}";
6087 return "add{b}\t{%2, %0|%0, %2}";
6091 (if_then_else (eq_attr "alternative" "3")
6092 (const_string "lea")
6093 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6094 (const_string "incdec")
6095 (const_string "alu"))))
6096 (set_attr "mode" "QI,QI,SI,SI")])
6098 (define_insn "*addqi_1"
6099 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6100 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6101 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6102 (clobber (reg:CC FLAGS_REG))]
6103 "TARGET_PARTIAL_REG_STALL
6104 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6106 int widen = (which_alternative == 2);
6107 switch (get_attr_type (insn))
6110 if (operands[2] == const1_rtx)
6111 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6114 gcc_assert (operands[2] == constm1_rtx);
6115 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6119 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6120 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6121 if (GET_CODE (operands[2]) == CONST_INT
6122 && (INTVAL (operands[2]) == 128
6123 || (INTVAL (operands[2]) < 0
6124 && INTVAL (operands[2]) != -128)))
6126 operands[2] = GEN_INT (-INTVAL (operands[2]));
6128 return "sub{l}\t{%2, %k0|%k0, %2}";
6130 return "sub{b}\t{%2, %0|%0, %2}";
6133 return "add{l}\t{%k2, %k0|%k0, %k2}";
6135 return "add{b}\t{%2, %0|%0, %2}";
6139 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6140 (const_string "incdec")
6141 (const_string "alu")))
6142 (set_attr "mode" "QI,QI,SI")])
6144 (define_insn "*addqi_1_slp"
6145 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6146 (plus:QI (match_dup 0)
6147 (match_operand:QI 1 "general_operand" "qn,qnm")))
6148 (clobber (reg:CC FLAGS_REG))]
6149 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6150 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6152 switch (get_attr_type (insn))
6155 if (operands[1] == const1_rtx)
6156 return "inc{b}\t%0";
6159 gcc_assert (operands[1] == constm1_rtx);
6160 return "dec{b}\t%0";
6164 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6165 if (GET_CODE (operands[1]) == CONST_INT
6166 && INTVAL (operands[1]) < 0)
6168 operands[1] = GEN_INT (-INTVAL (operands[1]));
6169 return "sub{b}\t{%1, %0|%0, %1}";
6171 return "add{b}\t{%1, %0|%0, %1}";
6175 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6176 (const_string "incdec")
6177 (const_string "alu1")))
6178 (set (attr "memory")
6179 (if_then_else (match_operand 1 "memory_operand" "")
6180 (const_string "load")
6181 (const_string "none")))
6182 (set_attr "mode" "QI")])
6184 (define_insn "*addqi_2"
6185 [(set (reg FLAGS_REG)
6187 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6188 (match_operand:QI 2 "general_operand" "qmni,qni"))
6190 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6191 (plus:QI (match_dup 1) (match_dup 2)))]
6192 "ix86_match_ccmode (insn, CCGOCmode)
6193 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6195 switch (get_attr_type (insn))
6198 if (operands[2] == const1_rtx)
6199 return "inc{b}\t%0";
6202 gcc_assert (operands[2] == constm1_rtx
6203 || (GET_CODE (operands[2]) == CONST_INT
6204 && INTVAL (operands[2]) == 255));
6205 return "dec{b}\t%0";
6209 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6210 if (GET_CODE (operands[2]) == CONST_INT
6211 && INTVAL (operands[2]) < 0)
6213 operands[2] = GEN_INT (-INTVAL (operands[2]));
6214 return "sub{b}\t{%2, %0|%0, %2}";
6216 return "add{b}\t{%2, %0|%0, %2}";
6220 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6221 (const_string "incdec")
6222 (const_string "alu")))
6223 (set_attr "mode" "QI")])
6225 (define_insn "*addqi_3"
6226 [(set (reg FLAGS_REG)
6227 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6228 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6229 (clobber (match_scratch:QI 0 "=q"))]
6230 "ix86_match_ccmode (insn, CCZmode)
6231 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6233 switch (get_attr_type (insn))
6236 if (operands[2] == const1_rtx)
6237 return "inc{b}\t%0";
6240 gcc_assert (operands[2] == constm1_rtx
6241 || (GET_CODE (operands[2]) == CONST_INT
6242 && INTVAL (operands[2]) == 255));
6243 return "dec{b}\t%0";
6247 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6248 if (GET_CODE (operands[2]) == CONST_INT
6249 && INTVAL (operands[2]) < 0)
6251 operands[2] = GEN_INT (-INTVAL (operands[2]));
6252 return "sub{b}\t{%2, %0|%0, %2}";
6254 return "add{b}\t{%2, %0|%0, %2}";
6258 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6259 (const_string "incdec")
6260 (const_string "alu")))
6261 (set_attr "mode" "QI")])
6263 ; See comments above addsi_4 for details.
6264 (define_insn "*addqi_4"
6265 [(set (reg FLAGS_REG)
6266 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6267 (match_operand:QI 2 "const_int_operand" "n")))
6268 (clobber (match_scratch:QI 0 "=qm"))]
6269 "ix86_match_ccmode (insn, CCGCmode)
6270 && (INTVAL (operands[2]) & 0xff) != 0x80"
6272 switch (get_attr_type (insn))
6275 if (operands[2] == constm1_rtx
6276 || (GET_CODE (operands[2]) == CONST_INT
6277 && INTVAL (operands[2]) == 255))
6278 return "inc{b}\t%0";
6281 gcc_assert (operands[2] == const1_rtx);
6282 return "dec{b}\t%0";
6286 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6287 if (INTVAL (operands[2]) < 0)
6289 operands[2] = GEN_INT (-INTVAL (operands[2]));
6290 return "add{b}\t{%2, %0|%0, %2}";
6292 return "sub{b}\t{%2, %0|%0, %2}";
6296 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6297 (const_string "incdec")
6298 (const_string "alu")))
6299 (set_attr "mode" "QI")])
6302 (define_insn "*addqi_5"
6303 [(set (reg FLAGS_REG)
6305 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6306 (match_operand:QI 2 "general_operand" "qmni"))
6308 (clobber (match_scratch:QI 0 "=q"))]
6309 "ix86_match_ccmode (insn, CCGOCmode)
6310 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6312 switch (get_attr_type (insn))
6315 if (operands[2] == const1_rtx)
6316 return "inc{b}\t%0";
6319 gcc_assert (operands[2] == constm1_rtx
6320 || (GET_CODE (operands[2]) == CONST_INT
6321 && INTVAL (operands[2]) == 255));
6322 return "dec{b}\t%0";
6326 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6327 if (GET_CODE (operands[2]) == CONST_INT
6328 && INTVAL (operands[2]) < 0)
6330 operands[2] = GEN_INT (-INTVAL (operands[2]));
6331 return "sub{b}\t{%2, %0|%0, %2}";
6333 return "add{b}\t{%2, %0|%0, %2}";
6337 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6338 (const_string "incdec")
6339 (const_string "alu")))
6340 (set_attr "mode" "QI")])
6343 (define_insn "addqi_ext_1"
6344 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6349 (match_operand 1 "ext_register_operand" "0")
6352 (match_operand:QI 2 "general_operand" "Qmn")))
6353 (clobber (reg:CC FLAGS_REG))]
6356 switch (get_attr_type (insn))
6359 if (operands[2] == const1_rtx)
6360 return "inc{b}\t%h0";
6363 gcc_assert (operands[2] == constm1_rtx
6364 || (GET_CODE (operands[2]) == CONST_INT
6365 && INTVAL (operands[2]) == 255));
6366 return "dec{b}\t%h0";
6370 return "add{b}\t{%2, %h0|%h0, %2}";
6374 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6375 (const_string "incdec")
6376 (const_string "alu")))
6377 (set_attr "mode" "QI")])
6379 (define_insn "*addqi_ext_1_rex64"
6380 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6385 (match_operand 1 "ext_register_operand" "0")
6388 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6389 (clobber (reg:CC FLAGS_REG))]
6392 switch (get_attr_type (insn))
6395 if (operands[2] == const1_rtx)
6396 return "inc{b}\t%h0";
6399 gcc_assert (operands[2] == constm1_rtx
6400 || (GET_CODE (operands[2]) == CONST_INT
6401 && INTVAL (operands[2]) == 255));
6402 return "dec{b}\t%h0";
6406 return "add{b}\t{%2, %h0|%h0, %2}";
6410 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6411 (const_string "incdec")
6412 (const_string "alu")))
6413 (set_attr "mode" "QI")])
6415 (define_insn "*addqi_ext_2"
6416 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6421 (match_operand 1 "ext_register_operand" "%0")
6425 (match_operand 2 "ext_register_operand" "Q")
6428 (clobber (reg:CC FLAGS_REG))]
6430 "add{b}\t{%h2, %h0|%h0, %h2}"
6431 [(set_attr "type" "alu")
6432 (set_attr "mode" "QI")])
6434 ;; The patterns that match these are at the end of this file.
6436 (define_expand "addxf3"
6437 [(set (match_operand:XF 0 "register_operand" "")
6438 (plus:XF (match_operand:XF 1 "register_operand" "")
6439 (match_operand:XF 2 "register_operand" "")))]
6443 (define_expand "adddf3"
6444 [(set (match_operand:DF 0 "register_operand" "")
6445 (plus:DF (match_operand:DF 1 "register_operand" "")
6446 (match_operand:DF 2 "nonimmediate_operand" "")))]
6447 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6450 (define_expand "addsf3"
6451 [(set (match_operand:SF 0 "register_operand" "")
6452 (plus:SF (match_operand:SF 1 "register_operand" "")
6453 (match_operand:SF 2 "nonimmediate_operand" "")))]
6454 "TARGET_80387 || TARGET_SSE_MATH"
6457 ;; Subtract instructions
6459 ;; %%% splits for subditi3
6461 (define_expand "subti3"
6462 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6463 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6464 (match_operand:TI 2 "x86_64_general_operand" "")))
6465 (clobber (reg:CC FLAGS_REG))])]
6467 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6469 (define_insn "*subti3_1"
6470 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6471 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6472 (match_operand:TI 2 "general_operand" "roiF,riF")))
6473 (clobber (reg:CC FLAGS_REG))]
6474 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6478 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6479 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6480 (match_operand:TI 2 "general_operand" "")))
6481 (clobber (reg:CC FLAGS_REG))]
6482 "TARGET_64BIT && reload_completed"
6483 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6484 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6485 (parallel [(set (match_dup 3)
6486 (minus:DI (match_dup 4)
6487 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6489 (clobber (reg:CC FLAGS_REG))])]
6490 "split_ti (operands+0, 1, operands+0, operands+3);
6491 split_ti (operands+1, 1, operands+1, operands+4);
6492 split_ti (operands+2, 1, operands+2, operands+5);")
6494 ;; %%% splits for subsidi3
6496 (define_expand "subdi3"
6497 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6498 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6499 (match_operand:DI 2 "x86_64_general_operand" "")))
6500 (clobber (reg:CC FLAGS_REG))])]
6502 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6504 (define_insn "*subdi3_1"
6505 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6506 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6507 (match_operand:DI 2 "general_operand" "roiF,riF")))
6508 (clobber (reg:CC FLAGS_REG))]
6509 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6513 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6514 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6515 (match_operand:DI 2 "general_operand" "")))
6516 (clobber (reg:CC FLAGS_REG))]
6517 "!TARGET_64BIT && reload_completed"
6518 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6519 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6520 (parallel [(set (match_dup 3)
6521 (minus:SI (match_dup 4)
6522 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6524 (clobber (reg:CC FLAGS_REG))])]
6525 "split_di (operands+0, 1, operands+0, operands+3);
6526 split_di (operands+1, 1, operands+1, operands+4);
6527 split_di (operands+2, 1, operands+2, operands+5);")
6529 (define_insn "subdi3_carry_rex64"
6530 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6531 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6532 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6533 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6534 (clobber (reg:CC FLAGS_REG))]
6535 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6536 "sbb{q}\t{%2, %0|%0, %2}"
6537 [(set_attr "type" "alu")
6538 (set_attr "pent_pair" "pu")
6539 (set_attr "mode" "DI")])
6541 (define_insn "*subdi_1_rex64"
6542 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6543 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6544 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6545 (clobber (reg:CC FLAGS_REG))]
6546 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6547 "sub{q}\t{%2, %0|%0, %2}"
6548 [(set_attr "type" "alu")
6549 (set_attr "mode" "DI")])
6551 (define_insn "*subdi_2_rex64"
6552 [(set (reg FLAGS_REG)
6554 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6555 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6557 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6558 (minus:DI (match_dup 1) (match_dup 2)))]
6559 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6560 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6561 "sub{q}\t{%2, %0|%0, %2}"
6562 [(set_attr "type" "alu")
6563 (set_attr "mode" "DI")])
6565 (define_insn "*subdi_3_rex63"
6566 [(set (reg FLAGS_REG)
6567 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6568 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6569 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6570 (minus:DI (match_dup 1) (match_dup 2)))]
6571 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6572 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6573 "sub{q}\t{%2, %0|%0, %2}"
6574 [(set_attr "type" "alu")
6575 (set_attr "mode" "DI")])
6577 (define_insn "subqi3_carry"
6578 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6579 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6580 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6581 (match_operand:QI 2 "general_operand" "qi,qm"))))
6582 (clobber (reg:CC FLAGS_REG))]
6583 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6584 "sbb{b}\t{%2, %0|%0, %2}"
6585 [(set_attr "type" "alu")
6586 (set_attr "pent_pair" "pu")
6587 (set_attr "mode" "QI")])
6589 (define_insn "subhi3_carry"
6590 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6591 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6592 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6593 (match_operand:HI 2 "general_operand" "ri,rm"))))
6594 (clobber (reg:CC FLAGS_REG))]
6595 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6596 "sbb{w}\t{%2, %0|%0, %2}"
6597 [(set_attr "type" "alu")
6598 (set_attr "pent_pair" "pu")
6599 (set_attr "mode" "HI")])
6601 (define_insn "subsi3_carry"
6602 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6603 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6604 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6605 (match_operand:SI 2 "general_operand" "ri,rm"))))
6606 (clobber (reg:CC FLAGS_REG))]
6607 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6608 "sbb{l}\t{%2, %0|%0, %2}"
6609 [(set_attr "type" "alu")
6610 (set_attr "pent_pair" "pu")
6611 (set_attr "mode" "SI")])
6613 (define_insn "subsi3_carry_zext"
6614 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6616 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6617 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6618 (match_operand:SI 2 "general_operand" "ri,rm")))))
6619 (clobber (reg:CC FLAGS_REG))]
6620 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6621 "sbb{l}\t{%2, %k0|%k0, %2}"
6622 [(set_attr "type" "alu")
6623 (set_attr "pent_pair" "pu")
6624 (set_attr "mode" "SI")])
6626 (define_expand "subsi3"
6627 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6628 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6629 (match_operand:SI 2 "general_operand" "")))
6630 (clobber (reg:CC FLAGS_REG))])]
6632 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6634 (define_insn "*subsi_1"
6635 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6636 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6637 (match_operand:SI 2 "general_operand" "ri,rm")))
6638 (clobber (reg:CC FLAGS_REG))]
6639 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6640 "sub{l}\t{%2, %0|%0, %2}"
6641 [(set_attr "type" "alu")
6642 (set_attr "mode" "SI")])
6644 (define_insn "*subsi_1_zext"
6645 [(set (match_operand:DI 0 "register_operand" "=r")
6647 (minus:SI (match_operand:SI 1 "register_operand" "0")
6648 (match_operand:SI 2 "general_operand" "rim"))))
6649 (clobber (reg:CC FLAGS_REG))]
6650 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6651 "sub{l}\t{%2, %k0|%k0, %2}"
6652 [(set_attr "type" "alu")
6653 (set_attr "mode" "SI")])
6655 (define_insn "*subsi_2"
6656 [(set (reg FLAGS_REG)
6658 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6659 (match_operand:SI 2 "general_operand" "ri,rm"))
6661 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6662 (minus:SI (match_dup 1) (match_dup 2)))]
6663 "ix86_match_ccmode (insn, CCGOCmode)
6664 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6665 "sub{l}\t{%2, %0|%0, %2}"
6666 [(set_attr "type" "alu")
6667 (set_attr "mode" "SI")])
6669 (define_insn "*subsi_2_zext"
6670 [(set (reg FLAGS_REG)
6672 (minus:SI (match_operand:SI 1 "register_operand" "0")
6673 (match_operand:SI 2 "general_operand" "rim"))
6675 (set (match_operand:DI 0 "register_operand" "=r")
6677 (minus:SI (match_dup 1)
6679 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6680 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6681 "sub{l}\t{%2, %k0|%k0, %2}"
6682 [(set_attr "type" "alu")
6683 (set_attr "mode" "SI")])
6685 (define_insn "*subsi_3"
6686 [(set (reg FLAGS_REG)
6687 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6688 (match_operand:SI 2 "general_operand" "ri,rm")))
6689 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6690 (minus:SI (match_dup 1) (match_dup 2)))]
6691 "ix86_match_ccmode (insn, CCmode)
6692 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6693 "sub{l}\t{%2, %0|%0, %2}"
6694 [(set_attr "type" "alu")
6695 (set_attr "mode" "SI")])
6697 (define_insn "*subsi_3_zext"
6698 [(set (reg FLAGS_REG)
6699 (compare (match_operand:SI 1 "register_operand" "0")
6700 (match_operand:SI 2 "general_operand" "rim")))
6701 (set (match_operand:DI 0 "register_operand" "=r")
6703 (minus:SI (match_dup 1)
6705 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6706 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6707 "sub{l}\t{%2, %1|%1, %2}"
6708 [(set_attr "type" "alu")
6709 (set_attr "mode" "DI")])
6711 (define_expand "subhi3"
6712 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6713 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6714 (match_operand:HI 2 "general_operand" "")))
6715 (clobber (reg:CC FLAGS_REG))])]
6716 "TARGET_HIMODE_MATH"
6717 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6719 (define_insn "*subhi_1"
6720 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6721 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6722 (match_operand:HI 2 "general_operand" "ri,rm")))
6723 (clobber (reg:CC FLAGS_REG))]
6724 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6725 "sub{w}\t{%2, %0|%0, %2}"
6726 [(set_attr "type" "alu")
6727 (set_attr "mode" "HI")])
6729 (define_insn "*subhi_2"
6730 [(set (reg FLAGS_REG)
6732 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6733 (match_operand:HI 2 "general_operand" "ri,rm"))
6735 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6736 (minus:HI (match_dup 1) (match_dup 2)))]
6737 "ix86_match_ccmode (insn, CCGOCmode)
6738 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6739 "sub{w}\t{%2, %0|%0, %2}"
6740 [(set_attr "type" "alu")
6741 (set_attr "mode" "HI")])
6743 (define_insn "*subhi_3"
6744 [(set (reg FLAGS_REG)
6745 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6746 (match_operand:HI 2 "general_operand" "ri,rm")))
6747 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6748 (minus:HI (match_dup 1) (match_dup 2)))]
6749 "ix86_match_ccmode (insn, CCmode)
6750 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6751 "sub{w}\t{%2, %0|%0, %2}"
6752 [(set_attr "type" "alu")
6753 (set_attr "mode" "HI")])
6755 (define_expand "subqi3"
6756 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6757 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6758 (match_operand:QI 2 "general_operand" "")))
6759 (clobber (reg:CC FLAGS_REG))])]
6760 "TARGET_QIMODE_MATH"
6761 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6763 (define_insn "*subqi_1"
6764 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6765 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6766 (match_operand:QI 2 "general_operand" "qn,qmn")))
6767 (clobber (reg:CC FLAGS_REG))]
6768 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6769 "sub{b}\t{%2, %0|%0, %2}"
6770 [(set_attr "type" "alu")
6771 (set_attr "mode" "QI")])
6773 (define_insn "*subqi_1_slp"
6774 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6775 (minus:QI (match_dup 0)
6776 (match_operand:QI 1 "general_operand" "qn,qmn")))
6777 (clobber (reg:CC FLAGS_REG))]
6778 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6779 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6780 "sub{b}\t{%1, %0|%0, %1}"
6781 [(set_attr "type" "alu1")
6782 (set_attr "mode" "QI")])
6784 (define_insn "*subqi_2"
6785 [(set (reg FLAGS_REG)
6787 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6788 (match_operand:QI 2 "general_operand" "qi,qm"))
6790 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6791 (minus:HI (match_dup 1) (match_dup 2)))]
6792 "ix86_match_ccmode (insn, CCGOCmode)
6793 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6794 "sub{b}\t{%2, %0|%0, %2}"
6795 [(set_attr "type" "alu")
6796 (set_attr "mode" "QI")])
6798 (define_insn "*subqi_3"
6799 [(set (reg FLAGS_REG)
6800 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6801 (match_operand:QI 2 "general_operand" "qi,qm")))
6802 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6803 (minus:HI (match_dup 1) (match_dup 2)))]
6804 "ix86_match_ccmode (insn, CCmode)
6805 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6806 "sub{b}\t{%2, %0|%0, %2}"
6807 [(set_attr "type" "alu")
6808 (set_attr "mode" "QI")])
6810 ;; The patterns that match these are at the end of this file.
6812 (define_expand "subxf3"
6813 [(set (match_operand:XF 0 "register_operand" "")
6814 (minus:XF (match_operand:XF 1 "register_operand" "")
6815 (match_operand:XF 2 "register_operand" "")))]
6819 (define_expand "subdf3"
6820 [(set (match_operand:DF 0 "register_operand" "")
6821 (minus:DF (match_operand:DF 1 "register_operand" "")
6822 (match_operand:DF 2 "nonimmediate_operand" "")))]
6823 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6826 (define_expand "subsf3"
6827 [(set (match_operand:SF 0 "register_operand" "")
6828 (minus:SF (match_operand:SF 1 "register_operand" "")
6829 (match_operand:SF 2 "nonimmediate_operand" "")))]
6830 "TARGET_80387 || TARGET_SSE_MATH"
6833 ;; Multiply instructions
6835 (define_expand "muldi3"
6836 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6837 (mult:DI (match_operand:DI 1 "register_operand" "")
6838 (match_operand:DI 2 "x86_64_general_operand" "")))
6839 (clobber (reg:CC FLAGS_REG))])]
6843 (define_insn "*muldi3_1_rex64"
6844 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6845 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6846 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6847 (clobber (reg:CC FLAGS_REG))]
6849 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6851 imul{q}\t{%2, %1, %0|%0, %1, %2}
6852 imul{q}\t{%2, %1, %0|%0, %1, %2}
6853 imul{q}\t{%2, %0|%0, %2}"
6854 [(set_attr "type" "imul")
6855 (set_attr "prefix_0f" "0,0,1")
6856 (set (attr "athlon_decode")
6857 (cond [(eq_attr "cpu" "athlon")
6858 (const_string "vector")
6859 (eq_attr "alternative" "1")
6860 (const_string "vector")
6861 (and (eq_attr "alternative" "2")
6862 (match_operand 1 "memory_operand" ""))
6863 (const_string "vector")]
6864 (const_string "direct")))
6865 (set_attr "mode" "DI")])
6867 (define_expand "mulsi3"
6868 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6869 (mult:SI (match_operand:SI 1 "register_operand" "")
6870 (match_operand:SI 2 "general_operand" "")))
6871 (clobber (reg:CC FLAGS_REG))])]
6875 (define_insn "*mulsi3_1"
6876 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6877 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6878 (match_operand:SI 2 "general_operand" "K,i,mr")))
6879 (clobber (reg:CC FLAGS_REG))]
6880 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6882 imul{l}\t{%2, %1, %0|%0, %1, %2}
6883 imul{l}\t{%2, %1, %0|%0, %1, %2}
6884 imul{l}\t{%2, %0|%0, %2}"
6885 [(set_attr "type" "imul")
6886 (set_attr "prefix_0f" "0,0,1")
6887 (set (attr "athlon_decode")
6888 (cond [(eq_attr "cpu" "athlon")
6889 (const_string "vector")
6890 (eq_attr "alternative" "1")
6891 (const_string "vector")
6892 (and (eq_attr "alternative" "2")
6893 (match_operand 1 "memory_operand" ""))
6894 (const_string "vector")]
6895 (const_string "direct")))
6896 (set_attr "mode" "SI")])
6898 (define_insn "*mulsi3_1_zext"
6899 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6901 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6902 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6903 (clobber (reg:CC FLAGS_REG))]
6905 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6907 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6908 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6909 imul{l}\t{%2, %k0|%k0, %2}"
6910 [(set_attr "type" "imul")
6911 (set_attr "prefix_0f" "0,0,1")
6912 (set (attr "athlon_decode")
6913 (cond [(eq_attr "cpu" "athlon")
6914 (const_string "vector")
6915 (eq_attr "alternative" "1")
6916 (const_string "vector")
6917 (and (eq_attr "alternative" "2")
6918 (match_operand 1 "memory_operand" ""))
6919 (const_string "vector")]
6920 (const_string "direct")))
6921 (set_attr "mode" "SI")])
6923 (define_expand "mulhi3"
6924 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6925 (mult:HI (match_operand:HI 1 "register_operand" "")
6926 (match_operand:HI 2 "general_operand" "")))
6927 (clobber (reg:CC FLAGS_REG))])]
6928 "TARGET_HIMODE_MATH"
6931 (define_insn "*mulhi3_1"
6932 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6933 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6934 (match_operand:HI 2 "general_operand" "K,i,mr")))
6935 (clobber (reg:CC FLAGS_REG))]
6936 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6938 imul{w}\t{%2, %1, %0|%0, %1, %2}
6939 imul{w}\t{%2, %1, %0|%0, %1, %2}
6940 imul{w}\t{%2, %0|%0, %2}"
6941 [(set_attr "type" "imul")
6942 (set_attr "prefix_0f" "0,0,1")
6943 (set (attr "athlon_decode")
6944 (cond [(eq_attr "cpu" "athlon")
6945 (const_string "vector")
6946 (eq_attr "alternative" "1,2")
6947 (const_string "vector")]
6948 (const_string "direct")))
6949 (set_attr "mode" "HI")])
6951 (define_expand "mulqi3"
6952 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6953 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6954 (match_operand:QI 2 "register_operand" "")))
6955 (clobber (reg:CC FLAGS_REG))])]
6956 "TARGET_QIMODE_MATH"
6959 (define_insn "*mulqi3_1"
6960 [(set (match_operand:QI 0 "register_operand" "=a")
6961 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6962 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6963 (clobber (reg:CC FLAGS_REG))]
6965 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6967 [(set_attr "type" "imul")
6968 (set_attr "length_immediate" "0")
6969 (set (attr "athlon_decode")
6970 (if_then_else (eq_attr "cpu" "athlon")
6971 (const_string "vector")
6972 (const_string "direct")))
6973 (set_attr "mode" "QI")])
6975 (define_expand "umulqihi3"
6976 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6977 (mult:HI (zero_extend:HI
6978 (match_operand:QI 1 "nonimmediate_operand" ""))
6980 (match_operand:QI 2 "register_operand" ""))))
6981 (clobber (reg:CC FLAGS_REG))])]
6982 "TARGET_QIMODE_MATH"
6985 (define_insn "*umulqihi3_1"
6986 [(set (match_operand:HI 0 "register_operand" "=a")
6987 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6988 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6989 (clobber (reg:CC FLAGS_REG))]
6991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6993 [(set_attr "type" "imul")
6994 (set_attr "length_immediate" "0")
6995 (set (attr "athlon_decode")
6996 (if_then_else (eq_attr "cpu" "athlon")
6997 (const_string "vector")
6998 (const_string "direct")))
6999 (set_attr "mode" "QI")])
7001 (define_expand "mulqihi3"
7002 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7003 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7004 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7005 (clobber (reg:CC FLAGS_REG))])]
7006 "TARGET_QIMODE_MATH"
7009 (define_insn "*mulqihi3_insn"
7010 [(set (match_operand:HI 0 "register_operand" "=a")
7011 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7012 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7013 (clobber (reg:CC FLAGS_REG))]
7015 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7017 [(set_attr "type" "imul")
7018 (set_attr "length_immediate" "0")
7019 (set (attr "athlon_decode")
7020 (if_then_else (eq_attr "cpu" "athlon")
7021 (const_string "vector")
7022 (const_string "direct")))
7023 (set_attr "mode" "QI")])
7025 (define_expand "umulditi3"
7026 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7027 (mult:TI (zero_extend:TI
7028 (match_operand:DI 1 "nonimmediate_operand" ""))
7030 (match_operand:DI 2 "register_operand" ""))))
7031 (clobber (reg:CC FLAGS_REG))])]
7035 (define_insn "*umulditi3_insn"
7036 [(set (match_operand:TI 0 "register_operand" "=A")
7037 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7038 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7039 (clobber (reg:CC FLAGS_REG))]
7041 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7043 [(set_attr "type" "imul")
7044 (set_attr "length_immediate" "0")
7045 (set (attr "athlon_decode")
7046 (if_then_else (eq_attr "cpu" "athlon")
7047 (const_string "vector")
7048 (const_string "double")))
7049 (set_attr "mode" "DI")])
7051 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7052 (define_expand "umulsidi3"
7053 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7054 (mult:DI (zero_extend:DI
7055 (match_operand:SI 1 "nonimmediate_operand" ""))
7057 (match_operand:SI 2 "register_operand" ""))))
7058 (clobber (reg:CC FLAGS_REG))])]
7062 (define_insn "*umulsidi3_insn"
7063 [(set (match_operand:DI 0 "register_operand" "=A")
7064 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7065 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7066 (clobber (reg:CC FLAGS_REG))]
7068 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7070 [(set_attr "type" "imul")
7071 (set_attr "length_immediate" "0")
7072 (set (attr "athlon_decode")
7073 (if_then_else (eq_attr "cpu" "athlon")
7074 (const_string "vector")
7075 (const_string "double")))
7076 (set_attr "mode" "SI")])
7078 (define_expand "mulditi3"
7079 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7080 (mult:TI (sign_extend:TI
7081 (match_operand:DI 1 "nonimmediate_operand" ""))
7083 (match_operand:DI 2 "register_operand" ""))))
7084 (clobber (reg:CC FLAGS_REG))])]
7088 (define_insn "*mulditi3_insn"
7089 [(set (match_operand:TI 0 "register_operand" "=A")
7090 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7091 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7092 (clobber (reg:CC FLAGS_REG))]
7094 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7096 [(set_attr "type" "imul")
7097 (set_attr "length_immediate" "0")
7098 (set (attr "athlon_decode")
7099 (if_then_else (eq_attr "cpu" "athlon")
7100 (const_string "vector")
7101 (const_string "double")))
7102 (set_attr "mode" "DI")])
7104 (define_expand "mulsidi3"
7105 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7106 (mult:DI (sign_extend:DI
7107 (match_operand:SI 1 "nonimmediate_operand" ""))
7109 (match_operand:SI 2 "register_operand" ""))))
7110 (clobber (reg:CC FLAGS_REG))])]
7114 (define_insn "*mulsidi3_insn"
7115 [(set (match_operand:DI 0 "register_operand" "=A")
7116 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7117 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7118 (clobber (reg:CC FLAGS_REG))]
7120 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7122 [(set_attr "type" "imul")
7123 (set_attr "length_immediate" "0")
7124 (set (attr "athlon_decode")
7125 (if_then_else (eq_attr "cpu" "athlon")
7126 (const_string "vector")
7127 (const_string "double")))
7128 (set_attr "mode" "SI")])
7130 (define_expand "umuldi3_highpart"
7131 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7134 (mult:TI (zero_extend:TI
7135 (match_operand:DI 1 "nonimmediate_operand" ""))
7137 (match_operand:DI 2 "register_operand" "")))
7139 (clobber (match_scratch:DI 3 ""))
7140 (clobber (reg:CC FLAGS_REG))])]
7144 (define_insn "*umuldi3_highpart_rex64"
7145 [(set (match_operand:DI 0 "register_operand" "=d")
7148 (mult:TI (zero_extend:TI
7149 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7151 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7153 (clobber (match_scratch:DI 3 "=1"))
7154 (clobber (reg:CC FLAGS_REG))]
7156 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7158 [(set_attr "type" "imul")
7159 (set_attr "length_immediate" "0")
7160 (set (attr "athlon_decode")
7161 (if_then_else (eq_attr "cpu" "athlon")
7162 (const_string "vector")
7163 (const_string "double")))
7164 (set_attr "mode" "DI")])
7166 (define_expand "umulsi3_highpart"
7167 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7170 (mult:DI (zero_extend:DI
7171 (match_operand:SI 1 "nonimmediate_operand" ""))
7173 (match_operand:SI 2 "register_operand" "")))
7175 (clobber (match_scratch:SI 3 ""))
7176 (clobber (reg:CC FLAGS_REG))])]
7180 (define_insn "*umulsi3_highpart_insn"
7181 [(set (match_operand:SI 0 "register_operand" "=d")
7184 (mult:DI (zero_extend:DI
7185 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7187 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7189 (clobber (match_scratch:SI 3 "=1"))
7190 (clobber (reg:CC FLAGS_REG))]
7191 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7193 [(set_attr "type" "imul")
7194 (set_attr "length_immediate" "0")
7195 (set (attr "athlon_decode")
7196 (if_then_else (eq_attr "cpu" "athlon")
7197 (const_string "vector")
7198 (const_string "double")))
7199 (set_attr "mode" "SI")])
7201 (define_insn "*umulsi3_highpart_zext"
7202 [(set (match_operand:DI 0 "register_operand" "=d")
7203 (zero_extend:DI (truncate:SI
7205 (mult:DI (zero_extend:DI
7206 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7208 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7210 (clobber (match_scratch:SI 3 "=1"))
7211 (clobber (reg:CC FLAGS_REG))]
7213 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7215 [(set_attr "type" "imul")
7216 (set_attr "length_immediate" "0")
7217 (set (attr "athlon_decode")
7218 (if_then_else (eq_attr "cpu" "athlon")
7219 (const_string "vector")
7220 (const_string "double")))
7221 (set_attr "mode" "SI")])
7223 (define_expand "smuldi3_highpart"
7224 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7227 (mult:TI (sign_extend:TI
7228 (match_operand:DI 1 "nonimmediate_operand" ""))
7230 (match_operand:DI 2 "register_operand" "")))
7232 (clobber (match_scratch:DI 3 ""))
7233 (clobber (reg:CC FLAGS_REG))])]
7237 (define_insn "*smuldi3_highpart_rex64"
7238 [(set (match_operand:DI 0 "register_operand" "=d")
7241 (mult:TI (sign_extend:TI
7242 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7244 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7246 (clobber (match_scratch:DI 3 "=1"))
7247 (clobber (reg:CC FLAGS_REG))]
7249 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7251 [(set_attr "type" "imul")
7252 (set (attr "athlon_decode")
7253 (if_then_else (eq_attr "cpu" "athlon")
7254 (const_string "vector")
7255 (const_string "double")))
7256 (set_attr "mode" "DI")])
7258 (define_expand "smulsi3_highpart"
7259 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7262 (mult:DI (sign_extend:DI
7263 (match_operand:SI 1 "nonimmediate_operand" ""))
7265 (match_operand:SI 2 "register_operand" "")))
7267 (clobber (match_scratch:SI 3 ""))
7268 (clobber (reg:CC FLAGS_REG))])]
7272 (define_insn "*smulsi3_highpart_insn"
7273 [(set (match_operand:SI 0 "register_operand" "=d")
7276 (mult:DI (sign_extend:DI
7277 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7279 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7281 (clobber (match_scratch:SI 3 "=1"))
7282 (clobber (reg:CC FLAGS_REG))]
7283 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7285 [(set_attr "type" "imul")
7286 (set (attr "athlon_decode")
7287 (if_then_else (eq_attr "cpu" "athlon")
7288 (const_string "vector")
7289 (const_string "double")))
7290 (set_attr "mode" "SI")])
7292 (define_insn "*smulsi3_highpart_zext"
7293 [(set (match_operand:DI 0 "register_operand" "=d")
7294 (zero_extend:DI (truncate:SI
7296 (mult:DI (sign_extend:DI
7297 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7299 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7301 (clobber (match_scratch:SI 3 "=1"))
7302 (clobber (reg:CC FLAGS_REG))]
7304 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7306 [(set_attr "type" "imul")
7307 (set (attr "athlon_decode")
7308 (if_then_else (eq_attr "cpu" "athlon")
7309 (const_string "vector")
7310 (const_string "double")))
7311 (set_attr "mode" "SI")])
7313 ;; The patterns that match these are at the end of this file.
7315 (define_expand "mulxf3"
7316 [(set (match_operand:XF 0 "register_operand" "")
7317 (mult:XF (match_operand:XF 1 "register_operand" "")
7318 (match_operand:XF 2 "register_operand" "")))]
7322 (define_expand "muldf3"
7323 [(set (match_operand:DF 0 "register_operand" "")
7324 (mult:DF (match_operand:DF 1 "register_operand" "")
7325 (match_operand:DF 2 "nonimmediate_operand" "")))]
7326 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7329 (define_expand "mulsf3"
7330 [(set (match_operand:SF 0 "register_operand" "")
7331 (mult:SF (match_operand:SF 1 "register_operand" "")
7332 (match_operand:SF 2 "nonimmediate_operand" "")))]
7333 "TARGET_80387 || TARGET_SSE_MATH"
7336 ;; Divide instructions
7338 (define_insn "divqi3"
7339 [(set (match_operand:QI 0 "register_operand" "=a")
7340 (div:QI (match_operand:HI 1 "register_operand" "0")
7341 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7342 (clobber (reg:CC FLAGS_REG))]
7343 "TARGET_QIMODE_MATH"
7345 [(set_attr "type" "idiv")
7346 (set_attr "mode" "QI")])
7348 (define_insn "udivqi3"
7349 [(set (match_operand:QI 0 "register_operand" "=a")
7350 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7351 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7352 (clobber (reg:CC FLAGS_REG))]
7353 "TARGET_QIMODE_MATH"
7355 [(set_attr "type" "idiv")
7356 (set_attr "mode" "QI")])
7358 ;; The patterns that match these are at the end of this file.
7360 (define_expand "divxf3"
7361 [(set (match_operand:XF 0 "register_operand" "")
7362 (div:XF (match_operand:XF 1 "register_operand" "")
7363 (match_operand:XF 2 "register_operand" "")))]
7367 (define_expand "divdf3"
7368 [(set (match_operand:DF 0 "register_operand" "")
7369 (div:DF (match_operand:DF 1 "register_operand" "")
7370 (match_operand:DF 2 "nonimmediate_operand" "")))]
7371 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7374 (define_expand "divsf3"
7375 [(set (match_operand:SF 0 "register_operand" "")
7376 (div:SF (match_operand:SF 1 "register_operand" "")
7377 (match_operand:SF 2 "nonimmediate_operand" "")))]
7378 "TARGET_80387 || TARGET_SSE_MATH"
7381 ;; Remainder instructions.
7383 (define_expand "divmoddi4"
7384 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7385 (div:DI (match_operand:DI 1 "register_operand" "")
7386 (match_operand:DI 2 "nonimmediate_operand" "")))
7387 (set (match_operand:DI 3 "register_operand" "")
7388 (mod:DI (match_dup 1) (match_dup 2)))
7389 (clobber (reg:CC FLAGS_REG))])]
7393 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7394 ;; Penalize eax case slightly because it results in worse scheduling
7396 (define_insn "*divmoddi4_nocltd_rex64"
7397 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7398 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7399 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7400 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7401 (mod:DI (match_dup 2) (match_dup 3)))
7402 (clobber (reg:CC FLAGS_REG))]
7403 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7405 [(set_attr "type" "multi")])
7407 (define_insn "*divmoddi4_cltd_rex64"
7408 [(set (match_operand:DI 0 "register_operand" "=a")
7409 (div:DI (match_operand:DI 2 "register_operand" "a")
7410 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7411 (set (match_operand:DI 1 "register_operand" "=&d")
7412 (mod:DI (match_dup 2) (match_dup 3)))
7413 (clobber (reg:CC FLAGS_REG))]
7414 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7416 [(set_attr "type" "multi")])
7418 (define_insn "*divmoddi_noext_rex64"
7419 [(set (match_operand:DI 0 "register_operand" "=a")
7420 (div:DI (match_operand:DI 1 "register_operand" "0")
7421 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7422 (set (match_operand:DI 3 "register_operand" "=d")
7423 (mod:DI (match_dup 1) (match_dup 2)))
7424 (use (match_operand:DI 4 "register_operand" "3"))
7425 (clobber (reg:CC FLAGS_REG))]
7428 [(set_attr "type" "idiv")
7429 (set_attr "mode" "DI")])
7432 [(set (match_operand:DI 0 "register_operand" "")
7433 (div:DI (match_operand:DI 1 "register_operand" "")
7434 (match_operand:DI 2 "nonimmediate_operand" "")))
7435 (set (match_operand:DI 3 "register_operand" "")
7436 (mod:DI (match_dup 1) (match_dup 2)))
7437 (clobber (reg:CC FLAGS_REG))]
7438 "TARGET_64BIT && reload_completed"
7439 [(parallel [(set (match_dup 3)
7440 (ashiftrt:DI (match_dup 4) (const_int 63)))
7441 (clobber (reg:CC FLAGS_REG))])
7442 (parallel [(set (match_dup 0)
7443 (div:DI (reg:DI 0) (match_dup 2)))
7445 (mod:DI (reg:DI 0) (match_dup 2)))
7447 (clobber (reg:CC FLAGS_REG))])]
7449 /* Avoid use of cltd in favor of a mov+shift. */
7450 if (!TARGET_USE_CLTD && !optimize_size)
7452 if (true_regnum (operands[1]))
7453 emit_move_insn (operands[0], operands[1]);
7455 emit_move_insn (operands[3], operands[1]);
7456 operands[4] = operands[3];
7460 gcc_assert (!true_regnum (operands[1]));
7461 operands[4] = operands[1];
7466 (define_expand "divmodsi4"
7467 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7468 (div:SI (match_operand:SI 1 "register_operand" "")
7469 (match_operand:SI 2 "nonimmediate_operand" "")))
7470 (set (match_operand:SI 3 "register_operand" "")
7471 (mod:SI (match_dup 1) (match_dup 2)))
7472 (clobber (reg:CC FLAGS_REG))])]
7476 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7477 ;; Penalize eax case slightly because it results in worse scheduling
7479 (define_insn "*divmodsi4_nocltd"
7480 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7481 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7482 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7483 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7484 (mod:SI (match_dup 2) (match_dup 3)))
7485 (clobber (reg:CC FLAGS_REG))]
7486 "!optimize_size && !TARGET_USE_CLTD"
7488 [(set_attr "type" "multi")])
7490 (define_insn "*divmodsi4_cltd"
7491 [(set (match_operand:SI 0 "register_operand" "=a")
7492 (div:SI (match_operand:SI 2 "register_operand" "a")
7493 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7494 (set (match_operand:SI 1 "register_operand" "=&d")
7495 (mod:SI (match_dup 2) (match_dup 3)))
7496 (clobber (reg:CC FLAGS_REG))]
7497 "optimize_size || TARGET_USE_CLTD"
7499 [(set_attr "type" "multi")])
7501 (define_insn "*divmodsi_noext"
7502 [(set (match_operand:SI 0 "register_operand" "=a")
7503 (div:SI (match_operand:SI 1 "register_operand" "0")
7504 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7505 (set (match_operand:SI 3 "register_operand" "=d")
7506 (mod:SI (match_dup 1) (match_dup 2)))
7507 (use (match_operand:SI 4 "register_operand" "3"))
7508 (clobber (reg:CC FLAGS_REG))]
7511 [(set_attr "type" "idiv")
7512 (set_attr "mode" "SI")])
7515 [(set (match_operand:SI 0 "register_operand" "")
7516 (div:SI (match_operand:SI 1 "register_operand" "")
7517 (match_operand:SI 2 "nonimmediate_operand" "")))
7518 (set (match_operand:SI 3 "register_operand" "")
7519 (mod:SI (match_dup 1) (match_dup 2)))
7520 (clobber (reg:CC FLAGS_REG))]
7522 [(parallel [(set (match_dup 3)
7523 (ashiftrt:SI (match_dup 4) (const_int 31)))
7524 (clobber (reg:CC FLAGS_REG))])
7525 (parallel [(set (match_dup 0)
7526 (div:SI (reg:SI 0) (match_dup 2)))
7528 (mod:SI (reg:SI 0) (match_dup 2)))
7530 (clobber (reg:CC FLAGS_REG))])]
7532 /* Avoid use of cltd in favor of a mov+shift. */
7533 if (!TARGET_USE_CLTD && !optimize_size)
7535 if (true_regnum (operands[1]))
7536 emit_move_insn (operands[0], operands[1]);
7538 emit_move_insn (operands[3], operands[1]);
7539 operands[4] = operands[3];
7543 gcc_assert (!true_regnum (operands[1]));
7544 operands[4] = operands[1];
7548 (define_insn "divmodhi4"
7549 [(set (match_operand:HI 0 "register_operand" "=a")
7550 (div: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 (mod:HI (match_dup 1) (match_dup 2)))
7554 (clobber (reg:CC FLAGS_REG))]
7555 "TARGET_HIMODE_MATH"
7557 [(set_attr "type" "multi")
7558 (set_attr "length_immediate" "0")
7559 (set_attr "mode" "SI")])
7561 (define_insn "udivmoddi4"
7562 [(set (match_operand:DI 0 "register_operand" "=a")
7563 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7564 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7565 (set (match_operand:DI 3 "register_operand" "=&d")
7566 (umod:DI (match_dup 1) (match_dup 2)))
7567 (clobber (reg:CC FLAGS_REG))]
7569 "xor{q}\t%3, %3\;div{q}\t%2"
7570 [(set_attr "type" "multi")
7571 (set_attr "length_immediate" "0")
7572 (set_attr "mode" "DI")])
7574 (define_insn "*udivmoddi4_noext"
7575 [(set (match_operand:DI 0 "register_operand" "=a")
7576 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7577 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7578 (set (match_operand:DI 3 "register_operand" "=d")
7579 (umod:DI (match_dup 1) (match_dup 2)))
7581 (clobber (reg:CC FLAGS_REG))]
7584 [(set_attr "type" "idiv")
7585 (set_attr "mode" "DI")])
7588 [(set (match_operand:DI 0 "register_operand" "")
7589 (udiv:DI (match_operand:DI 1 "register_operand" "")
7590 (match_operand:DI 2 "nonimmediate_operand" "")))
7591 (set (match_operand:DI 3 "register_operand" "")
7592 (umod:DI (match_dup 1) (match_dup 2)))
7593 (clobber (reg:CC FLAGS_REG))]
7594 "TARGET_64BIT && reload_completed"
7595 [(set (match_dup 3) (const_int 0))
7596 (parallel [(set (match_dup 0)
7597 (udiv:DI (match_dup 1) (match_dup 2)))
7599 (umod:DI (match_dup 1) (match_dup 2)))
7601 (clobber (reg:CC FLAGS_REG))])]
7604 (define_insn "udivmodsi4"
7605 [(set (match_operand:SI 0 "register_operand" "=a")
7606 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7607 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7608 (set (match_operand:SI 3 "register_operand" "=&d")
7609 (umod:SI (match_dup 1) (match_dup 2)))
7610 (clobber (reg:CC FLAGS_REG))]
7612 "xor{l}\t%3, %3\;div{l}\t%2"
7613 [(set_attr "type" "multi")
7614 (set_attr "length_immediate" "0")
7615 (set_attr "mode" "SI")])
7617 (define_insn "*udivmodsi4_noext"
7618 [(set (match_operand:SI 0 "register_operand" "=a")
7619 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7620 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7621 (set (match_operand:SI 3 "register_operand" "=d")
7622 (umod:SI (match_dup 1) (match_dup 2)))
7624 (clobber (reg:CC FLAGS_REG))]
7627 [(set_attr "type" "idiv")
7628 (set_attr "mode" "SI")])
7631 [(set (match_operand:SI 0 "register_operand" "")
7632 (udiv:SI (match_operand:SI 1 "register_operand" "")
7633 (match_operand:SI 2 "nonimmediate_operand" "")))
7634 (set (match_operand:SI 3 "register_operand" "")
7635 (umod:SI (match_dup 1) (match_dup 2)))
7636 (clobber (reg:CC FLAGS_REG))]
7638 [(set (match_dup 3) (const_int 0))
7639 (parallel [(set (match_dup 0)
7640 (udiv:SI (match_dup 1) (match_dup 2)))
7642 (umod:SI (match_dup 1) (match_dup 2)))
7644 (clobber (reg:CC FLAGS_REG))])]
7647 (define_expand "udivmodhi4"
7648 [(set (match_dup 4) (const_int 0))
7649 (parallel [(set (match_operand:HI 0 "register_operand" "")
7650 (udiv:HI (match_operand:HI 1 "register_operand" "")
7651 (match_operand:HI 2 "nonimmediate_operand" "")))
7652 (set (match_operand:HI 3 "register_operand" "")
7653 (umod:HI (match_dup 1) (match_dup 2)))
7655 (clobber (reg:CC FLAGS_REG))])]
7656 "TARGET_HIMODE_MATH"
7657 "operands[4] = gen_reg_rtx (HImode);")
7659 (define_insn "*udivmodhi_noext"
7660 [(set (match_operand:HI 0 "register_operand" "=a")
7661 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7662 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7663 (set (match_operand:HI 3 "register_operand" "=d")
7664 (umod:HI (match_dup 1) (match_dup 2)))
7665 (use (match_operand:HI 4 "register_operand" "3"))
7666 (clobber (reg:CC FLAGS_REG))]
7669 [(set_attr "type" "idiv")
7670 (set_attr "mode" "HI")])
7672 ;; We cannot use div/idiv for double division, because it causes
7673 ;; "division by zero" on the overflow and that's not what we expect
7674 ;; from truncate. Because true (non truncating) double division is
7675 ;; never generated, we can't create this insn anyway.
7678 ; [(set (match_operand:SI 0 "register_operand" "=a")
7680 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7682 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7683 ; (set (match_operand:SI 3 "register_operand" "=d")
7685 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7686 ; (clobber (reg:CC FLAGS_REG))]
7688 ; "div{l}\t{%2, %0|%0, %2}"
7689 ; [(set_attr "type" "idiv")])
7691 ;;- Logical AND instructions
7693 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7694 ;; Note that this excludes ah.
7696 (define_insn "*testdi_1_rex64"
7697 [(set (reg FLAGS_REG)
7699 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7700 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7702 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7703 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7705 test{l}\t{%k1, %k0|%k0, %k1}
7706 test{l}\t{%k1, %k0|%k0, %k1}
7707 test{q}\t{%1, %0|%0, %1}
7708 test{q}\t{%1, %0|%0, %1}
7709 test{q}\t{%1, %0|%0, %1}"
7710 [(set_attr "type" "test")
7711 (set_attr "modrm" "0,1,0,1,1")
7712 (set_attr "mode" "SI,SI,DI,DI,DI")
7713 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7715 (define_insn "testsi_1"
7716 [(set (reg FLAGS_REG)
7718 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7719 (match_operand:SI 1 "general_operand" "in,in,rin"))
7721 "ix86_match_ccmode (insn, CCNOmode)
7722 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7723 "test{l}\t{%1, %0|%0, %1}"
7724 [(set_attr "type" "test")
7725 (set_attr "modrm" "0,1,1")
7726 (set_attr "mode" "SI")
7727 (set_attr "pent_pair" "uv,np,uv")])
7729 (define_expand "testsi_ccno_1"
7730 [(set (reg:CCNO FLAGS_REG)
7732 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7733 (match_operand:SI 1 "nonmemory_operand" ""))
7738 (define_insn "*testhi_1"
7739 [(set (reg FLAGS_REG)
7740 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7741 (match_operand:HI 1 "general_operand" "n,n,rn"))
7743 "ix86_match_ccmode (insn, CCNOmode)
7744 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7745 "test{w}\t{%1, %0|%0, %1}"
7746 [(set_attr "type" "test")
7747 (set_attr "modrm" "0,1,1")
7748 (set_attr "mode" "HI")
7749 (set_attr "pent_pair" "uv,np,uv")])
7751 (define_expand "testqi_ccz_1"
7752 [(set (reg:CCZ FLAGS_REG)
7753 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7754 (match_operand:QI 1 "nonmemory_operand" ""))
7759 (define_insn "*testqi_1_maybe_si"
7760 [(set (reg FLAGS_REG)
7763 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7764 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7766 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7767 && ix86_match_ccmode (insn,
7768 GET_CODE (operands[1]) == CONST_INT
7769 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7771 if (which_alternative == 3)
7773 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7774 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7775 return "test{l}\t{%1, %k0|%k0, %1}";
7777 return "test{b}\t{%1, %0|%0, %1}";
7779 [(set_attr "type" "test")
7780 (set_attr "modrm" "0,1,1,1")
7781 (set_attr "mode" "QI,QI,QI,SI")
7782 (set_attr "pent_pair" "uv,np,uv,np")])
7784 (define_insn "*testqi_1"
7785 [(set (reg FLAGS_REG)
7788 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7789 (match_operand:QI 1 "general_operand" "n,n,qn"))
7791 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7792 && ix86_match_ccmode (insn, CCNOmode)"
7793 "test{b}\t{%1, %0|%0, %1}"
7794 [(set_attr "type" "test")
7795 (set_attr "modrm" "0,1,1")
7796 (set_attr "mode" "QI")
7797 (set_attr "pent_pair" "uv,np,uv")])
7799 (define_expand "testqi_ext_ccno_0"
7800 [(set (reg:CCNO FLAGS_REG)
7804 (match_operand 0 "ext_register_operand" "")
7807 (match_operand 1 "const_int_operand" ""))
7812 (define_insn "*testqi_ext_0"
7813 [(set (reg FLAGS_REG)
7817 (match_operand 0 "ext_register_operand" "Q")
7820 (match_operand 1 "const_int_operand" "n"))
7822 "ix86_match_ccmode (insn, CCNOmode)"
7823 "test{b}\t{%1, %h0|%h0, %1}"
7824 [(set_attr "type" "test")
7825 (set_attr "mode" "QI")
7826 (set_attr "length_immediate" "1")
7827 (set_attr "pent_pair" "np")])
7829 (define_insn "*testqi_ext_1"
7830 [(set (reg FLAGS_REG)
7834 (match_operand 0 "ext_register_operand" "Q")
7838 (match_operand:QI 1 "general_operand" "Qm")))
7840 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7841 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7842 "test{b}\t{%1, %h0|%h0, %1}"
7843 [(set_attr "type" "test")
7844 (set_attr "mode" "QI")])
7846 (define_insn "*testqi_ext_1_rex64"
7847 [(set (reg FLAGS_REG)
7851 (match_operand 0 "ext_register_operand" "Q")
7855 (match_operand:QI 1 "register_operand" "Q")))
7857 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7858 "test{b}\t{%1, %h0|%h0, %1}"
7859 [(set_attr "type" "test")
7860 (set_attr "mode" "QI")])
7862 (define_insn "*testqi_ext_2"
7863 [(set (reg FLAGS_REG)
7867 (match_operand 0 "ext_register_operand" "Q")
7871 (match_operand 1 "ext_register_operand" "Q")
7875 "ix86_match_ccmode (insn, CCNOmode)"
7876 "test{b}\t{%h1, %h0|%h0, %h1}"
7877 [(set_attr "type" "test")
7878 (set_attr "mode" "QI")])
7880 ;; Combine likes to form bit extractions for some tests. Humor it.
7881 (define_insn "*testqi_ext_3"
7882 [(set (reg FLAGS_REG)
7883 (compare (zero_extract:SI
7884 (match_operand 0 "nonimmediate_operand" "rm")
7885 (match_operand:SI 1 "const_int_operand" "")
7886 (match_operand:SI 2 "const_int_operand" ""))
7888 "ix86_match_ccmode (insn, CCNOmode)
7889 && INTVAL (operands[1]) > 0
7890 && INTVAL (operands[2]) >= 0
7891 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7892 && (GET_MODE (operands[0]) == SImode
7893 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7894 || GET_MODE (operands[0]) == HImode
7895 || GET_MODE (operands[0]) == QImode)"
7898 (define_insn "*testqi_ext_3_rex64"
7899 [(set (reg FLAGS_REG)
7900 (compare (zero_extract:DI
7901 (match_operand 0 "nonimmediate_operand" "rm")
7902 (match_operand:DI 1 "const_int_operand" "")
7903 (match_operand:DI 2 "const_int_operand" ""))
7906 && ix86_match_ccmode (insn, CCNOmode)
7907 && INTVAL (operands[1]) > 0
7908 && INTVAL (operands[2]) >= 0
7909 /* Ensure that resulting mask is zero or sign extended operand. */
7910 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7911 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7912 && INTVAL (operands[1]) > 32))
7913 && (GET_MODE (operands[0]) == SImode
7914 || GET_MODE (operands[0]) == DImode
7915 || GET_MODE (operands[0]) == HImode
7916 || GET_MODE (operands[0]) == QImode)"
7920 [(set (match_operand 0 "flags_reg_operand" "")
7921 (match_operator 1 "compare_operator"
7923 (match_operand 2 "nonimmediate_operand" "")
7924 (match_operand 3 "const_int_operand" "")
7925 (match_operand 4 "const_int_operand" ""))
7927 "ix86_match_ccmode (insn, CCNOmode)"
7928 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7930 rtx val = operands[2];
7931 HOST_WIDE_INT len = INTVAL (operands[3]);
7932 HOST_WIDE_INT pos = INTVAL (operands[4]);
7934 enum machine_mode mode, submode;
7936 mode = GET_MODE (val);
7937 if (GET_CODE (val) == MEM)
7939 /* ??? Combine likes to put non-volatile mem extractions in QImode
7940 no matter the size of the test. So find a mode that works. */
7941 if (! MEM_VOLATILE_P (val))
7943 mode = smallest_mode_for_size (pos + len, MODE_INT);
7944 val = adjust_address (val, mode, 0);
7947 else if (GET_CODE (val) == SUBREG
7948 && (submode = GET_MODE (SUBREG_REG (val)),
7949 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7950 && pos + len <= GET_MODE_BITSIZE (submode))
7952 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7954 val = SUBREG_REG (val);
7956 else if (mode == HImode && pos + len <= 8)
7958 /* Small HImode tests can be converted to QImode. */
7960 val = gen_lowpart (QImode, val);
7963 if (len == HOST_BITS_PER_WIDE_INT)
7966 mask = ((HOST_WIDE_INT)1 << len) - 1;
7969 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7972 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7973 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7974 ;; this is relatively important trick.
7975 ;; Do the conversion only post-reload to avoid limiting of the register class
7978 [(set (match_operand 0 "flags_reg_operand" "")
7979 (match_operator 1 "compare_operator"
7980 [(and (match_operand 2 "register_operand" "")
7981 (match_operand 3 "const_int_operand" ""))
7984 && QI_REG_P (operands[2])
7985 && GET_MODE (operands[2]) != QImode
7986 && ((ix86_match_ccmode (insn, CCZmode)
7987 && !(INTVAL (operands[3]) & ~(255 << 8)))
7988 || (ix86_match_ccmode (insn, CCNOmode)
7989 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7992 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7995 "operands[2] = gen_lowpart (SImode, operands[2]);
7996 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7999 [(set (match_operand 0 "flags_reg_operand" "")
8000 (match_operator 1 "compare_operator"
8001 [(and (match_operand 2 "nonimmediate_operand" "")
8002 (match_operand 3 "const_int_operand" ""))
8005 && GET_MODE (operands[2]) != QImode
8006 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8007 && ((ix86_match_ccmode (insn, CCZmode)
8008 && !(INTVAL (operands[3]) & ~255))
8009 || (ix86_match_ccmode (insn, CCNOmode)
8010 && !(INTVAL (operands[3]) & ~127)))"
8012 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8014 "operands[2] = gen_lowpart (QImode, operands[2]);
8015 operands[3] = gen_lowpart (QImode, operands[3]);")
8018 ;; %%% This used to optimize known byte-wide and operations to memory,
8019 ;; and sometimes to QImode registers. If this is considered useful,
8020 ;; it should be done with splitters.
8022 (define_expand "anddi3"
8023 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8024 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8025 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8026 (clobber (reg:CC FLAGS_REG))]
8028 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8030 (define_insn "*anddi_1_rex64"
8031 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8032 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8033 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8034 (clobber (reg:CC FLAGS_REG))]
8035 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8037 switch (get_attr_type (insn))
8041 enum machine_mode mode;
8043 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8044 if (INTVAL (operands[2]) == 0xff)
8048 gcc_assert (INTVAL (operands[2]) == 0xffff);
8052 operands[1] = gen_lowpart (mode, operands[1]);
8054 return "movz{bq|x}\t{%1,%0|%0, %1}";
8056 return "movz{wq|x}\t{%1,%0|%0, %1}";
8060 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8061 if (get_attr_mode (insn) == MODE_SI)
8062 return "and{l}\t{%k2, %k0|%k0, %k2}";
8064 return "and{q}\t{%2, %0|%0, %2}";
8067 [(set_attr "type" "alu,alu,alu,imovx")
8068 (set_attr "length_immediate" "*,*,*,0")
8069 (set_attr "mode" "SI,DI,DI,DI")])
8071 (define_insn "*anddi_2"
8072 [(set (reg FLAGS_REG)
8073 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8074 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8076 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8077 (and:DI (match_dup 1) (match_dup 2)))]
8078 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8079 && ix86_binary_operator_ok (AND, DImode, operands)"
8081 and{l}\t{%k2, %k0|%k0, %k2}
8082 and{q}\t{%2, %0|%0, %2}
8083 and{q}\t{%2, %0|%0, %2}"
8084 [(set_attr "type" "alu")
8085 (set_attr "mode" "SI,DI,DI")])
8087 (define_expand "andsi3"
8088 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8089 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8090 (match_operand:SI 2 "general_operand" "")))
8091 (clobber (reg:CC FLAGS_REG))]
8093 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8095 (define_insn "*andsi_1"
8096 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8097 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8098 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8099 (clobber (reg:CC FLAGS_REG))]
8100 "ix86_binary_operator_ok (AND, SImode, operands)"
8102 switch (get_attr_type (insn))
8106 enum machine_mode mode;
8108 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8109 if (INTVAL (operands[2]) == 0xff)
8113 gcc_assert (INTVAL (operands[2]) == 0xffff);
8117 operands[1] = gen_lowpart (mode, operands[1]);
8119 return "movz{bl|x}\t{%1,%0|%0, %1}";
8121 return "movz{wl|x}\t{%1,%0|%0, %1}";
8125 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8126 return "and{l}\t{%2, %0|%0, %2}";
8129 [(set_attr "type" "alu,alu,imovx")
8130 (set_attr "length_immediate" "*,*,0")
8131 (set_attr "mode" "SI")])
8134 [(set (match_operand 0 "register_operand" "")
8136 (const_int -65536)))
8137 (clobber (reg:CC FLAGS_REG))]
8138 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8139 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8140 "operands[1] = gen_lowpart (HImode, operands[0]);")
8143 [(set (match_operand 0 "ext_register_operand" "")
8146 (clobber (reg:CC FLAGS_REG))]
8147 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8148 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8149 "operands[1] = gen_lowpart (QImode, operands[0]);")
8152 [(set (match_operand 0 "ext_register_operand" "")
8154 (const_int -65281)))
8155 (clobber (reg:CC FLAGS_REG))]
8156 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8157 [(parallel [(set (zero_extract:SI (match_dup 0)
8161 (zero_extract:SI (match_dup 0)
8164 (zero_extract:SI (match_dup 0)
8167 (clobber (reg:CC FLAGS_REG))])]
8168 "operands[0] = gen_lowpart (SImode, operands[0]);")
8170 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8171 (define_insn "*andsi_1_zext"
8172 [(set (match_operand:DI 0 "register_operand" "=r")
8174 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8175 (match_operand:SI 2 "general_operand" "rim"))))
8176 (clobber (reg:CC FLAGS_REG))]
8177 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8178 "and{l}\t{%2, %k0|%k0, %2}"
8179 [(set_attr "type" "alu")
8180 (set_attr "mode" "SI")])
8182 (define_insn "*andsi_2"
8183 [(set (reg FLAGS_REG)
8184 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8185 (match_operand:SI 2 "general_operand" "rim,ri"))
8187 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8188 (and:SI (match_dup 1) (match_dup 2)))]
8189 "ix86_match_ccmode (insn, CCNOmode)
8190 && ix86_binary_operator_ok (AND, SImode, operands)"
8191 "and{l}\t{%2, %0|%0, %2}"
8192 [(set_attr "type" "alu")
8193 (set_attr "mode" "SI")])
8195 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8196 (define_insn "*andsi_2_zext"
8197 [(set (reg FLAGS_REG)
8198 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8199 (match_operand:SI 2 "general_operand" "rim"))
8201 (set (match_operand:DI 0 "register_operand" "=r")
8202 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8203 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8204 && ix86_binary_operator_ok (AND, SImode, operands)"
8205 "and{l}\t{%2, %k0|%k0, %2}"
8206 [(set_attr "type" "alu")
8207 (set_attr "mode" "SI")])
8209 (define_expand "andhi3"
8210 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8211 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8212 (match_operand:HI 2 "general_operand" "")))
8213 (clobber (reg:CC FLAGS_REG))]
8214 "TARGET_HIMODE_MATH"
8215 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8217 (define_insn "*andhi_1"
8218 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8219 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8220 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8221 (clobber (reg:CC FLAGS_REG))]
8222 "ix86_binary_operator_ok (AND, HImode, operands)"
8224 switch (get_attr_type (insn))
8227 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8228 gcc_assert (INTVAL (operands[2]) == 0xff);
8229 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8232 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8234 return "and{w}\t{%2, %0|%0, %2}";
8237 [(set_attr "type" "alu,alu,imovx")
8238 (set_attr "length_immediate" "*,*,0")
8239 (set_attr "mode" "HI,HI,SI")])
8241 (define_insn "*andhi_2"
8242 [(set (reg FLAGS_REG)
8243 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8244 (match_operand:HI 2 "general_operand" "rim,ri"))
8246 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8247 (and:HI (match_dup 1) (match_dup 2)))]
8248 "ix86_match_ccmode (insn, CCNOmode)
8249 && ix86_binary_operator_ok (AND, HImode, operands)"
8250 "and{w}\t{%2, %0|%0, %2}"
8251 [(set_attr "type" "alu")
8252 (set_attr "mode" "HI")])
8254 (define_expand "andqi3"
8255 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8256 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8257 (match_operand:QI 2 "general_operand" "")))
8258 (clobber (reg:CC FLAGS_REG))]
8259 "TARGET_QIMODE_MATH"
8260 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8262 ;; %%% Potential partial reg stall on alternative 2. What to do?
8263 (define_insn "*andqi_1"
8264 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8265 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8266 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8267 (clobber (reg:CC FLAGS_REG))]
8268 "ix86_binary_operator_ok (AND, QImode, operands)"
8270 and{b}\t{%2, %0|%0, %2}
8271 and{b}\t{%2, %0|%0, %2}
8272 and{l}\t{%k2, %k0|%k0, %k2}"
8273 [(set_attr "type" "alu")
8274 (set_attr "mode" "QI,QI,SI")])
8276 (define_insn "*andqi_1_slp"
8277 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8278 (and:QI (match_dup 0)
8279 (match_operand:QI 1 "general_operand" "qi,qmi")))
8280 (clobber (reg:CC FLAGS_REG))]
8281 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8282 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8283 "and{b}\t{%1, %0|%0, %1}"
8284 [(set_attr "type" "alu1")
8285 (set_attr "mode" "QI")])
8287 (define_insn "*andqi_2_maybe_si"
8288 [(set (reg FLAGS_REG)
8290 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8291 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8293 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8294 (and:QI (match_dup 1) (match_dup 2)))]
8295 "ix86_binary_operator_ok (AND, QImode, operands)
8296 && ix86_match_ccmode (insn,
8297 GET_CODE (operands[2]) == CONST_INT
8298 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8300 if (which_alternative == 2)
8302 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8303 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8304 return "and{l}\t{%2, %k0|%k0, %2}";
8306 return "and{b}\t{%2, %0|%0, %2}";
8308 [(set_attr "type" "alu")
8309 (set_attr "mode" "QI,QI,SI")])
8311 (define_insn "*andqi_2"
8312 [(set (reg FLAGS_REG)
8314 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8315 (match_operand:QI 2 "general_operand" "qim,qi"))
8317 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8318 (and:QI (match_dup 1) (match_dup 2)))]
8319 "ix86_match_ccmode (insn, CCNOmode)
8320 && ix86_binary_operator_ok (AND, QImode, operands)"
8321 "and{b}\t{%2, %0|%0, %2}"
8322 [(set_attr "type" "alu")
8323 (set_attr "mode" "QI")])
8325 (define_insn "*andqi_2_slp"
8326 [(set (reg FLAGS_REG)
8328 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8329 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8331 (set (strict_low_part (match_dup 0))
8332 (and:QI (match_dup 0) (match_dup 1)))]
8333 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8334 && ix86_match_ccmode (insn, CCNOmode)
8335 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8336 "and{b}\t{%1, %0|%0, %1}"
8337 [(set_attr "type" "alu1")
8338 (set_attr "mode" "QI")])
8340 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8341 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8342 ;; for a QImode operand, which of course failed.
8344 (define_insn "andqi_ext_0"
8345 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8350 (match_operand 1 "ext_register_operand" "0")
8353 (match_operand 2 "const_int_operand" "n")))
8354 (clobber (reg:CC FLAGS_REG))]
8356 "and{b}\t{%2, %h0|%h0, %2}"
8357 [(set_attr "type" "alu")
8358 (set_attr "length_immediate" "1")
8359 (set_attr "mode" "QI")])
8361 ;; Generated by peephole translating test to and. This shows up
8362 ;; often in fp comparisons.
8364 (define_insn "*andqi_ext_0_cc"
8365 [(set (reg FLAGS_REG)
8369 (match_operand 1 "ext_register_operand" "0")
8372 (match_operand 2 "const_int_operand" "n"))
8374 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8383 "ix86_match_ccmode (insn, CCNOmode)"
8384 "and{b}\t{%2, %h0|%h0, %2}"
8385 [(set_attr "type" "alu")
8386 (set_attr "length_immediate" "1")
8387 (set_attr "mode" "QI")])
8389 (define_insn "*andqi_ext_1"
8390 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8395 (match_operand 1 "ext_register_operand" "0")
8399 (match_operand:QI 2 "general_operand" "Qm"))))
8400 (clobber (reg:CC FLAGS_REG))]
8402 "and{b}\t{%2, %h0|%h0, %2}"
8403 [(set_attr "type" "alu")
8404 (set_attr "length_immediate" "0")
8405 (set_attr "mode" "QI")])
8407 (define_insn "*andqi_ext_1_rex64"
8408 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8413 (match_operand 1 "ext_register_operand" "0")
8417 (match_operand 2 "ext_register_operand" "Q"))))
8418 (clobber (reg:CC FLAGS_REG))]
8420 "and{b}\t{%2, %h0|%h0, %2}"
8421 [(set_attr "type" "alu")
8422 (set_attr "length_immediate" "0")
8423 (set_attr "mode" "QI")])
8425 (define_insn "*andqi_ext_2"
8426 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8431 (match_operand 1 "ext_register_operand" "%0")
8435 (match_operand 2 "ext_register_operand" "Q")
8438 (clobber (reg:CC FLAGS_REG))]
8440 "and{b}\t{%h2, %h0|%h0, %h2}"
8441 [(set_attr "type" "alu")
8442 (set_attr "length_immediate" "0")
8443 (set_attr "mode" "QI")])
8445 ;; Convert wide AND instructions with immediate operand to shorter QImode
8446 ;; equivalents when possible.
8447 ;; Don't do the splitting with memory operands, since it introduces risk
8448 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8449 ;; for size, but that can (should?) be handled by generic code instead.
8451 [(set (match_operand 0 "register_operand" "")
8452 (and (match_operand 1 "register_operand" "")
8453 (match_operand 2 "const_int_operand" "")))
8454 (clobber (reg:CC FLAGS_REG))]
8456 && QI_REG_P (operands[0])
8457 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8458 && !(~INTVAL (operands[2]) & ~(255 << 8))
8459 && GET_MODE (operands[0]) != QImode"
8460 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8461 (and:SI (zero_extract:SI (match_dup 1)
8462 (const_int 8) (const_int 8))
8464 (clobber (reg:CC FLAGS_REG))])]
8465 "operands[0] = gen_lowpart (SImode, operands[0]);
8466 operands[1] = gen_lowpart (SImode, operands[1]);
8467 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8469 ;; Since AND can be encoded with sign extended immediate, this is only
8470 ;; profitable when 7th bit is not set.
8472 [(set (match_operand 0 "register_operand" "")
8473 (and (match_operand 1 "general_operand" "")
8474 (match_operand 2 "const_int_operand" "")))
8475 (clobber (reg:CC FLAGS_REG))]
8477 && ANY_QI_REG_P (operands[0])
8478 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8479 && !(~INTVAL (operands[2]) & ~255)
8480 && !(INTVAL (operands[2]) & 128)
8481 && GET_MODE (operands[0]) != QImode"
8482 [(parallel [(set (strict_low_part (match_dup 0))
8483 (and:QI (match_dup 1)
8485 (clobber (reg:CC FLAGS_REG))])]
8486 "operands[0] = gen_lowpart (QImode, operands[0]);
8487 operands[1] = gen_lowpart (QImode, operands[1]);
8488 operands[2] = gen_lowpart (QImode, operands[2]);")
8490 ;; Logical inclusive OR instructions
8492 ;; %%% This used to optimize known byte-wide and operations to memory.
8493 ;; If this is considered useful, it should be done with splitters.
8495 (define_expand "iordi3"
8496 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8497 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8498 (match_operand:DI 2 "x86_64_general_operand" "")))
8499 (clobber (reg:CC FLAGS_REG))]
8501 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8503 (define_insn "*iordi_1_rex64"
8504 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8505 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8506 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8507 (clobber (reg:CC FLAGS_REG))]
8509 && ix86_binary_operator_ok (IOR, DImode, operands)"
8510 "or{q}\t{%2, %0|%0, %2}"
8511 [(set_attr "type" "alu")
8512 (set_attr "mode" "DI")])
8514 (define_insn "*iordi_2_rex64"
8515 [(set (reg FLAGS_REG)
8516 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8517 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8519 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8520 (ior:DI (match_dup 1) (match_dup 2)))]
8522 && ix86_match_ccmode (insn, CCNOmode)
8523 && ix86_binary_operator_ok (IOR, DImode, operands)"
8524 "or{q}\t{%2, %0|%0, %2}"
8525 [(set_attr "type" "alu")
8526 (set_attr "mode" "DI")])
8528 (define_insn "*iordi_3_rex64"
8529 [(set (reg FLAGS_REG)
8530 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8531 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8533 (clobber (match_scratch:DI 0 "=r"))]
8535 && ix86_match_ccmode (insn, CCNOmode)
8536 && ix86_binary_operator_ok (IOR, DImode, operands)"
8537 "or{q}\t{%2, %0|%0, %2}"
8538 [(set_attr "type" "alu")
8539 (set_attr "mode" "DI")])
8542 (define_expand "iorsi3"
8543 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8544 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8545 (match_operand:SI 2 "general_operand" "")))
8546 (clobber (reg:CC FLAGS_REG))]
8548 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8550 (define_insn "*iorsi_1"
8551 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8552 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8553 (match_operand:SI 2 "general_operand" "ri,rmi")))
8554 (clobber (reg:CC FLAGS_REG))]
8555 "ix86_binary_operator_ok (IOR, SImode, operands)"
8556 "or{l}\t{%2, %0|%0, %2}"
8557 [(set_attr "type" "alu")
8558 (set_attr "mode" "SI")])
8560 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8561 (define_insn "*iorsi_1_zext"
8562 [(set (match_operand:DI 0 "register_operand" "=rm")
8564 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8565 (match_operand:SI 2 "general_operand" "rim"))))
8566 (clobber (reg:CC FLAGS_REG))]
8567 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8568 "or{l}\t{%2, %k0|%k0, %2}"
8569 [(set_attr "type" "alu")
8570 (set_attr "mode" "SI")])
8572 (define_insn "*iorsi_1_zext_imm"
8573 [(set (match_operand:DI 0 "register_operand" "=rm")
8574 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8575 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8576 (clobber (reg:CC FLAGS_REG))]
8578 "or{l}\t{%2, %k0|%k0, %2}"
8579 [(set_attr "type" "alu")
8580 (set_attr "mode" "SI")])
8582 (define_insn "*iorsi_2"
8583 [(set (reg FLAGS_REG)
8584 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8585 (match_operand:SI 2 "general_operand" "rim,ri"))
8587 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8588 (ior:SI (match_dup 1) (match_dup 2)))]
8589 "ix86_match_ccmode (insn, CCNOmode)
8590 && ix86_binary_operator_ok (IOR, SImode, operands)"
8591 "or{l}\t{%2, %0|%0, %2}"
8592 [(set_attr "type" "alu")
8593 (set_attr "mode" "SI")])
8595 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8596 ;; ??? Special case for immediate operand is missing - it is tricky.
8597 (define_insn "*iorsi_2_zext"
8598 [(set (reg FLAGS_REG)
8599 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8600 (match_operand:SI 2 "general_operand" "rim"))
8602 (set (match_operand:DI 0 "register_operand" "=r")
8603 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8604 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8605 && ix86_binary_operator_ok (IOR, SImode, operands)"
8606 "or{l}\t{%2, %k0|%k0, %2}"
8607 [(set_attr "type" "alu")
8608 (set_attr "mode" "SI")])
8610 (define_insn "*iorsi_2_zext_imm"
8611 [(set (reg FLAGS_REG)
8612 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8613 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8615 (set (match_operand:DI 0 "register_operand" "=r")
8616 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8617 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8618 && ix86_binary_operator_ok (IOR, SImode, operands)"
8619 "or{l}\t{%2, %k0|%k0, %2}"
8620 [(set_attr "type" "alu")
8621 (set_attr "mode" "SI")])
8623 (define_insn "*iorsi_3"
8624 [(set (reg FLAGS_REG)
8625 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8626 (match_operand:SI 2 "general_operand" "rim"))
8628 (clobber (match_scratch:SI 0 "=r"))]
8629 "ix86_match_ccmode (insn, CCNOmode)
8630 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8631 "or{l}\t{%2, %0|%0, %2}"
8632 [(set_attr "type" "alu")
8633 (set_attr "mode" "SI")])
8635 (define_expand "iorhi3"
8636 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8637 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8638 (match_operand:HI 2 "general_operand" "")))
8639 (clobber (reg:CC FLAGS_REG))]
8640 "TARGET_HIMODE_MATH"
8641 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8643 (define_insn "*iorhi_1"
8644 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8645 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8646 (match_operand:HI 2 "general_operand" "rmi,ri")))
8647 (clobber (reg:CC FLAGS_REG))]
8648 "ix86_binary_operator_ok (IOR, HImode, operands)"
8649 "or{w}\t{%2, %0|%0, %2}"
8650 [(set_attr "type" "alu")
8651 (set_attr "mode" "HI")])
8653 (define_insn "*iorhi_2"
8654 [(set (reg FLAGS_REG)
8655 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8656 (match_operand:HI 2 "general_operand" "rim,ri"))
8658 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8659 (ior:HI (match_dup 1) (match_dup 2)))]
8660 "ix86_match_ccmode (insn, CCNOmode)
8661 && ix86_binary_operator_ok (IOR, HImode, operands)"
8662 "or{w}\t{%2, %0|%0, %2}"
8663 [(set_attr "type" "alu")
8664 (set_attr "mode" "HI")])
8666 (define_insn "*iorhi_3"
8667 [(set (reg FLAGS_REG)
8668 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8669 (match_operand:HI 2 "general_operand" "rim"))
8671 (clobber (match_scratch:HI 0 "=r"))]
8672 "ix86_match_ccmode (insn, CCNOmode)
8673 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8674 "or{w}\t{%2, %0|%0, %2}"
8675 [(set_attr "type" "alu")
8676 (set_attr "mode" "HI")])
8678 (define_expand "iorqi3"
8679 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8680 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8681 (match_operand:QI 2 "general_operand" "")))
8682 (clobber (reg:CC FLAGS_REG))]
8683 "TARGET_QIMODE_MATH"
8684 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8686 ;; %%% Potential partial reg stall on alternative 2. What to do?
8687 (define_insn "*iorqi_1"
8688 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8689 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8690 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8691 (clobber (reg:CC FLAGS_REG))]
8692 "ix86_binary_operator_ok (IOR, QImode, operands)"
8694 or{b}\t{%2, %0|%0, %2}
8695 or{b}\t{%2, %0|%0, %2}
8696 or{l}\t{%k2, %k0|%k0, %k2}"
8697 [(set_attr "type" "alu")
8698 (set_attr "mode" "QI,QI,SI")])
8700 (define_insn "*iorqi_1_slp"
8701 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8702 (ior:QI (match_dup 0)
8703 (match_operand:QI 1 "general_operand" "qmi,qi")))
8704 (clobber (reg:CC FLAGS_REG))]
8705 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8706 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8707 "or{b}\t{%1, %0|%0, %1}"
8708 [(set_attr "type" "alu1")
8709 (set_attr "mode" "QI")])
8711 (define_insn "*iorqi_2"
8712 [(set (reg FLAGS_REG)
8713 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8714 (match_operand:QI 2 "general_operand" "qim,qi"))
8716 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8717 (ior:QI (match_dup 1) (match_dup 2)))]
8718 "ix86_match_ccmode (insn, CCNOmode)
8719 && ix86_binary_operator_ok (IOR, QImode, operands)"
8720 "or{b}\t{%2, %0|%0, %2}"
8721 [(set_attr "type" "alu")
8722 (set_attr "mode" "QI")])
8724 (define_insn "*iorqi_2_slp"
8725 [(set (reg FLAGS_REG)
8726 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8727 (match_operand:QI 1 "general_operand" "qim,qi"))
8729 (set (strict_low_part (match_dup 0))
8730 (ior:QI (match_dup 0) (match_dup 1)))]
8731 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8732 && ix86_match_ccmode (insn, CCNOmode)
8733 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8734 "or{b}\t{%1, %0|%0, %1}"
8735 [(set_attr "type" "alu1")
8736 (set_attr "mode" "QI")])
8738 (define_insn "*iorqi_3"
8739 [(set (reg FLAGS_REG)
8740 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8741 (match_operand:QI 2 "general_operand" "qim"))
8743 (clobber (match_scratch:QI 0 "=q"))]
8744 "ix86_match_ccmode (insn, CCNOmode)
8745 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8746 "or{b}\t{%2, %0|%0, %2}"
8747 [(set_attr "type" "alu")
8748 (set_attr "mode" "QI")])
8750 (define_insn "iorqi_ext_0"
8751 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8756 (match_operand 1 "ext_register_operand" "0")
8759 (match_operand 2 "const_int_operand" "n")))
8760 (clobber (reg:CC FLAGS_REG))]
8761 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8762 "or{b}\t{%2, %h0|%h0, %2}"
8763 [(set_attr "type" "alu")
8764 (set_attr "length_immediate" "1")
8765 (set_attr "mode" "QI")])
8767 (define_insn "*iorqi_ext_1"
8768 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8773 (match_operand 1 "ext_register_operand" "0")
8777 (match_operand:QI 2 "general_operand" "Qm"))))
8778 (clobber (reg:CC FLAGS_REG))]
8780 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8781 "or{b}\t{%2, %h0|%h0, %2}"
8782 [(set_attr "type" "alu")
8783 (set_attr "length_immediate" "0")
8784 (set_attr "mode" "QI")])
8786 (define_insn "*iorqi_ext_1_rex64"
8787 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8792 (match_operand 1 "ext_register_operand" "0")
8796 (match_operand 2 "ext_register_operand" "Q"))))
8797 (clobber (reg:CC FLAGS_REG))]
8799 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8800 "or{b}\t{%2, %h0|%h0, %2}"
8801 [(set_attr "type" "alu")
8802 (set_attr "length_immediate" "0")
8803 (set_attr "mode" "QI")])
8805 (define_insn "*iorqi_ext_2"
8806 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8810 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8813 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8816 (clobber (reg:CC FLAGS_REG))]
8817 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8818 "ior{b}\t{%h2, %h0|%h0, %h2}"
8819 [(set_attr "type" "alu")
8820 (set_attr "length_immediate" "0")
8821 (set_attr "mode" "QI")])
8824 [(set (match_operand 0 "register_operand" "")
8825 (ior (match_operand 1 "register_operand" "")
8826 (match_operand 2 "const_int_operand" "")))
8827 (clobber (reg:CC FLAGS_REG))]
8829 && QI_REG_P (operands[0])
8830 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8831 && !(INTVAL (operands[2]) & ~(255 << 8))
8832 && GET_MODE (operands[0]) != QImode"
8833 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8834 (ior:SI (zero_extract:SI (match_dup 1)
8835 (const_int 8) (const_int 8))
8837 (clobber (reg:CC FLAGS_REG))])]
8838 "operands[0] = gen_lowpart (SImode, operands[0]);
8839 operands[1] = gen_lowpart (SImode, operands[1]);
8840 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8842 ;; Since OR can be encoded with sign extended immediate, this is only
8843 ;; profitable when 7th bit is set.
8845 [(set (match_operand 0 "register_operand" "")
8846 (ior (match_operand 1 "general_operand" "")
8847 (match_operand 2 "const_int_operand" "")))
8848 (clobber (reg:CC FLAGS_REG))]
8850 && ANY_QI_REG_P (operands[0])
8851 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8852 && !(INTVAL (operands[2]) & ~255)
8853 && (INTVAL (operands[2]) & 128)
8854 && GET_MODE (operands[0]) != QImode"
8855 [(parallel [(set (strict_low_part (match_dup 0))
8856 (ior:QI (match_dup 1)
8858 (clobber (reg:CC FLAGS_REG))])]
8859 "operands[0] = gen_lowpart (QImode, operands[0]);
8860 operands[1] = gen_lowpart (QImode, operands[1]);
8861 operands[2] = gen_lowpart (QImode, operands[2]);")
8863 ;; Logical XOR instructions
8865 ;; %%% This used to optimize known byte-wide and operations to memory.
8866 ;; If this is considered useful, it should be done with splitters.
8868 (define_expand "xordi3"
8869 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8870 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8871 (match_operand:DI 2 "x86_64_general_operand" "")))
8872 (clobber (reg:CC FLAGS_REG))]
8874 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8876 (define_insn "*xordi_1_rex64"
8877 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8878 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8879 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8880 (clobber (reg:CC FLAGS_REG))]
8882 && ix86_binary_operator_ok (XOR, DImode, operands)"
8884 xor{q}\t{%2, %0|%0, %2}
8885 xor{q}\t{%2, %0|%0, %2}"
8886 [(set_attr "type" "alu")
8887 (set_attr "mode" "DI,DI")])
8889 (define_insn "*xordi_2_rex64"
8890 [(set (reg FLAGS_REG)
8891 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8892 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8894 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8895 (xor:DI (match_dup 1) (match_dup 2)))]
8897 && ix86_match_ccmode (insn, CCNOmode)
8898 && ix86_binary_operator_ok (XOR, DImode, operands)"
8900 xor{q}\t{%2, %0|%0, %2}
8901 xor{q}\t{%2, %0|%0, %2}"
8902 [(set_attr "type" "alu")
8903 (set_attr "mode" "DI,DI")])
8905 (define_insn "*xordi_3_rex64"
8906 [(set (reg FLAGS_REG)
8907 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8908 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8910 (clobber (match_scratch:DI 0 "=r"))]
8912 && ix86_match_ccmode (insn, CCNOmode)
8913 && ix86_binary_operator_ok (XOR, DImode, operands)"
8914 "xor{q}\t{%2, %0|%0, %2}"
8915 [(set_attr "type" "alu")
8916 (set_attr "mode" "DI")])
8918 (define_expand "xorsi3"
8919 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8920 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8921 (match_operand:SI 2 "general_operand" "")))
8922 (clobber (reg:CC FLAGS_REG))]
8924 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8926 (define_insn "*xorsi_1"
8927 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8928 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8929 (match_operand:SI 2 "general_operand" "ri,rm")))
8930 (clobber (reg:CC FLAGS_REG))]
8931 "ix86_binary_operator_ok (XOR, SImode, operands)"
8932 "xor{l}\t{%2, %0|%0, %2}"
8933 [(set_attr "type" "alu")
8934 (set_attr "mode" "SI")])
8936 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8937 ;; Add speccase for immediates
8938 (define_insn "*xorsi_1_zext"
8939 [(set (match_operand:DI 0 "register_operand" "=r")
8941 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8942 (match_operand:SI 2 "general_operand" "rim"))))
8943 (clobber (reg:CC FLAGS_REG))]
8944 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8945 "xor{l}\t{%2, %k0|%k0, %2}"
8946 [(set_attr "type" "alu")
8947 (set_attr "mode" "SI")])
8949 (define_insn "*xorsi_1_zext_imm"
8950 [(set (match_operand:DI 0 "register_operand" "=r")
8951 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8952 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8953 (clobber (reg:CC FLAGS_REG))]
8954 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8955 "xor{l}\t{%2, %k0|%k0, %2}"
8956 [(set_attr "type" "alu")
8957 (set_attr "mode" "SI")])
8959 (define_insn "*xorsi_2"
8960 [(set (reg FLAGS_REG)
8961 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8962 (match_operand:SI 2 "general_operand" "rim,ri"))
8964 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8965 (xor:SI (match_dup 1) (match_dup 2)))]
8966 "ix86_match_ccmode (insn, CCNOmode)
8967 && ix86_binary_operator_ok (XOR, SImode, operands)"
8968 "xor{l}\t{%2, %0|%0, %2}"
8969 [(set_attr "type" "alu")
8970 (set_attr "mode" "SI")])
8972 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8973 ;; ??? Special case for immediate operand is missing - it is tricky.
8974 (define_insn "*xorsi_2_zext"
8975 [(set (reg FLAGS_REG)
8976 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8977 (match_operand:SI 2 "general_operand" "rim"))
8979 (set (match_operand:DI 0 "register_operand" "=r")
8980 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8981 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8982 && ix86_binary_operator_ok (XOR, SImode, operands)"
8983 "xor{l}\t{%2, %k0|%k0, %2}"
8984 [(set_attr "type" "alu")
8985 (set_attr "mode" "SI")])
8987 (define_insn "*xorsi_2_zext_imm"
8988 [(set (reg FLAGS_REG)
8989 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8990 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8992 (set (match_operand:DI 0 "register_operand" "=r")
8993 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8994 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8995 && ix86_binary_operator_ok (XOR, SImode, operands)"
8996 "xor{l}\t{%2, %k0|%k0, %2}"
8997 [(set_attr "type" "alu")
8998 (set_attr "mode" "SI")])
9000 (define_insn "*xorsi_3"
9001 [(set (reg FLAGS_REG)
9002 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9003 (match_operand:SI 2 "general_operand" "rim"))
9005 (clobber (match_scratch:SI 0 "=r"))]
9006 "ix86_match_ccmode (insn, CCNOmode)
9007 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9008 "xor{l}\t{%2, %0|%0, %2}"
9009 [(set_attr "type" "alu")
9010 (set_attr "mode" "SI")])
9012 (define_expand "xorhi3"
9013 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9014 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9015 (match_operand:HI 2 "general_operand" "")))
9016 (clobber (reg:CC FLAGS_REG))]
9017 "TARGET_HIMODE_MATH"
9018 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9020 (define_insn "*xorhi_1"
9021 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9022 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9023 (match_operand:HI 2 "general_operand" "rmi,ri")))
9024 (clobber (reg:CC FLAGS_REG))]
9025 "ix86_binary_operator_ok (XOR, HImode, operands)"
9026 "xor{w}\t{%2, %0|%0, %2}"
9027 [(set_attr "type" "alu")
9028 (set_attr "mode" "HI")])
9030 (define_insn "*xorhi_2"
9031 [(set (reg FLAGS_REG)
9032 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9033 (match_operand:HI 2 "general_operand" "rim,ri"))
9035 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9036 (xor:HI (match_dup 1) (match_dup 2)))]
9037 "ix86_match_ccmode (insn, CCNOmode)
9038 && ix86_binary_operator_ok (XOR, HImode, operands)"
9039 "xor{w}\t{%2, %0|%0, %2}"
9040 [(set_attr "type" "alu")
9041 (set_attr "mode" "HI")])
9043 (define_insn "*xorhi_3"
9044 [(set (reg FLAGS_REG)
9045 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9046 (match_operand:HI 2 "general_operand" "rim"))
9048 (clobber (match_scratch:HI 0 "=r"))]
9049 "ix86_match_ccmode (insn, CCNOmode)
9050 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9051 "xor{w}\t{%2, %0|%0, %2}"
9052 [(set_attr "type" "alu")
9053 (set_attr "mode" "HI")])
9055 (define_expand "xorqi3"
9056 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9057 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9058 (match_operand:QI 2 "general_operand" "")))
9059 (clobber (reg:CC FLAGS_REG))]
9060 "TARGET_QIMODE_MATH"
9061 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9063 ;; %%% Potential partial reg stall on alternative 2. What to do?
9064 (define_insn "*xorqi_1"
9065 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9066 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9067 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9068 (clobber (reg:CC FLAGS_REG))]
9069 "ix86_binary_operator_ok (XOR, QImode, operands)"
9071 xor{b}\t{%2, %0|%0, %2}
9072 xor{b}\t{%2, %0|%0, %2}
9073 xor{l}\t{%k2, %k0|%k0, %k2}"
9074 [(set_attr "type" "alu")
9075 (set_attr "mode" "QI,QI,SI")])
9077 (define_insn "*xorqi_1_slp"
9078 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9079 (xor:QI (match_dup 0)
9080 (match_operand:QI 1 "general_operand" "qi,qmi")))
9081 (clobber (reg:CC FLAGS_REG))]
9082 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9083 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9084 "xor{b}\t{%1, %0|%0, %1}"
9085 [(set_attr "type" "alu1")
9086 (set_attr "mode" "QI")])
9088 (define_insn "xorqi_ext_0"
9089 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9094 (match_operand 1 "ext_register_operand" "0")
9097 (match_operand 2 "const_int_operand" "n")))
9098 (clobber (reg:CC FLAGS_REG))]
9099 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9100 "xor{b}\t{%2, %h0|%h0, %2}"
9101 [(set_attr "type" "alu")
9102 (set_attr "length_immediate" "1")
9103 (set_attr "mode" "QI")])
9105 (define_insn "*xorqi_ext_1"
9106 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9111 (match_operand 1 "ext_register_operand" "0")
9115 (match_operand:QI 2 "general_operand" "Qm"))))
9116 (clobber (reg:CC FLAGS_REG))]
9118 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9119 "xor{b}\t{%2, %h0|%h0, %2}"
9120 [(set_attr "type" "alu")
9121 (set_attr "length_immediate" "0")
9122 (set_attr "mode" "QI")])
9124 (define_insn "*xorqi_ext_1_rex64"
9125 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9130 (match_operand 1 "ext_register_operand" "0")
9134 (match_operand 2 "ext_register_operand" "Q"))))
9135 (clobber (reg:CC FLAGS_REG))]
9137 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9138 "xor{b}\t{%2, %h0|%h0, %2}"
9139 [(set_attr "type" "alu")
9140 (set_attr "length_immediate" "0")
9141 (set_attr "mode" "QI")])
9143 (define_insn "*xorqi_ext_2"
9144 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9148 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9151 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9154 (clobber (reg:CC FLAGS_REG))]
9155 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9156 "xor{b}\t{%h2, %h0|%h0, %h2}"
9157 [(set_attr "type" "alu")
9158 (set_attr "length_immediate" "0")
9159 (set_attr "mode" "QI")])
9161 (define_insn "*xorqi_cc_1"
9162 [(set (reg FLAGS_REG)
9164 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9165 (match_operand:QI 2 "general_operand" "qim,qi"))
9167 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9168 (xor:QI (match_dup 1) (match_dup 2)))]
9169 "ix86_match_ccmode (insn, CCNOmode)
9170 && ix86_binary_operator_ok (XOR, QImode, operands)"
9171 "xor{b}\t{%2, %0|%0, %2}"
9172 [(set_attr "type" "alu")
9173 (set_attr "mode" "QI")])
9175 (define_insn "*xorqi_2_slp"
9176 [(set (reg FLAGS_REG)
9177 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9178 (match_operand:QI 1 "general_operand" "qim,qi"))
9180 (set (strict_low_part (match_dup 0))
9181 (xor:QI (match_dup 0) (match_dup 1)))]
9182 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9183 && ix86_match_ccmode (insn, CCNOmode)
9184 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9185 "xor{b}\t{%1, %0|%0, %1}"
9186 [(set_attr "type" "alu1")
9187 (set_attr "mode" "QI")])
9189 (define_insn "*xorqi_cc_2"
9190 [(set (reg FLAGS_REG)
9192 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9193 (match_operand:QI 2 "general_operand" "qim"))
9195 (clobber (match_scratch:QI 0 "=q"))]
9196 "ix86_match_ccmode (insn, CCNOmode)
9197 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9198 "xor{b}\t{%2, %0|%0, %2}"
9199 [(set_attr "type" "alu")
9200 (set_attr "mode" "QI")])
9202 (define_insn "*xorqi_cc_ext_1"
9203 [(set (reg FLAGS_REG)
9207 (match_operand 1 "ext_register_operand" "0")
9210 (match_operand:QI 2 "general_operand" "qmn"))
9212 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9216 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9218 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9219 "xor{b}\t{%2, %h0|%h0, %2}"
9220 [(set_attr "type" "alu")
9221 (set_attr "mode" "QI")])
9223 (define_insn "*xorqi_cc_ext_1_rex64"
9224 [(set (reg FLAGS_REG)
9228 (match_operand 1 "ext_register_operand" "0")
9231 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9233 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9237 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9239 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9240 "xor{b}\t{%2, %h0|%h0, %2}"
9241 [(set_attr "type" "alu")
9242 (set_attr "mode" "QI")])
9244 (define_expand "xorqi_cc_ext_1"
9246 (set (reg:CCNO FLAGS_REG)
9250 (match_operand 1 "ext_register_operand" "")
9253 (match_operand:QI 2 "general_operand" ""))
9255 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9259 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9265 [(set (match_operand 0 "register_operand" "")
9266 (xor (match_operand 1 "register_operand" "")
9267 (match_operand 2 "const_int_operand" "")))
9268 (clobber (reg:CC FLAGS_REG))]
9270 && QI_REG_P (operands[0])
9271 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9272 && !(INTVAL (operands[2]) & ~(255 << 8))
9273 && GET_MODE (operands[0]) != QImode"
9274 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9275 (xor:SI (zero_extract:SI (match_dup 1)
9276 (const_int 8) (const_int 8))
9278 (clobber (reg:CC FLAGS_REG))])]
9279 "operands[0] = gen_lowpart (SImode, operands[0]);
9280 operands[1] = gen_lowpart (SImode, operands[1]);
9281 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9283 ;; Since XOR can be encoded with sign extended immediate, this is only
9284 ;; profitable when 7th bit is set.
9286 [(set (match_operand 0 "register_operand" "")
9287 (xor (match_operand 1 "general_operand" "")
9288 (match_operand 2 "const_int_operand" "")))
9289 (clobber (reg:CC FLAGS_REG))]
9291 && ANY_QI_REG_P (operands[0])
9292 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9293 && !(INTVAL (operands[2]) & ~255)
9294 && (INTVAL (operands[2]) & 128)
9295 && GET_MODE (operands[0]) != QImode"
9296 [(parallel [(set (strict_low_part (match_dup 0))
9297 (xor:QI (match_dup 1)
9299 (clobber (reg:CC FLAGS_REG))])]
9300 "operands[0] = gen_lowpart (QImode, operands[0]);
9301 operands[1] = gen_lowpart (QImode, operands[1]);
9302 operands[2] = gen_lowpart (QImode, operands[2]);")
9304 ;; Negation instructions
9306 (define_expand "negti2"
9307 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9308 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9309 (clobber (reg:CC FLAGS_REG))])]
9311 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9313 (define_insn "*negti2_1"
9314 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9315 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9316 (clobber (reg:CC FLAGS_REG))]
9318 && ix86_unary_operator_ok (NEG, TImode, operands)"
9322 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9323 (neg:TI (match_operand:TI 1 "general_operand" "")))
9324 (clobber (reg:CC FLAGS_REG))]
9325 "TARGET_64BIT && reload_completed"
9327 [(set (reg:CCZ FLAGS_REG)
9328 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9329 (set (match_dup 0) (neg:DI (match_dup 2)))])
9332 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9335 (clobber (reg:CC FLAGS_REG))])
9338 (neg:DI (match_dup 1)))
9339 (clobber (reg:CC FLAGS_REG))])]
9340 "split_ti (operands+1, 1, operands+2, operands+3);
9341 split_ti (operands+0, 1, operands+0, operands+1);")
9343 (define_expand "negdi2"
9344 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9345 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9346 (clobber (reg:CC FLAGS_REG))])]
9348 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9350 (define_insn "*negdi2_1"
9351 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9352 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9353 (clobber (reg:CC FLAGS_REG))]
9355 && ix86_unary_operator_ok (NEG, DImode, operands)"
9359 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9360 (neg:DI (match_operand:DI 1 "general_operand" "")))
9361 (clobber (reg:CC FLAGS_REG))]
9362 "!TARGET_64BIT && reload_completed"
9364 [(set (reg:CCZ FLAGS_REG)
9365 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9366 (set (match_dup 0) (neg:SI (match_dup 2)))])
9369 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9372 (clobber (reg:CC FLAGS_REG))])
9375 (neg:SI (match_dup 1)))
9376 (clobber (reg:CC FLAGS_REG))])]
9377 "split_di (operands+1, 1, operands+2, operands+3);
9378 split_di (operands+0, 1, operands+0, operands+1);")
9380 (define_insn "*negdi2_1_rex64"
9381 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9382 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9383 (clobber (reg:CC FLAGS_REG))]
9384 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9386 [(set_attr "type" "negnot")
9387 (set_attr "mode" "DI")])
9389 ;; The problem with neg is that it does not perform (compare x 0),
9390 ;; it really performs (compare 0 x), which leaves us with the zero
9391 ;; flag being the only useful item.
9393 (define_insn "*negdi2_cmpz_rex64"
9394 [(set (reg:CCZ FLAGS_REG)
9395 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9397 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9398 (neg:DI (match_dup 1)))]
9399 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9401 [(set_attr "type" "negnot")
9402 (set_attr "mode" "DI")])
9405 (define_expand "negsi2"
9406 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9407 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9408 (clobber (reg:CC FLAGS_REG))])]
9410 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9412 (define_insn "*negsi2_1"
9413 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9414 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9415 (clobber (reg:CC FLAGS_REG))]
9416 "ix86_unary_operator_ok (NEG, SImode, operands)"
9418 [(set_attr "type" "negnot")
9419 (set_attr "mode" "SI")])
9421 ;; Combine is quite creative about this pattern.
9422 (define_insn "*negsi2_1_zext"
9423 [(set (match_operand:DI 0 "register_operand" "=r")
9424 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9427 (clobber (reg:CC FLAGS_REG))]
9428 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9430 [(set_attr "type" "negnot")
9431 (set_attr "mode" "SI")])
9433 ;; The problem with neg is that it does not perform (compare x 0),
9434 ;; it really performs (compare 0 x), which leaves us with the zero
9435 ;; flag being the only useful item.
9437 (define_insn "*negsi2_cmpz"
9438 [(set (reg:CCZ FLAGS_REG)
9439 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9441 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9442 (neg:SI (match_dup 1)))]
9443 "ix86_unary_operator_ok (NEG, SImode, operands)"
9445 [(set_attr "type" "negnot")
9446 (set_attr "mode" "SI")])
9448 (define_insn "*negsi2_cmpz_zext"
9449 [(set (reg:CCZ FLAGS_REG)
9450 (compare:CCZ (lshiftrt:DI
9452 (match_operand:DI 1 "register_operand" "0")
9456 (set (match_operand:DI 0 "register_operand" "=r")
9457 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9460 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9462 [(set_attr "type" "negnot")
9463 (set_attr "mode" "SI")])
9465 (define_expand "neghi2"
9466 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9467 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9468 (clobber (reg:CC FLAGS_REG))])]
9469 "TARGET_HIMODE_MATH"
9470 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9472 (define_insn "*neghi2_1"
9473 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9474 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9475 (clobber (reg:CC FLAGS_REG))]
9476 "ix86_unary_operator_ok (NEG, HImode, operands)"
9478 [(set_attr "type" "negnot")
9479 (set_attr "mode" "HI")])
9481 (define_insn "*neghi2_cmpz"
9482 [(set (reg:CCZ FLAGS_REG)
9483 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9485 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9486 (neg:HI (match_dup 1)))]
9487 "ix86_unary_operator_ok (NEG, HImode, operands)"
9489 [(set_attr "type" "negnot")
9490 (set_attr "mode" "HI")])
9492 (define_expand "negqi2"
9493 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9494 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9495 (clobber (reg:CC FLAGS_REG))])]
9496 "TARGET_QIMODE_MATH"
9497 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9499 (define_insn "*negqi2_1"
9500 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9501 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9502 (clobber (reg:CC FLAGS_REG))]
9503 "ix86_unary_operator_ok (NEG, QImode, operands)"
9505 [(set_attr "type" "negnot")
9506 (set_attr "mode" "QI")])
9508 (define_insn "*negqi2_cmpz"
9509 [(set (reg:CCZ FLAGS_REG)
9510 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9512 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9513 (neg:QI (match_dup 1)))]
9514 "ix86_unary_operator_ok (NEG, QImode, operands)"
9516 [(set_attr "type" "negnot")
9517 (set_attr "mode" "QI")])
9519 ;; Changing of sign for FP values is doable using integer unit too.
9521 (define_expand "negsf2"
9522 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9523 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9524 "TARGET_80387 || TARGET_SSE_MATH"
9525 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9527 (define_expand "abssf2"
9528 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9529 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9530 "TARGET_80387 || TARGET_SSE_MATH"
9531 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9533 (define_insn "*absnegsf2_mixed"
9534 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9535 (match_operator:SF 3 "absneg_operator"
9536 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9537 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9538 (clobber (reg:CC FLAGS_REG))]
9539 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9540 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9543 (define_insn "*absnegsf2_sse"
9544 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9545 (match_operator:SF 3 "absneg_operator"
9546 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9547 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9548 (clobber (reg:CC FLAGS_REG))]
9550 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9553 (define_insn "*absnegsf2_i387"
9554 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9555 (match_operator:SF 3 "absneg_operator"
9556 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9557 (use (match_operand 2 "" ""))
9558 (clobber (reg:CC FLAGS_REG))]
9559 "TARGET_80387 && !TARGET_SSE_MATH
9560 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9563 (define_expand "copysignsf3"
9564 [(match_operand:SF 0 "register_operand" "")
9565 (match_operand:SF 1 "nonmemory_operand" "")
9566 (match_operand:SF 2 "register_operand" "")]
9569 ix86_expand_copysign (operands);
9573 (define_insn_and_split "copysignsf3_const"
9574 [(set (match_operand:SF 0 "register_operand" "=x")
9576 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9577 (match_operand:SF 2 "register_operand" "0")
9578 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9582 "&& reload_completed"
9585 ix86_split_copysign_const (operands);
9589 (define_insn "copysignsf3_var"
9590 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9592 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9593 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9594 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9595 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9597 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9602 [(set (match_operand:SF 0 "register_operand" "")
9604 [(match_operand:SF 2 "register_operand" "")
9605 (match_operand:SF 3 "register_operand" "")
9606 (match_operand:V4SF 4 "" "")
9607 (match_operand:V4SF 5 "" "")]
9609 (clobber (match_scratch:V4SF 1 ""))]
9610 "TARGET_SSE_MATH && reload_completed"
9613 ix86_split_copysign_var (operands);
9617 (define_expand "negdf2"
9618 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9619 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9620 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9621 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9623 (define_expand "absdf2"
9624 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9625 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9626 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9627 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9629 (define_insn "*absnegdf2_mixed"
9630 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9631 (match_operator:DF 3 "absneg_operator"
9632 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9633 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9634 (clobber (reg:CC FLAGS_REG))]
9635 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9636 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9639 (define_insn "*absnegdf2_sse"
9640 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9641 (match_operator:DF 3 "absneg_operator"
9642 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9643 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9644 (clobber (reg:CC FLAGS_REG))]
9645 "TARGET_SSE2 && TARGET_SSE_MATH
9646 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9649 (define_insn "*absnegdf2_i387"
9650 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9651 (match_operator:DF 3 "absneg_operator"
9652 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9653 (use (match_operand 2 "" ""))
9654 (clobber (reg:CC FLAGS_REG))]
9655 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9656 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9659 (define_expand "copysigndf3"
9660 [(match_operand:DF 0 "register_operand" "")
9661 (match_operand:DF 1 "nonmemory_operand" "")
9662 (match_operand:DF 2 "register_operand" "")]
9663 "TARGET_SSE2 && TARGET_SSE_MATH"
9665 ix86_expand_copysign (operands);
9669 (define_insn_and_split "copysigndf3_const"
9670 [(set (match_operand:DF 0 "register_operand" "=x")
9672 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9673 (match_operand:DF 2 "register_operand" "0")
9674 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9676 "TARGET_SSE2 && TARGET_SSE_MATH"
9678 "&& reload_completed"
9681 ix86_split_copysign_const (operands);
9685 (define_insn "copysigndf3_var"
9686 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9688 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9689 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9690 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9691 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9693 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9694 "TARGET_SSE2 && TARGET_SSE_MATH"
9698 [(set (match_operand:DF 0 "register_operand" "")
9700 [(match_operand:DF 2 "register_operand" "")
9701 (match_operand:DF 3 "register_operand" "")
9702 (match_operand:V2DF 4 "" "")
9703 (match_operand:V2DF 5 "" "")]
9705 (clobber (match_scratch:V2DF 1 ""))]
9706 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9709 ix86_split_copysign_var (operands);
9713 (define_expand "negxf2"
9714 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9715 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9717 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9719 (define_expand "absxf2"
9720 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9721 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9723 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9725 (define_insn "*absnegxf2_i387"
9726 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9727 (match_operator:XF 3 "absneg_operator"
9728 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9729 (use (match_operand 2 "" ""))
9730 (clobber (reg:CC FLAGS_REG))]
9732 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9735 ;; Splitters for fp abs and neg.
9738 [(set (match_operand 0 "fp_register_operand" "")
9739 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9740 (use (match_operand 2 "" ""))
9741 (clobber (reg:CC FLAGS_REG))]
9743 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9746 [(set (match_operand 0 "register_operand" "")
9747 (match_operator 3 "absneg_operator"
9748 [(match_operand 1 "register_operand" "")]))
9749 (use (match_operand 2 "nonimmediate_operand" ""))
9750 (clobber (reg:CC FLAGS_REG))]
9751 "reload_completed && SSE_REG_P (operands[0])"
9752 [(set (match_dup 0) (match_dup 3))]
9754 enum machine_mode mode = GET_MODE (operands[0]);
9755 enum machine_mode vmode = GET_MODE (operands[2]);
9758 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9759 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9760 if (operands_match_p (operands[0], operands[2]))
9763 operands[1] = operands[2];
9766 if (GET_CODE (operands[3]) == ABS)
9767 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9769 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9774 [(set (match_operand:SF 0 "register_operand" "")
9775 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9776 (use (match_operand:V4SF 2 "" ""))
9777 (clobber (reg:CC FLAGS_REG))]
9779 [(parallel [(set (match_dup 0) (match_dup 1))
9780 (clobber (reg:CC FLAGS_REG))])]
9783 operands[0] = gen_lowpart (SImode, operands[0]);
9784 if (GET_CODE (operands[1]) == ABS)
9786 tmp = gen_int_mode (0x7fffffff, SImode);
9787 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9791 tmp = gen_int_mode (0x80000000, SImode);
9792 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9798 [(set (match_operand:DF 0 "register_operand" "")
9799 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9800 (use (match_operand 2 "" ""))
9801 (clobber (reg:CC FLAGS_REG))]
9803 [(parallel [(set (match_dup 0) (match_dup 1))
9804 (clobber (reg:CC FLAGS_REG))])]
9809 tmp = gen_lowpart (DImode, operands[0]);
9810 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9813 if (GET_CODE (operands[1]) == ABS)
9816 tmp = gen_rtx_NOT (DImode, tmp);
9820 operands[0] = gen_highpart (SImode, operands[0]);
9821 if (GET_CODE (operands[1]) == ABS)
9823 tmp = gen_int_mode (0x7fffffff, SImode);
9824 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9828 tmp = gen_int_mode (0x80000000, SImode);
9829 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9836 [(set (match_operand:XF 0 "register_operand" "")
9837 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9838 (use (match_operand 2 "" ""))
9839 (clobber (reg:CC FLAGS_REG))]
9841 [(parallel [(set (match_dup 0) (match_dup 1))
9842 (clobber (reg:CC FLAGS_REG))])]
9845 operands[0] = gen_rtx_REG (SImode,
9846 true_regnum (operands[0])
9847 + (TARGET_64BIT ? 1 : 2));
9848 if (GET_CODE (operands[1]) == ABS)
9850 tmp = GEN_INT (0x7fff);
9851 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9855 tmp = GEN_INT (0x8000);
9856 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9862 [(set (match_operand 0 "memory_operand" "")
9863 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9864 (use (match_operand 2 "" ""))
9865 (clobber (reg:CC FLAGS_REG))]
9867 [(parallel [(set (match_dup 0) (match_dup 1))
9868 (clobber (reg:CC FLAGS_REG))])]
9870 enum machine_mode mode = GET_MODE (operands[0]);
9871 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9874 operands[0] = adjust_address (operands[0], QImode, size - 1);
9875 if (GET_CODE (operands[1]) == ABS)
9877 tmp = gen_int_mode (0x7f, QImode);
9878 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9882 tmp = gen_int_mode (0x80, QImode);
9883 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9888 ;; Conditionalize these after reload. If they match before reload, we
9889 ;; lose the clobber and ability to use integer instructions.
9891 (define_insn "*negsf2_1"
9892 [(set (match_operand:SF 0 "register_operand" "=f")
9893 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9894 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9896 [(set_attr "type" "fsgn")
9897 (set_attr "mode" "SF")])
9899 (define_insn "*negdf2_1"
9900 [(set (match_operand:DF 0 "register_operand" "=f")
9901 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9902 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9904 [(set_attr "type" "fsgn")
9905 (set_attr "mode" "DF")])
9907 (define_insn "*negxf2_1"
9908 [(set (match_operand:XF 0 "register_operand" "=f")
9909 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9912 [(set_attr "type" "fsgn")
9913 (set_attr "mode" "XF")])
9915 (define_insn "*abssf2_1"
9916 [(set (match_operand:SF 0 "register_operand" "=f")
9917 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9918 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9920 [(set_attr "type" "fsgn")
9921 (set_attr "mode" "SF")])
9923 (define_insn "*absdf2_1"
9924 [(set (match_operand:DF 0 "register_operand" "=f")
9925 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9926 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9928 [(set_attr "type" "fsgn")
9929 (set_attr "mode" "DF")])
9931 (define_insn "*absxf2_1"
9932 [(set (match_operand:XF 0 "register_operand" "=f")
9933 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9936 [(set_attr "type" "fsgn")
9937 (set_attr "mode" "DF")])
9939 (define_insn "*negextendsfdf2"
9940 [(set (match_operand:DF 0 "register_operand" "=f")
9941 (neg:DF (float_extend:DF
9942 (match_operand:SF 1 "register_operand" "0"))))]
9943 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9945 [(set_attr "type" "fsgn")
9946 (set_attr "mode" "DF")])
9948 (define_insn "*negextenddfxf2"
9949 [(set (match_operand:XF 0 "register_operand" "=f")
9950 (neg:XF (float_extend:XF
9951 (match_operand:DF 1 "register_operand" "0"))))]
9954 [(set_attr "type" "fsgn")
9955 (set_attr "mode" "XF")])
9957 (define_insn "*negextendsfxf2"
9958 [(set (match_operand:XF 0 "register_operand" "=f")
9959 (neg:XF (float_extend:XF
9960 (match_operand:SF 1 "register_operand" "0"))))]
9963 [(set_attr "type" "fsgn")
9964 (set_attr "mode" "XF")])
9966 (define_insn "*absextendsfdf2"
9967 [(set (match_operand:DF 0 "register_operand" "=f")
9968 (abs:DF (float_extend:DF
9969 (match_operand:SF 1 "register_operand" "0"))))]
9970 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9972 [(set_attr "type" "fsgn")
9973 (set_attr "mode" "DF")])
9975 (define_insn "*absextenddfxf2"
9976 [(set (match_operand:XF 0 "register_operand" "=f")
9977 (abs:XF (float_extend:XF
9978 (match_operand:DF 1 "register_operand" "0"))))]
9981 [(set_attr "type" "fsgn")
9982 (set_attr "mode" "XF")])
9984 (define_insn "*absextendsfxf2"
9985 [(set (match_operand:XF 0 "register_operand" "=f")
9986 (abs:XF (float_extend:XF
9987 (match_operand:SF 1 "register_operand" "0"))))]
9990 [(set_attr "type" "fsgn")
9991 (set_attr "mode" "XF")])
9993 ;; One complement instructions
9995 (define_expand "one_cmpldi2"
9996 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9997 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9999 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10001 (define_insn "*one_cmpldi2_1_rex64"
10002 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10003 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10004 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10006 [(set_attr "type" "negnot")
10007 (set_attr "mode" "DI")])
10009 (define_insn "*one_cmpldi2_2_rex64"
10010 [(set (reg FLAGS_REG)
10011 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10013 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10014 (not:DI (match_dup 1)))]
10015 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10016 && ix86_unary_operator_ok (NOT, DImode, operands)"
10018 [(set_attr "type" "alu1")
10019 (set_attr "mode" "DI")])
10022 [(set (match_operand 0 "flags_reg_operand" "")
10023 (match_operator 2 "compare_operator"
10024 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10026 (set (match_operand:DI 1 "nonimmediate_operand" "")
10027 (not:DI (match_dup 3)))]
10028 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10029 [(parallel [(set (match_dup 0)
10031 [(xor:DI (match_dup 3) (const_int -1))
10034 (xor:DI (match_dup 3) (const_int -1)))])]
10037 (define_expand "one_cmplsi2"
10038 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10039 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10041 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10043 (define_insn "*one_cmplsi2_1"
10044 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10045 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10046 "ix86_unary_operator_ok (NOT, SImode, operands)"
10048 [(set_attr "type" "negnot")
10049 (set_attr "mode" "SI")])
10051 ;; ??? Currently never generated - xor is used instead.
10052 (define_insn "*one_cmplsi2_1_zext"
10053 [(set (match_operand:DI 0 "register_operand" "=r")
10054 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10055 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10057 [(set_attr "type" "negnot")
10058 (set_attr "mode" "SI")])
10060 (define_insn "*one_cmplsi2_2"
10061 [(set (reg FLAGS_REG)
10062 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10064 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10065 (not:SI (match_dup 1)))]
10066 "ix86_match_ccmode (insn, CCNOmode)
10067 && ix86_unary_operator_ok (NOT, SImode, operands)"
10069 [(set_attr "type" "alu1")
10070 (set_attr "mode" "SI")])
10073 [(set (match_operand 0 "flags_reg_operand" "")
10074 (match_operator 2 "compare_operator"
10075 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10077 (set (match_operand:SI 1 "nonimmediate_operand" "")
10078 (not:SI (match_dup 3)))]
10079 "ix86_match_ccmode (insn, CCNOmode)"
10080 [(parallel [(set (match_dup 0)
10081 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10084 (xor:SI (match_dup 3) (const_int -1)))])]
10087 ;; ??? Currently never generated - xor is used instead.
10088 (define_insn "*one_cmplsi2_2_zext"
10089 [(set (reg FLAGS_REG)
10090 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10092 (set (match_operand:DI 0 "register_operand" "=r")
10093 (zero_extend:DI (not:SI (match_dup 1))))]
10094 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10095 && ix86_unary_operator_ok (NOT, SImode, operands)"
10097 [(set_attr "type" "alu1")
10098 (set_attr "mode" "SI")])
10101 [(set (match_operand 0 "flags_reg_operand" "")
10102 (match_operator 2 "compare_operator"
10103 [(not:SI (match_operand:SI 3 "register_operand" ""))
10105 (set (match_operand:DI 1 "register_operand" "")
10106 (zero_extend:DI (not:SI (match_dup 3))))]
10107 "ix86_match_ccmode (insn, CCNOmode)"
10108 [(parallel [(set (match_dup 0)
10109 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10112 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10115 (define_expand "one_cmplhi2"
10116 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10117 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10118 "TARGET_HIMODE_MATH"
10119 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10121 (define_insn "*one_cmplhi2_1"
10122 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10123 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10124 "ix86_unary_operator_ok (NOT, HImode, operands)"
10126 [(set_attr "type" "negnot")
10127 (set_attr "mode" "HI")])
10129 (define_insn "*one_cmplhi2_2"
10130 [(set (reg FLAGS_REG)
10131 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10133 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10134 (not:HI (match_dup 1)))]
10135 "ix86_match_ccmode (insn, CCNOmode)
10136 && ix86_unary_operator_ok (NEG, HImode, operands)"
10138 [(set_attr "type" "alu1")
10139 (set_attr "mode" "HI")])
10142 [(set (match_operand 0 "flags_reg_operand" "")
10143 (match_operator 2 "compare_operator"
10144 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10146 (set (match_operand:HI 1 "nonimmediate_operand" "")
10147 (not:HI (match_dup 3)))]
10148 "ix86_match_ccmode (insn, CCNOmode)"
10149 [(parallel [(set (match_dup 0)
10150 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10153 (xor:HI (match_dup 3) (const_int -1)))])]
10156 ;; %%% Potential partial reg stall on alternative 1. What to do?
10157 (define_expand "one_cmplqi2"
10158 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10159 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10160 "TARGET_QIMODE_MATH"
10161 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10163 (define_insn "*one_cmplqi2_1"
10164 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10165 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10166 "ix86_unary_operator_ok (NOT, QImode, operands)"
10170 [(set_attr "type" "negnot")
10171 (set_attr "mode" "QI,SI")])
10173 (define_insn "*one_cmplqi2_2"
10174 [(set (reg FLAGS_REG)
10175 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10177 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10178 (not:QI (match_dup 1)))]
10179 "ix86_match_ccmode (insn, CCNOmode)
10180 && ix86_unary_operator_ok (NOT, QImode, operands)"
10182 [(set_attr "type" "alu1")
10183 (set_attr "mode" "QI")])
10186 [(set (match_operand 0 "flags_reg_operand" "")
10187 (match_operator 2 "compare_operator"
10188 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10190 (set (match_operand:QI 1 "nonimmediate_operand" "")
10191 (not:QI (match_dup 3)))]
10192 "ix86_match_ccmode (insn, CCNOmode)"
10193 [(parallel [(set (match_dup 0)
10194 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10197 (xor:QI (match_dup 3) (const_int -1)))])]
10200 ;; Arithmetic shift instructions
10202 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10203 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10204 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10205 ;; from the assembler input.
10207 ;; This instruction shifts the target reg/mem as usual, but instead of
10208 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10209 ;; is a left shift double, bits are taken from the high order bits of
10210 ;; reg, else if the insn is a shift right double, bits are taken from the
10211 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10212 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10214 ;; Since sh[lr]d does not change the `reg' operand, that is done
10215 ;; separately, making all shifts emit pairs of shift double and normal
10216 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10217 ;; support a 63 bit shift, each shift where the count is in a reg expands
10218 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10220 ;; If the shift count is a constant, we need never emit more than one
10221 ;; shift pair, instead using moves and sign extension for counts greater
10224 (define_expand "ashlti3"
10225 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10226 (ashift:TI (match_operand:TI 1 "register_operand" "")
10227 (match_operand:QI 2 "nonmemory_operand" "")))
10228 (clobber (reg:CC FLAGS_REG))])]
10231 if (! immediate_operand (operands[2], QImode))
10233 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10236 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10240 (define_insn "ashlti3_1"
10241 [(set (match_operand:TI 0 "register_operand" "=r")
10242 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10243 (match_operand:QI 2 "register_operand" "c")))
10244 (clobber (match_scratch:DI 3 "=&r"))
10245 (clobber (reg:CC FLAGS_REG))]
10248 [(set_attr "type" "multi")])
10250 (define_insn "*ashlti3_2"
10251 [(set (match_operand:TI 0 "register_operand" "=r")
10252 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10253 (match_operand:QI 2 "immediate_operand" "O")))
10254 (clobber (reg:CC FLAGS_REG))]
10257 [(set_attr "type" "multi")])
10260 [(set (match_operand:TI 0 "register_operand" "")
10261 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10262 (match_operand:QI 2 "register_operand" "")))
10263 (clobber (match_scratch:DI 3 ""))
10264 (clobber (reg:CC FLAGS_REG))]
10265 "TARGET_64BIT && reload_completed"
10267 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10270 [(set (match_operand:TI 0 "register_operand" "")
10271 (ashift:TI (match_operand:TI 1 "register_operand" "")
10272 (match_operand:QI 2 "immediate_operand" "")))
10273 (clobber (reg:CC FLAGS_REG))]
10274 "TARGET_64BIT && reload_completed"
10276 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10278 (define_insn "x86_64_shld"
10279 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10280 (ior:DI (ashift:DI (match_dup 0)
10281 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10282 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10283 (minus:QI (const_int 64) (match_dup 2)))))
10284 (clobber (reg:CC FLAGS_REG))]
10287 shld{q}\t{%2, %1, %0|%0, %1, %2}
10288 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10289 [(set_attr "type" "ishift")
10290 (set_attr "prefix_0f" "1")
10291 (set_attr "mode" "DI")
10292 (set_attr "athlon_decode" "vector")])
10294 (define_expand "x86_64_shift_adj"
10295 [(set (reg:CCZ FLAGS_REG)
10296 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10299 (set (match_operand:DI 0 "register_operand" "")
10300 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10301 (match_operand:DI 1 "register_operand" "")
10304 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10305 (match_operand:DI 3 "register_operand" "r")
10310 (define_expand "ashldi3"
10311 [(set (match_operand:DI 0 "shiftdi_operand" "")
10312 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10313 (match_operand:QI 2 "nonmemory_operand" "")))]
10315 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10317 (define_insn "*ashldi3_1_rex64"
10318 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10319 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10320 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10321 (clobber (reg:CC FLAGS_REG))]
10322 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10324 switch (get_attr_type (insn))
10327 gcc_assert (operands[2] == const1_rtx);
10328 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10329 return "add{q}\t{%0, %0|%0, %0}";
10332 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10333 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10334 operands[1] = gen_rtx_MULT (DImode, operands[1],
10335 GEN_INT (1 << INTVAL (operands[2])));
10336 return "lea{q}\t{%a1, %0|%0, %a1}";
10339 if (REG_P (operands[2]))
10340 return "sal{q}\t{%b2, %0|%0, %b2}";
10341 else if (operands[2] == const1_rtx
10342 && (TARGET_SHIFT1 || optimize_size))
10343 return "sal{q}\t%0";
10345 return "sal{q}\t{%2, %0|%0, %2}";
10348 [(set (attr "type")
10349 (cond [(eq_attr "alternative" "1")
10350 (const_string "lea")
10351 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10353 (match_operand 0 "register_operand" ""))
10354 (match_operand 2 "const1_operand" ""))
10355 (const_string "alu")
10357 (const_string "ishift")))
10358 (set_attr "mode" "DI")])
10360 ;; Convert lea to the lea pattern to avoid flags dependency.
10362 [(set (match_operand:DI 0 "register_operand" "")
10363 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10364 (match_operand:QI 2 "immediate_operand" "")))
10365 (clobber (reg:CC FLAGS_REG))]
10366 "TARGET_64BIT && reload_completed
10367 && true_regnum (operands[0]) != true_regnum (operands[1])"
10368 [(set (match_dup 0)
10369 (mult:DI (match_dup 1)
10371 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10373 ;; This pattern can't accept a variable shift count, since shifts by
10374 ;; zero don't affect the flags. We assume that shifts by constant
10375 ;; zero are optimized away.
10376 (define_insn "*ashldi3_cmp_rex64"
10377 [(set (reg FLAGS_REG)
10379 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10380 (match_operand:QI 2 "immediate_operand" "e"))
10382 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10383 (ashift:DI (match_dup 1) (match_dup 2)))]
10384 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10385 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10387 || !TARGET_PARTIAL_FLAG_REG_STALL
10388 || (operands[2] == const1_rtx
10390 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10392 switch (get_attr_type (insn))
10395 gcc_assert (operands[2] == const1_rtx);
10396 return "add{q}\t{%0, %0|%0, %0}";
10399 if (REG_P (operands[2]))
10400 return "sal{q}\t{%b2, %0|%0, %b2}";
10401 else if (operands[2] == const1_rtx
10402 && (TARGET_SHIFT1 || optimize_size))
10403 return "sal{q}\t%0";
10405 return "sal{q}\t{%2, %0|%0, %2}";
10408 [(set (attr "type")
10409 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10411 (match_operand 0 "register_operand" ""))
10412 (match_operand 2 "const1_operand" ""))
10413 (const_string "alu")
10415 (const_string "ishift")))
10416 (set_attr "mode" "DI")])
10418 (define_insn "*ashldi3_cconly_rex64"
10419 [(set (reg FLAGS_REG)
10421 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10422 (match_operand:QI 2 "immediate_operand" "e"))
10424 (clobber (match_scratch:DI 0 "=r"))]
10425 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10426 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10428 || !TARGET_PARTIAL_FLAG_REG_STALL
10429 || (operands[2] == const1_rtx
10431 || TARGET_DOUBLE_WITH_ADD)))"
10433 switch (get_attr_type (insn))
10436 gcc_assert (operands[2] == const1_rtx);
10437 return "add{q}\t{%0, %0|%0, %0}";
10440 if (REG_P (operands[2]))
10441 return "sal{q}\t{%b2, %0|%0, %b2}";
10442 else if (operands[2] == const1_rtx
10443 && (TARGET_SHIFT1 || optimize_size))
10444 return "sal{q}\t%0";
10446 return "sal{q}\t{%2, %0|%0, %2}";
10449 [(set (attr "type")
10450 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10452 (match_operand 0 "register_operand" ""))
10453 (match_operand 2 "const1_operand" ""))
10454 (const_string "alu")
10456 (const_string "ishift")))
10457 (set_attr "mode" "DI")])
10459 (define_insn "*ashldi3_1"
10460 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10461 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10462 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10463 (clobber (reg:CC FLAGS_REG))]
10466 [(set_attr "type" "multi")])
10468 ;; By default we don't ask for a scratch register, because when DImode
10469 ;; values are manipulated, registers are already at a premium. But if
10470 ;; we have one handy, we won't turn it away.
10472 [(match_scratch:SI 3 "r")
10473 (parallel [(set (match_operand:DI 0 "register_operand" "")
10474 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10475 (match_operand:QI 2 "nonmemory_operand" "")))
10476 (clobber (reg:CC FLAGS_REG))])
10478 "!TARGET_64BIT && TARGET_CMOVE"
10480 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10483 [(set (match_operand:DI 0 "register_operand" "")
10484 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10485 (match_operand:QI 2 "nonmemory_operand" "")))
10486 (clobber (reg:CC FLAGS_REG))]
10487 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10488 ? flow2_completed : reload_completed)"
10490 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10492 (define_insn "x86_shld_1"
10493 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10494 (ior:SI (ashift:SI (match_dup 0)
10495 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10496 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10497 (minus:QI (const_int 32) (match_dup 2)))))
10498 (clobber (reg:CC FLAGS_REG))]
10501 shld{l}\t{%2, %1, %0|%0, %1, %2}
10502 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10503 [(set_attr "type" "ishift")
10504 (set_attr "prefix_0f" "1")
10505 (set_attr "mode" "SI")
10506 (set_attr "pent_pair" "np")
10507 (set_attr "athlon_decode" "vector")])
10509 (define_expand "x86_shift_adj_1"
10510 [(set (reg:CCZ FLAGS_REG)
10511 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10514 (set (match_operand:SI 0 "register_operand" "")
10515 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10516 (match_operand:SI 1 "register_operand" "")
10519 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10520 (match_operand:SI 3 "register_operand" "r")
10525 (define_expand "x86_shift_adj_2"
10526 [(use (match_operand:SI 0 "register_operand" ""))
10527 (use (match_operand:SI 1 "register_operand" ""))
10528 (use (match_operand:QI 2 "register_operand" ""))]
10531 rtx label = gen_label_rtx ();
10534 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10536 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10537 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10538 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10539 gen_rtx_LABEL_REF (VOIDmode, label),
10541 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10542 JUMP_LABEL (tmp) = label;
10544 emit_move_insn (operands[0], operands[1]);
10545 ix86_expand_clear (operands[1]);
10547 emit_label (label);
10548 LABEL_NUSES (label) = 1;
10553 (define_expand "ashlsi3"
10554 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10555 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10556 (match_operand:QI 2 "nonmemory_operand" "")))
10557 (clobber (reg:CC FLAGS_REG))]
10559 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10561 (define_insn "*ashlsi3_1"
10562 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10563 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10564 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10565 (clobber (reg:CC FLAGS_REG))]
10566 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10568 switch (get_attr_type (insn))
10571 gcc_assert (operands[2] == const1_rtx);
10572 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10573 return "add{l}\t{%0, %0|%0, %0}";
10579 if (REG_P (operands[2]))
10580 return "sal{l}\t{%b2, %0|%0, %b2}";
10581 else if (operands[2] == const1_rtx
10582 && (TARGET_SHIFT1 || optimize_size))
10583 return "sal{l}\t%0";
10585 return "sal{l}\t{%2, %0|%0, %2}";
10588 [(set (attr "type")
10589 (cond [(eq_attr "alternative" "1")
10590 (const_string "lea")
10591 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10593 (match_operand 0 "register_operand" ""))
10594 (match_operand 2 "const1_operand" ""))
10595 (const_string "alu")
10597 (const_string "ishift")))
10598 (set_attr "mode" "SI")])
10600 ;; Convert lea to the lea pattern to avoid flags dependency.
10602 [(set (match_operand 0 "register_operand" "")
10603 (ashift (match_operand 1 "index_register_operand" "")
10604 (match_operand:QI 2 "const_int_operand" "")))
10605 (clobber (reg:CC FLAGS_REG))]
10607 && true_regnum (operands[0]) != true_regnum (operands[1])
10608 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10612 enum machine_mode mode = GET_MODE (operands[0]);
10614 if (GET_MODE_SIZE (mode) < 4)
10615 operands[0] = gen_lowpart (SImode, operands[0]);
10617 operands[1] = gen_lowpart (Pmode, operands[1]);
10618 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10620 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10621 if (Pmode != SImode)
10622 pat = gen_rtx_SUBREG (SImode, pat, 0);
10623 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10627 ;; Rare case of shifting RSP is handled by generating move and shift
10629 [(set (match_operand 0 "register_operand" "")
10630 (ashift (match_operand 1 "register_operand" "")
10631 (match_operand:QI 2 "const_int_operand" "")))
10632 (clobber (reg:CC FLAGS_REG))]
10634 && true_regnum (operands[0]) != true_regnum (operands[1])"
10638 emit_move_insn (operands[0], operands[1]);
10639 pat = gen_rtx_SET (VOIDmode, operands[0],
10640 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10641 operands[0], operands[2]));
10642 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10643 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10647 (define_insn "*ashlsi3_1_zext"
10648 [(set (match_operand:DI 0 "register_operand" "=r,r")
10649 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10650 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10651 (clobber (reg:CC FLAGS_REG))]
10652 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10654 switch (get_attr_type (insn))
10657 gcc_assert (operands[2] == const1_rtx);
10658 return "add{l}\t{%k0, %k0|%k0, %k0}";
10664 if (REG_P (operands[2]))
10665 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10666 else if (operands[2] == const1_rtx
10667 && (TARGET_SHIFT1 || optimize_size))
10668 return "sal{l}\t%k0";
10670 return "sal{l}\t{%2, %k0|%k0, %2}";
10673 [(set (attr "type")
10674 (cond [(eq_attr "alternative" "1")
10675 (const_string "lea")
10676 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10678 (match_operand 2 "const1_operand" ""))
10679 (const_string "alu")
10681 (const_string "ishift")))
10682 (set_attr "mode" "SI")])
10684 ;; Convert lea to the lea pattern to avoid flags dependency.
10686 [(set (match_operand:DI 0 "register_operand" "")
10687 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10688 (match_operand:QI 2 "const_int_operand" ""))))
10689 (clobber (reg:CC FLAGS_REG))]
10690 "TARGET_64BIT && reload_completed
10691 && true_regnum (operands[0]) != true_regnum (operands[1])"
10692 [(set (match_dup 0) (zero_extend:DI
10693 (subreg:SI (mult:SI (match_dup 1)
10694 (match_dup 2)) 0)))]
10696 operands[1] = gen_lowpart (Pmode, operands[1]);
10697 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10700 ;; This pattern can't accept a variable shift count, since shifts by
10701 ;; zero don't affect the flags. We assume that shifts by constant
10702 ;; zero are optimized away.
10703 (define_insn "*ashlsi3_cmp"
10704 [(set (reg FLAGS_REG)
10706 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10707 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10709 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10710 (ashift:SI (match_dup 1) (match_dup 2)))]
10711 "ix86_match_ccmode (insn, CCGOCmode)
10712 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10714 || !TARGET_PARTIAL_FLAG_REG_STALL
10715 || (operands[2] == const1_rtx
10717 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10719 switch (get_attr_type (insn))
10722 gcc_assert (operands[2] == const1_rtx);
10723 return "add{l}\t{%0, %0|%0, %0}";
10726 if (REG_P (operands[2]))
10727 return "sal{l}\t{%b2, %0|%0, %b2}";
10728 else if (operands[2] == const1_rtx
10729 && (TARGET_SHIFT1 || optimize_size))
10730 return "sal{l}\t%0";
10732 return "sal{l}\t{%2, %0|%0, %2}";
10735 [(set (attr "type")
10736 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10738 (match_operand 0 "register_operand" ""))
10739 (match_operand 2 "const1_operand" ""))
10740 (const_string "alu")
10742 (const_string "ishift")))
10743 (set_attr "mode" "SI")])
10745 (define_insn "*ashlsi3_cconly"
10746 [(set (reg FLAGS_REG)
10748 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10749 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10751 (clobber (match_scratch:SI 0 "=r"))]
10752 "ix86_match_ccmode (insn, CCGOCmode)
10753 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10755 || !TARGET_PARTIAL_FLAG_REG_STALL
10756 || (operands[2] == const1_rtx
10758 || TARGET_DOUBLE_WITH_ADD)))"
10760 switch (get_attr_type (insn))
10763 gcc_assert (operands[2] == const1_rtx);
10764 return "add{l}\t{%0, %0|%0, %0}";
10767 if (REG_P (operands[2]))
10768 return "sal{l}\t{%b2, %0|%0, %b2}";
10769 else if (operands[2] == const1_rtx
10770 && (TARGET_SHIFT1 || optimize_size))
10771 return "sal{l}\t%0";
10773 return "sal{l}\t{%2, %0|%0, %2}";
10776 [(set (attr "type")
10777 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10779 (match_operand 0 "register_operand" ""))
10780 (match_operand 2 "const1_operand" ""))
10781 (const_string "alu")
10783 (const_string "ishift")))
10784 (set_attr "mode" "SI")])
10786 (define_insn "*ashlsi3_cmp_zext"
10787 [(set (reg FLAGS_REG)
10789 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10790 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10792 (set (match_operand:DI 0 "register_operand" "=r")
10793 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10794 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10795 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10797 || !TARGET_PARTIAL_FLAG_REG_STALL
10798 || (operands[2] == const1_rtx
10800 || TARGET_DOUBLE_WITH_ADD)))"
10802 switch (get_attr_type (insn))
10805 gcc_assert (operands[2] == const1_rtx);
10806 return "add{l}\t{%k0, %k0|%k0, %k0}";
10809 if (REG_P (operands[2]))
10810 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10811 else if (operands[2] == const1_rtx
10812 && (TARGET_SHIFT1 || optimize_size))
10813 return "sal{l}\t%k0";
10815 return "sal{l}\t{%2, %k0|%k0, %2}";
10818 [(set (attr "type")
10819 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10821 (match_operand 2 "const1_operand" ""))
10822 (const_string "alu")
10824 (const_string "ishift")))
10825 (set_attr "mode" "SI")])
10827 (define_expand "ashlhi3"
10828 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10829 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10830 (match_operand:QI 2 "nonmemory_operand" "")))
10831 (clobber (reg:CC FLAGS_REG))]
10832 "TARGET_HIMODE_MATH"
10833 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10835 (define_insn "*ashlhi3_1_lea"
10836 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10837 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10838 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10839 (clobber (reg:CC FLAGS_REG))]
10840 "!TARGET_PARTIAL_REG_STALL
10841 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10843 switch (get_attr_type (insn))
10848 gcc_assert (operands[2] == const1_rtx);
10849 return "add{w}\t{%0, %0|%0, %0}";
10852 if (REG_P (operands[2]))
10853 return "sal{w}\t{%b2, %0|%0, %b2}";
10854 else if (operands[2] == const1_rtx
10855 && (TARGET_SHIFT1 || optimize_size))
10856 return "sal{w}\t%0";
10858 return "sal{w}\t{%2, %0|%0, %2}";
10861 [(set (attr "type")
10862 (cond [(eq_attr "alternative" "1")
10863 (const_string "lea")
10864 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10866 (match_operand 0 "register_operand" ""))
10867 (match_operand 2 "const1_operand" ""))
10868 (const_string "alu")
10870 (const_string "ishift")))
10871 (set_attr "mode" "HI,SI")])
10873 (define_insn "*ashlhi3_1"
10874 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10875 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10876 (match_operand:QI 2 "nonmemory_operand" "cI")))
10877 (clobber (reg:CC FLAGS_REG))]
10878 "TARGET_PARTIAL_REG_STALL
10879 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10881 switch (get_attr_type (insn))
10884 gcc_assert (operands[2] == const1_rtx);
10885 return "add{w}\t{%0, %0|%0, %0}";
10888 if (REG_P (operands[2]))
10889 return "sal{w}\t{%b2, %0|%0, %b2}";
10890 else if (operands[2] == const1_rtx
10891 && (TARGET_SHIFT1 || optimize_size))
10892 return "sal{w}\t%0";
10894 return "sal{w}\t{%2, %0|%0, %2}";
10897 [(set (attr "type")
10898 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10900 (match_operand 0 "register_operand" ""))
10901 (match_operand 2 "const1_operand" ""))
10902 (const_string "alu")
10904 (const_string "ishift")))
10905 (set_attr "mode" "HI")])
10907 ;; This pattern can't accept a variable shift count, since shifts by
10908 ;; zero don't affect the flags. We assume that shifts by constant
10909 ;; zero are optimized away.
10910 (define_insn "*ashlhi3_cmp"
10911 [(set (reg FLAGS_REG)
10913 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10914 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10916 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10917 (ashift:HI (match_dup 1) (match_dup 2)))]
10918 "ix86_match_ccmode (insn, CCGOCmode)
10919 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10921 || !TARGET_PARTIAL_FLAG_REG_STALL
10922 || (operands[2] == const1_rtx
10924 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10926 switch (get_attr_type (insn))
10929 gcc_assert (operands[2] == const1_rtx);
10930 return "add{w}\t{%0, %0|%0, %0}";
10933 if (REG_P (operands[2]))
10934 return "sal{w}\t{%b2, %0|%0, %b2}";
10935 else if (operands[2] == const1_rtx
10936 && (TARGET_SHIFT1 || optimize_size))
10937 return "sal{w}\t%0";
10939 return "sal{w}\t{%2, %0|%0, %2}";
10942 [(set (attr "type")
10943 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10945 (match_operand 0 "register_operand" ""))
10946 (match_operand 2 "const1_operand" ""))
10947 (const_string "alu")
10949 (const_string "ishift")))
10950 (set_attr "mode" "HI")])
10952 (define_insn "*ashlhi3_cconly"
10953 [(set (reg FLAGS_REG)
10955 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10956 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10958 (clobber (match_scratch:HI 0 "=r"))]
10959 "ix86_match_ccmode (insn, CCGOCmode)
10960 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10962 || !TARGET_PARTIAL_FLAG_REG_STALL
10963 || (operands[2] == const1_rtx
10965 || TARGET_DOUBLE_WITH_ADD)))"
10967 switch (get_attr_type (insn))
10970 gcc_assert (operands[2] == const1_rtx);
10971 return "add{w}\t{%0, %0|%0, %0}";
10974 if (REG_P (operands[2]))
10975 return "sal{w}\t{%b2, %0|%0, %b2}";
10976 else if (operands[2] == const1_rtx
10977 && (TARGET_SHIFT1 || optimize_size))
10978 return "sal{w}\t%0";
10980 return "sal{w}\t{%2, %0|%0, %2}";
10983 [(set (attr "type")
10984 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10986 (match_operand 0 "register_operand" ""))
10987 (match_operand 2 "const1_operand" ""))
10988 (const_string "alu")
10990 (const_string "ishift")))
10991 (set_attr "mode" "HI")])
10993 (define_expand "ashlqi3"
10994 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10995 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10996 (match_operand:QI 2 "nonmemory_operand" "")))
10997 (clobber (reg:CC FLAGS_REG))]
10998 "TARGET_QIMODE_MATH"
10999 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11001 ;; %%% Potential partial reg stall on alternative 2. What to do?
11003 (define_insn "*ashlqi3_1_lea"
11004 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11005 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11006 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11007 (clobber (reg:CC FLAGS_REG))]
11008 "!TARGET_PARTIAL_REG_STALL
11009 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11011 switch (get_attr_type (insn))
11016 gcc_assert (operands[2] == const1_rtx);
11017 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11018 return "add{l}\t{%k0, %k0|%k0, %k0}";
11020 return "add{b}\t{%0, %0|%0, %0}";
11023 if (REG_P (operands[2]))
11025 if (get_attr_mode (insn) == MODE_SI)
11026 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11028 return "sal{b}\t{%b2, %0|%0, %b2}";
11030 else if (operands[2] == const1_rtx
11031 && (TARGET_SHIFT1 || optimize_size))
11033 if (get_attr_mode (insn) == MODE_SI)
11034 return "sal{l}\t%0";
11036 return "sal{b}\t%0";
11040 if (get_attr_mode (insn) == MODE_SI)
11041 return "sal{l}\t{%2, %k0|%k0, %2}";
11043 return "sal{b}\t{%2, %0|%0, %2}";
11047 [(set (attr "type")
11048 (cond [(eq_attr "alternative" "2")
11049 (const_string "lea")
11050 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11052 (match_operand 0 "register_operand" ""))
11053 (match_operand 2 "const1_operand" ""))
11054 (const_string "alu")
11056 (const_string "ishift")))
11057 (set_attr "mode" "QI,SI,SI")])
11059 (define_insn "*ashlqi3_1"
11060 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11061 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11062 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11063 (clobber (reg:CC FLAGS_REG))]
11064 "TARGET_PARTIAL_REG_STALL
11065 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11067 switch (get_attr_type (insn))
11070 gcc_assert (operands[2] == const1_rtx);
11071 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11072 return "add{l}\t{%k0, %k0|%k0, %k0}";
11074 return "add{b}\t{%0, %0|%0, %0}";
11077 if (REG_P (operands[2]))
11079 if (get_attr_mode (insn) == MODE_SI)
11080 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11082 return "sal{b}\t{%b2, %0|%0, %b2}";
11084 else if (operands[2] == const1_rtx
11085 && (TARGET_SHIFT1 || optimize_size))
11087 if (get_attr_mode (insn) == MODE_SI)
11088 return "sal{l}\t%0";
11090 return "sal{b}\t%0";
11094 if (get_attr_mode (insn) == MODE_SI)
11095 return "sal{l}\t{%2, %k0|%k0, %2}";
11097 return "sal{b}\t{%2, %0|%0, %2}";
11101 [(set (attr "type")
11102 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11104 (match_operand 0 "register_operand" ""))
11105 (match_operand 2 "const1_operand" ""))
11106 (const_string "alu")
11108 (const_string "ishift")))
11109 (set_attr "mode" "QI,SI")])
11111 ;; This pattern can't accept a variable shift count, since shifts by
11112 ;; zero don't affect the flags. We assume that shifts by constant
11113 ;; zero are optimized away.
11114 (define_insn "*ashlqi3_cmp"
11115 [(set (reg FLAGS_REG)
11117 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11118 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11120 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11121 (ashift:QI (match_dup 1) (match_dup 2)))]
11122 "ix86_match_ccmode (insn, CCGOCmode)
11123 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11125 || !TARGET_PARTIAL_FLAG_REG_STALL
11126 || (operands[2] == const1_rtx
11128 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11130 switch (get_attr_type (insn))
11133 gcc_assert (operands[2] == const1_rtx);
11134 return "add{b}\t{%0, %0|%0, %0}";
11137 if (REG_P (operands[2]))
11138 return "sal{b}\t{%b2, %0|%0, %b2}";
11139 else if (operands[2] == const1_rtx
11140 && (TARGET_SHIFT1 || optimize_size))
11141 return "sal{b}\t%0";
11143 return "sal{b}\t{%2, %0|%0, %2}";
11146 [(set (attr "type")
11147 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11149 (match_operand 0 "register_operand" ""))
11150 (match_operand 2 "const1_operand" ""))
11151 (const_string "alu")
11153 (const_string "ishift")))
11154 (set_attr "mode" "QI")])
11156 (define_insn "*ashlqi3_cconly"
11157 [(set (reg FLAGS_REG)
11159 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11160 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11162 (clobber (match_scratch:QI 0 "=q"))]
11163 "ix86_match_ccmode (insn, CCGOCmode)
11164 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11166 || !TARGET_PARTIAL_FLAG_REG_STALL
11167 || (operands[2] == const1_rtx
11169 || TARGET_DOUBLE_WITH_ADD)))"
11171 switch (get_attr_type (insn))
11174 gcc_assert (operands[2] == const1_rtx);
11175 return "add{b}\t{%0, %0|%0, %0}";
11178 if (REG_P (operands[2]))
11179 return "sal{b}\t{%b2, %0|%0, %b2}";
11180 else if (operands[2] == const1_rtx
11181 && (TARGET_SHIFT1 || optimize_size))
11182 return "sal{b}\t%0";
11184 return "sal{b}\t{%2, %0|%0, %2}";
11187 [(set (attr "type")
11188 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11190 (match_operand 0 "register_operand" ""))
11191 (match_operand 2 "const1_operand" ""))
11192 (const_string "alu")
11194 (const_string "ishift")))
11195 (set_attr "mode" "QI")])
11197 ;; See comment above `ashldi3' about how this works.
11199 (define_expand "ashrti3"
11200 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11201 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11202 (match_operand:QI 2 "nonmemory_operand" "")))
11203 (clobber (reg:CC FLAGS_REG))])]
11206 if (! immediate_operand (operands[2], QImode))
11208 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11211 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11215 (define_insn "ashrti3_1"
11216 [(set (match_operand:TI 0 "register_operand" "=r")
11217 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11218 (match_operand:QI 2 "register_operand" "c")))
11219 (clobber (match_scratch:DI 3 "=&r"))
11220 (clobber (reg:CC FLAGS_REG))]
11223 [(set_attr "type" "multi")])
11225 (define_insn "*ashrti3_2"
11226 [(set (match_operand:TI 0 "register_operand" "=r")
11227 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11228 (match_operand:QI 2 "immediate_operand" "O")))
11229 (clobber (reg:CC FLAGS_REG))]
11232 [(set_attr "type" "multi")])
11235 [(set (match_operand:TI 0 "register_operand" "")
11236 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11237 (match_operand:QI 2 "register_operand" "")))
11238 (clobber (match_scratch:DI 3 ""))
11239 (clobber (reg:CC FLAGS_REG))]
11240 "TARGET_64BIT && reload_completed"
11242 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11245 [(set (match_operand:TI 0 "register_operand" "")
11246 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11247 (match_operand:QI 2 "immediate_operand" "")))
11248 (clobber (reg:CC FLAGS_REG))]
11249 "TARGET_64BIT && reload_completed"
11251 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11253 (define_insn "x86_64_shrd"
11254 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11255 (ior:DI (ashiftrt:DI (match_dup 0)
11256 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11257 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11258 (minus:QI (const_int 64) (match_dup 2)))))
11259 (clobber (reg:CC FLAGS_REG))]
11262 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11263 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11264 [(set_attr "type" "ishift")
11265 (set_attr "prefix_0f" "1")
11266 (set_attr "mode" "DI")
11267 (set_attr "athlon_decode" "vector")])
11269 (define_expand "ashrdi3"
11270 [(set (match_operand:DI 0 "shiftdi_operand" "")
11271 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11272 (match_operand:QI 2 "nonmemory_operand" "")))]
11274 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11276 (define_insn "*ashrdi3_63_rex64"
11277 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11278 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11279 (match_operand:DI 2 "const_int_operand" "i,i")))
11280 (clobber (reg:CC FLAGS_REG))]
11281 "TARGET_64BIT && INTVAL (operands[2]) == 63
11282 && (TARGET_USE_CLTD || optimize_size)
11283 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11286 sar{q}\t{%2, %0|%0, %2}"
11287 [(set_attr "type" "imovx,ishift")
11288 (set_attr "prefix_0f" "0,*")
11289 (set_attr "length_immediate" "0,*")
11290 (set_attr "modrm" "0,1")
11291 (set_attr "mode" "DI")])
11293 (define_insn "*ashrdi3_1_one_bit_rex64"
11294 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11295 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11296 (match_operand:QI 2 "const1_operand" "")))
11297 (clobber (reg:CC FLAGS_REG))]
11298 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11299 && (TARGET_SHIFT1 || optimize_size)"
11301 [(set_attr "type" "ishift")
11302 (set (attr "length")
11303 (if_then_else (match_operand:DI 0 "register_operand" "")
11305 (const_string "*")))])
11307 (define_insn "*ashrdi3_1_rex64"
11308 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11309 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11310 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11311 (clobber (reg:CC FLAGS_REG))]
11312 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11314 sar{q}\t{%2, %0|%0, %2}
11315 sar{q}\t{%b2, %0|%0, %b2}"
11316 [(set_attr "type" "ishift")
11317 (set_attr "mode" "DI")])
11319 ;; This pattern can't accept a variable shift count, since shifts by
11320 ;; zero don't affect the flags. We assume that shifts by constant
11321 ;; zero are optimized away.
11322 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11323 [(set (reg FLAGS_REG)
11325 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11326 (match_operand:QI 2 "const1_operand" ""))
11328 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11329 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11330 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11331 && (TARGET_SHIFT1 || optimize_size)
11332 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11334 [(set_attr "type" "ishift")
11335 (set (attr "length")
11336 (if_then_else (match_operand:DI 0 "register_operand" "")
11338 (const_string "*")))])
11340 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11341 [(set (reg FLAGS_REG)
11343 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11344 (match_operand:QI 2 "const1_operand" ""))
11346 (clobber (match_scratch:DI 0 "=r"))]
11347 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11348 && (TARGET_SHIFT1 || optimize_size)
11349 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11351 [(set_attr "type" "ishift")
11352 (set_attr "length" "2")])
11354 ;; This pattern can't accept a variable shift count, since shifts by
11355 ;; zero don't affect the flags. We assume that shifts by constant
11356 ;; zero are optimized away.
11357 (define_insn "*ashrdi3_cmp_rex64"
11358 [(set (reg FLAGS_REG)
11360 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11361 (match_operand:QI 2 "const_int_operand" "n"))
11363 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11364 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11365 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11366 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11368 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11369 "sar{q}\t{%2, %0|%0, %2}"
11370 [(set_attr "type" "ishift")
11371 (set_attr "mode" "DI")])
11373 (define_insn "*ashrdi3_cconly_rex64"
11374 [(set (reg FLAGS_REG)
11376 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11377 (match_operand:QI 2 "const_int_operand" "n"))
11379 (clobber (match_scratch:DI 0 "=r"))]
11380 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11381 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11383 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11384 "sar{q}\t{%2, %0|%0, %2}"
11385 [(set_attr "type" "ishift")
11386 (set_attr "mode" "DI")])
11388 (define_insn "*ashrdi3_1"
11389 [(set (match_operand:DI 0 "register_operand" "=r")
11390 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11391 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11392 (clobber (reg:CC FLAGS_REG))]
11395 [(set_attr "type" "multi")])
11397 ;; By default we don't ask for a scratch register, because when DImode
11398 ;; values are manipulated, registers are already at a premium. But if
11399 ;; we have one handy, we won't turn it away.
11401 [(match_scratch:SI 3 "r")
11402 (parallel [(set (match_operand:DI 0 "register_operand" "")
11403 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11404 (match_operand:QI 2 "nonmemory_operand" "")))
11405 (clobber (reg:CC FLAGS_REG))])
11407 "!TARGET_64BIT && TARGET_CMOVE"
11409 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11412 [(set (match_operand:DI 0 "register_operand" "")
11413 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11414 (match_operand:QI 2 "nonmemory_operand" "")))
11415 (clobber (reg:CC FLAGS_REG))]
11416 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11417 ? flow2_completed : reload_completed)"
11419 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11421 (define_insn "x86_shrd_1"
11422 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11423 (ior:SI (ashiftrt:SI (match_dup 0)
11424 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11425 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11426 (minus:QI (const_int 32) (match_dup 2)))))
11427 (clobber (reg:CC FLAGS_REG))]
11430 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11431 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11432 [(set_attr "type" "ishift")
11433 (set_attr "prefix_0f" "1")
11434 (set_attr "pent_pair" "np")
11435 (set_attr "mode" "SI")])
11437 (define_expand "x86_shift_adj_3"
11438 [(use (match_operand:SI 0 "register_operand" ""))
11439 (use (match_operand:SI 1 "register_operand" ""))
11440 (use (match_operand:QI 2 "register_operand" ""))]
11443 rtx label = gen_label_rtx ();
11446 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11448 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11449 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11450 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11451 gen_rtx_LABEL_REF (VOIDmode, label),
11453 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11454 JUMP_LABEL (tmp) = label;
11456 emit_move_insn (operands[0], operands[1]);
11457 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11459 emit_label (label);
11460 LABEL_NUSES (label) = 1;
11465 (define_insn "ashrsi3_31"
11466 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11467 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11468 (match_operand:SI 2 "const_int_operand" "i,i")))
11469 (clobber (reg:CC FLAGS_REG))]
11470 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11471 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11474 sar{l}\t{%2, %0|%0, %2}"
11475 [(set_attr "type" "imovx,ishift")
11476 (set_attr "prefix_0f" "0,*")
11477 (set_attr "length_immediate" "0,*")
11478 (set_attr "modrm" "0,1")
11479 (set_attr "mode" "SI")])
11481 (define_insn "*ashrsi3_31_zext"
11482 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11483 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11484 (match_operand:SI 2 "const_int_operand" "i,i"))))
11485 (clobber (reg:CC FLAGS_REG))]
11486 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11487 && INTVAL (operands[2]) == 31
11488 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11491 sar{l}\t{%2, %k0|%k0, %2}"
11492 [(set_attr "type" "imovx,ishift")
11493 (set_attr "prefix_0f" "0,*")
11494 (set_attr "length_immediate" "0,*")
11495 (set_attr "modrm" "0,1")
11496 (set_attr "mode" "SI")])
11498 (define_expand "ashrsi3"
11499 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11500 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11501 (match_operand:QI 2 "nonmemory_operand" "")))
11502 (clobber (reg:CC FLAGS_REG))]
11504 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11506 (define_insn "*ashrsi3_1_one_bit"
11507 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11508 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11509 (match_operand:QI 2 "const1_operand" "")))
11510 (clobber (reg:CC FLAGS_REG))]
11511 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11512 && (TARGET_SHIFT1 || optimize_size)"
11514 [(set_attr "type" "ishift")
11515 (set (attr "length")
11516 (if_then_else (match_operand:SI 0 "register_operand" "")
11518 (const_string "*")))])
11520 (define_insn "*ashrsi3_1_one_bit_zext"
11521 [(set (match_operand:DI 0 "register_operand" "=r")
11522 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11523 (match_operand:QI 2 "const1_operand" ""))))
11524 (clobber (reg:CC FLAGS_REG))]
11525 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11526 && (TARGET_SHIFT1 || optimize_size)"
11528 [(set_attr "type" "ishift")
11529 (set_attr "length" "2")])
11531 (define_insn "*ashrsi3_1"
11532 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11533 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11534 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11535 (clobber (reg:CC FLAGS_REG))]
11536 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11538 sar{l}\t{%2, %0|%0, %2}
11539 sar{l}\t{%b2, %0|%0, %b2}"
11540 [(set_attr "type" "ishift")
11541 (set_attr "mode" "SI")])
11543 (define_insn "*ashrsi3_1_zext"
11544 [(set (match_operand:DI 0 "register_operand" "=r,r")
11545 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11546 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11547 (clobber (reg:CC FLAGS_REG))]
11548 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11550 sar{l}\t{%2, %k0|%k0, %2}
11551 sar{l}\t{%b2, %k0|%k0, %b2}"
11552 [(set_attr "type" "ishift")
11553 (set_attr "mode" "SI")])
11555 ;; This pattern can't accept a variable shift count, since shifts by
11556 ;; zero don't affect the flags. We assume that shifts by constant
11557 ;; zero are optimized away.
11558 (define_insn "*ashrsi3_one_bit_cmp"
11559 [(set (reg FLAGS_REG)
11561 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11562 (match_operand:QI 2 "const1_operand" ""))
11564 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11565 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11566 "ix86_match_ccmode (insn, CCGOCmode)
11567 && (TARGET_SHIFT1 || optimize_size)
11568 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11570 [(set_attr "type" "ishift")
11571 (set (attr "length")
11572 (if_then_else (match_operand:SI 0 "register_operand" "")
11574 (const_string "*")))])
11576 (define_insn "*ashrsi3_one_bit_cconly"
11577 [(set (reg FLAGS_REG)
11579 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11580 (match_operand:QI 2 "const1_operand" ""))
11582 (clobber (match_scratch:SI 0 "=r"))]
11583 "ix86_match_ccmode (insn, CCGOCmode)
11584 && (TARGET_SHIFT1 || optimize_size)
11585 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11587 [(set_attr "type" "ishift")
11588 (set_attr "length" "2")])
11590 (define_insn "*ashrsi3_one_bit_cmp_zext"
11591 [(set (reg FLAGS_REG)
11593 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11594 (match_operand:QI 2 "const1_operand" ""))
11596 (set (match_operand:DI 0 "register_operand" "=r")
11597 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11598 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11599 && (TARGET_SHIFT1 || optimize_size)
11600 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11602 [(set_attr "type" "ishift")
11603 (set_attr "length" "2")])
11605 ;; This pattern can't accept a variable shift count, since shifts by
11606 ;; zero don't affect the flags. We assume that shifts by constant
11607 ;; zero are optimized away.
11608 (define_insn "*ashrsi3_cmp"
11609 [(set (reg FLAGS_REG)
11611 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11612 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11614 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11615 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11616 "ix86_match_ccmode (insn, CCGOCmode)
11617 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11619 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11620 "sar{l}\t{%2, %0|%0, %2}"
11621 [(set_attr "type" "ishift")
11622 (set_attr "mode" "SI")])
11624 (define_insn "*ashrsi3_cconly"
11625 [(set (reg FLAGS_REG)
11627 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11628 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11630 (clobber (match_scratch:SI 0 "=r"))]
11631 "ix86_match_ccmode (insn, CCGOCmode)
11632 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11634 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11635 "sar{l}\t{%2, %0|%0, %2}"
11636 [(set_attr "type" "ishift")
11637 (set_attr "mode" "SI")])
11639 (define_insn "*ashrsi3_cmp_zext"
11640 [(set (reg FLAGS_REG)
11642 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11643 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11645 (set (match_operand:DI 0 "register_operand" "=r")
11646 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11647 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11648 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11650 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11651 "sar{l}\t{%2, %k0|%k0, %2}"
11652 [(set_attr "type" "ishift")
11653 (set_attr "mode" "SI")])
11655 (define_expand "ashrhi3"
11656 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11657 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11658 (match_operand:QI 2 "nonmemory_operand" "")))
11659 (clobber (reg:CC FLAGS_REG))]
11660 "TARGET_HIMODE_MATH"
11661 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11663 (define_insn "*ashrhi3_1_one_bit"
11664 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11665 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11666 (match_operand:QI 2 "const1_operand" "")))
11667 (clobber (reg:CC FLAGS_REG))]
11668 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11669 && (TARGET_SHIFT1 || optimize_size)"
11671 [(set_attr "type" "ishift")
11672 (set (attr "length")
11673 (if_then_else (match_operand 0 "register_operand" "")
11675 (const_string "*")))])
11677 (define_insn "*ashrhi3_1"
11678 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11679 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11680 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11681 (clobber (reg:CC FLAGS_REG))]
11682 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11684 sar{w}\t{%2, %0|%0, %2}
11685 sar{w}\t{%b2, %0|%0, %b2}"
11686 [(set_attr "type" "ishift")
11687 (set_attr "mode" "HI")])
11689 ;; This pattern can't accept a variable shift count, since shifts by
11690 ;; zero don't affect the flags. We assume that shifts by constant
11691 ;; zero are optimized away.
11692 (define_insn "*ashrhi3_one_bit_cmp"
11693 [(set (reg FLAGS_REG)
11695 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11696 (match_operand:QI 2 "const1_operand" ""))
11698 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11699 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11700 "ix86_match_ccmode (insn, CCGOCmode)
11701 && (TARGET_SHIFT1 || optimize_size)
11702 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11704 [(set_attr "type" "ishift")
11705 (set (attr "length")
11706 (if_then_else (match_operand 0 "register_operand" "")
11708 (const_string "*")))])
11710 (define_insn "*ashrhi3_one_bit_cconly"
11711 [(set (reg FLAGS_REG)
11713 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11714 (match_operand:QI 2 "const1_operand" ""))
11716 (clobber (match_scratch:HI 0 "=r"))]
11717 "ix86_match_ccmode (insn, CCGOCmode)
11718 && (TARGET_SHIFT1 || optimize_size)
11719 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11721 [(set_attr "type" "ishift")
11722 (set_attr "length" "2")])
11724 ;; This pattern can't accept a variable shift count, since shifts by
11725 ;; zero don't affect the flags. We assume that shifts by constant
11726 ;; zero are optimized away.
11727 (define_insn "*ashrhi3_cmp"
11728 [(set (reg FLAGS_REG)
11730 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11731 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11733 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11734 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11735 "ix86_match_ccmode (insn, CCGOCmode)
11736 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11738 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11739 "sar{w}\t{%2, %0|%0, %2}"
11740 [(set_attr "type" "ishift")
11741 (set_attr "mode" "HI")])
11743 (define_insn "*ashrhi3_cconly"
11744 [(set (reg FLAGS_REG)
11746 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11747 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11749 (clobber (match_scratch:HI 0 "=r"))]
11750 "ix86_match_ccmode (insn, CCGOCmode)
11751 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11753 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11754 "sar{w}\t{%2, %0|%0, %2}"
11755 [(set_attr "type" "ishift")
11756 (set_attr "mode" "HI")])
11758 (define_expand "ashrqi3"
11759 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11760 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11761 (match_operand:QI 2 "nonmemory_operand" "")))
11762 (clobber (reg:CC FLAGS_REG))]
11763 "TARGET_QIMODE_MATH"
11764 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11766 (define_insn "*ashrqi3_1_one_bit"
11767 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11768 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11769 (match_operand:QI 2 "const1_operand" "")))
11770 (clobber (reg:CC FLAGS_REG))]
11771 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11772 && (TARGET_SHIFT1 || optimize_size)"
11774 [(set_attr "type" "ishift")
11775 (set (attr "length")
11776 (if_then_else (match_operand 0 "register_operand" "")
11778 (const_string "*")))])
11780 (define_insn "*ashrqi3_1_one_bit_slp"
11781 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11782 (ashiftrt:QI (match_dup 0)
11783 (match_operand:QI 1 "const1_operand" "")))
11784 (clobber (reg:CC FLAGS_REG))]
11785 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11786 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11787 && (TARGET_SHIFT1 || optimize_size)"
11789 [(set_attr "type" "ishift1")
11790 (set (attr "length")
11791 (if_then_else (match_operand 0 "register_operand" "")
11793 (const_string "*")))])
11795 (define_insn "*ashrqi3_1"
11796 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11797 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11798 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11799 (clobber (reg:CC FLAGS_REG))]
11800 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11802 sar{b}\t{%2, %0|%0, %2}
11803 sar{b}\t{%b2, %0|%0, %b2}"
11804 [(set_attr "type" "ishift")
11805 (set_attr "mode" "QI")])
11807 (define_insn "*ashrqi3_1_slp"
11808 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11809 (ashiftrt:QI (match_dup 0)
11810 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11811 (clobber (reg:CC FLAGS_REG))]
11812 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11813 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11815 sar{b}\t{%1, %0|%0, %1}
11816 sar{b}\t{%b1, %0|%0, %b1}"
11817 [(set_attr "type" "ishift1")
11818 (set_attr "mode" "QI")])
11820 ;; This pattern can't accept a variable shift count, since shifts by
11821 ;; zero don't affect the flags. We assume that shifts by constant
11822 ;; zero are optimized away.
11823 (define_insn "*ashrqi3_one_bit_cmp"
11824 [(set (reg FLAGS_REG)
11826 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11827 (match_operand:QI 2 "const1_operand" "I"))
11829 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11830 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11831 "ix86_match_ccmode (insn, CCGOCmode)
11832 && (TARGET_SHIFT1 || optimize_size)
11833 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11835 [(set_attr "type" "ishift")
11836 (set (attr "length")
11837 (if_then_else (match_operand 0 "register_operand" "")
11839 (const_string "*")))])
11841 (define_insn "*ashrqi3_one_bit_cconly"
11842 [(set (reg FLAGS_REG)
11844 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11845 (match_operand:QI 2 "const1_operand" "I"))
11847 (clobber (match_scratch:QI 0 "=q"))]
11848 "ix86_match_ccmode (insn, CCGOCmode)
11849 && (TARGET_SHIFT1 || optimize_size)
11850 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11852 [(set_attr "type" "ishift")
11853 (set_attr "length" "2")])
11855 ;; This pattern can't accept a variable shift count, since shifts by
11856 ;; zero don't affect the flags. We assume that shifts by constant
11857 ;; zero are optimized away.
11858 (define_insn "*ashrqi3_cmp"
11859 [(set (reg FLAGS_REG)
11861 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11862 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11864 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11865 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11866 "ix86_match_ccmode (insn, CCGOCmode)
11867 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11869 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11870 "sar{b}\t{%2, %0|%0, %2}"
11871 [(set_attr "type" "ishift")
11872 (set_attr "mode" "QI")])
11874 (define_insn "*ashrqi3_cconly"
11875 [(set (reg FLAGS_REG)
11877 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11878 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11880 (clobber (match_scratch:QI 0 "=q"))]
11881 "ix86_match_ccmode (insn, CCGOCmode)
11882 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11884 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11885 "sar{b}\t{%2, %0|%0, %2}"
11886 [(set_attr "type" "ishift")
11887 (set_attr "mode" "QI")])
11890 ;; Logical shift instructions
11892 ;; See comment above `ashldi3' about how this works.
11894 (define_expand "lshrti3"
11895 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11896 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11897 (match_operand:QI 2 "nonmemory_operand" "")))
11898 (clobber (reg:CC FLAGS_REG))])]
11901 if (! immediate_operand (operands[2], QImode))
11903 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11906 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11910 (define_insn "lshrti3_1"
11911 [(set (match_operand:TI 0 "register_operand" "=r")
11912 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11913 (match_operand:QI 2 "register_operand" "c")))
11914 (clobber (match_scratch:DI 3 "=&r"))
11915 (clobber (reg:CC FLAGS_REG))]
11918 [(set_attr "type" "multi")])
11920 (define_insn "*lshrti3_2"
11921 [(set (match_operand:TI 0 "register_operand" "=r")
11922 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11923 (match_operand:QI 2 "immediate_operand" "O")))
11924 (clobber (reg:CC FLAGS_REG))]
11927 [(set_attr "type" "multi")])
11930 [(set (match_operand:TI 0 "register_operand" "")
11931 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11932 (match_operand:QI 2 "register_operand" "")))
11933 (clobber (match_scratch:DI 3 ""))
11934 (clobber (reg:CC FLAGS_REG))]
11935 "TARGET_64BIT && reload_completed"
11937 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11940 [(set (match_operand:TI 0 "register_operand" "")
11941 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11942 (match_operand:QI 2 "immediate_operand" "")))
11943 (clobber (reg:CC FLAGS_REG))]
11944 "TARGET_64BIT && reload_completed"
11946 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11948 (define_expand "lshrdi3"
11949 [(set (match_operand:DI 0 "shiftdi_operand" "")
11950 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11951 (match_operand:QI 2 "nonmemory_operand" "")))]
11953 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11955 (define_insn "*lshrdi3_1_one_bit_rex64"
11956 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11957 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11958 (match_operand:QI 2 "const1_operand" "")))
11959 (clobber (reg:CC FLAGS_REG))]
11960 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11961 && (TARGET_SHIFT1 || optimize_size)"
11963 [(set_attr "type" "ishift")
11964 (set (attr "length")
11965 (if_then_else (match_operand:DI 0 "register_operand" "")
11967 (const_string "*")))])
11969 (define_insn "*lshrdi3_1_rex64"
11970 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11971 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11972 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11973 (clobber (reg:CC FLAGS_REG))]
11974 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11976 shr{q}\t{%2, %0|%0, %2}
11977 shr{q}\t{%b2, %0|%0, %b2}"
11978 [(set_attr "type" "ishift")
11979 (set_attr "mode" "DI")])
11981 ;; This pattern can't accept a variable shift count, since shifts by
11982 ;; zero don't affect the flags. We assume that shifts by constant
11983 ;; zero are optimized away.
11984 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11985 [(set (reg FLAGS_REG)
11987 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11988 (match_operand:QI 2 "const1_operand" ""))
11990 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11991 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11992 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11993 && (TARGET_SHIFT1 || optimize_size)
11994 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11996 [(set_attr "type" "ishift")
11997 (set (attr "length")
11998 (if_then_else (match_operand:DI 0 "register_operand" "")
12000 (const_string "*")))])
12002 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12003 [(set (reg FLAGS_REG)
12005 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12006 (match_operand:QI 2 "const1_operand" ""))
12008 (clobber (match_scratch:DI 0 "=r"))]
12009 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12010 && (TARGET_SHIFT1 || optimize_size)
12011 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12013 [(set_attr "type" "ishift")
12014 (set_attr "length" "2")])
12016 ;; This pattern can't accept a variable shift count, since shifts by
12017 ;; zero don't affect the flags. We assume that shifts by constant
12018 ;; zero are optimized away.
12019 (define_insn "*lshrdi3_cmp_rex64"
12020 [(set (reg FLAGS_REG)
12022 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12023 (match_operand:QI 2 "const_int_operand" "e"))
12025 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12026 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12027 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12028 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12030 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12031 "shr{q}\t{%2, %0|%0, %2}"
12032 [(set_attr "type" "ishift")
12033 (set_attr "mode" "DI")])
12035 (define_insn "*lshrdi3_cconly_rex64"
12036 [(set (reg FLAGS_REG)
12038 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12039 (match_operand:QI 2 "const_int_operand" "e"))
12041 (clobber (match_scratch:DI 0 "=r"))]
12042 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12043 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12045 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12046 "shr{q}\t{%2, %0|%0, %2}"
12047 [(set_attr "type" "ishift")
12048 (set_attr "mode" "DI")])
12050 (define_insn "*lshrdi3_1"
12051 [(set (match_operand:DI 0 "register_operand" "=r")
12052 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12053 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12054 (clobber (reg:CC FLAGS_REG))]
12057 [(set_attr "type" "multi")])
12059 ;; By default we don't ask for a scratch register, because when DImode
12060 ;; values are manipulated, registers are already at a premium. But if
12061 ;; we have one handy, we won't turn it away.
12063 [(match_scratch:SI 3 "r")
12064 (parallel [(set (match_operand:DI 0 "register_operand" "")
12065 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12066 (match_operand:QI 2 "nonmemory_operand" "")))
12067 (clobber (reg:CC FLAGS_REG))])
12069 "!TARGET_64BIT && TARGET_CMOVE"
12071 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12074 [(set (match_operand:DI 0 "register_operand" "")
12075 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12076 (match_operand:QI 2 "nonmemory_operand" "")))
12077 (clobber (reg:CC FLAGS_REG))]
12078 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12079 ? flow2_completed : reload_completed)"
12081 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12083 (define_expand "lshrsi3"
12084 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12085 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12086 (match_operand:QI 2 "nonmemory_operand" "")))
12087 (clobber (reg:CC FLAGS_REG))]
12089 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12091 (define_insn "*lshrsi3_1_one_bit"
12092 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12093 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12094 (match_operand:QI 2 "const1_operand" "")))
12095 (clobber (reg:CC FLAGS_REG))]
12096 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12097 && (TARGET_SHIFT1 || optimize_size)"
12099 [(set_attr "type" "ishift")
12100 (set (attr "length")
12101 (if_then_else (match_operand:SI 0 "register_operand" "")
12103 (const_string "*")))])
12105 (define_insn "*lshrsi3_1_one_bit_zext"
12106 [(set (match_operand:DI 0 "register_operand" "=r")
12107 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12108 (match_operand:QI 2 "const1_operand" "")))
12109 (clobber (reg:CC FLAGS_REG))]
12110 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12111 && (TARGET_SHIFT1 || optimize_size)"
12113 [(set_attr "type" "ishift")
12114 (set_attr "length" "2")])
12116 (define_insn "*lshrsi3_1"
12117 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12118 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12119 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12120 (clobber (reg:CC FLAGS_REG))]
12121 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12123 shr{l}\t{%2, %0|%0, %2}
12124 shr{l}\t{%b2, %0|%0, %b2}"
12125 [(set_attr "type" "ishift")
12126 (set_attr "mode" "SI")])
12128 (define_insn "*lshrsi3_1_zext"
12129 [(set (match_operand:DI 0 "register_operand" "=r,r")
12131 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12132 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12133 (clobber (reg:CC FLAGS_REG))]
12134 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12136 shr{l}\t{%2, %k0|%k0, %2}
12137 shr{l}\t{%b2, %k0|%k0, %b2}"
12138 [(set_attr "type" "ishift")
12139 (set_attr "mode" "SI")])
12141 ;; This pattern can't accept a variable shift count, since shifts by
12142 ;; zero don't affect the flags. We assume that shifts by constant
12143 ;; zero are optimized away.
12144 (define_insn "*lshrsi3_one_bit_cmp"
12145 [(set (reg FLAGS_REG)
12147 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12148 (match_operand:QI 2 "const1_operand" ""))
12150 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12151 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12152 "ix86_match_ccmode (insn, CCGOCmode)
12153 && (TARGET_SHIFT1 || optimize_size)
12154 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12156 [(set_attr "type" "ishift")
12157 (set (attr "length")
12158 (if_then_else (match_operand:SI 0 "register_operand" "")
12160 (const_string "*")))])
12162 (define_insn "*lshrsi3_one_bit_cconly"
12163 [(set (reg FLAGS_REG)
12165 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12166 (match_operand:QI 2 "const1_operand" ""))
12168 (clobber (match_scratch:SI 0 "=r"))]
12169 "ix86_match_ccmode (insn, CCGOCmode)
12170 && (TARGET_SHIFT1 || optimize_size)
12171 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12173 [(set_attr "type" "ishift")
12174 (set_attr "length" "2")])
12176 (define_insn "*lshrsi3_cmp_one_bit_zext"
12177 [(set (reg FLAGS_REG)
12179 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12180 (match_operand:QI 2 "const1_operand" ""))
12182 (set (match_operand:DI 0 "register_operand" "=r")
12183 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12184 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12185 && (TARGET_SHIFT1 || optimize_size)
12186 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12188 [(set_attr "type" "ishift")
12189 (set_attr "length" "2")])
12191 ;; This pattern can't accept a variable shift count, since shifts by
12192 ;; zero don't affect the flags. We assume that shifts by constant
12193 ;; zero are optimized away.
12194 (define_insn "*lshrsi3_cmp"
12195 [(set (reg FLAGS_REG)
12197 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12198 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12200 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12201 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12202 "ix86_match_ccmode (insn, CCGOCmode)
12203 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12205 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12206 "shr{l}\t{%2, %0|%0, %2}"
12207 [(set_attr "type" "ishift")
12208 (set_attr "mode" "SI")])
12210 (define_insn "*lshrsi3_cconly"
12211 [(set (reg FLAGS_REG)
12213 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12214 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12216 (clobber (match_scratch:SI 0 "=r"))]
12217 "ix86_match_ccmode (insn, CCGOCmode)
12218 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12220 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12221 "shr{l}\t{%2, %0|%0, %2}"
12222 [(set_attr "type" "ishift")
12223 (set_attr "mode" "SI")])
12225 (define_insn "*lshrsi3_cmp_zext"
12226 [(set (reg FLAGS_REG)
12228 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12229 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12231 (set (match_operand:DI 0 "register_operand" "=r")
12232 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12233 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12234 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12236 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12237 "shr{l}\t{%2, %k0|%k0, %2}"
12238 [(set_attr "type" "ishift")
12239 (set_attr "mode" "SI")])
12241 (define_expand "lshrhi3"
12242 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12243 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12244 (match_operand:QI 2 "nonmemory_operand" "")))
12245 (clobber (reg:CC FLAGS_REG))]
12246 "TARGET_HIMODE_MATH"
12247 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12249 (define_insn "*lshrhi3_1_one_bit"
12250 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12251 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12252 (match_operand:QI 2 "const1_operand" "")))
12253 (clobber (reg:CC FLAGS_REG))]
12254 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12255 && (TARGET_SHIFT1 || optimize_size)"
12257 [(set_attr "type" "ishift")
12258 (set (attr "length")
12259 (if_then_else (match_operand 0 "register_operand" "")
12261 (const_string "*")))])
12263 (define_insn "*lshrhi3_1"
12264 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12265 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12266 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12267 (clobber (reg:CC FLAGS_REG))]
12268 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12270 shr{w}\t{%2, %0|%0, %2}
12271 shr{w}\t{%b2, %0|%0, %b2}"
12272 [(set_attr "type" "ishift")
12273 (set_attr "mode" "HI")])
12275 ;; This pattern can't accept a variable shift count, since shifts by
12276 ;; zero don't affect the flags. We assume that shifts by constant
12277 ;; zero are optimized away.
12278 (define_insn "*lshrhi3_one_bit_cmp"
12279 [(set (reg FLAGS_REG)
12281 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12282 (match_operand:QI 2 "const1_operand" ""))
12284 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12285 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12286 "ix86_match_ccmode (insn, CCGOCmode)
12287 && (TARGET_SHIFT1 || optimize_size)
12288 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12290 [(set_attr "type" "ishift")
12291 (set (attr "length")
12292 (if_then_else (match_operand:SI 0 "register_operand" "")
12294 (const_string "*")))])
12296 (define_insn "*lshrhi3_one_bit_cconly"
12297 [(set (reg FLAGS_REG)
12299 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12300 (match_operand:QI 2 "const1_operand" ""))
12302 (clobber (match_scratch:HI 0 "=r"))]
12303 "ix86_match_ccmode (insn, CCGOCmode)
12304 && (TARGET_SHIFT1 || optimize_size)
12305 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12307 [(set_attr "type" "ishift")
12308 (set_attr "length" "2")])
12310 ;; This pattern can't accept a variable shift count, since shifts by
12311 ;; zero don't affect the flags. We assume that shifts by constant
12312 ;; zero are optimized away.
12313 (define_insn "*lshrhi3_cmp"
12314 [(set (reg FLAGS_REG)
12316 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12317 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12319 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12320 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12321 "ix86_match_ccmode (insn, CCGOCmode)
12322 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12324 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12325 "shr{w}\t{%2, %0|%0, %2}"
12326 [(set_attr "type" "ishift")
12327 (set_attr "mode" "HI")])
12329 (define_insn "*lshrhi3_cconly"
12330 [(set (reg FLAGS_REG)
12332 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12333 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12335 (clobber (match_scratch:HI 0 "=r"))]
12336 "ix86_match_ccmode (insn, CCGOCmode)
12337 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12339 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12340 "shr{w}\t{%2, %0|%0, %2}"
12341 [(set_attr "type" "ishift")
12342 (set_attr "mode" "HI")])
12344 (define_expand "lshrqi3"
12345 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12346 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12347 (match_operand:QI 2 "nonmemory_operand" "")))
12348 (clobber (reg:CC FLAGS_REG))]
12349 "TARGET_QIMODE_MATH"
12350 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12352 (define_insn "*lshrqi3_1_one_bit"
12353 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12354 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12355 (match_operand:QI 2 "const1_operand" "")))
12356 (clobber (reg:CC FLAGS_REG))]
12357 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12358 && (TARGET_SHIFT1 || optimize_size)"
12360 [(set_attr "type" "ishift")
12361 (set (attr "length")
12362 (if_then_else (match_operand 0 "register_operand" "")
12364 (const_string "*")))])
12366 (define_insn "*lshrqi3_1_one_bit_slp"
12367 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12368 (lshiftrt:QI (match_dup 0)
12369 (match_operand:QI 1 "const1_operand" "")))
12370 (clobber (reg:CC FLAGS_REG))]
12371 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12372 && (TARGET_SHIFT1 || optimize_size)"
12374 [(set_attr "type" "ishift1")
12375 (set (attr "length")
12376 (if_then_else (match_operand 0 "register_operand" "")
12378 (const_string "*")))])
12380 (define_insn "*lshrqi3_1"
12381 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12382 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12383 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12384 (clobber (reg:CC FLAGS_REG))]
12385 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12387 shr{b}\t{%2, %0|%0, %2}
12388 shr{b}\t{%b2, %0|%0, %b2}"
12389 [(set_attr "type" "ishift")
12390 (set_attr "mode" "QI")])
12392 (define_insn "*lshrqi3_1_slp"
12393 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12394 (lshiftrt:QI (match_dup 0)
12395 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12396 (clobber (reg:CC FLAGS_REG))]
12397 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12398 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12400 shr{b}\t{%1, %0|%0, %1}
12401 shr{b}\t{%b1, %0|%0, %b1}"
12402 [(set_attr "type" "ishift1")
12403 (set_attr "mode" "QI")])
12405 ;; This pattern can't accept a variable shift count, since shifts by
12406 ;; zero don't affect the flags. We assume that shifts by constant
12407 ;; zero are optimized away.
12408 (define_insn "*lshrqi2_one_bit_cmp"
12409 [(set (reg FLAGS_REG)
12411 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12412 (match_operand:QI 2 "const1_operand" ""))
12414 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12415 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12416 "ix86_match_ccmode (insn, CCGOCmode)
12417 && (TARGET_SHIFT1 || optimize_size)
12418 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12420 [(set_attr "type" "ishift")
12421 (set (attr "length")
12422 (if_then_else (match_operand:SI 0 "register_operand" "")
12424 (const_string "*")))])
12426 (define_insn "*lshrqi2_one_bit_cconly"
12427 [(set (reg FLAGS_REG)
12429 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12430 (match_operand:QI 2 "const1_operand" ""))
12432 (clobber (match_scratch:QI 0 "=q"))]
12433 "ix86_match_ccmode (insn, CCGOCmode)
12434 && (TARGET_SHIFT1 || optimize_size)
12435 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12437 [(set_attr "type" "ishift")
12438 (set_attr "length" "2")])
12440 ;; This pattern can't accept a variable shift count, since shifts by
12441 ;; zero don't affect the flags. We assume that shifts by constant
12442 ;; zero are optimized away.
12443 (define_insn "*lshrqi2_cmp"
12444 [(set (reg FLAGS_REG)
12446 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12447 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12449 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12450 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12451 "ix86_match_ccmode (insn, CCGOCmode)
12452 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12454 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12455 "shr{b}\t{%2, %0|%0, %2}"
12456 [(set_attr "type" "ishift")
12457 (set_attr "mode" "QI")])
12459 (define_insn "*lshrqi2_cconly"
12460 [(set (reg FLAGS_REG)
12462 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12463 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12465 (clobber (match_scratch:QI 0 "=q"))]
12466 "ix86_match_ccmode (insn, CCGOCmode)
12467 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12469 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12470 "shr{b}\t{%2, %0|%0, %2}"
12471 [(set_attr "type" "ishift")
12472 (set_attr "mode" "QI")])
12474 ;; Rotate instructions
12476 (define_expand "rotldi3"
12477 [(set (match_operand:DI 0 "shiftdi_operand" "")
12478 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12479 (match_operand:QI 2 "nonmemory_operand" "")))
12480 (clobber (reg:CC FLAGS_REG))]
12485 ix86_expand_binary_operator (ROTATE, DImode, operands);
12488 if (!const_1_to_31_operand (operands[2], VOIDmode))
12490 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12494 ;; Implement rotation using two double-precision shift instructions
12495 ;; and a scratch register.
12496 (define_insn_and_split "ix86_rotldi3"
12497 [(set (match_operand:DI 0 "register_operand" "=r")
12498 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12499 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12500 (clobber (reg:CC FLAGS_REG))
12501 (clobber (match_scratch:SI 3 "=&r"))]
12504 "&& reload_completed"
12505 [(set (match_dup 3) (match_dup 4))
12507 [(set (match_dup 4)
12508 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12509 (lshiftrt:SI (match_dup 5)
12510 (minus:QI (const_int 32) (match_dup 2)))))
12511 (clobber (reg:CC FLAGS_REG))])
12513 [(set (match_dup 5)
12514 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12515 (lshiftrt:SI (match_dup 3)
12516 (minus:QI (const_int 32) (match_dup 2)))))
12517 (clobber (reg:CC FLAGS_REG))])]
12518 "split_di (operands, 1, operands + 4, operands + 5);")
12520 (define_insn "*rotlsi3_1_one_bit_rex64"
12521 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12522 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12523 (match_operand:QI 2 "const1_operand" "")))
12524 (clobber (reg:CC FLAGS_REG))]
12525 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12526 && (TARGET_SHIFT1 || optimize_size)"
12528 [(set_attr "type" "rotate")
12529 (set (attr "length")
12530 (if_then_else (match_operand:DI 0 "register_operand" "")
12532 (const_string "*")))])
12534 (define_insn "*rotldi3_1_rex64"
12535 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12536 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12537 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12538 (clobber (reg:CC FLAGS_REG))]
12539 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12541 rol{q}\t{%2, %0|%0, %2}
12542 rol{q}\t{%b2, %0|%0, %b2}"
12543 [(set_attr "type" "rotate")
12544 (set_attr "mode" "DI")])
12546 (define_expand "rotlsi3"
12547 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12548 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12549 (match_operand:QI 2 "nonmemory_operand" "")))
12550 (clobber (reg:CC FLAGS_REG))]
12552 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12554 (define_insn "*rotlsi3_1_one_bit"
12555 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12556 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12557 (match_operand:QI 2 "const1_operand" "")))
12558 (clobber (reg:CC FLAGS_REG))]
12559 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12560 && (TARGET_SHIFT1 || optimize_size)"
12562 [(set_attr "type" "rotate")
12563 (set (attr "length")
12564 (if_then_else (match_operand:SI 0 "register_operand" "")
12566 (const_string "*")))])
12568 (define_insn "*rotlsi3_1_one_bit_zext"
12569 [(set (match_operand:DI 0 "register_operand" "=r")
12571 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12572 (match_operand:QI 2 "const1_operand" ""))))
12573 (clobber (reg:CC FLAGS_REG))]
12574 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12575 && (TARGET_SHIFT1 || optimize_size)"
12577 [(set_attr "type" "rotate")
12578 (set_attr "length" "2")])
12580 (define_insn "*rotlsi3_1"
12581 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12582 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12583 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12584 (clobber (reg:CC FLAGS_REG))]
12585 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12587 rol{l}\t{%2, %0|%0, %2}
12588 rol{l}\t{%b2, %0|%0, %b2}"
12589 [(set_attr "type" "rotate")
12590 (set_attr "mode" "SI")])
12592 (define_insn "*rotlsi3_1_zext"
12593 [(set (match_operand:DI 0 "register_operand" "=r,r")
12595 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12596 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12597 (clobber (reg:CC FLAGS_REG))]
12598 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12600 rol{l}\t{%2, %k0|%k0, %2}
12601 rol{l}\t{%b2, %k0|%k0, %b2}"
12602 [(set_attr "type" "rotate")
12603 (set_attr "mode" "SI")])
12605 (define_expand "rotlhi3"
12606 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12607 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12608 (match_operand:QI 2 "nonmemory_operand" "")))
12609 (clobber (reg:CC FLAGS_REG))]
12610 "TARGET_HIMODE_MATH"
12611 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12613 (define_insn "*rotlhi3_1_one_bit"
12614 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12615 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12616 (match_operand:QI 2 "const1_operand" "")))
12617 (clobber (reg:CC FLAGS_REG))]
12618 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12619 && (TARGET_SHIFT1 || optimize_size)"
12621 [(set_attr "type" "rotate")
12622 (set (attr "length")
12623 (if_then_else (match_operand 0 "register_operand" "")
12625 (const_string "*")))])
12627 (define_insn "*rotlhi3_1"
12628 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12629 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12630 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12631 (clobber (reg:CC FLAGS_REG))]
12632 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12634 rol{w}\t{%2, %0|%0, %2}
12635 rol{w}\t{%b2, %0|%0, %b2}"
12636 [(set_attr "type" "rotate")
12637 (set_attr "mode" "HI")])
12639 (define_expand "rotlqi3"
12640 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12641 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12642 (match_operand:QI 2 "nonmemory_operand" "")))
12643 (clobber (reg:CC FLAGS_REG))]
12644 "TARGET_QIMODE_MATH"
12645 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12647 (define_insn "*rotlqi3_1_one_bit_slp"
12648 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12649 (rotate:QI (match_dup 0)
12650 (match_operand:QI 1 "const1_operand" "")))
12651 (clobber (reg:CC FLAGS_REG))]
12652 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12653 && (TARGET_SHIFT1 || optimize_size)"
12655 [(set_attr "type" "rotate1")
12656 (set (attr "length")
12657 (if_then_else (match_operand 0 "register_operand" "")
12659 (const_string "*")))])
12661 (define_insn "*rotlqi3_1_one_bit"
12662 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12663 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12664 (match_operand:QI 2 "const1_operand" "")))
12665 (clobber (reg:CC FLAGS_REG))]
12666 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12667 && (TARGET_SHIFT1 || optimize_size)"
12669 [(set_attr "type" "rotate")
12670 (set (attr "length")
12671 (if_then_else (match_operand 0 "register_operand" "")
12673 (const_string "*")))])
12675 (define_insn "*rotlqi3_1_slp"
12676 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12677 (rotate:QI (match_dup 0)
12678 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12679 (clobber (reg:CC FLAGS_REG))]
12680 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12681 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12683 rol{b}\t{%1, %0|%0, %1}
12684 rol{b}\t{%b1, %0|%0, %b1}"
12685 [(set_attr "type" "rotate1")
12686 (set_attr "mode" "QI")])
12688 (define_insn "*rotlqi3_1"
12689 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12690 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12691 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12692 (clobber (reg:CC FLAGS_REG))]
12693 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12695 rol{b}\t{%2, %0|%0, %2}
12696 rol{b}\t{%b2, %0|%0, %b2}"
12697 [(set_attr "type" "rotate")
12698 (set_attr "mode" "QI")])
12700 (define_expand "rotrdi3"
12701 [(set (match_operand:DI 0 "shiftdi_operand" "")
12702 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12703 (match_operand:QI 2 "nonmemory_operand" "")))
12704 (clobber (reg:CC FLAGS_REG))]
12709 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12712 if (!const_1_to_31_operand (operands[2], VOIDmode))
12714 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12718 ;; Implement rotation using two double-precision shift instructions
12719 ;; and a scratch register.
12720 (define_insn_and_split "ix86_rotrdi3"
12721 [(set (match_operand:DI 0 "register_operand" "=r")
12722 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12723 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12724 (clobber (reg:CC FLAGS_REG))
12725 (clobber (match_scratch:SI 3 "=&r"))]
12728 "&& reload_completed"
12729 [(set (match_dup 3) (match_dup 4))
12731 [(set (match_dup 4)
12732 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12733 (ashift:SI (match_dup 5)
12734 (minus:QI (const_int 32) (match_dup 2)))))
12735 (clobber (reg:CC FLAGS_REG))])
12737 [(set (match_dup 5)
12738 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12739 (ashift:SI (match_dup 3)
12740 (minus:QI (const_int 32) (match_dup 2)))))
12741 (clobber (reg:CC FLAGS_REG))])]
12742 "split_di (operands, 1, operands + 4, operands + 5);")
12744 (define_insn "*rotrdi3_1_one_bit_rex64"
12745 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12746 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12747 (match_operand:QI 2 "const1_operand" "")))
12748 (clobber (reg:CC FLAGS_REG))]
12749 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12750 && (TARGET_SHIFT1 || optimize_size)"
12752 [(set_attr "type" "rotate")
12753 (set (attr "length")
12754 (if_then_else (match_operand:DI 0 "register_operand" "")
12756 (const_string "*")))])
12758 (define_insn "*rotrdi3_1_rex64"
12759 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12760 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12761 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12762 (clobber (reg:CC FLAGS_REG))]
12763 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12765 ror{q}\t{%2, %0|%0, %2}
12766 ror{q}\t{%b2, %0|%0, %b2}"
12767 [(set_attr "type" "rotate")
12768 (set_attr "mode" "DI")])
12770 (define_expand "rotrsi3"
12771 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12772 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12773 (match_operand:QI 2 "nonmemory_operand" "")))
12774 (clobber (reg:CC FLAGS_REG))]
12776 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12778 (define_insn "*rotrsi3_1_one_bit"
12779 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12780 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12781 (match_operand:QI 2 "const1_operand" "")))
12782 (clobber (reg:CC FLAGS_REG))]
12783 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12784 && (TARGET_SHIFT1 || optimize_size)"
12786 [(set_attr "type" "rotate")
12787 (set (attr "length")
12788 (if_then_else (match_operand:SI 0 "register_operand" "")
12790 (const_string "*")))])
12792 (define_insn "*rotrsi3_1_one_bit_zext"
12793 [(set (match_operand:DI 0 "register_operand" "=r")
12795 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12796 (match_operand:QI 2 "const1_operand" ""))))
12797 (clobber (reg:CC FLAGS_REG))]
12798 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12799 && (TARGET_SHIFT1 || optimize_size)"
12801 [(set_attr "type" "rotate")
12802 (set (attr "length")
12803 (if_then_else (match_operand:SI 0 "register_operand" "")
12805 (const_string "*")))])
12807 (define_insn "*rotrsi3_1"
12808 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12809 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12810 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12811 (clobber (reg:CC FLAGS_REG))]
12812 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12814 ror{l}\t{%2, %0|%0, %2}
12815 ror{l}\t{%b2, %0|%0, %b2}"
12816 [(set_attr "type" "rotate")
12817 (set_attr "mode" "SI")])
12819 (define_insn "*rotrsi3_1_zext"
12820 [(set (match_operand:DI 0 "register_operand" "=r,r")
12822 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12823 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12824 (clobber (reg:CC FLAGS_REG))]
12825 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12827 ror{l}\t{%2, %k0|%k0, %2}
12828 ror{l}\t{%b2, %k0|%k0, %b2}"
12829 [(set_attr "type" "rotate")
12830 (set_attr "mode" "SI")])
12832 (define_expand "rotrhi3"
12833 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12834 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12835 (match_operand:QI 2 "nonmemory_operand" "")))
12836 (clobber (reg:CC FLAGS_REG))]
12837 "TARGET_HIMODE_MATH"
12838 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12840 (define_insn "*rotrhi3_one_bit"
12841 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12842 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12843 (match_operand:QI 2 "const1_operand" "")))
12844 (clobber (reg:CC FLAGS_REG))]
12845 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12846 && (TARGET_SHIFT1 || optimize_size)"
12848 [(set_attr "type" "rotate")
12849 (set (attr "length")
12850 (if_then_else (match_operand 0 "register_operand" "")
12852 (const_string "*")))])
12854 (define_insn "*rotrhi3"
12855 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12856 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12857 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12858 (clobber (reg:CC FLAGS_REG))]
12859 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12861 ror{w}\t{%2, %0|%0, %2}
12862 ror{w}\t{%b2, %0|%0, %b2}"
12863 [(set_attr "type" "rotate")
12864 (set_attr "mode" "HI")])
12866 (define_expand "rotrqi3"
12867 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12868 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12869 (match_operand:QI 2 "nonmemory_operand" "")))
12870 (clobber (reg:CC FLAGS_REG))]
12871 "TARGET_QIMODE_MATH"
12872 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12874 (define_insn "*rotrqi3_1_one_bit"
12875 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12876 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12877 (match_operand:QI 2 "const1_operand" "")))
12878 (clobber (reg:CC FLAGS_REG))]
12879 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12880 && (TARGET_SHIFT1 || optimize_size)"
12882 [(set_attr "type" "rotate")
12883 (set (attr "length")
12884 (if_then_else (match_operand 0 "register_operand" "")
12886 (const_string "*")))])
12888 (define_insn "*rotrqi3_1_one_bit_slp"
12889 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12890 (rotatert:QI (match_dup 0)
12891 (match_operand:QI 1 "const1_operand" "")))
12892 (clobber (reg:CC FLAGS_REG))]
12893 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12894 && (TARGET_SHIFT1 || optimize_size)"
12896 [(set_attr "type" "rotate1")
12897 (set (attr "length")
12898 (if_then_else (match_operand 0 "register_operand" "")
12900 (const_string "*")))])
12902 (define_insn "*rotrqi3_1"
12903 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12904 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12905 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12906 (clobber (reg:CC FLAGS_REG))]
12907 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12909 ror{b}\t{%2, %0|%0, %2}
12910 ror{b}\t{%b2, %0|%0, %b2}"
12911 [(set_attr "type" "rotate")
12912 (set_attr "mode" "QI")])
12914 (define_insn "*rotrqi3_1_slp"
12915 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12916 (rotatert:QI (match_dup 0)
12917 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12918 (clobber (reg:CC FLAGS_REG))]
12919 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12920 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12922 ror{b}\t{%1, %0|%0, %1}
12923 ror{b}\t{%b1, %0|%0, %b1}"
12924 [(set_attr "type" "rotate1")
12925 (set_attr "mode" "QI")])
12927 ;; Bit set / bit test instructions
12929 (define_expand "extv"
12930 [(set (match_operand:SI 0 "register_operand" "")
12931 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12932 (match_operand:SI 2 "const8_operand" "")
12933 (match_operand:SI 3 "const8_operand" "")))]
12936 /* Handle extractions from %ah et al. */
12937 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12940 /* From mips.md: extract_bit_field doesn't verify that our source
12941 matches the predicate, so check it again here. */
12942 if (! ext_register_operand (operands[1], VOIDmode))
12946 (define_expand "extzv"
12947 [(set (match_operand:SI 0 "register_operand" "")
12948 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12949 (match_operand:SI 2 "const8_operand" "")
12950 (match_operand:SI 3 "const8_operand" "")))]
12953 /* Handle extractions from %ah et al. */
12954 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12957 /* From mips.md: extract_bit_field doesn't verify that our source
12958 matches the predicate, so check it again here. */
12959 if (! ext_register_operand (operands[1], VOIDmode))
12963 (define_expand "insv"
12964 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12965 (match_operand 1 "const8_operand" "")
12966 (match_operand 2 "const8_operand" ""))
12967 (match_operand 3 "register_operand" ""))]
12970 /* Handle insertions to %ah et al. */
12971 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12974 /* From mips.md: insert_bit_field doesn't verify that our source
12975 matches the predicate, so check it again here. */
12976 if (! ext_register_operand (operands[0], VOIDmode))
12980 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12982 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12987 ;; %%% bts, btr, btc, bt.
12988 ;; In general these instructions are *slow* when applied to memory,
12989 ;; since they enforce atomic operation. When applied to registers,
12990 ;; it depends on the cpu implementation. They're never faster than
12991 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12992 ;; no point. But in 64-bit, we can't hold the relevant immediates
12993 ;; within the instruction itself, so operating on bits in the high
12994 ;; 32-bits of a register becomes easier.
12996 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12997 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12998 ;; negdf respectively, so they can never be disabled entirely.
13000 (define_insn "*btsq"
13001 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13003 (match_operand:DI 1 "const_0_to_63_operand" ""))
13005 (clobber (reg:CC FLAGS_REG))]
13006 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13008 [(set_attr "type" "alu1")])
13010 (define_insn "*btrq"
13011 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13013 (match_operand:DI 1 "const_0_to_63_operand" ""))
13015 (clobber (reg:CC FLAGS_REG))]
13016 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13018 [(set_attr "type" "alu1")])
13020 (define_insn "*btcq"
13021 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13023 (match_operand:DI 1 "const_0_to_63_operand" ""))
13024 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13025 (clobber (reg:CC FLAGS_REG))]
13026 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13028 [(set_attr "type" "alu1")])
13030 ;; Allow Nocona to avoid these instructions if a register is available.
13033 [(match_scratch:DI 2 "r")
13034 (parallel [(set (zero_extract:DI
13035 (match_operand:DI 0 "register_operand" "")
13037 (match_operand:DI 1 "const_0_to_63_operand" ""))
13039 (clobber (reg:CC FLAGS_REG))])]
13040 "TARGET_64BIT && !TARGET_USE_BT"
13043 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13046 if (HOST_BITS_PER_WIDE_INT >= 64)
13047 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13048 else if (i < HOST_BITS_PER_WIDE_INT)
13049 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13051 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13053 op1 = immed_double_const (lo, hi, DImode);
13056 emit_move_insn (operands[2], op1);
13060 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13065 [(match_scratch:DI 2 "r")
13066 (parallel [(set (zero_extract:DI
13067 (match_operand:DI 0 "register_operand" "")
13069 (match_operand:DI 1 "const_0_to_63_operand" ""))
13071 (clobber (reg:CC FLAGS_REG))])]
13072 "TARGET_64BIT && !TARGET_USE_BT"
13075 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13078 if (HOST_BITS_PER_WIDE_INT >= 64)
13079 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13080 else if (i < HOST_BITS_PER_WIDE_INT)
13081 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13083 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13085 op1 = immed_double_const (~lo, ~hi, DImode);
13088 emit_move_insn (operands[2], op1);
13092 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13097 [(match_scratch:DI 2 "r")
13098 (parallel [(set (zero_extract:DI
13099 (match_operand:DI 0 "register_operand" "")
13101 (match_operand:DI 1 "const_0_to_63_operand" ""))
13102 (not:DI (zero_extract:DI
13103 (match_dup 0) (const_int 1) (match_dup 1))))
13104 (clobber (reg:CC FLAGS_REG))])]
13105 "TARGET_64BIT && !TARGET_USE_BT"
13108 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13111 if (HOST_BITS_PER_WIDE_INT >= 64)
13112 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13113 else if (i < HOST_BITS_PER_WIDE_INT)
13114 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13116 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13118 op1 = immed_double_const (lo, hi, DImode);
13121 emit_move_insn (operands[2], op1);
13125 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13129 ;; Store-flag instructions.
13131 ;; For all sCOND expanders, also expand the compare or test insn that
13132 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13134 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13135 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13136 ;; way, which can later delete the movzx if only QImode is needed.
13138 (define_expand "seq"
13139 [(set (match_operand:QI 0 "register_operand" "")
13140 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13142 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13144 (define_expand "sne"
13145 [(set (match_operand:QI 0 "register_operand" "")
13146 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13148 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13150 (define_expand "sgt"
13151 [(set (match_operand:QI 0 "register_operand" "")
13152 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13154 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13156 (define_expand "sgtu"
13157 [(set (match_operand:QI 0 "register_operand" "")
13158 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13160 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13162 (define_expand "slt"
13163 [(set (match_operand:QI 0 "register_operand" "")
13164 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13166 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13168 (define_expand "sltu"
13169 [(set (match_operand:QI 0 "register_operand" "")
13170 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13172 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13174 (define_expand "sge"
13175 [(set (match_operand:QI 0 "register_operand" "")
13176 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13178 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13180 (define_expand "sgeu"
13181 [(set (match_operand:QI 0 "register_operand" "")
13182 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13184 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13186 (define_expand "sle"
13187 [(set (match_operand:QI 0 "register_operand" "")
13188 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13190 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13192 (define_expand "sleu"
13193 [(set (match_operand:QI 0 "register_operand" "")
13194 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13196 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13198 (define_expand "sunordered"
13199 [(set (match_operand:QI 0 "register_operand" "")
13200 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13201 "TARGET_80387 || TARGET_SSE"
13202 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13204 (define_expand "sordered"
13205 [(set (match_operand:QI 0 "register_operand" "")
13206 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13208 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13210 (define_expand "suneq"
13211 [(set (match_operand:QI 0 "register_operand" "")
13212 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13213 "TARGET_80387 || TARGET_SSE"
13214 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13216 (define_expand "sunge"
13217 [(set (match_operand:QI 0 "register_operand" "")
13218 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13219 "TARGET_80387 || TARGET_SSE"
13220 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13222 (define_expand "sungt"
13223 [(set (match_operand:QI 0 "register_operand" "")
13224 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13225 "TARGET_80387 || TARGET_SSE"
13226 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13228 (define_expand "sunle"
13229 [(set (match_operand:QI 0 "register_operand" "")
13230 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13231 "TARGET_80387 || TARGET_SSE"
13232 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13234 (define_expand "sunlt"
13235 [(set (match_operand:QI 0 "register_operand" "")
13236 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13237 "TARGET_80387 || TARGET_SSE"
13238 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13240 (define_expand "sltgt"
13241 [(set (match_operand:QI 0 "register_operand" "")
13242 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13243 "TARGET_80387 || TARGET_SSE"
13244 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13246 (define_insn "*setcc_1"
13247 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13248 (match_operator:QI 1 "ix86_comparison_operator"
13249 [(reg FLAGS_REG) (const_int 0)]))]
13252 [(set_attr "type" "setcc")
13253 (set_attr "mode" "QI")])
13255 (define_insn "*setcc_2"
13256 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13257 (match_operator:QI 1 "ix86_comparison_operator"
13258 [(reg FLAGS_REG) (const_int 0)]))]
13261 [(set_attr "type" "setcc")
13262 (set_attr "mode" "QI")])
13264 ;; In general it is not safe to assume too much about CCmode registers,
13265 ;; so simplify-rtx stops when it sees a second one. Under certain
13266 ;; conditions this is safe on x86, so help combine not create
13273 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13274 (ne:QI (match_operator 1 "ix86_comparison_operator"
13275 [(reg FLAGS_REG) (const_int 0)])
13278 [(set (match_dup 0) (match_dup 1))]
13280 PUT_MODE (operands[1], QImode);
13284 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13285 (ne:QI (match_operator 1 "ix86_comparison_operator"
13286 [(reg FLAGS_REG) (const_int 0)])
13289 [(set (match_dup 0) (match_dup 1))]
13291 PUT_MODE (operands[1], QImode);
13295 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13296 (eq:QI (match_operator 1 "ix86_comparison_operator"
13297 [(reg FLAGS_REG) (const_int 0)])
13300 [(set (match_dup 0) (match_dup 1))]
13302 rtx new_op1 = copy_rtx (operands[1]);
13303 operands[1] = new_op1;
13304 PUT_MODE (new_op1, QImode);
13305 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13306 GET_MODE (XEXP (new_op1, 0))));
13308 /* Make sure that (a) the CCmode we have for the flags is strong
13309 enough for the reversed compare or (b) we have a valid FP compare. */
13310 if (! ix86_comparison_operator (new_op1, VOIDmode))
13315 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13316 (eq:QI (match_operator 1 "ix86_comparison_operator"
13317 [(reg FLAGS_REG) (const_int 0)])
13320 [(set (match_dup 0) (match_dup 1))]
13322 rtx new_op1 = copy_rtx (operands[1]);
13323 operands[1] = new_op1;
13324 PUT_MODE (new_op1, QImode);
13325 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13326 GET_MODE (XEXP (new_op1, 0))));
13328 /* Make sure that (a) the CCmode we have for the flags is strong
13329 enough for the reversed compare or (b) we have a valid FP compare. */
13330 if (! ix86_comparison_operator (new_op1, VOIDmode))
13334 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13335 ;; subsequent logical operations are used to imitate conditional moves.
13336 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13339 (define_insn "*sse_setccsf"
13340 [(set (match_operand:SF 0 "register_operand" "=x")
13341 (match_operator:SF 1 "sse_comparison_operator"
13342 [(match_operand:SF 2 "register_operand" "0")
13343 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13345 "cmp%D1ss\t{%3, %0|%0, %3}"
13346 [(set_attr "type" "ssecmp")
13347 (set_attr "mode" "SF")])
13349 (define_insn "*sse_setccdf"
13350 [(set (match_operand:DF 0 "register_operand" "=Y")
13351 (match_operator:DF 1 "sse_comparison_operator"
13352 [(match_operand:DF 2 "register_operand" "0")
13353 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13355 "cmp%D1sd\t{%3, %0|%0, %3}"
13356 [(set_attr "type" "ssecmp")
13357 (set_attr "mode" "DF")])
13359 ;; Basic conditional jump instructions.
13360 ;; We ignore the overflow flag for signed branch instructions.
13362 ;; For all bCOND expanders, also expand the compare or test insn that
13363 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13365 (define_expand "beq"
13367 (if_then_else (match_dup 1)
13368 (label_ref (match_operand 0 "" ""))
13371 "ix86_expand_branch (EQ, operands[0]); DONE;")
13373 (define_expand "bne"
13375 (if_then_else (match_dup 1)
13376 (label_ref (match_operand 0 "" ""))
13379 "ix86_expand_branch (NE, operands[0]); DONE;")
13381 (define_expand "bgt"
13383 (if_then_else (match_dup 1)
13384 (label_ref (match_operand 0 "" ""))
13387 "ix86_expand_branch (GT, operands[0]); DONE;")
13389 (define_expand "bgtu"
13391 (if_then_else (match_dup 1)
13392 (label_ref (match_operand 0 "" ""))
13395 "ix86_expand_branch (GTU, operands[0]); DONE;")
13397 (define_expand "blt"
13399 (if_then_else (match_dup 1)
13400 (label_ref (match_operand 0 "" ""))
13403 "ix86_expand_branch (LT, operands[0]); DONE;")
13405 (define_expand "bltu"
13407 (if_then_else (match_dup 1)
13408 (label_ref (match_operand 0 "" ""))
13411 "ix86_expand_branch (LTU, operands[0]); DONE;")
13413 (define_expand "bge"
13415 (if_then_else (match_dup 1)
13416 (label_ref (match_operand 0 "" ""))
13419 "ix86_expand_branch (GE, operands[0]); DONE;")
13421 (define_expand "bgeu"
13423 (if_then_else (match_dup 1)
13424 (label_ref (match_operand 0 "" ""))
13427 "ix86_expand_branch (GEU, operands[0]); DONE;")
13429 (define_expand "ble"
13431 (if_then_else (match_dup 1)
13432 (label_ref (match_operand 0 "" ""))
13435 "ix86_expand_branch (LE, operands[0]); DONE;")
13437 (define_expand "bleu"
13439 (if_then_else (match_dup 1)
13440 (label_ref (match_operand 0 "" ""))
13443 "ix86_expand_branch (LEU, operands[0]); DONE;")
13445 (define_expand "bunordered"
13447 (if_then_else (match_dup 1)
13448 (label_ref (match_operand 0 "" ""))
13450 "TARGET_80387 || TARGET_SSE_MATH"
13451 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13453 (define_expand "bordered"
13455 (if_then_else (match_dup 1)
13456 (label_ref (match_operand 0 "" ""))
13458 "TARGET_80387 || TARGET_SSE_MATH"
13459 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13461 (define_expand "buneq"
13463 (if_then_else (match_dup 1)
13464 (label_ref (match_operand 0 "" ""))
13466 "TARGET_80387 || TARGET_SSE_MATH"
13467 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13469 (define_expand "bunge"
13471 (if_then_else (match_dup 1)
13472 (label_ref (match_operand 0 "" ""))
13474 "TARGET_80387 || TARGET_SSE_MATH"
13475 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13477 (define_expand "bungt"
13479 (if_then_else (match_dup 1)
13480 (label_ref (match_operand 0 "" ""))
13482 "TARGET_80387 || TARGET_SSE_MATH"
13483 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13485 (define_expand "bunle"
13487 (if_then_else (match_dup 1)
13488 (label_ref (match_operand 0 "" ""))
13490 "TARGET_80387 || TARGET_SSE_MATH"
13491 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13493 (define_expand "bunlt"
13495 (if_then_else (match_dup 1)
13496 (label_ref (match_operand 0 "" ""))
13498 "TARGET_80387 || TARGET_SSE_MATH"
13499 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13501 (define_expand "bltgt"
13503 (if_then_else (match_dup 1)
13504 (label_ref (match_operand 0 "" ""))
13506 "TARGET_80387 || TARGET_SSE_MATH"
13507 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13509 (define_insn "*jcc_1"
13511 (if_then_else (match_operator 1 "ix86_comparison_operator"
13512 [(reg FLAGS_REG) (const_int 0)])
13513 (label_ref (match_operand 0 "" ""))
13517 [(set_attr "type" "ibr")
13518 (set_attr "modrm" "0")
13519 (set (attr "length")
13520 (if_then_else (and (ge (minus (match_dup 0) (pc))
13522 (lt (minus (match_dup 0) (pc))
13527 (define_insn "*jcc_2"
13529 (if_then_else (match_operator 1 "ix86_comparison_operator"
13530 [(reg FLAGS_REG) (const_int 0)])
13532 (label_ref (match_operand 0 "" ""))))]
13535 [(set_attr "type" "ibr")
13536 (set_attr "modrm" "0")
13537 (set (attr "length")
13538 (if_then_else (and (ge (minus (match_dup 0) (pc))
13540 (lt (minus (match_dup 0) (pc))
13545 ;; In general it is not safe to assume too much about CCmode registers,
13546 ;; so simplify-rtx stops when it sees a second one. Under certain
13547 ;; conditions this is safe on x86, so help combine not create
13555 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13556 [(reg FLAGS_REG) (const_int 0)])
13558 (label_ref (match_operand 1 "" ""))
13562 (if_then_else (match_dup 0)
13563 (label_ref (match_dup 1))
13566 PUT_MODE (operands[0], VOIDmode);
13571 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13572 [(reg FLAGS_REG) (const_int 0)])
13574 (label_ref (match_operand 1 "" ""))
13578 (if_then_else (match_dup 0)
13579 (label_ref (match_dup 1))
13582 rtx new_op0 = copy_rtx (operands[0]);
13583 operands[0] = new_op0;
13584 PUT_MODE (new_op0, VOIDmode);
13585 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13586 GET_MODE (XEXP (new_op0, 0))));
13588 /* Make sure that (a) the CCmode we have for the flags is strong
13589 enough for the reversed compare or (b) we have a valid FP compare. */
13590 if (! ix86_comparison_operator (new_op0, VOIDmode))
13594 ;; Define combination compare-and-branch fp compare instructions to use
13595 ;; during early optimization. Splitting the operation apart early makes
13596 ;; for bad code when we want to reverse the operation.
13598 (define_insn "*fp_jcc_1_mixed"
13600 (if_then_else (match_operator 0 "comparison_operator"
13601 [(match_operand 1 "register_operand" "f,x")
13602 (match_operand 2 "nonimmediate_operand" "f,xm")])
13603 (label_ref (match_operand 3 "" ""))
13605 (clobber (reg:CCFP FPSR_REG))
13606 (clobber (reg:CCFP FLAGS_REG))]
13607 "TARGET_MIX_SSE_I387
13608 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13609 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13610 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13613 (define_insn "*fp_jcc_1_sse"
13615 (if_then_else (match_operator 0 "comparison_operator"
13616 [(match_operand 1 "register_operand" "x")
13617 (match_operand 2 "nonimmediate_operand" "xm")])
13618 (label_ref (match_operand 3 "" ""))
13620 (clobber (reg:CCFP FPSR_REG))
13621 (clobber (reg:CCFP FLAGS_REG))]
13623 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13624 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13625 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13628 (define_insn "*fp_jcc_1_387"
13630 (if_then_else (match_operator 0 "comparison_operator"
13631 [(match_operand 1 "register_operand" "f")
13632 (match_operand 2 "register_operand" "f")])
13633 (label_ref (match_operand 3 "" ""))
13635 (clobber (reg:CCFP FPSR_REG))
13636 (clobber (reg:CCFP FLAGS_REG))]
13637 "TARGET_CMOVE && TARGET_80387
13638 && FLOAT_MODE_P (GET_MODE (operands[1]))
13639 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13640 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13643 (define_insn "*fp_jcc_2_mixed"
13645 (if_then_else (match_operator 0 "comparison_operator"
13646 [(match_operand 1 "register_operand" "f,x")
13647 (match_operand 2 "nonimmediate_operand" "f,xm")])
13649 (label_ref (match_operand 3 "" ""))))
13650 (clobber (reg:CCFP FPSR_REG))
13651 (clobber (reg:CCFP FLAGS_REG))]
13652 "TARGET_MIX_SSE_I387
13653 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13654 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13655 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13658 (define_insn "*fp_jcc_2_sse"
13660 (if_then_else (match_operator 0 "comparison_operator"
13661 [(match_operand 1 "register_operand" "x")
13662 (match_operand 2 "nonimmediate_operand" "xm")])
13664 (label_ref (match_operand 3 "" ""))))
13665 (clobber (reg:CCFP FPSR_REG))
13666 (clobber (reg:CCFP FLAGS_REG))]
13668 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13669 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13670 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13673 (define_insn "*fp_jcc_2_387"
13675 (if_then_else (match_operator 0 "comparison_operator"
13676 [(match_operand 1 "register_operand" "f")
13677 (match_operand 2 "register_operand" "f")])
13679 (label_ref (match_operand 3 "" ""))))
13680 (clobber (reg:CCFP FPSR_REG))
13681 (clobber (reg:CCFP FLAGS_REG))]
13682 "TARGET_CMOVE && TARGET_80387
13683 && FLOAT_MODE_P (GET_MODE (operands[1]))
13684 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13685 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13688 (define_insn "*fp_jcc_3_387"
13690 (if_then_else (match_operator 0 "comparison_operator"
13691 [(match_operand 1 "register_operand" "f")
13692 (match_operand 2 "nonimmediate_operand" "fm")])
13693 (label_ref (match_operand 3 "" ""))
13695 (clobber (reg:CCFP FPSR_REG))
13696 (clobber (reg:CCFP FLAGS_REG))
13697 (clobber (match_scratch:HI 4 "=a"))]
13699 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13700 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13701 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13702 && SELECT_CC_MODE (GET_CODE (operands[0]),
13703 operands[1], operands[2]) == CCFPmode
13704 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13707 (define_insn "*fp_jcc_4_387"
13709 (if_then_else (match_operator 0 "comparison_operator"
13710 [(match_operand 1 "register_operand" "f")
13711 (match_operand 2 "nonimmediate_operand" "fm")])
13713 (label_ref (match_operand 3 "" ""))))
13714 (clobber (reg:CCFP FPSR_REG))
13715 (clobber (reg:CCFP FLAGS_REG))
13716 (clobber (match_scratch:HI 4 "=a"))]
13718 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13719 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13720 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13721 && SELECT_CC_MODE (GET_CODE (operands[0]),
13722 operands[1], operands[2]) == CCFPmode
13723 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13726 (define_insn "*fp_jcc_5_387"
13728 (if_then_else (match_operator 0 "comparison_operator"
13729 [(match_operand 1 "register_operand" "f")
13730 (match_operand 2 "register_operand" "f")])
13731 (label_ref (match_operand 3 "" ""))
13733 (clobber (reg:CCFP FPSR_REG))
13734 (clobber (reg:CCFP FLAGS_REG))
13735 (clobber (match_scratch:HI 4 "=a"))]
13737 && FLOAT_MODE_P (GET_MODE (operands[1]))
13738 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13739 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13742 (define_insn "*fp_jcc_6_387"
13744 (if_then_else (match_operator 0 "comparison_operator"
13745 [(match_operand 1 "register_operand" "f")
13746 (match_operand 2 "register_operand" "f")])
13748 (label_ref (match_operand 3 "" ""))))
13749 (clobber (reg:CCFP FPSR_REG))
13750 (clobber (reg:CCFP FLAGS_REG))
13751 (clobber (match_scratch:HI 4 "=a"))]
13753 && FLOAT_MODE_P (GET_MODE (operands[1]))
13754 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13755 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13758 (define_insn "*fp_jcc_7_387"
13760 (if_then_else (match_operator 0 "comparison_operator"
13761 [(match_operand 1 "register_operand" "f")
13762 (match_operand 2 "const0_operand" "X")])
13763 (label_ref (match_operand 3 "" ""))
13765 (clobber (reg:CCFP FPSR_REG))
13766 (clobber (reg:CCFP FLAGS_REG))
13767 (clobber (match_scratch:HI 4 "=a"))]
13769 && FLOAT_MODE_P (GET_MODE (operands[1]))
13770 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13771 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13772 && SELECT_CC_MODE (GET_CODE (operands[0]),
13773 operands[1], operands[2]) == CCFPmode
13774 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13777 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13778 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13779 ;; with a precedence over other operators and is always put in the first
13780 ;; place. Swap condition and operands to match ficom instruction.
13782 (define_insn "*fp_jcc_8<mode>_387"
13784 (if_then_else (match_operator 0 "comparison_operator"
13785 [(match_operator 1 "float_operator"
13786 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13787 (match_operand 3 "register_operand" "f,f")])
13788 (label_ref (match_operand 4 "" ""))
13790 (clobber (reg:CCFP FPSR_REG))
13791 (clobber (reg:CCFP FLAGS_REG))
13792 (clobber (match_scratch:HI 5 "=a,a"))]
13793 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13794 && FLOAT_MODE_P (GET_MODE (operands[3]))
13795 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13796 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13797 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13798 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13803 (if_then_else (match_operator 0 "comparison_operator"
13804 [(match_operand 1 "register_operand" "")
13805 (match_operand 2 "nonimmediate_operand" "")])
13806 (match_operand 3 "" "")
13807 (match_operand 4 "" "")))
13808 (clobber (reg:CCFP FPSR_REG))
13809 (clobber (reg:CCFP FLAGS_REG))]
13813 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13814 operands[3], operands[4], NULL_RTX, NULL_RTX);
13820 (if_then_else (match_operator 0 "comparison_operator"
13821 [(match_operand 1 "register_operand" "")
13822 (match_operand 2 "general_operand" "")])
13823 (match_operand 3 "" "")
13824 (match_operand 4 "" "")))
13825 (clobber (reg:CCFP FPSR_REG))
13826 (clobber (reg:CCFP FLAGS_REG))
13827 (clobber (match_scratch:HI 5 "=a"))]
13831 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13832 operands[3], operands[4], operands[5], NULL_RTX);
13838 (if_then_else (match_operator 0 "comparison_operator"
13839 [(match_operator 1 "float_operator"
13840 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13841 (match_operand 3 "register_operand" "")])
13842 (match_operand 4 "" "")
13843 (match_operand 5 "" "")))
13844 (clobber (reg:CCFP FPSR_REG))
13845 (clobber (reg:CCFP FLAGS_REG))
13846 (clobber (match_scratch:HI 6 "=a"))]
13850 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13851 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13852 operands[3], operands[7],
13853 operands[4], operands[5], operands[6], NULL_RTX);
13857 ;; %%% Kill this when reload knows how to do it.
13860 (if_then_else (match_operator 0 "comparison_operator"
13861 [(match_operator 1 "float_operator"
13862 [(match_operand:X87MODEI12 2 "register_operand" "")])
13863 (match_operand 3 "register_operand" "")])
13864 (match_operand 4 "" "")
13865 (match_operand 5 "" "")))
13866 (clobber (reg:CCFP FPSR_REG))
13867 (clobber (reg:CCFP FLAGS_REG))
13868 (clobber (match_scratch:HI 6 "=a"))]
13872 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13873 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13874 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13875 operands[3], operands[7],
13876 operands[4], operands[5], operands[6], operands[2]);
13880 ;; Unconditional and other jump instructions
13882 (define_insn "jump"
13884 (label_ref (match_operand 0 "" "")))]
13887 [(set_attr "type" "ibr")
13888 (set (attr "length")
13889 (if_then_else (and (ge (minus (match_dup 0) (pc))
13891 (lt (minus (match_dup 0) (pc))
13895 (set_attr "modrm" "0")])
13897 (define_expand "indirect_jump"
13898 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13902 (define_insn "*indirect_jump"
13903 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13906 [(set_attr "type" "ibr")
13907 (set_attr "length_immediate" "0")])
13909 (define_insn "*indirect_jump_rtx64"
13910 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13913 [(set_attr "type" "ibr")
13914 (set_attr "length_immediate" "0")])
13916 (define_expand "tablejump"
13917 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13918 (use (label_ref (match_operand 1 "" "")))])]
13921 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13922 relative. Convert the relative address to an absolute address. */
13926 enum rtx_code code;
13932 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13934 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13938 op1 = pic_offset_table_rtx;
13943 op0 = pic_offset_table_rtx;
13947 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13952 (define_insn "*tablejump_1"
13953 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13954 (use (label_ref (match_operand 1 "" "")))]
13957 [(set_attr "type" "ibr")
13958 (set_attr "length_immediate" "0")])
13960 (define_insn "*tablejump_1_rtx64"
13961 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13962 (use (label_ref (match_operand 1 "" "")))]
13965 [(set_attr "type" "ibr")
13966 (set_attr "length_immediate" "0")])
13968 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13971 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13972 (set (match_operand:QI 1 "register_operand" "")
13973 (match_operator:QI 2 "ix86_comparison_operator"
13974 [(reg FLAGS_REG) (const_int 0)]))
13975 (set (match_operand 3 "q_regs_operand" "")
13976 (zero_extend (match_dup 1)))]
13977 "(peep2_reg_dead_p (3, operands[1])
13978 || operands_match_p (operands[1], operands[3]))
13979 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13980 [(set (match_dup 4) (match_dup 0))
13981 (set (strict_low_part (match_dup 5))
13984 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13985 operands[5] = gen_lowpart (QImode, operands[3]);
13986 ix86_expand_clear (operands[3]);
13989 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13992 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13993 (set (match_operand:QI 1 "register_operand" "")
13994 (match_operator:QI 2 "ix86_comparison_operator"
13995 [(reg FLAGS_REG) (const_int 0)]))
13996 (parallel [(set (match_operand 3 "q_regs_operand" "")
13997 (zero_extend (match_dup 1)))
13998 (clobber (reg:CC FLAGS_REG))])]
13999 "(peep2_reg_dead_p (3, operands[1])
14000 || operands_match_p (operands[1], operands[3]))
14001 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14002 [(set (match_dup 4) (match_dup 0))
14003 (set (strict_low_part (match_dup 5))
14006 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14007 operands[5] = gen_lowpart (QImode, operands[3]);
14008 ix86_expand_clear (operands[3]);
14011 ;; Call instructions.
14013 ;; The predicates normally associated with named expanders are not properly
14014 ;; checked for calls. This is a bug in the generic code, but it isn't that
14015 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14017 ;; Call subroutine returning no value.
14019 (define_expand "call_pop"
14020 [(parallel [(call (match_operand:QI 0 "" "")
14021 (match_operand:SI 1 "" ""))
14022 (set (reg:SI SP_REG)
14023 (plus:SI (reg:SI SP_REG)
14024 (match_operand:SI 3 "" "")))])]
14027 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14031 (define_insn "*call_pop_0"
14032 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14033 (match_operand:SI 1 "" ""))
14034 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14035 (match_operand:SI 2 "immediate_operand" "")))]
14038 if (SIBLING_CALL_P (insn))
14041 return "call\t%P0";
14043 [(set_attr "type" "call")])
14045 (define_insn "*call_pop_1"
14046 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14047 (match_operand:SI 1 "" ""))
14048 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14049 (match_operand:SI 2 "immediate_operand" "i")))]
14052 if (constant_call_address_operand (operands[0], Pmode))
14054 if (SIBLING_CALL_P (insn))
14057 return "call\t%P0";
14059 if (SIBLING_CALL_P (insn))
14062 return "call\t%A0";
14064 [(set_attr "type" "call")])
14066 (define_expand "call"
14067 [(call (match_operand:QI 0 "" "")
14068 (match_operand 1 "" ""))
14069 (use (match_operand 2 "" ""))]
14072 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14076 (define_expand "sibcall"
14077 [(call (match_operand:QI 0 "" "")
14078 (match_operand 1 "" ""))
14079 (use (match_operand 2 "" ""))]
14082 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14086 (define_insn "*call_0"
14087 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14088 (match_operand 1 "" ""))]
14091 if (SIBLING_CALL_P (insn))
14094 return "call\t%P0";
14096 [(set_attr "type" "call")])
14098 (define_insn "*call_1"
14099 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14100 (match_operand 1 "" ""))]
14101 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14103 if (constant_call_address_operand (operands[0], Pmode))
14104 return "call\t%P0";
14105 return "call\t%A0";
14107 [(set_attr "type" "call")])
14109 (define_insn "*sibcall_1"
14110 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14111 (match_operand 1 "" ""))]
14112 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14114 if (constant_call_address_operand (operands[0], Pmode))
14118 [(set_attr "type" "call")])
14120 (define_insn "*call_1_rex64"
14121 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14122 (match_operand 1 "" ""))]
14123 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14125 if (constant_call_address_operand (operands[0], Pmode))
14126 return "call\t%P0";
14127 return "call\t%A0";
14129 [(set_attr "type" "call")])
14131 (define_insn "*sibcall_1_rex64"
14132 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14133 (match_operand 1 "" ""))]
14134 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14136 [(set_attr "type" "call")])
14138 (define_insn "*sibcall_1_rex64_v"
14139 [(call (mem:QI (reg:DI 40))
14140 (match_operand 0 "" ""))]
14141 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14143 [(set_attr "type" "call")])
14146 ;; Call subroutine, returning value in operand 0
14148 (define_expand "call_value_pop"
14149 [(parallel [(set (match_operand 0 "" "")
14150 (call (match_operand:QI 1 "" "")
14151 (match_operand:SI 2 "" "")))
14152 (set (reg:SI SP_REG)
14153 (plus:SI (reg:SI SP_REG)
14154 (match_operand:SI 4 "" "")))])]
14157 ix86_expand_call (operands[0], operands[1], operands[2],
14158 operands[3], operands[4], 0);
14162 (define_expand "call_value"
14163 [(set (match_operand 0 "" "")
14164 (call (match_operand:QI 1 "" "")
14165 (match_operand:SI 2 "" "")))
14166 (use (match_operand:SI 3 "" ""))]
14167 ;; Operand 2 not used on the i386.
14170 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14174 (define_expand "sibcall_value"
14175 [(set (match_operand 0 "" "")
14176 (call (match_operand:QI 1 "" "")
14177 (match_operand:SI 2 "" "")))
14178 (use (match_operand:SI 3 "" ""))]
14179 ;; Operand 2 not used on the i386.
14182 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14186 ;; Call subroutine returning any type.
14188 (define_expand "untyped_call"
14189 [(parallel [(call (match_operand 0 "" "")
14191 (match_operand 1 "" "")
14192 (match_operand 2 "" "")])]
14197 /* In order to give reg-stack an easier job in validating two
14198 coprocessor registers as containing a possible return value,
14199 simply pretend the untyped call returns a complex long double
14202 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14203 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14204 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14207 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14209 rtx set = XVECEXP (operands[2], 0, i);
14210 emit_move_insn (SET_DEST (set), SET_SRC (set));
14213 /* The optimizer does not know that the call sets the function value
14214 registers we stored in the result block. We avoid problems by
14215 claiming that all hard registers are used and clobbered at this
14217 emit_insn (gen_blockage (const0_rtx));
14222 ;; Prologue and epilogue instructions
14224 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14225 ;; all of memory. This blocks insns from being moved across this point.
14227 (define_insn "blockage"
14228 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14231 [(set_attr "length" "0")])
14233 ;; Insn emitted into the body of a function to return from a function.
14234 ;; This is only done if the function's epilogue is known to be simple.
14235 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14237 (define_expand "return"
14239 "ix86_can_use_return_insn_p ()"
14241 if (current_function_pops_args)
14243 rtx popc = GEN_INT (current_function_pops_args);
14244 emit_jump_insn (gen_return_pop_internal (popc));
14249 (define_insn "return_internal"
14253 [(set_attr "length" "1")
14254 (set_attr "length_immediate" "0")
14255 (set_attr "modrm" "0")])
14257 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14258 ;; instruction Athlon and K8 have.
14260 (define_insn "return_internal_long"
14262 (unspec [(const_int 0)] UNSPEC_REP)]
14265 [(set_attr "length" "1")
14266 (set_attr "length_immediate" "0")
14267 (set_attr "prefix_rep" "1")
14268 (set_attr "modrm" "0")])
14270 (define_insn "return_pop_internal"
14272 (use (match_operand:SI 0 "const_int_operand" ""))]
14275 [(set_attr "length" "3")
14276 (set_attr "length_immediate" "2")
14277 (set_attr "modrm" "0")])
14279 (define_insn "return_indirect_internal"
14281 (use (match_operand:SI 0 "register_operand" "r"))]
14284 [(set_attr "type" "ibr")
14285 (set_attr "length_immediate" "0")])
14291 [(set_attr "length" "1")
14292 (set_attr "length_immediate" "0")
14293 (set_attr "modrm" "0")])
14295 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14296 ;; branch prediction penalty for the third jump in a 16-byte
14299 (define_insn "align"
14300 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14303 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14304 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14306 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14307 The align insn is used to avoid 3 jump instructions in the row to improve
14308 branch prediction and the benefits hardly outweigh the cost of extra 8
14309 nops on the average inserted by full alignment pseudo operation. */
14313 [(set_attr "length" "16")])
14315 (define_expand "prologue"
14318 "ix86_expand_prologue (); DONE;")
14320 (define_insn "set_got"
14321 [(set (match_operand:SI 0 "register_operand" "=r")
14322 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14323 (clobber (reg:CC FLAGS_REG))]
14325 { return output_set_got (operands[0], NULL_RTX); }
14326 [(set_attr "type" "multi")
14327 (set_attr "length" "12")])
14329 (define_insn "set_got_labelled"
14330 [(set (match_operand:SI 0 "register_operand" "=r")
14331 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14333 (clobber (reg:CC FLAGS_REG))]
14335 { return output_set_got (operands[0], operands[1]); }
14336 [(set_attr "type" "multi")
14337 (set_attr "length" "12")])
14339 (define_insn "set_got_rex64"
14340 [(set (match_operand:DI 0 "register_operand" "=r")
14341 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14343 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14344 [(set_attr "type" "lea")
14345 (set_attr "length" "6")])
14347 (define_expand "epilogue"
14350 "ix86_expand_epilogue (1); DONE;")
14352 (define_expand "sibcall_epilogue"
14355 "ix86_expand_epilogue (0); DONE;")
14357 (define_expand "eh_return"
14358 [(use (match_operand 0 "register_operand" ""))]
14361 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14363 /* Tricky bit: we write the address of the handler to which we will
14364 be returning into someone else's stack frame, one word below the
14365 stack address we wish to restore. */
14366 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14367 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14368 tmp = gen_rtx_MEM (Pmode, tmp);
14369 emit_move_insn (tmp, ra);
14371 if (Pmode == SImode)
14372 emit_jump_insn (gen_eh_return_si (sa));
14374 emit_jump_insn (gen_eh_return_di (sa));
14379 (define_insn_and_split "eh_return_si"
14381 (unspec [(match_operand:SI 0 "register_operand" "c")]
14382 UNSPEC_EH_RETURN))]
14387 "ix86_expand_epilogue (2); DONE;")
14389 (define_insn_and_split "eh_return_di"
14391 (unspec [(match_operand:DI 0 "register_operand" "c")]
14392 UNSPEC_EH_RETURN))]
14397 "ix86_expand_epilogue (2); DONE;")
14399 (define_insn "leave"
14400 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14401 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14402 (clobber (mem:BLK (scratch)))]
14405 [(set_attr "type" "leave")])
14407 (define_insn "leave_rex64"
14408 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14409 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14410 (clobber (mem:BLK (scratch)))]
14413 [(set_attr "type" "leave")])
14415 (define_expand "ffssi2"
14417 [(set (match_operand:SI 0 "register_operand" "")
14418 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14419 (clobber (match_scratch:SI 2 ""))
14420 (clobber (reg:CC FLAGS_REG))])]
14424 (define_insn_and_split "*ffs_cmove"
14425 [(set (match_operand:SI 0 "register_operand" "=r")
14426 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14427 (clobber (match_scratch:SI 2 "=&r"))
14428 (clobber (reg:CC FLAGS_REG))]
14431 "&& reload_completed"
14432 [(set (match_dup 2) (const_int -1))
14433 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14434 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14435 (set (match_dup 0) (if_then_else:SI
14436 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14439 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14440 (clobber (reg:CC FLAGS_REG))])]
14443 (define_insn_and_split "*ffs_no_cmove"
14444 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14445 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14446 (clobber (match_scratch:SI 2 "=&q"))
14447 (clobber (reg:CC FLAGS_REG))]
14451 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14452 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14453 (set (strict_low_part (match_dup 3))
14454 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14455 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14456 (clobber (reg:CC FLAGS_REG))])
14457 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14458 (clobber (reg:CC FLAGS_REG))])
14459 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14460 (clobber (reg:CC FLAGS_REG))])]
14462 operands[3] = gen_lowpart (QImode, operands[2]);
14463 ix86_expand_clear (operands[2]);
14466 (define_insn "*ffssi_1"
14467 [(set (reg:CCZ FLAGS_REG)
14468 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14470 (set (match_operand:SI 0 "register_operand" "=r")
14471 (ctz:SI (match_dup 1)))]
14473 "bsf{l}\t{%1, %0|%0, %1}"
14474 [(set_attr "prefix_0f" "1")])
14476 (define_expand "ffsdi2"
14478 [(set (match_operand:DI 0 "register_operand" "")
14479 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14480 (clobber (match_scratch:DI 2 ""))
14481 (clobber (reg:CC FLAGS_REG))])]
14482 "TARGET_64BIT && TARGET_CMOVE"
14485 (define_insn_and_split "*ffs_rex64"
14486 [(set (match_operand:DI 0 "register_operand" "=r")
14487 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14488 (clobber (match_scratch:DI 2 "=&r"))
14489 (clobber (reg:CC FLAGS_REG))]
14490 "TARGET_64BIT && TARGET_CMOVE"
14492 "&& reload_completed"
14493 [(set (match_dup 2) (const_int -1))
14494 (parallel [(set (reg:CCZ FLAGS_REG)
14495 (compare:CCZ (match_dup 1) (const_int 0)))
14496 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14497 (set (match_dup 0) (if_then_else:DI
14498 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14501 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14502 (clobber (reg:CC FLAGS_REG))])]
14505 (define_insn "*ffsdi_1"
14506 [(set (reg:CCZ FLAGS_REG)
14507 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14509 (set (match_operand:DI 0 "register_operand" "=r")
14510 (ctz:DI (match_dup 1)))]
14512 "bsf{q}\t{%1, %0|%0, %1}"
14513 [(set_attr "prefix_0f" "1")])
14515 (define_insn "ctzsi2"
14516 [(set (match_operand:SI 0 "register_operand" "=r")
14517 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14518 (clobber (reg:CC FLAGS_REG))]
14520 "bsf{l}\t{%1, %0|%0, %1}"
14521 [(set_attr "prefix_0f" "1")])
14523 (define_insn "ctzdi2"
14524 [(set (match_operand:DI 0 "register_operand" "=r")
14525 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14526 (clobber (reg:CC FLAGS_REG))]
14528 "bsf{q}\t{%1, %0|%0, %1}"
14529 [(set_attr "prefix_0f" "1")])
14531 (define_expand "clzsi2"
14533 [(set (match_operand:SI 0 "register_operand" "")
14534 (minus:SI (const_int 31)
14535 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14536 (clobber (reg:CC FLAGS_REG))])
14538 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14539 (clobber (reg:CC FLAGS_REG))])]
14543 (define_insn "*bsr"
14544 [(set (match_operand:SI 0 "register_operand" "=r")
14545 (minus:SI (const_int 31)
14546 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14547 (clobber (reg:CC FLAGS_REG))]
14549 "bsr{l}\t{%1, %0|%0, %1}"
14550 [(set_attr "prefix_0f" "1")])
14552 (define_expand "clzdi2"
14554 [(set (match_operand:DI 0 "register_operand" "")
14555 (minus:DI (const_int 63)
14556 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14557 (clobber (reg:CC FLAGS_REG))])
14559 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14560 (clobber (reg:CC FLAGS_REG))])]
14564 (define_insn "*bsr_rex64"
14565 [(set (match_operand:DI 0 "register_operand" "=r")
14566 (minus:DI (const_int 63)
14567 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14568 (clobber (reg:CC FLAGS_REG))]
14570 "bsr{q}\t{%1, %0|%0, %1}"
14571 [(set_attr "prefix_0f" "1")])
14573 ;; Thread-local storage patterns for ELF.
14575 ;; Note that these code sequences must appear exactly as shown
14576 ;; in order to allow linker relaxation.
14578 (define_insn "*tls_global_dynamic_32_gnu"
14579 [(set (match_operand:SI 0 "register_operand" "=a")
14580 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14581 (match_operand:SI 2 "tls_symbolic_operand" "")
14582 (match_operand:SI 3 "call_insn_operand" "")]
14584 (clobber (match_scratch:SI 4 "=d"))
14585 (clobber (match_scratch:SI 5 "=c"))
14586 (clobber (reg:CC FLAGS_REG))]
14587 "!TARGET_64BIT && TARGET_GNU_TLS"
14588 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14589 [(set_attr "type" "multi")
14590 (set_attr "length" "12")])
14592 (define_insn "*tls_global_dynamic_32_sun"
14593 [(set (match_operand:SI 0 "register_operand" "=a")
14594 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14595 (match_operand:SI 2 "tls_symbolic_operand" "")
14596 (match_operand:SI 3 "call_insn_operand" "")]
14598 (clobber (match_scratch:SI 4 "=d"))
14599 (clobber (match_scratch:SI 5 "=c"))
14600 (clobber (reg:CC FLAGS_REG))]
14601 "!TARGET_64BIT && TARGET_SUN_TLS"
14602 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14603 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14604 [(set_attr "type" "multi")
14605 (set_attr "length" "14")])
14607 (define_expand "tls_global_dynamic_32"
14608 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14611 (match_operand:SI 1 "tls_symbolic_operand" "")
14614 (clobber (match_scratch:SI 4 ""))
14615 (clobber (match_scratch:SI 5 ""))
14616 (clobber (reg:CC FLAGS_REG))])]
14620 operands[2] = pic_offset_table_rtx;
14623 operands[2] = gen_reg_rtx (Pmode);
14624 emit_insn (gen_set_got (operands[2]));
14626 if (TARGET_GNU2_TLS)
14628 emit_insn (gen_tls_dynamic_gnu2_32
14629 (operands[0], operands[1], operands[2]));
14632 operands[3] = ix86_tls_get_addr ();
14635 (define_insn "*tls_global_dynamic_64"
14636 [(set (match_operand:DI 0 "register_operand" "=a")
14637 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14638 (match_operand:DI 3 "" "")))
14639 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14642 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14643 [(set_attr "type" "multi")
14644 (set_attr "length" "16")])
14646 (define_expand "tls_global_dynamic_64"
14647 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14648 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14649 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14653 if (TARGET_GNU2_TLS)
14655 emit_insn (gen_tls_dynamic_gnu2_64
14656 (operands[0], operands[1]));
14659 operands[2] = ix86_tls_get_addr ();
14662 (define_insn "*tls_local_dynamic_base_32_gnu"
14663 [(set (match_operand:SI 0 "register_operand" "=a")
14664 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14665 (match_operand:SI 2 "call_insn_operand" "")]
14666 UNSPEC_TLS_LD_BASE))
14667 (clobber (match_scratch:SI 3 "=d"))
14668 (clobber (match_scratch:SI 4 "=c"))
14669 (clobber (reg:CC FLAGS_REG))]
14670 "!TARGET_64BIT && TARGET_GNU_TLS"
14671 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14672 [(set_attr "type" "multi")
14673 (set_attr "length" "11")])
14675 (define_insn "*tls_local_dynamic_base_32_sun"
14676 [(set (match_operand:SI 0 "register_operand" "=a")
14677 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14678 (match_operand:SI 2 "call_insn_operand" "")]
14679 UNSPEC_TLS_LD_BASE))
14680 (clobber (match_scratch:SI 3 "=d"))
14681 (clobber (match_scratch:SI 4 "=c"))
14682 (clobber (reg:CC FLAGS_REG))]
14683 "!TARGET_64BIT && TARGET_SUN_TLS"
14684 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14685 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14686 [(set_attr "type" "multi")
14687 (set_attr "length" "13")])
14689 (define_expand "tls_local_dynamic_base_32"
14690 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14691 (unspec:SI [(match_dup 1) (match_dup 2)]
14692 UNSPEC_TLS_LD_BASE))
14693 (clobber (match_scratch:SI 3 ""))
14694 (clobber (match_scratch:SI 4 ""))
14695 (clobber (reg:CC FLAGS_REG))])]
14699 operands[1] = pic_offset_table_rtx;
14702 operands[1] = gen_reg_rtx (Pmode);
14703 emit_insn (gen_set_got (operands[1]));
14705 if (TARGET_GNU2_TLS)
14707 emit_insn (gen_tls_dynamic_gnu2_32
14708 (operands[0], ix86_tls_module_base (), operands[1]));
14711 operands[2] = ix86_tls_get_addr ();
14714 (define_insn "*tls_local_dynamic_base_64"
14715 [(set (match_operand:DI 0 "register_operand" "=a")
14716 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14717 (match_operand:DI 2 "" "")))
14718 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14720 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14721 [(set_attr "type" "multi")
14722 (set_attr "length" "12")])
14724 (define_expand "tls_local_dynamic_base_64"
14725 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14726 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14727 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14730 if (TARGET_GNU2_TLS)
14732 emit_insn (gen_tls_dynamic_gnu2_64
14733 (operands[0], ix86_tls_module_base ()));
14736 operands[1] = ix86_tls_get_addr ();
14739 ;; Local dynamic of a single variable is a lose. Show combine how
14740 ;; to convert that back to global dynamic.
14742 (define_insn_and_split "*tls_local_dynamic_32_once"
14743 [(set (match_operand:SI 0 "register_operand" "=a")
14744 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14745 (match_operand:SI 2 "call_insn_operand" "")]
14746 UNSPEC_TLS_LD_BASE)
14747 (const:SI (unspec:SI
14748 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14750 (clobber (match_scratch:SI 4 "=d"))
14751 (clobber (match_scratch:SI 5 "=c"))
14752 (clobber (reg:CC FLAGS_REG))]
14756 [(parallel [(set (match_dup 0)
14757 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14759 (clobber (match_dup 4))
14760 (clobber (match_dup 5))
14761 (clobber (reg:CC FLAGS_REG))])]
14764 ;; Load and add the thread base pointer from %gs:0.
14766 (define_insn "*load_tp_si"
14767 [(set (match_operand:SI 0 "register_operand" "=r")
14768 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14770 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14771 [(set_attr "type" "imov")
14772 (set_attr "modrm" "0")
14773 (set_attr "length" "7")
14774 (set_attr "memory" "load")
14775 (set_attr "imm_disp" "false")])
14777 (define_insn "*add_tp_si"
14778 [(set (match_operand:SI 0 "register_operand" "=r")
14779 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14780 (match_operand:SI 1 "register_operand" "0")))
14781 (clobber (reg:CC FLAGS_REG))]
14783 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14784 [(set_attr "type" "alu")
14785 (set_attr "modrm" "0")
14786 (set_attr "length" "7")
14787 (set_attr "memory" "load")
14788 (set_attr "imm_disp" "false")])
14790 (define_insn "*load_tp_di"
14791 [(set (match_operand:DI 0 "register_operand" "=r")
14792 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14794 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14795 [(set_attr "type" "imov")
14796 (set_attr "modrm" "0")
14797 (set_attr "length" "7")
14798 (set_attr "memory" "load")
14799 (set_attr "imm_disp" "false")])
14801 (define_insn "*add_tp_di"
14802 [(set (match_operand:DI 0 "register_operand" "=r")
14803 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14804 (match_operand:DI 1 "register_operand" "0")))
14805 (clobber (reg:CC FLAGS_REG))]
14807 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14808 [(set_attr "type" "alu")
14809 (set_attr "modrm" "0")
14810 (set_attr "length" "7")
14811 (set_attr "memory" "load")
14812 (set_attr "imm_disp" "false")])
14814 ;; GNU2 TLS patterns can be split.
14816 (define_expand "tls_dynamic_gnu2_32"
14817 [(set (match_dup 3)
14818 (plus:SI (match_operand:SI 2 "register_operand" "")
14820 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14823 [(set (match_operand:SI 0 "register_operand" "")
14824 (unspec:SI [(match_dup 1) (match_dup 3)
14825 (match_dup 2) (reg:SI SP_REG)]
14827 (clobber (reg:CC FLAGS_REG))])]
14828 "!TARGET_64BIT && TARGET_GNU2_TLS"
14830 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14831 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14834 (define_insn "*tls_dynamic_lea_32"
14835 [(set (match_operand:SI 0 "register_operand" "=r")
14836 (plus:SI (match_operand:SI 1 "register_operand" "b")
14838 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14839 UNSPEC_TLSDESC))))]
14840 "!TARGET_64BIT && TARGET_GNU2_TLS"
14841 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14842 [(set_attr "type" "lea")
14843 (set_attr "mode" "SI")
14844 (set_attr "length" "6")
14845 (set_attr "length_address" "4")])
14847 (define_insn "*tls_dynamic_call_32"
14848 [(set (match_operand:SI 0 "register_operand" "=a")
14849 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14850 (match_operand:SI 2 "register_operand" "0")
14851 ;; we have to make sure %ebx still points to the GOT
14852 (match_operand:SI 3 "register_operand" "b")
14855 (clobber (reg:CC FLAGS_REG))]
14856 "!TARGET_64BIT && TARGET_GNU2_TLS"
14857 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14858 [(set_attr "type" "call")
14859 (set_attr "length" "2")
14860 (set_attr "length_address" "0")])
14862 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14863 [(set (match_operand:SI 0 "register_operand" "=&a")
14865 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14866 (match_operand:SI 4 "" "")
14867 (match_operand:SI 2 "register_operand" "b")
14870 (const:SI (unspec:SI
14871 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14873 (clobber (reg:CC FLAGS_REG))]
14874 "!TARGET_64BIT && TARGET_GNU2_TLS"
14877 [(set (match_dup 0) (match_dup 5))]
14879 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14880 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14883 (define_expand "tls_dynamic_gnu2_64"
14884 [(set (match_dup 2)
14885 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14888 [(set (match_operand:DI 0 "register_operand" "")
14889 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14891 (clobber (reg:CC FLAGS_REG))])]
14892 "TARGET_64BIT && TARGET_GNU2_TLS"
14894 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14895 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14898 (define_insn "*tls_dynamic_lea_64"
14899 [(set (match_operand:DI 0 "register_operand" "=r")
14900 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14902 "TARGET_64BIT && TARGET_GNU2_TLS"
14903 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14904 [(set_attr "type" "lea")
14905 (set_attr "mode" "DI")
14906 (set_attr "length" "7")
14907 (set_attr "length_address" "4")])
14909 (define_insn "*tls_dynamic_call_64"
14910 [(set (match_operand:DI 0 "register_operand" "=a")
14911 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14912 (match_operand:DI 2 "register_operand" "0")
14915 (clobber (reg:CC FLAGS_REG))]
14916 "TARGET_64BIT && TARGET_GNU2_TLS"
14917 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14918 [(set_attr "type" "call")
14919 (set_attr "length" "2")
14920 (set_attr "length_address" "0")])
14922 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14923 [(set (match_operand:DI 0 "register_operand" "=&a")
14925 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14926 (match_operand:DI 3 "" "")
14929 (const:DI (unspec:DI
14930 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14932 (clobber (reg:CC FLAGS_REG))]
14933 "TARGET_64BIT && TARGET_GNU2_TLS"
14936 [(set (match_dup 0) (match_dup 4))]
14938 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14939 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14944 ;; These patterns match the binary 387 instructions for addM3, subM3,
14945 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14946 ;; SFmode. The first is the normal insn, the second the same insn but
14947 ;; with one operand a conversion, and the third the same insn but with
14948 ;; the other operand a conversion. The conversion may be SFmode or
14949 ;; SImode if the target mode DFmode, but only SImode if the target mode
14952 ;; Gcc is slightly more smart about handling normal two address instructions
14953 ;; so use special patterns for add and mull.
14955 (define_insn "*fop_sf_comm_mixed"
14956 [(set (match_operand:SF 0 "register_operand" "=f,x")
14957 (match_operator:SF 3 "binary_fp_operator"
14958 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14959 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14960 "TARGET_MIX_SSE_I387
14961 && COMMUTATIVE_ARITH_P (operands[3])
14962 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14963 "* return output_387_binary_op (insn, operands);"
14964 [(set (attr "type")
14965 (if_then_else (eq_attr "alternative" "1")
14966 (if_then_else (match_operand:SF 3 "mult_operator" "")
14967 (const_string "ssemul")
14968 (const_string "sseadd"))
14969 (if_then_else (match_operand:SF 3 "mult_operator" "")
14970 (const_string "fmul")
14971 (const_string "fop"))))
14972 (set_attr "mode" "SF")])
14974 (define_insn "*fop_sf_comm_sse"
14975 [(set (match_operand:SF 0 "register_operand" "=x")
14976 (match_operator:SF 3 "binary_fp_operator"
14977 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14978 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14980 && COMMUTATIVE_ARITH_P (operands[3])
14981 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14982 "* return output_387_binary_op (insn, operands);"
14983 [(set (attr "type")
14984 (if_then_else (match_operand:SF 3 "mult_operator" "")
14985 (const_string "ssemul")
14986 (const_string "sseadd")))
14987 (set_attr "mode" "SF")])
14989 (define_insn "*fop_sf_comm_i387"
14990 [(set (match_operand:SF 0 "register_operand" "=f")
14991 (match_operator:SF 3 "binary_fp_operator"
14992 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14993 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14995 && COMMUTATIVE_ARITH_P (operands[3])
14996 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14997 "* return output_387_binary_op (insn, operands);"
14998 [(set (attr "type")
14999 (if_then_else (match_operand:SF 3 "mult_operator" "")
15000 (const_string "fmul")
15001 (const_string "fop")))
15002 (set_attr "mode" "SF")])
15004 (define_insn "*fop_sf_1_mixed"
15005 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15006 (match_operator:SF 3 "binary_fp_operator"
15007 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15008 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15009 "TARGET_MIX_SSE_I387
15010 && !COMMUTATIVE_ARITH_P (operands[3])
15011 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15012 "* return output_387_binary_op (insn, operands);"
15013 [(set (attr "type")
15014 (cond [(and (eq_attr "alternative" "2")
15015 (match_operand:SF 3 "mult_operator" ""))
15016 (const_string "ssemul")
15017 (and (eq_attr "alternative" "2")
15018 (match_operand:SF 3 "div_operator" ""))
15019 (const_string "ssediv")
15020 (eq_attr "alternative" "2")
15021 (const_string "sseadd")
15022 (match_operand:SF 3 "mult_operator" "")
15023 (const_string "fmul")
15024 (match_operand:SF 3 "div_operator" "")
15025 (const_string "fdiv")
15027 (const_string "fop")))
15028 (set_attr "mode" "SF")])
15030 (define_insn "*fop_sf_1_sse"
15031 [(set (match_operand:SF 0 "register_operand" "=x")
15032 (match_operator:SF 3 "binary_fp_operator"
15033 [(match_operand:SF 1 "register_operand" "0")
15034 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15036 && !COMMUTATIVE_ARITH_P (operands[3])"
15037 "* return output_387_binary_op (insn, operands);"
15038 [(set (attr "type")
15039 (cond [(match_operand:SF 3 "mult_operator" "")
15040 (const_string "ssemul")
15041 (match_operand:SF 3 "div_operator" "")
15042 (const_string "ssediv")
15044 (const_string "sseadd")))
15045 (set_attr "mode" "SF")])
15047 ;; This pattern is not fully shadowed by the pattern above.
15048 (define_insn "*fop_sf_1_i387"
15049 [(set (match_operand:SF 0 "register_operand" "=f,f")
15050 (match_operator:SF 3 "binary_fp_operator"
15051 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15052 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15053 "TARGET_80387 && !TARGET_SSE_MATH
15054 && !COMMUTATIVE_ARITH_P (operands[3])
15055 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15056 "* return output_387_binary_op (insn, operands);"
15057 [(set (attr "type")
15058 (cond [(match_operand:SF 3 "mult_operator" "")
15059 (const_string "fmul")
15060 (match_operand:SF 3 "div_operator" "")
15061 (const_string "fdiv")
15063 (const_string "fop")))
15064 (set_attr "mode" "SF")])
15066 ;; ??? Add SSE splitters for these!
15067 (define_insn "*fop_sf_2<mode>_i387"
15068 [(set (match_operand:SF 0 "register_operand" "=f,f")
15069 (match_operator:SF 3 "binary_fp_operator"
15070 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15071 (match_operand:SF 2 "register_operand" "0,0")]))]
15072 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15073 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15074 [(set (attr "type")
15075 (cond [(match_operand:SF 3 "mult_operator" "")
15076 (const_string "fmul")
15077 (match_operand:SF 3 "div_operator" "")
15078 (const_string "fdiv")
15080 (const_string "fop")))
15081 (set_attr "fp_int_src" "true")
15082 (set_attr "mode" "<MODE>")])
15084 (define_insn "*fop_sf_3<mode>_i387"
15085 [(set (match_operand:SF 0 "register_operand" "=f,f")
15086 (match_operator:SF 3 "binary_fp_operator"
15087 [(match_operand:SF 1 "register_operand" "0,0")
15088 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15089 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15090 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15091 [(set (attr "type")
15092 (cond [(match_operand:SF 3 "mult_operator" "")
15093 (const_string "fmul")
15094 (match_operand:SF 3 "div_operator" "")
15095 (const_string "fdiv")
15097 (const_string "fop")))
15098 (set_attr "fp_int_src" "true")
15099 (set_attr "mode" "<MODE>")])
15101 (define_insn "*fop_df_comm_mixed"
15102 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15103 (match_operator:DF 3 "binary_fp_operator"
15104 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15105 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15106 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15107 && COMMUTATIVE_ARITH_P (operands[3])
15108 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15109 "* return output_387_binary_op (insn, operands);"
15110 [(set (attr "type")
15111 (if_then_else (eq_attr "alternative" "1")
15112 (if_then_else (match_operand:DF 3 "mult_operator" "")
15113 (const_string "ssemul")
15114 (const_string "sseadd"))
15115 (if_then_else (match_operand:DF 3 "mult_operator" "")
15116 (const_string "fmul")
15117 (const_string "fop"))))
15118 (set_attr "mode" "DF")])
15120 (define_insn "*fop_df_comm_sse"
15121 [(set (match_operand:DF 0 "register_operand" "=Y")
15122 (match_operator:DF 3 "binary_fp_operator"
15123 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15124 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15125 "TARGET_SSE2 && TARGET_SSE_MATH
15126 && COMMUTATIVE_ARITH_P (operands[3])
15127 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15128 "* return output_387_binary_op (insn, operands);"
15129 [(set (attr "type")
15130 (if_then_else (match_operand:DF 3 "mult_operator" "")
15131 (const_string "ssemul")
15132 (const_string "sseadd")))
15133 (set_attr "mode" "DF")])
15135 (define_insn "*fop_df_comm_i387"
15136 [(set (match_operand:DF 0 "register_operand" "=f")
15137 (match_operator:DF 3 "binary_fp_operator"
15138 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15139 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15141 && COMMUTATIVE_ARITH_P (operands[3])
15142 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15143 "* return output_387_binary_op (insn, operands);"
15144 [(set (attr "type")
15145 (if_then_else (match_operand:DF 3 "mult_operator" "")
15146 (const_string "fmul")
15147 (const_string "fop")))
15148 (set_attr "mode" "DF")])
15150 (define_insn "*fop_df_1_mixed"
15151 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15152 (match_operator:DF 3 "binary_fp_operator"
15153 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15154 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15155 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15156 && !COMMUTATIVE_ARITH_P (operands[3])
15157 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15158 "* return output_387_binary_op (insn, operands);"
15159 [(set (attr "type")
15160 (cond [(and (eq_attr "alternative" "2")
15161 (match_operand:DF 3 "mult_operator" ""))
15162 (const_string "ssemul")
15163 (and (eq_attr "alternative" "2")
15164 (match_operand:DF 3 "div_operator" ""))
15165 (const_string "ssediv")
15166 (eq_attr "alternative" "2")
15167 (const_string "sseadd")
15168 (match_operand:DF 3 "mult_operator" "")
15169 (const_string "fmul")
15170 (match_operand:DF 3 "div_operator" "")
15171 (const_string "fdiv")
15173 (const_string "fop")))
15174 (set_attr "mode" "DF")])
15176 (define_insn "*fop_df_1_sse"
15177 [(set (match_operand:DF 0 "register_operand" "=Y")
15178 (match_operator:DF 3 "binary_fp_operator"
15179 [(match_operand:DF 1 "register_operand" "0")
15180 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15181 "TARGET_SSE2 && TARGET_SSE_MATH
15182 && !COMMUTATIVE_ARITH_P (operands[3])"
15183 "* return output_387_binary_op (insn, operands);"
15184 [(set_attr "mode" "DF")
15186 (cond [(match_operand:DF 3 "mult_operator" "")
15187 (const_string "ssemul")
15188 (match_operand:DF 3 "div_operator" "")
15189 (const_string "ssediv")
15191 (const_string "sseadd")))])
15193 ;; This pattern is not fully shadowed by the pattern above.
15194 (define_insn "*fop_df_1_i387"
15195 [(set (match_operand:DF 0 "register_operand" "=f,f")
15196 (match_operator:DF 3 "binary_fp_operator"
15197 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15198 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15199 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15200 && !COMMUTATIVE_ARITH_P (operands[3])
15201 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15202 "* return output_387_binary_op (insn, operands);"
15203 [(set (attr "type")
15204 (cond [(match_operand:DF 3 "mult_operator" "")
15205 (const_string "fmul")
15206 (match_operand:DF 3 "div_operator" "")
15207 (const_string "fdiv")
15209 (const_string "fop")))
15210 (set_attr "mode" "DF")])
15212 ;; ??? Add SSE splitters for these!
15213 (define_insn "*fop_df_2<mode>_i387"
15214 [(set (match_operand:DF 0 "register_operand" "=f,f")
15215 (match_operator:DF 3 "binary_fp_operator"
15216 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15217 (match_operand:DF 2 "register_operand" "0,0")]))]
15218 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15219 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15220 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15221 [(set (attr "type")
15222 (cond [(match_operand:DF 3 "mult_operator" "")
15223 (const_string "fmul")
15224 (match_operand:DF 3 "div_operator" "")
15225 (const_string "fdiv")
15227 (const_string "fop")))
15228 (set_attr "fp_int_src" "true")
15229 (set_attr "mode" "<MODE>")])
15231 (define_insn "*fop_df_3<mode>_i387"
15232 [(set (match_operand:DF 0 "register_operand" "=f,f")
15233 (match_operator:DF 3 "binary_fp_operator"
15234 [(match_operand:DF 1 "register_operand" "0,0")
15235 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15236 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15237 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15238 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15239 [(set (attr "type")
15240 (cond [(match_operand:DF 3 "mult_operator" "")
15241 (const_string "fmul")
15242 (match_operand:DF 3 "div_operator" "")
15243 (const_string "fdiv")
15245 (const_string "fop")))
15246 (set_attr "fp_int_src" "true")
15247 (set_attr "mode" "<MODE>")])
15249 (define_insn "*fop_df_4_i387"
15250 [(set (match_operand:DF 0 "register_operand" "=f,f")
15251 (match_operator:DF 3 "binary_fp_operator"
15252 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15253 (match_operand:DF 2 "register_operand" "0,f")]))]
15254 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15255 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15256 "* return output_387_binary_op (insn, operands);"
15257 [(set (attr "type")
15258 (cond [(match_operand:DF 3 "mult_operator" "")
15259 (const_string "fmul")
15260 (match_operand:DF 3 "div_operator" "")
15261 (const_string "fdiv")
15263 (const_string "fop")))
15264 (set_attr "mode" "SF")])
15266 (define_insn "*fop_df_5_i387"
15267 [(set (match_operand:DF 0 "register_operand" "=f,f")
15268 (match_operator:DF 3 "binary_fp_operator"
15269 [(match_operand:DF 1 "register_operand" "0,f")
15271 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15272 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15273 "* return output_387_binary_op (insn, operands);"
15274 [(set (attr "type")
15275 (cond [(match_operand:DF 3 "mult_operator" "")
15276 (const_string "fmul")
15277 (match_operand:DF 3 "div_operator" "")
15278 (const_string "fdiv")
15280 (const_string "fop")))
15281 (set_attr "mode" "SF")])
15283 (define_insn "*fop_df_6_i387"
15284 [(set (match_operand:DF 0 "register_operand" "=f,f")
15285 (match_operator:DF 3 "binary_fp_operator"
15287 (match_operand:SF 1 "register_operand" "0,f"))
15289 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15290 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15291 "* return output_387_binary_op (insn, operands);"
15292 [(set (attr "type")
15293 (cond [(match_operand:DF 3 "mult_operator" "")
15294 (const_string "fmul")
15295 (match_operand:DF 3 "div_operator" "")
15296 (const_string "fdiv")
15298 (const_string "fop")))
15299 (set_attr "mode" "SF")])
15301 (define_insn "*fop_xf_comm_i387"
15302 [(set (match_operand:XF 0 "register_operand" "=f")
15303 (match_operator:XF 3 "binary_fp_operator"
15304 [(match_operand:XF 1 "register_operand" "%0")
15305 (match_operand:XF 2 "register_operand" "f")]))]
15307 && COMMUTATIVE_ARITH_P (operands[3])"
15308 "* return output_387_binary_op (insn, operands);"
15309 [(set (attr "type")
15310 (if_then_else (match_operand:XF 3 "mult_operator" "")
15311 (const_string "fmul")
15312 (const_string "fop")))
15313 (set_attr "mode" "XF")])
15315 (define_insn "*fop_xf_1_i387"
15316 [(set (match_operand:XF 0 "register_operand" "=f,f")
15317 (match_operator:XF 3 "binary_fp_operator"
15318 [(match_operand:XF 1 "register_operand" "0,f")
15319 (match_operand:XF 2 "register_operand" "f,0")]))]
15321 && !COMMUTATIVE_ARITH_P (operands[3])"
15322 "* return output_387_binary_op (insn, operands);"
15323 [(set (attr "type")
15324 (cond [(match_operand:XF 3 "mult_operator" "")
15325 (const_string "fmul")
15326 (match_operand:XF 3 "div_operator" "")
15327 (const_string "fdiv")
15329 (const_string "fop")))
15330 (set_attr "mode" "XF")])
15332 (define_insn "*fop_xf_2<mode>_i387"
15333 [(set (match_operand:XF 0 "register_operand" "=f,f")
15334 (match_operator:XF 3 "binary_fp_operator"
15335 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15336 (match_operand:XF 2 "register_operand" "0,0")]))]
15337 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15338 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15339 [(set (attr "type")
15340 (cond [(match_operand:XF 3 "mult_operator" "")
15341 (const_string "fmul")
15342 (match_operand:XF 3 "div_operator" "")
15343 (const_string "fdiv")
15345 (const_string "fop")))
15346 (set_attr "fp_int_src" "true")
15347 (set_attr "mode" "<MODE>")])
15349 (define_insn "*fop_xf_3<mode>_i387"
15350 [(set (match_operand:XF 0 "register_operand" "=f,f")
15351 (match_operator:XF 3 "binary_fp_operator"
15352 [(match_operand:XF 1 "register_operand" "0,0")
15353 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15354 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15355 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15356 [(set (attr "type")
15357 (cond [(match_operand:XF 3 "mult_operator" "")
15358 (const_string "fmul")
15359 (match_operand:XF 3 "div_operator" "")
15360 (const_string "fdiv")
15362 (const_string "fop")))
15363 (set_attr "fp_int_src" "true")
15364 (set_attr "mode" "<MODE>")])
15366 (define_insn "*fop_xf_4_i387"
15367 [(set (match_operand:XF 0 "register_operand" "=f,f")
15368 (match_operator:XF 3 "binary_fp_operator"
15369 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15370 (match_operand:XF 2 "register_operand" "0,f")]))]
15372 "* return output_387_binary_op (insn, operands);"
15373 [(set (attr "type")
15374 (cond [(match_operand:XF 3 "mult_operator" "")
15375 (const_string "fmul")
15376 (match_operand:XF 3 "div_operator" "")
15377 (const_string "fdiv")
15379 (const_string "fop")))
15380 (set_attr "mode" "SF")])
15382 (define_insn "*fop_xf_5_i387"
15383 [(set (match_operand:XF 0 "register_operand" "=f,f")
15384 (match_operator:XF 3 "binary_fp_operator"
15385 [(match_operand:XF 1 "register_operand" "0,f")
15387 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15389 "* return output_387_binary_op (insn, operands);"
15390 [(set (attr "type")
15391 (cond [(match_operand:XF 3 "mult_operator" "")
15392 (const_string "fmul")
15393 (match_operand:XF 3 "div_operator" "")
15394 (const_string "fdiv")
15396 (const_string "fop")))
15397 (set_attr "mode" "SF")])
15399 (define_insn "*fop_xf_6_i387"
15400 [(set (match_operand:XF 0 "register_operand" "=f,f")
15401 (match_operator:XF 3 "binary_fp_operator"
15403 (match_operand 1 "register_operand" "0,f"))
15405 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15407 "* return output_387_binary_op (insn, operands);"
15408 [(set (attr "type")
15409 (cond [(match_operand:XF 3 "mult_operator" "")
15410 (const_string "fmul")
15411 (match_operand:XF 3 "div_operator" "")
15412 (const_string "fdiv")
15414 (const_string "fop")))
15415 (set_attr "mode" "SF")])
15418 [(set (match_operand 0 "register_operand" "")
15419 (match_operator 3 "binary_fp_operator"
15420 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15421 (match_operand 2 "register_operand" "")]))]
15422 "TARGET_80387 && reload_completed
15423 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15426 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15427 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15428 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15429 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15430 GET_MODE (operands[3]),
15433 ix86_free_from_memory (GET_MODE (operands[1]));
15438 [(set (match_operand 0 "register_operand" "")
15439 (match_operator 3 "binary_fp_operator"
15440 [(match_operand 1 "register_operand" "")
15441 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15442 "TARGET_80387 && reload_completed
15443 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15446 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15447 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15448 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15449 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15450 GET_MODE (operands[3]),
15453 ix86_free_from_memory (GET_MODE (operands[2]));
15457 ;; FPU special functions.
15459 (define_expand "sqrtsf2"
15460 [(set (match_operand:SF 0 "register_operand" "")
15461 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15462 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15464 if (!TARGET_SSE_MATH)
15465 operands[1] = force_reg (SFmode, operands[1]);
15468 (define_insn "*sqrtsf2_mixed"
15469 [(set (match_operand:SF 0 "register_operand" "=f,x")
15470 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15471 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15474 sqrtss\t{%1, %0|%0, %1}"
15475 [(set_attr "type" "fpspc,sse")
15476 (set_attr "mode" "SF,SF")
15477 (set_attr "athlon_decode" "direct,*")])
15479 (define_insn "*sqrtsf2_sse"
15480 [(set (match_operand:SF 0 "register_operand" "=x")
15481 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15483 "sqrtss\t{%1, %0|%0, %1}"
15484 [(set_attr "type" "sse")
15485 (set_attr "mode" "SF")
15486 (set_attr "athlon_decode" "*")])
15488 (define_insn "*sqrtsf2_i387"
15489 [(set (match_operand:SF 0 "register_operand" "=f")
15490 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15491 "TARGET_USE_FANCY_MATH_387"
15493 [(set_attr "type" "fpspc")
15494 (set_attr "mode" "SF")
15495 (set_attr "athlon_decode" "direct")])
15497 (define_expand "sqrtdf2"
15498 [(set (match_operand:DF 0 "register_operand" "")
15499 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15500 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15502 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15503 operands[1] = force_reg (DFmode, operands[1]);
15506 (define_insn "*sqrtdf2_mixed"
15507 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15508 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15509 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15512 sqrtsd\t{%1, %0|%0, %1}"
15513 [(set_attr "type" "fpspc,sse")
15514 (set_attr "mode" "DF,DF")
15515 (set_attr "athlon_decode" "direct,*")])
15517 (define_insn "*sqrtdf2_sse"
15518 [(set (match_operand:DF 0 "register_operand" "=Y")
15519 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15520 "TARGET_SSE2 && TARGET_SSE_MATH"
15521 "sqrtsd\t{%1, %0|%0, %1}"
15522 [(set_attr "type" "sse")
15523 (set_attr "mode" "DF")
15524 (set_attr "athlon_decode" "*")])
15526 (define_insn "*sqrtdf2_i387"
15527 [(set (match_operand:DF 0 "register_operand" "=f")
15528 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15529 "TARGET_USE_FANCY_MATH_387"
15531 [(set_attr "type" "fpspc")
15532 (set_attr "mode" "DF")
15533 (set_attr "athlon_decode" "direct")])
15535 (define_insn "*sqrtextendsfdf2_i387"
15536 [(set (match_operand:DF 0 "register_operand" "=f")
15537 (sqrt:DF (float_extend:DF
15538 (match_operand:SF 1 "register_operand" "0"))))]
15539 "TARGET_USE_FANCY_MATH_387
15540 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15542 [(set_attr "type" "fpspc")
15543 (set_attr "mode" "DF")
15544 (set_attr "athlon_decode" "direct")])
15546 (define_insn "sqrtxf2"
15547 [(set (match_operand:XF 0 "register_operand" "=f")
15548 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15549 "TARGET_USE_FANCY_MATH_387"
15551 [(set_attr "type" "fpspc")
15552 (set_attr "mode" "XF")
15553 (set_attr "athlon_decode" "direct")])
15555 (define_insn "*sqrtextendsfxf2_i387"
15556 [(set (match_operand:XF 0 "register_operand" "=f")
15557 (sqrt:XF (float_extend:XF
15558 (match_operand:SF 1 "register_operand" "0"))))]
15559 "TARGET_USE_FANCY_MATH_387"
15561 [(set_attr "type" "fpspc")
15562 (set_attr "mode" "XF")
15563 (set_attr "athlon_decode" "direct")])
15565 (define_insn "*sqrtextenddfxf2_i387"
15566 [(set (match_operand:XF 0 "register_operand" "=f")
15567 (sqrt:XF (float_extend:XF
15568 (match_operand:DF 1 "register_operand" "0"))))]
15569 "TARGET_USE_FANCY_MATH_387"
15571 [(set_attr "type" "fpspc")
15572 (set_attr "mode" "XF")
15573 (set_attr "athlon_decode" "direct")])
15575 (define_insn "fpremxf4"
15576 [(set (match_operand:XF 0 "register_operand" "=f")
15577 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15578 (match_operand:XF 3 "register_operand" "1")]
15580 (set (match_operand:XF 1 "register_operand" "=u")
15581 (unspec:XF [(match_dup 2) (match_dup 3)]
15583 (set (reg:CCFP FPSR_REG)
15584 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15585 "TARGET_USE_FANCY_MATH_387
15586 && flag_unsafe_math_optimizations"
15588 [(set_attr "type" "fpspc")
15589 (set_attr "mode" "XF")])
15591 (define_expand "fmodsf3"
15592 [(use (match_operand:SF 0 "register_operand" ""))
15593 (use (match_operand:SF 1 "register_operand" ""))
15594 (use (match_operand:SF 2 "register_operand" ""))]
15595 "TARGET_USE_FANCY_MATH_387
15596 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15597 && flag_unsafe_math_optimizations"
15599 rtx label = gen_label_rtx ();
15601 rtx op1 = gen_reg_rtx (XFmode);
15602 rtx op2 = gen_reg_rtx (XFmode);
15604 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15605 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15607 emit_label (label);
15609 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15610 ix86_emit_fp_unordered_jump (label);
15612 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15616 (define_expand "fmoddf3"
15617 [(use (match_operand:DF 0 "register_operand" ""))
15618 (use (match_operand:DF 1 "register_operand" ""))
15619 (use (match_operand:DF 2 "register_operand" ""))]
15620 "TARGET_USE_FANCY_MATH_387
15621 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15622 && flag_unsafe_math_optimizations"
15624 rtx label = gen_label_rtx ();
15626 rtx op1 = gen_reg_rtx (XFmode);
15627 rtx op2 = gen_reg_rtx (XFmode);
15629 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15630 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15632 emit_label (label);
15634 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15635 ix86_emit_fp_unordered_jump (label);
15637 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15641 (define_expand "fmodxf3"
15642 [(use (match_operand:XF 0 "register_operand" ""))
15643 (use (match_operand:XF 1 "register_operand" ""))
15644 (use (match_operand:XF 2 "register_operand" ""))]
15645 "TARGET_USE_FANCY_MATH_387
15646 && flag_unsafe_math_optimizations"
15648 rtx label = gen_label_rtx ();
15650 emit_label (label);
15652 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15653 operands[1], operands[2]));
15654 ix86_emit_fp_unordered_jump (label);
15656 emit_move_insn (operands[0], operands[1]);
15660 (define_insn "fprem1xf4"
15661 [(set (match_operand:XF 0 "register_operand" "=f")
15662 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15663 (match_operand:XF 3 "register_operand" "1")]
15665 (set (match_operand:XF 1 "register_operand" "=u")
15666 (unspec:XF [(match_dup 2) (match_dup 3)]
15668 (set (reg:CCFP FPSR_REG)
15669 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15670 "TARGET_USE_FANCY_MATH_387
15671 && flag_unsafe_math_optimizations"
15673 [(set_attr "type" "fpspc")
15674 (set_attr "mode" "XF")])
15676 (define_expand "dremsf3"
15677 [(use (match_operand:SF 0 "register_operand" ""))
15678 (use (match_operand:SF 1 "register_operand" ""))
15679 (use (match_operand:SF 2 "register_operand" ""))]
15680 "TARGET_USE_FANCY_MATH_387
15681 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15682 && flag_unsafe_math_optimizations"
15684 rtx label = gen_label_rtx ();
15686 rtx op1 = gen_reg_rtx (XFmode);
15687 rtx op2 = gen_reg_rtx (XFmode);
15689 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15690 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15692 emit_label (label);
15694 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15695 ix86_emit_fp_unordered_jump (label);
15697 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15701 (define_expand "dremdf3"
15702 [(use (match_operand:DF 0 "register_operand" ""))
15703 (use (match_operand:DF 1 "register_operand" ""))
15704 (use (match_operand:DF 2 "register_operand" ""))]
15705 "TARGET_USE_FANCY_MATH_387
15706 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15707 && flag_unsafe_math_optimizations"
15709 rtx label = gen_label_rtx ();
15711 rtx op1 = gen_reg_rtx (XFmode);
15712 rtx op2 = gen_reg_rtx (XFmode);
15714 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15715 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15717 emit_label (label);
15719 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15720 ix86_emit_fp_unordered_jump (label);
15722 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15726 (define_expand "dremxf3"
15727 [(use (match_operand:XF 0 "register_operand" ""))
15728 (use (match_operand:XF 1 "register_operand" ""))
15729 (use (match_operand:XF 2 "register_operand" ""))]
15730 "TARGET_USE_FANCY_MATH_387
15731 && flag_unsafe_math_optimizations"
15733 rtx label = gen_label_rtx ();
15735 emit_label (label);
15737 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15738 operands[1], operands[2]));
15739 ix86_emit_fp_unordered_jump (label);
15741 emit_move_insn (operands[0], operands[1]);
15745 (define_insn "*sindf2"
15746 [(set (match_operand:DF 0 "register_operand" "=f")
15747 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15748 "TARGET_USE_FANCY_MATH_387
15749 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15750 && flag_unsafe_math_optimizations"
15752 [(set_attr "type" "fpspc")
15753 (set_attr "mode" "DF")])
15755 (define_insn "*sinsf2"
15756 [(set (match_operand:SF 0 "register_operand" "=f")
15757 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15758 "TARGET_USE_FANCY_MATH_387
15759 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15760 && flag_unsafe_math_optimizations"
15762 [(set_attr "type" "fpspc")
15763 (set_attr "mode" "SF")])
15765 (define_insn "*sinextendsfdf2"
15766 [(set (match_operand:DF 0 "register_operand" "=f")
15767 (unspec:DF [(float_extend:DF
15768 (match_operand:SF 1 "register_operand" "0"))]
15770 "TARGET_USE_FANCY_MATH_387
15771 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15772 && flag_unsafe_math_optimizations"
15774 [(set_attr "type" "fpspc")
15775 (set_attr "mode" "DF")])
15777 (define_insn "*sinxf2"
15778 [(set (match_operand:XF 0 "register_operand" "=f")
15779 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15780 "TARGET_USE_FANCY_MATH_387
15781 && flag_unsafe_math_optimizations"
15783 [(set_attr "type" "fpspc")
15784 (set_attr "mode" "XF")])
15786 (define_insn "*cosdf2"
15787 [(set (match_operand:DF 0 "register_operand" "=f")
15788 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15789 "TARGET_USE_FANCY_MATH_387
15790 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15791 && flag_unsafe_math_optimizations"
15793 [(set_attr "type" "fpspc")
15794 (set_attr "mode" "DF")])
15796 (define_insn "*cossf2"
15797 [(set (match_operand:SF 0 "register_operand" "=f")
15798 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15799 "TARGET_USE_FANCY_MATH_387
15800 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15801 && flag_unsafe_math_optimizations"
15803 [(set_attr "type" "fpspc")
15804 (set_attr "mode" "SF")])
15806 (define_insn "*cosextendsfdf2"
15807 [(set (match_operand:DF 0 "register_operand" "=f")
15808 (unspec:DF [(float_extend:DF
15809 (match_operand:SF 1 "register_operand" "0"))]
15811 "TARGET_USE_FANCY_MATH_387
15812 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15813 && flag_unsafe_math_optimizations"
15815 [(set_attr "type" "fpspc")
15816 (set_attr "mode" "DF")])
15818 (define_insn "*cosxf2"
15819 [(set (match_operand:XF 0 "register_operand" "=f")
15820 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15821 "TARGET_USE_FANCY_MATH_387
15822 && flag_unsafe_math_optimizations"
15824 [(set_attr "type" "fpspc")
15825 (set_attr "mode" "XF")])
15827 ;; With sincos pattern defined, sin and cos builtin function will be
15828 ;; expanded to sincos pattern with one of its outputs left unused.
15829 ;; Cse pass will detected, if two sincos patterns can be combined,
15830 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15831 ;; depending on the unused output.
15833 (define_insn "sincosdf3"
15834 [(set (match_operand:DF 0 "register_operand" "=f")
15835 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15836 UNSPEC_SINCOS_COS))
15837 (set (match_operand:DF 1 "register_operand" "=u")
15838 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15839 "TARGET_USE_FANCY_MATH_387
15840 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15841 && flag_unsafe_math_optimizations"
15843 [(set_attr "type" "fpspc")
15844 (set_attr "mode" "DF")])
15847 [(set (match_operand:DF 0 "register_operand" "")
15848 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15849 UNSPEC_SINCOS_COS))
15850 (set (match_operand:DF 1 "register_operand" "")
15851 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15852 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15853 && !reload_completed && !reload_in_progress"
15854 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15858 [(set (match_operand:DF 0 "register_operand" "")
15859 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15860 UNSPEC_SINCOS_COS))
15861 (set (match_operand:DF 1 "register_operand" "")
15862 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15863 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15864 && !reload_completed && !reload_in_progress"
15865 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15868 (define_insn "sincossf3"
15869 [(set (match_operand:SF 0 "register_operand" "=f")
15870 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15871 UNSPEC_SINCOS_COS))
15872 (set (match_operand:SF 1 "register_operand" "=u")
15873 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15874 "TARGET_USE_FANCY_MATH_387
15875 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15876 && flag_unsafe_math_optimizations"
15878 [(set_attr "type" "fpspc")
15879 (set_attr "mode" "SF")])
15882 [(set (match_operand:SF 0 "register_operand" "")
15883 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15884 UNSPEC_SINCOS_COS))
15885 (set (match_operand:SF 1 "register_operand" "")
15886 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15887 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15888 && !reload_completed && !reload_in_progress"
15889 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15893 [(set (match_operand:SF 0 "register_operand" "")
15894 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15895 UNSPEC_SINCOS_COS))
15896 (set (match_operand:SF 1 "register_operand" "")
15897 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15898 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15899 && !reload_completed && !reload_in_progress"
15900 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15903 (define_insn "*sincosextendsfdf3"
15904 [(set (match_operand:DF 0 "register_operand" "=f")
15905 (unspec:DF [(float_extend:DF
15906 (match_operand:SF 2 "register_operand" "0"))]
15907 UNSPEC_SINCOS_COS))
15908 (set (match_operand:DF 1 "register_operand" "=u")
15909 (unspec:DF [(float_extend:DF
15910 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15911 "TARGET_USE_FANCY_MATH_387
15912 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15913 && flag_unsafe_math_optimizations"
15915 [(set_attr "type" "fpspc")
15916 (set_attr "mode" "DF")])
15919 [(set (match_operand:DF 0 "register_operand" "")
15920 (unspec:DF [(float_extend:DF
15921 (match_operand:SF 2 "register_operand" ""))]
15922 UNSPEC_SINCOS_COS))
15923 (set (match_operand:DF 1 "register_operand" "")
15924 (unspec:DF [(float_extend:DF
15925 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15926 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15927 && !reload_completed && !reload_in_progress"
15928 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15929 (match_dup 2))] UNSPEC_SIN))]
15933 [(set (match_operand:DF 0 "register_operand" "")
15934 (unspec:DF [(float_extend:DF
15935 (match_operand:SF 2 "register_operand" ""))]
15936 UNSPEC_SINCOS_COS))
15937 (set (match_operand:DF 1 "register_operand" "")
15938 (unspec:DF [(float_extend:DF
15939 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15940 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15941 && !reload_completed && !reload_in_progress"
15942 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15943 (match_dup 2))] UNSPEC_COS))]
15946 (define_insn "sincosxf3"
15947 [(set (match_operand:XF 0 "register_operand" "=f")
15948 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15949 UNSPEC_SINCOS_COS))
15950 (set (match_operand:XF 1 "register_operand" "=u")
15951 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15952 "TARGET_USE_FANCY_MATH_387
15953 && flag_unsafe_math_optimizations"
15955 [(set_attr "type" "fpspc")
15956 (set_attr "mode" "XF")])
15959 [(set (match_operand:XF 0 "register_operand" "")
15960 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15961 UNSPEC_SINCOS_COS))
15962 (set (match_operand:XF 1 "register_operand" "")
15963 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15964 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15965 && !reload_completed && !reload_in_progress"
15966 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15970 [(set (match_operand:XF 0 "register_operand" "")
15971 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15972 UNSPEC_SINCOS_COS))
15973 (set (match_operand:XF 1 "register_operand" "")
15974 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15975 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15976 && !reload_completed && !reload_in_progress"
15977 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15980 (define_insn "*tandf3_1"
15981 [(set (match_operand:DF 0 "register_operand" "=f")
15982 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15984 (set (match_operand:DF 1 "register_operand" "=u")
15985 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15986 "TARGET_USE_FANCY_MATH_387
15987 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15988 && flag_unsafe_math_optimizations"
15990 [(set_attr "type" "fpspc")
15991 (set_attr "mode" "DF")])
15993 ;; optimize sequence: fptan
15996 ;; into fptan insn.
15999 [(parallel[(set (match_operand:DF 0 "register_operand" "")
16000 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16002 (set (match_operand:DF 1 "register_operand" "")
16003 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16005 (match_operand:DF 3 "immediate_operand" ""))]
16006 "standard_80387_constant_p (operands[3]) == 2"
16007 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16008 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16011 (define_expand "tandf2"
16012 [(parallel [(set (match_dup 2)
16013 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16015 (set (match_operand:DF 0 "register_operand" "")
16016 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16017 "TARGET_USE_FANCY_MATH_387
16018 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16019 && flag_unsafe_math_optimizations"
16021 operands[2] = gen_reg_rtx (DFmode);
16024 (define_insn "*tansf3_1"
16025 [(set (match_operand:SF 0 "register_operand" "=f")
16026 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16028 (set (match_operand:SF 1 "register_operand" "=u")
16029 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16030 "TARGET_USE_FANCY_MATH_387
16031 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16032 && flag_unsafe_math_optimizations"
16034 [(set_attr "type" "fpspc")
16035 (set_attr "mode" "SF")])
16037 ;; optimize sequence: fptan
16040 ;; into fptan insn.
16043 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16044 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16046 (set (match_operand:SF 1 "register_operand" "")
16047 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16049 (match_operand:SF 3 "immediate_operand" ""))]
16050 "standard_80387_constant_p (operands[3]) == 2"
16051 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16052 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16055 (define_expand "tansf2"
16056 [(parallel [(set (match_dup 2)
16057 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16059 (set (match_operand:SF 0 "register_operand" "")
16060 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16061 "TARGET_USE_FANCY_MATH_387
16062 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16063 && flag_unsafe_math_optimizations"
16065 operands[2] = gen_reg_rtx (SFmode);
16068 (define_insn "*tanxf3_1"
16069 [(set (match_operand:XF 0 "register_operand" "=f")
16070 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16072 (set (match_operand:XF 1 "register_operand" "=u")
16073 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16074 "TARGET_USE_FANCY_MATH_387
16075 && flag_unsafe_math_optimizations"
16077 [(set_attr "type" "fpspc")
16078 (set_attr "mode" "XF")])
16080 ;; optimize sequence: fptan
16083 ;; into fptan insn.
16086 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16087 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16089 (set (match_operand:XF 1 "register_operand" "")
16090 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16092 (match_operand:XF 3 "immediate_operand" ""))]
16093 "standard_80387_constant_p (operands[3]) == 2"
16094 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16095 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16098 (define_expand "tanxf2"
16099 [(parallel [(set (match_dup 2)
16100 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16102 (set (match_operand:XF 0 "register_operand" "")
16103 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16104 "TARGET_USE_FANCY_MATH_387
16105 && flag_unsafe_math_optimizations"
16107 operands[2] = gen_reg_rtx (XFmode);
16110 (define_insn "atan2df3_1"
16111 [(set (match_operand:DF 0 "register_operand" "=f")
16112 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16113 (match_operand:DF 1 "register_operand" "u")]
16115 (clobber (match_scratch:DF 3 "=1"))]
16116 "TARGET_USE_FANCY_MATH_387
16117 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16118 && flag_unsafe_math_optimizations"
16120 [(set_attr "type" "fpspc")
16121 (set_attr "mode" "DF")])
16123 (define_expand "atan2df3"
16124 [(use (match_operand:DF 0 "register_operand" ""))
16125 (use (match_operand:DF 2 "register_operand" ""))
16126 (use (match_operand:DF 1 "register_operand" ""))]
16127 "TARGET_USE_FANCY_MATH_387
16128 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16129 && flag_unsafe_math_optimizations"
16131 rtx copy = gen_reg_rtx (DFmode);
16132 emit_move_insn (copy, operands[1]);
16133 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16137 (define_expand "atandf2"
16138 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16139 (unspec:DF [(match_dup 2)
16140 (match_operand:DF 1 "register_operand" "")]
16142 (clobber (match_scratch:DF 3 ""))])]
16143 "TARGET_USE_FANCY_MATH_387
16144 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16145 && flag_unsafe_math_optimizations"
16147 operands[2] = gen_reg_rtx (DFmode);
16148 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16151 (define_insn "atan2sf3_1"
16152 [(set (match_operand:SF 0 "register_operand" "=f")
16153 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16154 (match_operand:SF 1 "register_operand" "u")]
16156 (clobber (match_scratch:SF 3 "=1"))]
16157 "TARGET_USE_FANCY_MATH_387
16158 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16159 && flag_unsafe_math_optimizations"
16161 [(set_attr "type" "fpspc")
16162 (set_attr "mode" "SF")])
16164 (define_expand "atan2sf3"
16165 [(use (match_operand:SF 0 "register_operand" ""))
16166 (use (match_operand:SF 2 "register_operand" ""))
16167 (use (match_operand:SF 1 "register_operand" ""))]
16168 "TARGET_USE_FANCY_MATH_387
16169 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16170 && flag_unsafe_math_optimizations"
16172 rtx copy = gen_reg_rtx (SFmode);
16173 emit_move_insn (copy, operands[1]);
16174 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16178 (define_expand "atansf2"
16179 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16180 (unspec:SF [(match_dup 2)
16181 (match_operand:SF 1 "register_operand" "")]
16183 (clobber (match_scratch:SF 3 ""))])]
16184 "TARGET_USE_FANCY_MATH_387
16185 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16186 && flag_unsafe_math_optimizations"
16188 operands[2] = gen_reg_rtx (SFmode);
16189 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16192 (define_insn "atan2xf3_1"
16193 [(set (match_operand:XF 0 "register_operand" "=f")
16194 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16195 (match_operand:XF 1 "register_operand" "u")]
16197 (clobber (match_scratch:XF 3 "=1"))]
16198 "TARGET_USE_FANCY_MATH_387
16199 && flag_unsafe_math_optimizations"
16201 [(set_attr "type" "fpspc")
16202 (set_attr "mode" "XF")])
16204 (define_expand "atan2xf3"
16205 [(use (match_operand:XF 0 "register_operand" ""))
16206 (use (match_operand:XF 2 "register_operand" ""))
16207 (use (match_operand:XF 1 "register_operand" ""))]
16208 "TARGET_USE_FANCY_MATH_387
16209 && flag_unsafe_math_optimizations"
16211 rtx copy = gen_reg_rtx (XFmode);
16212 emit_move_insn (copy, operands[1]);
16213 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16217 (define_expand "atanxf2"
16218 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16219 (unspec:XF [(match_dup 2)
16220 (match_operand:XF 1 "register_operand" "")]
16222 (clobber (match_scratch:XF 3 ""))])]
16223 "TARGET_USE_FANCY_MATH_387
16224 && flag_unsafe_math_optimizations"
16226 operands[2] = gen_reg_rtx (XFmode);
16227 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16230 (define_expand "asindf2"
16231 [(set (match_dup 2)
16232 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16233 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16234 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16235 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16236 (parallel [(set (match_dup 7)
16237 (unspec:XF [(match_dup 6) (match_dup 2)]
16239 (clobber (match_scratch:XF 8 ""))])
16240 (set (match_operand:DF 0 "register_operand" "")
16241 (float_truncate:DF (match_dup 7)))]
16242 "TARGET_USE_FANCY_MATH_387
16243 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16244 && flag_unsafe_math_optimizations"
16248 for (i=2; i<8; i++)
16249 operands[i] = gen_reg_rtx (XFmode);
16251 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16254 (define_expand "asinsf2"
16255 [(set (match_dup 2)
16256 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16257 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16258 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16259 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16260 (parallel [(set (match_dup 7)
16261 (unspec:XF [(match_dup 6) (match_dup 2)]
16263 (clobber (match_scratch:XF 8 ""))])
16264 (set (match_operand:SF 0 "register_operand" "")
16265 (float_truncate:SF (match_dup 7)))]
16266 "TARGET_USE_FANCY_MATH_387
16267 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16268 && flag_unsafe_math_optimizations"
16272 for (i=2; i<8; i++)
16273 operands[i] = gen_reg_rtx (XFmode);
16275 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16278 (define_expand "asinxf2"
16279 [(set (match_dup 2)
16280 (mult:XF (match_operand:XF 1 "register_operand" "")
16282 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16283 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16284 (parallel [(set (match_operand:XF 0 "register_operand" "")
16285 (unspec:XF [(match_dup 5) (match_dup 1)]
16287 (clobber (match_scratch:XF 6 ""))])]
16288 "TARGET_USE_FANCY_MATH_387
16289 && flag_unsafe_math_optimizations"
16293 for (i=2; i<6; i++)
16294 operands[i] = gen_reg_rtx (XFmode);
16296 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16299 (define_expand "acosdf2"
16300 [(set (match_dup 2)
16301 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16302 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16303 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16304 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16305 (parallel [(set (match_dup 7)
16306 (unspec:XF [(match_dup 2) (match_dup 6)]
16308 (clobber (match_scratch:XF 8 ""))])
16309 (set (match_operand:DF 0 "register_operand" "")
16310 (float_truncate:DF (match_dup 7)))]
16311 "TARGET_USE_FANCY_MATH_387
16312 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16313 && flag_unsafe_math_optimizations"
16317 for (i=2; i<8; i++)
16318 operands[i] = gen_reg_rtx (XFmode);
16320 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16323 (define_expand "acossf2"
16324 [(set (match_dup 2)
16325 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16326 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16327 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16328 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16329 (parallel [(set (match_dup 7)
16330 (unspec:XF [(match_dup 2) (match_dup 6)]
16332 (clobber (match_scratch:XF 8 ""))])
16333 (set (match_operand:SF 0 "register_operand" "")
16334 (float_truncate:SF (match_dup 7)))]
16335 "TARGET_USE_FANCY_MATH_387
16336 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16337 && flag_unsafe_math_optimizations"
16341 for (i=2; i<8; i++)
16342 operands[i] = gen_reg_rtx (XFmode);
16344 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16347 (define_expand "acosxf2"
16348 [(set (match_dup 2)
16349 (mult:XF (match_operand:XF 1 "register_operand" "")
16351 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16352 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16353 (parallel [(set (match_operand:XF 0 "register_operand" "")
16354 (unspec:XF [(match_dup 1) (match_dup 5)]
16356 (clobber (match_scratch:XF 6 ""))])]
16357 "TARGET_USE_FANCY_MATH_387
16358 && flag_unsafe_math_optimizations"
16362 for (i=2; i<6; i++)
16363 operands[i] = gen_reg_rtx (XFmode);
16365 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16368 (define_insn "fyl2x_xf3"
16369 [(set (match_operand:XF 0 "register_operand" "=f")
16370 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16371 (match_operand:XF 1 "register_operand" "u")]
16373 (clobber (match_scratch:XF 3 "=1"))]
16374 "TARGET_USE_FANCY_MATH_387
16375 && flag_unsafe_math_optimizations"
16377 [(set_attr "type" "fpspc")
16378 (set_attr "mode" "XF")])
16380 (define_expand "logsf2"
16381 [(set (match_dup 2)
16382 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16383 (parallel [(set (match_dup 4)
16384 (unspec:XF [(match_dup 2)
16385 (match_dup 3)] UNSPEC_FYL2X))
16386 (clobber (match_scratch:XF 5 ""))])
16387 (set (match_operand:SF 0 "register_operand" "")
16388 (float_truncate:SF (match_dup 4)))]
16389 "TARGET_USE_FANCY_MATH_387
16390 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16391 && flag_unsafe_math_optimizations"
16395 operands[2] = gen_reg_rtx (XFmode);
16396 operands[3] = gen_reg_rtx (XFmode);
16397 operands[4] = gen_reg_rtx (XFmode);
16399 temp = standard_80387_constant_rtx (4); /* fldln2 */
16400 emit_move_insn (operands[3], temp);
16403 (define_expand "logdf2"
16404 [(set (match_dup 2)
16405 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16406 (parallel [(set (match_dup 4)
16407 (unspec:XF [(match_dup 2)
16408 (match_dup 3)] UNSPEC_FYL2X))
16409 (clobber (match_scratch:XF 5 ""))])
16410 (set (match_operand:DF 0 "register_operand" "")
16411 (float_truncate:DF (match_dup 4)))]
16412 "TARGET_USE_FANCY_MATH_387
16413 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16414 && flag_unsafe_math_optimizations"
16418 operands[2] = gen_reg_rtx (XFmode);
16419 operands[3] = gen_reg_rtx (XFmode);
16420 operands[4] = gen_reg_rtx (XFmode);
16422 temp = standard_80387_constant_rtx (4); /* fldln2 */
16423 emit_move_insn (operands[3], temp);
16426 (define_expand "logxf2"
16427 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16428 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16429 (match_dup 2)] UNSPEC_FYL2X))
16430 (clobber (match_scratch:XF 3 ""))])]
16431 "TARGET_USE_FANCY_MATH_387
16432 && flag_unsafe_math_optimizations"
16436 operands[2] = gen_reg_rtx (XFmode);
16437 temp = standard_80387_constant_rtx (4); /* fldln2 */
16438 emit_move_insn (operands[2], temp);
16441 (define_expand "log10sf2"
16442 [(set (match_dup 2)
16443 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16444 (parallel [(set (match_dup 4)
16445 (unspec:XF [(match_dup 2)
16446 (match_dup 3)] UNSPEC_FYL2X))
16447 (clobber (match_scratch:XF 5 ""))])
16448 (set (match_operand:SF 0 "register_operand" "")
16449 (float_truncate:SF (match_dup 4)))]
16450 "TARGET_USE_FANCY_MATH_387
16451 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16452 && flag_unsafe_math_optimizations"
16456 operands[2] = gen_reg_rtx (XFmode);
16457 operands[3] = gen_reg_rtx (XFmode);
16458 operands[4] = gen_reg_rtx (XFmode);
16460 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16461 emit_move_insn (operands[3], temp);
16464 (define_expand "log10df2"
16465 [(set (match_dup 2)
16466 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16467 (parallel [(set (match_dup 4)
16468 (unspec:XF [(match_dup 2)
16469 (match_dup 3)] UNSPEC_FYL2X))
16470 (clobber (match_scratch:XF 5 ""))])
16471 (set (match_operand:DF 0 "register_operand" "")
16472 (float_truncate:DF (match_dup 4)))]
16473 "TARGET_USE_FANCY_MATH_387
16474 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16475 && flag_unsafe_math_optimizations"
16479 operands[2] = gen_reg_rtx (XFmode);
16480 operands[3] = gen_reg_rtx (XFmode);
16481 operands[4] = gen_reg_rtx (XFmode);
16483 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16484 emit_move_insn (operands[3], temp);
16487 (define_expand "log10xf2"
16488 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16489 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16490 (match_dup 2)] UNSPEC_FYL2X))
16491 (clobber (match_scratch:XF 3 ""))])]
16492 "TARGET_USE_FANCY_MATH_387
16493 && flag_unsafe_math_optimizations"
16497 operands[2] = gen_reg_rtx (XFmode);
16498 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16499 emit_move_insn (operands[2], temp);
16502 (define_expand "log2sf2"
16503 [(set (match_dup 2)
16504 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16505 (parallel [(set (match_dup 4)
16506 (unspec:XF [(match_dup 2)
16507 (match_dup 3)] UNSPEC_FYL2X))
16508 (clobber (match_scratch:XF 5 ""))])
16509 (set (match_operand:SF 0 "register_operand" "")
16510 (float_truncate:SF (match_dup 4)))]
16511 "TARGET_USE_FANCY_MATH_387
16512 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16513 && flag_unsafe_math_optimizations"
16515 operands[2] = gen_reg_rtx (XFmode);
16516 operands[3] = gen_reg_rtx (XFmode);
16517 operands[4] = gen_reg_rtx (XFmode);
16519 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16522 (define_expand "log2df2"
16523 [(set (match_dup 2)
16524 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16525 (parallel [(set (match_dup 4)
16526 (unspec:XF [(match_dup 2)
16527 (match_dup 3)] UNSPEC_FYL2X))
16528 (clobber (match_scratch:XF 5 ""))])
16529 (set (match_operand:DF 0 "register_operand" "")
16530 (float_truncate:DF (match_dup 4)))]
16531 "TARGET_USE_FANCY_MATH_387
16532 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16533 && flag_unsafe_math_optimizations"
16535 operands[2] = gen_reg_rtx (XFmode);
16536 operands[3] = gen_reg_rtx (XFmode);
16537 operands[4] = gen_reg_rtx (XFmode);
16539 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16542 (define_expand "log2xf2"
16543 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16544 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16545 (match_dup 2)] UNSPEC_FYL2X))
16546 (clobber (match_scratch:XF 3 ""))])]
16547 "TARGET_USE_FANCY_MATH_387
16548 && flag_unsafe_math_optimizations"
16550 operands[2] = gen_reg_rtx (XFmode);
16551 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16554 (define_insn "fyl2xp1_xf3"
16555 [(set (match_operand:XF 0 "register_operand" "=f")
16556 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16557 (match_operand:XF 1 "register_operand" "u")]
16559 (clobber (match_scratch:XF 3 "=1"))]
16560 "TARGET_USE_FANCY_MATH_387
16561 && flag_unsafe_math_optimizations"
16563 [(set_attr "type" "fpspc")
16564 (set_attr "mode" "XF")])
16566 (define_expand "log1psf2"
16567 [(use (match_operand:SF 0 "register_operand" ""))
16568 (use (match_operand:SF 1 "register_operand" ""))]
16569 "TARGET_USE_FANCY_MATH_387
16570 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16571 && flag_unsafe_math_optimizations"
16573 rtx op0 = gen_reg_rtx (XFmode);
16574 rtx op1 = gen_reg_rtx (XFmode);
16576 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16577 ix86_emit_i387_log1p (op0, op1);
16578 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16582 (define_expand "log1pdf2"
16583 [(use (match_operand:DF 0 "register_operand" ""))
16584 (use (match_operand:DF 1 "register_operand" ""))]
16585 "TARGET_USE_FANCY_MATH_387
16586 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16587 && flag_unsafe_math_optimizations"
16589 rtx op0 = gen_reg_rtx (XFmode);
16590 rtx op1 = gen_reg_rtx (XFmode);
16592 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16593 ix86_emit_i387_log1p (op0, op1);
16594 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16598 (define_expand "log1pxf2"
16599 [(use (match_operand:XF 0 "register_operand" ""))
16600 (use (match_operand:XF 1 "register_operand" ""))]
16601 "TARGET_USE_FANCY_MATH_387
16602 && flag_unsafe_math_optimizations"
16604 ix86_emit_i387_log1p (operands[0], operands[1]);
16608 (define_insn "*fxtractxf3"
16609 [(set (match_operand:XF 0 "register_operand" "=f")
16610 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16611 UNSPEC_XTRACT_FRACT))
16612 (set (match_operand:XF 1 "register_operand" "=u")
16613 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16614 "TARGET_USE_FANCY_MATH_387
16615 && flag_unsafe_math_optimizations"
16617 [(set_attr "type" "fpspc")
16618 (set_attr "mode" "XF")])
16620 (define_expand "logbsf2"
16621 [(set (match_dup 2)
16622 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16623 (parallel [(set (match_dup 3)
16624 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16626 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16627 (set (match_operand:SF 0 "register_operand" "")
16628 (float_truncate:SF (match_dup 4)))]
16629 "TARGET_USE_FANCY_MATH_387
16630 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16631 && flag_unsafe_math_optimizations"
16633 operands[2] = gen_reg_rtx (XFmode);
16634 operands[3] = gen_reg_rtx (XFmode);
16635 operands[4] = gen_reg_rtx (XFmode);
16638 (define_expand "logbdf2"
16639 [(set (match_dup 2)
16640 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16641 (parallel [(set (match_dup 3)
16642 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16644 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16645 (set (match_operand:DF 0 "register_operand" "")
16646 (float_truncate:DF (match_dup 4)))]
16647 "TARGET_USE_FANCY_MATH_387
16648 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16649 && flag_unsafe_math_optimizations"
16651 operands[2] = gen_reg_rtx (XFmode);
16652 operands[3] = gen_reg_rtx (XFmode);
16653 operands[4] = gen_reg_rtx (XFmode);
16656 (define_expand "logbxf2"
16657 [(parallel [(set (match_dup 2)
16658 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16659 UNSPEC_XTRACT_FRACT))
16660 (set (match_operand:XF 0 "register_operand" "")
16661 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16662 "TARGET_USE_FANCY_MATH_387
16663 && flag_unsafe_math_optimizations"
16665 operands[2] = gen_reg_rtx (XFmode);
16668 (define_expand "ilogbsi2"
16669 [(parallel [(set (match_dup 2)
16670 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16671 UNSPEC_XTRACT_FRACT))
16672 (set (match_operand:XF 3 "register_operand" "")
16673 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16674 (parallel [(set (match_operand:SI 0 "register_operand" "")
16675 (fix:SI (match_dup 3)))
16676 (clobber (reg:CC FLAGS_REG))])]
16677 "TARGET_USE_FANCY_MATH_387
16678 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16679 && flag_unsafe_math_optimizations"
16681 operands[2] = gen_reg_rtx (XFmode);
16682 operands[3] = gen_reg_rtx (XFmode);
16685 (define_insn "*f2xm1xf2"
16686 [(set (match_operand:XF 0 "register_operand" "=f")
16687 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16689 "TARGET_USE_FANCY_MATH_387
16690 && flag_unsafe_math_optimizations"
16692 [(set_attr "type" "fpspc")
16693 (set_attr "mode" "XF")])
16695 (define_insn "*fscalexf4"
16696 [(set (match_operand:XF 0 "register_operand" "=f")
16697 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16698 (match_operand:XF 3 "register_operand" "1")]
16699 UNSPEC_FSCALE_FRACT))
16700 (set (match_operand:XF 1 "register_operand" "=u")
16701 (unspec:XF [(match_dup 2) (match_dup 3)]
16702 UNSPEC_FSCALE_EXP))]
16703 "TARGET_USE_FANCY_MATH_387
16704 && flag_unsafe_math_optimizations"
16706 [(set_attr "type" "fpspc")
16707 (set_attr "mode" "XF")])
16709 (define_expand "expsf2"
16710 [(set (match_dup 2)
16711 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16712 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16713 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16714 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16715 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16716 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16717 (parallel [(set (match_dup 10)
16718 (unspec:XF [(match_dup 9) (match_dup 5)]
16719 UNSPEC_FSCALE_FRACT))
16720 (set (match_dup 11)
16721 (unspec:XF [(match_dup 9) (match_dup 5)]
16722 UNSPEC_FSCALE_EXP))])
16723 (set (match_operand:SF 0 "register_operand" "")
16724 (float_truncate:SF (match_dup 10)))]
16725 "TARGET_USE_FANCY_MATH_387
16726 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16727 && flag_unsafe_math_optimizations"
16732 for (i=2; i<12; i++)
16733 operands[i] = gen_reg_rtx (XFmode);
16734 temp = standard_80387_constant_rtx (5); /* fldl2e */
16735 emit_move_insn (operands[3], temp);
16736 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16739 (define_expand "expdf2"
16740 [(set (match_dup 2)
16741 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16742 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16743 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16744 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16745 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16746 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16747 (parallel [(set (match_dup 10)
16748 (unspec:XF [(match_dup 9) (match_dup 5)]
16749 UNSPEC_FSCALE_FRACT))
16750 (set (match_dup 11)
16751 (unspec:XF [(match_dup 9) (match_dup 5)]
16752 UNSPEC_FSCALE_EXP))])
16753 (set (match_operand:DF 0 "register_operand" "")
16754 (float_truncate:DF (match_dup 10)))]
16755 "TARGET_USE_FANCY_MATH_387
16756 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16757 && flag_unsafe_math_optimizations"
16762 for (i=2; i<12; i++)
16763 operands[i] = gen_reg_rtx (XFmode);
16764 temp = standard_80387_constant_rtx (5); /* fldl2e */
16765 emit_move_insn (operands[3], temp);
16766 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16769 (define_expand "expxf2"
16770 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16772 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16773 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16774 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16775 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16776 (parallel [(set (match_operand:XF 0 "register_operand" "")
16777 (unspec:XF [(match_dup 8) (match_dup 4)]
16778 UNSPEC_FSCALE_FRACT))
16780 (unspec:XF [(match_dup 8) (match_dup 4)]
16781 UNSPEC_FSCALE_EXP))])]
16782 "TARGET_USE_FANCY_MATH_387
16783 && flag_unsafe_math_optimizations"
16788 for (i=2; i<10; i++)
16789 operands[i] = gen_reg_rtx (XFmode);
16790 temp = standard_80387_constant_rtx (5); /* fldl2e */
16791 emit_move_insn (operands[2], temp);
16792 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16795 (define_expand "exp10sf2"
16796 [(set (match_dup 2)
16797 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16798 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16799 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16800 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16801 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16802 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16803 (parallel [(set (match_dup 10)
16804 (unspec:XF [(match_dup 9) (match_dup 5)]
16805 UNSPEC_FSCALE_FRACT))
16806 (set (match_dup 11)
16807 (unspec:XF [(match_dup 9) (match_dup 5)]
16808 UNSPEC_FSCALE_EXP))])
16809 (set (match_operand:SF 0 "register_operand" "")
16810 (float_truncate:SF (match_dup 10)))]
16811 "TARGET_USE_FANCY_MATH_387
16812 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16813 && flag_unsafe_math_optimizations"
16818 for (i=2; i<12; i++)
16819 operands[i] = gen_reg_rtx (XFmode);
16820 temp = standard_80387_constant_rtx (6); /* fldl2t */
16821 emit_move_insn (operands[3], temp);
16822 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16825 (define_expand "exp10df2"
16826 [(set (match_dup 2)
16827 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16828 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16829 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16830 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16831 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16832 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16833 (parallel [(set (match_dup 10)
16834 (unspec:XF [(match_dup 9) (match_dup 5)]
16835 UNSPEC_FSCALE_FRACT))
16836 (set (match_dup 11)
16837 (unspec:XF [(match_dup 9) (match_dup 5)]
16838 UNSPEC_FSCALE_EXP))])
16839 (set (match_operand:DF 0 "register_operand" "")
16840 (float_truncate:DF (match_dup 10)))]
16841 "TARGET_USE_FANCY_MATH_387
16842 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16843 && flag_unsafe_math_optimizations"
16848 for (i=2; i<12; i++)
16849 operands[i] = gen_reg_rtx (XFmode);
16850 temp = standard_80387_constant_rtx (6); /* fldl2t */
16851 emit_move_insn (operands[3], temp);
16852 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16855 (define_expand "exp10xf2"
16856 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16858 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16859 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16860 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16861 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16862 (parallel [(set (match_operand:XF 0 "register_operand" "")
16863 (unspec:XF [(match_dup 8) (match_dup 4)]
16864 UNSPEC_FSCALE_FRACT))
16866 (unspec:XF [(match_dup 8) (match_dup 4)]
16867 UNSPEC_FSCALE_EXP))])]
16868 "TARGET_USE_FANCY_MATH_387
16869 && flag_unsafe_math_optimizations"
16874 for (i=2; i<10; i++)
16875 operands[i] = gen_reg_rtx (XFmode);
16876 temp = standard_80387_constant_rtx (6); /* fldl2t */
16877 emit_move_insn (operands[2], temp);
16878 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16881 (define_expand "exp2sf2"
16882 [(set (match_dup 2)
16883 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16884 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16885 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16886 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16887 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16888 (parallel [(set (match_dup 8)
16889 (unspec:XF [(match_dup 7) (match_dup 3)]
16890 UNSPEC_FSCALE_FRACT))
16892 (unspec:XF [(match_dup 7) (match_dup 3)]
16893 UNSPEC_FSCALE_EXP))])
16894 (set (match_operand:SF 0 "register_operand" "")
16895 (float_truncate:SF (match_dup 8)))]
16896 "TARGET_USE_FANCY_MATH_387
16897 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16898 && flag_unsafe_math_optimizations"
16902 for (i=2; i<10; i++)
16903 operands[i] = gen_reg_rtx (XFmode);
16904 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16907 (define_expand "exp2df2"
16908 [(set (match_dup 2)
16909 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16910 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16911 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16912 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16913 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16914 (parallel [(set (match_dup 8)
16915 (unspec:XF [(match_dup 7) (match_dup 3)]
16916 UNSPEC_FSCALE_FRACT))
16918 (unspec:XF [(match_dup 7) (match_dup 3)]
16919 UNSPEC_FSCALE_EXP))])
16920 (set (match_operand:DF 0 "register_operand" "")
16921 (float_truncate:DF (match_dup 8)))]
16922 "TARGET_USE_FANCY_MATH_387
16923 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16924 && flag_unsafe_math_optimizations"
16928 for (i=2; i<10; i++)
16929 operands[i] = gen_reg_rtx (XFmode);
16930 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16933 (define_expand "exp2xf2"
16934 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16935 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16936 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16937 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16938 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16939 (parallel [(set (match_operand:XF 0 "register_operand" "")
16940 (unspec:XF [(match_dup 7) (match_dup 3)]
16941 UNSPEC_FSCALE_FRACT))
16943 (unspec:XF [(match_dup 7) (match_dup 3)]
16944 UNSPEC_FSCALE_EXP))])]
16945 "TARGET_USE_FANCY_MATH_387
16946 && flag_unsafe_math_optimizations"
16950 for (i=2; i<9; i++)
16951 operands[i] = gen_reg_rtx (XFmode);
16952 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16955 (define_expand "expm1df2"
16956 [(set (match_dup 2)
16957 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16958 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16959 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16960 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16961 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16962 (parallel [(set (match_dup 8)
16963 (unspec:XF [(match_dup 7) (match_dup 5)]
16964 UNSPEC_FSCALE_FRACT))
16966 (unspec:XF [(match_dup 7) (match_dup 5)]
16967 UNSPEC_FSCALE_EXP))])
16968 (parallel [(set (match_dup 11)
16969 (unspec:XF [(match_dup 10) (match_dup 9)]
16970 UNSPEC_FSCALE_FRACT))
16971 (set (match_dup 12)
16972 (unspec:XF [(match_dup 10) (match_dup 9)]
16973 UNSPEC_FSCALE_EXP))])
16974 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16975 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16976 (set (match_operand:DF 0 "register_operand" "")
16977 (float_truncate:DF (match_dup 14)))]
16978 "TARGET_USE_FANCY_MATH_387
16979 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16980 && flag_unsafe_math_optimizations"
16985 for (i=2; i<15; i++)
16986 operands[i] = gen_reg_rtx (XFmode);
16987 temp = standard_80387_constant_rtx (5); /* fldl2e */
16988 emit_move_insn (operands[3], temp);
16989 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16992 (define_expand "expm1sf2"
16993 [(set (match_dup 2)
16994 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16995 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16996 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16997 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16998 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16999 (parallel [(set (match_dup 8)
17000 (unspec:XF [(match_dup 7) (match_dup 5)]
17001 UNSPEC_FSCALE_FRACT))
17003 (unspec:XF [(match_dup 7) (match_dup 5)]
17004 UNSPEC_FSCALE_EXP))])
17005 (parallel [(set (match_dup 11)
17006 (unspec:XF [(match_dup 10) (match_dup 9)]
17007 UNSPEC_FSCALE_FRACT))
17008 (set (match_dup 12)
17009 (unspec:XF [(match_dup 10) (match_dup 9)]
17010 UNSPEC_FSCALE_EXP))])
17011 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17012 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17013 (set (match_operand:SF 0 "register_operand" "")
17014 (float_truncate:SF (match_dup 14)))]
17015 "TARGET_USE_FANCY_MATH_387
17016 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17017 && flag_unsafe_math_optimizations"
17022 for (i=2; i<15; i++)
17023 operands[i] = gen_reg_rtx (XFmode);
17024 temp = standard_80387_constant_rtx (5); /* fldl2e */
17025 emit_move_insn (operands[3], temp);
17026 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17029 (define_expand "expm1xf2"
17030 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17032 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17033 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17034 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17035 (parallel [(set (match_dup 7)
17036 (unspec:XF [(match_dup 6) (match_dup 4)]
17037 UNSPEC_FSCALE_FRACT))
17039 (unspec:XF [(match_dup 6) (match_dup 4)]
17040 UNSPEC_FSCALE_EXP))])
17041 (parallel [(set (match_dup 10)
17042 (unspec:XF [(match_dup 9) (match_dup 8)]
17043 UNSPEC_FSCALE_FRACT))
17044 (set (match_dup 11)
17045 (unspec:XF [(match_dup 9) (match_dup 8)]
17046 UNSPEC_FSCALE_EXP))])
17047 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17048 (set (match_operand:XF 0 "register_operand" "")
17049 (plus:XF (match_dup 12) (match_dup 7)))]
17050 "TARGET_USE_FANCY_MATH_387
17051 && flag_unsafe_math_optimizations"
17056 for (i=2; i<13; i++)
17057 operands[i] = gen_reg_rtx (XFmode);
17058 temp = standard_80387_constant_rtx (5); /* fldl2e */
17059 emit_move_insn (operands[2], temp);
17060 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17063 (define_expand "ldexpdf3"
17064 [(set (match_dup 3)
17065 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17067 (float:XF (match_operand:SI 2 "register_operand" "")))
17068 (parallel [(set (match_dup 5)
17069 (unspec:XF [(match_dup 3) (match_dup 4)]
17070 UNSPEC_FSCALE_FRACT))
17072 (unspec:XF [(match_dup 3) (match_dup 4)]
17073 UNSPEC_FSCALE_EXP))])
17074 (set (match_operand:DF 0 "register_operand" "")
17075 (float_truncate:DF (match_dup 5)))]
17076 "TARGET_USE_FANCY_MATH_387
17077 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17078 && flag_unsafe_math_optimizations"
17082 for (i=3; i<7; i++)
17083 operands[i] = gen_reg_rtx (XFmode);
17086 (define_expand "ldexpsf3"
17087 [(set (match_dup 3)
17088 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17090 (float:XF (match_operand:SI 2 "register_operand" "")))
17091 (parallel [(set (match_dup 5)
17092 (unspec:XF [(match_dup 3) (match_dup 4)]
17093 UNSPEC_FSCALE_FRACT))
17095 (unspec:XF [(match_dup 3) (match_dup 4)]
17096 UNSPEC_FSCALE_EXP))])
17097 (set (match_operand:SF 0 "register_operand" "")
17098 (float_truncate:SF (match_dup 5)))]
17099 "TARGET_USE_FANCY_MATH_387
17100 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17101 && flag_unsafe_math_optimizations"
17105 for (i=3; i<7; i++)
17106 operands[i] = gen_reg_rtx (XFmode);
17109 (define_expand "ldexpxf3"
17110 [(set (match_dup 3)
17111 (float:XF (match_operand:SI 2 "register_operand" "")))
17112 (parallel [(set (match_operand:XF 0 " register_operand" "")
17113 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17115 UNSPEC_FSCALE_FRACT))
17117 (unspec:XF [(match_dup 1) (match_dup 3)]
17118 UNSPEC_FSCALE_EXP))])]
17119 "TARGET_USE_FANCY_MATH_387
17120 && flag_unsafe_math_optimizations"
17124 for (i=3; i<5; i++)
17125 operands[i] = gen_reg_rtx (XFmode);
17129 (define_insn "frndintxf2"
17130 [(set (match_operand:XF 0 "register_operand" "=f")
17131 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17133 "TARGET_USE_FANCY_MATH_387
17134 && flag_unsafe_math_optimizations"
17136 [(set_attr "type" "fpspc")
17137 (set_attr "mode" "XF")])
17139 (define_expand "rintdf2"
17140 [(use (match_operand:DF 0 "register_operand" ""))
17141 (use (match_operand:DF 1 "register_operand" ""))]
17142 "TARGET_USE_FANCY_MATH_387
17143 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17144 && flag_unsafe_math_optimizations"
17146 rtx op0 = gen_reg_rtx (XFmode);
17147 rtx op1 = gen_reg_rtx (XFmode);
17149 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17150 emit_insn (gen_frndintxf2 (op0, op1));
17152 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17156 (define_expand "rintsf2"
17157 [(use (match_operand:SF 0 "register_operand" ""))
17158 (use (match_operand:SF 1 "register_operand" ""))]
17159 "TARGET_USE_FANCY_MATH_387
17160 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17161 && flag_unsafe_math_optimizations"
17163 rtx op0 = gen_reg_rtx (XFmode);
17164 rtx op1 = gen_reg_rtx (XFmode);
17166 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17167 emit_insn (gen_frndintxf2 (op0, op1));
17169 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17173 (define_expand "rintxf2"
17174 [(use (match_operand:XF 0 "register_operand" ""))
17175 (use (match_operand:XF 1 "register_operand" ""))]
17176 "TARGET_USE_FANCY_MATH_387
17177 && flag_unsafe_math_optimizations"
17179 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17183 (define_insn_and_split "*fistdi2_1"
17184 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17185 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17187 "TARGET_USE_FANCY_MATH_387
17188 && flag_unsafe_math_optimizations
17189 && !(reload_completed || reload_in_progress)"
17194 if (memory_operand (operands[0], VOIDmode))
17195 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17198 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17199 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17204 [(set_attr "type" "fpspc")
17205 (set_attr "mode" "DI")])
17207 (define_insn "fistdi2"
17208 [(set (match_operand:DI 0 "memory_operand" "=m")
17209 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17211 (clobber (match_scratch:XF 2 "=&1f"))]
17212 "TARGET_USE_FANCY_MATH_387
17213 && flag_unsafe_math_optimizations"
17214 "* return output_fix_trunc (insn, operands, 0);"
17215 [(set_attr "type" "fpspc")
17216 (set_attr "mode" "DI")])
17218 (define_insn "fistdi2_with_temp"
17219 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17220 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17222 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17223 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17224 "TARGET_USE_FANCY_MATH_387
17225 && flag_unsafe_math_optimizations"
17227 [(set_attr "type" "fpspc")
17228 (set_attr "mode" "DI")])
17231 [(set (match_operand:DI 0 "register_operand" "")
17232 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17234 (clobber (match_operand:DI 2 "memory_operand" ""))
17235 (clobber (match_scratch 3 ""))]
17237 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17238 (clobber (match_dup 3))])
17239 (set (match_dup 0) (match_dup 2))]
17243 [(set (match_operand:DI 0 "memory_operand" "")
17244 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17246 (clobber (match_operand:DI 2 "memory_operand" ""))
17247 (clobber (match_scratch 3 ""))]
17249 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17250 (clobber (match_dup 3))])]
17253 (define_insn_and_split "*fist<mode>2_1"
17254 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17255 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17257 "TARGET_USE_FANCY_MATH_387
17258 && flag_unsafe_math_optimizations
17259 && !(reload_completed || reload_in_progress)"
17264 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17265 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17269 [(set_attr "type" "fpspc")
17270 (set_attr "mode" "<MODE>")])
17272 (define_insn "fist<mode>2"
17273 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17274 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17276 "TARGET_USE_FANCY_MATH_387
17277 && flag_unsafe_math_optimizations"
17278 "* return output_fix_trunc (insn, operands, 0);"
17279 [(set_attr "type" "fpspc")
17280 (set_attr "mode" "<MODE>")])
17282 (define_insn "fist<mode>2_with_temp"
17283 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17284 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17286 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17287 "TARGET_USE_FANCY_MATH_387
17288 && flag_unsafe_math_optimizations"
17290 [(set_attr "type" "fpspc")
17291 (set_attr "mode" "<MODE>")])
17294 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17295 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17297 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17299 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17301 (set (match_dup 0) (match_dup 2))]
17305 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17306 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17308 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17310 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17314 (define_expand "lrint<mode>2"
17315 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17316 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17318 "TARGET_USE_FANCY_MATH_387
17319 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17320 && flag_unsafe_math_optimizations"
17323 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17324 (define_insn_and_split "frndintxf2_floor"
17325 [(set (match_operand:XF 0 "register_operand" "=f")
17326 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17327 UNSPEC_FRNDINT_FLOOR))
17328 (clobber (reg:CC FLAGS_REG))]
17329 "TARGET_USE_FANCY_MATH_387
17330 && flag_unsafe_math_optimizations
17331 && !(reload_completed || reload_in_progress)"
17336 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17338 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17339 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17341 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17342 operands[2], operands[3]));
17345 [(set_attr "type" "frndint")
17346 (set_attr "i387_cw" "floor")
17347 (set_attr "mode" "XF")])
17349 (define_insn "frndintxf2_floor_i387"
17350 [(set (match_operand:XF 0 "register_operand" "=f")
17351 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17352 UNSPEC_FRNDINT_FLOOR))
17353 (use (match_operand:HI 2 "memory_operand" "m"))
17354 (use (match_operand:HI 3 "memory_operand" "m"))]
17355 "TARGET_USE_FANCY_MATH_387
17356 && flag_unsafe_math_optimizations"
17357 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17358 [(set_attr "type" "frndint")
17359 (set_attr "i387_cw" "floor")
17360 (set_attr "mode" "XF")])
17362 (define_expand "floorxf2"
17363 [(use (match_operand:XF 0 "register_operand" ""))
17364 (use (match_operand:XF 1 "register_operand" ""))]
17365 "TARGET_USE_FANCY_MATH_387
17366 && flag_unsafe_math_optimizations"
17368 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17372 (define_expand "floordf2"
17373 [(use (match_operand:DF 0 "register_operand" ""))
17374 (use (match_operand:DF 1 "register_operand" ""))]
17375 "TARGET_USE_FANCY_MATH_387
17376 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17377 && flag_unsafe_math_optimizations"
17379 rtx op0 = gen_reg_rtx (XFmode);
17380 rtx op1 = gen_reg_rtx (XFmode);
17382 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17383 emit_insn (gen_frndintxf2_floor (op0, op1));
17385 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17389 (define_expand "floorsf2"
17390 [(use (match_operand:SF 0 "register_operand" ""))
17391 (use (match_operand:SF 1 "register_operand" ""))]
17392 "TARGET_USE_FANCY_MATH_387
17393 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17394 && flag_unsafe_math_optimizations"
17396 rtx op0 = gen_reg_rtx (XFmode);
17397 rtx op1 = gen_reg_rtx (XFmode);
17399 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17400 emit_insn (gen_frndintxf2_floor (op0, op1));
17402 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17406 (define_insn_and_split "*fist<mode>2_floor_1"
17407 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17408 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17409 UNSPEC_FIST_FLOOR))
17410 (clobber (reg:CC FLAGS_REG))]
17411 "TARGET_USE_FANCY_MATH_387
17412 && flag_unsafe_math_optimizations
17413 && !(reload_completed || reload_in_progress)"
17418 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17420 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17421 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17422 if (memory_operand (operands[0], VOIDmode))
17423 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17424 operands[2], operands[3]));
17427 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17428 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17429 operands[2], operands[3],
17434 [(set_attr "type" "fistp")
17435 (set_attr "i387_cw" "floor")
17436 (set_attr "mode" "<MODE>")])
17438 (define_insn "fistdi2_floor"
17439 [(set (match_operand:DI 0 "memory_operand" "=m")
17440 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17441 UNSPEC_FIST_FLOOR))
17442 (use (match_operand:HI 2 "memory_operand" "m"))
17443 (use (match_operand:HI 3 "memory_operand" "m"))
17444 (clobber (match_scratch:XF 4 "=&1f"))]
17445 "TARGET_USE_FANCY_MATH_387
17446 && flag_unsafe_math_optimizations"
17447 "* return output_fix_trunc (insn, operands, 0);"
17448 [(set_attr "type" "fistp")
17449 (set_attr "i387_cw" "floor")
17450 (set_attr "mode" "DI")])
17452 (define_insn "fistdi2_floor_with_temp"
17453 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17454 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17455 UNSPEC_FIST_FLOOR))
17456 (use (match_operand:HI 2 "memory_operand" "m,m"))
17457 (use (match_operand:HI 3 "memory_operand" "m,m"))
17458 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17459 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17460 "TARGET_USE_FANCY_MATH_387
17461 && flag_unsafe_math_optimizations"
17463 [(set_attr "type" "fistp")
17464 (set_attr "i387_cw" "floor")
17465 (set_attr "mode" "DI")])
17468 [(set (match_operand:DI 0 "register_operand" "")
17469 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17470 UNSPEC_FIST_FLOOR))
17471 (use (match_operand:HI 2 "memory_operand" ""))
17472 (use (match_operand:HI 3 "memory_operand" ""))
17473 (clobber (match_operand:DI 4 "memory_operand" ""))
17474 (clobber (match_scratch 5 ""))]
17476 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17477 (use (match_dup 2))
17478 (use (match_dup 3))
17479 (clobber (match_dup 5))])
17480 (set (match_dup 0) (match_dup 4))]
17484 [(set (match_operand:DI 0 "memory_operand" "")
17485 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17486 UNSPEC_FIST_FLOOR))
17487 (use (match_operand:HI 2 "memory_operand" ""))
17488 (use (match_operand:HI 3 "memory_operand" ""))
17489 (clobber (match_operand:DI 4 "memory_operand" ""))
17490 (clobber (match_scratch 5 ""))]
17492 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17493 (use (match_dup 2))
17494 (use (match_dup 3))
17495 (clobber (match_dup 5))])]
17498 (define_insn "fist<mode>2_floor"
17499 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17500 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17501 UNSPEC_FIST_FLOOR))
17502 (use (match_operand:HI 2 "memory_operand" "m"))
17503 (use (match_operand:HI 3 "memory_operand" "m"))]
17504 "TARGET_USE_FANCY_MATH_387
17505 && flag_unsafe_math_optimizations"
17506 "* return output_fix_trunc (insn, operands, 0);"
17507 [(set_attr "type" "fistp")
17508 (set_attr "i387_cw" "floor")
17509 (set_attr "mode" "<MODE>")])
17511 (define_insn "fist<mode>2_floor_with_temp"
17512 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17513 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17514 UNSPEC_FIST_FLOOR))
17515 (use (match_operand:HI 2 "memory_operand" "m,m"))
17516 (use (match_operand:HI 3 "memory_operand" "m,m"))
17517 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17518 "TARGET_USE_FANCY_MATH_387
17519 && flag_unsafe_math_optimizations"
17521 [(set_attr "type" "fistp")
17522 (set_attr "i387_cw" "floor")
17523 (set_attr "mode" "<MODE>")])
17526 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17527 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17528 UNSPEC_FIST_FLOOR))
17529 (use (match_operand:HI 2 "memory_operand" ""))
17530 (use (match_operand:HI 3 "memory_operand" ""))
17531 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17533 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17534 UNSPEC_FIST_FLOOR))
17535 (use (match_dup 2))
17536 (use (match_dup 3))])
17537 (set (match_dup 0) (match_dup 4))]
17541 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17542 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17543 UNSPEC_FIST_FLOOR))
17544 (use (match_operand:HI 2 "memory_operand" ""))
17545 (use (match_operand:HI 3 "memory_operand" ""))
17546 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17548 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17549 UNSPEC_FIST_FLOOR))
17550 (use (match_dup 2))
17551 (use (match_dup 3))])]
17554 (define_expand "lfloor<mode>2"
17555 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17556 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17557 UNSPEC_FIST_FLOOR))
17558 (clobber (reg:CC FLAGS_REG))])]
17559 "TARGET_USE_FANCY_MATH_387
17560 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17561 && flag_unsafe_math_optimizations"
17564 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17565 (define_insn_and_split "frndintxf2_ceil"
17566 [(set (match_operand:XF 0 "register_operand" "=f")
17567 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17568 UNSPEC_FRNDINT_CEIL))
17569 (clobber (reg:CC FLAGS_REG))]
17570 "TARGET_USE_FANCY_MATH_387
17571 && flag_unsafe_math_optimizations
17572 && !(reload_completed || reload_in_progress)"
17577 ix86_optimize_mode_switching[I387_CEIL] = 1;
17579 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17580 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17582 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17583 operands[2], operands[3]));
17586 [(set_attr "type" "frndint")
17587 (set_attr "i387_cw" "ceil")
17588 (set_attr "mode" "XF")])
17590 (define_insn "frndintxf2_ceil_i387"
17591 [(set (match_operand:XF 0 "register_operand" "=f")
17592 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17593 UNSPEC_FRNDINT_CEIL))
17594 (use (match_operand:HI 2 "memory_operand" "m"))
17595 (use (match_operand:HI 3 "memory_operand" "m"))]
17596 "TARGET_USE_FANCY_MATH_387
17597 && flag_unsafe_math_optimizations"
17598 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17599 [(set_attr "type" "frndint")
17600 (set_attr "i387_cw" "ceil")
17601 (set_attr "mode" "XF")])
17603 (define_expand "ceilxf2"
17604 [(use (match_operand:XF 0 "register_operand" ""))
17605 (use (match_operand:XF 1 "register_operand" ""))]
17606 "TARGET_USE_FANCY_MATH_387
17607 && flag_unsafe_math_optimizations"
17609 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17613 (define_expand "ceildf2"
17614 [(use (match_operand:DF 0 "register_operand" ""))
17615 (use (match_operand:DF 1 "register_operand" ""))]
17616 "TARGET_USE_FANCY_MATH_387
17617 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17618 && flag_unsafe_math_optimizations"
17620 rtx op0 = gen_reg_rtx (XFmode);
17621 rtx op1 = gen_reg_rtx (XFmode);
17623 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17624 emit_insn (gen_frndintxf2_ceil (op0, op1));
17626 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17630 (define_expand "ceilsf2"
17631 [(use (match_operand:SF 0 "register_operand" ""))
17632 (use (match_operand:SF 1 "register_operand" ""))]
17633 "TARGET_USE_FANCY_MATH_387
17634 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17635 && flag_unsafe_math_optimizations"
17637 rtx op0 = gen_reg_rtx (XFmode);
17638 rtx op1 = gen_reg_rtx (XFmode);
17640 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17641 emit_insn (gen_frndintxf2_ceil (op0, op1));
17643 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17647 (define_insn_and_split "*fist<mode>2_ceil_1"
17648 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17649 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17651 (clobber (reg:CC FLAGS_REG))]
17652 "TARGET_USE_FANCY_MATH_387
17653 && flag_unsafe_math_optimizations
17654 && !(reload_completed || reload_in_progress)"
17659 ix86_optimize_mode_switching[I387_CEIL] = 1;
17661 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17662 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17663 if (memory_operand (operands[0], VOIDmode))
17664 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17665 operands[2], operands[3]));
17668 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17669 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17670 operands[2], operands[3],
17675 [(set_attr "type" "fistp")
17676 (set_attr "i387_cw" "ceil")
17677 (set_attr "mode" "<MODE>")])
17679 (define_insn "fistdi2_ceil"
17680 [(set (match_operand:DI 0 "memory_operand" "=m")
17681 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17683 (use (match_operand:HI 2 "memory_operand" "m"))
17684 (use (match_operand:HI 3 "memory_operand" "m"))
17685 (clobber (match_scratch:XF 4 "=&1f"))]
17686 "TARGET_USE_FANCY_MATH_387
17687 && flag_unsafe_math_optimizations"
17688 "* return output_fix_trunc (insn, operands, 0);"
17689 [(set_attr "type" "fistp")
17690 (set_attr "i387_cw" "ceil")
17691 (set_attr "mode" "DI")])
17693 (define_insn "fistdi2_ceil_with_temp"
17694 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17695 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17697 (use (match_operand:HI 2 "memory_operand" "m,m"))
17698 (use (match_operand:HI 3 "memory_operand" "m,m"))
17699 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17700 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17701 "TARGET_USE_FANCY_MATH_387
17702 && flag_unsafe_math_optimizations"
17704 [(set_attr "type" "fistp")
17705 (set_attr "i387_cw" "ceil")
17706 (set_attr "mode" "DI")])
17709 [(set (match_operand:DI 0 "register_operand" "")
17710 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17712 (use (match_operand:HI 2 "memory_operand" ""))
17713 (use (match_operand:HI 3 "memory_operand" ""))
17714 (clobber (match_operand:DI 4 "memory_operand" ""))
17715 (clobber (match_scratch 5 ""))]
17717 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17718 (use (match_dup 2))
17719 (use (match_dup 3))
17720 (clobber (match_dup 5))])
17721 (set (match_dup 0) (match_dup 4))]
17725 [(set (match_operand:DI 0 "memory_operand" "")
17726 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17728 (use (match_operand:HI 2 "memory_operand" ""))
17729 (use (match_operand:HI 3 "memory_operand" ""))
17730 (clobber (match_operand:DI 4 "memory_operand" ""))
17731 (clobber (match_scratch 5 ""))]
17733 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17734 (use (match_dup 2))
17735 (use (match_dup 3))
17736 (clobber (match_dup 5))])]
17739 (define_insn "fist<mode>2_ceil"
17740 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17741 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17743 (use (match_operand:HI 2 "memory_operand" "m"))
17744 (use (match_operand:HI 3 "memory_operand" "m"))]
17745 "TARGET_USE_FANCY_MATH_387
17746 && flag_unsafe_math_optimizations"
17747 "* return output_fix_trunc (insn, operands, 0);"
17748 [(set_attr "type" "fistp")
17749 (set_attr "i387_cw" "ceil")
17750 (set_attr "mode" "<MODE>")])
17752 (define_insn "fist<mode>2_ceil_with_temp"
17753 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17754 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17756 (use (match_operand:HI 2 "memory_operand" "m,m"))
17757 (use (match_operand:HI 3 "memory_operand" "m,m"))
17758 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17759 "TARGET_USE_FANCY_MATH_387
17760 && flag_unsafe_math_optimizations"
17762 [(set_attr "type" "fistp")
17763 (set_attr "i387_cw" "ceil")
17764 (set_attr "mode" "<MODE>")])
17767 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17768 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17770 (use (match_operand:HI 2 "memory_operand" ""))
17771 (use (match_operand:HI 3 "memory_operand" ""))
17772 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17774 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17776 (use (match_dup 2))
17777 (use (match_dup 3))])
17778 (set (match_dup 0) (match_dup 4))]
17782 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17783 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17785 (use (match_operand:HI 2 "memory_operand" ""))
17786 (use (match_operand:HI 3 "memory_operand" ""))
17787 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17789 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17791 (use (match_dup 2))
17792 (use (match_dup 3))])]
17795 (define_expand "lceil<mode>2"
17796 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17797 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17799 (clobber (reg:CC FLAGS_REG))])]
17800 "TARGET_USE_FANCY_MATH_387
17801 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17802 && flag_unsafe_math_optimizations"
17805 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17806 (define_insn_and_split "frndintxf2_trunc"
17807 [(set (match_operand:XF 0 "register_operand" "=f")
17808 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17809 UNSPEC_FRNDINT_TRUNC))
17810 (clobber (reg:CC FLAGS_REG))]
17811 "TARGET_USE_FANCY_MATH_387
17812 && flag_unsafe_math_optimizations
17813 && !(reload_completed || reload_in_progress)"
17818 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17820 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17821 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17823 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17824 operands[2], operands[3]));
17827 [(set_attr "type" "frndint")
17828 (set_attr "i387_cw" "trunc")
17829 (set_attr "mode" "XF")])
17831 (define_insn "frndintxf2_trunc_i387"
17832 [(set (match_operand:XF 0 "register_operand" "=f")
17833 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17834 UNSPEC_FRNDINT_TRUNC))
17835 (use (match_operand:HI 2 "memory_operand" "m"))
17836 (use (match_operand:HI 3 "memory_operand" "m"))]
17837 "TARGET_USE_FANCY_MATH_387
17838 && flag_unsafe_math_optimizations"
17839 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17840 [(set_attr "type" "frndint")
17841 (set_attr "i387_cw" "trunc")
17842 (set_attr "mode" "XF")])
17844 (define_expand "btruncxf2"
17845 [(use (match_operand:XF 0 "register_operand" ""))
17846 (use (match_operand:XF 1 "register_operand" ""))]
17847 "TARGET_USE_FANCY_MATH_387
17848 && flag_unsafe_math_optimizations"
17850 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17854 (define_expand "btruncdf2"
17855 [(use (match_operand:DF 0 "register_operand" ""))
17856 (use (match_operand:DF 1 "register_operand" ""))]
17857 "TARGET_USE_FANCY_MATH_387
17858 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17859 && flag_unsafe_math_optimizations"
17861 rtx op0 = gen_reg_rtx (XFmode);
17862 rtx op1 = gen_reg_rtx (XFmode);
17864 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17865 emit_insn (gen_frndintxf2_trunc (op0, op1));
17867 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17871 (define_expand "btruncsf2"
17872 [(use (match_operand:SF 0 "register_operand" ""))
17873 (use (match_operand:SF 1 "register_operand" ""))]
17874 "TARGET_USE_FANCY_MATH_387
17875 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17876 && flag_unsafe_math_optimizations"
17878 rtx op0 = gen_reg_rtx (XFmode);
17879 rtx op1 = gen_reg_rtx (XFmode);
17881 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17882 emit_insn (gen_frndintxf2_trunc (op0, op1));
17884 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17888 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17889 (define_insn_and_split "frndintxf2_mask_pm"
17890 [(set (match_operand:XF 0 "register_operand" "=f")
17891 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17892 UNSPEC_FRNDINT_MASK_PM))
17893 (clobber (reg:CC FLAGS_REG))]
17894 "TARGET_USE_FANCY_MATH_387
17895 && flag_unsafe_math_optimizations
17896 && !(reload_completed || reload_in_progress)"
17901 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17903 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17904 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17906 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17907 operands[2], operands[3]));
17910 [(set_attr "type" "frndint")
17911 (set_attr "i387_cw" "mask_pm")
17912 (set_attr "mode" "XF")])
17914 (define_insn "frndintxf2_mask_pm_i387"
17915 [(set (match_operand:XF 0 "register_operand" "=f")
17916 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17917 UNSPEC_FRNDINT_MASK_PM))
17918 (use (match_operand:HI 2 "memory_operand" "m"))
17919 (use (match_operand:HI 3 "memory_operand" "m"))]
17920 "TARGET_USE_FANCY_MATH_387
17921 && flag_unsafe_math_optimizations"
17922 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17923 [(set_attr "type" "frndint")
17924 (set_attr "i387_cw" "mask_pm")
17925 (set_attr "mode" "XF")])
17927 (define_expand "nearbyintxf2"
17928 [(use (match_operand:XF 0 "register_operand" ""))
17929 (use (match_operand:XF 1 "register_operand" ""))]
17930 "TARGET_USE_FANCY_MATH_387
17931 && flag_unsafe_math_optimizations"
17933 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17938 (define_expand "nearbyintdf2"
17939 [(use (match_operand:DF 0 "register_operand" ""))
17940 (use (match_operand:DF 1 "register_operand" ""))]
17941 "TARGET_USE_FANCY_MATH_387
17942 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17943 && flag_unsafe_math_optimizations"
17945 rtx op0 = gen_reg_rtx (XFmode);
17946 rtx op1 = gen_reg_rtx (XFmode);
17948 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17949 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17951 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17955 (define_expand "nearbyintsf2"
17956 [(use (match_operand:SF 0 "register_operand" ""))
17957 (use (match_operand:SF 1 "register_operand" ""))]
17958 "TARGET_USE_FANCY_MATH_387
17959 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17960 && flag_unsafe_math_optimizations"
17962 rtx op0 = gen_reg_rtx (XFmode);
17963 rtx op1 = gen_reg_rtx (XFmode);
17965 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17966 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17968 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17973 ;; Block operation instructions
17976 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17979 [(set_attr "type" "cld")])
17981 (define_expand "movmemsi"
17982 [(use (match_operand:BLK 0 "memory_operand" ""))
17983 (use (match_operand:BLK 1 "memory_operand" ""))
17984 (use (match_operand:SI 2 "nonmemory_operand" ""))
17985 (use (match_operand:SI 3 "const_int_operand" ""))]
17986 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17988 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17994 (define_expand "movmemdi"
17995 [(use (match_operand:BLK 0 "memory_operand" ""))
17996 (use (match_operand:BLK 1 "memory_operand" ""))
17997 (use (match_operand:DI 2 "nonmemory_operand" ""))
17998 (use (match_operand:DI 3 "const_int_operand" ""))]
18001 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18007 ;; Most CPUs don't like single string operations
18008 ;; Handle this case here to simplify previous expander.
18010 (define_expand "strmov"
18011 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18012 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18013 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18014 (clobber (reg:CC FLAGS_REG))])
18015 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18016 (clobber (reg:CC FLAGS_REG))])]
18019 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18021 /* If .md ever supports :P for Pmode, these can be directly
18022 in the pattern above. */
18023 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18024 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18026 if (TARGET_SINGLE_STRINGOP || optimize_size)
18028 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18029 operands[2], operands[3],
18030 operands[5], operands[6]));
18034 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18037 (define_expand "strmov_singleop"
18038 [(parallel [(set (match_operand 1 "memory_operand" "")
18039 (match_operand 3 "memory_operand" ""))
18040 (set (match_operand 0 "register_operand" "")
18041 (match_operand 4 "" ""))
18042 (set (match_operand 2 "register_operand" "")
18043 (match_operand 5 "" ""))
18044 (use (reg:SI DIRFLAG_REG))])]
18045 "TARGET_SINGLE_STRINGOP || optimize_size"
18048 (define_insn "*strmovdi_rex_1"
18049 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18050 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18051 (set (match_operand:DI 0 "register_operand" "=D")
18052 (plus:DI (match_dup 2)
18054 (set (match_operand:DI 1 "register_operand" "=S")
18055 (plus:DI (match_dup 3)
18057 (use (reg:SI DIRFLAG_REG))]
18058 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18060 [(set_attr "type" "str")
18061 (set_attr "mode" "DI")
18062 (set_attr "memory" "both")])
18064 (define_insn "*strmovsi_1"
18065 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18066 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18067 (set (match_operand:SI 0 "register_operand" "=D")
18068 (plus:SI (match_dup 2)
18070 (set (match_operand:SI 1 "register_operand" "=S")
18071 (plus:SI (match_dup 3)
18073 (use (reg:SI DIRFLAG_REG))]
18074 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18076 [(set_attr "type" "str")
18077 (set_attr "mode" "SI")
18078 (set_attr "memory" "both")])
18080 (define_insn "*strmovsi_rex_1"
18081 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18082 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18083 (set (match_operand:DI 0 "register_operand" "=D")
18084 (plus:DI (match_dup 2)
18086 (set (match_operand:DI 1 "register_operand" "=S")
18087 (plus:DI (match_dup 3)
18089 (use (reg:SI DIRFLAG_REG))]
18090 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18092 [(set_attr "type" "str")
18093 (set_attr "mode" "SI")
18094 (set_attr "memory" "both")])
18096 (define_insn "*strmovhi_1"
18097 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18098 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18099 (set (match_operand:SI 0 "register_operand" "=D")
18100 (plus:SI (match_dup 2)
18102 (set (match_operand:SI 1 "register_operand" "=S")
18103 (plus:SI (match_dup 3)
18105 (use (reg:SI DIRFLAG_REG))]
18106 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18108 [(set_attr "type" "str")
18109 (set_attr "memory" "both")
18110 (set_attr "mode" "HI")])
18112 (define_insn "*strmovhi_rex_1"
18113 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18114 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18115 (set (match_operand:DI 0 "register_operand" "=D")
18116 (plus:DI (match_dup 2)
18118 (set (match_operand:DI 1 "register_operand" "=S")
18119 (plus:DI (match_dup 3)
18121 (use (reg:SI DIRFLAG_REG))]
18122 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18124 [(set_attr "type" "str")
18125 (set_attr "memory" "both")
18126 (set_attr "mode" "HI")])
18128 (define_insn "*strmovqi_1"
18129 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18130 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18131 (set (match_operand:SI 0 "register_operand" "=D")
18132 (plus:SI (match_dup 2)
18134 (set (match_operand:SI 1 "register_operand" "=S")
18135 (plus:SI (match_dup 3)
18137 (use (reg:SI DIRFLAG_REG))]
18138 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18140 [(set_attr "type" "str")
18141 (set_attr "memory" "both")
18142 (set_attr "mode" "QI")])
18144 (define_insn "*strmovqi_rex_1"
18145 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18146 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18147 (set (match_operand:DI 0 "register_operand" "=D")
18148 (plus:DI (match_dup 2)
18150 (set (match_operand:DI 1 "register_operand" "=S")
18151 (plus:DI (match_dup 3)
18153 (use (reg:SI DIRFLAG_REG))]
18154 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18156 [(set_attr "type" "str")
18157 (set_attr "memory" "both")
18158 (set_attr "mode" "QI")])
18160 (define_expand "rep_mov"
18161 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18162 (set (match_operand 0 "register_operand" "")
18163 (match_operand 5 "" ""))
18164 (set (match_operand 2 "register_operand" "")
18165 (match_operand 6 "" ""))
18166 (set (match_operand 1 "memory_operand" "")
18167 (match_operand 3 "memory_operand" ""))
18168 (use (match_dup 4))
18169 (use (reg:SI DIRFLAG_REG))])]
18173 (define_insn "*rep_movdi_rex64"
18174 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18175 (set (match_operand:DI 0 "register_operand" "=D")
18176 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18178 (match_operand:DI 3 "register_operand" "0")))
18179 (set (match_operand:DI 1 "register_operand" "=S")
18180 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18181 (match_operand:DI 4 "register_operand" "1")))
18182 (set (mem:BLK (match_dup 3))
18183 (mem:BLK (match_dup 4)))
18184 (use (match_dup 5))
18185 (use (reg:SI DIRFLAG_REG))]
18187 "{rep\;movsq|rep movsq}"
18188 [(set_attr "type" "str")
18189 (set_attr "prefix_rep" "1")
18190 (set_attr "memory" "both")
18191 (set_attr "mode" "DI")])
18193 (define_insn "*rep_movsi"
18194 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18195 (set (match_operand:SI 0 "register_operand" "=D")
18196 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18198 (match_operand:SI 3 "register_operand" "0")))
18199 (set (match_operand:SI 1 "register_operand" "=S")
18200 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18201 (match_operand:SI 4 "register_operand" "1")))
18202 (set (mem:BLK (match_dup 3))
18203 (mem:BLK (match_dup 4)))
18204 (use (match_dup 5))
18205 (use (reg:SI DIRFLAG_REG))]
18207 "{rep\;movsl|rep movsd}"
18208 [(set_attr "type" "str")
18209 (set_attr "prefix_rep" "1")
18210 (set_attr "memory" "both")
18211 (set_attr "mode" "SI")])
18213 (define_insn "*rep_movsi_rex64"
18214 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18215 (set (match_operand:DI 0 "register_operand" "=D")
18216 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18218 (match_operand:DI 3 "register_operand" "0")))
18219 (set (match_operand:DI 1 "register_operand" "=S")
18220 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18221 (match_operand:DI 4 "register_operand" "1")))
18222 (set (mem:BLK (match_dup 3))
18223 (mem:BLK (match_dup 4)))
18224 (use (match_dup 5))
18225 (use (reg:SI DIRFLAG_REG))]
18227 "{rep\;movsl|rep movsd}"
18228 [(set_attr "type" "str")
18229 (set_attr "prefix_rep" "1")
18230 (set_attr "memory" "both")
18231 (set_attr "mode" "SI")])
18233 (define_insn "*rep_movqi"
18234 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18235 (set (match_operand:SI 0 "register_operand" "=D")
18236 (plus:SI (match_operand:SI 3 "register_operand" "0")
18237 (match_operand:SI 5 "register_operand" "2")))
18238 (set (match_operand:SI 1 "register_operand" "=S")
18239 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18240 (set (mem:BLK (match_dup 3))
18241 (mem:BLK (match_dup 4)))
18242 (use (match_dup 5))
18243 (use (reg:SI DIRFLAG_REG))]
18245 "{rep\;movsb|rep movsb}"
18246 [(set_attr "type" "str")
18247 (set_attr "prefix_rep" "1")
18248 (set_attr "memory" "both")
18249 (set_attr "mode" "SI")])
18251 (define_insn "*rep_movqi_rex64"
18252 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18253 (set (match_operand:DI 0 "register_operand" "=D")
18254 (plus:DI (match_operand:DI 3 "register_operand" "0")
18255 (match_operand:DI 5 "register_operand" "2")))
18256 (set (match_operand:DI 1 "register_operand" "=S")
18257 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18258 (set (mem:BLK (match_dup 3))
18259 (mem:BLK (match_dup 4)))
18260 (use (match_dup 5))
18261 (use (reg:SI DIRFLAG_REG))]
18263 "{rep\;movsb|rep movsb}"
18264 [(set_attr "type" "str")
18265 (set_attr "prefix_rep" "1")
18266 (set_attr "memory" "both")
18267 (set_attr "mode" "SI")])
18269 (define_expand "setmemsi"
18270 [(use (match_operand:BLK 0 "memory_operand" ""))
18271 (use (match_operand:SI 1 "nonmemory_operand" ""))
18272 (use (match_operand 2 "const_int_operand" ""))
18273 (use (match_operand 3 "const_int_operand" ""))]
18276 /* If value to set is not zero, use the library routine. */
18277 if (operands[2] != const0_rtx)
18280 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18286 (define_expand "setmemdi"
18287 [(use (match_operand:BLK 0 "memory_operand" ""))
18288 (use (match_operand:DI 1 "nonmemory_operand" ""))
18289 (use (match_operand 2 "const_int_operand" ""))
18290 (use (match_operand 3 "const_int_operand" ""))]
18293 /* If value to set is not zero, use the library routine. */
18294 if (operands[2] != const0_rtx)
18297 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18303 ;; Most CPUs don't like single string operations
18304 ;; Handle this case here to simplify previous expander.
18306 (define_expand "strset"
18307 [(set (match_operand 1 "memory_operand" "")
18308 (match_operand 2 "register_operand" ""))
18309 (parallel [(set (match_operand 0 "register_operand" "")
18311 (clobber (reg:CC FLAGS_REG))])]
18314 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18315 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18317 /* If .md ever supports :P for Pmode, this can be directly
18318 in the pattern above. */
18319 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18320 GEN_INT (GET_MODE_SIZE (GET_MODE
18322 if (TARGET_SINGLE_STRINGOP || optimize_size)
18324 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18330 (define_expand "strset_singleop"
18331 [(parallel [(set (match_operand 1 "memory_operand" "")
18332 (match_operand 2 "register_operand" ""))
18333 (set (match_operand 0 "register_operand" "")
18334 (match_operand 3 "" ""))
18335 (use (reg:SI DIRFLAG_REG))])]
18336 "TARGET_SINGLE_STRINGOP || optimize_size"
18339 (define_insn "*strsetdi_rex_1"
18340 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18341 (match_operand:DI 2 "register_operand" "a"))
18342 (set (match_operand:DI 0 "register_operand" "=D")
18343 (plus:DI (match_dup 1)
18345 (use (reg:SI DIRFLAG_REG))]
18346 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18348 [(set_attr "type" "str")
18349 (set_attr "memory" "store")
18350 (set_attr "mode" "DI")])
18352 (define_insn "*strsetsi_1"
18353 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18354 (match_operand:SI 2 "register_operand" "a"))
18355 (set (match_operand:SI 0 "register_operand" "=D")
18356 (plus:SI (match_dup 1)
18358 (use (reg:SI DIRFLAG_REG))]
18359 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18361 [(set_attr "type" "str")
18362 (set_attr "memory" "store")
18363 (set_attr "mode" "SI")])
18365 (define_insn "*strsetsi_rex_1"
18366 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18367 (match_operand:SI 2 "register_operand" "a"))
18368 (set (match_operand:DI 0 "register_operand" "=D")
18369 (plus:DI (match_dup 1)
18371 (use (reg:SI DIRFLAG_REG))]
18372 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18374 [(set_attr "type" "str")
18375 (set_attr "memory" "store")
18376 (set_attr "mode" "SI")])
18378 (define_insn "*strsethi_1"
18379 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18380 (match_operand:HI 2 "register_operand" "a"))
18381 (set (match_operand:SI 0 "register_operand" "=D")
18382 (plus:SI (match_dup 1)
18384 (use (reg:SI DIRFLAG_REG))]
18385 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18387 [(set_attr "type" "str")
18388 (set_attr "memory" "store")
18389 (set_attr "mode" "HI")])
18391 (define_insn "*strsethi_rex_1"
18392 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18393 (match_operand:HI 2 "register_operand" "a"))
18394 (set (match_operand:DI 0 "register_operand" "=D")
18395 (plus:DI (match_dup 1)
18397 (use (reg:SI DIRFLAG_REG))]
18398 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18400 [(set_attr "type" "str")
18401 (set_attr "memory" "store")
18402 (set_attr "mode" "HI")])
18404 (define_insn "*strsetqi_1"
18405 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18406 (match_operand:QI 2 "register_operand" "a"))
18407 (set (match_operand:SI 0 "register_operand" "=D")
18408 (plus:SI (match_dup 1)
18410 (use (reg:SI DIRFLAG_REG))]
18411 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18413 [(set_attr "type" "str")
18414 (set_attr "memory" "store")
18415 (set_attr "mode" "QI")])
18417 (define_insn "*strsetqi_rex_1"
18418 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18419 (match_operand:QI 2 "register_operand" "a"))
18420 (set (match_operand:DI 0 "register_operand" "=D")
18421 (plus:DI (match_dup 1)
18423 (use (reg:SI DIRFLAG_REG))]
18424 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18426 [(set_attr "type" "str")
18427 (set_attr "memory" "store")
18428 (set_attr "mode" "QI")])
18430 (define_expand "rep_stos"
18431 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18432 (set (match_operand 0 "register_operand" "")
18433 (match_operand 4 "" ""))
18434 (set (match_operand 2 "memory_operand" "") (const_int 0))
18435 (use (match_operand 3 "register_operand" ""))
18436 (use (match_dup 1))
18437 (use (reg:SI DIRFLAG_REG))])]
18441 (define_insn "*rep_stosdi_rex64"
18442 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18443 (set (match_operand:DI 0 "register_operand" "=D")
18444 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18446 (match_operand:DI 3 "register_operand" "0")))
18447 (set (mem:BLK (match_dup 3))
18449 (use (match_operand:DI 2 "register_operand" "a"))
18450 (use (match_dup 4))
18451 (use (reg:SI DIRFLAG_REG))]
18453 "{rep\;stosq|rep stosq}"
18454 [(set_attr "type" "str")
18455 (set_attr "prefix_rep" "1")
18456 (set_attr "memory" "store")
18457 (set_attr "mode" "DI")])
18459 (define_insn "*rep_stossi"
18460 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18461 (set (match_operand:SI 0 "register_operand" "=D")
18462 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18464 (match_operand:SI 3 "register_operand" "0")))
18465 (set (mem:BLK (match_dup 3))
18467 (use (match_operand:SI 2 "register_operand" "a"))
18468 (use (match_dup 4))
18469 (use (reg:SI DIRFLAG_REG))]
18471 "{rep\;stosl|rep stosd}"
18472 [(set_attr "type" "str")
18473 (set_attr "prefix_rep" "1")
18474 (set_attr "memory" "store")
18475 (set_attr "mode" "SI")])
18477 (define_insn "*rep_stossi_rex64"
18478 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18479 (set (match_operand:DI 0 "register_operand" "=D")
18480 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18482 (match_operand:DI 3 "register_operand" "0")))
18483 (set (mem:BLK (match_dup 3))
18485 (use (match_operand:SI 2 "register_operand" "a"))
18486 (use (match_dup 4))
18487 (use (reg:SI DIRFLAG_REG))]
18489 "{rep\;stosl|rep stosd}"
18490 [(set_attr "type" "str")
18491 (set_attr "prefix_rep" "1")
18492 (set_attr "memory" "store")
18493 (set_attr "mode" "SI")])
18495 (define_insn "*rep_stosqi"
18496 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18497 (set (match_operand:SI 0 "register_operand" "=D")
18498 (plus:SI (match_operand:SI 3 "register_operand" "0")
18499 (match_operand:SI 4 "register_operand" "1")))
18500 (set (mem:BLK (match_dup 3))
18502 (use (match_operand:QI 2 "register_operand" "a"))
18503 (use (match_dup 4))
18504 (use (reg:SI DIRFLAG_REG))]
18506 "{rep\;stosb|rep stosb}"
18507 [(set_attr "type" "str")
18508 (set_attr "prefix_rep" "1")
18509 (set_attr "memory" "store")
18510 (set_attr "mode" "QI")])
18512 (define_insn "*rep_stosqi_rex64"
18513 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18514 (set (match_operand:DI 0 "register_operand" "=D")
18515 (plus:DI (match_operand:DI 3 "register_operand" "0")
18516 (match_operand:DI 4 "register_operand" "1")))
18517 (set (mem:BLK (match_dup 3))
18519 (use (match_operand:QI 2 "register_operand" "a"))
18520 (use (match_dup 4))
18521 (use (reg:SI DIRFLAG_REG))]
18523 "{rep\;stosb|rep stosb}"
18524 [(set_attr "type" "str")
18525 (set_attr "prefix_rep" "1")
18526 (set_attr "memory" "store")
18527 (set_attr "mode" "QI")])
18529 (define_expand "cmpstrnsi"
18530 [(set (match_operand:SI 0 "register_operand" "")
18531 (compare:SI (match_operand:BLK 1 "general_operand" "")
18532 (match_operand:BLK 2 "general_operand" "")))
18533 (use (match_operand 3 "general_operand" ""))
18534 (use (match_operand 4 "immediate_operand" ""))]
18535 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18537 rtx addr1, addr2, out, outlow, count, countreg, align;
18539 /* Can't use this if the user has appropriated esi or edi. */
18540 if (global_regs[4] || global_regs[5])
18544 if (GET_CODE (out) != REG)
18545 out = gen_reg_rtx (SImode);
18547 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18548 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18549 if (addr1 != XEXP (operands[1], 0))
18550 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18551 if (addr2 != XEXP (operands[2], 0))
18552 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18554 count = operands[3];
18555 countreg = ix86_zero_extend_to_Pmode (count);
18557 /* %%% Iff we are testing strict equality, we can use known alignment
18558 to good advantage. This may be possible with combine, particularly
18559 once cc0 is dead. */
18560 align = operands[4];
18562 emit_insn (gen_cld ());
18563 if (GET_CODE (count) == CONST_INT)
18565 if (INTVAL (count) == 0)
18567 emit_move_insn (operands[0], const0_rtx);
18570 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18571 operands[1], operands[2]));
18576 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18578 emit_insn (gen_cmpsi_1 (countreg, countreg));
18579 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18580 operands[1], operands[2]));
18583 outlow = gen_lowpart (QImode, out);
18584 emit_insn (gen_cmpintqi (outlow));
18585 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18587 if (operands[0] != out)
18588 emit_move_insn (operands[0], out);
18593 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18595 (define_expand "cmpintqi"
18596 [(set (match_dup 1)
18597 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18599 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18600 (parallel [(set (match_operand:QI 0 "register_operand" "")
18601 (minus:QI (match_dup 1)
18603 (clobber (reg:CC FLAGS_REG))])]
18605 "operands[1] = gen_reg_rtx (QImode);
18606 operands[2] = gen_reg_rtx (QImode);")
18608 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18609 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18611 (define_expand "cmpstrnqi_nz_1"
18612 [(parallel [(set (reg:CC FLAGS_REG)
18613 (compare:CC (match_operand 4 "memory_operand" "")
18614 (match_operand 5 "memory_operand" "")))
18615 (use (match_operand 2 "register_operand" ""))
18616 (use (match_operand:SI 3 "immediate_operand" ""))
18617 (use (reg:SI DIRFLAG_REG))
18618 (clobber (match_operand 0 "register_operand" ""))
18619 (clobber (match_operand 1 "register_operand" ""))
18620 (clobber (match_dup 2))])]
18624 (define_insn "*cmpstrnqi_nz_1"
18625 [(set (reg:CC FLAGS_REG)
18626 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18627 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18628 (use (match_operand:SI 6 "register_operand" "2"))
18629 (use (match_operand:SI 3 "immediate_operand" "i"))
18630 (use (reg:SI DIRFLAG_REG))
18631 (clobber (match_operand:SI 0 "register_operand" "=S"))
18632 (clobber (match_operand:SI 1 "register_operand" "=D"))
18633 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18636 [(set_attr "type" "str")
18637 (set_attr "mode" "QI")
18638 (set_attr "prefix_rep" "1")])
18640 (define_insn "*cmpstrnqi_nz_rex_1"
18641 [(set (reg:CC FLAGS_REG)
18642 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18643 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18644 (use (match_operand:DI 6 "register_operand" "2"))
18645 (use (match_operand:SI 3 "immediate_operand" "i"))
18646 (use (reg:SI DIRFLAG_REG))
18647 (clobber (match_operand:DI 0 "register_operand" "=S"))
18648 (clobber (match_operand:DI 1 "register_operand" "=D"))
18649 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18652 [(set_attr "type" "str")
18653 (set_attr "mode" "QI")
18654 (set_attr "prefix_rep" "1")])
18656 ;; The same, but the count is not known to not be zero.
18658 (define_expand "cmpstrnqi_1"
18659 [(parallel [(set (reg:CC FLAGS_REG)
18660 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18662 (compare:CC (match_operand 4 "memory_operand" "")
18663 (match_operand 5 "memory_operand" ""))
18665 (use (match_operand:SI 3 "immediate_operand" ""))
18666 (use (reg:CC FLAGS_REG))
18667 (use (reg:SI DIRFLAG_REG))
18668 (clobber (match_operand 0 "register_operand" ""))
18669 (clobber (match_operand 1 "register_operand" ""))
18670 (clobber (match_dup 2))])]
18674 (define_insn "*cmpstrnqi_1"
18675 [(set (reg:CC FLAGS_REG)
18676 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18678 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18679 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18681 (use (match_operand:SI 3 "immediate_operand" "i"))
18682 (use (reg:CC FLAGS_REG))
18683 (use (reg:SI DIRFLAG_REG))
18684 (clobber (match_operand:SI 0 "register_operand" "=S"))
18685 (clobber (match_operand:SI 1 "register_operand" "=D"))
18686 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18689 [(set_attr "type" "str")
18690 (set_attr "mode" "QI")
18691 (set_attr "prefix_rep" "1")])
18693 (define_insn "*cmpstrnqi_rex_1"
18694 [(set (reg:CC FLAGS_REG)
18695 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18697 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18698 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18700 (use (match_operand:SI 3 "immediate_operand" "i"))
18701 (use (reg:CC FLAGS_REG))
18702 (use (reg:SI DIRFLAG_REG))
18703 (clobber (match_operand:DI 0 "register_operand" "=S"))
18704 (clobber (match_operand:DI 1 "register_operand" "=D"))
18705 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18708 [(set_attr "type" "str")
18709 (set_attr "mode" "QI")
18710 (set_attr "prefix_rep" "1")])
18712 (define_expand "strlensi"
18713 [(set (match_operand:SI 0 "register_operand" "")
18714 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18715 (match_operand:QI 2 "immediate_operand" "")
18716 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18719 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18725 (define_expand "strlendi"
18726 [(set (match_operand:DI 0 "register_operand" "")
18727 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18728 (match_operand:QI 2 "immediate_operand" "")
18729 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18732 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18738 (define_expand "strlenqi_1"
18739 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18740 (use (reg:SI DIRFLAG_REG))
18741 (clobber (match_operand 1 "register_operand" ""))
18742 (clobber (reg:CC FLAGS_REG))])]
18746 (define_insn "*strlenqi_1"
18747 [(set (match_operand:SI 0 "register_operand" "=&c")
18748 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18749 (match_operand:QI 2 "register_operand" "a")
18750 (match_operand:SI 3 "immediate_operand" "i")
18751 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18752 (use (reg:SI DIRFLAG_REG))
18753 (clobber (match_operand:SI 1 "register_operand" "=D"))
18754 (clobber (reg:CC FLAGS_REG))]
18757 [(set_attr "type" "str")
18758 (set_attr "mode" "QI")
18759 (set_attr "prefix_rep" "1")])
18761 (define_insn "*strlenqi_rex_1"
18762 [(set (match_operand:DI 0 "register_operand" "=&c")
18763 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18764 (match_operand:QI 2 "register_operand" "a")
18765 (match_operand:DI 3 "immediate_operand" "i")
18766 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18767 (use (reg:SI DIRFLAG_REG))
18768 (clobber (match_operand:DI 1 "register_operand" "=D"))
18769 (clobber (reg:CC FLAGS_REG))]
18772 [(set_attr "type" "str")
18773 (set_attr "mode" "QI")
18774 (set_attr "prefix_rep" "1")])
18776 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18777 ;; handled in combine, but it is not currently up to the task.
18778 ;; When used for their truth value, the cmpstrn* expanders generate
18787 ;; The intermediate three instructions are unnecessary.
18789 ;; This one handles cmpstrn*_nz_1...
18792 (set (reg:CC FLAGS_REG)
18793 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18794 (mem:BLK (match_operand 5 "register_operand" ""))))
18795 (use (match_operand 6 "register_operand" ""))
18796 (use (match_operand:SI 3 "immediate_operand" ""))
18797 (use (reg:SI DIRFLAG_REG))
18798 (clobber (match_operand 0 "register_operand" ""))
18799 (clobber (match_operand 1 "register_operand" ""))
18800 (clobber (match_operand 2 "register_operand" ""))])
18801 (set (match_operand:QI 7 "register_operand" "")
18802 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18803 (set (match_operand:QI 8 "register_operand" "")
18804 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18805 (set (reg FLAGS_REG)
18806 (compare (match_dup 7) (match_dup 8)))
18808 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18810 (set (reg:CC FLAGS_REG)
18811 (compare:CC (mem:BLK (match_dup 4))
18812 (mem:BLK (match_dup 5))))
18813 (use (match_dup 6))
18814 (use (match_dup 3))
18815 (use (reg:SI DIRFLAG_REG))
18816 (clobber (match_dup 0))
18817 (clobber (match_dup 1))
18818 (clobber (match_dup 2))])]
18821 ;; ...and this one handles cmpstrn*_1.
18824 (set (reg:CC FLAGS_REG)
18825 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18827 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18828 (mem:BLK (match_operand 5 "register_operand" "")))
18830 (use (match_operand:SI 3 "immediate_operand" ""))
18831 (use (reg:CC FLAGS_REG))
18832 (use (reg:SI DIRFLAG_REG))
18833 (clobber (match_operand 0 "register_operand" ""))
18834 (clobber (match_operand 1 "register_operand" ""))
18835 (clobber (match_operand 2 "register_operand" ""))])
18836 (set (match_operand:QI 7 "register_operand" "")
18837 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18838 (set (match_operand:QI 8 "register_operand" "")
18839 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18840 (set (reg FLAGS_REG)
18841 (compare (match_dup 7) (match_dup 8)))
18843 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18845 (set (reg:CC FLAGS_REG)
18846 (if_then_else:CC (ne (match_dup 6)
18848 (compare:CC (mem:BLK (match_dup 4))
18849 (mem:BLK (match_dup 5)))
18851 (use (match_dup 3))
18852 (use (reg:CC FLAGS_REG))
18853 (use (reg:SI DIRFLAG_REG))
18854 (clobber (match_dup 0))
18855 (clobber (match_dup 1))
18856 (clobber (match_dup 2))])]
18861 ;; Conditional move instructions.
18863 (define_expand "movdicc"
18864 [(set (match_operand:DI 0 "register_operand" "")
18865 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18866 (match_operand:DI 2 "general_operand" "")
18867 (match_operand:DI 3 "general_operand" "")))]
18869 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18871 (define_insn "x86_movdicc_0_m1_rex64"
18872 [(set (match_operand:DI 0 "register_operand" "=r")
18873 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18876 (clobber (reg:CC FLAGS_REG))]
18879 ; Since we don't have the proper number of operands for an alu insn,
18880 ; fill in all the blanks.
18881 [(set_attr "type" "alu")
18882 (set_attr "pent_pair" "pu")
18883 (set_attr "memory" "none")
18884 (set_attr "imm_disp" "false")
18885 (set_attr "mode" "DI")
18886 (set_attr "length_immediate" "0")])
18888 (define_insn "*movdicc_c_rex64"
18889 [(set (match_operand:DI 0 "register_operand" "=r,r")
18890 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18891 [(reg FLAGS_REG) (const_int 0)])
18892 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18893 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18894 "TARGET_64BIT && TARGET_CMOVE
18895 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18897 cmov%O2%C1\t{%2, %0|%0, %2}
18898 cmov%O2%c1\t{%3, %0|%0, %3}"
18899 [(set_attr "type" "icmov")
18900 (set_attr "mode" "DI")])
18902 (define_expand "movsicc"
18903 [(set (match_operand:SI 0 "register_operand" "")
18904 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18905 (match_operand:SI 2 "general_operand" "")
18906 (match_operand:SI 3 "general_operand" "")))]
18908 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18910 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18911 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18912 ;; So just document what we're doing explicitly.
18914 (define_insn "x86_movsicc_0_m1"
18915 [(set (match_operand:SI 0 "register_operand" "=r")
18916 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18919 (clobber (reg:CC FLAGS_REG))]
18922 ; Since we don't have the proper number of operands for an alu insn,
18923 ; fill in all the blanks.
18924 [(set_attr "type" "alu")
18925 (set_attr "pent_pair" "pu")
18926 (set_attr "memory" "none")
18927 (set_attr "imm_disp" "false")
18928 (set_attr "mode" "SI")
18929 (set_attr "length_immediate" "0")])
18931 (define_insn "*movsicc_noc"
18932 [(set (match_operand:SI 0 "register_operand" "=r,r")
18933 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18934 [(reg FLAGS_REG) (const_int 0)])
18935 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18936 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18938 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18940 cmov%O2%C1\t{%2, %0|%0, %2}
18941 cmov%O2%c1\t{%3, %0|%0, %3}"
18942 [(set_attr "type" "icmov")
18943 (set_attr "mode" "SI")])
18945 (define_expand "movhicc"
18946 [(set (match_operand:HI 0 "register_operand" "")
18947 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18948 (match_operand:HI 2 "general_operand" "")
18949 (match_operand:HI 3 "general_operand" "")))]
18950 "TARGET_HIMODE_MATH"
18951 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18953 (define_insn "*movhicc_noc"
18954 [(set (match_operand:HI 0 "register_operand" "=r,r")
18955 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18956 [(reg FLAGS_REG) (const_int 0)])
18957 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18958 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18960 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18962 cmov%O2%C1\t{%2, %0|%0, %2}
18963 cmov%O2%c1\t{%3, %0|%0, %3}"
18964 [(set_attr "type" "icmov")
18965 (set_attr "mode" "HI")])
18967 (define_expand "movqicc"
18968 [(set (match_operand:QI 0 "register_operand" "")
18969 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18970 (match_operand:QI 2 "general_operand" "")
18971 (match_operand:QI 3 "general_operand" "")))]
18972 "TARGET_QIMODE_MATH"
18973 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18975 (define_insn_and_split "*movqicc_noc"
18976 [(set (match_operand:QI 0 "register_operand" "=r,r")
18977 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18978 [(match_operand 4 "flags_reg_operand" "")
18980 (match_operand:QI 2 "register_operand" "r,0")
18981 (match_operand:QI 3 "register_operand" "0,r")))]
18982 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18984 "&& reload_completed"
18985 [(set (match_dup 0)
18986 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18989 "operands[0] = gen_lowpart (SImode, operands[0]);
18990 operands[2] = gen_lowpart (SImode, operands[2]);
18991 operands[3] = gen_lowpart (SImode, operands[3]);"
18992 [(set_attr "type" "icmov")
18993 (set_attr "mode" "SI")])
18995 (define_expand "movsfcc"
18996 [(set (match_operand:SF 0 "register_operand" "")
18997 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18998 (match_operand:SF 2 "register_operand" "")
18999 (match_operand:SF 3 "register_operand" "")))]
19000 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19001 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19003 (define_insn "*movsfcc_1_387"
19004 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19005 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19006 [(reg FLAGS_REG) (const_int 0)])
19007 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19008 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19009 "TARGET_80387 && TARGET_CMOVE
19010 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19012 fcmov%F1\t{%2, %0|%0, %2}
19013 fcmov%f1\t{%3, %0|%0, %3}
19014 cmov%O2%C1\t{%2, %0|%0, %2}
19015 cmov%O2%c1\t{%3, %0|%0, %3}"
19016 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19017 (set_attr "mode" "SF,SF,SI,SI")])
19019 (define_expand "movdfcc"
19020 [(set (match_operand:DF 0 "register_operand" "")
19021 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19022 (match_operand:DF 2 "register_operand" "")
19023 (match_operand:DF 3 "register_operand" "")))]
19024 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19025 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19027 (define_insn "*movdfcc_1"
19028 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19029 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19030 [(reg FLAGS_REG) (const_int 0)])
19031 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19032 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19033 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19034 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19036 fcmov%F1\t{%2, %0|%0, %2}
19037 fcmov%f1\t{%3, %0|%0, %3}
19040 [(set_attr "type" "fcmov,fcmov,multi,multi")
19041 (set_attr "mode" "DF")])
19043 (define_insn "*movdfcc_1_rex64"
19044 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19045 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19046 [(reg FLAGS_REG) (const_int 0)])
19047 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19048 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19049 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19050 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19052 fcmov%F1\t{%2, %0|%0, %2}
19053 fcmov%f1\t{%3, %0|%0, %3}
19054 cmov%O2%C1\t{%2, %0|%0, %2}
19055 cmov%O2%c1\t{%3, %0|%0, %3}"
19056 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19057 (set_attr "mode" "DF")])
19060 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19061 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19062 [(match_operand 4 "flags_reg_operand" "")
19064 (match_operand:DF 2 "nonimmediate_operand" "")
19065 (match_operand:DF 3 "nonimmediate_operand" "")))]
19066 "!TARGET_64BIT && reload_completed"
19067 [(set (match_dup 2)
19068 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19072 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19075 "split_di (operands+2, 1, operands+5, operands+6);
19076 split_di (operands+3, 1, operands+7, operands+8);
19077 split_di (operands, 1, operands+2, operands+3);")
19079 (define_expand "movxfcc"
19080 [(set (match_operand:XF 0 "register_operand" "")
19081 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19082 (match_operand:XF 2 "register_operand" "")
19083 (match_operand:XF 3 "register_operand" "")))]
19084 "TARGET_80387 && TARGET_CMOVE"
19085 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19087 (define_insn "*movxfcc_1"
19088 [(set (match_operand:XF 0 "register_operand" "=f,f")
19089 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19090 [(reg FLAGS_REG) (const_int 0)])
19091 (match_operand:XF 2 "register_operand" "f,0")
19092 (match_operand:XF 3 "register_operand" "0,f")))]
19093 "TARGET_80387 && TARGET_CMOVE"
19095 fcmov%F1\t{%2, %0|%0, %2}
19096 fcmov%f1\t{%3, %0|%0, %3}"
19097 [(set_attr "type" "fcmov")
19098 (set_attr "mode" "XF")])
19100 ;; These versions of the min/max patterns are intentionally ignorant of
19101 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19102 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19103 ;; are undefined in this condition, we're certain this is correct.
19105 (define_insn "sminsf3"
19106 [(set (match_operand:SF 0 "register_operand" "=x")
19107 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19108 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19110 "minss\t{%2, %0|%0, %2}"
19111 [(set_attr "type" "sseadd")
19112 (set_attr "mode" "SF")])
19114 (define_insn "smaxsf3"
19115 [(set (match_operand:SF 0 "register_operand" "=x")
19116 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19117 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19119 "maxss\t{%2, %0|%0, %2}"
19120 [(set_attr "type" "sseadd")
19121 (set_attr "mode" "SF")])
19123 (define_insn "smindf3"
19124 [(set (match_operand:DF 0 "register_operand" "=x")
19125 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19126 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19127 "TARGET_SSE2 && TARGET_SSE_MATH"
19128 "minsd\t{%2, %0|%0, %2}"
19129 [(set_attr "type" "sseadd")
19130 (set_attr "mode" "DF")])
19132 (define_insn "smaxdf3"
19133 [(set (match_operand:DF 0 "register_operand" "=x")
19134 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19135 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19136 "TARGET_SSE2 && TARGET_SSE_MATH"
19137 "maxsd\t{%2, %0|%0, %2}"
19138 [(set_attr "type" "sseadd")
19139 (set_attr "mode" "DF")])
19141 ;; These versions of the min/max patterns implement exactly the operations
19142 ;; min = (op1 < op2 ? op1 : op2)
19143 ;; max = (!(op1 < op2) ? op1 : op2)
19144 ;; Their operands are not commutative, and thus they may be used in the
19145 ;; presence of -0.0 and NaN.
19147 (define_insn "*ieee_sminsf3"
19148 [(set (match_operand:SF 0 "register_operand" "=x")
19149 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19150 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19153 "minss\t{%2, %0|%0, %2}"
19154 [(set_attr "type" "sseadd")
19155 (set_attr "mode" "SF")])
19157 (define_insn "*ieee_smaxsf3"
19158 [(set (match_operand:SF 0 "register_operand" "=x")
19159 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19160 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19163 "maxss\t{%2, %0|%0, %2}"
19164 [(set_attr "type" "sseadd")
19165 (set_attr "mode" "SF")])
19167 (define_insn "*ieee_smindf3"
19168 [(set (match_operand:DF 0 "register_operand" "=x")
19169 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19170 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19172 "TARGET_SSE2 && TARGET_SSE_MATH"
19173 "minsd\t{%2, %0|%0, %2}"
19174 [(set_attr "type" "sseadd")
19175 (set_attr "mode" "DF")])
19177 (define_insn "*ieee_smaxdf3"
19178 [(set (match_operand:DF 0 "register_operand" "=x")
19179 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19180 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19182 "TARGET_SSE2 && TARGET_SSE_MATH"
19183 "maxsd\t{%2, %0|%0, %2}"
19184 [(set_attr "type" "sseadd")
19185 (set_attr "mode" "DF")])
19187 ;; Make two stack loads independent:
19189 ;; fld %st(0) -> fld bb
19190 ;; fmul bb fmul %st(1), %st
19192 ;; Actually we only match the last two instructions for simplicity.
19194 [(set (match_operand 0 "fp_register_operand" "")
19195 (match_operand 1 "fp_register_operand" ""))
19197 (match_operator 2 "binary_fp_operator"
19199 (match_operand 3 "memory_operand" "")]))]
19200 "REGNO (operands[0]) != REGNO (operands[1])"
19201 [(set (match_dup 0) (match_dup 3))
19202 (set (match_dup 0) (match_dup 4))]
19204 ;; The % modifier is not operational anymore in peephole2's, so we have to
19205 ;; swap the operands manually in the case of addition and multiplication.
19206 "if (COMMUTATIVE_ARITH_P (operands[2]))
19207 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19208 operands[0], operands[1]);
19210 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19211 operands[1], operands[0]);")
19213 ;; Conditional addition patterns
19214 (define_expand "addqicc"
19215 [(match_operand:QI 0 "register_operand" "")
19216 (match_operand 1 "comparison_operator" "")
19217 (match_operand:QI 2 "register_operand" "")
19218 (match_operand:QI 3 "const_int_operand" "")]
19220 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19222 (define_expand "addhicc"
19223 [(match_operand:HI 0 "register_operand" "")
19224 (match_operand 1 "comparison_operator" "")
19225 (match_operand:HI 2 "register_operand" "")
19226 (match_operand:HI 3 "const_int_operand" "")]
19228 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19230 (define_expand "addsicc"
19231 [(match_operand:SI 0 "register_operand" "")
19232 (match_operand 1 "comparison_operator" "")
19233 (match_operand:SI 2 "register_operand" "")
19234 (match_operand:SI 3 "const_int_operand" "")]
19236 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19238 (define_expand "adddicc"
19239 [(match_operand:DI 0 "register_operand" "")
19240 (match_operand 1 "comparison_operator" "")
19241 (match_operand:DI 2 "register_operand" "")
19242 (match_operand:DI 3 "const_int_operand" "")]
19244 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19247 ;; Misc patterns (?)
19249 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19250 ;; Otherwise there will be nothing to keep
19252 ;; [(set (reg ebp) (reg esp))]
19253 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19254 ;; (clobber (eflags)]
19255 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19257 ;; in proper program order.
19258 (define_insn "pro_epilogue_adjust_stack_1"
19259 [(set (match_operand:SI 0 "register_operand" "=r,r")
19260 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19261 (match_operand:SI 2 "immediate_operand" "i,i")))
19262 (clobber (reg:CC FLAGS_REG))
19263 (clobber (mem:BLK (scratch)))]
19266 switch (get_attr_type (insn))
19269 return "mov{l}\t{%1, %0|%0, %1}";
19272 if (GET_CODE (operands[2]) == CONST_INT
19273 && (INTVAL (operands[2]) == 128
19274 || (INTVAL (operands[2]) < 0
19275 && INTVAL (operands[2]) != -128)))
19277 operands[2] = GEN_INT (-INTVAL (operands[2]));
19278 return "sub{l}\t{%2, %0|%0, %2}";
19280 return "add{l}\t{%2, %0|%0, %2}";
19283 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19284 return "lea{l}\t{%a2, %0|%0, %a2}";
19287 gcc_unreachable ();
19290 [(set (attr "type")
19291 (cond [(eq_attr "alternative" "0")
19292 (const_string "alu")
19293 (match_operand:SI 2 "const0_operand" "")
19294 (const_string "imov")
19296 (const_string "lea")))
19297 (set_attr "mode" "SI")])
19299 (define_insn "pro_epilogue_adjust_stack_rex64"
19300 [(set (match_operand:DI 0 "register_operand" "=r,r")
19301 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19302 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19303 (clobber (reg:CC FLAGS_REG))
19304 (clobber (mem:BLK (scratch)))]
19307 switch (get_attr_type (insn))
19310 return "mov{q}\t{%1, %0|%0, %1}";
19313 if (GET_CODE (operands[2]) == CONST_INT
19314 /* Avoid overflows. */
19315 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19316 && (INTVAL (operands[2]) == 128
19317 || (INTVAL (operands[2]) < 0
19318 && INTVAL (operands[2]) != -128)))
19320 operands[2] = GEN_INT (-INTVAL (operands[2]));
19321 return "sub{q}\t{%2, %0|%0, %2}";
19323 return "add{q}\t{%2, %0|%0, %2}";
19326 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19327 return "lea{q}\t{%a2, %0|%0, %a2}";
19330 gcc_unreachable ();
19333 [(set (attr "type")
19334 (cond [(eq_attr "alternative" "0")
19335 (const_string "alu")
19336 (match_operand:DI 2 "const0_operand" "")
19337 (const_string "imov")
19339 (const_string "lea")))
19340 (set_attr "mode" "DI")])
19342 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19343 [(set (match_operand:DI 0 "register_operand" "=r,r")
19344 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19345 (match_operand:DI 3 "immediate_operand" "i,i")))
19346 (use (match_operand:DI 2 "register_operand" "r,r"))
19347 (clobber (reg:CC FLAGS_REG))
19348 (clobber (mem:BLK (scratch)))]
19351 switch (get_attr_type (insn))
19354 return "add{q}\t{%2, %0|%0, %2}";
19357 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19358 return "lea{q}\t{%a2, %0|%0, %a2}";
19361 gcc_unreachable ();
19364 [(set_attr "type" "alu,lea")
19365 (set_attr "mode" "DI")])
19367 (define_expand "allocate_stack_worker"
19368 [(match_operand:SI 0 "register_operand" "")]
19369 "TARGET_STACK_PROBE"
19371 if (reload_completed)
19374 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19376 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19381 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19383 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19388 (define_insn "allocate_stack_worker_1"
19389 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19390 UNSPECV_STACK_PROBE)
19391 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19392 (clobber (match_scratch:SI 1 "=0"))
19393 (clobber (reg:CC FLAGS_REG))]
19394 "!TARGET_64BIT && TARGET_STACK_PROBE"
19396 [(set_attr "type" "multi")
19397 (set_attr "length" "5")])
19399 (define_expand "allocate_stack_worker_postreload"
19400 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19401 UNSPECV_STACK_PROBE)
19402 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19403 (clobber (match_dup 0))
19404 (clobber (reg:CC FLAGS_REG))])]
19408 (define_insn "allocate_stack_worker_rex64"
19409 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19410 UNSPECV_STACK_PROBE)
19411 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19412 (clobber (match_scratch:DI 1 "=0"))
19413 (clobber (reg:CC FLAGS_REG))]
19414 "TARGET_64BIT && TARGET_STACK_PROBE"
19416 [(set_attr "type" "multi")
19417 (set_attr "length" "5")])
19419 (define_expand "allocate_stack_worker_rex64_postreload"
19420 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19421 UNSPECV_STACK_PROBE)
19422 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19423 (clobber (match_dup 0))
19424 (clobber (reg:CC FLAGS_REG))])]
19428 (define_expand "allocate_stack"
19429 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19430 (minus:SI (reg:SI SP_REG)
19431 (match_operand:SI 1 "general_operand" "")))
19432 (clobber (reg:CC FLAGS_REG))])
19433 (parallel [(set (reg:SI SP_REG)
19434 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19435 (clobber (reg:CC FLAGS_REG))])]
19436 "TARGET_STACK_PROBE"
19438 #ifdef CHECK_STACK_LIMIT
19439 if (GET_CODE (operands[1]) == CONST_INT
19440 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19441 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19445 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19448 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19452 (define_expand "builtin_setjmp_receiver"
19453 [(label_ref (match_operand 0 "" ""))]
19454 "!TARGET_64BIT && flag_pic"
19459 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19460 rtx label_rtx = gen_label_rtx ();
19461 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19462 xops[0] = xops[1] = picreg;
19463 xops[2] = gen_rtx_CONST (SImode,
19464 gen_rtx_MINUS (SImode,
19465 gen_rtx_LABEL_REF (SImode, label_rtx),
19466 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19467 ix86_expand_binary_operator (MINUS, SImode, xops);
19470 emit_insn (gen_set_got (pic_offset_table_rtx));
19474 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19477 [(set (match_operand 0 "register_operand" "")
19478 (match_operator 3 "promotable_binary_operator"
19479 [(match_operand 1 "register_operand" "")
19480 (match_operand 2 "aligned_operand" "")]))
19481 (clobber (reg:CC FLAGS_REG))]
19482 "! TARGET_PARTIAL_REG_STALL && reload_completed
19483 && ((GET_MODE (operands[0]) == HImode
19484 && ((!optimize_size && !TARGET_FAST_PREFIX)
19485 /* ??? next two lines just !satisfies_constraint_K (...) */
19486 || GET_CODE (operands[2]) != CONST_INT
19487 || satisfies_constraint_K (operands[2])))
19488 || (GET_MODE (operands[0]) == QImode
19489 && (TARGET_PROMOTE_QImode || optimize_size)))"
19490 [(parallel [(set (match_dup 0)
19491 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19492 (clobber (reg:CC FLAGS_REG))])]
19493 "operands[0] = gen_lowpart (SImode, operands[0]);
19494 operands[1] = gen_lowpart (SImode, operands[1]);
19495 if (GET_CODE (operands[3]) != ASHIFT)
19496 operands[2] = gen_lowpart (SImode, operands[2]);
19497 PUT_MODE (operands[3], SImode);")
19499 ; Promote the QImode tests, as i386 has encoding of the AND
19500 ; instruction with 32-bit sign-extended immediate and thus the
19501 ; instruction size is unchanged, except in the %eax case for
19502 ; which it is increased by one byte, hence the ! optimize_size.
19504 [(set (match_operand 0 "flags_reg_operand" "")
19505 (match_operator 2 "compare_operator"
19506 [(and (match_operand 3 "aligned_operand" "")
19507 (match_operand 4 "const_int_operand" ""))
19509 (set (match_operand 1 "register_operand" "")
19510 (and (match_dup 3) (match_dup 4)))]
19511 "! TARGET_PARTIAL_REG_STALL && reload_completed
19512 /* Ensure that the operand will remain sign-extended immediate. */
19513 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19515 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19516 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19517 [(parallel [(set (match_dup 0)
19518 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19521 (and:SI (match_dup 3) (match_dup 4)))])]
19524 = gen_int_mode (INTVAL (operands[4])
19525 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19526 operands[1] = gen_lowpart (SImode, operands[1]);
19527 operands[3] = gen_lowpart (SImode, operands[3]);
19530 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19531 ; the TEST instruction with 32-bit sign-extended immediate and thus
19532 ; the instruction size would at least double, which is not what we
19533 ; want even with ! optimize_size.
19535 [(set (match_operand 0 "flags_reg_operand" "")
19536 (match_operator 1 "compare_operator"
19537 [(and (match_operand:HI 2 "aligned_operand" "")
19538 (match_operand:HI 3 "const_int_operand" ""))
19540 "! TARGET_PARTIAL_REG_STALL && reload_completed
19541 /* Ensure that the operand will remain sign-extended immediate. */
19542 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19543 && ! TARGET_FAST_PREFIX
19544 && ! optimize_size"
19545 [(set (match_dup 0)
19546 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19550 = gen_int_mode (INTVAL (operands[3])
19551 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19552 operands[2] = gen_lowpart (SImode, operands[2]);
19556 [(set (match_operand 0 "register_operand" "")
19557 (neg (match_operand 1 "register_operand" "")))
19558 (clobber (reg:CC FLAGS_REG))]
19559 "! TARGET_PARTIAL_REG_STALL && reload_completed
19560 && (GET_MODE (operands[0]) == HImode
19561 || (GET_MODE (operands[0]) == QImode
19562 && (TARGET_PROMOTE_QImode || optimize_size)))"
19563 [(parallel [(set (match_dup 0)
19564 (neg:SI (match_dup 1)))
19565 (clobber (reg:CC FLAGS_REG))])]
19566 "operands[0] = gen_lowpart (SImode, operands[0]);
19567 operands[1] = gen_lowpart (SImode, operands[1]);")
19570 [(set (match_operand 0 "register_operand" "")
19571 (not (match_operand 1 "register_operand" "")))]
19572 "! TARGET_PARTIAL_REG_STALL && reload_completed
19573 && (GET_MODE (operands[0]) == HImode
19574 || (GET_MODE (operands[0]) == QImode
19575 && (TARGET_PROMOTE_QImode || optimize_size)))"
19576 [(set (match_dup 0)
19577 (not:SI (match_dup 1)))]
19578 "operands[0] = gen_lowpart (SImode, operands[0]);
19579 operands[1] = gen_lowpart (SImode, operands[1]);")
19582 [(set (match_operand 0 "register_operand" "")
19583 (if_then_else (match_operator 1 "comparison_operator"
19584 [(reg FLAGS_REG) (const_int 0)])
19585 (match_operand 2 "register_operand" "")
19586 (match_operand 3 "register_operand" "")))]
19587 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19588 && (GET_MODE (operands[0]) == HImode
19589 || (GET_MODE (operands[0]) == QImode
19590 && (TARGET_PROMOTE_QImode || optimize_size)))"
19591 [(set (match_dup 0)
19592 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19593 "operands[0] = gen_lowpart (SImode, operands[0]);
19594 operands[2] = gen_lowpart (SImode, operands[2]);
19595 operands[3] = gen_lowpart (SImode, operands[3]);")
19598 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19599 ;; transform a complex memory operation into two memory to register operations.
19601 ;; Don't push memory operands
19603 [(set (match_operand:SI 0 "push_operand" "")
19604 (match_operand:SI 1 "memory_operand" ""))
19605 (match_scratch:SI 2 "r")]
19606 "!optimize_size && !TARGET_PUSH_MEMORY
19607 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19608 [(set (match_dup 2) (match_dup 1))
19609 (set (match_dup 0) (match_dup 2))]
19613 [(set (match_operand:DI 0 "push_operand" "")
19614 (match_operand:DI 1 "memory_operand" ""))
19615 (match_scratch:DI 2 "r")]
19616 "!optimize_size && !TARGET_PUSH_MEMORY
19617 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19618 [(set (match_dup 2) (match_dup 1))
19619 (set (match_dup 0) (match_dup 2))]
19622 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19625 [(set (match_operand:SF 0 "push_operand" "")
19626 (match_operand:SF 1 "memory_operand" ""))
19627 (match_scratch:SF 2 "r")]
19628 "!optimize_size && !TARGET_PUSH_MEMORY
19629 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19630 [(set (match_dup 2) (match_dup 1))
19631 (set (match_dup 0) (match_dup 2))]
19635 [(set (match_operand:HI 0 "push_operand" "")
19636 (match_operand:HI 1 "memory_operand" ""))
19637 (match_scratch:HI 2 "r")]
19638 "!optimize_size && !TARGET_PUSH_MEMORY
19639 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19640 [(set (match_dup 2) (match_dup 1))
19641 (set (match_dup 0) (match_dup 2))]
19645 [(set (match_operand:QI 0 "push_operand" "")
19646 (match_operand:QI 1 "memory_operand" ""))
19647 (match_scratch:QI 2 "q")]
19648 "!optimize_size && !TARGET_PUSH_MEMORY
19649 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19650 [(set (match_dup 2) (match_dup 1))
19651 (set (match_dup 0) (match_dup 2))]
19654 ;; Don't move an immediate directly to memory when the instruction
19657 [(match_scratch:SI 1 "r")
19658 (set (match_operand:SI 0 "memory_operand" "")
19661 && ! TARGET_USE_MOV0
19662 && TARGET_SPLIT_LONG_MOVES
19663 && get_attr_length (insn) >= ix86_cost->large_insn
19664 && peep2_regno_dead_p (0, FLAGS_REG)"
19665 [(parallel [(set (match_dup 1) (const_int 0))
19666 (clobber (reg:CC FLAGS_REG))])
19667 (set (match_dup 0) (match_dup 1))]
19671 [(match_scratch:HI 1 "r")
19672 (set (match_operand:HI 0 "memory_operand" "")
19675 && ! TARGET_USE_MOV0
19676 && TARGET_SPLIT_LONG_MOVES
19677 && get_attr_length (insn) >= ix86_cost->large_insn
19678 && peep2_regno_dead_p (0, FLAGS_REG)"
19679 [(parallel [(set (match_dup 2) (const_int 0))
19680 (clobber (reg:CC FLAGS_REG))])
19681 (set (match_dup 0) (match_dup 1))]
19682 "operands[2] = gen_lowpart (SImode, operands[1]);")
19685 [(match_scratch:QI 1 "q")
19686 (set (match_operand:QI 0 "memory_operand" "")
19689 && ! TARGET_USE_MOV0
19690 && TARGET_SPLIT_LONG_MOVES
19691 && get_attr_length (insn) >= ix86_cost->large_insn
19692 && peep2_regno_dead_p (0, FLAGS_REG)"
19693 [(parallel [(set (match_dup 2) (const_int 0))
19694 (clobber (reg:CC FLAGS_REG))])
19695 (set (match_dup 0) (match_dup 1))]
19696 "operands[2] = gen_lowpart (SImode, operands[1]);")
19699 [(match_scratch:SI 2 "r")
19700 (set (match_operand:SI 0 "memory_operand" "")
19701 (match_operand:SI 1 "immediate_operand" ""))]
19703 && get_attr_length (insn) >= ix86_cost->large_insn
19704 && TARGET_SPLIT_LONG_MOVES"
19705 [(set (match_dup 2) (match_dup 1))
19706 (set (match_dup 0) (match_dup 2))]
19710 [(match_scratch:HI 2 "r")
19711 (set (match_operand:HI 0 "memory_operand" "")
19712 (match_operand:HI 1 "immediate_operand" ""))]
19713 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19714 && TARGET_SPLIT_LONG_MOVES"
19715 [(set (match_dup 2) (match_dup 1))
19716 (set (match_dup 0) (match_dup 2))]
19720 [(match_scratch:QI 2 "q")
19721 (set (match_operand:QI 0 "memory_operand" "")
19722 (match_operand:QI 1 "immediate_operand" ""))]
19723 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19724 && TARGET_SPLIT_LONG_MOVES"
19725 [(set (match_dup 2) (match_dup 1))
19726 (set (match_dup 0) (match_dup 2))]
19729 ;; Don't compare memory with zero, load and use a test instead.
19731 [(set (match_operand 0 "flags_reg_operand" "")
19732 (match_operator 1 "compare_operator"
19733 [(match_operand:SI 2 "memory_operand" "")
19735 (match_scratch:SI 3 "r")]
19736 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19737 [(set (match_dup 3) (match_dup 2))
19738 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19741 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19742 ;; Don't split NOTs with a displacement operand, because resulting XOR
19743 ;; will not be pairable anyway.
19745 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19746 ;; represented using a modRM byte. The XOR replacement is long decoded,
19747 ;; so this split helps here as well.
19749 ;; Note: Can't do this as a regular split because we can't get proper
19750 ;; lifetime information then.
19753 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19754 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19756 && peep2_regno_dead_p (0, FLAGS_REG)
19757 && ((TARGET_PENTIUM
19758 && (GET_CODE (operands[0]) != MEM
19759 || !memory_displacement_operand (operands[0], SImode)))
19760 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19761 [(parallel [(set (match_dup 0)
19762 (xor:SI (match_dup 1) (const_int -1)))
19763 (clobber (reg:CC FLAGS_REG))])]
19767 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19768 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19770 && peep2_regno_dead_p (0, FLAGS_REG)
19771 && ((TARGET_PENTIUM
19772 && (GET_CODE (operands[0]) != MEM
19773 || !memory_displacement_operand (operands[0], HImode)))
19774 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19775 [(parallel [(set (match_dup 0)
19776 (xor:HI (match_dup 1) (const_int -1)))
19777 (clobber (reg:CC FLAGS_REG))])]
19781 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19782 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19784 && peep2_regno_dead_p (0, FLAGS_REG)
19785 && ((TARGET_PENTIUM
19786 && (GET_CODE (operands[0]) != MEM
19787 || !memory_displacement_operand (operands[0], QImode)))
19788 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19789 [(parallel [(set (match_dup 0)
19790 (xor:QI (match_dup 1) (const_int -1)))
19791 (clobber (reg:CC FLAGS_REG))])]
19794 ;; Non pairable "test imm, reg" instructions can be translated to
19795 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19796 ;; byte opcode instead of two, have a short form for byte operands),
19797 ;; so do it for other CPUs as well. Given that the value was dead,
19798 ;; this should not create any new dependencies. Pass on the sub-word
19799 ;; versions if we're concerned about partial register stalls.
19802 [(set (match_operand 0 "flags_reg_operand" "")
19803 (match_operator 1 "compare_operator"
19804 [(and:SI (match_operand:SI 2 "register_operand" "")
19805 (match_operand:SI 3 "immediate_operand" ""))
19807 "ix86_match_ccmode (insn, CCNOmode)
19808 && (true_regnum (operands[2]) != 0
19809 || satisfies_constraint_K (operands[3]))
19810 && peep2_reg_dead_p (1, operands[2])"
19812 [(set (match_dup 0)
19813 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19816 (and:SI (match_dup 2) (match_dup 3)))])]
19819 ;; We don't need to handle HImode case, because it will be promoted to SImode
19820 ;; on ! TARGET_PARTIAL_REG_STALL
19823 [(set (match_operand 0 "flags_reg_operand" "")
19824 (match_operator 1 "compare_operator"
19825 [(and:QI (match_operand:QI 2 "register_operand" "")
19826 (match_operand:QI 3 "immediate_operand" ""))
19828 "! TARGET_PARTIAL_REG_STALL
19829 && ix86_match_ccmode (insn, CCNOmode)
19830 && true_regnum (operands[2]) != 0
19831 && peep2_reg_dead_p (1, operands[2])"
19833 [(set (match_dup 0)
19834 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19837 (and:QI (match_dup 2) (match_dup 3)))])]
19841 [(set (match_operand 0 "flags_reg_operand" "")
19842 (match_operator 1 "compare_operator"
19845 (match_operand 2 "ext_register_operand" "")
19848 (match_operand 3 "const_int_operand" ""))
19850 "! TARGET_PARTIAL_REG_STALL
19851 && ix86_match_ccmode (insn, CCNOmode)
19852 && true_regnum (operands[2]) != 0
19853 && peep2_reg_dead_p (1, operands[2])"
19854 [(parallel [(set (match_dup 0)
19863 (set (zero_extract:SI (match_dup 2)
19874 ;; Don't do logical operations with memory inputs.
19876 [(match_scratch:SI 2 "r")
19877 (parallel [(set (match_operand:SI 0 "register_operand" "")
19878 (match_operator:SI 3 "arith_or_logical_operator"
19880 (match_operand:SI 1 "memory_operand" "")]))
19881 (clobber (reg:CC FLAGS_REG))])]
19882 "! optimize_size && ! TARGET_READ_MODIFY"
19883 [(set (match_dup 2) (match_dup 1))
19884 (parallel [(set (match_dup 0)
19885 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19886 (clobber (reg:CC FLAGS_REG))])]
19890 [(match_scratch:SI 2 "r")
19891 (parallel [(set (match_operand:SI 0 "register_operand" "")
19892 (match_operator:SI 3 "arith_or_logical_operator"
19893 [(match_operand:SI 1 "memory_operand" "")
19895 (clobber (reg:CC FLAGS_REG))])]
19896 "! optimize_size && ! TARGET_READ_MODIFY"
19897 [(set (match_dup 2) (match_dup 1))
19898 (parallel [(set (match_dup 0)
19899 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19900 (clobber (reg:CC FLAGS_REG))])]
19903 ; Don't do logical operations with memory outputs
19905 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19906 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19907 ; the same decoder scheduling characteristics as the original.
19910 [(match_scratch:SI 2 "r")
19911 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19912 (match_operator:SI 3 "arith_or_logical_operator"
19914 (match_operand:SI 1 "nonmemory_operand" "")]))
19915 (clobber (reg:CC FLAGS_REG))])]
19916 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19917 [(set (match_dup 2) (match_dup 0))
19918 (parallel [(set (match_dup 2)
19919 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19920 (clobber (reg:CC FLAGS_REG))])
19921 (set (match_dup 0) (match_dup 2))]
19925 [(match_scratch:SI 2 "r")
19926 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19927 (match_operator:SI 3 "arith_or_logical_operator"
19928 [(match_operand:SI 1 "nonmemory_operand" "")
19930 (clobber (reg:CC FLAGS_REG))])]
19931 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19932 [(set (match_dup 2) (match_dup 0))
19933 (parallel [(set (match_dup 2)
19934 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19935 (clobber (reg:CC FLAGS_REG))])
19936 (set (match_dup 0) (match_dup 2))]
19939 ;; Attempt to always use XOR for zeroing registers.
19941 [(set (match_operand 0 "register_operand" "")
19942 (match_operand 1 "const0_operand" ""))]
19943 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19944 && (! TARGET_USE_MOV0 || optimize_size)
19945 && GENERAL_REG_P (operands[0])
19946 && peep2_regno_dead_p (0, FLAGS_REG)"
19947 [(parallel [(set (match_dup 0) (const_int 0))
19948 (clobber (reg:CC FLAGS_REG))])]
19950 operands[0] = gen_lowpart (word_mode, operands[0]);
19954 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19956 "(GET_MODE (operands[0]) == QImode
19957 || GET_MODE (operands[0]) == HImode)
19958 && (! TARGET_USE_MOV0 || optimize_size)
19959 && peep2_regno_dead_p (0, FLAGS_REG)"
19960 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19961 (clobber (reg:CC FLAGS_REG))])])
19963 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19965 [(set (match_operand 0 "register_operand" "")
19967 "(GET_MODE (operands[0]) == HImode
19968 || GET_MODE (operands[0]) == SImode
19969 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19970 && (optimize_size || TARGET_PENTIUM)
19971 && peep2_regno_dead_p (0, FLAGS_REG)"
19972 [(parallel [(set (match_dup 0) (const_int -1))
19973 (clobber (reg:CC FLAGS_REG))])]
19974 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19977 ;; Attempt to convert simple leas to adds. These can be created by
19980 [(set (match_operand:SI 0 "register_operand" "")
19981 (plus:SI (match_dup 0)
19982 (match_operand:SI 1 "nonmemory_operand" "")))]
19983 "peep2_regno_dead_p (0, FLAGS_REG)"
19984 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19985 (clobber (reg:CC FLAGS_REG))])]
19989 [(set (match_operand:SI 0 "register_operand" "")
19990 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19991 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19992 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19993 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19994 (clobber (reg:CC FLAGS_REG))])]
19995 "operands[2] = gen_lowpart (SImode, operands[2]);")
19998 [(set (match_operand:DI 0 "register_operand" "")
19999 (plus:DI (match_dup 0)
20000 (match_operand:DI 1 "x86_64_general_operand" "")))]
20001 "peep2_regno_dead_p (0, FLAGS_REG)"
20002 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20003 (clobber (reg:CC FLAGS_REG))])]
20007 [(set (match_operand:SI 0 "register_operand" "")
20008 (mult:SI (match_dup 0)
20009 (match_operand:SI 1 "const_int_operand" "")))]
20010 "exact_log2 (INTVAL (operands[1])) >= 0
20011 && peep2_regno_dead_p (0, FLAGS_REG)"
20012 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20013 (clobber (reg:CC FLAGS_REG))])]
20014 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20017 [(set (match_operand:DI 0 "register_operand" "")
20018 (mult:DI (match_dup 0)
20019 (match_operand:DI 1 "const_int_operand" "")))]
20020 "exact_log2 (INTVAL (operands[1])) >= 0
20021 && peep2_regno_dead_p (0, FLAGS_REG)"
20022 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20023 (clobber (reg:CC FLAGS_REG))])]
20024 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20027 [(set (match_operand:SI 0 "register_operand" "")
20028 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20029 (match_operand:DI 2 "const_int_operand" "")) 0))]
20030 "exact_log2 (INTVAL (operands[2])) >= 0
20031 && REGNO (operands[0]) == REGNO (operands[1])
20032 && peep2_regno_dead_p (0, FLAGS_REG)"
20033 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20034 (clobber (reg:CC FLAGS_REG))])]
20035 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20037 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20038 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20039 ;; many CPUs it is also faster, since special hardware to avoid esp
20040 ;; dependencies is present.
20042 ;; While some of these conversions may be done using splitters, we use peepholes
20043 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20045 ;; Convert prologue esp subtractions to push.
20046 ;; We need register to push. In order to keep verify_flow_info happy we have
20048 ;; - use scratch and clobber it in order to avoid dependencies
20049 ;; - use already live register
20050 ;; We can't use the second way right now, since there is no reliable way how to
20051 ;; verify that given register is live. First choice will also most likely in
20052 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20053 ;; call clobbered registers are dead. We may want to use base pointer as an
20054 ;; alternative when no register is available later.
20057 [(match_scratch:SI 0 "r")
20058 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20059 (clobber (reg:CC FLAGS_REG))
20060 (clobber (mem:BLK (scratch)))])]
20061 "optimize_size || !TARGET_SUB_ESP_4"
20062 [(clobber (match_dup 0))
20063 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20064 (clobber (mem:BLK (scratch)))])])
20067 [(match_scratch:SI 0 "r")
20068 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20069 (clobber (reg:CC FLAGS_REG))
20070 (clobber (mem:BLK (scratch)))])]
20071 "optimize_size || !TARGET_SUB_ESP_8"
20072 [(clobber (match_dup 0))
20073 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20074 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20075 (clobber (mem:BLK (scratch)))])])
20077 ;; Convert esp subtractions to push.
20079 [(match_scratch:SI 0 "r")
20080 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20081 (clobber (reg:CC FLAGS_REG))])]
20082 "optimize_size || !TARGET_SUB_ESP_4"
20083 [(clobber (match_dup 0))
20084 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20087 [(match_scratch:SI 0 "r")
20088 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20089 (clobber (reg:CC FLAGS_REG))])]
20090 "optimize_size || !TARGET_SUB_ESP_8"
20091 [(clobber (match_dup 0))
20092 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20093 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20095 ;; Convert epilogue deallocator to pop.
20097 [(match_scratch:SI 0 "r")
20098 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20099 (clobber (reg:CC FLAGS_REG))
20100 (clobber (mem:BLK (scratch)))])]
20101 "optimize_size || !TARGET_ADD_ESP_4"
20102 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20103 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20104 (clobber (mem:BLK (scratch)))])]
20107 ;; Two pops case is tricky, since pop causes dependency on destination register.
20108 ;; We use two registers if available.
20110 [(match_scratch:SI 0 "r")
20111 (match_scratch:SI 1 "r")
20112 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20113 (clobber (reg:CC FLAGS_REG))
20114 (clobber (mem:BLK (scratch)))])]
20115 "optimize_size || !TARGET_ADD_ESP_8"
20116 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20117 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20118 (clobber (mem:BLK (scratch)))])
20119 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20120 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20124 [(match_scratch:SI 0 "r")
20125 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20126 (clobber (reg:CC FLAGS_REG))
20127 (clobber (mem:BLK (scratch)))])]
20129 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20130 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20131 (clobber (mem:BLK (scratch)))])
20132 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20133 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20136 ;; Convert esp additions to pop.
20138 [(match_scratch:SI 0 "r")
20139 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20140 (clobber (reg:CC FLAGS_REG))])]
20142 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20143 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20146 ;; Two pops case is tricky, since pop causes dependency on destination register.
20147 ;; We use two registers if available.
20149 [(match_scratch:SI 0 "r")
20150 (match_scratch:SI 1 "r")
20151 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20152 (clobber (reg:CC FLAGS_REG))])]
20154 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20155 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20156 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20157 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20161 [(match_scratch:SI 0 "r")
20162 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20163 (clobber (reg:CC FLAGS_REG))])]
20165 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20166 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20167 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20168 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20171 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20172 ;; required and register dies. Similarly for 128 to plus -128.
20174 [(set (match_operand 0 "flags_reg_operand" "")
20175 (match_operator 1 "compare_operator"
20176 [(match_operand 2 "register_operand" "")
20177 (match_operand 3 "const_int_operand" "")]))]
20178 "(INTVAL (operands[3]) == -1
20179 || INTVAL (operands[3]) == 1
20180 || INTVAL (operands[3]) == 128)
20181 && ix86_match_ccmode (insn, CCGCmode)
20182 && peep2_reg_dead_p (1, operands[2])"
20183 [(parallel [(set (match_dup 0)
20184 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20185 (clobber (match_dup 2))])]
20189 [(match_scratch:DI 0 "r")
20190 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20191 (clobber (reg:CC FLAGS_REG))
20192 (clobber (mem:BLK (scratch)))])]
20193 "optimize_size || !TARGET_SUB_ESP_4"
20194 [(clobber (match_dup 0))
20195 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20196 (clobber (mem:BLK (scratch)))])])
20199 [(match_scratch:DI 0 "r")
20200 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20201 (clobber (reg:CC FLAGS_REG))
20202 (clobber (mem:BLK (scratch)))])]
20203 "optimize_size || !TARGET_SUB_ESP_8"
20204 [(clobber (match_dup 0))
20205 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20206 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20207 (clobber (mem:BLK (scratch)))])])
20209 ;; Convert esp subtractions to push.
20211 [(match_scratch:DI 0 "r")
20212 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20213 (clobber (reg:CC FLAGS_REG))])]
20214 "optimize_size || !TARGET_SUB_ESP_4"
20215 [(clobber (match_dup 0))
20216 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20219 [(match_scratch:DI 0 "r")
20220 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20221 (clobber (reg:CC FLAGS_REG))])]
20222 "optimize_size || !TARGET_SUB_ESP_8"
20223 [(clobber (match_dup 0))
20224 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20225 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20227 ;; Convert epilogue deallocator to pop.
20229 [(match_scratch:DI 0 "r")
20230 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20231 (clobber (reg:CC FLAGS_REG))
20232 (clobber (mem:BLK (scratch)))])]
20233 "optimize_size || !TARGET_ADD_ESP_4"
20234 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20235 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20236 (clobber (mem:BLK (scratch)))])]
20239 ;; Two pops case is tricky, since pop causes dependency on destination register.
20240 ;; We use two registers if available.
20242 [(match_scratch:DI 0 "r")
20243 (match_scratch:DI 1 "r")
20244 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20245 (clobber (reg:CC FLAGS_REG))
20246 (clobber (mem:BLK (scratch)))])]
20247 "optimize_size || !TARGET_ADD_ESP_8"
20248 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20249 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20250 (clobber (mem:BLK (scratch)))])
20251 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20252 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20256 [(match_scratch:DI 0 "r")
20257 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20258 (clobber (reg:CC FLAGS_REG))
20259 (clobber (mem:BLK (scratch)))])]
20261 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20262 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20263 (clobber (mem:BLK (scratch)))])
20264 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20265 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20268 ;; Convert esp additions to pop.
20270 [(match_scratch:DI 0 "r")
20271 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20272 (clobber (reg:CC FLAGS_REG))])]
20274 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20275 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20278 ;; Two pops case is tricky, since pop causes dependency on destination register.
20279 ;; We use two registers if available.
20281 [(match_scratch:DI 0 "r")
20282 (match_scratch:DI 1 "r")
20283 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20284 (clobber (reg:CC FLAGS_REG))])]
20286 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20287 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20288 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20289 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20293 [(match_scratch:DI 0 "r")
20294 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20295 (clobber (reg:CC FLAGS_REG))])]
20297 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20298 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20299 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20300 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20303 ;; Convert imul by three, five and nine into lea
20306 [(set (match_operand:SI 0 "register_operand" "")
20307 (mult:SI (match_operand:SI 1 "register_operand" "")
20308 (match_operand:SI 2 "const_int_operand" "")))
20309 (clobber (reg:CC FLAGS_REG))])]
20310 "INTVAL (operands[2]) == 3
20311 || INTVAL (operands[2]) == 5
20312 || INTVAL (operands[2]) == 9"
20313 [(set (match_dup 0)
20314 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20316 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20320 [(set (match_operand:SI 0 "register_operand" "")
20321 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20322 (match_operand:SI 2 "const_int_operand" "")))
20323 (clobber (reg:CC FLAGS_REG))])]
20325 && (INTVAL (operands[2]) == 3
20326 || INTVAL (operands[2]) == 5
20327 || INTVAL (operands[2]) == 9)"
20328 [(set (match_dup 0) (match_dup 1))
20330 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20332 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20336 [(set (match_operand:DI 0 "register_operand" "")
20337 (mult:DI (match_operand:DI 1 "register_operand" "")
20338 (match_operand:DI 2 "const_int_operand" "")))
20339 (clobber (reg:CC FLAGS_REG))])]
20341 && (INTVAL (operands[2]) == 3
20342 || INTVAL (operands[2]) == 5
20343 || INTVAL (operands[2]) == 9)"
20344 [(set (match_dup 0)
20345 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20347 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20351 [(set (match_operand:DI 0 "register_operand" "")
20352 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20353 (match_operand:DI 2 "const_int_operand" "")))
20354 (clobber (reg:CC FLAGS_REG))])]
20357 && (INTVAL (operands[2]) == 3
20358 || INTVAL (operands[2]) == 5
20359 || INTVAL (operands[2]) == 9)"
20360 [(set (match_dup 0) (match_dup 1))
20362 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20364 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20366 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20367 ;; imul $32bit_imm, reg, reg is direct decoded.
20369 [(match_scratch:DI 3 "r")
20370 (parallel [(set (match_operand:DI 0 "register_operand" "")
20371 (mult:DI (match_operand:DI 1 "memory_operand" "")
20372 (match_operand:DI 2 "immediate_operand" "")))
20373 (clobber (reg:CC FLAGS_REG))])]
20374 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20375 && !satisfies_constraint_K (operands[2])"
20376 [(set (match_dup 3) (match_dup 1))
20377 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20378 (clobber (reg:CC FLAGS_REG))])]
20382 [(match_scratch:SI 3 "r")
20383 (parallel [(set (match_operand:SI 0 "register_operand" "")
20384 (mult:SI (match_operand:SI 1 "memory_operand" "")
20385 (match_operand:SI 2 "immediate_operand" "")))
20386 (clobber (reg:CC FLAGS_REG))])]
20387 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20388 && !satisfies_constraint_K (operands[2])"
20389 [(set (match_dup 3) (match_dup 1))
20390 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20391 (clobber (reg:CC FLAGS_REG))])]
20395 [(match_scratch:SI 3 "r")
20396 (parallel [(set (match_operand:DI 0 "register_operand" "")
20398 (mult:SI (match_operand:SI 1 "memory_operand" "")
20399 (match_operand:SI 2 "immediate_operand" ""))))
20400 (clobber (reg:CC FLAGS_REG))])]
20401 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20402 && !satisfies_constraint_K (operands[2])"
20403 [(set (match_dup 3) (match_dup 1))
20404 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20405 (clobber (reg:CC FLAGS_REG))])]
20408 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20409 ;; Convert it into imul reg, reg
20410 ;; It would be better to force assembler to encode instruction using long
20411 ;; immediate, but there is apparently no way to do so.
20413 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20414 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20415 (match_operand:DI 2 "const_int_operand" "")))
20416 (clobber (reg:CC FLAGS_REG))])
20417 (match_scratch:DI 3 "r")]
20418 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20419 && satisfies_constraint_K (operands[2])"
20420 [(set (match_dup 3) (match_dup 2))
20421 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20422 (clobber (reg:CC FLAGS_REG))])]
20424 if (!rtx_equal_p (operands[0], operands[1]))
20425 emit_move_insn (operands[0], operands[1]);
20429 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20430 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20431 (match_operand:SI 2 "const_int_operand" "")))
20432 (clobber (reg:CC FLAGS_REG))])
20433 (match_scratch:SI 3 "r")]
20434 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20435 && satisfies_constraint_K (operands[2])"
20436 [(set (match_dup 3) (match_dup 2))
20437 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20438 (clobber (reg:CC FLAGS_REG))])]
20440 if (!rtx_equal_p (operands[0], operands[1]))
20441 emit_move_insn (operands[0], operands[1]);
20445 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20446 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20447 (match_operand:HI 2 "immediate_operand" "")))
20448 (clobber (reg:CC FLAGS_REG))])
20449 (match_scratch:HI 3 "r")]
20450 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20451 [(set (match_dup 3) (match_dup 2))
20452 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20453 (clobber (reg:CC FLAGS_REG))])]
20455 if (!rtx_equal_p (operands[0], operands[1]))
20456 emit_move_insn (operands[0], operands[1]);
20459 ;; After splitting up read-modify operations, array accesses with memory
20460 ;; operands might end up in form:
20462 ;; movl 4(%esp), %edx
20464 ;; instead of pre-splitting:
20466 ;; addl 4(%esp), %eax
20468 ;; movl 4(%esp), %edx
20469 ;; leal (%edx,%eax,4), %eax
20472 [(parallel [(set (match_operand 0 "register_operand" "")
20473 (ashift (match_operand 1 "register_operand" "")
20474 (match_operand 2 "const_int_operand" "")))
20475 (clobber (reg:CC FLAGS_REG))])
20476 (set (match_operand 3 "register_operand")
20477 (match_operand 4 "x86_64_general_operand" ""))
20478 (parallel [(set (match_operand 5 "register_operand" "")
20479 (plus (match_operand 6 "register_operand" "")
20480 (match_operand 7 "register_operand" "")))
20481 (clobber (reg:CC FLAGS_REG))])]
20482 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20483 /* Validate MODE for lea. */
20484 && ((!TARGET_PARTIAL_REG_STALL
20485 && (GET_MODE (operands[0]) == QImode
20486 || GET_MODE (operands[0]) == HImode))
20487 || GET_MODE (operands[0]) == SImode
20488 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20489 /* We reorder load and the shift. */
20490 && !rtx_equal_p (operands[1], operands[3])
20491 && !reg_overlap_mentioned_p (operands[0], operands[4])
20492 /* Last PLUS must consist of operand 0 and 3. */
20493 && !rtx_equal_p (operands[0], operands[3])
20494 && (rtx_equal_p (operands[3], operands[6])
20495 || rtx_equal_p (operands[3], operands[7]))
20496 && (rtx_equal_p (operands[0], operands[6])
20497 || rtx_equal_p (operands[0], operands[7]))
20498 /* The intermediate operand 0 must die or be same as output. */
20499 && (rtx_equal_p (operands[0], operands[5])
20500 || peep2_reg_dead_p (3, operands[0]))"
20501 [(set (match_dup 3) (match_dup 4))
20502 (set (match_dup 0) (match_dup 1))]
20504 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20505 int scale = 1 << INTVAL (operands[2]);
20506 rtx index = gen_lowpart (Pmode, operands[1]);
20507 rtx base = gen_lowpart (Pmode, operands[3]);
20508 rtx dest = gen_lowpart (mode, operands[5]);
20510 operands[1] = gen_rtx_PLUS (Pmode, base,
20511 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20513 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20514 operands[0] = dest;
20517 ;; Call-value patterns last so that the wildcard operand does not
20518 ;; disrupt insn-recog's switch tables.
20520 (define_insn "*call_value_pop_0"
20521 [(set (match_operand 0 "" "")
20522 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20523 (match_operand:SI 2 "" "")))
20524 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20525 (match_operand:SI 3 "immediate_operand" "")))]
20528 if (SIBLING_CALL_P (insn))
20531 return "call\t%P1";
20533 [(set_attr "type" "callv")])
20535 (define_insn "*call_value_pop_1"
20536 [(set (match_operand 0 "" "")
20537 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20538 (match_operand:SI 2 "" "")))
20539 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20540 (match_operand:SI 3 "immediate_operand" "i")))]
20543 if (constant_call_address_operand (operands[1], Pmode))
20545 if (SIBLING_CALL_P (insn))
20548 return "call\t%P1";
20550 if (SIBLING_CALL_P (insn))
20553 return "call\t%A1";
20555 [(set_attr "type" "callv")])
20557 (define_insn "*call_value_0"
20558 [(set (match_operand 0 "" "")
20559 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20560 (match_operand:SI 2 "" "")))]
20563 if (SIBLING_CALL_P (insn))
20566 return "call\t%P1";
20568 [(set_attr "type" "callv")])
20570 (define_insn "*call_value_0_rex64"
20571 [(set (match_operand 0 "" "")
20572 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20573 (match_operand:DI 2 "const_int_operand" "")))]
20576 if (SIBLING_CALL_P (insn))
20579 return "call\t%P1";
20581 [(set_attr "type" "callv")])
20583 (define_insn "*call_value_1"
20584 [(set (match_operand 0 "" "")
20585 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20586 (match_operand:SI 2 "" "")))]
20587 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20589 if (constant_call_address_operand (operands[1], Pmode))
20590 return "call\t%P1";
20591 return "call\t%A1";
20593 [(set_attr "type" "callv")])
20595 (define_insn "*sibcall_value_1"
20596 [(set (match_operand 0 "" "")
20597 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20598 (match_operand:SI 2 "" "")))]
20599 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20601 if (constant_call_address_operand (operands[1], Pmode))
20605 [(set_attr "type" "callv")])
20607 (define_insn "*call_value_1_rex64"
20608 [(set (match_operand 0 "" "")
20609 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20610 (match_operand:DI 2 "" "")))]
20611 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20613 if (constant_call_address_operand (operands[1], Pmode))
20614 return "call\t%P1";
20615 return "call\t%A1";
20617 [(set_attr "type" "callv")])
20619 (define_insn "*sibcall_value_1_rex64"
20620 [(set (match_operand 0 "" "")
20621 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20622 (match_operand:DI 2 "" "")))]
20623 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20625 [(set_attr "type" "callv")])
20627 (define_insn "*sibcall_value_1_rex64_v"
20628 [(set (match_operand 0 "" "")
20629 (call (mem:QI (reg:DI 40))
20630 (match_operand:DI 1 "" "")))]
20631 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20633 [(set_attr "type" "callv")])
20635 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20636 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20637 ;; caught for use by garbage collectors and the like. Using an insn that
20638 ;; maps to SIGILL makes it more likely the program will rightfully die.
20639 ;; Keeping with tradition, "6" is in honor of #UD.
20640 (define_insn "trap"
20641 [(trap_if (const_int 1) (const_int 6))]
20643 { return ASM_SHORT "0x0b0f"; }
20644 [(set_attr "length" "2")])
20646 (define_expand "sse_prologue_save"
20647 [(parallel [(set (match_operand:BLK 0 "" "")
20648 (unspec:BLK [(reg:DI 21)
20655 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20656 (use (match_operand:DI 1 "register_operand" ""))
20657 (use (match_operand:DI 2 "immediate_operand" ""))
20658 (use (label_ref:DI (match_operand 3 "" "")))])]
20662 (define_insn "*sse_prologue_save_insn"
20663 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20664 (match_operand:DI 4 "const_int_operand" "n")))
20665 (unspec:BLK [(reg:DI 21)
20672 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20673 (use (match_operand:DI 1 "register_operand" "r"))
20674 (use (match_operand:DI 2 "const_int_operand" "i"))
20675 (use (label_ref:DI (match_operand 3 "" "X")))]
20677 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20678 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20682 operands[0] = gen_rtx_MEM (Pmode,
20683 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20684 output_asm_insn (\"jmp\\t%A1\", operands);
20685 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20687 operands[4] = adjust_address (operands[0], DImode, i*16);
20688 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20689 PUT_MODE (operands[4], TImode);
20690 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20691 output_asm_insn (\"rex\", operands);
20692 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20694 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20695 CODE_LABEL_NUMBER (operands[3]));
20699 [(set_attr "type" "other")
20700 (set_attr "length_immediate" "0")
20701 (set_attr "length_address" "0")
20702 (set_attr "length" "135")
20703 (set_attr "memory" "store")
20704 (set_attr "modrm" "0")
20705 (set_attr "mode" "DI")])
20707 (define_expand "prefetch"
20708 [(prefetch (match_operand 0 "address_operand" "")
20709 (match_operand:SI 1 "const_int_operand" "")
20710 (match_operand:SI 2 "const_int_operand" ""))]
20711 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20713 int rw = INTVAL (operands[1]);
20714 int locality = INTVAL (operands[2]);
20716 gcc_assert (rw == 0 || rw == 1);
20717 gcc_assert (locality >= 0 && locality <= 3);
20718 gcc_assert (GET_MODE (operands[0]) == Pmode
20719 || GET_MODE (operands[0]) == VOIDmode);
20721 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20722 supported by SSE counterpart or the SSE prefetch is not available
20723 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20725 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20726 operands[2] = GEN_INT (3);
20728 operands[1] = const0_rtx;
20731 (define_insn "*prefetch_sse"
20732 [(prefetch (match_operand:SI 0 "address_operand" "p")
20734 (match_operand:SI 1 "const_int_operand" ""))]
20735 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20737 static const char * const patterns[4] = {
20738 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20741 int locality = INTVAL (operands[1]);
20742 gcc_assert (locality >= 0 && locality <= 3);
20744 return patterns[locality];
20746 [(set_attr "type" "sse")
20747 (set_attr "memory" "none")])
20749 (define_insn "*prefetch_sse_rex"
20750 [(prefetch (match_operand:DI 0 "address_operand" "p")
20752 (match_operand:SI 1 "const_int_operand" ""))]
20753 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20755 static const char * const patterns[4] = {
20756 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20759 int locality = INTVAL (operands[1]);
20760 gcc_assert (locality >= 0 && locality <= 3);
20762 return patterns[locality];
20764 [(set_attr "type" "sse")
20765 (set_attr "memory" "none")])
20767 (define_insn "*prefetch_3dnow"
20768 [(prefetch (match_operand:SI 0 "address_operand" "p")
20769 (match_operand:SI 1 "const_int_operand" "n")
20771 "TARGET_3DNOW && !TARGET_64BIT"
20773 if (INTVAL (operands[1]) == 0)
20774 return "prefetch\t%a0";
20776 return "prefetchw\t%a0";
20778 [(set_attr "type" "mmx")
20779 (set_attr "memory" "none")])
20781 (define_insn "*prefetch_3dnow_rex"
20782 [(prefetch (match_operand:DI 0 "address_operand" "p")
20783 (match_operand:SI 1 "const_int_operand" "n")
20785 "TARGET_3DNOW && TARGET_64BIT"
20787 if (INTVAL (operands[1]) == 0)
20788 return "prefetch\t%a0";
20790 return "prefetchw\t%a0";
20792 [(set_attr "type" "mmx")
20793 (set_attr "memory" "none")])
20795 (define_expand "stack_protect_set"
20796 [(match_operand 0 "memory_operand" "")
20797 (match_operand 1 "memory_operand" "")]
20800 #ifdef TARGET_THREAD_SSP_OFFSET
20802 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20803 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20805 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20806 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20809 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20811 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20816 (define_insn "stack_protect_set_si"
20817 [(set (match_operand:SI 0 "memory_operand" "=m")
20818 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20819 (set (match_scratch:SI 2 "=&r") (const_int 0))
20820 (clobber (reg:CC FLAGS_REG))]
20822 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20823 [(set_attr "type" "multi")])
20825 (define_insn "stack_protect_set_di"
20826 [(set (match_operand:DI 0 "memory_operand" "=m")
20827 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20828 (set (match_scratch:DI 2 "=&r") (const_int 0))
20829 (clobber (reg:CC FLAGS_REG))]
20831 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20832 [(set_attr "type" "multi")])
20834 (define_insn "stack_tls_protect_set_si"
20835 [(set (match_operand:SI 0 "memory_operand" "=m")
20836 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20837 (set (match_scratch:SI 2 "=&r") (const_int 0))
20838 (clobber (reg:CC FLAGS_REG))]
20840 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20841 [(set_attr "type" "multi")])
20843 (define_insn "stack_tls_protect_set_di"
20844 [(set (match_operand:DI 0 "memory_operand" "=m")
20845 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20846 (set (match_scratch:DI 2 "=&r") (const_int 0))
20847 (clobber (reg:CC FLAGS_REG))]
20850 /* The kernel uses a different segment register for performance reasons; a
20851 system call would not have to trash the userspace segment register,
20852 which would be expensive */
20853 if (ix86_cmodel != CM_KERNEL)
20854 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20856 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20858 [(set_attr "type" "multi")])
20860 (define_expand "stack_protect_test"
20861 [(match_operand 0 "memory_operand" "")
20862 (match_operand 1 "memory_operand" "")
20863 (match_operand 2 "" "")]
20866 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20867 ix86_compare_op0 = operands[0];
20868 ix86_compare_op1 = operands[1];
20869 ix86_compare_emitted = flags;
20871 #ifdef TARGET_THREAD_SSP_OFFSET
20873 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20874 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20876 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20877 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20880 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20882 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20884 emit_jump_insn (gen_beq (operands[2]));
20888 (define_insn "stack_protect_test_si"
20889 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20890 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20891 (match_operand:SI 2 "memory_operand" "m")]
20893 (clobber (match_scratch:SI 3 "=&r"))]
20895 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20896 [(set_attr "type" "multi")])
20898 (define_insn "stack_protect_test_di"
20899 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20900 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20901 (match_operand:DI 2 "memory_operand" "m")]
20903 (clobber (match_scratch:DI 3 "=&r"))]
20905 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20906 [(set_attr "type" "multi")])
20908 (define_insn "stack_tls_protect_test_si"
20909 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20910 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20911 (match_operand:SI 2 "const_int_operand" "i")]
20912 UNSPEC_SP_TLS_TEST))
20913 (clobber (match_scratch:SI 3 "=r"))]
20915 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20916 [(set_attr "type" "multi")])
20918 (define_insn "stack_tls_protect_test_di"
20919 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20920 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20921 (match_operand:DI 2 "const_int_operand" "i")]
20922 UNSPEC_SP_TLS_TEST))
20923 (clobber (match_scratch:DI 3 "=r"))]
20926 /* The kernel uses a different segment register for performance reasons; a
20927 system call would not have to trash the userspace segment register,
20928 which would be expensive */
20929 if (ix86_cmodel != CM_KERNEL)
20930 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20932 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20934 [(set_attr "type" "multi")])
20938 (include "sync.md")