1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 30)
98 (UNSPEC_NOP 38) ; prevents combiner cleverness
109 ; Generic math support
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
125 (UNSPEC_FRNDINT_FLOOR 70)
126 (UNSPEC_FRNDINT_CEIL 71)
127 (UNSPEC_FRNDINT_TRUNC 72)
128 (UNSPEC_FRNDINT_MASK_PM 73)
129 (UNSPEC_FIST_FLOOR 74)
130 (UNSPEC_FIST_CEIL 75)
132 ; x87 Double output FP
133 (UNSPEC_SINCOS_COS 80)
134 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
149 (UNSPEC_SP_TLS_SET 102)
150 (UNSPEC_SP_TLS_TEST 103)
159 [(UNSPECV_BLOCKAGE 0)
160 (UNSPECV_STACK_PROBE 1)
169 (UNSPECV_CMPXCHG_1 10)
170 (UNSPECV_CMPXCHG_2 11)
175 ;; Registers by name.
184 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
187 ;; In C guard expressions, put expressions which may be compile-time
188 ;; constants first. This allows for better optimization. For
189 ;; example, write "TARGET_64BIT && reload_completed", not
190 ;; "reload_completed && TARGET_64BIT".
193 ;; Processor type. This attribute must exactly match the processor_type
194 ;; enumeration in i386.h.
195 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
196 (const (symbol_ref "ix86_tune")))
198 ;; A basic instruction type. Refinements due to arguments to be
199 ;; provided in other attributes.
202 alu,alu1,negnot,imov,imovx,lea,
203 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
204 icmp,test,ibr,setcc,icmov,
205 push,pop,call,callv,leave,
207 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
208 sselog,sselog1,sseiadd,sseishft,sseimul,
209 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
210 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
211 (const_string "other"))
213 ;; Main data type used by the insn
215 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
216 (const_string "unknown"))
218 ;; The CPU unit operations uses.
219 (define_attr "unit" "integer,i387,sse,mmx,unknown"
220 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
221 (const_string "i387")
222 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
223 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
225 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
227 (eq_attr "type" "other")
228 (const_string "unknown")]
229 (const_string "integer")))
231 ;; The (bounding maximum) length of an instruction immediate.
232 (define_attr "length_immediate" ""
233 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
235 (eq_attr "unit" "i387,sse,mmx")
237 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
239 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
240 (eq_attr "type" "imov,test")
241 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
242 (eq_attr "type" "call")
243 (if_then_else (match_operand 0 "constant_call_address_operand" "")
246 (eq_attr "type" "callv")
247 (if_then_else (match_operand 1 "constant_call_address_operand" "")
250 ;; We don't know the size before shorten_branches. Expect
251 ;; the instruction to fit for better scheduling.
252 (eq_attr "type" "ibr")
255 (symbol_ref "/* Update immediate_length and other attributes! */
256 gcc_unreachable (),1")))
258 ;; The (bounding maximum) length of an instruction address.
259 (define_attr "length_address" ""
260 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
262 (and (eq_attr "type" "call")
263 (match_operand 0 "constant_call_address_operand" ""))
265 (and (eq_attr "type" "callv")
266 (match_operand 1 "constant_call_address_operand" ""))
269 (symbol_ref "ix86_attr_length_address_default (insn)")))
271 ;; Set when length prefix is used.
272 (define_attr "prefix_data16" ""
273 (if_then_else (ior (eq_attr "mode" "HI")
274 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
278 ;; Set when string REP prefix is used.
279 (define_attr "prefix_rep" ""
280 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
284 ;; Set when 0f opcode prefix is used.
285 (define_attr "prefix_0f" ""
287 (ior (eq_attr "type" "imovx,setcc,icmov")
288 (eq_attr "unit" "sse,mmx"))
292 ;; Set when REX opcode prefix is used.
293 (define_attr "prefix_rex" ""
294 (cond [(and (eq_attr "mode" "DI")
295 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
297 (and (eq_attr "mode" "QI")
298 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
301 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
307 ;; Set when modrm byte is used.
308 (define_attr "modrm" ""
309 (cond [(eq_attr "type" "str,cld,leave")
311 (eq_attr "unit" "i387")
313 (and (eq_attr "type" "incdec")
314 (ior (match_operand:SI 1 "register_operand" "")
315 (match_operand:HI 1 "register_operand" "")))
317 (and (eq_attr "type" "push")
318 (not (match_operand 1 "memory_operand" "")))
320 (and (eq_attr "type" "pop")
321 (not (match_operand 0 "memory_operand" "")))
323 (and (eq_attr "type" "imov")
324 (ior (and (match_operand 0 "register_operand" "")
325 (match_operand 1 "immediate_operand" ""))
326 (ior (and (match_operand 0 "ax_reg_operand" "")
327 (match_operand 1 "memory_displacement_only_operand" ""))
328 (and (match_operand 0 "memory_displacement_only_operand" "")
329 (match_operand 1 "ax_reg_operand" "")))))
331 (and (eq_attr "type" "call")
332 (match_operand 0 "constant_call_address_operand" ""))
334 (and (eq_attr "type" "callv")
335 (match_operand 1 "constant_call_address_operand" ""))
340 ;; The (bounding maximum) length of an instruction in bytes.
341 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
342 ;; Later we may want to split them and compute proper length as for
344 (define_attr "length" ""
345 (cond [(eq_attr "type" "other,multi,fistp,frndint")
347 (eq_attr "type" "fcmp")
349 (eq_attr "unit" "i387")
351 (plus (attr "prefix_data16")
352 (attr "length_address")))]
353 (plus (plus (attr "modrm")
354 (plus (attr "prefix_0f")
355 (plus (attr "prefix_rex")
357 (plus (attr "prefix_rep")
358 (plus (attr "prefix_data16")
359 (plus (attr "length_immediate")
360 (attr "length_address")))))))
362 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
363 ;; `store' if there is a simple memory reference therein, or `unknown'
364 ;; if the instruction is complex.
366 (define_attr "memory" "none,load,store,both,unknown"
367 (cond [(eq_attr "type" "other,multi,str")
368 (const_string "unknown")
369 (eq_attr "type" "lea,fcmov,fpspc,cld")
370 (const_string "none")
371 (eq_attr "type" "fistp,leave")
372 (const_string "both")
373 (eq_attr "type" "frndint")
374 (const_string "load")
375 (eq_attr "type" "push")
376 (if_then_else (match_operand 1 "memory_operand" "")
377 (const_string "both")
378 (const_string "store"))
379 (eq_attr "type" "pop")
380 (if_then_else (match_operand 0 "memory_operand" "")
381 (const_string "both")
382 (const_string "load"))
383 (eq_attr "type" "setcc")
384 (if_then_else (match_operand 0 "memory_operand" "")
385 (const_string "store")
386 (const_string "none"))
387 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
388 (if_then_else (ior (match_operand 0 "memory_operand" "")
389 (match_operand 1 "memory_operand" ""))
390 (const_string "load")
391 (const_string "none"))
392 (eq_attr "type" "ibr")
393 (if_then_else (match_operand 0 "memory_operand" "")
394 (const_string "load")
395 (const_string "none"))
396 (eq_attr "type" "call")
397 (if_then_else (match_operand 0 "constant_call_address_operand" "")
398 (const_string "none")
399 (const_string "load"))
400 (eq_attr "type" "callv")
401 (if_then_else (match_operand 1 "constant_call_address_operand" "")
402 (const_string "none")
403 (const_string "load"))
404 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
405 (match_operand 1 "memory_operand" ""))
406 (const_string "both")
407 (and (match_operand 0 "memory_operand" "")
408 (match_operand 1 "memory_operand" ""))
409 (const_string "both")
410 (match_operand 0 "memory_operand" "")
411 (const_string "store")
412 (match_operand 1 "memory_operand" "")
413 (const_string "load")
415 "!alu1,negnot,ishift1,
416 imov,imovx,icmp,test,
418 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
419 mmx,mmxmov,mmxcmp,mmxcvt")
420 (match_operand 2 "memory_operand" ""))
421 (const_string "load")
422 (and (eq_attr "type" "icmov")
423 (match_operand 3 "memory_operand" ""))
424 (const_string "load")
426 (const_string "none")))
428 ;; Indicates if an instruction has both an immediate and a displacement.
430 (define_attr "imm_disp" "false,true,unknown"
431 (cond [(eq_attr "type" "other,multi")
432 (const_string "unknown")
433 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
434 (and (match_operand 0 "memory_displacement_operand" "")
435 (match_operand 1 "immediate_operand" "")))
436 (const_string "true")
437 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
438 (and (match_operand 0 "memory_displacement_operand" "")
439 (match_operand 2 "immediate_operand" "")))
440 (const_string "true")
442 (const_string "false")))
444 ;; Indicates if an FP operation has an integer source.
446 (define_attr "fp_int_src" "false,true"
447 (const_string "false"))
449 ;; Defines rounding mode of an FP operation.
451 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
452 (const_string "any"))
454 ;; Describe a user's asm statement.
455 (define_asm_attributes
456 [(set_attr "length" "128")
457 (set_attr "type" "multi")])
459 ;; All x87 floating point modes
460 (define_mode_macro X87MODEF [SF DF XF])
462 ;; All integer modes handled by x87 fisttp operator.
463 (define_mode_macro X87MODEI [HI SI DI])
465 ;; All integer modes handled by integer x87 operators.
466 (define_mode_macro X87MODEI12 [HI SI])
468 ;; All SSE floating point modes
469 (define_mode_macro SSEMODEF [SF DF])
471 ;; All integer modes handled by SSE cvtts?2si* operators.
472 (define_mode_macro SSEMODEI24 [SI DI])
475 ;; Scheduling descriptions
477 (include "pentium.md")
480 (include "athlon.md")
484 ;; Operand and operator predicates and constraints
486 (include "predicates.md")
487 (include "constraints.md")
490 ;; Compare instructions.
492 ;; All compare insns have expanders that save the operands away without
493 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
494 ;; after the cmp) will actually emit the cmpM.
496 (define_expand "cmpti"
497 [(set (reg:CC FLAGS_REG)
498 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
499 (match_operand:TI 1 "x86_64_general_operand" "")))]
502 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
503 operands[0] = force_reg (TImode, operands[0]);
504 ix86_compare_op0 = operands[0];
505 ix86_compare_op1 = operands[1];
509 (define_expand "cmpdi"
510 [(set (reg:CC FLAGS_REG)
511 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
512 (match_operand:DI 1 "x86_64_general_operand" "")))]
515 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
516 operands[0] = force_reg (DImode, operands[0]);
517 ix86_compare_op0 = operands[0];
518 ix86_compare_op1 = operands[1];
522 (define_expand "cmpsi"
523 [(set (reg:CC FLAGS_REG)
524 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
525 (match_operand:SI 1 "general_operand" "")))]
528 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
529 operands[0] = force_reg (SImode, operands[0]);
530 ix86_compare_op0 = operands[0];
531 ix86_compare_op1 = operands[1];
535 (define_expand "cmphi"
536 [(set (reg:CC FLAGS_REG)
537 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
538 (match_operand:HI 1 "general_operand" "")))]
541 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
542 operands[0] = force_reg (HImode, operands[0]);
543 ix86_compare_op0 = operands[0];
544 ix86_compare_op1 = operands[1];
548 (define_expand "cmpqi"
549 [(set (reg:CC FLAGS_REG)
550 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
551 (match_operand:QI 1 "general_operand" "")))]
554 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
555 operands[0] = force_reg (QImode, operands[0]);
556 ix86_compare_op0 = operands[0];
557 ix86_compare_op1 = operands[1];
561 (define_insn "cmpdi_ccno_1_rex64"
562 [(set (reg FLAGS_REG)
563 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
564 (match_operand:DI 1 "const0_operand" "n,n")))]
565 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
567 test{q}\t{%0, %0|%0, %0}
568 cmp{q}\t{%1, %0|%0, %1}"
569 [(set_attr "type" "test,icmp")
570 (set_attr "length_immediate" "0,1")
571 (set_attr "mode" "DI")])
573 (define_insn "*cmpdi_minus_1_rex64"
574 [(set (reg FLAGS_REG)
575 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
576 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
578 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
579 "cmp{q}\t{%1, %0|%0, %1}"
580 [(set_attr "type" "icmp")
581 (set_attr "mode" "DI")])
583 (define_expand "cmpdi_1_rex64"
584 [(set (reg:CC FLAGS_REG)
585 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
586 (match_operand:DI 1 "general_operand" "")))]
590 (define_insn "cmpdi_1_insn_rex64"
591 [(set (reg FLAGS_REG)
592 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
593 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
594 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
595 "cmp{q}\t{%1, %0|%0, %1}"
596 [(set_attr "type" "icmp")
597 (set_attr "mode" "DI")])
600 (define_insn "*cmpsi_ccno_1"
601 [(set (reg FLAGS_REG)
602 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
603 (match_operand:SI 1 "const0_operand" "n,n")))]
604 "ix86_match_ccmode (insn, CCNOmode)"
606 test{l}\t{%0, %0|%0, %0}
607 cmp{l}\t{%1, %0|%0, %1}"
608 [(set_attr "type" "test,icmp")
609 (set_attr "length_immediate" "0,1")
610 (set_attr "mode" "SI")])
612 (define_insn "*cmpsi_minus_1"
613 [(set (reg FLAGS_REG)
614 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
615 (match_operand:SI 1 "general_operand" "ri,mr"))
617 "ix86_match_ccmode (insn, CCGOCmode)"
618 "cmp{l}\t{%1, %0|%0, %1}"
619 [(set_attr "type" "icmp")
620 (set_attr "mode" "SI")])
622 (define_expand "cmpsi_1"
623 [(set (reg:CC FLAGS_REG)
624 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625 (match_operand:SI 1 "general_operand" "ri,mr")))]
629 (define_insn "*cmpsi_1_insn"
630 [(set (reg FLAGS_REG)
631 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
632 (match_operand:SI 1 "general_operand" "ri,mr")))]
633 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
634 && ix86_match_ccmode (insn, CCmode)"
635 "cmp{l}\t{%1, %0|%0, %1}"
636 [(set_attr "type" "icmp")
637 (set_attr "mode" "SI")])
639 (define_insn "*cmphi_ccno_1"
640 [(set (reg FLAGS_REG)
641 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
642 (match_operand:HI 1 "const0_operand" "n,n")))]
643 "ix86_match_ccmode (insn, CCNOmode)"
645 test{w}\t{%0, %0|%0, %0}
646 cmp{w}\t{%1, %0|%0, %1}"
647 [(set_attr "type" "test,icmp")
648 (set_attr "length_immediate" "0,1")
649 (set_attr "mode" "HI")])
651 (define_insn "*cmphi_minus_1"
652 [(set (reg FLAGS_REG)
653 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
654 (match_operand:HI 1 "general_operand" "ri,mr"))
656 "ix86_match_ccmode (insn, CCGOCmode)"
657 "cmp{w}\t{%1, %0|%0, %1}"
658 [(set_attr "type" "icmp")
659 (set_attr "mode" "HI")])
661 (define_insn "*cmphi_1"
662 [(set (reg FLAGS_REG)
663 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
664 (match_operand:HI 1 "general_operand" "ri,mr")))]
665 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
666 && ix86_match_ccmode (insn, CCmode)"
667 "cmp{w}\t{%1, %0|%0, %1}"
668 [(set_attr "type" "icmp")
669 (set_attr "mode" "HI")])
671 (define_insn "*cmpqi_ccno_1"
672 [(set (reg FLAGS_REG)
673 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
674 (match_operand:QI 1 "const0_operand" "n,n")))]
675 "ix86_match_ccmode (insn, CCNOmode)"
677 test{b}\t{%0, %0|%0, %0}
678 cmp{b}\t{$0, %0|%0, 0}"
679 [(set_attr "type" "test,icmp")
680 (set_attr "length_immediate" "0,1")
681 (set_attr "mode" "QI")])
683 (define_insn "*cmpqi_1"
684 [(set (reg FLAGS_REG)
685 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
686 (match_operand:QI 1 "general_operand" "qi,mq")))]
687 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
688 && ix86_match_ccmode (insn, CCmode)"
689 "cmp{b}\t{%1, %0|%0, %1}"
690 [(set_attr "type" "icmp")
691 (set_attr "mode" "QI")])
693 (define_insn "*cmpqi_minus_1"
694 [(set (reg FLAGS_REG)
695 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
696 (match_operand:QI 1 "general_operand" "qi,mq"))
698 "ix86_match_ccmode (insn, CCGOCmode)"
699 "cmp{b}\t{%1, %0|%0, %1}"
700 [(set_attr "type" "icmp")
701 (set_attr "mode" "QI")])
703 (define_insn "*cmpqi_ext_1"
704 [(set (reg FLAGS_REG)
706 (match_operand:QI 0 "general_operand" "Qm")
709 (match_operand 1 "ext_register_operand" "Q")
712 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
713 "cmp{b}\t{%h1, %0|%0, %h1}"
714 [(set_attr "type" "icmp")
715 (set_attr "mode" "QI")])
717 (define_insn "*cmpqi_ext_1_rex64"
718 [(set (reg FLAGS_REG)
720 (match_operand:QI 0 "register_operand" "Q")
723 (match_operand 1 "ext_register_operand" "Q")
726 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
727 "cmp{b}\t{%h1, %0|%0, %h1}"
728 [(set_attr "type" "icmp")
729 (set_attr "mode" "QI")])
731 (define_insn "*cmpqi_ext_2"
732 [(set (reg FLAGS_REG)
736 (match_operand 0 "ext_register_operand" "Q")
739 (match_operand:QI 1 "const0_operand" "n")))]
740 "ix86_match_ccmode (insn, CCNOmode)"
742 [(set_attr "type" "test")
743 (set_attr "length_immediate" "0")
744 (set_attr "mode" "QI")])
746 (define_expand "cmpqi_ext_3"
747 [(set (reg:CC FLAGS_REG)
751 (match_operand 0 "ext_register_operand" "")
754 (match_operand:QI 1 "general_operand" "")))]
758 (define_insn "cmpqi_ext_3_insn"
759 [(set (reg FLAGS_REG)
763 (match_operand 0 "ext_register_operand" "Q")
766 (match_operand:QI 1 "general_operand" "Qmn")))]
767 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
768 "cmp{b}\t{%1, %h0|%h0, %1}"
769 [(set_attr "type" "icmp")
770 (set_attr "mode" "QI")])
772 (define_insn "cmpqi_ext_3_insn_rex64"
773 [(set (reg FLAGS_REG)
777 (match_operand 0 "ext_register_operand" "Q")
780 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
781 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
782 "cmp{b}\t{%1, %h0|%h0, %1}"
783 [(set_attr "type" "icmp")
784 (set_attr "mode" "QI")])
786 (define_insn "*cmpqi_ext_4"
787 [(set (reg FLAGS_REG)
791 (match_operand 0 "ext_register_operand" "Q")
796 (match_operand 1 "ext_register_operand" "Q")
799 "ix86_match_ccmode (insn, CCmode)"
800 "cmp{b}\t{%h1, %h0|%h0, %h1}"
801 [(set_attr "type" "icmp")
802 (set_attr "mode" "QI")])
804 ;; These implement float point compares.
805 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
806 ;; which would allow mix and match FP modes on the compares. Which is what
807 ;; the old patterns did, but with many more of them.
809 (define_expand "cmpxf"
810 [(set (reg:CC FLAGS_REG)
811 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
812 (match_operand:XF 1 "nonmemory_operand" "")))]
815 ix86_compare_op0 = operands[0];
816 ix86_compare_op1 = operands[1];
820 (define_expand "cmpdf"
821 [(set (reg:CC FLAGS_REG)
822 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
823 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
824 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
826 ix86_compare_op0 = operands[0];
827 ix86_compare_op1 = operands[1];
831 (define_expand "cmpsf"
832 [(set (reg:CC FLAGS_REG)
833 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
834 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
835 "TARGET_80387 || TARGET_SSE_MATH"
837 ix86_compare_op0 = operands[0];
838 ix86_compare_op1 = operands[1];
842 ;; FP compares, step 1:
843 ;; Set the FP condition codes.
845 ;; CCFPmode compare with exceptions
846 ;; CCFPUmode compare with no exceptions
848 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
849 ;; used to manage the reg stack popping would not be preserved.
851 (define_insn "*cmpfp_0"
852 [(set (match_operand:HI 0 "register_operand" "=a")
855 (match_operand 1 "register_operand" "f")
856 (match_operand 2 "const0_operand" "X"))]
859 && FLOAT_MODE_P (GET_MODE (operands[1]))
860 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
861 "* return output_fp_compare (insn, operands, 0, 0);"
862 [(set_attr "type" "multi")
863 (set_attr "unit" "i387")
865 (cond [(match_operand:SF 1 "" "")
867 (match_operand:DF 1 "" "")
870 (const_string "XF")))])
872 (define_insn "*cmpfp_sf"
873 [(set (match_operand:HI 0 "register_operand" "=a")
876 (match_operand:SF 1 "register_operand" "f")
877 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
880 "* return output_fp_compare (insn, operands, 0, 0);"
881 [(set_attr "type" "multi")
882 (set_attr "unit" "i387")
883 (set_attr "mode" "SF")])
885 (define_insn "*cmpfp_df"
886 [(set (match_operand:HI 0 "register_operand" "=a")
889 (match_operand:DF 1 "register_operand" "f")
890 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
893 "* return output_fp_compare (insn, operands, 0, 0);"
894 [(set_attr "type" "multi")
895 (set_attr "unit" "i387")
896 (set_attr "mode" "DF")])
898 (define_insn "*cmpfp_xf"
899 [(set (match_operand:HI 0 "register_operand" "=a")
902 (match_operand:XF 1 "register_operand" "f")
903 (match_operand:XF 2 "register_operand" "f"))]
906 "* return output_fp_compare (insn, operands, 0, 0);"
907 [(set_attr "type" "multi")
908 (set_attr "unit" "i387")
909 (set_attr "mode" "XF")])
911 (define_insn "*cmpfp_u"
912 [(set (match_operand:HI 0 "register_operand" "=a")
915 (match_operand 1 "register_operand" "f")
916 (match_operand 2 "register_operand" "f"))]
919 && FLOAT_MODE_P (GET_MODE (operands[1]))
920 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
921 "* return output_fp_compare (insn, operands, 0, 1);"
922 [(set_attr "type" "multi")
923 (set_attr "unit" "i387")
925 (cond [(match_operand:SF 1 "" "")
927 (match_operand:DF 1 "" "")
930 (const_string "XF")))])
932 (define_insn "*cmpfp_<mode>"
933 [(set (match_operand:HI 0 "register_operand" "=a")
936 (match_operand 1 "register_operand" "f")
937 (match_operator 3 "float_operator"
938 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
940 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
941 && FLOAT_MODE_P (GET_MODE (operands[1]))
942 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
943 "* return output_fp_compare (insn, operands, 0, 0);"
944 [(set_attr "type" "multi")
945 (set_attr "unit" "i387")
946 (set_attr "fp_int_src" "true")
947 (set_attr "mode" "<MODE>")])
949 ;; FP compares, step 2
950 ;; Move the fpsw to ax.
952 (define_insn "x86_fnstsw_1"
953 [(set (match_operand:HI 0 "register_operand" "=a")
954 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
957 [(set_attr "length" "2")
958 (set_attr "mode" "SI")
959 (set_attr "unit" "i387")])
961 ;; FP compares, step 3
962 ;; Get ax into flags, general case.
964 (define_insn "x86_sahf_1"
965 [(set (reg:CC FLAGS_REG)
966 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
969 [(set_attr "length" "1")
970 (set_attr "athlon_decode" "vector")
971 (set_attr "mode" "SI")])
973 ;; Pentium Pro can do steps 1 through 3 in one go.
975 (define_insn "*cmpfp_i_mixed"
976 [(set (reg:CCFP FLAGS_REG)
977 (compare:CCFP (match_operand 0 "register_operand" "f,x")
978 (match_operand 1 "nonimmediate_operand" "f,xm")))]
980 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
981 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
982 "* return output_fp_compare (insn, operands, 1, 0);"
983 [(set_attr "type" "fcmp,ssecomi")
985 (if_then_else (match_operand:SF 1 "" "")
987 (const_string "DF")))
988 (set_attr "athlon_decode" "vector")])
990 (define_insn "*cmpfp_i_sse"
991 [(set (reg:CCFP FLAGS_REG)
992 (compare:CCFP (match_operand 0 "register_operand" "x")
993 (match_operand 1 "nonimmediate_operand" "xm")))]
995 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
996 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
997 "* return output_fp_compare (insn, operands, 1, 0);"
998 [(set_attr "type" "ssecomi")
1000 (if_then_else (match_operand:SF 1 "" "")
1002 (const_string "DF")))
1003 (set_attr "athlon_decode" "vector")])
1005 (define_insn "*cmpfp_i_i387"
1006 [(set (reg:CCFP FLAGS_REG)
1007 (compare:CCFP (match_operand 0 "register_operand" "f")
1008 (match_operand 1 "register_operand" "f")))]
1009 "TARGET_80387 && TARGET_CMOVE
1010 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1011 && FLOAT_MODE_P (GET_MODE (operands[0]))
1012 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1013 "* return output_fp_compare (insn, operands, 1, 0);"
1014 [(set_attr "type" "fcmp")
1016 (cond [(match_operand:SF 1 "" "")
1018 (match_operand:DF 1 "" "")
1021 (const_string "XF")))
1022 (set_attr "athlon_decode" "vector")])
1024 (define_insn "*cmpfp_iu_mixed"
1025 [(set (reg:CCFPU FLAGS_REG)
1026 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1027 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1028 "TARGET_MIX_SSE_I387
1029 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1030 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1031 "* return output_fp_compare (insn, operands, 1, 1);"
1032 [(set_attr "type" "fcmp,ssecomi")
1034 (if_then_else (match_operand:SF 1 "" "")
1036 (const_string "DF")))
1037 (set_attr "athlon_decode" "vector")])
1039 (define_insn "*cmpfp_iu_sse"
1040 [(set (reg:CCFPU FLAGS_REG)
1041 (compare:CCFPU (match_operand 0 "register_operand" "x")
1042 (match_operand 1 "nonimmediate_operand" "xm")))]
1044 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1045 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1046 "* return output_fp_compare (insn, operands, 1, 1);"
1047 [(set_attr "type" "ssecomi")
1049 (if_then_else (match_operand:SF 1 "" "")
1051 (const_string "DF")))
1052 (set_attr "athlon_decode" "vector")])
1054 (define_insn "*cmpfp_iu_387"
1055 [(set (reg:CCFPU FLAGS_REG)
1056 (compare:CCFPU (match_operand 0 "register_operand" "f")
1057 (match_operand 1 "register_operand" "f")))]
1058 "TARGET_80387 && TARGET_CMOVE
1059 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1060 && FLOAT_MODE_P (GET_MODE (operands[0]))
1061 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1062 "* return output_fp_compare (insn, operands, 1, 1);"
1063 [(set_attr "type" "fcmp")
1065 (cond [(match_operand:SF 1 "" "")
1067 (match_operand:DF 1 "" "")
1070 (const_string "XF")))
1071 (set_attr "athlon_decode" "vector")])
1073 ;; Move instructions.
1075 ;; General case of fullword move.
1077 (define_expand "movsi"
1078 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1079 (match_operand:SI 1 "general_operand" ""))]
1081 "ix86_expand_move (SImode, operands); DONE;")
1083 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1086 ;; %%% We don't use a post-inc memory reference because x86 is not a
1087 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1088 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1089 ;; targets without our curiosities, and it is just as easy to represent
1090 ;; this differently.
1092 (define_insn "*pushsi2"
1093 [(set (match_operand:SI 0 "push_operand" "=<")
1094 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1097 [(set_attr "type" "push")
1098 (set_attr "mode" "SI")])
1100 ;; For 64BIT abi we always round up to 8 bytes.
1101 (define_insn "*pushsi2_rex64"
1102 [(set (match_operand:SI 0 "push_operand" "=X")
1103 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1106 [(set_attr "type" "push")
1107 (set_attr "mode" "SI")])
1109 (define_insn "*pushsi2_prologue"
1110 [(set (match_operand:SI 0 "push_operand" "=<")
1111 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1112 (clobber (mem:BLK (scratch)))]
1115 [(set_attr "type" "push")
1116 (set_attr "mode" "SI")])
1118 (define_insn "*popsi1_epilogue"
1119 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1120 (mem:SI (reg:SI SP_REG)))
1121 (set (reg:SI SP_REG)
1122 (plus:SI (reg:SI SP_REG) (const_int 4)))
1123 (clobber (mem:BLK (scratch)))]
1126 [(set_attr "type" "pop")
1127 (set_attr "mode" "SI")])
1129 (define_insn "popsi1"
1130 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1131 (mem:SI (reg:SI SP_REG)))
1132 (set (reg:SI SP_REG)
1133 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1136 [(set_attr "type" "pop")
1137 (set_attr "mode" "SI")])
1139 (define_insn "*movsi_xor"
1140 [(set (match_operand:SI 0 "register_operand" "=r")
1141 (match_operand:SI 1 "const0_operand" "i"))
1142 (clobber (reg:CC FLAGS_REG))]
1143 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1144 "xor{l}\t{%0, %0|%0, %0}"
1145 [(set_attr "type" "alu1")
1146 (set_attr "mode" "SI")
1147 (set_attr "length_immediate" "0")])
1149 (define_insn "*movsi_or"
1150 [(set (match_operand:SI 0 "register_operand" "=r")
1151 (match_operand:SI 1 "immediate_operand" "i"))
1152 (clobber (reg:CC FLAGS_REG))]
1154 && operands[1] == constm1_rtx
1155 && (TARGET_PENTIUM || optimize_size)"
1157 operands[1] = constm1_rtx;
1158 return "or{l}\t{%1, %0|%0, %1}";
1160 [(set_attr "type" "alu1")
1161 (set_attr "mode" "SI")
1162 (set_attr "length_immediate" "1")])
1164 (define_insn "*movsi_1"
1165 [(set (match_operand:SI 0 "nonimmediate_operand"
1166 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1167 (match_operand:SI 1 "general_operand"
1168 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1169 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1171 switch (get_attr_type (insn))
1174 if (get_attr_mode (insn) == MODE_TI)
1175 return "pxor\t%0, %0";
1176 return "xorps\t%0, %0";
1179 switch (get_attr_mode (insn))
1182 return "movdqa\t{%1, %0|%0, %1}";
1184 return "movaps\t{%1, %0|%0, %1}";
1186 return "movd\t{%1, %0|%0, %1}";
1188 return "movss\t{%1, %0|%0, %1}";
1194 return "pxor\t%0, %0";
1197 if (get_attr_mode (insn) == MODE_DI)
1198 return "movq\t{%1, %0|%0, %1}";
1199 return "movd\t{%1, %0|%0, %1}";
1202 return "lea{l}\t{%1, %0|%0, %1}";
1205 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1206 return "mov{l}\t{%1, %0|%0, %1}";
1210 (cond [(eq_attr "alternative" "2")
1211 (const_string "mmxadd")
1212 (eq_attr "alternative" "3,4,5")
1213 (const_string "mmxmov")
1214 (eq_attr "alternative" "6")
1215 (const_string "sselog1")
1216 (eq_attr "alternative" "7,8,9,10,11")
1217 (const_string "ssemov")
1218 (match_operand:DI 1 "pic_32bit_operand" "")
1219 (const_string "lea")
1221 (const_string "imov")))
1223 (cond [(eq_attr "alternative" "2,3")
1225 (eq_attr "alternative" "6,7")
1227 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1228 (const_string "V4SF")
1229 (const_string "TI"))
1230 (and (eq_attr "alternative" "8,9,10,11")
1231 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1234 (const_string "SI")))])
1236 ;; Stores and loads of ax to arbitrary constant address.
1237 ;; We fake an second form of instruction to force reload to load address
1238 ;; into register when rax is not available
1239 (define_insn "*movabssi_1_rex64"
1240 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1241 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1242 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1244 movabs{l}\t{%1, %P0|%P0, %1}
1245 mov{l}\t{%1, %a0|%a0, %1}"
1246 [(set_attr "type" "imov")
1247 (set_attr "modrm" "0,*")
1248 (set_attr "length_address" "8,0")
1249 (set_attr "length_immediate" "0,*")
1250 (set_attr "memory" "store")
1251 (set_attr "mode" "SI")])
1253 (define_insn "*movabssi_2_rex64"
1254 [(set (match_operand:SI 0 "register_operand" "=a,r")
1255 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1256 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1258 movabs{l}\t{%P1, %0|%0, %P1}
1259 mov{l}\t{%a1, %0|%0, %a1}"
1260 [(set_attr "type" "imov")
1261 (set_attr "modrm" "0,*")
1262 (set_attr "length_address" "8,0")
1263 (set_attr "length_immediate" "0")
1264 (set_attr "memory" "load")
1265 (set_attr "mode" "SI")])
1267 (define_insn "*swapsi"
1268 [(set (match_operand:SI 0 "register_operand" "+r")
1269 (match_operand:SI 1 "register_operand" "+r"))
1274 [(set_attr "type" "imov")
1275 (set_attr "mode" "SI")
1276 (set_attr "pent_pair" "np")
1277 (set_attr "athlon_decode" "vector")])
1279 (define_expand "movhi"
1280 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1281 (match_operand:HI 1 "general_operand" ""))]
1283 "ix86_expand_move (HImode, operands); DONE;")
1285 (define_insn "*pushhi2"
1286 [(set (match_operand:HI 0 "push_operand" "=X")
1287 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1290 [(set_attr "type" "push")
1291 (set_attr "mode" "SI")])
1293 ;; For 64BIT abi we always round up to 8 bytes.
1294 (define_insn "*pushhi2_rex64"
1295 [(set (match_operand:HI 0 "push_operand" "=X")
1296 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1299 [(set_attr "type" "push")
1300 (set_attr "mode" "DI")])
1302 (define_insn "*movhi_1"
1303 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1304 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1305 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1307 switch (get_attr_type (insn))
1310 /* movzwl is faster than movw on p2 due to partial word stalls,
1311 though not as fast as an aligned movl. */
1312 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1314 if (get_attr_mode (insn) == MODE_SI)
1315 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1317 return "mov{w}\t{%1, %0|%0, %1}";
1321 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1322 (const_string "imov")
1323 (and (eq_attr "alternative" "0")
1324 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1326 (eq (symbol_ref "TARGET_HIMODE_MATH")
1328 (const_string "imov")
1329 (and (eq_attr "alternative" "1,2")
1330 (match_operand:HI 1 "aligned_operand" ""))
1331 (const_string "imov")
1332 (and (ne (symbol_ref "TARGET_MOVX")
1334 (eq_attr "alternative" "0,2"))
1335 (const_string "imovx")
1337 (const_string "imov")))
1339 (cond [(eq_attr "type" "imovx")
1341 (and (eq_attr "alternative" "1,2")
1342 (match_operand:HI 1 "aligned_operand" ""))
1344 (and (eq_attr "alternative" "0")
1345 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1347 (eq (symbol_ref "TARGET_HIMODE_MATH")
1351 (const_string "HI")))])
1353 ;; Stores and loads of ax to arbitrary constant address.
1354 ;; We fake an second form of instruction to force reload to load address
1355 ;; into register when rax is not available
1356 (define_insn "*movabshi_1_rex64"
1357 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1358 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1359 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1361 movabs{w}\t{%1, %P0|%P0, %1}
1362 mov{w}\t{%1, %a0|%a0, %1}"
1363 [(set_attr "type" "imov")
1364 (set_attr "modrm" "0,*")
1365 (set_attr "length_address" "8,0")
1366 (set_attr "length_immediate" "0,*")
1367 (set_attr "memory" "store")
1368 (set_attr "mode" "HI")])
1370 (define_insn "*movabshi_2_rex64"
1371 [(set (match_operand:HI 0 "register_operand" "=a,r")
1372 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1373 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1375 movabs{w}\t{%P1, %0|%0, %P1}
1376 mov{w}\t{%a1, %0|%0, %a1}"
1377 [(set_attr "type" "imov")
1378 (set_attr "modrm" "0,*")
1379 (set_attr "length_address" "8,0")
1380 (set_attr "length_immediate" "0")
1381 (set_attr "memory" "load")
1382 (set_attr "mode" "HI")])
1384 (define_insn "*swaphi_1"
1385 [(set (match_operand:HI 0 "register_operand" "+r")
1386 (match_operand:HI 1 "register_operand" "+r"))
1389 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1391 [(set_attr "type" "imov")
1392 (set_attr "mode" "SI")
1393 (set_attr "pent_pair" "np")
1394 (set_attr "athlon_decode" "vector")])
1396 (define_insn "*swaphi_2"
1397 [(set (match_operand:HI 0 "register_operand" "+r")
1398 (match_operand:HI 1 "register_operand" "+r"))
1401 "TARGET_PARTIAL_REG_STALL"
1403 [(set_attr "type" "imov")
1404 (set_attr "mode" "HI")
1405 (set_attr "pent_pair" "np")
1406 (set_attr "athlon_decode" "vector")])
1408 (define_expand "movstricthi"
1409 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1410 (match_operand:HI 1 "general_operand" ""))]
1411 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1413 /* Don't generate memory->memory moves, go through a register */
1414 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1415 operands[1] = force_reg (HImode, operands[1]);
1418 (define_insn "*movstricthi_1"
1419 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1420 (match_operand:HI 1 "general_operand" "rn,m"))]
1421 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1422 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1423 "mov{w}\t{%1, %0|%0, %1}"
1424 [(set_attr "type" "imov")
1425 (set_attr "mode" "HI")])
1427 (define_insn "*movstricthi_xor"
1428 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1429 (match_operand:HI 1 "const0_operand" "i"))
1430 (clobber (reg:CC FLAGS_REG))]
1432 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1433 "xor{w}\t{%0, %0|%0, %0}"
1434 [(set_attr "type" "alu1")
1435 (set_attr "mode" "HI")
1436 (set_attr "length_immediate" "0")])
1438 (define_expand "movqi"
1439 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1440 (match_operand:QI 1 "general_operand" ""))]
1442 "ix86_expand_move (QImode, operands); DONE;")
1444 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1445 ;; "push a byte". But actually we use pushl, which has the effect
1446 ;; of rounding the amount pushed up to a word.
1448 (define_insn "*pushqi2"
1449 [(set (match_operand:QI 0 "push_operand" "=X")
1450 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1453 [(set_attr "type" "push")
1454 (set_attr "mode" "SI")])
1456 ;; For 64BIT abi we always round up to 8 bytes.
1457 (define_insn "*pushqi2_rex64"
1458 [(set (match_operand:QI 0 "push_operand" "=X")
1459 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1462 [(set_attr "type" "push")
1463 (set_attr "mode" "DI")])
1465 ;; Situation is quite tricky about when to choose full sized (SImode) move
1466 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1467 ;; partial register dependency machines (such as AMD Athlon), where QImode
1468 ;; moves issue extra dependency and for partial register stalls machines
1469 ;; that don't use QImode patterns (and QImode move cause stall on the next
1472 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1473 ;; register stall machines with, where we use QImode instructions, since
1474 ;; partial register stall can be caused there. Then we use movzx.
1475 (define_insn "*movqi_1"
1476 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1477 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1478 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1480 switch (get_attr_type (insn))
1483 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1484 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1486 if (get_attr_mode (insn) == MODE_SI)
1487 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1489 return "mov{b}\t{%1, %0|%0, %1}";
1493 (cond [(and (eq_attr "alternative" "5")
1494 (not (match_operand:QI 1 "aligned_operand" "")))
1495 (const_string "imovx")
1496 (ne (symbol_ref "optimize_size") (const_int 0))
1497 (const_string "imov")
1498 (and (eq_attr "alternative" "3")
1499 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1501 (eq (symbol_ref "TARGET_QIMODE_MATH")
1503 (const_string "imov")
1504 (eq_attr "alternative" "3,5")
1505 (const_string "imovx")
1506 (and (ne (symbol_ref "TARGET_MOVX")
1508 (eq_attr "alternative" "2"))
1509 (const_string "imovx")
1511 (const_string "imov")))
1513 (cond [(eq_attr "alternative" "3,4,5")
1515 (eq_attr "alternative" "6")
1517 (eq_attr "type" "imovx")
1519 (and (eq_attr "type" "imov")
1520 (and (eq_attr "alternative" "0,1")
1521 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1523 (and (eq (symbol_ref "optimize_size")
1525 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1528 ;; Avoid partial register stalls when not using QImode arithmetic
1529 (and (eq_attr "type" "imov")
1530 (and (eq_attr "alternative" "0,1")
1531 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1533 (eq (symbol_ref "TARGET_QIMODE_MATH")
1537 (const_string "QI")))])
1539 (define_expand "reload_outqi"
1540 [(parallel [(match_operand:QI 0 "" "=m")
1541 (match_operand:QI 1 "register_operand" "r")
1542 (match_operand:QI 2 "register_operand" "=&q")])]
1546 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1548 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1549 if (! q_regs_operand (op1, QImode))
1551 emit_insn (gen_movqi (op2, op1));
1554 emit_insn (gen_movqi (op0, op1));
1558 (define_insn "*swapqi_1"
1559 [(set (match_operand:QI 0 "register_operand" "+r")
1560 (match_operand:QI 1 "register_operand" "+r"))
1563 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1565 [(set_attr "type" "imov")
1566 (set_attr "mode" "SI")
1567 (set_attr "pent_pair" "np")
1568 (set_attr "athlon_decode" "vector")])
1570 (define_insn "*swapqi_2"
1571 [(set (match_operand:QI 0 "register_operand" "+q")
1572 (match_operand:QI 1 "register_operand" "+q"))
1575 "TARGET_PARTIAL_REG_STALL"
1577 [(set_attr "type" "imov")
1578 (set_attr "mode" "QI")
1579 (set_attr "pent_pair" "np")
1580 (set_attr "athlon_decode" "vector")])
1582 (define_expand "movstrictqi"
1583 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1584 (match_operand:QI 1 "general_operand" ""))]
1585 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1587 /* Don't generate memory->memory moves, go through a register. */
1588 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1589 operands[1] = force_reg (QImode, operands[1]);
1592 (define_insn "*movstrictqi_1"
1593 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1594 (match_operand:QI 1 "general_operand" "*qn,m"))]
1595 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1596 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1597 "mov{b}\t{%1, %0|%0, %1}"
1598 [(set_attr "type" "imov")
1599 (set_attr "mode" "QI")])
1601 (define_insn "*movstrictqi_xor"
1602 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1603 (match_operand:QI 1 "const0_operand" "i"))
1604 (clobber (reg:CC FLAGS_REG))]
1605 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1606 "xor{b}\t{%0, %0|%0, %0}"
1607 [(set_attr "type" "alu1")
1608 (set_attr "mode" "QI")
1609 (set_attr "length_immediate" "0")])
1611 (define_insn "*movsi_extv_1"
1612 [(set (match_operand:SI 0 "register_operand" "=R")
1613 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1617 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1618 [(set_attr "type" "imovx")
1619 (set_attr "mode" "SI")])
1621 (define_insn "*movhi_extv_1"
1622 [(set (match_operand:HI 0 "register_operand" "=R")
1623 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1627 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1628 [(set_attr "type" "imovx")
1629 (set_attr "mode" "SI")])
1631 (define_insn "*movqi_extv_1"
1632 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1633 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1638 switch (get_attr_type (insn))
1641 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1643 return "mov{b}\t{%h1, %0|%0, %h1}";
1647 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1648 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1649 (ne (symbol_ref "TARGET_MOVX")
1651 (const_string "imovx")
1652 (const_string "imov")))
1654 (if_then_else (eq_attr "type" "imovx")
1656 (const_string "QI")))])
1658 (define_insn "*movqi_extv_1_rex64"
1659 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1660 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1665 switch (get_attr_type (insn))
1668 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1670 return "mov{b}\t{%h1, %0|%0, %h1}";
1674 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1675 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1676 (ne (symbol_ref "TARGET_MOVX")
1678 (const_string "imovx")
1679 (const_string "imov")))
1681 (if_then_else (eq_attr "type" "imovx")
1683 (const_string "QI")))])
1685 ;; Stores and loads of ax to arbitrary constant address.
1686 ;; We fake an second form of instruction to force reload to load address
1687 ;; into register when rax is not available
1688 (define_insn "*movabsqi_1_rex64"
1689 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1690 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1691 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1693 movabs{b}\t{%1, %P0|%P0, %1}
1694 mov{b}\t{%1, %a0|%a0, %1}"
1695 [(set_attr "type" "imov")
1696 (set_attr "modrm" "0,*")
1697 (set_attr "length_address" "8,0")
1698 (set_attr "length_immediate" "0,*")
1699 (set_attr "memory" "store")
1700 (set_attr "mode" "QI")])
1702 (define_insn "*movabsqi_2_rex64"
1703 [(set (match_operand:QI 0 "register_operand" "=a,r")
1704 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1705 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1707 movabs{b}\t{%P1, %0|%0, %P1}
1708 mov{b}\t{%a1, %0|%0, %a1}"
1709 [(set_attr "type" "imov")
1710 (set_attr "modrm" "0,*")
1711 (set_attr "length_address" "8,0")
1712 (set_attr "length_immediate" "0")
1713 (set_attr "memory" "load")
1714 (set_attr "mode" "QI")])
1716 (define_insn "*movdi_extzv_1"
1717 [(set (match_operand:DI 0 "register_operand" "=R")
1718 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1722 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1723 [(set_attr "type" "imovx")
1724 (set_attr "mode" "DI")])
1726 (define_insn "*movsi_extzv_1"
1727 [(set (match_operand:SI 0 "register_operand" "=R")
1728 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1732 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1733 [(set_attr "type" "imovx")
1734 (set_attr "mode" "SI")])
1736 (define_insn "*movqi_extzv_2"
1737 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1738 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1743 switch (get_attr_type (insn))
1746 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1748 return "mov{b}\t{%h1, %0|%0, %h1}";
1752 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1753 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1754 (ne (symbol_ref "TARGET_MOVX")
1756 (const_string "imovx")
1757 (const_string "imov")))
1759 (if_then_else (eq_attr "type" "imovx")
1761 (const_string "QI")))])
1763 (define_insn "*movqi_extzv_2_rex64"
1764 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1765 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1770 switch (get_attr_type (insn))
1773 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1775 return "mov{b}\t{%h1, %0|%0, %h1}";
1779 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1780 (ne (symbol_ref "TARGET_MOVX")
1782 (const_string "imovx")
1783 (const_string "imov")))
1785 (if_then_else (eq_attr "type" "imovx")
1787 (const_string "QI")))])
1789 (define_insn "movsi_insv_1"
1790 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1793 (match_operand:SI 1 "general_operand" "Qmn"))]
1795 "mov{b}\t{%b1, %h0|%h0, %b1}"
1796 [(set_attr "type" "imov")
1797 (set_attr "mode" "QI")])
1799 (define_insn "movdi_insv_1_rex64"
1800 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1803 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1805 "mov{b}\t{%b1, %h0|%h0, %b1}"
1806 [(set_attr "type" "imov")
1807 (set_attr "mode" "QI")])
1809 (define_insn "*movqi_insv_2"
1810 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1813 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1816 "mov{b}\t{%h1, %h0|%h0, %h1}"
1817 [(set_attr "type" "imov")
1818 (set_attr "mode" "QI")])
1820 (define_expand "movdi"
1821 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1822 (match_operand:DI 1 "general_operand" ""))]
1824 "ix86_expand_move (DImode, operands); DONE;")
1826 (define_insn "*pushdi"
1827 [(set (match_operand:DI 0 "push_operand" "=<")
1828 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1832 (define_insn "*pushdi2_rex64"
1833 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1834 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1839 [(set_attr "type" "push,multi")
1840 (set_attr "mode" "DI")])
1842 ;; Convert impossible pushes of immediate to existing instructions.
1843 ;; First try to get scratch register and go through it. In case this
1844 ;; fails, push sign extended lower part first and then overwrite
1845 ;; upper part by 32bit move.
1847 [(match_scratch:DI 2 "r")
1848 (set (match_operand:DI 0 "push_operand" "")
1849 (match_operand:DI 1 "immediate_operand" ""))]
1850 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1851 && !x86_64_immediate_operand (operands[1], DImode)"
1852 [(set (match_dup 2) (match_dup 1))
1853 (set (match_dup 0) (match_dup 2))]
1856 ;; We need to define this as both peepholer and splitter for case
1857 ;; peephole2 pass is not run.
1858 ;; "&& 1" is needed to keep it from matching the previous pattern.
1860 [(set (match_operand:DI 0 "push_operand" "")
1861 (match_operand:DI 1 "immediate_operand" ""))]
1862 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1863 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1864 [(set (match_dup 0) (match_dup 1))
1865 (set (match_dup 2) (match_dup 3))]
1866 "split_di (operands + 1, 1, operands + 2, operands + 3);
1867 operands[1] = gen_lowpart (DImode, operands[2]);
1868 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1873 [(set (match_operand:DI 0 "push_operand" "")
1874 (match_operand:DI 1 "immediate_operand" ""))]
1875 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1876 ? flow2_completed : reload_completed)
1877 && !symbolic_operand (operands[1], DImode)
1878 && !x86_64_immediate_operand (operands[1], DImode)"
1879 [(set (match_dup 0) (match_dup 1))
1880 (set (match_dup 2) (match_dup 3))]
1881 "split_di (operands + 1, 1, operands + 2, operands + 3);
1882 operands[1] = gen_lowpart (DImode, operands[2]);
1883 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1887 (define_insn "*pushdi2_prologue_rex64"
1888 [(set (match_operand:DI 0 "push_operand" "=<")
1889 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1890 (clobber (mem:BLK (scratch)))]
1893 [(set_attr "type" "push")
1894 (set_attr "mode" "DI")])
1896 (define_insn "*popdi1_epilogue_rex64"
1897 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1898 (mem:DI (reg:DI SP_REG)))
1899 (set (reg:DI SP_REG)
1900 (plus:DI (reg:DI SP_REG) (const_int 8)))
1901 (clobber (mem:BLK (scratch)))]
1904 [(set_attr "type" "pop")
1905 (set_attr "mode" "DI")])
1907 (define_insn "popdi1"
1908 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1909 (mem:DI (reg:DI SP_REG)))
1910 (set (reg:DI SP_REG)
1911 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1914 [(set_attr "type" "pop")
1915 (set_attr "mode" "DI")])
1917 (define_insn "*movdi_xor_rex64"
1918 [(set (match_operand:DI 0 "register_operand" "=r")
1919 (match_operand:DI 1 "const0_operand" "i"))
1920 (clobber (reg:CC FLAGS_REG))]
1921 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1922 && reload_completed"
1923 "xor{l}\t{%k0, %k0|%k0, %k0}"
1924 [(set_attr "type" "alu1")
1925 (set_attr "mode" "SI")
1926 (set_attr "length_immediate" "0")])
1928 (define_insn "*movdi_or_rex64"
1929 [(set (match_operand:DI 0 "register_operand" "=r")
1930 (match_operand:DI 1 "const_int_operand" "i"))
1931 (clobber (reg:CC FLAGS_REG))]
1932 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1934 && operands[1] == constm1_rtx"
1936 operands[1] = constm1_rtx;
1937 return "or{q}\t{%1, %0|%0, %1}";
1939 [(set_attr "type" "alu1")
1940 (set_attr "mode" "DI")
1941 (set_attr "length_immediate" "1")])
1943 (define_insn "*movdi_2"
1944 [(set (match_operand:DI 0 "nonimmediate_operand"
1945 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1946 (match_operand:DI 1 "general_operand"
1947 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1948 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1953 movq\t{%1, %0|%0, %1}
1954 movq\t{%1, %0|%0, %1}
1956 movq\t{%1, %0|%0, %1}
1957 movdqa\t{%1, %0|%0, %1}
1958 movq\t{%1, %0|%0, %1}
1960 movlps\t{%1, %0|%0, %1}
1961 movaps\t{%1, %0|%0, %1}
1962 movlps\t{%1, %0|%0, %1}"
1963 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1964 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1967 [(set (match_operand:DI 0 "push_operand" "")
1968 (match_operand:DI 1 "general_operand" ""))]
1969 "!TARGET_64BIT && reload_completed
1970 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1972 "ix86_split_long_move (operands); DONE;")
1974 ;; %%% This multiword shite has got to go.
1976 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1977 (match_operand:DI 1 "general_operand" ""))]
1978 "!TARGET_64BIT && reload_completed
1979 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1980 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1982 "ix86_split_long_move (operands); DONE;")
1984 (define_insn "*movdi_1_rex64"
1985 [(set (match_operand:DI 0 "nonimmediate_operand"
1986 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1987 (match_operand:DI 1 "general_operand"
1988 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1989 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1991 switch (get_attr_type (insn))
1994 if (which_alternative == 13)
1995 return "movq2dq\t{%1, %0|%0, %1}";
1997 return "movdq2q\t{%1, %0|%0, %1}";
1999 if (get_attr_mode (insn) == MODE_TI)
2000 return "movdqa\t{%1, %0|%0, %1}";
2003 /* Moves from and into integer register is done using movd opcode with
2005 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2006 return "movd\t{%1, %0|%0, %1}";
2007 return "movq\t{%1, %0|%0, %1}";
2010 return "pxor\t%0, %0";
2014 return "lea{q}\t{%a1, %0|%0, %a1}";
2016 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2017 if (get_attr_mode (insn) == MODE_SI)
2018 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2019 else if (which_alternative == 2)
2020 return "movabs{q}\t{%1, %0|%0, %1}";
2022 return "mov{q}\t{%1, %0|%0, %1}";
2026 (cond [(eq_attr "alternative" "5")
2027 (const_string "mmxadd")
2028 (eq_attr "alternative" "6,7,8")
2029 (const_string "mmxmov")
2030 (eq_attr "alternative" "9")
2031 (const_string "sselog1")
2032 (eq_attr "alternative" "10,11,12")
2033 (const_string "ssemov")
2034 (eq_attr "alternative" "13,14")
2035 (const_string "ssecvt")
2036 (eq_attr "alternative" "4")
2037 (const_string "multi")
2038 (match_operand:DI 1 "pic_32bit_operand" "")
2039 (const_string "lea")
2041 (const_string "imov")))
2042 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2043 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2044 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2046 ;; Stores and loads of ax to arbitrary constant address.
2047 ;; We fake an second form of instruction to force reload to load address
2048 ;; into register when rax is not available
2049 (define_insn "*movabsdi_1_rex64"
2050 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2051 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2052 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2054 movabs{q}\t{%1, %P0|%P0, %1}
2055 mov{q}\t{%1, %a0|%a0, %1}"
2056 [(set_attr "type" "imov")
2057 (set_attr "modrm" "0,*")
2058 (set_attr "length_address" "8,0")
2059 (set_attr "length_immediate" "0,*")
2060 (set_attr "memory" "store")
2061 (set_attr "mode" "DI")])
2063 (define_insn "*movabsdi_2_rex64"
2064 [(set (match_operand:DI 0 "register_operand" "=a,r")
2065 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2066 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2068 movabs{q}\t{%P1, %0|%0, %P1}
2069 mov{q}\t{%a1, %0|%0, %a1}"
2070 [(set_attr "type" "imov")
2071 (set_attr "modrm" "0,*")
2072 (set_attr "length_address" "8,0")
2073 (set_attr "length_immediate" "0")
2074 (set_attr "memory" "load")
2075 (set_attr "mode" "DI")])
2077 ;; Convert impossible stores of immediate to existing instructions.
2078 ;; First try to get scratch register and go through it. In case this
2079 ;; fails, move by 32bit parts.
2081 [(match_scratch:DI 2 "r")
2082 (set (match_operand:DI 0 "memory_operand" "")
2083 (match_operand:DI 1 "immediate_operand" ""))]
2084 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2085 && !x86_64_immediate_operand (operands[1], DImode)"
2086 [(set (match_dup 2) (match_dup 1))
2087 (set (match_dup 0) (match_dup 2))]
2090 ;; We need to define this as both peepholer and splitter for case
2091 ;; peephole2 pass is not run.
2092 ;; "&& 1" is needed to keep it from matching the previous pattern.
2094 [(set (match_operand:DI 0 "memory_operand" "")
2095 (match_operand:DI 1 "immediate_operand" ""))]
2096 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2097 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2098 [(set (match_dup 2) (match_dup 3))
2099 (set (match_dup 4) (match_dup 5))]
2100 "split_di (operands, 2, operands + 2, operands + 4);")
2103 [(set (match_operand:DI 0 "memory_operand" "")
2104 (match_operand:DI 1 "immediate_operand" ""))]
2105 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2106 ? flow2_completed : reload_completed)
2107 && !symbolic_operand (operands[1], DImode)
2108 && !x86_64_immediate_operand (operands[1], DImode)"
2109 [(set (match_dup 2) (match_dup 3))
2110 (set (match_dup 4) (match_dup 5))]
2111 "split_di (operands, 2, operands + 2, operands + 4);")
2113 (define_insn "*swapdi_rex64"
2114 [(set (match_operand:DI 0 "register_operand" "+r")
2115 (match_operand:DI 1 "register_operand" "+r"))
2120 [(set_attr "type" "imov")
2121 (set_attr "mode" "DI")
2122 (set_attr "pent_pair" "np")
2123 (set_attr "athlon_decode" "vector")])
2125 (define_expand "movti"
2126 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2127 (match_operand:TI 1 "nonimmediate_operand" ""))]
2128 "TARGET_SSE || TARGET_64BIT"
2131 ix86_expand_move (TImode, operands);
2133 ix86_expand_vector_move (TImode, operands);
2137 (define_insn "*movti_internal"
2138 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2139 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2140 "TARGET_SSE && !TARGET_64BIT
2141 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2143 switch (which_alternative)
2146 if (get_attr_mode (insn) == MODE_V4SF)
2147 return "xorps\t%0, %0";
2149 return "pxor\t%0, %0";
2152 if (get_attr_mode (insn) == MODE_V4SF)
2153 return "movaps\t{%1, %0|%0, %1}";
2155 return "movdqa\t{%1, %0|%0, %1}";
2160 [(set_attr "type" "sselog1,ssemov,ssemov")
2162 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2163 (ne (symbol_ref "optimize_size") (const_int 0)))
2164 (const_string "V4SF")
2165 (and (eq_attr "alternative" "2")
2166 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2168 (const_string "V4SF")]
2169 (const_string "TI")))])
2171 (define_insn "*movti_rex64"
2172 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2173 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2175 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2177 switch (which_alternative)
2183 if (get_attr_mode (insn) == MODE_V4SF)
2184 return "xorps\t%0, %0";
2186 return "pxor\t%0, %0";
2189 if (get_attr_mode (insn) == MODE_V4SF)
2190 return "movaps\t{%1, %0|%0, %1}";
2192 return "movdqa\t{%1, %0|%0, %1}";
2197 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2199 (cond [(eq_attr "alternative" "2,3")
2201 (ne (symbol_ref "optimize_size")
2203 (const_string "V4SF")
2204 (const_string "TI"))
2205 (eq_attr "alternative" "4")
2207 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2209 (ne (symbol_ref "optimize_size")
2211 (const_string "V4SF")
2212 (const_string "TI"))]
2213 (const_string "DI")))])
2216 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2217 (match_operand:TI 1 "general_operand" ""))]
2218 "reload_completed && !SSE_REG_P (operands[0])
2219 && !SSE_REG_P (operands[1])"
2221 "ix86_split_long_move (operands); DONE;")
2223 (define_expand "movsf"
2224 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2225 (match_operand:SF 1 "general_operand" ""))]
2227 "ix86_expand_move (SFmode, operands); DONE;")
2229 (define_insn "*pushsf"
2230 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2231 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2234 /* Anything else should be already split before reg-stack. */
2235 gcc_assert (which_alternative == 1);
2236 return "push{l}\t%1";
2238 [(set_attr "type" "multi,push,multi")
2239 (set_attr "unit" "i387,*,*")
2240 (set_attr "mode" "SF,SI,SF")])
2242 (define_insn "*pushsf_rex64"
2243 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2244 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2247 /* Anything else should be already split before reg-stack. */
2248 gcc_assert (which_alternative == 1);
2249 return "push{q}\t%q1";
2251 [(set_attr "type" "multi,push,multi")
2252 (set_attr "unit" "i387,*,*")
2253 (set_attr "mode" "SF,DI,SF")])
2256 [(set (match_operand:SF 0 "push_operand" "")
2257 (match_operand:SF 1 "memory_operand" ""))]
2259 && GET_CODE (operands[1]) == MEM
2260 && constant_pool_reference_p (operands[1])"
2263 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2266 ;; %%% Kill this when call knows how to work this out.
2268 [(set (match_operand:SF 0 "push_operand" "")
2269 (match_operand:SF 1 "any_fp_register_operand" ""))]
2271 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2272 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2275 [(set (match_operand:SF 0 "push_operand" "")
2276 (match_operand:SF 1 "any_fp_register_operand" ""))]
2278 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2279 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2281 (define_insn "*movsf_1"
2282 [(set (match_operand:SF 0 "nonimmediate_operand"
2283 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2284 (match_operand:SF 1 "general_operand"
2285 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2286 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2287 && (reload_in_progress || reload_completed
2288 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2289 || GET_CODE (operands[1]) != CONST_DOUBLE
2290 || memory_operand (operands[0], SFmode))"
2292 switch (which_alternative)
2295 return output_387_reg_move (insn, operands);
2298 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2299 return "fstp%z0\t%y0";
2301 return "fst%z0\t%y0";
2304 return standard_80387_constant_opcode (operands[1]);
2308 return "mov{l}\t{%1, %0|%0, %1}";
2310 if (get_attr_mode (insn) == MODE_TI)
2311 return "pxor\t%0, %0";
2313 return "xorps\t%0, %0";
2315 if (get_attr_mode (insn) == MODE_V4SF)
2316 return "movaps\t{%1, %0|%0, %1}";
2318 return "movss\t{%1, %0|%0, %1}";
2321 return "movss\t{%1, %0|%0, %1}";
2325 return "movd\t{%1, %0|%0, %1}";
2328 return "movq\t{%1, %0|%0, %1}";
2334 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2336 (cond [(eq_attr "alternative" "3,4,9,10")
2338 (eq_attr "alternative" "5")
2340 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2342 (ne (symbol_ref "TARGET_SSE2")
2344 (eq (symbol_ref "optimize_size")
2347 (const_string "V4SF"))
2348 /* For architectures resolving dependencies on
2349 whole SSE registers use APS move to break dependency
2350 chains, otherwise use short move to avoid extra work.
2352 Do the same for architectures resolving dependencies on
2353 the parts. While in DF mode it is better to always handle
2354 just register parts, the SF mode is different due to lack
2355 of instructions to load just part of the register. It is
2356 better to maintain the whole registers in single format
2357 to avoid problems on using packed logical operations. */
2358 (eq_attr "alternative" "6")
2360 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2362 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2364 (const_string "V4SF")
2365 (const_string "SF"))
2366 (eq_attr "alternative" "11")
2367 (const_string "DI")]
2368 (const_string "SF")))])
2370 (define_insn "*swapsf"
2371 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2372 (match_operand:SF 1 "fp_register_operand" "+f"))
2375 "reload_completed || TARGET_80387"
2377 if (STACK_TOP_P (operands[0]))
2382 [(set_attr "type" "fxch")
2383 (set_attr "mode" "SF")])
2385 (define_expand "movdf"
2386 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2387 (match_operand:DF 1 "general_operand" ""))]
2389 "ix86_expand_move (DFmode, operands); DONE;")
2391 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2392 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2393 ;; On the average, pushdf using integers can be still shorter. Allow this
2394 ;; pattern for optimize_size too.
2396 (define_insn "*pushdf_nointeger"
2397 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2398 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2399 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2401 /* This insn should be already split before reg-stack. */
2404 [(set_attr "type" "multi")
2405 (set_attr "unit" "i387,*,*,*")
2406 (set_attr "mode" "DF,SI,SI,DF")])
2408 (define_insn "*pushdf_integer"
2409 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2410 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2411 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2413 /* This insn should be already split before reg-stack. */
2416 [(set_attr "type" "multi")
2417 (set_attr "unit" "i387,*,*")
2418 (set_attr "mode" "DF,SI,DF")])
2420 ;; %%% Kill this when call knows how to work this out.
2422 [(set (match_operand:DF 0 "push_operand" "")
2423 (match_operand:DF 1 "any_fp_register_operand" ""))]
2424 "!TARGET_64BIT && reload_completed"
2425 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2426 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2430 [(set (match_operand:DF 0 "push_operand" "")
2431 (match_operand:DF 1 "any_fp_register_operand" ""))]
2432 "TARGET_64BIT && reload_completed"
2433 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2434 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2438 [(set (match_operand:DF 0 "push_operand" "")
2439 (match_operand:DF 1 "general_operand" ""))]
2442 "ix86_split_long_move (operands); DONE;")
2444 ;; Moving is usually shorter when only FP registers are used. This separate
2445 ;; movdf pattern avoids the use of integer registers for FP operations
2446 ;; when optimizing for size.
2448 (define_insn "*movdf_nointeger"
2449 [(set (match_operand:DF 0 "nonimmediate_operand"
2450 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2451 (match_operand:DF 1 "general_operand"
2452 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2453 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2454 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2455 && (reload_in_progress || reload_completed
2456 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2457 || GET_CODE (operands[1]) != CONST_DOUBLE
2458 || memory_operand (operands[0], DFmode))"
2460 switch (which_alternative)
2463 return output_387_reg_move (insn, operands);
2466 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2467 return "fstp%z0\t%y0";
2469 return "fst%z0\t%y0";
2472 return standard_80387_constant_opcode (operands[1]);
2478 switch (get_attr_mode (insn))
2481 return "xorps\t%0, %0";
2483 return "xorpd\t%0, %0";
2485 return "pxor\t%0, %0";
2492 switch (get_attr_mode (insn))
2495 return "movaps\t{%1, %0|%0, %1}";
2497 return "movapd\t{%1, %0|%0, %1}";
2499 return "movdqa\t{%1, %0|%0, %1}";
2501 return "movq\t{%1, %0|%0, %1}";
2503 return "movsd\t{%1, %0|%0, %1}";
2505 return "movlpd\t{%1, %0|%0, %1}";
2507 return "movlps\t{%1, %0|%0, %1}";
2516 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2518 (cond [(eq_attr "alternative" "0,1,2")
2520 (eq_attr "alternative" "3,4")
2523 /* For SSE1, we have many fewer alternatives. */
2524 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2525 (cond [(eq_attr "alternative" "5,6")
2526 (const_string "V4SF")
2528 (const_string "V2SF"))
2530 /* xorps is one byte shorter. */
2531 (eq_attr "alternative" "5")
2532 (cond [(ne (symbol_ref "optimize_size")
2534 (const_string "V4SF")
2535 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2539 (const_string "V2DF"))
2541 /* For architectures resolving dependencies on
2542 whole SSE registers use APD move to break dependency
2543 chains, otherwise use short move to avoid extra work.
2545 movaps encodes one byte shorter. */
2546 (eq_attr "alternative" "6")
2548 [(ne (symbol_ref "optimize_size")
2550 (const_string "V4SF")
2551 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2553 (const_string "V2DF")
2555 (const_string "DF"))
2556 /* For architectures resolving dependencies on register
2557 parts we may avoid extra work to zero out upper part
2559 (eq_attr "alternative" "7")
2561 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2563 (const_string "V1DF")
2564 (const_string "DF"))
2566 (const_string "DF")))])
2568 (define_insn "*movdf_integer"
2569 [(set (match_operand:DF 0 "nonimmediate_operand"
2570 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2571 (match_operand:DF 1 "general_operand"
2572 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2573 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2574 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2575 && (reload_in_progress || reload_completed
2576 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2577 || GET_CODE (operands[1]) != CONST_DOUBLE
2578 || memory_operand (operands[0], DFmode))"
2580 switch (which_alternative)
2583 return output_387_reg_move (insn, operands);
2586 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2587 return "fstp%z0\t%y0";
2589 return "fst%z0\t%y0";
2592 return standard_80387_constant_opcode (operands[1]);
2599 switch (get_attr_mode (insn))
2602 return "xorps\t%0, %0";
2604 return "xorpd\t%0, %0";
2606 return "pxor\t%0, %0";
2613 switch (get_attr_mode (insn))
2616 return "movaps\t{%1, %0|%0, %1}";
2618 return "movapd\t{%1, %0|%0, %1}";
2620 return "movdqa\t{%1, %0|%0, %1}";
2622 return "movq\t{%1, %0|%0, %1}";
2624 return "movsd\t{%1, %0|%0, %1}";
2626 return "movlpd\t{%1, %0|%0, %1}";
2628 return "movlps\t{%1, %0|%0, %1}";
2637 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2639 (cond [(eq_attr "alternative" "0,1,2")
2641 (eq_attr "alternative" "3,4")
2644 /* For SSE1, we have many fewer alternatives. */
2645 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2646 (cond [(eq_attr "alternative" "5,6")
2647 (const_string "V4SF")
2649 (const_string "V2SF"))
2651 /* xorps is one byte shorter. */
2652 (eq_attr "alternative" "5")
2653 (cond [(ne (symbol_ref "optimize_size")
2655 (const_string "V4SF")
2656 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2660 (const_string "V2DF"))
2662 /* For architectures resolving dependencies on
2663 whole SSE registers use APD move to break dependency
2664 chains, otherwise use short move to avoid extra work.
2666 movaps encodes one byte shorter. */
2667 (eq_attr "alternative" "6")
2669 [(ne (symbol_ref "optimize_size")
2671 (const_string "V4SF")
2672 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2674 (const_string "V2DF")
2676 (const_string "DF"))
2677 /* For architectures resolving dependencies on register
2678 parts we may avoid extra work to zero out upper part
2680 (eq_attr "alternative" "7")
2682 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2684 (const_string "V1DF")
2685 (const_string "DF"))
2687 (const_string "DF")))])
2690 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2691 (match_operand:DF 1 "general_operand" ""))]
2693 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2694 && ! (ANY_FP_REG_P (operands[0]) ||
2695 (GET_CODE (operands[0]) == SUBREG
2696 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2697 && ! (ANY_FP_REG_P (operands[1]) ||
2698 (GET_CODE (operands[1]) == SUBREG
2699 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2701 "ix86_split_long_move (operands); DONE;")
2703 (define_insn "*swapdf"
2704 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2705 (match_operand:DF 1 "fp_register_operand" "+f"))
2708 "reload_completed || TARGET_80387"
2710 if (STACK_TOP_P (operands[0]))
2715 [(set_attr "type" "fxch")
2716 (set_attr "mode" "DF")])
2718 (define_expand "movxf"
2719 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2720 (match_operand:XF 1 "general_operand" ""))]
2722 "ix86_expand_move (XFmode, operands); DONE;")
2724 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2725 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2726 ;; Pushing using integer instructions is longer except for constants
2727 ;; and direct memory references.
2728 ;; (assuming that any given constant is pushed only once, but this ought to be
2729 ;; handled elsewhere).
2731 (define_insn "*pushxf_nointeger"
2732 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2733 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2736 /* This insn should be already split before reg-stack. */
2739 [(set_attr "type" "multi")
2740 (set_attr "unit" "i387,*,*")
2741 (set_attr "mode" "XF,SI,SI")])
2743 (define_insn "*pushxf_integer"
2744 [(set (match_operand:XF 0 "push_operand" "=<,<")
2745 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2748 /* This insn should be already split before reg-stack. */
2751 [(set_attr "type" "multi")
2752 (set_attr "unit" "i387,*")
2753 (set_attr "mode" "XF,SI")])
2756 [(set (match_operand 0 "push_operand" "")
2757 (match_operand 1 "general_operand" ""))]
2759 && (GET_MODE (operands[0]) == XFmode
2760 || GET_MODE (operands[0]) == DFmode)
2761 && !ANY_FP_REG_P (operands[1])"
2763 "ix86_split_long_move (operands); DONE;")
2766 [(set (match_operand:XF 0 "push_operand" "")
2767 (match_operand:XF 1 "any_fp_register_operand" ""))]
2769 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2770 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2771 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774 [(set (match_operand:XF 0 "push_operand" "")
2775 (match_operand:XF 1 "any_fp_register_operand" ""))]
2777 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2778 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2779 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2781 ;; Do not use integer registers when optimizing for size
2782 (define_insn "*movxf_nointeger"
2783 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2784 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2786 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2787 && (reload_in_progress || reload_completed
2788 || GET_CODE (operands[1]) != CONST_DOUBLE
2789 || memory_operand (operands[0], XFmode))"
2791 switch (which_alternative)
2794 return output_387_reg_move (insn, operands);
2797 /* There is no non-popping store to memory for XFmode. So if
2798 we need one, follow the store with a load. */
2799 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2800 return "fstp%z0\t%y0\;fld%z0\t%y0";
2802 return "fstp%z0\t%y0";
2805 return standard_80387_constant_opcode (operands[1]);
2813 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2814 (set_attr "mode" "XF,XF,XF,SI,SI")])
2816 (define_insn "*movxf_integer"
2817 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2818 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2820 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2821 && (reload_in_progress || reload_completed
2822 || GET_CODE (operands[1]) != CONST_DOUBLE
2823 || memory_operand (operands[0], XFmode))"
2825 switch (which_alternative)
2828 return output_387_reg_move (insn, operands);
2831 /* There is no non-popping store to memory for XFmode. So if
2832 we need one, follow the store with a load. */
2833 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2834 return "fstp%z0\t%y0\;fld%z0\t%y0";
2836 return "fstp%z0\t%y0";
2839 return standard_80387_constant_opcode (operands[1]);
2848 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2849 (set_attr "mode" "XF,XF,XF,SI,SI")])
2852 [(set (match_operand 0 "nonimmediate_operand" "")
2853 (match_operand 1 "general_operand" ""))]
2855 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2856 && GET_MODE (operands[0]) == XFmode
2857 && ! (ANY_FP_REG_P (operands[0]) ||
2858 (GET_CODE (operands[0]) == SUBREG
2859 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2860 && ! (ANY_FP_REG_P (operands[1]) ||
2861 (GET_CODE (operands[1]) == SUBREG
2862 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2864 "ix86_split_long_move (operands); DONE;")
2867 [(set (match_operand 0 "register_operand" "")
2868 (match_operand 1 "memory_operand" ""))]
2870 && GET_CODE (operands[1]) == MEM
2871 && (GET_MODE (operands[0]) == XFmode
2872 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2873 && constant_pool_reference_p (operands[1])"
2874 [(set (match_dup 0) (match_dup 1))]
2876 rtx c = avoid_constant_pool_reference (operands[1]);
2877 rtx r = operands[0];
2879 if (GET_CODE (r) == SUBREG)
2884 if (!standard_sse_constant_p (c))
2887 else if (FP_REG_P (r))
2889 if (!standard_80387_constant_p (c))
2892 else if (MMX_REG_P (r))
2898 (define_insn "swapxf"
2899 [(set (match_operand:XF 0 "register_operand" "+f")
2900 (match_operand:XF 1 "register_operand" "+f"))
2905 if (STACK_TOP_P (operands[0]))
2910 [(set_attr "type" "fxch")
2911 (set_attr "mode" "XF")])
2913 (define_expand "movtf"
2914 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2915 (match_operand:TF 1 "nonimmediate_operand" ""))]
2918 ix86_expand_move (TFmode, operands);
2922 (define_insn "*movtf_internal"
2923 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2924 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2926 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2928 switch (which_alternative)
2934 if (get_attr_mode (insn) == MODE_V4SF)
2935 return "xorps\t%0, %0";
2937 return "pxor\t%0, %0";
2940 if (get_attr_mode (insn) == MODE_V4SF)
2941 return "movaps\t{%1, %0|%0, %1}";
2943 return "movdqa\t{%1, %0|%0, %1}";
2948 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2950 (cond [(eq_attr "alternative" "2,3")
2952 (ne (symbol_ref "optimize_size")
2954 (const_string "V4SF")
2955 (const_string "TI"))
2956 (eq_attr "alternative" "4")
2958 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2960 (ne (symbol_ref "optimize_size")
2962 (const_string "V4SF")
2963 (const_string "TI"))]
2964 (const_string "DI")))])
2967 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2968 (match_operand:TF 1 "general_operand" ""))]
2969 "reload_completed && !SSE_REG_P (operands[0])
2970 && !SSE_REG_P (operands[1])"
2972 "ix86_split_long_move (operands); DONE;")
2974 ;; Zero extension instructions
2976 (define_expand "zero_extendhisi2"
2977 [(set (match_operand:SI 0 "register_operand" "")
2978 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2981 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2983 operands[1] = force_reg (HImode, operands[1]);
2984 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2989 (define_insn "zero_extendhisi2_and"
2990 [(set (match_operand:SI 0 "register_operand" "=r")
2991 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2992 (clobber (reg:CC FLAGS_REG))]
2993 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2995 [(set_attr "type" "alu1")
2996 (set_attr "mode" "SI")])
2999 [(set (match_operand:SI 0 "register_operand" "")
3000 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3001 (clobber (reg:CC FLAGS_REG))]
3002 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3003 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3004 (clobber (reg:CC FLAGS_REG))])]
3007 (define_insn "*zero_extendhisi2_movzwl"
3008 [(set (match_operand:SI 0 "register_operand" "=r")
3009 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3010 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3011 "movz{wl|x}\t{%1, %0|%0, %1}"
3012 [(set_attr "type" "imovx")
3013 (set_attr "mode" "SI")])
3015 (define_expand "zero_extendqihi2"
3017 [(set (match_operand:HI 0 "register_operand" "")
3018 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3019 (clobber (reg:CC FLAGS_REG))])]
3023 (define_insn "*zero_extendqihi2_and"
3024 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3025 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3026 (clobber (reg:CC FLAGS_REG))]
3027 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3029 [(set_attr "type" "alu1")
3030 (set_attr "mode" "HI")])
3032 (define_insn "*zero_extendqihi2_movzbw_and"
3033 [(set (match_operand:HI 0 "register_operand" "=r,r")
3034 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3035 (clobber (reg:CC FLAGS_REG))]
3036 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3038 [(set_attr "type" "imovx,alu1")
3039 (set_attr "mode" "HI")])
3041 ; zero extend to SImode here to avoid partial register stalls
3042 (define_insn "*zero_extendqihi2_movzbl"
3043 [(set (match_operand:HI 0 "register_operand" "=r")
3044 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3045 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3046 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3047 [(set_attr "type" "imovx")
3048 (set_attr "mode" "SI")])
3050 ;; For the movzbw case strip only the clobber
3052 [(set (match_operand:HI 0 "register_operand" "")
3053 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3054 (clobber (reg:CC FLAGS_REG))]
3056 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3057 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3058 [(set (match_operand:HI 0 "register_operand" "")
3059 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3061 ;; When source and destination does not overlap, clear destination
3062 ;; first and then do the movb
3064 [(set (match_operand:HI 0 "register_operand" "")
3065 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3066 (clobber (reg:CC FLAGS_REG))]
3068 && ANY_QI_REG_P (operands[0])
3069 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3070 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3071 [(set (match_dup 0) (const_int 0))
3072 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3073 "operands[2] = gen_lowpart (QImode, operands[0]);")
3075 ;; Rest is handled by single and.
3077 [(set (match_operand:HI 0 "register_operand" "")
3078 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3079 (clobber (reg:CC FLAGS_REG))]
3081 && true_regnum (operands[0]) == true_regnum (operands[1])"
3082 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3083 (clobber (reg:CC FLAGS_REG))])]
3086 (define_expand "zero_extendqisi2"
3088 [(set (match_operand:SI 0 "register_operand" "")
3089 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3090 (clobber (reg:CC FLAGS_REG))])]
3094 (define_insn "*zero_extendqisi2_and"
3095 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3096 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3097 (clobber (reg:CC FLAGS_REG))]
3098 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3100 [(set_attr "type" "alu1")
3101 (set_attr "mode" "SI")])
3103 (define_insn "*zero_extendqisi2_movzbw_and"
3104 [(set (match_operand:SI 0 "register_operand" "=r,r")
3105 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3106 (clobber (reg:CC FLAGS_REG))]
3107 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3109 [(set_attr "type" "imovx,alu1")
3110 (set_attr "mode" "SI")])
3112 (define_insn "*zero_extendqisi2_movzbw"
3113 [(set (match_operand:SI 0 "register_operand" "=r")
3114 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3115 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3116 "movz{bl|x}\t{%1, %0|%0, %1}"
3117 [(set_attr "type" "imovx")
3118 (set_attr "mode" "SI")])
3120 ;; For the movzbl case strip only the clobber
3122 [(set (match_operand:SI 0 "register_operand" "")
3123 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3124 (clobber (reg:CC FLAGS_REG))]
3126 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3127 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3129 (zero_extend:SI (match_dup 1)))])
3131 ;; When source and destination does not overlap, clear destination
3132 ;; first and then do the movb
3134 [(set (match_operand:SI 0 "register_operand" "")
3135 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3136 (clobber (reg:CC FLAGS_REG))]
3138 && ANY_QI_REG_P (operands[0])
3139 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3140 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3141 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3142 [(set (match_dup 0) (const_int 0))
3143 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3144 "operands[2] = gen_lowpart (QImode, operands[0]);")
3146 ;; Rest is handled by single and.
3148 [(set (match_operand:SI 0 "register_operand" "")
3149 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3150 (clobber (reg:CC FLAGS_REG))]
3152 && true_regnum (operands[0]) == true_regnum (operands[1])"
3153 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3154 (clobber (reg:CC FLAGS_REG))])]
3157 ;; %%% Kill me once multi-word ops are sane.
3158 (define_expand "zero_extendsidi2"
3159 [(set (match_operand:DI 0 "register_operand" "=r")
3160 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3164 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3169 (define_insn "zero_extendsidi2_32"
3170 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3171 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3172 (clobber (reg:CC FLAGS_REG))]
3178 movd\t{%1, %0|%0, %1}
3179 movd\t{%1, %0|%0, %1}"
3180 [(set_attr "mode" "SI,SI,SI,DI,TI")
3181 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3183 (define_insn "zero_extendsidi2_rex64"
3184 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3185 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3188 mov\t{%k1, %k0|%k0, %k1}
3190 movd\t{%1, %0|%0, %1}
3191 movd\t{%1, %0|%0, %1}"
3192 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3193 (set_attr "mode" "SI,DI,SI,SI")])
3196 [(set (match_operand:DI 0 "memory_operand" "")
3197 (zero_extend:DI (match_dup 0)))]
3199 [(set (match_dup 4) (const_int 0))]
3200 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3203 [(set (match_operand:DI 0 "register_operand" "")
3204 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3205 (clobber (reg:CC FLAGS_REG))]
3206 "!TARGET_64BIT && reload_completed
3207 && true_regnum (operands[0]) == true_regnum (operands[1])"
3208 [(set (match_dup 4) (const_int 0))]
3209 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3212 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3213 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3214 (clobber (reg:CC FLAGS_REG))]
3215 "!TARGET_64BIT && reload_completed
3216 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3217 [(set (match_dup 3) (match_dup 1))
3218 (set (match_dup 4) (const_int 0))]
3219 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3221 (define_insn "zero_extendhidi2"
3222 [(set (match_operand:DI 0 "register_operand" "=r")
3223 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3225 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3226 [(set_attr "type" "imovx")
3227 (set_attr "mode" "DI")])
3229 (define_insn "zero_extendqidi2"
3230 [(set (match_operand:DI 0 "register_operand" "=r")
3231 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3233 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3234 [(set_attr "type" "imovx")
3235 (set_attr "mode" "DI")])
3237 ;; Sign extension instructions
3239 (define_expand "extendsidi2"
3240 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3241 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3242 (clobber (reg:CC FLAGS_REG))
3243 (clobber (match_scratch:SI 2 ""))])]
3248 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3253 (define_insn "*extendsidi2_1"
3254 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3255 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3256 (clobber (reg:CC FLAGS_REG))
3257 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3261 (define_insn "extendsidi2_rex64"
3262 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3263 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3267 movs{lq|x}\t{%1,%0|%0, %1}"
3268 [(set_attr "type" "imovx")
3269 (set_attr "mode" "DI")
3270 (set_attr "prefix_0f" "0")
3271 (set_attr "modrm" "0,1")])
3273 (define_insn "extendhidi2"
3274 [(set (match_operand:DI 0 "register_operand" "=r")
3275 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3277 "movs{wq|x}\t{%1,%0|%0, %1}"
3278 [(set_attr "type" "imovx")
3279 (set_attr "mode" "DI")])
3281 (define_insn "extendqidi2"
3282 [(set (match_operand:DI 0 "register_operand" "=r")
3283 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3285 "movs{bq|x}\t{%1,%0|%0, %1}"
3286 [(set_attr "type" "imovx")
3287 (set_attr "mode" "DI")])
3289 ;; Extend to memory case when source register does die.
3291 [(set (match_operand:DI 0 "memory_operand" "")
3292 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3293 (clobber (reg:CC FLAGS_REG))
3294 (clobber (match_operand:SI 2 "register_operand" ""))]
3296 && dead_or_set_p (insn, operands[1])
3297 && !reg_mentioned_p (operands[1], operands[0]))"
3298 [(set (match_dup 3) (match_dup 1))
3299 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3300 (clobber (reg:CC FLAGS_REG))])
3301 (set (match_dup 4) (match_dup 1))]
3302 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3304 ;; Extend to memory case when source register does not die.
3306 [(set (match_operand:DI 0 "memory_operand" "")
3307 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3308 (clobber (reg:CC FLAGS_REG))
3309 (clobber (match_operand:SI 2 "register_operand" ""))]
3313 split_di (&operands[0], 1, &operands[3], &operands[4]);
3315 emit_move_insn (operands[3], operands[1]);
3317 /* Generate a cltd if possible and doing so it profitable. */
3318 if (true_regnum (operands[1]) == 0
3319 && true_regnum (operands[2]) == 1
3320 && (optimize_size || TARGET_USE_CLTD))
3322 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3326 emit_move_insn (operands[2], operands[1]);
3327 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3329 emit_move_insn (operands[4], operands[2]);
3333 ;; Extend to register case. Optimize case where source and destination
3334 ;; registers match and cases where we can use cltd.
3336 [(set (match_operand:DI 0 "register_operand" "")
3337 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3338 (clobber (reg:CC FLAGS_REG))
3339 (clobber (match_scratch:SI 2 ""))]
3343 split_di (&operands[0], 1, &operands[3], &operands[4]);
3345 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3346 emit_move_insn (operands[3], operands[1]);
3348 /* Generate a cltd if possible and doing so it profitable. */
3349 if (true_regnum (operands[3]) == 0
3350 && (optimize_size || TARGET_USE_CLTD))
3352 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3356 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3357 emit_move_insn (operands[4], operands[1]);
3359 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3363 (define_insn "extendhisi2"
3364 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3365 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3368 switch (get_attr_prefix_0f (insn))
3371 return "{cwtl|cwde}";
3373 return "movs{wl|x}\t{%1,%0|%0, %1}";
3376 [(set_attr "type" "imovx")
3377 (set_attr "mode" "SI")
3378 (set (attr "prefix_0f")
3379 ;; movsx is short decodable while cwtl is vector decoded.
3380 (if_then_else (and (eq_attr "cpu" "!k6")
3381 (eq_attr "alternative" "0"))
3383 (const_string "1")))
3385 (if_then_else (eq_attr "prefix_0f" "0")
3387 (const_string "1")))])
3389 (define_insn "*extendhisi2_zext"
3390 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3392 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3395 switch (get_attr_prefix_0f (insn))
3398 return "{cwtl|cwde}";
3400 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3403 [(set_attr "type" "imovx")
3404 (set_attr "mode" "SI")
3405 (set (attr "prefix_0f")
3406 ;; movsx is short decodable while cwtl is vector decoded.
3407 (if_then_else (and (eq_attr "cpu" "!k6")
3408 (eq_attr "alternative" "0"))
3410 (const_string "1")))
3412 (if_then_else (eq_attr "prefix_0f" "0")
3414 (const_string "1")))])
3416 (define_insn "extendqihi2"
3417 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3418 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3421 switch (get_attr_prefix_0f (insn))
3424 return "{cbtw|cbw}";
3426 return "movs{bw|x}\t{%1,%0|%0, %1}";
3429 [(set_attr "type" "imovx")
3430 (set_attr "mode" "HI")
3431 (set (attr "prefix_0f")
3432 ;; movsx is short decodable while cwtl is vector decoded.
3433 (if_then_else (and (eq_attr "cpu" "!k6")
3434 (eq_attr "alternative" "0"))
3436 (const_string "1")))
3438 (if_then_else (eq_attr "prefix_0f" "0")
3440 (const_string "1")))])
3442 (define_insn "extendqisi2"
3443 [(set (match_operand:SI 0 "register_operand" "=r")
3444 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3446 "movs{bl|x}\t{%1,%0|%0, %1}"
3447 [(set_attr "type" "imovx")
3448 (set_attr "mode" "SI")])
3450 (define_insn "*extendqisi2_zext"
3451 [(set (match_operand:DI 0 "register_operand" "=r")
3453 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3455 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3456 [(set_attr "type" "imovx")
3457 (set_attr "mode" "SI")])
3459 ;; Conversions between float and double.
3461 ;; These are all no-ops in the model used for the 80387. So just
3464 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3465 (define_insn "*dummy_extendsfdf2"
3466 [(set (match_operand:DF 0 "push_operand" "=<")
3467 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3472 [(set (match_operand:DF 0 "push_operand" "")
3473 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3475 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3476 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3479 [(set (match_operand:DF 0 "push_operand" "")
3480 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3482 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3483 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3485 (define_insn "*dummy_extendsfxf2"
3486 [(set (match_operand:XF 0 "push_operand" "=<")
3487 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3492 [(set (match_operand:XF 0 "push_operand" "")
3493 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3495 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3496 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3497 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3500 [(set (match_operand:XF 0 "push_operand" "")
3501 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3503 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3504 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3505 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3508 [(set (match_operand:XF 0 "push_operand" "")
3509 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3511 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3512 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3513 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3516 [(set (match_operand:XF 0 "push_operand" "")
3517 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3519 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3520 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3521 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3523 (define_expand "extendsfdf2"
3524 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3525 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3526 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3528 /* ??? Needed for compress_float_constant since all fp constants
3529 are LEGITIMATE_CONSTANT_P. */
3530 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3532 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3533 && standard_80387_constant_p (operands[1]) > 0)
3535 operands[1] = simplify_const_unary_operation
3536 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3537 emit_move_insn_1 (operands[0], operands[1]);
3540 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3542 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3543 operands[1] = force_reg (SFmode, operands[1]);
3546 (define_insn "*extendsfdf2_mixed"
3547 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3548 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3549 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3550 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3552 switch (which_alternative)
3555 return output_387_reg_move (insn, operands);
3558 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3559 return "fstp%z0\t%y0";
3561 return "fst%z0\t%y0";
3564 return "cvtss2sd\t{%1, %0|%0, %1}";
3570 [(set_attr "type" "fmov,fmov,ssecvt")
3571 (set_attr "mode" "SF,XF,DF")])
3573 (define_insn "*extendsfdf2_sse"
3574 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3575 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3576 "TARGET_SSE2 && TARGET_SSE_MATH
3577 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3578 "cvtss2sd\t{%1, %0|%0, %1}"
3579 [(set_attr "type" "ssecvt")
3580 (set_attr "mode" "DF")])
3582 (define_insn "*extendsfdf2_i387"
3583 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3584 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3586 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3588 switch (which_alternative)
3591 return output_387_reg_move (insn, operands);
3594 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3595 return "fstp%z0\t%y0";
3597 return "fst%z0\t%y0";
3603 [(set_attr "type" "fmov")
3604 (set_attr "mode" "SF,XF")])
3606 (define_expand "extendsfxf2"
3607 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3608 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3611 /* ??? Needed for compress_float_constant since all fp constants
3612 are LEGITIMATE_CONSTANT_P. */
3613 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3615 if (standard_80387_constant_p (operands[1]) > 0)
3617 operands[1] = simplify_const_unary_operation
3618 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3619 emit_move_insn_1 (operands[0], operands[1]);
3622 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3624 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3625 operands[1] = force_reg (SFmode, operands[1]);
3628 (define_insn "*extendsfxf2_i387"
3629 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3630 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3632 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3634 switch (which_alternative)
3637 return output_387_reg_move (insn, operands);
3640 /* There is no non-popping store to memory for XFmode. So if
3641 we need one, follow the store with a load. */
3642 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3643 return "fstp%z0\t%y0";
3645 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3651 [(set_attr "type" "fmov")
3652 (set_attr "mode" "SF,XF")])
3654 (define_expand "extenddfxf2"
3655 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3656 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3659 /* ??? Needed for compress_float_constant since all fp constants
3660 are LEGITIMATE_CONSTANT_P. */
3661 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3663 if (standard_80387_constant_p (operands[1]) > 0)
3665 operands[1] = simplify_const_unary_operation
3666 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3667 emit_move_insn_1 (operands[0], operands[1]);
3670 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3672 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3673 operands[1] = force_reg (DFmode, operands[1]);
3676 (define_insn "*extenddfxf2_i387"
3677 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3678 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3680 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3682 switch (which_alternative)
3685 return output_387_reg_move (insn, operands);
3688 /* There is no non-popping store to memory for XFmode. So if
3689 we need one, follow the store with a load. */
3690 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3691 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3693 return "fstp%z0\t%y0";
3699 [(set_attr "type" "fmov")
3700 (set_attr "mode" "DF,XF")])
3702 ;; %%% This seems bad bad news.
3703 ;; This cannot output into an f-reg because there is no way to be sure
3704 ;; of truncating in that case. Otherwise this is just like a simple move
3705 ;; insn. So we pretend we can output to a reg in order to get better
3706 ;; register preferencing, but we really use a stack slot.
3708 ;; Conversion from DFmode to SFmode.
3710 (define_expand "truncdfsf2"
3711 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3713 (match_operand:DF 1 "nonimmediate_operand" "")))]
3714 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3716 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3717 operands[1] = force_reg (DFmode, operands[1]);
3719 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3721 else if (flag_unsafe_math_optimizations)
3725 rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3726 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3731 (define_expand "truncdfsf2_with_temp"
3732 [(parallel [(set (match_operand:SF 0 "" "")
3733 (float_truncate:SF (match_operand:DF 1 "" "")))
3734 (clobber (match_operand:SF 2 "" ""))])]
3737 (define_insn "*truncdfsf_fast_mixed"
3738 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3740 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3741 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3743 switch (which_alternative)
3746 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3747 return "fstp%z0\t%y0";
3749 return "fst%z0\t%y0";
3751 return output_387_reg_move (insn, operands);
3753 return "cvtsd2ss\t{%1, %0|%0, %1}";
3758 [(set_attr "type" "fmov,fmov,ssecvt")
3759 (set_attr "mode" "SF")])
3761 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3762 ;; because nothing we do here is unsafe.
3763 (define_insn "*truncdfsf_fast_sse"
3764 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3766 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3767 "TARGET_SSE2 && TARGET_SSE_MATH"
3768 "cvtsd2ss\t{%1, %0|%0, %1}"
3769 [(set_attr "type" "ssecvt")
3770 (set_attr "mode" "SF")])
3772 (define_insn "*truncdfsf_fast_i387"
3773 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3775 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3776 "TARGET_80387 && flag_unsafe_math_optimizations"
3777 "* return output_387_reg_move (insn, operands);"
3778 [(set_attr "type" "fmov")
3779 (set_attr "mode" "SF")])
3781 (define_insn "*truncdfsf_mixed"
3782 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3784 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3785 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3786 "TARGET_MIX_SSE_I387"
3788 switch (which_alternative)
3791 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3792 return "fstp%z0\t%y0";
3794 return "fst%z0\t%y0";
3798 return "cvtsd2ss\t{%1, %0|%0, %1}";
3803 [(set_attr "type" "fmov,multi,ssecvt")
3804 (set_attr "unit" "*,i387,*")
3805 (set_attr "mode" "SF")])
3807 (define_insn "*truncdfsf_i387"
3808 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3810 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3811 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3814 switch (which_alternative)
3817 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3818 return "fstp%z0\t%y0";
3820 return "fst%z0\t%y0";
3827 [(set_attr "type" "fmov,multi")
3828 (set_attr "unit" "*,i387")
3829 (set_attr "mode" "SF")])
3831 (define_insn "*truncdfsf2_i387_1"
3832 [(set (match_operand:SF 0 "memory_operand" "=m")
3834 (match_operand:DF 1 "register_operand" "f")))]
3836 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3837 && !TARGET_MIX_SSE_I387"
3839 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3840 return "fstp%z0\t%y0";
3842 return "fst%z0\t%y0";
3844 [(set_attr "type" "fmov")
3845 (set_attr "mode" "SF")])
3848 [(set (match_operand:SF 0 "register_operand" "")
3850 (match_operand:DF 1 "fp_register_operand" "")))
3851 (clobber (match_operand 2 "" ""))]
3853 [(set (match_dup 2) (match_dup 1))
3854 (set (match_dup 0) (match_dup 2))]
3856 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3859 ;; Conversion from XFmode to SFmode.
3861 (define_expand "truncxfsf2"
3862 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3864 (match_operand:XF 1 "register_operand" "")))
3865 (clobber (match_dup 2))])]
3868 if (flag_unsafe_math_optimizations)
3870 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3871 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3872 if (reg != operands[0])
3873 emit_move_insn (operands[0], reg);
3877 operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3880 (define_insn "*truncxfsf2_mixed"
3881 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3883 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3884 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3885 "TARGET_MIX_SSE_I387"
3887 gcc_assert (!which_alternative);
3888 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3889 return "fstp%z0\t%y0";
3891 return "fst%z0\t%y0";
3893 [(set_attr "type" "fmov,multi,multi,multi")
3894 (set_attr "unit" "*,i387,i387,i387")
3895 (set_attr "mode" "SF")])
3897 (define_insn "truncxfsf2_i387_noop"
3898 [(set (match_operand:SF 0 "register_operand" "=f")
3899 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3900 "TARGET_80387 && flag_unsafe_math_optimizations"
3902 return output_387_reg_move (insn, operands);
3904 [(set_attr "type" "fmov")
3905 (set_attr "mode" "SF")])
3907 (define_insn "*truncxfsf2_i387"
3908 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3910 (match_operand:XF 1 "register_operand" "f,f,f")))
3911 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3914 gcc_assert (!which_alternative);
3915 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3916 return "fstp%z0\t%y0";
3918 return "fst%z0\t%y0";
3920 [(set_attr "type" "fmov,multi,multi")
3921 (set_attr "unit" "*,i387,i387")
3922 (set_attr "mode" "SF")])
3924 (define_insn "*truncxfsf2_i387_1"
3925 [(set (match_operand:SF 0 "memory_operand" "=m")
3927 (match_operand:XF 1 "register_operand" "f")))]
3930 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3931 return "fstp%z0\t%y0";
3933 return "fst%z0\t%y0";
3935 [(set_attr "type" "fmov")
3936 (set_attr "mode" "SF")])
3939 [(set (match_operand:SF 0 "register_operand" "")
3941 (match_operand:XF 1 "register_operand" "")))
3942 (clobber (match_operand:SF 2 "memory_operand" ""))]
3943 "TARGET_80387 && reload_completed"
3944 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3945 (set (match_dup 0) (match_dup 2))]
3949 [(set (match_operand:SF 0 "memory_operand" "")
3951 (match_operand:XF 1 "register_operand" "")))
3952 (clobber (match_operand:SF 2 "memory_operand" ""))]
3954 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3957 ;; Conversion from XFmode to DFmode.
3959 (define_expand "truncxfdf2"
3960 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3962 (match_operand:XF 1 "register_operand" "")))
3963 (clobber (match_dup 2))])]
3966 if (flag_unsafe_math_optimizations)
3968 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3969 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3970 if (reg != operands[0])
3971 emit_move_insn (operands[0], reg);
3975 operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3978 (define_insn "*truncxfdf2_mixed"
3979 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3981 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3982 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3983 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3985 gcc_assert (!which_alternative);
3986 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3987 return "fstp%z0\t%y0";
3989 return "fst%z0\t%y0";
3991 [(set_attr "type" "fmov,multi,multi,multi")
3992 (set_attr "unit" "*,i387,i387,i387")
3993 (set_attr "mode" "DF")])
3995 (define_insn "truncxfdf2_i387_noop"
3996 [(set (match_operand:DF 0 "register_operand" "=f")
3997 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3998 "TARGET_80387 && flag_unsafe_math_optimizations"
4000 return output_387_reg_move (insn, operands);
4002 [(set_attr "type" "fmov")
4003 (set_attr "mode" "DF")])
4005 (define_insn "*truncxfdf2_i387"
4006 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4008 (match_operand:XF 1 "register_operand" "f,f,f")))
4009 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4012 gcc_assert (!which_alternative);
4013 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4014 return "fstp%z0\t%y0";
4016 return "fst%z0\t%y0";
4018 [(set_attr "type" "fmov,multi,multi")
4019 (set_attr "unit" "*,i387,i387")
4020 (set_attr "mode" "DF")])
4022 (define_insn "*truncxfdf2_i387_1"
4023 [(set (match_operand:DF 0 "memory_operand" "=m")
4025 (match_operand:XF 1 "register_operand" "f")))]
4028 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4029 return "fstp%z0\t%y0";
4031 return "fst%z0\t%y0";
4033 [(set_attr "type" "fmov")
4034 (set_attr "mode" "DF")])
4037 [(set (match_operand:DF 0 "register_operand" "")
4039 (match_operand:XF 1 "register_operand" "")))
4040 (clobber (match_operand:DF 2 "memory_operand" ""))]
4041 "TARGET_80387 && reload_completed"
4042 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4043 (set (match_dup 0) (match_dup 2))]
4047 [(set (match_operand:DF 0 "memory_operand" "")
4049 (match_operand:XF 1 "register_operand" "")))
4050 (clobber (match_operand:DF 2 "memory_operand" ""))]
4052 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4055 ;; Signed conversion to DImode.
4057 (define_expand "fix_truncxfdi2"
4058 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4059 (fix:DI (match_operand:XF 1 "register_operand" "")))
4060 (clobber (reg:CC FLAGS_REG))])]
4065 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4070 (define_expand "fix_trunc<mode>di2"
4071 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4072 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4073 (clobber (reg:CC FLAGS_REG))])]
4074 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4077 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4079 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4082 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4084 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4085 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4086 if (out != operands[0])
4087 emit_move_insn (operands[0], out);
4092 ;; Signed conversion to SImode.
4094 (define_expand "fix_truncxfsi2"
4095 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4096 (fix:SI (match_operand:XF 1 "register_operand" "")))
4097 (clobber (reg:CC FLAGS_REG))])]
4102 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4107 (define_expand "fix_trunc<mode>si2"
4108 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4109 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4110 (clobber (reg:CC FLAGS_REG))])]
4111 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4114 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4116 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4119 if (SSE_FLOAT_MODE_P (<MODE>mode))
4121 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4122 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4123 if (out != operands[0])
4124 emit_move_insn (operands[0], out);
4129 ;; Signed conversion to HImode.
4131 (define_expand "fix_trunc<mode>hi2"
4132 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4133 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4134 (clobber (reg:CC FLAGS_REG))])]
4136 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4140 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4145 ;; When SSE is available, it is always faster to use it!
4146 (define_insn "fix_truncsfdi_sse"
4147 [(set (match_operand:DI 0 "register_operand" "=r,r")
4148 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4149 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4150 "cvttss2si{q}\t{%1, %0|%0, %1}"
4151 [(set_attr "type" "sseicvt")
4152 (set_attr "mode" "SF")
4153 (set_attr "athlon_decode" "double,vector")])
4155 (define_insn "fix_truncdfdi_sse"
4156 [(set (match_operand:DI 0 "register_operand" "=r,r")
4157 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4158 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4159 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4160 [(set_attr "type" "sseicvt")
4161 (set_attr "mode" "DF")
4162 (set_attr "athlon_decode" "double,vector")])
4164 (define_insn "fix_truncsfsi_sse"
4165 [(set (match_operand:SI 0 "register_operand" "=r,r")
4166 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4167 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4168 "cvttss2si\t{%1, %0|%0, %1}"
4169 [(set_attr "type" "sseicvt")
4170 (set_attr "mode" "DF")
4171 (set_attr "athlon_decode" "double,vector")])
4173 (define_insn "fix_truncdfsi_sse"
4174 [(set (match_operand:SI 0 "register_operand" "=r,r")
4175 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4176 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4177 "cvttsd2si\t{%1, %0|%0, %1}"
4178 [(set_attr "type" "sseicvt")
4179 (set_attr "mode" "DF")
4180 (set_attr "athlon_decode" "double,vector")])
4182 ;; Avoid vector decoded forms of the instruction.
4184 [(match_scratch:DF 2 "Y")
4185 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4186 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4187 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4188 [(set (match_dup 2) (match_dup 1))
4189 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4193 [(match_scratch:SF 2 "x")
4194 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4195 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4196 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4197 [(set (match_dup 2) (match_dup 1))
4198 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4201 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4202 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4203 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4205 && FLOAT_MODE_P (GET_MODE (operands[1]))
4206 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4207 && (TARGET_64BIT || <MODE>mode != DImode))
4209 && !(reload_completed || reload_in_progress)"
4214 if (memory_operand (operands[0], VOIDmode))
4215 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4218 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4219 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4225 [(set_attr "type" "fisttp")
4226 (set_attr "mode" "<MODE>")])
4228 (define_insn "fix_trunc<mode>_i387_fisttp"
4229 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4230 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4231 (clobber (match_scratch:XF 2 "=&1f"))]
4233 && FLOAT_MODE_P (GET_MODE (operands[1]))
4234 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4235 && (TARGET_64BIT || <MODE>mode != DImode))
4236 && TARGET_SSE_MATH)"
4237 "* return output_fix_trunc (insn, operands, 1);"
4238 [(set_attr "type" "fisttp")
4239 (set_attr "mode" "<MODE>")])
4241 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4242 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4243 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4244 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4245 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4247 && FLOAT_MODE_P (GET_MODE (operands[1]))
4248 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4249 && (TARGET_64BIT || <MODE>mode != DImode))
4250 && TARGET_SSE_MATH)"
4252 [(set_attr "type" "fisttp")
4253 (set_attr "mode" "<MODE>")])
4256 [(set (match_operand:X87MODEI 0 "register_operand" "")
4257 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4258 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4259 (clobber (match_scratch 3 ""))]
4261 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4262 (clobber (match_dup 3))])
4263 (set (match_dup 0) (match_dup 2))]
4267 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4268 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4269 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4270 (clobber (match_scratch 3 ""))]
4272 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4273 (clobber (match_dup 3))])]
4276 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4277 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4278 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4279 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4280 ;; function in i386.c.
4281 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4282 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4283 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4284 (clobber (reg:CC FLAGS_REG))]
4285 "TARGET_80387 && !TARGET_FISTTP
4286 && FLOAT_MODE_P (GET_MODE (operands[1]))
4287 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4288 && (TARGET_64BIT || <MODE>mode != DImode))
4289 && !(reload_completed || reload_in_progress)"
4294 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4296 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4297 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4298 if (memory_operand (operands[0], VOIDmode))
4299 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4300 operands[2], operands[3]));
4303 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4304 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4305 operands[2], operands[3],
4310 [(set_attr "type" "fistp")
4311 (set_attr "i387_cw" "trunc")
4312 (set_attr "mode" "<MODE>")])
4314 (define_insn "fix_truncdi_i387"
4315 [(set (match_operand:DI 0 "memory_operand" "=m")
4316 (fix:DI (match_operand 1 "register_operand" "f")))
4317 (use (match_operand:HI 2 "memory_operand" "m"))
4318 (use (match_operand:HI 3 "memory_operand" "m"))
4319 (clobber (match_scratch:XF 4 "=&1f"))]
4320 "TARGET_80387 && !TARGET_FISTTP
4321 && FLOAT_MODE_P (GET_MODE (operands[1]))
4322 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4323 "* return output_fix_trunc (insn, operands, 0);"
4324 [(set_attr "type" "fistp")
4325 (set_attr "i387_cw" "trunc")
4326 (set_attr "mode" "DI")])
4328 (define_insn "fix_truncdi_i387_with_temp"
4329 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4330 (fix:DI (match_operand 1 "register_operand" "f,f")))
4331 (use (match_operand:HI 2 "memory_operand" "m,m"))
4332 (use (match_operand:HI 3 "memory_operand" "m,m"))
4333 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4334 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4335 "TARGET_80387 && !TARGET_FISTTP
4336 && FLOAT_MODE_P (GET_MODE (operands[1]))
4337 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4339 [(set_attr "type" "fistp")
4340 (set_attr "i387_cw" "trunc")
4341 (set_attr "mode" "DI")])
4344 [(set (match_operand:DI 0 "register_operand" "")
4345 (fix:DI (match_operand 1 "register_operand" "")))
4346 (use (match_operand:HI 2 "memory_operand" ""))
4347 (use (match_operand:HI 3 "memory_operand" ""))
4348 (clobber (match_operand:DI 4 "memory_operand" ""))
4349 (clobber (match_scratch 5 ""))]
4351 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4354 (clobber (match_dup 5))])
4355 (set (match_dup 0) (match_dup 4))]
4359 [(set (match_operand:DI 0 "memory_operand" "")
4360 (fix:DI (match_operand 1 "register_operand" "")))
4361 (use (match_operand:HI 2 "memory_operand" ""))
4362 (use (match_operand:HI 3 "memory_operand" ""))
4363 (clobber (match_operand:DI 4 "memory_operand" ""))
4364 (clobber (match_scratch 5 ""))]
4366 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4369 (clobber (match_dup 5))])]
4372 (define_insn "fix_trunc<mode>_i387"
4373 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4374 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4375 (use (match_operand:HI 2 "memory_operand" "m"))
4376 (use (match_operand:HI 3 "memory_operand" "m"))]
4377 "TARGET_80387 && !TARGET_FISTTP
4378 && FLOAT_MODE_P (GET_MODE (operands[1]))
4379 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4380 "* return output_fix_trunc (insn, operands, 0);"
4381 [(set_attr "type" "fistp")
4382 (set_attr "i387_cw" "trunc")
4383 (set_attr "mode" "<MODE>")])
4385 (define_insn "fix_trunc<mode>_i387_with_temp"
4386 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4387 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4388 (use (match_operand:HI 2 "memory_operand" "m,m"))
4389 (use (match_operand:HI 3 "memory_operand" "m,m"))
4390 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4391 "TARGET_80387 && !TARGET_FISTTP
4392 && FLOAT_MODE_P (GET_MODE (operands[1]))
4393 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4395 [(set_attr "type" "fistp")
4396 (set_attr "i387_cw" "trunc")
4397 (set_attr "mode" "<MODE>")])
4400 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4401 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4402 (use (match_operand:HI 2 "memory_operand" ""))
4403 (use (match_operand:HI 3 "memory_operand" ""))
4404 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4406 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4408 (use (match_dup 3))])
4409 (set (match_dup 0) (match_dup 4))]
4413 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4414 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4415 (use (match_operand:HI 2 "memory_operand" ""))
4416 (use (match_operand:HI 3 "memory_operand" ""))
4417 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4419 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4421 (use (match_dup 3))])]
4424 (define_insn "x86_fnstcw_1"
4425 [(set (match_operand:HI 0 "memory_operand" "=m")
4426 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4429 [(set_attr "length" "2")
4430 (set_attr "mode" "HI")
4431 (set_attr "unit" "i387")])
4433 (define_insn "x86_fldcw_1"
4434 [(set (reg:HI FPSR_REG)
4435 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4438 [(set_attr "length" "2")
4439 (set_attr "mode" "HI")
4440 (set_attr "unit" "i387")
4441 (set_attr "athlon_decode" "vector")])
4443 ;; Conversion between fixed point and floating point.
4445 ;; Even though we only accept memory inputs, the backend _really_
4446 ;; wants to be able to do this between registers.
4448 (define_expand "floathisf2"
4449 [(set (match_operand:SF 0 "register_operand" "")
4450 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4451 "TARGET_80387 || TARGET_SSE_MATH"
4453 if (TARGET_SSE_MATH)
4455 emit_insn (gen_floatsisf2 (operands[0],
4456 convert_to_mode (SImode, operands[1], 0)));
4461 (define_insn "*floathisf2_i387"
4462 [(set (match_operand:SF 0 "register_operand" "=f,f")
4463 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4464 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4468 [(set_attr "type" "fmov,multi")
4469 (set_attr "mode" "SF")
4470 (set_attr "unit" "*,i387")
4471 (set_attr "fp_int_src" "true")])
4473 (define_expand "floatsisf2"
4474 [(set (match_operand:SF 0 "register_operand" "")
4475 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4476 "TARGET_80387 || TARGET_SSE_MATH"
4479 (define_insn "*floatsisf2_mixed"
4480 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4481 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4482 "TARGET_MIX_SSE_I387"
4486 cvtsi2ss\t{%1, %0|%0, %1}
4487 cvtsi2ss\t{%1, %0|%0, %1}"
4488 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4489 (set_attr "mode" "SF")
4490 (set_attr "unit" "*,i387,*,*")
4491 (set_attr "athlon_decode" "*,*,vector,double")
4492 (set_attr "fp_int_src" "true")])
4494 (define_insn "*floatsisf2_sse"
4495 [(set (match_operand:SF 0 "register_operand" "=x,x")
4496 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4498 "cvtsi2ss\t{%1, %0|%0, %1}"
4499 [(set_attr "type" "sseicvt")
4500 (set_attr "mode" "SF")
4501 (set_attr "athlon_decode" "vector,double")
4502 (set_attr "fp_int_src" "true")])
4504 (define_insn "*floatsisf2_i387"
4505 [(set (match_operand:SF 0 "register_operand" "=f,f")
4506 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4511 [(set_attr "type" "fmov,multi")
4512 (set_attr "mode" "SF")
4513 (set_attr "unit" "*,i387")
4514 (set_attr "fp_int_src" "true")])
4516 (define_expand "floatdisf2"
4517 [(set (match_operand:SF 0 "register_operand" "")
4518 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4519 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4522 (define_insn "*floatdisf2_mixed"
4523 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4524 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4525 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4529 cvtsi2ss{q}\t{%1, %0|%0, %1}
4530 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4531 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4532 (set_attr "mode" "SF")
4533 (set_attr "unit" "*,i387,*,*")
4534 (set_attr "athlon_decode" "*,*,vector,double")
4535 (set_attr "fp_int_src" "true")])
4537 (define_insn "*floatdisf2_sse"
4538 [(set (match_operand:SF 0 "register_operand" "=x,x")
4539 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4540 "TARGET_64BIT && TARGET_SSE_MATH"
4541 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4542 [(set_attr "type" "sseicvt")
4543 (set_attr "mode" "SF")
4544 (set_attr "athlon_decode" "vector,double")
4545 (set_attr "fp_int_src" "true")])
4547 (define_insn "*floatdisf2_i387"
4548 [(set (match_operand:SF 0 "register_operand" "=f,f")
4549 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4554 [(set_attr "type" "fmov,multi")
4555 (set_attr "mode" "SF")
4556 (set_attr "unit" "*,i387")
4557 (set_attr "fp_int_src" "true")])
4559 (define_expand "floathidf2"
4560 [(set (match_operand:DF 0 "register_operand" "")
4561 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4562 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4564 if (TARGET_SSE2 && TARGET_SSE_MATH)
4566 emit_insn (gen_floatsidf2 (operands[0],
4567 convert_to_mode (SImode, operands[1], 0)));
4572 (define_insn "*floathidf2_i387"
4573 [(set (match_operand:DF 0 "register_operand" "=f,f")
4574 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4575 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4579 [(set_attr "type" "fmov,multi")
4580 (set_attr "mode" "DF")
4581 (set_attr "unit" "*,i387")
4582 (set_attr "fp_int_src" "true")])
4584 (define_expand "floatsidf2"
4585 [(set (match_operand:DF 0 "register_operand" "")
4586 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4587 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4590 (define_insn "*floatsidf2_mixed"
4591 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4592 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4593 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4597 cvtsi2sd\t{%1, %0|%0, %1}
4598 cvtsi2sd\t{%1, %0|%0, %1}"
4599 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4600 (set_attr "mode" "DF")
4601 (set_attr "unit" "*,i387,*,*")
4602 (set_attr "athlon_decode" "*,*,double,direct")
4603 (set_attr "fp_int_src" "true")])
4605 (define_insn "*floatsidf2_sse"
4606 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4607 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4608 "TARGET_SSE2 && TARGET_SSE_MATH"
4609 "cvtsi2sd\t{%1, %0|%0, %1}"
4610 [(set_attr "type" "sseicvt")
4611 (set_attr "mode" "DF")
4612 (set_attr "athlon_decode" "double,direct")
4613 (set_attr "fp_int_src" "true")])
4615 (define_insn "*floatsidf2_i387"
4616 [(set (match_operand:DF 0 "register_operand" "=f,f")
4617 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4622 [(set_attr "type" "fmov,multi")
4623 (set_attr "mode" "DF")
4624 (set_attr "unit" "*,i387")
4625 (set_attr "fp_int_src" "true")])
4627 (define_expand "floatdidf2"
4628 [(set (match_operand:DF 0 "register_operand" "")
4629 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4630 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4633 (define_insn "*floatdidf2_mixed"
4634 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4635 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4636 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4640 cvtsi2sd{q}\t{%1, %0|%0, %1}
4641 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4642 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4643 (set_attr "mode" "DF")
4644 (set_attr "unit" "*,i387,*,*")
4645 (set_attr "athlon_decode" "*,*,double,direct")
4646 (set_attr "fp_int_src" "true")])
4648 (define_insn "*floatdidf2_sse"
4649 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4650 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4651 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4652 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4653 [(set_attr "type" "sseicvt")
4654 (set_attr "mode" "DF")
4655 (set_attr "athlon_decode" "double,direct")
4656 (set_attr "fp_int_src" "true")])
4658 (define_insn "*floatdidf2_i387"
4659 [(set (match_operand:DF 0 "register_operand" "=f,f")
4660 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4665 [(set_attr "type" "fmov,multi")
4666 (set_attr "mode" "DF")
4667 (set_attr "unit" "*,i387")
4668 (set_attr "fp_int_src" "true")])
4670 (define_insn "floathixf2"
4671 [(set (match_operand:XF 0 "register_operand" "=f,f")
4672 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4677 [(set_attr "type" "fmov,multi")
4678 (set_attr "mode" "XF")
4679 (set_attr "unit" "*,i387")
4680 (set_attr "fp_int_src" "true")])
4682 (define_insn "floatsixf2"
4683 [(set (match_operand:XF 0 "register_operand" "=f,f")
4684 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4689 [(set_attr "type" "fmov,multi")
4690 (set_attr "mode" "XF")
4691 (set_attr "unit" "*,i387")
4692 (set_attr "fp_int_src" "true")])
4694 (define_insn "floatdixf2"
4695 [(set (match_operand:XF 0 "register_operand" "=f,f")
4696 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4701 [(set_attr "type" "fmov,multi")
4702 (set_attr "mode" "XF")
4703 (set_attr "unit" "*,i387")
4704 (set_attr "fp_int_src" "true")])
4706 ;; %%% Kill these when reload knows how to do it.
4708 [(set (match_operand 0 "fp_register_operand" "")
4709 (float (match_operand 1 "register_operand" "")))]
4712 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4715 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4716 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4717 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4718 ix86_free_from_memory (GET_MODE (operands[1]));
4722 (define_expand "floatunssisf2"
4723 [(use (match_operand:SF 0 "register_operand" ""))
4724 (use (match_operand:SI 1 "register_operand" ""))]
4725 "!TARGET_64BIT && TARGET_SSE_MATH"
4726 "x86_emit_floatuns (operands); DONE;")
4728 (define_expand "floatunsdisf2"
4729 [(use (match_operand:SF 0 "register_operand" ""))
4730 (use (match_operand:DI 1 "register_operand" ""))]
4731 "TARGET_64BIT && TARGET_SSE_MATH"
4732 "x86_emit_floatuns (operands); DONE;")
4734 (define_expand "floatunsdidf2"
4735 [(use (match_operand:DF 0 "register_operand" ""))
4736 (use (match_operand:DI 1 "register_operand" ""))]
4737 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4738 "x86_emit_floatuns (operands); DONE;")
4740 ;; SSE extract/set expanders
4745 ;; %%% splits for addditi3
4747 (define_expand "addti3"
4748 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4749 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4750 (match_operand:TI 2 "x86_64_general_operand" "")))
4751 (clobber (reg:CC FLAGS_REG))]
4753 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4755 (define_insn "*addti3_1"
4756 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4757 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4758 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4759 (clobber (reg:CC FLAGS_REG))]
4760 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4764 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4765 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4766 (match_operand:TI 2 "x86_64_general_operand" "")))
4767 (clobber (reg:CC FLAGS_REG))]
4768 "TARGET_64BIT && reload_completed"
4769 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4771 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4772 (parallel [(set (match_dup 3)
4773 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4776 (clobber (reg:CC FLAGS_REG))])]
4777 "split_ti (operands+0, 1, operands+0, operands+3);
4778 split_ti (operands+1, 1, operands+1, operands+4);
4779 split_ti (operands+2, 1, operands+2, operands+5);")
4781 ;; %%% splits for addsidi3
4782 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4783 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4784 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4786 (define_expand "adddi3"
4787 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4788 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4789 (match_operand:DI 2 "x86_64_general_operand" "")))
4790 (clobber (reg:CC FLAGS_REG))]
4792 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4794 (define_insn "*adddi3_1"
4795 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4796 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4797 (match_operand:DI 2 "general_operand" "roiF,riF")))
4798 (clobber (reg:CC FLAGS_REG))]
4799 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4803 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4804 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4805 (match_operand:DI 2 "general_operand" "")))
4806 (clobber (reg:CC FLAGS_REG))]
4807 "!TARGET_64BIT && reload_completed"
4808 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4810 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4811 (parallel [(set (match_dup 3)
4812 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4815 (clobber (reg:CC FLAGS_REG))])]
4816 "split_di (operands+0, 1, operands+0, operands+3);
4817 split_di (operands+1, 1, operands+1, operands+4);
4818 split_di (operands+2, 1, operands+2, operands+5);")
4820 (define_insn "adddi3_carry_rex64"
4821 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4822 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4823 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4824 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4825 (clobber (reg:CC FLAGS_REG))]
4826 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4827 "adc{q}\t{%2, %0|%0, %2}"
4828 [(set_attr "type" "alu")
4829 (set_attr "pent_pair" "pu")
4830 (set_attr "mode" "DI")])
4832 (define_insn "*adddi3_cc_rex64"
4833 [(set (reg:CC FLAGS_REG)
4834 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4835 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4837 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4838 (plus:DI (match_dup 1) (match_dup 2)))]
4839 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4840 "add{q}\t{%2, %0|%0, %2}"
4841 [(set_attr "type" "alu")
4842 (set_attr "mode" "DI")])
4844 (define_insn "addqi3_carry"
4845 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4846 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4847 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4848 (match_operand:QI 2 "general_operand" "qi,qm")))
4849 (clobber (reg:CC FLAGS_REG))]
4850 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4851 "adc{b}\t{%2, %0|%0, %2}"
4852 [(set_attr "type" "alu")
4853 (set_attr "pent_pair" "pu")
4854 (set_attr "mode" "QI")])
4856 (define_insn "addhi3_carry"
4857 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4858 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4859 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4860 (match_operand:HI 2 "general_operand" "ri,rm")))
4861 (clobber (reg:CC FLAGS_REG))]
4862 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4863 "adc{w}\t{%2, %0|%0, %2}"
4864 [(set_attr "type" "alu")
4865 (set_attr "pent_pair" "pu")
4866 (set_attr "mode" "HI")])
4868 (define_insn "addsi3_carry"
4869 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4870 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4871 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4872 (match_operand:SI 2 "general_operand" "ri,rm")))
4873 (clobber (reg:CC FLAGS_REG))]
4874 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4875 "adc{l}\t{%2, %0|%0, %2}"
4876 [(set_attr "type" "alu")
4877 (set_attr "pent_pair" "pu")
4878 (set_attr "mode" "SI")])
4880 (define_insn "*addsi3_carry_zext"
4881 [(set (match_operand:DI 0 "register_operand" "=r")
4883 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4884 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4885 (match_operand:SI 2 "general_operand" "rim"))))
4886 (clobber (reg:CC FLAGS_REG))]
4887 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4888 "adc{l}\t{%2, %k0|%k0, %2}"
4889 [(set_attr "type" "alu")
4890 (set_attr "pent_pair" "pu")
4891 (set_attr "mode" "SI")])
4893 (define_insn "*addsi3_cc"
4894 [(set (reg:CC FLAGS_REG)
4895 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4896 (match_operand:SI 2 "general_operand" "ri,rm")]
4898 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4899 (plus:SI (match_dup 1) (match_dup 2)))]
4900 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4901 "add{l}\t{%2, %0|%0, %2}"
4902 [(set_attr "type" "alu")
4903 (set_attr "mode" "SI")])
4905 (define_insn "addqi3_cc"
4906 [(set (reg:CC FLAGS_REG)
4907 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4908 (match_operand:QI 2 "general_operand" "qi,qm")]
4910 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4911 (plus:QI (match_dup 1) (match_dup 2)))]
4912 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4913 "add{b}\t{%2, %0|%0, %2}"
4914 [(set_attr "type" "alu")
4915 (set_attr "mode" "QI")])
4917 (define_expand "addsi3"
4918 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4919 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4920 (match_operand:SI 2 "general_operand" "")))
4921 (clobber (reg:CC FLAGS_REG))])]
4923 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4925 (define_insn "*lea_1"
4926 [(set (match_operand:SI 0 "register_operand" "=r")
4927 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4929 "lea{l}\t{%a1, %0|%0, %a1}"
4930 [(set_attr "type" "lea")
4931 (set_attr "mode" "SI")])
4933 (define_insn "*lea_1_rex64"
4934 [(set (match_operand:SI 0 "register_operand" "=r")
4935 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4937 "lea{l}\t{%a1, %0|%0, %a1}"
4938 [(set_attr "type" "lea")
4939 (set_attr "mode" "SI")])
4941 (define_insn "*lea_1_zext"
4942 [(set (match_operand:DI 0 "register_operand" "=r")
4944 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4946 "lea{l}\t{%a1, %k0|%k0, %a1}"
4947 [(set_attr "type" "lea")
4948 (set_attr "mode" "SI")])
4950 (define_insn "*lea_2_rex64"
4951 [(set (match_operand:DI 0 "register_operand" "=r")
4952 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4954 "lea{q}\t{%a1, %0|%0, %a1}"
4955 [(set_attr "type" "lea")
4956 (set_attr "mode" "DI")])
4958 ;; The lea patterns for non-Pmodes needs to be matched by several
4959 ;; insns converted to real lea by splitters.
4961 (define_insn_and_split "*lea_general_1"
4962 [(set (match_operand 0 "register_operand" "=r")
4963 (plus (plus (match_operand 1 "index_register_operand" "l")
4964 (match_operand 2 "register_operand" "r"))
4965 (match_operand 3 "immediate_operand" "i")))]
4966 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4967 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4968 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4969 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4970 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4971 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4972 || GET_MODE (operands[3]) == VOIDmode)"
4974 "&& reload_completed"
4978 operands[0] = gen_lowpart (SImode, operands[0]);
4979 operands[1] = gen_lowpart (Pmode, operands[1]);
4980 operands[2] = gen_lowpart (Pmode, operands[2]);
4981 operands[3] = gen_lowpart (Pmode, operands[3]);
4982 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4984 if (Pmode != SImode)
4985 pat = gen_rtx_SUBREG (SImode, pat, 0);
4986 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4989 [(set_attr "type" "lea")
4990 (set_attr "mode" "SI")])
4992 (define_insn_and_split "*lea_general_1_zext"
4993 [(set (match_operand:DI 0 "register_operand" "=r")
4995 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4996 (match_operand:SI 2 "register_operand" "r"))
4997 (match_operand:SI 3 "immediate_operand" "i"))))]
5000 "&& reload_completed"
5002 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5004 (match_dup 3)) 0)))]
5006 operands[1] = gen_lowpart (Pmode, operands[1]);
5007 operands[2] = gen_lowpart (Pmode, operands[2]);
5008 operands[3] = gen_lowpart (Pmode, operands[3]);
5010 [(set_attr "type" "lea")
5011 (set_attr "mode" "SI")])
5013 (define_insn_and_split "*lea_general_2"
5014 [(set (match_operand 0 "register_operand" "=r")
5015 (plus (mult (match_operand 1 "index_register_operand" "l")
5016 (match_operand 2 "const248_operand" "i"))
5017 (match_operand 3 "nonmemory_operand" "ri")))]
5018 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5019 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5020 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5021 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5022 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5023 || GET_MODE (operands[3]) == VOIDmode)"
5025 "&& reload_completed"
5029 operands[0] = gen_lowpart (SImode, operands[0]);
5030 operands[1] = gen_lowpart (Pmode, operands[1]);
5031 operands[3] = gen_lowpart (Pmode, operands[3]);
5032 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5034 if (Pmode != SImode)
5035 pat = gen_rtx_SUBREG (SImode, pat, 0);
5036 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5039 [(set_attr "type" "lea")
5040 (set_attr "mode" "SI")])
5042 (define_insn_and_split "*lea_general_2_zext"
5043 [(set (match_operand:DI 0 "register_operand" "=r")
5045 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5046 (match_operand:SI 2 "const248_operand" "n"))
5047 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5050 "&& reload_completed"
5052 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5054 (match_dup 3)) 0)))]
5056 operands[1] = gen_lowpart (Pmode, operands[1]);
5057 operands[3] = gen_lowpart (Pmode, operands[3]);
5059 [(set_attr "type" "lea")
5060 (set_attr "mode" "SI")])
5062 (define_insn_and_split "*lea_general_3"
5063 [(set (match_operand 0 "register_operand" "=r")
5064 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5065 (match_operand 2 "const248_operand" "i"))
5066 (match_operand 3 "register_operand" "r"))
5067 (match_operand 4 "immediate_operand" "i")))]
5068 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5069 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5070 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5071 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5072 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5074 "&& reload_completed"
5078 operands[0] = gen_lowpart (SImode, operands[0]);
5079 operands[1] = gen_lowpart (Pmode, operands[1]);
5080 operands[3] = gen_lowpart (Pmode, operands[3]);
5081 operands[4] = gen_lowpart (Pmode, operands[4]);
5082 pat = gen_rtx_PLUS (Pmode,
5083 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5087 if (Pmode != SImode)
5088 pat = gen_rtx_SUBREG (SImode, pat, 0);
5089 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5092 [(set_attr "type" "lea")
5093 (set_attr "mode" "SI")])
5095 (define_insn_and_split "*lea_general_3_zext"
5096 [(set (match_operand:DI 0 "register_operand" "=r")
5098 (plus:SI (plus:SI (mult:SI
5099 (match_operand:SI 1 "index_register_operand" "l")
5100 (match_operand:SI 2 "const248_operand" "n"))
5101 (match_operand:SI 3 "register_operand" "r"))
5102 (match_operand:SI 4 "immediate_operand" "i"))))]
5105 "&& reload_completed"
5107 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5110 (match_dup 4)) 0)))]
5112 operands[1] = gen_lowpart (Pmode, operands[1]);
5113 operands[3] = gen_lowpart (Pmode, operands[3]);
5114 operands[4] = gen_lowpart (Pmode, operands[4]);
5116 [(set_attr "type" "lea")
5117 (set_attr "mode" "SI")])
5119 (define_insn "*adddi_1_rex64"
5120 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5121 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5122 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5123 (clobber (reg:CC FLAGS_REG))]
5124 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5126 switch (get_attr_type (insn))
5129 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5130 return "lea{q}\t{%a2, %0|%0, %a2}";
5133 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5134 if (operands[2] == const1_rtx)
5135 return "inc{q}\t%0";
5138 gcc_assert (operands[2] == constm1_rtx);
5139 return "dec{q}\t%0";
5143 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5145 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5146 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5147 if (GET_CODE (operands[2]) == CONST_INT
5148 /* Avoid overflows. */
5149 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5150 && (INTVAL (operands[2]) == 128
5151 || (INTVAL (operands[2]) < 0
5152 && INTVAL (operands[2]) != -128)))
5154 operands[2] = GEN_INT (-INTVAL (operands[2]));
5155 return "sub{q}\t{%2, %0|%0, %2}";
5157 return "add{q}\t{%2, %0|%0, %2}";
5161 (cond [(eq_attr "alternative" "2")
5162 (const_string "lea")
5163 ; Current assemblers are broken and do not allow @GOTOFF in
5164 ; ought but a memory context.
5165 (match_operand:DI 2 "pic_symbolic_operand" "")
5166 (const_string "lea")
5167 (match_operand:DI 2 "incdec_operand" "")
5168 (const_string "incdec")
5170 (const_string "alu")))
5171 (set_attr "mode" "DI")])
5173 ;; Convert lea to the lea pattern to avoid flags dependency.
5175 [(set (match_operand:DI 0 "register_operand" "")
5176 (plus:DI (match_operand:DI 1 "register_operand" "")
5177 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5178 (clobber (reg:CC FLAGS_REG))]
5179 "TARGET_64BIT && reload_completed
5180 && true_regnum (operands[0]) != true_regnum (operands[1])"
5182 (plus:DI (match_dup 1)
5186 (define_insn "*adddi_2_rex64"
5187 [(set (reg FLAGS_REG)
5189 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5190 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5192 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5193 (plus:DI (match_dup 1) (match_dup 2)))]
5194 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5195 && ix86_binary_operator_ok (PLUS, DImode, operands)
5196 /* Current assemblers are broken and do not allow @GOTOFF in
5197 ought but a memory context. */
5198 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5200 switch (get_attr_type (insn))
5203 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5204 if (operands[2] == const1_rtx)
5205 return "inc{q}\t%0";
5208 gcc_assert (operands[2] == constm1_rtx);
5209 return "dec{q}\t%0";
5213 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5214 /* ???? We ought to handle there the 32bit case too
5215 - do we need new constraint? */
5216 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5217 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5218 if (GET_CODE (operands[2]) == CONST_INT
5219 /* Avoid overflows. */
5220 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5221 && (INTVAL (operands[2]) == 128
5222 || (INTVAL (operands[2]) < 0
5223 && INTVAL (operands[2]) != -128)))
5225 operands[2] = GEN_INT (-INTVAL (operands[2]));
5226 return "sub{q}\t{%2, %0|%0, %2}";
5228 return "add{q}\t{%2, %0|%0, %2}";
5232 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5233 (const_string "incdec")
5234 (const_string "alu")))
5235 (set_attr "mode" "DI")])
5237 (define_insn "*adddi_3_rex64"
5238 [(set (reg FLAGS_REG)
5239 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5240 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5241 (clobber (match_scratch:DI 0 "=r"))]
5243 && ix86_match_ccmode (insn, CCZmode)
5244 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5245 /* Current assemblers are broken and do not allow @GOTOFF in
5246 ought but a memory context. */
5247 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5249 switch (get_attr_type (insn))
5252 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5253 if (operands[2] == const1_rtx)
5254 return "inc{q}\t%0";
5257 gcc_assert (operands[2] == constm1_rtx);
5258 return "dec{q}\t%0";
5262 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5263 /* ???? We ought to handle there the 32bit case too
5264 - do we need new constraint? */
5265 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5266 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5267 if (GET_CODE (operands[2]) == CONST_INT
5268 /* Avoid overflows. */
5269 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5270 && (INTVAL (operands[2]) == 128
5271 || (INTVAL (operands[2]) < 0
5272 && INTVAL (operands[2]) != -128)))
5274 operands[2] = GEN_INT (-INTVAL (operands[2]));
5275 return "sub{q}\t{%2, %0|%0, %2}";
5277 return "add{q}\t{%2, %0|%0, %2}";
5281 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5282 (const_string "incdec")
5283 (const_string "alu")))
5284 (set_attr "mode" "DI")])
5286 ; For comparisons against 1, -1 and 128, we may generate better code
5287 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5288 ; is matched then. We can't accept general immediate, because for
5289 ; case of overflows, the result is messed up.
5290 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5292 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5293 ; only for comparisons not depending on it.
5294 (define_insn "*adddi_4_rex64"
5295 [(set (reg FLAGS_REG)
5296 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5297 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5298 (clobber (match_scratch:DI 0 "=rm"))]
5300 && ix86_match_ccmode (insn, CCGCmode)"
5302 switch (get_attr_type (insn))
5305 if (operands[2] == constm1_rtx)
5306 return "inc{q}\t%0";
5309 gcc_assert (operands[2] == const1_rtx);
5310 return "dec{q}\t%0";
5314 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5315 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5316 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5317 if ((INTVAL (operands[2]) == -128
5318 || (INTVAL (operands[2]) > 0
5319 && INTVAL (operands[2]) != 128))
5320 /* Avoid overflows. */
5321 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5322 return "sub{q}\t{%2, %0|%0, %2}";
5323 operands[2] = GEN_INT (-INTVAL (operands[2]));
5324 return "add{q}\t{%2, %0|%0, %2}";
5328 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5329 (const_string "incdec")
5330 (const_string "alu")))
5331 (set_attr "mode" "DI")])
5333 (define_insn "*adddi_5_rex64"
5334 [(set (reg FLAGS_REG)
5336 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5337 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5339 (clobber (match_scratch:DI 0 "=r"))]
5341 && ix86_match_ccmode (insn, CCGOCmode)
5342 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5343 /* Current assemblers are broken and do not allow @GOTOFF in
5344 ought but a memory context. */
5345 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5347 switch (get_attr_type (insn))
5350 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5351 if (operands[2] == const1_rtx)
5352 return "inc{q}\t%0";
5355 gcc_assert (operands[2] == constm1_rtx);
5356 return "dec{q}\t%0";
5360 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5361 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5362 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5363 if (GET_CODE (operands[2]) == CONST_INT
5364 /* Avoid overflows. */
5365 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5366 && (INTVAL (operands[2]) == 128
5367 || (INTVAL (operands[2]) < 0
5368 && INTVAL (operands[2]) != -128)))
5370 operands[2] = GEN_INT (-INTVAL (operands[2]));
5371 return "sub{q}\t{%2, %0|%0, %2}";
5373 return "add{q}\t{%2, %0|%0, %2}";
5377 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378 (const_string "incdec")
5379 (const_string "alu")))
5380 (set_attr "mode" "DI")])
5383 (define_insn "*addsi_1"
5384 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5385 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5386 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5387 (clobber (reg:CC FLAGS_REG))]
5388 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5390 switch (get_attr_type (insn))
5393 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5394 return "lea{l}\t{%a2, %0|%0, %a2}";
5397 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5398 if (operands[2] == const1_rtx)
5399 return "inc{l}\t%0";
5402 gcc_assert (operands[2] == constm1_rtx);
5403 return "dec{l}\t%0";
5407 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5409 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5410 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5411 if (GET_CODE (operands[2]) == CONST_INT
5412 && (INTVAL (operands[2]) == 128
5413 || (INTVAL (operands[2]) < 0
5414 && INTVAL (operands[2]) != -128)))
5416 operands[2] = GEN_INT (-INTVAL (operands[2]));
5417 return "sub{l}\t{%2, %0|%0, %2}";
5419 return "add{l}\t{%2, %0|%0, %2}";
5423 (cond [(eq_attr "alternative" "2")
5424 (const_string "lea")
5425 ; Current assemblers are broken and do not allow @GOTOFF in
5426 ; ought but a memory context.
5427 (match_operand:SI 2 "pic_symbolic_operand" "")
5428 (const_string "lea")
5429 (match_operand:SI 2 "incdec_operand" "")
5430 (const_string "incdec")
5432 (const_string "alu")))
5433 (set_attr "mode" "SI")])
5435 ;; Convert lea to the lea pattern to avoid flags dependency.
5437 [(set (match_operand 0 "register_operand" "")
5438 (plus (match_operand 1 "register_operand" "")
5439 (match_operand 2 "nonmemory_operand" "")))
5440 (clobber (reg:CC FLAGS_REG))]
5442 && true_regnum (operands[0]) != true_regnum (operands[1])"
5446 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5447 may confuse gen_lowpart. */
5448 if (GET_MODE (operands[0]) != Pmode)
5450 operands[1] = gen_lowpart (Pmode, operands[1]);
5451 operands[2] = gen_lowpart (Pmode, operands[2]);
5453 operands[0] = gen_lowpart (SImode, operands[0]);
5454 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5455 if (Pmode != SImode)
5456 pat = gen_rtx_SUBREG (SImode, pat, 0);
5457 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5461 ;; It may seem that nonimmediate operand is proper one for operand 1.
5462 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5463 ;; we take care in ix86_binary_operator_ok to not allow two memory
5464 ;; operands so proper swapping will be done in reload. This allow
5465 ;; patterns constructed from addsi_1 to match.
5466 (define_insn "addsi_1_zext"
5467 [(set (match_operand:DI 0 "register_operand" "=r,r")
5469 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5470 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5471 (clobber (reg:CC FLAGS_REG))]
5472 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5474 switch (get_attr_type (insn))
5477 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5478 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5481 if (operands[2] == const1_rtx)
5482 return "inc{l}\t%k0";
5485 gcc_assert (operands[2] == constm1_rtx);
5486 return "dec{l}\t%k0";
5490 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5491 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5492 if (GET_CODE (operands[2]) == CONST_INT
5493 && (INTVAL (operands[2]) == 128
5494 || (INTVAL (operands[2]) < 0
5495 && INTVAL (operands[2]) != -128)))
5497 operands[2] = GEN_INT (-INTVAL (operands[2]));
5498 return "sub{l}\t{%2, %k0|%k0, %2}";
5500 return "add{l}\t{%2, %k0|%k0, %2}";
5504 (cond [(eq_attr "alternative" "1")
5505 (const_string "lea")
5506 ; Current assemblers are broken and do not allow @GOTOFF in
5507 ; ought but a memory context.
5508 (match_operand:SI 2 "pic_symbolic_operand" "")
5509 (const_string "lea")
5510 (match_operand:SI 2 "incdec_operand" "")
5511 (const_string "incdec")
5513 (const_string "alu")))
5514 (set_attr "mode" "SI")])
5516 ;; Convert lea to the lea pattern to avoid flags dependency.
5518 [(set (match_operand:DI 0 "register_operand" "")
5520 (plus:SI (match_operand:SI 1 "register_operand" "")
5521 (match_operand:SI 2 "nonmemory_operand" ""))))
5522 (clobber (reg:CC FLAGS_REG))]
5523 "TARGET_64BIT && reload_completed
5524 && true_regnum (operands[0]) != true_regnum (operands[1])"
5526 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5528 operands[1] = gen_lowpart (Pmode, operands[1]);
5529 operands[2] = gen_lowpart (Pmode, operands[2]);
5532 (define_insn "*addsi_2"
5533 [(set (reg FLAGS_REG)
5535 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5536 (match_operand:SI 2 "general_operand" "rmni,rni"))
5538 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5539 (plus:SI (match_dup 1) (match_dup 2)))]
5540 "ix86_match_ccmode (insn, CCGOCmode)
5541 && ix86_binary_operator_ok (PLUS, SImode, operands)
5542 /* Current assemblers are broken and do not allow @GOTOFF in
5543 ought but a memory context. */
5544 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5546 switch (get_attr_type (insn))
5549 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5550 if (operands[2] == const1_rtx)
5551 return "inc{l}\t%0";
5554 gcc_assert (operands[2] == constm1_rtx);
5555 return "dec{l}\t%0";
5559 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5560 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5561 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5562 if (GET_CODE (operands[2]) == CONST_INT
5563 && (INTVAL (operands[2]) == 128
5564 || (INTVAL (operands[2]) < 0
5565 && INTVAL (operands[2]) != -128)))
5567 operands[2] = GEN_INT (-INTVAL (operands[2]));
5568 return "sub{l}\t{%2, %0|%0, %2}";
5570 return "add{l}\t{%2, %0|%0, %2}";
5574 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5575 (const_string "incdec")
5576 (const_string "alu")))
5577 (set_attr "mode" "SI")])
5579 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5580 (define_insn "*addsi_2_zext"
5581 [(set (reg FLAGS_REG)
5583 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5584 (match_operand:SI 2 "general_operand" "rmni"))
5586 (set (match_operand:DI 0 "register_operand" "=r")
5587 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5588 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5589 && ix86_binary_operator_ok (PLUS, SImode, operands)
5590 /* Current assemblers are broken and do not allow @GOTOFF in
5591 ought but a memory context. */
5592 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5594 switch (get_attr_type (insn))
5597 if (operands[2] == const1_rtx)
5598 return "inc{l}\t%k0";
5601 gcc_assert (operands[2] == constm1_rtx);
5602 return "dec{l}\t%k0";
5606 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5607 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5608 if (GET_CODE (operands[2]) == CONST_INT
5609 && (INTVAL (operands[2]) == 128
5610 || (INTVAL (operands[2]) < 0
5611 && INTVAL (operands[2]) != -128)))
5613 operands[2] = GEN_INT (-INTVAL (operands[2]));
5614 return "sub{l}\t{%2, %k0|%k0, %2}";
5616 return "add{l}\t{%2, %k0|%k0, %2}";
5620 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5621 (const_string "incdec")
5622 (const_string "alu")))
5623 (set_attr "mode" "SI")])
5625 (define_insn "*addsi_3"
5626 [(set (reg FLAGS_REG)
5627 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5628 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5629 (clobber (match_scratch:SI 0 "=r"))]
5630 "ix86_match_ccmode (insn, CCZmode)
5631 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5632 /* Current assemblers are broken and do not allow @GOTOFF in
5633 ought but a memory context. */
5634 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5636 switch (get_attr_type (insn))
5639 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5640 if (operands[2] == const1_rtx)
5641 return "inc{l}\t%0";
5644 gcc_assert (operands[2] == constm1_rtx);
5645 return "dec{l}\t%0";
5649 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5650 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5651 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5652 if (GET_CODE (operands[2]) == CONST_INT
5653 && (INTVAL (operands[2]) == 128
5654 || (INTVAL (operands[2]) < 0
5655 && INTVAL (operands[2]) != -128)))
5657 operands[2] = GEN_INT (-INTVAL (operands[2]));
5658 return "sub{l}\t{%2, %0|%0, %2}";
5660 return "add{l}\t{%2, %0|%0, %2}";
5664 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5665 (const_string "incdec")
5666 (const_string "alu")))
5667 (set_attr "mode" "SI")])
5669 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5670 (define_insn "*addsi_3_zext"
5671 [(set (reg FLAGS_REG)
5672 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5673 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5674 (set (match_operand:DI 0 "register_operand" "=r")
5675 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5676 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5677 && ix86_binary_operator_ok (PLUS, SImode, operands)
5678 /* Current assemblers are broken and do not allow @GOTOFF in
5679 ought but a memory context. */
5680 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5682 switch (get_attr_type (insn))
5685 if (operands[2] == const1_rtx)
5686 return "inc{l}\t%k0";
5689 gcc_assert (operands[2] == constm1_rtx);
5690 return "dec{l}\t%k0";
5694 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5695 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5696 if (GET_CODE (operands[2]) == CONST_INT
5697 && (INTVAL (operands[2]) == 128
5698 || (INTVAL (operands[2]) < 0
5699 && INTVAL (operands[2]) != -128)))
5701 operands[2] = GEN_INT (-INTVAL (operands[2]));
5702 return "sub{l}\t{%2, %k0|%k0, %2}";
5704 return "add{l}\t{%2, %k0|%k0, %2}";
5708 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5709 (const_string "incdec")
5710 (const_string "alu")))
5711 (set_attr "mode" "SI")])
5713 ; For comparisons against 1, -1 and 128, we may generate better code
5714 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5715 ; is matched then. We can't accept general immediate, because for
5716 ; case of overflows, the result is messed up.
5717 ; This pattern also don't hold of 0x80000000, since the value overflows
5719 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5720 ; only for comparisons not depending on it.
5721 (define_insn "*addsi_4"
5722 [(set (reg FLAGS_REG)
5723 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5724 (match_operand:SI 2 "const_int_operand" "n")))
5725 (clobber (match_scratch:SI 0 "=rm"))]
5726 "ix86_match_ccmode (insn, CCGCmode)
5727 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5729 switch (get_attr_type (insn))
5732 if (operands[2] == constm1_rtx)
5733 return "inc{l}\t%0";
5736 gcc_assert (operands[2] == const1_rtx);
5737 return "dec{l}\t%0";
5741 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5742 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5743 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5744 if ((INTVAL (operands[2]) == -128
5745 || (INTVAL (operands[2]) > 0
5746 && INTVAL (operands[2]) != 128)))
5747 return "sub{l}\t{%2, %0|%0, %2}";
5748 operands[2] = GEN_INT (-INTVAL (operands[2]));
5749 return "add{l}\t{%2, %0|%0, %2}";
5753 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5754 (const_string "incdec")
5755 (const_string "alu")))
5756 (set_attr "mode" "SI")])
5758 (define_insn "*addsi_5"
5759 [(set (reg FLAGS_REG)
5761 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5762 (match_operand:SI 2 "general_operand" "rmni"))
5764 (clobber (match_scratch:SI 0 "=r"))]
5765 "ix86_match_ccmode (insn, CCGOCmode)
5766 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5767 /* Current assemblers are broken and do not allow @GOTOFF in
5768 ought but a memory context. */
5769 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5771 switch (get_attr_type (insn))
5774 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5775 if (operands[2] == const1_rtx)
5776 return "inc{l}\t%0";
5779 gcc_assert (operands[2] == constm1_rtx);
5780 return "dec{l}\t%0";
5784 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5785 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5786 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5787 if (GET_CODE (operands[2]) == CONST_INT
5788 && (INTVAL (operands[2]) == 128
5789 || (INTVAL (operands[2]) < 0
5790 && INTVAL (operands[2]) != -128)))
5792 operands[2] = GEN_INT (-INTVAL (operands[2]));
5793 return "sub{l}\t{%2, %0|%0, %2}";
5795 return "add{l}\t{%2, %0|%0, %2}";
5799 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5800 (const_string "incdec")
5801 (const_string "alu")))
5802 (set_attr "mode" "SI")])
5804 (define_expand "addhi3"
5805 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5806 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5807 (match_operand:HI 2 "general_operand" "")))
5808 (clobber (reg:CC FLAGS_REG))])]
5809 "TARGET_HIMODE_MATH"
5810 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5812 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5813 ;; type optimizations enabled by define-splits. This is not important
5814 ;; for PII, and in fact harmful because of partial register stalls.
5816 (define_insn "*addhi_1_lea"
5817 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5818 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5819 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5820 (clobber (reg:CC FLAGS_REG))]
5821 "!TARGET_PARTIAL_REG_STALL
5822 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5824 switch (get_attr_type (insn))
5829 if (operands[2] == const1_rtx)
5830 return "inc{w}\t%0";
5833 gcc_assert (operands[2] == constm1_rtx);
5834 return "dec{w}\t%0";
5838 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5839 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5840 if (GET_CODE (operands[2]) == CONST_INT
5841 && (INTVAL (operands[2]) == 128
5842 || (INTVAL (operands[2]) < 0
5843 && INTVAL (operands[2]) != -128)))
5845 operands[2] = GEN_INT (-INTVAL (operands[2]));
5846 return "sub{w}\t{%2, %0|%0, %2}";
5848 return "add{w}\t{%2, %0|%0, %2}";
5852 (if_then_else (eq_attr "alternative" "2")
5853 (const_string "lea")
5854 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5855 (const_string "incdec")
5856 (const_string "alu"))))
5857 (set_attr "mode" "HI,HI,SI")])
5859 (define_insn "*addhi_1"
5860 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5861 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5862 (match_operand:HI 2 "general_operand" "ri,rm")))
5863 (clobber (reg:CC FLAGS_REG))]
5864 "TARGET_PARTIAL_REG_STALL
5865 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5867 switch (get_attr_type (insn))
5870 if (operands[2] == const1_rtx)
5871 return "inc{w}\t%0";
5874 gcc_assert (operands[2] == constm1_rtx);
5875 return "dec{w}\t%0";
5879 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5880 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5881 if (GET_CODE (operands[2]) == CONST_INT
5882 && (INTVAL (operands[2]) == 128
5883 || (INTVAL (operands[2]) < 0
5884 && INTVAL (operands[2]) != -128)))
5886 operands[2] = GEN_INT (-INTVAL (operands[2]));
5887 return "sub{w}\t{%2, %0|%0, %2}";
5889 return "add{w}\t{%2, %0|%0, %2}";
5893 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5894 (const_string "incdec")
5895 (const_string "alu")))
5896 (set_attr "mode" "HI")])
5898 (define_insn "*addhi_2"
5899 [(set (reg FLAGS_REG)
5901 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5902 (match_operand:HI 2 "general_operand" "rmni,rni"))
5904 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5905 (plus:HI (match_dup 1) (match_dup 2)))]
5906 "ix86_match_ccmode (insn, CCGOCmode)
5907 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5909 switch (get_attr_type (insn))
5912 if (operands[2] == const1_rtx)
5913 return "inc{w}\t%0";
5916 gcc_assert (operands[2] == constm1_rtx);
5917 return "dec{w}\t%0";
5921 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5922 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5923 if (GET_CODE (operands[2]) == CONST_INT
5924 && (INTVAL (operands[2]) == 128
5925 || (INTVAL (operands[2]) < 0
5926 && INTVAL (operands[2]) != -128)))
5928 operands[2] = GEN_INT (-INTVAL (operands[2]));
5929 return "sub{w}\t{%2, %0|%0, %2}";
5931 return "add{w}\t{%2, %0|%0, %2}";
5935 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5936 (const_string "incdec")
5937 (const_string "alu")))
5938 (set_attr "mode" "HI")])
5940 (define_insn "*addhi_3"
5941 [(set (reg FLAGS_REG)
5942 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5943 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5944 (clobber (match_scratch:HI 0 "=r"))]
5945 "ix86_match_ccmode (insn, CCZmode)
5946 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5948 switch (get_attr_type (insn))
5951 if (operands[2] == const1_rtx)
5952 return "inc{w}\t%0";
5955 gcc_assert (operands[2] == constm1_rtx);
5956 return "dec{w}\t%0";
5960 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5961 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5962 if (GET_CODE (operands[2]) == CONST_INT
5963 && (INTVAL (operands[2]) == 128
5964 || (INTVAL (operands[2]) < 0
5965 && INTVAL (operands[2]) != -128)))
5967 operands[2] = GEN_INT (-INTVAL (operands[2]));
5968 return "sub{w}\t{%2, %0|%0, %2}";
5970 return "add{w}\t{%2, %0|%0, %2}";
5974 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5975 (const_string "incdec")
5976 (const_string "alu")))
5977 (set_attr "mode" "HI")])
5979 ; See comments above addsi_4 for details.
5980 (define_insn "*addhi_4"
5981 [(set (reg FLAGS_REG)
5982 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5983 (match_operand:HI 2 "const_int_operand" "n")))
5984 (clobber (match_scratch:HI 0 "=rm"))]
5985 "ix86_match_ccmode (insn, CCGCmode)
5986 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5988 switch (get_attr_type (insn))
5991 if (operands[2] == constm1_rtx)
5992 return "inc{w}\t%0";
5995 gcc_assert (operands[2] == const1_rtx);
5996 return "dec{w}\t%0";
6000 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6001 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6003 if ((INTVAL (operands[2]) == -128
6004 || (INTVAL (operands[2]) > 0
6005 && INTVAL (operands[2]) != 128)))
6006 return "sub{w}\t{%2, %0|%0, %2}";
6007 operands[2] = GEN_INT (-INTVAL (operands[2]));
6008 return "add{w}\t{%2, %0|%0, %2}";
6012 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6013 (const_string "incdec")
6014 (const_string "alu")))
6015 (set_attr "mode" "SI")])
6018 (define_insn "*addhi_5"
6019 [(set (reg FLAGS_REG)
6021 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6022 (match_operand:HI 2 "general_operand" "rmni"))
6024 (clobber (match_scratch:HI 0 "=r"))]
6025 "ix86_match_ccmode (insn, CCGOCmode)
6026 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6028 switch (get_attr_type (insn))
6031 if (operands[2] == const1_rtx)
6032 return "inc{w}\t%0";
6035 gcc_assert (operands[2] == constm1_rtx);
6036 return "dec{w}\t%0";
6040 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6041 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6042 if (GET_CODE (operands[2]) == CONST_INT
6043 && (INTVAL (operands[2]) == 128
6044 || (INTVAL (operands[2]) < 0
6045 && INTVAL (operands[2]) != -128)))
6047 operands[2] = GEN_INT (-INTVAL (operands[2]));
6048 return "sub{w}\t{%2, %0|%0, %2}";
6050 return "add{w}\t{%2, %0|%0, %2}";
6054 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6055 (const_string "incdec")
6056 (const_string "alu")))
6057 (set_attr "mode" "HI")])
6059 (define_expand "addqi3"
6060 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6061 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6062 (match_operand:QI 2 "general_operand" "")))
6063 (clobber (reg:CC FLAGS_REG))])]
6064 "TARGET_QIMODE_MATH"
6065 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6067 ;; %%% Potential partial reg stall on alternative 2. What to do?
6068 (define_insn "*addqi_1_lea"
6069 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6070 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6071 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6072 (clobber (reg:CC FLAGS_REG))]
6073 "!TARGET_PARTIAL_REG_STALL
6074 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6076 int widen = (which_alternative == 2);
6077 switch (get_attr_type (insn))
6082 if (operands[2] == const1_rtx)
6083 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6086 gcc_assert (operands[2] == constm1_rtx);
6087 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6091 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6092 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6093 if (GET_CODE (operands[2]) == CONST_INT
6094 && (INTVAL (operands[2]) == 128
6095 || (INTVAL (operands[2]) < 0
6096 && INTVAL (operands[2]) != -128)))
6098 operands[2] = GEN_INT (-INTVAL (operands[2]));
6100 return "sub{l}\t{%2, %k0|%k0, %2}";
6102 return "sub{b}\t{%2, %0|%0, %2}";
6105 return "add{l}\t{%k2, %k0|%k0, %k2}";
6107 return "add{b}\t{%2, %0|%0, %2}";
6111 (if_then_else (eq_attr "alternative" "3")
6112 (const_string "lea")
6113 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6114 (const_string "incdec")
6115 (const_string "alu"))))
6116 (set_attr "mode" "QI,QI,SI,SI")])
6118 (define_insn "*addqi_1"
6119 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6120 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6121 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6122 (clobber (reg:CC FLAGS_REG))]
6123 "TARGET_PARTIAL_REG_STALL
6124 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6126 int widen = (which_alternative == 2);
6127 switch (get_attr_type (insn))
6130 if (operands[2] == const1_rtx)
6131 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6134 gcc_assert (operands[2] == constm1_rtx);
6135 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6139 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6140 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6141 if (GET_CODE (operands[2]) == CONST_INT
6142 && (INTVAL (operands[2]) == 128
6143 || (INTVAL (operands[2]) < 0
6144 && INTVAL (operands[2]) != -128)))
6146 operands[2] = GEN_INT (-INTVAL (operands[2]));
6148 return "sub{l}\t{%2, %k0|%k0, %2}";
6150 return "sub{b}\t{%2, %0|%0, %2}";
6153 return "add{l}\t{%k2, %k0|%k0, %k2}";
6155 return "add{b}\t{%2, %0|%0, %2}";
6159 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6160 (const_string "incdec")
6161 (const_string "alu")))
6162 (set_attr "mode" "QI,QI,SI")])
6164 (define_insn "*addqi_1_slp"
6165 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6166 (plus:QI (match_dup 0)
6167 (match_operand:QI 1 "general_operand" "qn,qnm")))
6168 (clobber (reg:CC FLAGS_REG))]
6169 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6170 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6172 switch (get_attr_type (insn))
6175 if (operands[1] == const1_rtx)
6176 return "inc{b}\t%0";
6179 gcc_assert (operands[1] == constm1_rtx);
6180 return "dec{b}\t%0";
6184 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6185 if (GET_CODE (operands[1]) == CONST_INT
6186 && INTVAL (operands[1]) < 0)
6188 operands[1] = GEN_INT (-INTVAL (operands[1]));
6189 return "sub{b}\t{%1, %0|%0, %1}";
6191 return "add{b}\t{%1, %0|%0, %1}";
6195 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6196 (const_string "incdec")
6197 (const_string "alu1")))
6198 (set (attr "memory")
6199 (if_then_else (match_operand 1 "memory_operand" "")
6200 (const_string "load")
6201 (const_string "none")))
6202 (set_attr "mode" "QI")])
6204 (define_insn "*addqi_2"
6205 [(set (reg FLAGS_REG)
6207 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6208 (match_operand:QI 2 "general_operand" "qmni,qni"))
6210 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6211 (plus:QI (match_dup 1) (match_dup 2)))]
6212 "ix86_match_ccmode (insn, CCGOCmode)
6213 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6215 switch (get_attr_type (insn))
6218 if (operands[2] == const1_rtx)
6219 return "inc{b}\t%0";
6222 gcc_assert (operands[2] == constm1_rtx
6223 || (GET_CODE (operands[2]) == CONST_INT
6224 && INTVAL (operands[2]) == 255));
6225 return "dec{b}\t%0";
6229 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6230 if (GET_CODE (operands[2]) == CONST_INT
6231 && INTVAL (operands[2]) < 0)
6233 operands[2] = GEN_INT (-INTVAL (operands[2]));
6234 return "sub{b}\t{%2, %0|%0, %2}";
6236 return "add{b}\t{%2, %0|%0, %2}";
6240 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6241 (const_string "incdec")
6242 (const_string "alu")))
6243 (set_attr "mode" "QI")])
6245 (define_insn "*addqi_3"
6246 [(set (reg FLAGS_REG)
6247 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6248 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6249 (clobber (match_scratch:QI 0 "=q"))]
6250 "ix86_match_ccmode (insn, CCZmode)
6251 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6253 switch (get_attr_type (insn))
6256 if (operands[2] == const1_rtx)
6257 return "inc{b}\t%0";
6260 gcc_assert (operands[2] == constm1_rtx
6261 || (GET_CODE (operands[2]) == CONST_INT
6262 && INTVAL (operands[2]) == 255));
6263 return "dec{b}\t%0";
6267 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6268 if (GET_CODE (operands[2]) == CONST_INT
6269 && INTVAL (operands[2]) < 0)
6271 operands[2] = GEN_INT (-INTVAL (operands[2]));
6272 return "sub{b}\t{%2, %0|%0, %2}";
6274 return "add{b}\t{%2, %0|%0, %2}";
6278 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6279 (const_string "incdec")
6280 (const_string "alu")))
6281 (set_attr "mode" "QI")])
6283 ; See comments above addsi_4 for details.
6284 (define_insn "*addqi_4"
6285 [(set (reg FLAGS_REG)
6286 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6287 (match_operand:QI 2 "const_int_operand" "n")))
6288 (clobber (match_scratch:QI 0 "=qm"))]
6289 "ix86_match_ccmode (insn, CCGCmode)
6290 && (INTVAL (operands[2]) & 0xff) != 0x80"
6292 switch (get_attr_type (insn))
6295 if (operands[2] == constm1_rtx
6296 || (GET_CODE (operands[2]) == CONST_INT
6297 && INTVAL (operands[2]) == 255))
6298 return "inc{b}\t%0";
6301 gcc_assert (operands[2] == const1_rtx);
6302 return "dec{b}\t%0";
6306 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6307 if (INTVAL (operands[2]) < 0)
6309 operands[2] = GEN_INT (-INTVAL (operands[2]));
6310 return "add{b}\t{%2, %0|%0, %2}";
6312 return "sub{b}\t{%2, %0|%0, %2}";
6316 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6317 (const_string "incdec")
6318 (const_string "alu")))
6319 (set_attr "mode" "QI")])
6322 (define_insn "*addqi_5"
6323 [(set (reg FLAGS_REG)
6325 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6326 (match_operand:QI 2 "general_operand" "qmni"))
6328 (clobber (match_scratch:QI 0 "=q"))]
6329 "ix86_match_ccmode (insn, CCGOCmode)
6330 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6332 switch (get_attr_type (insn))
6335 if (operands[2] == const1_rtx)
6336 return "inc{b}\t%0";
6339 gcc_assert (operands[2] == constm1_rtx
6340 || (GET_CODE (operands[2]) == CONST_INT
6341 && INTVAL (operands[2]) == 255));
6342 return "dec{b}\t%0";
6346 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6347 if (GET_CODE (operands[2]) == CONST_INT
6348 && INTVAL (operands[2]) < 0)
6350 operands[2] = GEN_INT (-INTVAL (operands[2]));
6351 return "sub{b}\t{%2, %0|%0, %2}";
6353 return "add{b}\t{%2, %0|%0, %2}";
6357 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6358 (const_string "incdec")
6359 (const_string "alu")))
6360 (set_attr "mode" "QI")])
6363 (define_insn "addqi_ext_1"
6364 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6369 (match_operand 1 "ext_register_operand" "0")
6372 (match_operand:QI 2 "general_operand" "Qmn")))
6373 (clobber (reg:CC FLAGS_REG))]
6376 switch (get_attr_type (insn))
6379 if (operands[2] == const1_rtx)
6380 return "inc{b}\t%h0";
6383 gcc_assert (operands[2] == constm1_rtx
6384 || (GET_CODE (operands[2]) == CONST_INT
6385 && INTVAL (operands[2]) == 255));
6386 return "dec{b}\t%h0";
6390 return "add{b}\t{%2, %h0|%h0, %2}";
6394 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6395 (const_string "incdec")
6396 (const_string "alu")))
6397 (set_attr "mode" "QI")])
6399 (define_insn "*addqi_ext_1_rex64"
6400 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6405 (match_operand 1 "ext_register_operand" "0")
6408 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6409 (clobber (reg:CC FLAGS_REG))]
6412 switch (get_attr_type (insn))
6415 if (operands[2] == const1_rtx)
6416 return "inc{b}\t%h0";
6419 gcc_assert (operands[2] == constm1_rtx
6420 || (GET_CODE (operands[2]) == CONST_INT
6421 && INTVAL (operands[2]) == 255));
6422 return "dec{b}\t%h0";
6426 return "add{b}\t{%2, %h0|%h0, %2}";
6430 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6431 (const_string "incdec")
6432 (const_string "alu")))
6433 (set_attr "mode" "QI")])
6435 (define_insn "*addqi_ext_2"
6436 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6441 (match_operand 1 "ext_register_operand" "%0")
6445 (match_operand 2 "ext_register_operand" "Q")
6448 (clobber (reg:CC FLAGS_REG))]
6450 "add{b}\t{%h2, %h0|%h0, %h2}"
6451 [(set_attr "type" "alu")
6452 (set_attr "mode" "QI")])
6454 ;; The patterns that match these are at the end of this file.
6456 (define_expand "addxf3"
6457 [(set (match_operand:XF 0 "register_operand" "")
6458 (plus:XF (match_operand:XF 1 "register_operand" "")
6459 (match_operand:XF 2 "register_operand" "")))]
6463 (define_expand "adddf3"
6464 [(set (match_operand:DF 0 "register_operand" "")
6465 (plus:DF (match_operand:DF 1 "register_operand" "")
6466 (match_operand:DF 2 "nonimmediate_operand" "")))]
6467 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6470 (define_expand "addsf3"
6471 [(set (match_operand:SF 0 "register_operand" "")
6472 (plus:SF (match_operand:SF 1 "register_operand" "")
6473 (match_operand:SF 2 "nonimmediate_operand" "")))]
6474 "TARGET_80387 || TARGET_SSE_MATH"
6477 ;; Subtract instructions
6479 ;; %%% splits for subditi3
6481 (define_expand "subti3"
6482 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6483 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6484 (match_operand:TI 2 "x86_64_general_operand" "")))
6485 (clobber (reg:CC FLAGS_REG))])]
6487 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6489 (define_insn "*subti3_1"
6490 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6491 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6492 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6493 (clobber (reg:CC FLAGS_REG))]
6494 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6498 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6499 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6500 (match_operand:TI 2 "x86_64_general_operand" "")))
6501 (clobber (reg:CC FLAGS_REG))]
6502 "TARGET_64BIT && reload_completed"
6503 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6504 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6505 (parallel [(set (match_dup 3)
6506 (minus:DI (match_dup 4)
6507 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6509 (clobber (reg:CC FLAGS_REG))])]
6510 "split_ti (operands+0, 1, operands+0, operands+3);
6511 split_ti (operands+1, 1, operands+1, operands+4);
6512 split_ti (operands+2, 1, operands+2, operands+5);")
6514 ;; %%% splits for subsidi3
6516 (define_expand "subdi3"
6517 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6518 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6519 (match_operand:DI 2 "x86_64_general_operand" "")))
6520 (clobber (reg:CC FLAGS_REG))])]
6522 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6524 (define_insn "*subdi3_1"
6525 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6526 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6527 (match_operand:DI 2 "general_operand" "roiF,riF")))
6528 (clobber (reg:CC FLAGS_REG))]
6529 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6533 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6534 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6535 (match_operand:DI 2 "general_operand" "")))
6536 (clobber (reg:CC FLAGS_REG))]
6537 "!TARGET_64BIT && reload_completed"
6538 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6539 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6540 (parallel [(set (match_dup 3)
6541 (minus:SI (match_dup 4)
6542 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6544 (clobber (reg:CC FLAGS_REG))])]
6545 "split_di (operands+0, 1, operands+0, operands+3);
6546 split_di (operands+1, 1, operands+1, operands+4);
6547 split_di (operands+2, 1, operands+2, operands+5);")
6549 (define_insn "subdi3_carry_rex64"
6550 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6551 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6552 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6553 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6554 (clobber (reg:CC FLAGS_REG))]
6555 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6556 "sbb{q}\t{%2, %0|%0, %2}"
6557 [(set_attr "type" "alu")
6558 (set_attr "pent_pair" "pu")
6559 (set_attr "mode" "DI")])
6561 (define_insn "*subdi_1_rex64"
6562 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6563 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6564 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6565 (clobber (reg:CC FLAGS_REG))]
6566 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6567 "sub{q}\t{%2, %0|%0, %2}"
6568 [(set_attr "type" "alu")
6569 (set_attr "mode" "DI")])
6571 (define_insn "*subdi_2_rex64"
6572 [(set (reg FLAGS_REG)
6574 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6575 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6577 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6578 (minus:DI (match_dup 1) (match_dup 2)))]
6579 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6580 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6581 "sub{q}\t{%2, %0|%0, %2}"
6582 [(set_attr "type" "alu")
6583 (set_attr "mode" "DI")])
6585 (define_insn "*subdi_3_rex63"
6586 [(set (reg FLAGS_REG)
6587 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6588 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6589 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6590 (minus:DI (match_dup 1) (match_dup 2)))]
6591 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6592 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6593 "sub{q}\t{%2, %0|%0, %2}"
6594 [(set_attr "type" "alu")
6595 (set_attr "mode" "DI")])
6597 (define_insn "subqi3_carry"
6598 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6599 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6600 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6601 (match_operand:QI 2 "general_operand" "qi,qm"))))
6602 (clobber (reg:CC FLAGS_REG))]
6603 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6604 "sbb{b}\t{%2, %0|%0, %2}"
6605 [(set_attr "type" "alu")
6606 (set_attr "pent_pair" "pu")
6607 (set_attr "mode" "QI")])
6609 (define_insn "subhi3_carry"
6610 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6611 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6612 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6613 (match_operand:HI 2 "general_operand" "ri,rm"))))
6614 (clobber (reg:CC FLAGS_REG))]
6615 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6616 "sbb{w}\t{%2, %0|%0, %2}"
6617 [(set_attr "type" "alu")
6618 (set_attr "pent_pair" "pu")
6619 (set_attr "mode" "HI")])
6621 (define_insn "subsi3_carry"
6622 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6623 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6624 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6625 (match_operand:SI 2 "general_operand" "ri,rm"))))
6626 (clobber (reg:CC FLAGS_REG))]
6627 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6628 "sbb{l}\t{%2, %0|%0, %2}"
6629 [(set_attr "type" "alu")
6630 (set_attr "pent_pair" "pu")
6631 (set_attr "mode" "SI")])
6633 (define_insn "subsi3_carry_zext"
6634 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6636 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6637 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6638 (match_operand:SI 2 "general_operand" "ri,rm")))))
6639 (clobber (reg:CC FLAGS_REG))]
6640 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6641 "sbb{l}\t{%2, %k0|%k0, %2}"
6642 [(set_attr "type" "alu")
6643 (set_attr "pent_pair" "pu")
6644 (set_attr "mode" "SI")])
6646 (define_expand "subsi3"
6647 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6648 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6649 (match_operand:SI 2 "general_operand" "")))
6650 (clobber (reg:CC FLAGS_REG))])]
6652 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6654 (define_insn "*subsi_1"
6655 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6656 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6657 (match_operand:SI 2 "general_operand" "ri,rm")))
6658 (clobber (reg:CC FLAGS_REG))]
6659 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6660 "sub{l}\t{%2, %0|%0, %2}"
6661 [(set_attr "type" "alu")
6662 (set_attr "mode" "SI")])
6664 (define_insn "*subsi_1_zext"
6665 [(set (match_operand:DI 0 "register_operand" "=r")
6667 (minus:SI (match_operand:SI 1 "register_operand" "0")
6668 (match_operand:SI 2 "general_operand" "rim"))))
6669 (clobber (reg:CC FLAGS_REG))]
6670 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6671 "sub{l}\t{%2, %k0|%k0, %2}"
6672 [(set_attr "type" "alu")
6673 (set_attr "mode" "SI")])
6675 (define_insn "*subsi_2"
6676 [(set (reg FLAGS_REG)
6678 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6679 (match_operand:SI 2 "general_operand" "ri,rm"))
6681 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6682 (minus:SI (match_dup 1) (match_dup 2)))]
6683 "ix86_match_ccmode (insn, CCGOCmode)
6684 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6685 "sub{l}\t{%2, %0|%0, %2}"
6686 [(set_attr "type" "alu")
6687 (set_attr "mode" "SI")])
6689 (define_insn "*subsi_2_zext"
6690 [(set (reg FLAGS_REG)
6692 (minus:SI (match_operand:SI 1 "register_operand" "0")
6693 (match_operand:SI 2 "general_operand" "rim"))
6695 (set (match_operand:DI 0 "register_operand" "=r")
6697 (minus:SI (match_dup 1)
6699 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6700 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6701 "sub{l}\t{%2, %k0|%k0, %2}"
6702 [(set_attr "type" "alu")
6703 (set_attr "mode" "SI")])
6705 (define_insn "*subsi_3"
6706 [(set (reg FLAGS_REG)
6707 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6708 (match_operand:SI 2 "general_operand" "ri,rm")))
6709 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6710 (minus:SI (match_dup 1) (match_dup 2)))]
6711 "ix86_match_ccmode (insn, CCmode)
6712 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6713 "sub{l}\t{%2, %0|%0, %2}"
6714 [(set_attr "type" "alu")
6715 (set_attr "mode" "SI")])
6717 (define_insn "*subsi_3_zext"
6718 [(set (reg FLAGS_REG)
6719 (compare (match_operand:SI 1 "register_operand" "0")
6720 (match_operand:SI 2 "general_operand" "rim")))
6721 (set (match_operand:DI 0 "register_operand" "=r")
6723 (minus:SI (match_dup 1)
6725 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6726 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6727 "sub{l}\t{%2, %1|%1, %2}"
6728 [(set_attr "type" "alu")
6729 (set_attr "mode" "DI")])
6731 (define_expand "subhi3"
6732 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6733 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6734 (match_operand:HI 2 "general_operand" "")))
6735 (clobber (reg:CC FLAGS_REG))])]
6736 "TARGET_HIMODE_MATH"
6737 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6739 (define_insn "*subhi_1"
6740 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6741 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6742 (match_operand:HI 2 "general_operand" "ri,rm")))
6743 (clobber (reg:CC FLAGS_REG))]
6744 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6745 "sub{w}\t{%2, %0|%0, %2}"
6746 [(set_attr "type" "alu")
6747 (set_attr "mode" "HI")])
6749 (define_insn "*subhi_2"
6750 [(set (reg FLAGS_REG)
6752 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6753 (match_operand:HI 2 "general_operand" "ri,rm"))
6755 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6756 (minus:HI (match_dup 1) (match_dup 2)))]
6757 "ix86_match_ccmode (insn, CCGOCmode)
6758 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6759 "sub{w}\t{%2, %0|%0, %2}"
6760 [(set_attr "type" "alu")
6761 (set_attr "mode" "HI")])
6763 (define_insn "*subhi_3"
6764 [(set (reg FLAGS_REG)
6765 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6766 (match_operand:HI 2 "general_operand" "ri,rm")))
6767 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6768 (minus:HI (match_dup 1) (match_dup 2)))]
6769 "ix86_match_ccmode (insn, CCmode)
6770 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6771 "sub{w}\t{%2, %0|%0, %2}"
6772 [(set_attr "type" "alu")
6773 (set_attr "mode" "HI")])
6775 (define_expand "subqi3"
6776 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6777 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6778 (match_operand:QI 2 "general_operand" "")))
6779 (clobber (reg:CC FLAGS_REG))])]
6780 "TARGET_QIMODE_MATH"
6781 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6783 (define_insn "*subqi_1"
6784 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6785 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6786 (match_operand:QI 2 "general_operand" "qn,qmn")))
6787 (clobber (reg:CC FLAGS_REG))]
6788 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6789 "sub{b}\t{%2, %0|%0, %2}"
6790 [(set_attr "type" "alu")
6791 (set_attr "mode" "QI")])
6793 (define_insn "*subqi_1_slp"
6794 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6795 (minus:QI (match_dup 0)
6796 (match_operand:QI 1 "general_operand" "qn,qmn")))
6797 (clobber (reg:CC FLAGS_REG))]
6798 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6799 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6800 "sub{b}\t{%1, %0|%0, %1}"
6801 [(set_attr "type" "alu1")
6802 (set_attr "mode" "QI")])
6804 (define_insn "*subqi_2"
6805 [(set (reg FLAGS_REG)
6807 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6808 (match_operand:QI 2 "general_operand" "qi,qm"))
6810 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6811 (minus:HI (match_dup 1) (match_dup 2)))]
6812 "ix86_match_ccmode (insn, CCGOCmode)
6813 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6814 "sub{b}\t{%2, %0|%0, %2}"
6815 [(set_attr "type" "alu")
6816 (set_attr "mode" "QI")])
6818 (define_insn "*subqi_3"
6819 [(set (reg FLAGS_REG)
6820 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6821 (match_operand:QI 2 "general_operand" "qi,qm")))
6822 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6823 (minus:HI (match_dup 1) (match_dup 2)))]
6824 "ix86_match_ccmode (insn, CCmode)
6825 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6826 "sub{b}\t{%2, %0|%0, %2}"
6827 [(set_attr "type" "alu")
6828 (set_attr "mode" "QI")])
6830 ;; The patterns that match these are at the end of this file.
6832 (define_expand "subxf3"
6833 [(set (match_operand:XF 0 "register_operand" "")
6834 (minus:XF (match_operand:XF 1 "register_operand" "")
6835 (match_operand:XF 2 "register_operand" "")))]
6839 (define_expand "subdf3"
6840 [(set (match_operand:DF 0 "register_operand" "")
6841 (minus:DF (match_operand:DF 1 "register_operand" "")
6842 (match_operand:DF 2 "nonimmediate_operand" "")))]
6843 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6846 (define_expand "subsf3"
6847 [(set (match_operand:SF 0 "register_operand" "")
6848 (minus:SF (match_operand:SF 1 "register_operand" "")
6849 (match_operand:SF 2 "nonimmediate_operand" "")))]
6850 "TARGET_80387 || TARGET_SSE_MATH"
6853 ;; Multiply instructions
6855 (define_expand "muldi3"
6856 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6857 (mult:DI (match_operand:DI 1 "register_operand" "")
6858 (match_operand:DI 2 "x86_64_general_operand" "")))
6859 (clobber (reg:CC FLAGS_REG))])]
6863 (define_insn "*muldi3_1_rex64"
6864 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6865 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6866 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6867 (clobber (reg:CC FLAGS_REG))]
6869 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6871 imul{q}\t{%2, %1, %0|%0, %1, %2}
6872 imul{q}\t{%2, %1, %0|%0, %1, %2}
6873 imul{q}\t{%2, %0|%0, %2}"
6874 [(set_attr "type" "imul")
6875 (set_attr "prefix_0f" "0,0,1")
6876 (set (attr "athlon_decode")
6877 (cond [(eq_attr "cpu" "athlon")
6878 (const_string "vector")
6879 (eq_attr "alternative" "1")
6880 (const_string "vector")
6881 (and (eq_attr "alternative" "2")
6882 (match_operand 1 "memory_operand" ""))
6883 (const_string "vector")]
6884 (const_string "direct")))
6885 (set_attr "mode" "DI")])
6887 (define_expand "mulsi3"
6888 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6889 (mult:SI (match_operand:SI 1 "register_operand" "")
6890 (match_operand:SI 2 "general_operand" "")))
6891 (clobber (reg:CC FLAGS_REG))])]
6895 (define_insn "*mulsi3_1"
6896 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6897 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6898 (match_operand:SI 2 "general_operand" "K,i,mr")))
6899 (clobber (reg:CC FLAGS_REG))]
6900 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6902 imul{l}\t{%2, %1, %0|%0, %1, %2}
6903 imul{l}\t{%2, %1, %0|%0, %1, %2}
6904 imul{l}\t{%2, %0|%0, %2}"
6905 [(set_attr "type" "imul")
6906 (set_attr "prefix_0f" "0,0,1")
6907 (set (attr "athlon_decode")
6908 (cond [(eq_attr "cpu" "athlon")
6909 (const_string "vector")
6910 (eq_attr "alternative" "1")
6911 (const_string "vector")
6912 (and (eq_attr "alternative" "2")
6913 (match_operand 1 "memory_operand" ""))
6914 (const_string "vector")]
6915 (const_string "direct")))
6916 (set_attr "mode" "SI")])
6918 (define_insn "*mulsi3_1_zext"
6919 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6921 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6922 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6923 (clobber (reg:CC FLAGS_REG))]
6925 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6927 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6928 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6929 imul{l}\t{%2, %k0|%k0, %2}"
6930 [(set_attr "type" "imul")
6931 (set_attr "prefix_0f" "0,0,1")
6932 (set (attr "athlon_decode")
6933 (cond [(eq_attr "cpu" "athlon")
6934 (const_string "vector")
6935 (eq_attr "alternative" "1")
6936 (const_string "vector")
6937 (and (eq_attr "alternative" "2")
6938 (match_operand 1 "memory_operand" ""))
6939 (const_string "vector")]
6940 (const_string "direct")))
6941 (set_attr "mode" "SI")])
6943 (define_expand "mulhi3"
6944 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6945 (mult:HI (match_operand:HI 1 "register_operand" "")
6946 (match_operand:HI 2 "general_operand" "")))
6947 (clobber (reg:CC FLAGS_REG))])]
6948 "TARGET_HIMODE_MATH"
6951 (define_insn "*mulhi3_1"
6952 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6953 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6954 (match_operand:HI 2 "general_operand" "K,i,mr")))
6955 (clobber (reg:CC FLAGS_REG))]
6956 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6958 imul{w}\t{%2, %1, %0|%0, %1, %2}
6959 imul{w}\t{%2, %1, %0|%0, %1, %2}
6960 imul{w}\t{%2, %0|%0, %2}"
6961 [(set_attr "type" "imul")
6962 (set_attr "prefix_0f" "0,0,1")
6963 (set (attr "athlon_decode")
6964 (cond [(eq_attr "cpu" "athlon")
6965 (const_string "vector")
6966 (eq_attr "alternative" "1,2")
6967 (const_string "vector")]
6968 (const_string "direct")))
6969 (set_attr "mode" "HI")])
6971 (define_expand "mulqi3"
6972 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6973 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6974 (match_operand:QI 2 "register_operand" "")))
6975 (clobber (reg:CC FLAGS_REG))])]
6976 "TARGET_QIMODE_MATH"
6979 (define_insn "*mulqi3_1"
6980 [(set (match_operand:QI 0 "register_operand" "=a")
6981 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6982 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6983 (clobber (reg:CC FLAGS_REG))]
6985 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6987 [(set_attr "type" "imul")
6988 (set_attr "length_immediate" "0")
6989 (set (attr "athlon_decode")
6990 (if_then_else (eq_attr "cpu" "athlon")
6991 (const_string "vector")
6992 (const_string "direct")))
6993 (set_attr "mode" "QI")])
6995 (define_expand "umulqihi3"
6996 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6997 (mult:HI (zero_extend:HI
6998 (match_operand:QI 1 "nonimmediate_operand" ""))
7000 (match_operand:QI 2 "register_operand" ""))))
7001 (clobber (reg:CC FLAGS_REG))])]
7002 "TARGET_QIMODE_MATH"
7005 (define_insn "*umulqihi3_1"
7006 [(set (match_operand:HI 0 "register_operand" "=a")
7007 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7008 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7009 (clobber (reg:CC FLAGS_REG))]
7011 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7013 [(set_attr "type" "imul")
7014 (set_attr "length_immediate" "0")
7015 (set (attr "athlon_decode")
7016 (if_then_else (eq_attr "cpu" "athlon")
7017 (const_string "vector")
7018 (const_string "direct")))
7019 (set_attr "mode" "QI")])
7021 (define_expand "mulqihi3"
7022 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7023 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7024 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7025 (clobber (reg:CC FLAGS_REG))])]
7026 "TARGET_QIMODE_MATH"
7029 (define_insn "*mulqihi3_insn"
7030 [(set (match_operand:HI 0 "register_operand" "=a")
7031 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7032 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7033 (clobber (reg:CC FLAGS_REG))]
7035 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7037 [(set_attr "type" "imul")
7038 (set_attr "length_immediate" "0")
7039 (set (attr "athlon_decode")
7040 (if_then_else (eq_attr "cpu" "athlon")
7041 (const_string "vector")
7042 (const_string "direct")))
7043 (set_attr "mode" "QI")])
7045 (define_expand "umulditi3"
7046 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7047 (mult:TI (zero_extend:TI
7048 (match_operand:DI 1 "nonimmediate_operand" ""))
7050 (match_operand:DI 2 "register_operand" ""))))
7051 (clobber (reg:CC FLAGS_REG))])]
7055 (define_insn "*umulditi3_insn"
7056 [(set (match_operand:TI 0 "register_operand" "=A")
7057 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7058 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7059 (clobber (reg:CC FLAGS_REG))]
7061 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7063 [(set_attr "type" "imul")
7064 (set_attr "length_immediate" "0")
7065 (set (attr "athlon_decode")
7066 (if_then_else (eq_attr "cpu" "athlon")
7067 (const_string "vector")
7068 (const_string "double")))
7069 (set_attr "mode" "DI")])
7071 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7072 (define_expand "umulsidi3"
7073 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7074 (mult:DI (zero_extend:DI
7075 (match_operand:SI 1 "nonimmediate_operand" ""))
7077 (match_operand:SI 2 "register_operand" ""))))
7078 (clobber (reg:CC FLAGS_REG))])]
7082 (define_insn "*umulsidi3_insn"
7083 [(set (match_operand:DI 0 "register_operand" "=A")
7084 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7085 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7086 (clobber (reg:CC FLAGS_REG))]
7088 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7090 [(set_attr "type" "imul")
7091 (set_attr "length_immediate" "0")
7092 (set (attr "athlon_decode")
7093 (if_then_else (eq_attr "cpu" "athlon")
7094 (const_string "vector")
7095 (const_string "double")))
7096 (set_attr "mode" "SI")])
7098 (define_expand "mulditi3"
7099 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7100 (mult:TI (sign_extend:TI
7101 (match_operand:DI 1 "nonimmediate_operand" ""))
7103 (match_operand:DI 2 "register_operand" ""))))
7104 (clobber (reg:CC FLAGS_REG))])]
7108 (define_insn "*mulditi3_insn"
7109 [(set (match_operand:TI 0 "register_operand" "=A")
7110 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7111 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7112 (clobber (reg:CC FLAGS_REG))]
7114 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7116 [(set_attr "type" "imul")
7117 (set_attr "length_immediate" "0")
7118 (set (attr "athlon_decode")
7119 (if_then_else (eq_attr "cpu" "athlon")
7120 (const_string "vector")
7121 (const_string "double")))
7122 (set_attr "mode" "DI")])
7124 (define_expand "mulsidi3"
7125 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7126 (mult:DI (sign_extend:DI
7127 (match_operand:SI 1 "nonimmediate_operand" ""))
7129 (match_operand:SI 2 "register_operand" ""))))
7130 (clobber (reg:CC FLAGS_REG))])]
7134 (define_insn "*mulsidi3_insn"
7135 [(set (match_operand:DI 0 "register_operand" "=A")
7136 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7137 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7138 (clobber (reg:CC FLAGS_REG))]
7140 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7142 [(set_attr "type" "imul")
7143 (set_attr "length_immediate" "0")
7144 (set (attr "athlon_decode")
7145 (if_then_else (eq_attr "cpu" "athlon")
7146 (const_string "vector")
7147 (const_string "double")))
7148 (set_attr "mode" "SI")])
7150 (define_expand "umuldi3_highpart"
7151 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7154 (mult:TI (zero_extend:TI
7155 (match_operand:DI 1 "nonimmediate_operand" ""))
7157 (match_operand:DI 2 "register_operand" "")))
7159 (clobber (match_scratch:DI 3 ""))
7160 (clobber (reg:CC FLAGS_REG))])]
7164 (define_insn "*umuldi3_highpart_rex64"
7165 [(set (match_operand:DI 0 "register_operand" "=d")
7168 (mult:TI (zero_extend:TI
7169 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7171 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7173 (clobber (match_scratch:DI 3 "=1"))
7174 (clobber (reg:CC FLAGS_REG))]
7176 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7178 [(set_attr "type" "imul")
7179 (set_attr "length_immediate" "0")
7180 (set (attr "athlon_decode")
7181 (if_then_else (eq_attr "cpu" "athlon")
7182 (const_string "vector")
7183 (const_string "double")))
7184 (set_attr "mode" "DI")])
7186 (define_expand "umulsi3_highpart"
7187 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7190 (mult:DI (zero_extend:DI
7191 (match_operand:SI 1 "nonimmediate_operand" ""))
7193 (match_operand:SI 2 "register_operand" "")))
7195 (clobber (match_scratch:SI 3 ""))
7196 (clobber (reg:CC FLAGS_REG))])]
7200 (define_insn "*umulsi3_highpart_insn"
7201 [(set (match_operand:SI 0 "register_operand" "=d")
7204 (mult:DI (zero_extend:DI
7205 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7207 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7209 (clobber (match_scratch:SI 3 "=1"))
7210 (clobber (reg:CC FLAGS_REG))]
7211 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7213 [(set_attr "type" "imul")
7214 (set_attr "length_immediate" "0")
7215 (set (attr "athlon_decode")
7216 (if_then_else (eq_attr "cpu" "athlon")
7217 (const_string "vector")
7218 (const_string "double")))
7219 (set_attr "mode" "SI")])
7221 (define_insn "*umulsi3_highpart_zext"
7222 [(set (match_operand:DI 0 "register_operand" "=d")
7223 (zero_extend:DI (truncate:SI
7225 (mult:DI (zero_extend:DI
7226 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7228 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7230 (clobber (match_scratch:SI 3 "=1"))
7231 (clobber (reg:CC FLAGS_REG))]
7233 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7235 [(set_attr "type" "imul")
7236 (set_attr "length_immediate" "0")
7237 (set (attr "athlon_decode")
7238 (if_then_else (eq_attr "cpu" "athlon")
7239 (const_string "vector")
7240 (const_string "double")))
7241 (set_attr "mode" "SI")])
7243 (define_expand "smuldi3_highpart"
7244 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7247 (mult:TI (sign_extend:TI
7248 (match_operand:DI 1 "nonimmediate_operand" ""))
7250 (match_operand:DI 2 "register_operand" "")))
7252 (clobber (match_scratch:DI 3 ""))
7253 (clobber (reg:CC FLAGS_REG))])]
7257 (define_insn "*smuldi3_highpart_rex64"
7258 [(set (match_operand:DI 0 "register_operand" "=d")
7261 (mult:TI (sign_extend:TI
7262 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7264 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7266 (clobber (match_scratch:DI 3 "=1"))
7267 (clobber (reg:CC FLAGS_REG))]
7269 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7271 [(set_attr "type" "imul")
7272 (set (attr "athlon_decode")
7273 (if_then_else (eq_attr "cpu" "athlon")
7274 (const_string "vector")
7275 (const_string "double")))
7276 (set_attr "mode" "DI")])
7278 (define_expand "smulsi3_highpart"
7279 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7282 (mult:DI (sign_extend:DI
7283 (match_operand:SI 1 "nonimmediate_operand" ""))
7285 (match_operand:SI 2 "register_operand" "")))
7287 (clobber (match_scratch:SI 3 ""))
7288 (clobber (reg:CC FLAGS_REG))])]
7292 (define_insn "*smulsi3_highpart_insn"
7293 [(set (match_operand:SI 0 "register_operand" "=d")
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))]
7303 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7305 [(set_attr "type" "imul")
7306 (set (attr "athlon_decode")
7307 (if_then_else (eq_attr "cpu" "athlon")
7308 (const_string "vector")
7309 (const_string "double")))
7310 (set_attr "mode" "SI")])
7312 (define_insn "*smulsi3_highpart_zext"
7313 [(set (match_operand:DI 0 "register_operand" "=d")
7314 (zero_extend:DI (truncate:SI
7316 (mult:DI (sign_extend:DI
7317 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7319 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7321 (clobber (match_scratch:SI 3 "=1"))
7322 (clobber (reg:CC FLAGS_REG))]
7324 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7326 [(set_attr "type" "imul")
7327 (set (attr "athlon_decode")
7328 (if_then_else (eq_attr "cpu" "athlon")
7329 (const_string "vector")
7330 (const_string "double")))
7331 (set_attr "mode" "SI")])
7333 ;; The patterns that match these are at the end of this file.
7335 (define_expand "mulxf3"
7336 [(set (match_operand:XF 0 "register_operand" "")
7337 (mult:XF (match_operand:XF 1 "register_operand" "")
7338 (match_operand:XF 2 "register_operand" "")))]
7342 (define_expand "muldf3"
7343 [(set (match_operand:DF 0 "register_operand" "")
7344 (mult:DF (match_operand:DF 1 "register_operand" "")
7345 (match_operand:DF 2 "nonimmediate_operand" "")))]
7346 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7349 (define_expand "mulsf3"
7350 [(set (match_operand:SF 0 "register_operand" "")
7351 (mult:SF (match_operand:SF 1 "register_operand" "")
7352 (match_operand:SF 2 "nonimmediate_operand" "")))]
7353 "TARGET_80387 || TARGET_SSE_MATH"
7356 ;; Divide instructions
7358 (define_insn "divqi3"
7359 [(set (match_operand:QI 0 "register_operand" "=a")
7360 (div:QI (match_operand:HI 1 "register_operand" "0")
7361 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7362 (clobber (reg:CC FLAGS_REG))]
7363 "TARGET_QIMODE_MATH"
7365 [(set_attr "type" "idiv")
7366 (set_attr "mode" "QI")])
7368 (define_insn "udivqi3"
7369 [(set (match_operand:QI 0 "register_operand" "=a")
7370 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7371 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7372 (clobber (reg:CC FLAGS_REG))]
7373 "TARGET_QIMODE_MATH"
7375 [(set_attr "type" "idiv")
7376 (set_attr "mode" "QI")])
7378 ;; The patterns that match these are at the end of this file.
7380 (define_expand "divxf3"
7381 [(set (match_operand:XF 0 "register_operand" "")
7382 (div:XF (match_operand:XF 1 "register_operand" "")
7383 (match_operand:XF 2 "register_operand" "")))]
7387 (define_expand "divdf3"
7388 [(set (match_operand:DF 0 "register_operand" "")
7389 (div:DF (match_operand:DF 1 "register_operand" "")
7390 (match_operand:DF 2 "nonimmediate_operand" "")))]
7391 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7394 (define_expand "divsf3"
7395 [(set (match_operand:SF 0 "register_operand" "")
7396 (div:SF (match_operand:SF 1 "register_operand" "")
7397 (match_operand:SF 2 "nonimmediate_operand" "")))]
7398 "TARGET_80387 || TARGET_SSE_MATH"
7401 ;; Remainder instructions.
7403 (define_expand "divmoddi4"
7404 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7405 (div:DI (match_operand:DI 1 "register_operand" "")
7406 (match_operand:DI 2 "nonimmediate_operand" "")))
7407 (set (match_operand:DI 3 "register_operand" "")
7408 (mod:DI (match_dup 1) (match_dup 2)))
7409 (clobber (reg:CC FLAGS_REG))])]
7413 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7414 ;; Penalize eax case slightly because it results in worse scheduling
7416 (define_insn "*divmoddi4_nocltd_rex64"
7417 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7418 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7419 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7420 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7421 (mod:DI (match_dup 2) (match_dup 3)))
7422 (clobber (reg:CC FLAGS_REG))]
7423 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7425 [(set_attr "type" "multi")])
7427 (define_insn "*divmoddi4_cltd_rex64"
7428 [(set (match_operand:DI 0 "register_operand" "=a")
7429 (div:DI (match_operand:DI 2 "register_operand" "a")
7430 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7431 (set (match_operand:DI 1 "register_operand" "=&d")
7432 (mod:DI (match_dup 2) (match_dup 3)))
7433 (clobber (reg:CC FLAGS_REG))]
7434 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7436 [(set_attr "type" "multi")])
7438 (define_insn "*divmoddi_noext_rex64"
7439 [(set (match_operand:DI 0 "register_operand" "=a")
7440 (div:DI (match_operand:DI 1 "register_operand" "0")
7441 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7442 (set (match_operand:DI 3 "register_operand" "=d")
7443 (mod:DI (match_dup 1) (match_dup 2)))
7444 (use (match_operand:DI 4 "register_operand" "3"))
7445 (clobber (reg:CC FLAGS_REG))]
7448 [(set_attr "type" "idiv")
7449 (set_attr "mode" "DI")])
7452 [(set (match_operand:DI 0 "register_operand" "")
7453 (div:DI (match_operand:DI 1 "register_operand" "")
7454 (match_operand:DI 2 "nonimmediate_operand" "")))
7455 (set (match_operand:DI 3 "register_operand" "")
7456 (mod:DI (match_dup 1) (match_dup 2)))
7457 (clobber (reg:CC FLAGS_REG))]
7458 "TARGET_64BIT && reload_completed"
7459 [(parallel [(set (match_dup 3)
7460 (ashiftrt:DI (match_dup 4) (const_int 63)))
7461 (clobber (reg:CC FLAGS_REG))])
7462 (parallel [(set (match_dup 0)
7463 (div:DI (reg:DI 0) (match_dup 2)))
7465 (mod:DI (reg:DI 0) (match_dup 2)))
7467 (clobber (reg:CC FLAGS_REG))])]
7469 /* Avoid use of cltd in favor of a mov+shift. */
7470 if (!TARGET_USE_CLTD && !optimize_size)
7472 if (true_regnum (operands[1]))
7473 emit_move_insn (operands[0], operands[1]);
7475 emit_move_insn (operands[3], operands[1]);
7476 operands[4] = operands[3];
7480 gcc_assert (!true_regnum (operands[1]));
7481 operands[4] = operands[1];
7486 (define_expand "divmodsi4"
7487 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7488 (div:SI (match_operand:SI 1 "register_operand" "")
7489 (match_operand:SI 2 "nonimmediate_operand" "")))
7490 (set (match_operand:SI 3 "register_operand" "")
7491 (mod:SI (match_dup 1) (match_dup 2)))
7492 (clobber (reg:CC FLAGS_REG))])]
7496 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7497 ;; Penalize eax case slightly because it results in worse scheduling
7499 (define_insn "*divmodsi4_nocltd"
7500 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7501 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7502 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7503 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7504 (mod:SI (match_dup 2) (match_dup 3)))
7505 (clobber (reg:CC FLAGS_REG))]
7506 "!optimize_size && !TARGET_USE_CLTD"
7508 [(set_attr "type" "multi")])
7510 (define_insn "*divmodsi4_cltd"
7511 [(set (match_operand:SI 0 "register_operand" "=a")
7512 (div:SI (match_operand:SI 2 "register_operand" "a")
7513 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7514 (set (match_operand:SI 1 "register_operand" "=&d")
7515 (mod:SI (match_dup 2) (match_dup 3)))
7516 (clobber (reg:CC FLAGS_REG))]
7517 "optimize_size || TARGET_USE_CLTD"
7519 [(set_attr "type" "multi")])
7521 (define_insn "*divmodsi_noext"
7522 [(set (match_operand:SI 0 "register_operand" "=a")
7523 (div:SI (match_operand:SI 1 "register_operand" "0")
7524 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7525 (set (match_operand:SI 3 "register_operand" "=d")
7526 (mod:SI (match_dup 1) (match_dup 2)))
7527 (use (match_operand:SI 4 "register_operand" "3"))
7528 (clobber (reg:CC FLAGS_REG))]
7531 [(set_attr "type" "idiv")
7532 (set_attr "mode" "SI")])
7535 [(set (match_operand:SI 0 "register_operand" "")
7536 (div:SI (match_operand:SI 1 "register_operand" "")
7537 (match_operand:SI 2 "nonimmediate_operand" "")))
7538 (set (match_operand:SI 3 "register_operand" "")
7539 (mod:SI (match_dup 1) (match_dup 2)))
7540 (clobber (reg:CC FLAGS_REG))]
7542 [(parallel [(set (match_dup 3)
7543 (ashiftrt:SI (match_dup 4) (const_int 31)))
7544 (clobber (reg:CC FLAGS_REG))])
7545 (parallel [(set (match_dup 0)
7546 (div:SI (reg:SI 0) (match_dup 2)))
7548 (mod:SI (reg:SI 0) (match_dup 2)))
7550 (clobber (reg:CC FLAGS_REG))])]
7552 /* Avoid use of cltd in favor of a mov+shift. */
7553 if (!TARGET_USE_CLTD && !optimize_size)
7555 if (true_regnum (operands[1]))
7556 emit_move_insn (operands[0], operands[1]);
7558 emit_move_insn (operands[3], operands[1]);
7559 operands[4] = operands[3];
7563 gcc_assert (!true_regnum (operands[1]));
7564 operands[4] = operands[1];
7568 (define_insn "divmodhi4"
7569 [(set (match_operand:HI 0 "register_operand" "=a")
7570 (div:HI (match_operand:HI 1 "register_operand" "0")
7571 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7572 (set (match_operand:HI 3 "register_operand" "=&d")
7573 (mod:HI (match_dup 1) (match_dup 2)))
7574 (clobber (reg:CC FLAGS_REG))]
7575 "TARGET_HIMODE_MATH"
7577 [(set_attr "type" "multi")
7578 (set_attr "length_immediate" "0")
7579 (set_attr "mode" "SI")])
7581 (define_insn "udivmoddi4"
7582 [(set (match_operand:DI 0 "register_operand" "=a")
7583 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7584 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7585 (set (match_operand:DI 3 "register_operand" "=&d")
7586 (umod:DI (match_dup 1) (match_dup 2)))
7587 (clobber (reg:CC FLAGS_REG))]
7589 "xor{q}\t%3, %3\;div{q}\t%2"
7590 [(set_attr "type" "multi")
7591 (set_attr "length_immediate" "0")
7592 (set_attr "mode" "DI")])
7594 (define_insn "*udivmoddi4_noext"
7595 [(set (match_operand:DI 0 "register_operand" "=a")
7596 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7597 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7598 (set (match_operand:DI 3 "register_operand" "=d")
7599 (umod:DI (match_dup 1) (match_dup 2)))
7601 (clobber (reg:CC FLAGS_REG))]
7604 [(set_attr "type" "idiv")
7605 (set_attr "mode" "DI")])
7608 [(set (match_operand:DI 0 "register_operand" "")
7609 (udiv:DI (match_operand:DI 1 "register_operand" "")
7610 (match_operand:DI 2 "nonimmediate_operand" "")))
7611 (set (match_operand:DI 3 "register_operand" "")
7612 (umod:DI (match_dup 1) (match_dup 2)))
7613 (clobber (reg:CC FLAGS_REG))]
7614 "TARGET_64BIT && reload_completed"
7615 [(set (match_dup 3) (const_int 0))
7616 (parallel [(set (match_dup 0)
7617 (udiv:DI (match_dup 1) (match_dup 2)))
7619 (umod:DI (match_dup 1) (match_dup 2)))
7621 (clobber (reg:CC FLAGS_REG))])]
7624 (define_insn "udivmodsi4"
7625 [(set (match_operand:SI 0 "register_operand" "=a")
7626 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7627 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7628 (set (match_operand:SI 3 "register_operand" "=&d")
7629 (umod:SI (match_dup 1) (match_dup 2)))
7630 (clobber (reg:CC FLAGS_REG))]
7632 "xor{l}\t%3, %3\;div{l}\t%2"
7633 [(set_attr "type" "multi")
7634 (set_attr "length_immediate" "0")
7635 (set_attr "mode" "SI")])
7637 (define_insn "*udivmodsi4_noext"
7638 [(set (match_operand:SI 0 "register_operand" "=a")
7639 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7640 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7641 (set (match_operand:SI 3 "register_operand" "=d")
7642 (umod:SI (match_dup 1) (match_dup 2)))
7644 (clobber (reg:CC FLAGS_REG))]
7647 [(set_attr "type" "idiv")
7648 (set_attr "mode" "SI")])
7651 [(set (match_operand:SI 0 "register_operand" "")
7652 (udiv:SI (match_operand:SI 1 "register_operand" "")
7653 (match_operand:SI 2 "nonimmediate_operand" "")))
7654 (set (match_operand:SI 3 "register_operand" "")
7655 (umod:SI (match_dup 1) (match_dup 2)))
7656 (clobber (reg:CC FLAGS_REG))]
7658 [(set (match_dup 3) (const_int 0))
7659 (parallel [(set (match_dup 0)
7660 (udiv:SI (match_dup 1) (match_dup 2)))
7662 (umod:SI (match_dup 1) (match_dup 2)))
7664 (clobber (reg:CC FLAGS_REG))])]
7667 (define_expand "udivmodhi4"
7668 [(set (match_dup 4) (const_int 0))
7669 (parallel [(set (match_operand:HI 0 "register_operand" "")
7670 (udiv:HI (match_operand:HI 1 "register_operand" "")
7671 (match_operand:HI 2 "nonimmediate_operand" "")))
7672 (set (match_operand:HI 3 "register_operand" "")
7673 (umod:HI (match_dup 1) (match_dup 2)))
7675 (clobber (reg:CC FLAGS_REG))])]
7676 "TARGET_HIMODE_MATH"
7677 "operands[4] = gen_reg_rtx (HImode);")
7679 (define_insn "*udivmodhi_noext"
7680 [(set (match_operand:HI 0 "register_operand" "=a")
7681 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7682 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7683 (set (match_operand:HI 3 "register_operand" "=d")
7684 (umod:HI (match_dup 1) (match_dup 2)))
7685 (use (match_operand:HI 4 "register_operand" "3"))
7686 (clobber (reg:CC FLAGS_REG))]
7689 [(set_attr "type" "idiv")
7690 (set_attr "mode" "HI")])
7692 ;; We cannot use div/idiv for double division, because it causes
7693 ;; "division by zero" on the overflow and that's not what we expect
7694 ;; from truncate. Because true (non truncating) double division is
7695 ;; never generated, we can't create this insn anyway.
7698 ; [(set (match_operand:SI 0 "register_operand" "=a")
7700 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7702 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7703 ; (set (match_operand:SI 3 "register_operand" "=d")
7705 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7706 ; (clobber (reg:CC FLAGS_REG))]
7708 ; "div{l}\t{%2, %0|%0, %2}"
7709 ; [(set_attr "type" "idiv")])
7711 ;;- Logical AND instructions
7713 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7714 ;; Note that this excludes ah.
7716 (define_insn "*testdi_1_rex64"
7717 [(set (reg FLAGS_REG)
7719 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7720 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7722 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7723 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7725 test{l}\t{%k1, %k0|%k0, %k1}
7726 test{l}\t{%k1, %k0|%k0, %k1}
7727 test{q}\t{%1, %0|%0, %1}
7728 test{q}\t{%1, %0|%0, %1}
7729 test{q}\t{%1, %0|%0, %1}"
7730 [(set_attr "type" "test")
7731 (set_attr "modrm" "0,1,0,1,1")
7732 (set_attr "mode" "SI,SI,DI,DI,DI")
7733 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7735 (define_insn "testsi_1"
7736 [(set (reg FLAGS_REG)
7738 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7739 (match_operand:SI 1 "general_operand" "in,in,rin"))
7741 "ix86_match_ccmode (insn, CCNOmode)
7742 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7743 "test{l}\t{%1, %0|%0, %1}"
7744 [(set_attr "type" "test")
7745 (set_attr "modrm" "0,1,1")
7746 (set_attr "mode" "SI")
7747 (set_attr "pent_pair" "uv,np,uv")])
7749 (define_expand "testsi_ccno_1"
7750 [(set (reg:CCNO FLAGS_REG)
7752 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7753 (match_operand:SI 1 "nonmemory_operand" ""))
7758 (define_insn "*testhi_1"
7759 [(set (reg FLAGS_REG)
7760 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7761 (match_operand:HI 1 "general_operand" "n,n,rn"))
7763 "ix86_match_ccmode (insn, CCNOmode)
7764 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7765 "test{w}\t{%1, %0|%0, %1}"
7766 [(set_attr "type" "test")
7767 (set_attr "modrm" "0,1,1")
7768 (set_attr "mode" "HI")
7769 (set_attr "pent_pair" "uv,np,uv")])
7771 (define_expand "testqi_ccz_1"
7772 [(set (reg:CCZ FLAGS_REG)
7773 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7774 (match_operand:QI 1 "nonmemory_operand" ""))
7779 (define_insn "*testqi_1_maybe_si"
7780 [(set (reg FLAGS_REG)
7783 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7784 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7786 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7787 && ix86_match_ccmode (insn,
7788 GET_CODE (operands[1]) == CONST_INT
7789 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7791 if (which_alternative == 3)
7793 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7794 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7795 return "test{l}\t{%1, %k0|%k0, %1}";
7797 return "test{b}\t{%1, %0|%0, %1}";
7799 [(set_attr "type" "test")
7800 (set_attr "modrm" "0,1,1,1")
7801 (set_attr "mode" "QI,QI,QI,SI")
7802 (set_attr "pent_pair" "uv,np,uv,np")])
7804 (define_insn "*testqi_1"
7805 [(set (reg FLAGS_REG)
7808 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7809 (match_operand:QI 1 "general_operand" "n,n,qn"))
7811 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7812 && ix86_match_ccmode (insn, CCNOmode)"
7813 "test{b}\t{%1, %0|%0, %1}"
7814 [(set_attr "type" "test")
7815 (set_attr "modrm" "0,1,1")
7816 (set_attr "mode" "QI")
7817 (set_attr "pent_pair" "uv,np,uv")])
7819 (define_expand "testqi_ext_ccno_0"
7820 [(set (reg:CCNO FLAGS_REG)
7824 (match_operand 0 "ext_register_operand" "")
7827 (match_operand 1 "const_int_operand" ""))
7832 (define_insn "*testqi_ext_0"
7833 [(set (reg FLAGS_REG)
7837 (match_operand 0 "ext_register_operand" "Q")
7840 (match_operand 1 "const_int_operand" "n"))
7842 "ix86_match_ccmode (insn, CCNOmode)"
7843 "test{b}\t{%1, %h0|%h0, %1}"
7844 [(set_attr "type" "test")
7845 (set_attr "mode" "QI")
7846 (set_attr "length_immediate" "1")
7847 (set_attr "pent_pair" "np")])
7849 (define_insn "*testqi_ext_1"
7850 [(set (reg FLAGS_REG)
7854 (match_operand 0 "ext_register_operand" "Q")
7858 (match_operand:QI 1 "general_operand" "Qm")))
7860 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7861 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7862 "test{b}\t{%1, %h0|%h0, %1}"
7863 [(set_attr "type" "test")
7864 (set_attr "mode" "QI")])
7866 (define_insn "*testqi_ext_1_rex64"
7867 [(set (reg FLAGS_REG)
7871 (match_operand 0 "ext_register_operand" "Q")
7875 (match_operand:QI 1 "register_operand" "Q")))
7877 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7878 "test{b}\t{%1, %h0|%h0, %1}"
7879 [(set_attr "type" "test")
7880 (set_attr "mode" "QI")])
7882 (define_insn "*testqi_ext_2"
7883 [(set (reg FLAGS_REG)
7887 (match_operand 0 "ext_register_operand" "Q")
7891 (match_operand 1 "ext_register_operand" "Q")
7895 "ix86_match_ccmode (insn, CCNOmode)"
7896 "test{b}\t{%h1, %h0|%h0, %h1}"
7897 [(set_attr "type" "test")
7898 (set_attr "mode" "QI")])
7900 ;; Combine likes to form bit extractions for some tests. Humor it.
7901 (define_insn "*testqi_ext_3"
7902 [(set (reg FLAGS_REG)
7903 (compare (zero_extract:SI
7904 (match_operand 0 "nonimmediate_operand" "rm")
7905 (match_operand:SI 1 "const_int_operand" "")
7906 (match_operand:SI 2 "const_int_operand" ""))
7908 "ix86_match_ccmode (insn, CCNOmode)
7909 && INTVAL (operands[1]) > 0
7910 && INTVAL (operands[2]) >= 0
7911 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7912 && (GET_MODE (operands[0]) == SImode
7913 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7914 || GET_MODE (operands[0]) == HImode
7915 || GET_MODE (operands[0]) == QImode)"
7918 (define_insn "*testqi_ext_3_rex64"
7919 [(set (reg FLAGS_REG)
7920 (compare (zero_extract:DI
7921 (match_operand 0 "nonimmediate_operand" "rm")
7922 (match_operand:DI 1 "const_int_operand" "")
7923 (match_operand:DI 2 "const_int_operand" ""))
7926 && ix86_match_ccmode (insn, CCNOmode)
7927 && INTVAL (operands[1]) > 0
7928 && INTVAL (operands[2]) >= 0
7929 /* Ensure that resulting mask is zero or sign extended operand. */
7930 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7931 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7932 && INTVAL (operands[1]) > 32))
7933 && (GET_MODE (operands[0]) == SImode
7934 || GET_MODE (operands[0]) == DImode
7935 || GET_MODE (operands[0]) == HImode
7936 || GET_MODE (operands[0]) == QImode)"
7940 [(set (match_operand 0 "flags_reg_operand" "")
7941 (match_operator 1 "compare_operator"
7943 (match_operand 2 "nonimmediate_operand" "")
7944 (match_operand 3 "const_int_operand" "")
7945 (match_operand 4 "const_int_operand" ""))
7947 "ix86_match_ccmode (insn, CCNOmode)"
7948 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7950 rtx val = operands[2];
7951 HOST_WIDE_INT len = INTVAL (operands[3]);
7952 HOST_WIDE_INT pos = INTVAL (operands[4]);
7954 enum machine_mode mode, submode;
7956 mode = GET_MODE (val);
7957 if (GET_CODE (val) == MEM)
7959 /* ??? Combine likes to put non-volatile mem extractions in QImode
7960 no matter the size of the test. So find a mode that works. */
7961 if (! MEM_VOLATILE_P (val))
7963 mode = smallest_mode_for_size (pos + len, MODE_INT);
7964 val = adjust_address (val, mode, 0);
7967 else if (GET_CODE (val) == SUBREG
7968 && (submode = GET_MODE (SUBREG_REG (val)),
7969 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7970 && pos + len <= GET_MODE_BITSIZE (submode))
7972 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7974 val = SUBREG_REG (val);
7976 else if (mode == HImode && pos + len <= 8)
7978 /* Small HImode tests can be converted to QImode. */
7980 val = gen_lowpart (QImode, val);
7983 if (len == HOST_BITS_PER_WIDE_INT)
7986 mask = ((HOST_WIDE_INT)1 << len) - 1;
7989 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7992 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7993 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7994 ;; this is relatively important trick.
7995 ;; Do the conversion only post-reload to avoid limiting of the register class
7998 [(set (match_operand 0 "flags_reg_operand" "")
7999 (match_operator 1 "compare_operator"
8000 [(and (match_operand 2 "register_operand" "")
8001 (match_operand 3 "const_int_operand" ""))
8004 && QI_REG_P (operands[2])
8005 && GET_MODE (operands[2]) != QImode
8006 && ((ix86_match_ccmode (insn, CCZmode)
8007 && !(INTVAL (operands[3]) & ~(255 << 8)))
8008 || (ix86_match_ccmode (insn, CCNOmode)
8009 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8012 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8015 "operands[2] = gen_lowpart (SImode, operands[2]);
8016 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8019 [(set (match_operand 0 "flags_reg_operand" "")
8020 (match_operator 1 "compare_operator"
8021 [(and (match_operand 2 "nonimmediate_operand" "")
8022 (match_operand 3 "const_int_operand" ""))
8025 && GET_MODE (operands[2]) != QImode
8026 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8027 && ((ix86_match_ccmode (insn, CCZmode)
8028 && !(INTVAL (operands[3]) & ~255))
8029 || (ix86_match_ccmode (insn, CCNOmode)
8030 && !(INTVAL (operands[3]) & ~127)))"
8032 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8034 "operands[2] = gen_lowpart (QImode, operands[2]);
8035 operands[3] = gen_lowpart (QImode, operands[3]);")
8038 ;; %%% This used to optimize known byte-wide and operations to memory,
8039 ;; and sometimes to QImode registers. If this is considered useful,
8040 ;; it should be done with splitters.
8042 (define_expand "anddi3"
8043 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8044 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8045 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8046 (clobber (reg:CC FLAGS_REG))]
8048 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8050 (define_insn "*anddi_1_rex64"
8051 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8052 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8053 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8054 (clobber (reg:CC FLAGS_REG))]
8055 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8057 switch (get_attr_type (insn))
8061 enum machine_mode mode;
8063 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8064 if (INTVAL (operands[2]) == 0xff)
8068 gcc_assert (INTVAL (operands[2]) == 0xffff);
8072 operands[1] = gen_lowpart (mode, operands[1]);
8074 return "movz{bq|x}\t{%1,%0|%0, %1}";
8076 return "movz{wq|x}\t{%1,%0|%0, %1}";
8080 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8081 if (get_attr_mode (insn) == MODE_SI)
8082 return "and{l}\t{%k2, %k0|%k0, %k2}";
8084 return "and{q}\t{%2, %0|%0, %2}";
8087 [(set_attr "type" "alu,alu,alu,imovx")
8088 (set_attr "length_immediate" "*,*,*,0")
8089 (set_attr "mode" "SI,DI,DI,DI")])
8091 (define_insn "*anddi_2"
8092 [(set (reg FLAGS_REG)
8093 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8094 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8096 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8097 (and:DI (match_dup 1) (match_dup 2)))]
8098 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8099 && ix86_binary_operator_ok (AND, DImode, operands)"
8101 and{l}\t{%k2, %k0|%k0, %k2}
8102 and{q}\t{%2, %0|%0, %2}
8103 and{q}\t{%2, %0|%0, %2}"
8104 [(set_attr "type" "alu")
8105 (set_attr "mode" "SI,DI,DI")])
8107 (define_expand "andsi3"
8108 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8109 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8110 (match_operand:SI 2 "general_operand" "")))
8111 (clobber (reg:CC FLAGS_REG))]
8113 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8115 (define_insn "*andsi_1"
8116 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8117 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8118 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8119 (clobber (reg:CC FLAGS_REG))]
8120 "ix86_binary_operator_ok (AND, SImode, operands)"
8122 switch (get_attr_type (insn))
8126 enum machine_mode mode;
8128 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8129 if (INTVAL (operands[2]) == 0xff)
8133 gcc_assert (INTVAL (operands[2]) == 0xffff);
8137 operands[1] = gen_lowpart (mode, operands[1]);
8139 return "movz{bl|x}\t{%1,%0|%0, %1}";
8141 return "movz{wl|x}\t{%1,%0|%0, %1}";
8145 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8146 return "and{l}\t{%2, %0|%0, %2}";
8149 [(set_attr "type" "alu,alu,imovx")
8150 (set_attr "length_immediate" "*,*,0")
8151 (set_attr "mode" "SI")])
8154 [(set (match_operand 0 "register_operand" "")
8156 (const_int -65536)))
8157 (clobber (reg:CC FLAGS_REG))]
8158 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8159 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8160 "operands[1] = gen_lowpart (HImode, operands[0]);")
8163 [(set (match_operand 0 "ext_register_operand" "")
8166 (clobber (reg:CC FLAGS_REG))]
8167 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8168 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8169 "operands[1] = gen_lowpart (QImode, operands[0]);")
8172 [(set (match_operand 0 "ext_register_operand" "")
8174 (const_int -65281)))
8175 (clobber (reg:CC FLAGS_REG))]
8176 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8177 [(parallel [(set (zero_extract:SI (match_dup 0)
8181 (zero_extract:SI (match_dup 0)
8184 (zero_extract:SI (match_dup 0)
8187 (clobber (reg:CC FLAGS_REG))])]
8188 "operands[0] = gen_lowpart (SImode, operands[0]);")
8190 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8191 (define_insn "*andsi_1_zext"
8192 [(set (match_operand:DI 0 "register_operand" "=r")
8194 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8195 (match_operand:SI 2 "general_operand" "rim"))))
8196 (clobber (reg:CC FLAGS_REG))]
8197 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8198 "and{l}\t{%2, %k0|%k0, %2}"
8199 [(set_attr "type" "alu")
8200 (set_attr "mode" "SI")])
8202 (define_insn "*andsi_2"
8203 [(set (reg FLAGS_REG)
8204 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8205 (match_operand:SI 2 "general_operand" "rim,ri"))
8207 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8208 (and:SI (match_dup 1) (match_dup 2)))]
8209 "ix86_match_ccmode (insn, CCNOmode)
8210 && ix86_binary_operator_ok (AND, SImode, operands)"
8211 "and{l}\t{%2, %0|%0, %2}"
8212 [(set_attr "type" "alu")
8213 (set_attr "mode" "SI")])
8215 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8216 (define_insn "*andsi_2_zext"
8217 [(set (reg FLAGS_REG)
8218 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8219 (match_operand:SI 2 "general_operand" "rim"))
8221 (set (match_operand:DI 0 "register_operand" "=r")
8222 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8223 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8224 && ix86_binary_operator_ok (AND, SImode, operands)"
8225 "and{l}\t{%2, %k0|%k0, %2}"
8226 [(set_attr "type" "alu")
8227 (set_attr "mode" "SI")])
8229 (define_expand "andhi3"
8230 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8231 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8232 (match_operand:HI 2 "general_operand" "")))
8233 (clobber (reg:CC FLAGS_REG))]
8234 "TARGET_HIMODE_MATH"
8235 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8237 (define_insn "*andhi_1"
8238 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8239 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8240 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8241 (clobber (reg:CC FLAGS_REG))]
8242 "ix86_binary_operator_ok (AND, HImode, operands)"
8244 switch (get_attr_type (insn))
8247 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8248 gcc_assert (INTVAL (operands[2]) == 0xff);
8249 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8252 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8254 return "and{w}\t{%2, %0|%0, %2}";
8257 [(set_attr "type" "alu,alu,imovx")
8258 (set_attr "length_immediate" "*,*,0")
8259 (set_attr "mode" "HI,HI,SI")])
8261 (define_insn "*andhi_2"
8262 [(set (reg FLAGS_REG)
8263 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8264 (match_operand:HI 2 "general_operand" "rim,ri"))
8266 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8267 (and:HI (match_dup 1) (match_dup 2)))]
8268 "ix86_match_ccmode (insn, CCNOmode)
8269 && ix86_binary_operator_ok (AND, HImode, operands)"
8270 "and{w}\t{%2, %0|%0, %2}"
8271 [(set_attr "type" "alu")
8272 (set_attr "mode" "HI")])
8274 (define_expand "andqi3"
8275 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8276 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8277 (match_operand:QI 2 "general_operand" "")))
8278 (clobber (reg:CC FLAGS_REG))]
8279 "TARGET_QIMODE_MATH"
8280 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8282 ;; %%% Potential partial reg stall on alternative 2. What to do?
8283 (define_insn "*andqi_1"
8284 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8285 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8286 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8287 (clobber (reg:CC FLAGS_REG))]
8288 "ix86_binary_operator_ok (AND, QImode, operands)"
8290 and{b}\t{%2, %0|%0, %2}
8291 and{b}\t{%2, %0|%0, %2}
8292 and{l}\t{%k2, %k0|%k0, %k2}"
8293 [(set_attr "type" "alu")
8294 (set_attr "mode" "QI,QI,SI")])
8296 (define_insn "*andqi_1_slp"
8297 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8298 (and:QI (match_dup 0)
8299 (match_operand:QI 1 "general_operand" "qi,qmi")))
8300 (clobber (reg:CC FLAGS_REG))]
8301 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8302 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8303 "and{b}\t{%1, %0|%0, %1}"
8304 [(set_attr "type" "alu1")
8305 (set_attr "mode" "QI")])
8307 (define_insn "*andqi_2_maybe_si"
8308 [(set (reg FLAGS_REG)
8310 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8311 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8313 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8314 (and:QI (match_dup 1) (match_dup 2)))]
8315 "ix86_binary_operator_ok (AND, QImode, operands)
8316 && ix86_match_ccmode (insn,
8317 GET_CODE (operands[2]) == CONST_INT
8318 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8320 if (which_alternative == 2)
8322 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8323 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8324 return "and{l}\t{%2, %k0|%k0, %2}";
8326 return "and{b}\t{%2, %0|%0, %2}";
8328 [(set_attr "type" "alu")
8329 (set_attr "mode" "QI,QI,SI")])
8331 (define_insn "*andqi_2"
8332 [(set (reg FLAGS_REG)
8334 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8335 (match_operand:QI 2 "general_operand" "qim,qi"))
8337 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8338 (and:QI (match_dup 1) (match_dup 2)))]
8339 "ix86_match_ccmode (insn, CCNOmode)
8340 && ix86_binary_operator_ok (AND, QImode, operands)"
8341 "and{b}\t{%2, %0|%0, %2}"
8342 [(set_attr "type" "alu")
8343 (set_attr "mode" "QI")])
8345 (define_insn "*andqi_2_slp"
8346 [(set (reg FLAGS_REG)
8348 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8349 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8351 (set (strict_low_part (match_dup 0))
8352 (and:QI (match_dup 0) (match_dup 1)))]
8353 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8354 && ix86_match_ccmode (insn, CCNOmode)
8355 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8356 "and{b}\t{%1, %0|%0, %1}"
8357 [(set_attr "type" "alu1")
8358 (set_attr "mode" "QI")])
8360 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8361 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8362 ;; for a QImode operand, which of course failed.
8364 (define_insn "andqi_ext_0"
8365 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8370 (match_operand 1 "ext_register_operand" "0")
8373 (match_operand 2 "const_int_operand" "n")))
8374 (clobber (reg:CC FLAGS_REG))]
8376 "and{b}\t{%2, %h0|%h0, %2}"
8377 [(set_attr "type" "alu")
8378 (set_attr "length_immediate" "1")
8379 (set_attr "mode" "QI")])
8381 ;; Generated by peephole translating test to and. This shows up
8382 ;; often in fp comparisons.
8384 (define_insn "*andqi_ext_0_cc"
8385 [(set (reg FLAGS_REG)
8389 (match_operand 1 "ext_register_operand" "0")
8392 (match_operand 2 "const_int_operand" "n"))
8394 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8403 "ix86_match_ccmode (insn, CCNOmode)"
8404 "and{b}\t{%2, %h0|%h0, %2}"
8405 [(set_attr "type" "alu")
8406 (set_attr "length_immediate" "1")
8407 (set_attr "mode" "QI")])
8409 (define_insn "*andqi_ext_1"
8410 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8415 (match_operand 1 "ext_register_operand" "0")
8419 (match_operand:QI 2 "general_operand" "Qm"))))
8420 (clobber (reg:CC FLAGS_REG))]
8422 "and{b}\t{%2, %h0|%h0, %2}"
8423 [(set_attr "type" "alu")
8424 (set_attr "length_immediate" "0")
8425 (set_attr "mode" "QI")])
8427 (define_insn "*andqi_ext_1_rex64"
8428 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8433 (match_operand 1 "ext_register_operand" "0")
8437 (match_operand 2 "ext_register_operand" "Q"))))
8438 (clobber (reg:CC FLAGS_REG))]
8440 "and{b}\t{%2, %h0|%h0, %2}"
8441 [(set_attr "type" "alu")
8442 (set_attr "length_immediate" "0")
8443 (set_attr "mode" "QI")])
8445 (define_insn "*andqi_ext_2"
8446 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8451 (match_operand 1 "ext_register_operand" "%0")
8455 (match_operand 2 "ext_register_operand" "Q")
8458 (clobber (reg:CC FLAGS_REG))]
8460 "and{b}\t{%h2, %h0|%h0, %h2}"
8461 [(set_attr "type" "alu")
8462 (set_attr "length_immediate" "0")
8463 (set_attr "mode" "QI")])
8465 ;; Convert wide AND instructions with immediate operand to shorter QImode
8466 ;; equivalents when possible.
8467 ;; Don't do the splitting with memory operands, since it introduces risk
8468 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8469 ;; for size, but that can (should?) be handled by generic code instead.
8471 [(set (match_operand 0 "register_operand" "")
8472 (and (match_operand 1 "register_operand" "")
8473 (match_operand 2 "const_int_operand" "")))
8474 (clobber (reg:CC FLAGS_REG))]
8476 && QI_REG_P (operands[0])
8477 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8478 && !(~INTVAL (operands[2]) & ~(255 << 8))
8479 && GET_MODE (operands[0]) != QImode"
8480 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8481 (and:SI (zero_extract:SI (match_dup 1)
8482 (const_int 8) (const_int 8))
8484 (clobber (reg:CC FLAGS_REG))])]
8485 "operands[0] = gen_lowpart (SImode, operands[0]);
8486 operands[1] = gen_lowpart (SImode, operands[1]);
8487 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8489 ;; Since AND can be encoded with sign extended immediate, this is only
8490 ;; profitable when 7th bit is not set.
8492 [(set (match_operand 0 "register_operand" "")
8493 (and (match_operand 1 "general_operand" "")
8494 (match_operand 2 "const_int_operand" "")))
8495 (clobber (reg:CC FLAGS_REG))]
8497 && ANY_QI_REG_P (operands[0])
8498 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8499 && !(~INTVAL (operands[2]) & ~255)
8500 && !(INTVAL (operands[2]) & 128)
8501 && GET_MODE (operands[0]) != QImode"
8502 [(parallel [(set (strict_low_part (match_dup 0))
8503 (and:QI (match_dup 1)
8505 (clobber (reg:CC FLAGS_REG))])]
8506 "operands[0] = gen_lowpart (QImode, operands[0]);
8507 operands[1] = gen_lowpart (QImode, operands[1]);
8508 operands[2] = gen_lowpart (QImode, operands[2]);")
8510 ;; Logical inclusive OR instructions
8512 ;; %%% This used to optimize known byte-wide and operations to memory.
8513 ;; If this is considered useful, it should be done with splitters.
8515 (define_expand "iordi3"
8516 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8517 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8518 (match_operand:DI 2 "x86_64_general_operand" "")))
8519 (clobber (reg:CC FLAGS_REG))]
8521 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8523 (define_insn "*iordi_1_rex64"
8524 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8525 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8526 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8527 (clobber (reg:CC FLAGS_REG))]
8529 && ix86_binary_operator_ok (IOR, DImode, operands)"
8530 "or{q}\t{%2, %0|%0, %2}"
8531 [(set_attr "type" "alu")
8532 (set_attr "mode" "DI")])
8534 (define_insn "*iordi_2_rex64"
8535 [(set (reg FLAGS_REG)
8536 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8537 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8539 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8540 (ior:DI (match_dup 1) (match_dup 2)))]
8542 && ix86_match_ccmode (insn, CCNOmode)
8543 && ix86_binary_operator_ok (IOR, DImode, operands)"
8544 "or{q}\t{%2, %0|%0, %2}"
8545 [(set_attr "type" "alu")
8546 (set_attr "mode" "DI")])
8548 (define_insn "*iordi_3_rex64"
8549 [(set (reg FLAGS_REG)
8550 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8551 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8553 (clobber (match_scratch:DI 0 "=r"))]
8555 && ix86_match_ccmode (insn, CCNOmode)
8556 && ix86_binary_operator_ok (IOR, DImode, operands)"
8557 "or{q}\t{%2, %0|%0, %2}"
8558 [(set_attr "type" "alu")
8559 (set_attr "mode" "DI")])
8562 (define_expand "iorsi3"
8563 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8564 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8565 (match_operand:SI 2 "general_operand" "")))
8566 (clobber (reg:CC FLAGS_REG))]
8568 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8570 (define_insn "*iorsi_1"
8571 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8572 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8573 (match_operand:SI 2 "general_operand" "ri,rmi")))
8574 (clobber (reg:CC FLAGS_REG))]
8575 "ix86_binary_operator_ok (IOR, SImode, operands)"
8576 "or{l}\t{%2, %0|%0, %2}"
8577 [(set_attr "type" "alu")
8578 (set_attr "mode" "SI")])
8580 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8581 (define_insn "*iorsi_1_zext"
8582 [(set (match_operand:DI 0 "register_operand" "=rm")
8584 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8585 (match_operand:SI 2 "general_operand" "rim"))))
8586 (clobber (reg:CC FLAGS_REG))]
8587 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8588 "or{l}\t{%2, %k0|%k0, %2}"
8589 [(set_attr "type" "alu")
8590 (set_attr "mode" "SI")])
8592 (define_insn "*iorsi_1_zext_imm"
8593 [(set (match_operand:DI 0 "register_operand" "=rm")
8594 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8595 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8596 (clobber (reg:CC FLAGS_REG))]
8598 "or{l}\t{%2, %k0|%k0, %2}"
8599 [(set_attr "type" "alu")
8600 (set_attr "mode" "SI")])
8602 (define_insn "*iorsi_2"
8603 [(set (reg FLAGS_REG)
8604 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8605 (match_operand:SI 2 "general_operand" "rim,ri"))
8607 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8608 (ior:SI (match_dup 1) (match_dup 2)))]
8609 "ix86_match_ccmode (insn, CCNOmode)
8610 && ix86_binary_operator_ok (IOR, SImode, operands)"
8611 "or{l}\t{%2, %0|%0, %2}"
8612 [(set_attr "type" "alu")
8613 (set_attr "mode" "SI")])
8615 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8616 ;; ??? Special case for immediate operand is missing - it is tricky.
8617 (define_insn "*iorsi_2_zext"
8618 [(set (reg FLAGS_REG)
8619 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8620 (match_operand:SI 2 "general_operand" "rim"))
8622 (set (match_operand:DI 0 "register_operand" "=r")
8623 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8624 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8625 && ix86_binary_operator_ok (IOR, SImode, operands)"
8626 "or{l}\t{%2, %k0|%k0, %2}"
8627 [(set_attr "type" "alu")
8628 (set_attr "mode" "SI")])
8630 (define_insn "*iorsi_2_zext_imm"
8631 [(set (reg FLAGS_REG)
8632 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8633 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8635 (set (match_operand:DI 0 "register_operand" "=r")
8636 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8637 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8638 && ix86_binary_operator_ok (IOR, SImode, operands)"
8639 "or{l}\t{%2, %k0|%k0, %2}"
8640 [(set_attr "type" "alu")
8641 (set_attr "mode" "SI")])
8643 (define_insn "*iorsi_3"
8644 [(set (reg FLAGS_REG)
8645 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8646 (match_operand:SI 2 "general_operand" "rim"))
8648 (clobber (match_scratch:SI 0 "=r"))]
8649 "ix86_match_ccmode (insn, CCNOmode)
8650 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8651 "or{l}\t{%2, %0|%0, %2}"
8652 [(set_attr "type" "alu")
8653 (set_attr "mode" "SI")])
8655 (define_expand "iorhi3"
8656 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8657 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8658 (match_operand:HI 2 "general_operand" "")))
8659 (clobber (reg:CC FLAGS_REG))]
8660 "TARGET_HIMODE_MATH"
8661 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8663 (define_insn "*iorhi_1"
8664 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8665 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8666 (match_operand:HI 2 "general_operand" "rmi,ri")))
8667 (clobber (reg:CC FLAGS_REG))]
8668 "ix86_binary_operator_ok (IOR, HImode, operands)"
8669 "or{w}\t{%2, %0|%0, %2}"
8670 [(set_attr "type" "alu")
8671 (set_attr "mode" "HI")])
8673 (define_insn "*iorhi_2"
8674 [(set (reg FLAGS_REG)
8675 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8676 (match_operand:HI 2 "general_operand" "rim,ri"))
8678 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8679 (ior:HI (match_dup 1) (match_dup 2)))]
8680 "ix86_match_ccmode (insn, CCNOmode)
8681 && ix86_binary_operator_ok (IOR, HImode, operands)"
8682 "or{w}\t{%2, %0|%0, %2}"
8683 [(set_attr "type" "alu")
8684 (set_attr "mode" "HI")])
8686 (define_insn "*iorhi_3"
8687 [(set (reg FLAGS_REG)
8688 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8689 (match_operand:HI 2 "general_operand" "rim"))
8691 (clobber (match_scratch:HI 0 "=r"))]
8692 "ix86_match_ccmode (insn, CCNOmode)
8693 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8694 "or{w}\t{%2, %0|%0, %2}"
8695 [(set_attr "type" "alu")
8696 (set_attr "mode" "HI")])
8698 (define_expand "iorqi3"
8699 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8700 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8701 (match_operand:QI 2 "general_operand" "")))
8702 (clobber (reg:CC FLAGS_REG))]
8703 "TARGET_QIMODE_MATH"
8704 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8706 ;; %%% Potential partial reg stall on alternative 2. What to do?
8707 (define_insn "*iorqi_1"
8708 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8709 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8710 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8711 (clobber (reg:CC FLAGS_REG))]
8712 "ix86_binary_operator_ok (IOR, QImode, operands)"
8714 or{b}\t{%2, %0|%0, %2}
8715 or{b}\t{%2, %0|%0, %2}
8716 or{l}\t{%k2, %k0|%k0, %k2}"
8717 [(set_attr "type" "alu")
8718 (set_attr "mode" "QI,QI,SI")])
8720 (define_insn "*iorqi_1_slp"
8721 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8722 (ior:QI (match_dup 0)
8723 (match_operand:QI 1 "general_operand" "qmi,qi")))
8724 (clobber (reg:CC FLAGS_REG))]
8725 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8726 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8727 "or{b}\t{%1, %0|%0, %1}"
8728 [(set_attr "type" "alu1")
8729 (set_attr "mode" "QI")])
8731 (define_insn "*iorqi_2"
8732 [(set (reg FLAGS_REG)
8733 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8734 (match_operand:QI 2 "general_operand" "qim,qi"))
8736 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8737 (ior:QI (match_dup 1) (match_dup 2)))]
8738 "ix86_match_ccmode (insn, CCNOmode)
8739 && ix86_binary_operator_ok (IOR, QImode, operands)"
8740 "or{b}\t{%2, %0|%0, %2}"
8741 [(set_attr "type" "alu")
8742 (set_attr "mode" "QI")])
8744 (define_insn "*iorqi_2_slp"
8745 [(set (reg FLAGS_REG)
8746 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8747 (match_operand:QI 1 "general_operand" "qim,qi"))
8749 (set (strict_low_part (match_dup 0))
8750 (ior:QI (match_dup 0) (match_dup 1)))]
8751 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8752 && ix86_match_ccmode (insn, CCNOmode)
8753 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8754 "or{b}\t{%1, %0|%0, %1}"
8755 [(set_attr "type" "alu1")
8756 (set_attr "mode" "QI")])
8758 (define_insn "*iorqi_3"
8759 [(set (reg FLAGS_REG)
8760 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8761 (match_operand:QI 2 "general_operand" "qim"))
8763 (clobber (match_scratch:QI 0 "=q"))]
8764 "ix86_match_ccmode (insn, CCNOmode)
8765 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8766 "or{b}\t{%2, %0|%0, %2}"
8767 [(set_attr "type" "alu")
8768 (set_attr "mode" "QI")])
8770 (define_insn "iorqi_ext_0"
8771 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8776 (match_operand 1 "ext_register_operand" "0")
8779 (match_operand 2 "const_int_operand" "n")))
8780 (clobber (reg:CC FLAGS_REG))]
8781 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8782 "or{b}\t{%2, %h0|%h0, %2}"
8783 [(set_attr "type" "alu")
8784 (set_attr "length_immediate" "1")
8785 (set_attr "mode" "QI")])
8787 (define_insn "*iorqi_ext_1"
8788 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8793 (match_operand 1 "ext_register_operand" "0")
8797 (match_operand:QI 2 "general_operand" "Qm"))))
8798 (clobber (reg:CC FLAGS_REG))]
8800 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8801 "or{b}\t{%2, %h0|%h0, %2}"
8802 [(set_attr "type" "alu")
8803 (set_attr "length_immediate" "0")
8804 (set_attr "mode" "QI")])
8806 (define_insn "*iorqi_ext_1_rex64"
8807 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8812 (match_operand 1 "ext_register_operand" "0")
8816 (match_operand 2 "ext_register_operand" "Q"))))
8817 (clobber (reg:CC FLAGS_REG))]
8819 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8820 "or{b}\t{%2, %h0|%h0, %2}"
8821 [(set_attr "type" "alu")
8822 (set_attr "length_immediate" "0")
8823 (set_attr "mode" "QI")])
8825 (define_insn "*iorqi_ext_2"
8826 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8830 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8833 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8836 (clobber (reg:CC FLAGS_REG))]
8837 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8838 "ior{b}\t{%h2, %h0|%h0, %h2}"
8839 [(set_attr "type" "alu")
8840 (set_attr "length_immediate" "0")
8841 (set_attr "mode" "QI")])
8844 [(set (match_operand 0 "register_operand" "")
8845 (ior (match_operand 1 "register_operand" "")
8846 (match_operand 2 "const_int_operand" "")))
8847 (clobber (reg:CC FLAGS_REG))]
8849 && QI_REG_P (operands[0])
8850 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8851 && !(INTVAL (operands[2]) & ~(255 << 8))
8852 && GET_MODE (operands[0]) != QImode"
8853 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8854 (ior:SI (zero_extract:SI (match_dup 1)
8855 (const_int 8) (const_int 8))
8857 (clobber (reg:CC FLAGS_REG))])]
8858 "operands[0] = gen_lowpart (SImode, operands[0]);
8859 operands[1] = gen_lowpart (SImode, operands[1]);
8860 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8862 ;; Since OR can be encoded with sign extended immediate, this is only
8863 ;; profitable when 7th bit is set.
8865 [(set (match_operand 0 "register_operand" "")
8866 (ior (match_operand 1 "general_operand" "")
8867 (match_operand 2 "const_int_operand" "")))
8868 (clobber (reg:CC FLAGS_REG))]
8870 && ANY_QI_REG_P (operands[0])
8871 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8872 && !(INTVAL (operands[2]) & ~255)
8873 && (INTVAL (operands[2]) & 128)
8874 && GET_MODE (operands[0]) != QImode"
8875 [(parallel [(set (strict_low_part (match_dup 0))
8876 (ior:QI (match_dup 1)
8878 (clobber (reg:CC FLAGS_REG))])]
8879 "operands[0] = gen_lowpart (QImode, operands[0]);
8880 operands[1] = gen_lowpart (QImode, operands[1]);
8881 operands[2] = gen_lowpart (QImode, operands[2]);")
8883 ;; Logical XOR instructions
8885 ;; %%% This used to optimize known byte-wide and operations to memory.
8886 ;; If this is considered useful, it should be done with splitters.
8888 (define_expand "xordi3"
8889 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8890 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8891 (match_operand:DI 2 "x86_64_general_operand" "")))
8892 (clobber (reg:CC FLAGS_REG))]
8894 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8896 (define_insn "*xordi_1_rex64"
8897 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8898 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8899 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8900 (clobber (reg:CC FLAGS_REG))]
8902 && ix86_binary_operator_ok (XOR, DImode, operands)"
8904 xor{q}\t{%2, %0|%0, %2}
8905 xor{q}\t{%2, %0|%0, %2}"
8906 [(set_attr "type" "alu")
8907 (set_attr "mode" "DI,DI")])
8909 (define_insn "*xordi_2_rex64"
8910 [(set (reg FLAGS_REG)
8911 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8912 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8914 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8915 (xor:DI (match_dup 1) (match_dup 2)))]
8917 && ix86_match_ccmode (insn, CCNOmode)
8918 && ix86_binary_operator_ok (XOR, DImode, operands)"
8920 xor{q}\t{%2, %0|%0, %2}
8921 xor{q}\t{%2, %0|%0, %2}"
8922 [(set_attr "type" "alu")
8923 (set_attr "mode" "DI,DI")])
8925 (define_insn "*xordi_3_rex64"
8926 [(set (reg FLAGS_REG)
8927 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8928 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8930 (clobber (match_scratch:DI 0 "=r"))]
8932 && ix86_match_ccmode (insn, CCNOmode)
8933 && ix86_binary_operator_ok (XOR, DImode, operands)"
8934 "xor{q}\t{%2, %0|%0, %2}"
8935 [(set_attr "type" "alu")
8936 (set_attr "mode" "DI")])
8938 (define_expand "xorsi3"
8939 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8940 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8941 (match_operand:SI 2 "general_operand" "")))
8942 (clobber (reg:CC FLAGS_REG))]
8944 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8946 (define_insn "*xorsi_1"
8947 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8948 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8949 (match_operand:SI 2 "general_operand" "ri,rm")))
8950 (clobber (reg:CC FLAGS_REG))]
8951 "ix86_binary_operator_ok (XOR, SImode, operands)"
8952 "xor{l}\t{%2, %0|%0, %2}"
8953 [(set_attr "type" "alu")
8954 (set_attr "mode" "SI")])
8956 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8957 ;; Add speccase for immediates
8958 (define_insn "*xorsi_1_zext"
8959 [(set (match_operand:DI 0 "register_operand" "=r")
8961 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8962 (match_operand:SI 2 "general_operand" "rim"))))
8963 (clobber (reg:CC FLAGS_REG))]
8964 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8965 "xor{l}\t{%2, %k0|%k0, %2}"
8966 [(set_attr "type" "alu")
8967 (set_attr "mode" "SI")])
8969 (define_insn "*xorsi_1_zext_imm"
8970 [(set (match_operand:DI 0 "register_operand" "=r")
8971 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8972 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8973 (clobber (reg:CC FLAGS_REG))]
8974 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8975 "xor{l}\t{%2, %k0|%k0, %2}"
8976 [(set_attr "type" "alu")
8977 (set_attr "mode" "SI")])
8979 (define_insn "*xorsi_2"
8980 [(set (reg FLAGS_REG)
8981 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8982 (match_operand:SI 2 "general_operand" "rim,ri"))
8984 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8985 (xor:SI (match_dup 1) (match_dup 2)))]
8986 "ix86_match_ccmode (insn, CCNOmode)
8987 && ix86_binary_operator_ok (XOR, SImode, operands)"
8988 "xor{l}\t{%2, %0|%0, %2}"
8989 [(set_attr "type" "alu")
8990 (set_attr "mode" "SI")])
8992 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8993 ;; ??? Special case for immediate operand is missing - it is tricky.
8994 (define_insn "*xorsi_2_zext"
8995 [(set (reg FLAGS_REG)
8996 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8997 (match_operand:SI 2 "general_operand" "rim"))
8999 (set (match_operand:DI 0 "register_operand" "=r")
9000 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9001 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9002 && ix86_binary_operator_ok (XOR, SImode, operands)"
9003 "xor{l}\t{%2, %k0|%k0, %2}"
9004 [(set_attr "type" "alu")
9005 (set_attr "mode" "SI")])
9007 (define_insn "*xorsi_2_zext_imm"
9008 [(set (reg FLAGS_REG)
9009 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9010 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9012 (set (match_operand:DI 0 "register_operand" "=r")
9013 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9014 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9015 && ix86_binary_operator_ok (XOR, SImode, operands)"
9016 "xor{l}\t{%2, %k0|%k0, %2}"
9017 [(set_attr "type" "alu")
9018 (set_attr "mode" "SI")])
9020 (define_insn "*xorsi_3"
9021 [(set (reg FLAGS_REG)
9022 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9023 (match_operand:SI 2 "general_operand" "rim"))
9025 (clobber (match_scratch:SI 0 "=r"))]
9026 "ix86_match_ccmode (insn, CCNOmode)
9027 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9028 "xor{l}\t{%2, %0|%0, %2}"
9029 [(set_attr "type" "alu")
9030 (set_attr "mode" "SI")])
9032 (define_expand "xorhi3"
9033 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9034 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9035 (match_operand:HI 2 "general_operand" "")))
9036 (clobber (reg:CC FLAGS_REG))]
9037 "TARGET_HIMODE_MATH"
9038 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9040 (define_insn "*xorhi_1"
9041 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9042 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9043 (match_operand:HI 2 "general_operand" "rmi,ri")))
9044 (clobber (reg:CC FLAGS_REG))]
9045 "ix86_binary_operator_ok (XOR, HImode, operands)"
9046 "xor{w}\t{%2, %0|%0, %2}"
9047 [(set_attr "type" "alu")
9048 (set_attr "mode" "HI")])
9050 (define_insn "*xorhi_2"
9051 [(set (reg FLAGS_REG)
9052 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9053 (match_operand:HI 2 "general_operand" "rim,ri"))
9055 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9056 (xor:HI (match_dup 1) (match_dup 2)))]
9057 "ix86_match_ccmode (insn, CCNOmode)
9058 && ix86_binary_operator_ok (XOR, HImode, operands)"
9059 "xor{w}\t{%2, %0|%0, %2}"
9060 [(set_attr "type" "alu")
9061 (set_attr "mode" "HI")])
9063 (define_insn "*xorhi_3"
9064 [(set (reg FLAGS_REG)
9065 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9066 (match_operand:HI 2 "general_operand" "rim"))
9068 (clobber (match_scratch:HI 0 "=r"))]
9069 "ix86_match_ccmode (insn, CCNOmode)
9070 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9071 "xor{w}\t{%2, %0|%0, %2}"
9072 [(set_attr "type" "alu")
9073 (set_attr "mode" "HI")])
9075 (define_expand "xorqi3"
9076 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9077 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9078 (match_operand:QI 2 "general_operand" "")))
9079 (clobber (reg:CC FLAGS_REG))]
9080 "TARGET_QIMODE_MATH"
9081 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9083 ;; %%% Potential partial reg stall on alternative 2. What to do?
9084 (define_insn "*xorqi_1"
9085 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9086 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9087 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9088 (clobber (reg:CC FLAGS_REG))]
9089 "ix86_binary_operator_ok (XOR, QImode, operands)"
9091 xor{b}\t{%2, %0|%0, %2}
9092 xor{b}\t{%2, %0|%0, %2}
9093 xor{l}\t{%k2, %k0|%k0, %k2}"
9094 [(set_attr "type" "alu")
9095 (set_attr "mode" "QI,QI,SI")])
9097 (define_insn "*xorqi_1_slp"
9098 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9099 (xor:QI (match_dup 0)
9100 (match_operand:QI 1 "general_operand" "qi,qmi")))
9101 (clobber (reg:CC FLAGS_REG))]
9102 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9103 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9104 "xor{b}\t{%1, %0|%0, %1}"
9105 [(set_attr "type" "alu1")
9106 (set_attr "mode" "QI")])
9108 (define_insn "xorqi_ext_0"
9109 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9114 (match_operand 1 "ext_register_operand" "0")
9117 (match_operand 2 "const_int_operand" "n")))
9118 (clobber (reg:CC FLAGS_REG))]
9119 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9120 "xor{b}\t{%2, %h0|%h0, %2}"
9121 [(set_attr "type" "alu")
9122 (set_attr "length_immediate" "1")
9123 (set_attr "mode" "QI")])
9125 (define_insn "*xorqi_ext_1"
9126 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9131 (match_operand 1 "ext_register_operand" "0")
9135 (match_operand:QI 2 "general_operand" "Qm"))))
9136 (clobber (reg:CC FLAGS_REG))]
9138 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9139 "xor{b}\t{%2, %h0|%h0, %2}"
9140 [(set_attr "type" "alu")
9141 (set_attr "length_immediate" "0")
9142 (set_attr "mode" "QI")])
9144 (define_insn "*xorqi_ext_1_rex64"
9145 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9150 (match_operand 1 "ext_register_operand" "0")
9154 (match_operand 2 "ext_register_operand" "Q"))))
9155 (clobber (reg:CC FLAGS_REG))]
9157 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9158 "xor{b}\t{%2, %h0|%h0, %2}"
9159 [(set_attr "type" "alu")
9160 (set_attr "length_immediate" "0")
9161 (set_attr "mode" "QI")])
9163 (define_insn "*xorqi_ext_2"
9164 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9168 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9171 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9174 (clobber (reg:CC FLAGS_REG))]
9175 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9176 "xor{b}\t{%h2, %h0|%h0, %h2}"
9177 [(set_attr "type" "alu")
9178 (set_attr "length_immediate" "0")
9179 (set_attr "mode" "QI")])
9181 (define_insn "*xorqi_cc_1"
9182 [(set (reg FLAGS_REG)
9184 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9185 (match_operand:QI 2 "general_operand" "qim,qi"))
9187 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9188 (xor:QI (match_dup 1) (match_dup 2)))]
9189 "ix86_match_ccmode (insn, CCNOmode)
9190 && ix86_binary_operator_ok (XOR, QImode, operands)"
9191 "xor{b}\t{%2, %0|%0, %2}"
9192 [(set_attr "type" "alu")
9193 (set_attr "mode" "QI")])
9195 (define_insn "*xorqi_2_slp"
9196 [(set (reg FLAGS_REG)
9197 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9198 (match_operand:QI 1 "general_operand" "qim,qi"))
9200 (set (strict_low_part (match_dup 0))
9201 (xor:QI (match_dup 0) (match_dup 1)))]
9202 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9203 && ix86_match_ccmode (insn, CCNOmode)
9204 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9205 "xor{b}\t{%1, %0|%0, %1}"
9206 [(set_attr "type" "alu1")
9207 (set_attr "mode" "QI")])
9209 (define_insn "*xorqi_cc_2"
9210 [(set (reg FLAGS_REG)
9212 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9213 (match_operand:QI 2 "general_operand" "qim"))
9215 (clobber (match_scratch:QI 0 "=q"))]
9216 "ix86_match_ccmode (insn, CCNOmode)
9217 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9218 "xor{b}\t{%2, %0|%0, %2}"
9219 [(set_attr "type" "alu")
9220 (set_attr "mode" "QI")])
9222 (define_insn "*xorqi_cc_ext_1"
9223 [(set (reg FLAGS_REG)
9227 (match_operand 1 "ext_register_operand" "0")
9230 (match_operand:QI 2 "general_operand" "qmn"))
9232 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9236 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9238 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9239 "xor{b}\t{%2, %h0|%h0, %2}"
9240 [(set_attr "type" "alu")
9241 (set_attr "mode" "QI")])
9243 (define_insn "*xorqi_cc_ext_1_rex64"
9244 [(set (reg FLAGS_REG)
9248 (match_operand 1 "ext_register_operand" "0")
9251 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9253 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9257 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9259 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9260 "xor{b}\t{%2, %h0|%h0, %2}"
9261 [(set_attr "type" "alu")
9262 (set_attr "mode" "QI")])
9264 (define_expand "xorqi_cc_ext_1"
9266 (set (reg:CCNO FLAGS_REG)
9270 (match_operand 1 "ext_register_operand" "")
9273 (match_operand:QI 2 "general_operand" ""))
9275 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9279 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9285 [(set (match_operand 0 "register_operand" "")
9286 (xor (match_operand 1 "register_operand" "")
9287 (match_operand 2 "const_int_operand" "")))
9288 (clobber (reg:CC FLAGS_REG))]
9290 && QI_REG_P (operands[0])
9291 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9292 && !(INTVAL (operands[2]) & ~(255 << 8))
9293 && GET_MODE (operands[0]) != QImode"
9294 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9295 (xor:SI (zero_extract:SI (match_dup 1)
9296 (const_int 8) (const_int 8))
9298 (clobber (reg:CC FLAGS_REG))])]
9299 "operands[0] = gen_lowpart (SImode, operands[0]);
9300 operands[1] = gen_lowpart (SImode, operands[1]);
9301 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9303 ;; Since XOR can be encoded with sign extended immediate, this is only
9304 ;; profitable when 7th bit is set.
9306 [(set (match_operand 0 "register_operand" "")
9307 (xor (match_operand 1 "general_operand" "")
9308 (match_operand 2 "const_int_operand" "")))
9309 (clobber (reg:CC FLAGS_REG))]
9311 && ANY_QI_REG_P (operands[0])
9312 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9313 && !(INTVAL (operands[2]) & ~255)
9314 && (INTVAL (operands[2]) & 128)
9315 && GET_MODE (operands[0]) != QImode"
9316 [(parallel [(set (strict_low_part (match_dup 0))
9317 (xor:QI (match_dup 1)
9319 (clobber (reg:CC FLAGS_REG))])]
9320 "operands[0] = gen_lowpart (QImode, operands[0]);
9321 operands[1] = gen_lowpart (QImode, operands[1]);
9322 operands[2] = gen_lowpart (QImode, operands[2]);")
9324 ;; Negation instructions
9326 (define_expand "negti2"
9327 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9328 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9329 (clobber (reg:CC FLAGS_REG))])]
9331 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9333 (define_insn "*negti2_1"
9334 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9335 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9336 (clobber (reg:CC FLAGS_REG))]
9338 && ix86_unary_operator_ok (NEG, TImode, operands)"
9342 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9343 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9344 (clobber (reg:CC FLAGS_REG))]
9345 "TARGET_64BIT && reload_completed"
9347 [(set (reg:CCZ FLAGS_REG)
9348 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9349 (set (match_dup 0) (neg:DI (match_dup 2)))])
9352 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9355 (clobber (reg:CC FLAGS_REG))])
9358 (neg:DI (match_dup 1)))
9359 (clobber (reg:CC FLAGS_REG))])]
9360 "split_ti (operands+1, 1, operands+2, operands+3);
9361 split_ti (operands+0, 1, operands+0, operands+1);")
9363 (define_expand "negdi2"
9364 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9365 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9366 (clobber (reg:CC FLAGS_REG))])]
9368 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9370 (define_insn "*negdi2_1"
9371 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9372 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9373 (clobber (reg:CC FLAGS_REG))]
9375 && ix86_unary_operator_ok (NEG, DImode, operands)"
9379 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9380 (neg:DI (match_operand:DI 1 "general_operand" "")))
9381 (clobber (reg:CC FLAGS_REG))]
9382 "!TARGET_64BIT && reload_completed"
9384 [(set (reg:CCZ FLAGS_REG)
9385 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9386 (set (match_dup 0) (neg:SI (match_dup 2)))])
9389 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9392 (clobber (reg:CC FLAGS_REG))])
9395 (neg:SI (match_dup 1)))
9396 (clobber (reg:CC FLAGS_REG))])]
9397 "split_di (operands+1, 1, operands+2, operands+3);
9398 split_di (operands+0, 1, operands+0, operands+1);")
9400 (define_insn "*negdi2_1_rex64"
9401 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9402 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9403 (clobber (reg:CC FLAGS_REG))]
9404 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9406 [(set_attr "type" "negnot")
9407 (set_attr "mode" "DI")])
9409 ;; The problem with neg is that it does not perform (compare x 0),
9410 ;; it really performs (compare 0 x), which leaves us with the zero
9411 ;; flag being the only useful item.
9413 (define_insn "*negdi2_cmpz_rex64"
9414 [(set (reg:CCZ FLAGS_REG)
9415 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9417 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9418 (neg:DI (match_dup 1)))]
9419 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9421 [(set_attr "type" "negnot")
9422 (set_attr "mode" "DI")])
9425 (define_expand "negsi2"
9426 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9427 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9428 (clobber (reg:CC FLAGS_REG))])]
9430 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9432 (define_insn "*negsi2_1"
9433 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9434 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9435 (clobber (reg:CC FLAGS_REG))]
9436 "ix86_unary_operator_ok (NEG, SImode, operands)"
9438 [(set_attr "type" "negnot")
9439 (set_attr "mode" "SI")])
9441 ;; Combine is quite creative about this pattern.
9442 (define_insn "*negsi2_1_zext"
9443 [(set (match_operand:DI 0 "register_operand" "=r")
9444 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9447 (clobber (reg:CC FLAGS_REG))]
9448 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9450 [(set_attr "type" "negnot")
9451 (set_attr "mode" "SI")])
9453 ;; The problem with neg is that it does not perform (compare x 0),
9454 ;; it really performs (compare 0 x), which leaves us with the zero
9455 ;; flag being the only useful item.
9457 (define_insn "*negsi2_cmpz"
9458 [(set (reg:CCZ FLAGS_REG)
9459 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9461 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9462 (neg:SI (match_dup 1)))]
9463 "ix86_unary_operator_ok (NEG, SImode, operands)"
9465 [(set_attr "type" "negnot")
9466 (set_attr "mode" "SI")])
9468 (define_insn "*negsi2_cmpz_zext"
9469 [(set (reg:CCZ FLAGS_REG)
9470 (compare:CCZ (lshiftrt:DI
9472 (match_operand:DI 1 "register_operand" "0")
9476 (set (match_operand:DI 0 "register_operand" "=r")
9477 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9480 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9482 [(set_attr "type" "negnot")
9483 (set_attr "mode" "SI")])
9485 (define_expand "neghi2"
9486 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9487 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9488 (clobber (reg:CC FLAGS_REG))])]
9489 "TARGET_HIMODE_MATH"
9490 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9492 (define_insn "*neghi2_1"
9493 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9494 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9495 (clobber (reg:CC FLAGS_REG))]
9496 "ix86_unary_operator_ok (NEG, HImode, operands)"
9498 [(set_attr "type" "negnot")
9499 (set_attr "mode" "HI")])
9501 (define_insn "*neghi2_cmpz"
9502 [(set (reg:CCZ FLAGS_REG)
9503 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9505 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9506 (neg:HI (match_dup 1)))]
9507 "ix86_unary_operator_ok (NEG, HImode, operands)"
9509 [(set_attr "type" "negnot")
9510 (set_attr "mode" "HI")])
9512 (define_expand "negqi2"
9513 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9514 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9515 (clobber (reg:CC FLAGS_REG))])]
9516 "TARGET_QIMODE_MATH"
9517 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9519 (define_insn "*negqi2_1"
9520 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9521 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9522 (clobber (reg:CC FLAGS_REG))]
9523 "ix86_unary_operator_ok (NEG, QImode, operands)"
9525 [(set_attr "type" "negnot")
9526 (set_attr "mode" "QI")])
9528 (define_insn "*negqi2_cmpz"
9529 [(set (reg:CCZ FLAGS_REG)
9530 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9532 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9533 (neg:QI (match_dup 1)))]
9534 "ix86_unary_operator_ok (NEG, QImode, operands)"
9536 [(set_attr "type" "negnot")
9537 (set_attr "mode" "QI")])
9539 ;; Changing of sign for FP values is doable using integer unit too.
9541 (define_expand "negsf2"
9542 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9543 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9544 "TARGET_80387 || TARGET_SSE_MATH"
9545 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9547 (define_expand "abssf2"
9548 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9549 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9550 "TARGET_80387 || TARGET_SSE_MATH"
9551 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9553 (define_insn "*absnegsf2_mixed"
9554 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9555 (match_operator:SF 3 "absneg_operator"
9556 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9557 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9558 (clobber (reg:CC FLAGS_REG))]
9559 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9560 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9563 (define_insn "*absnegsf2_sse"
9564 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9565 (match_operator:SF 3 "absneg_operator"
9566 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9567 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9568 (clobber (reg:CC FLAGS_REG))]
9570 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9573 (define_insn "*absnegsf2_i387"
9574 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9575 (match_operator:SF 3 "absneg_operator"
9576 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9577 (use (match_operand 2 "" ""))
9578 (clobber (reg:CC FLAGS_REG))]
9579 "TARGET_80387 && !TARGET_SSE_MATH
9580 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9583 (define_expand "copysignsf3"
9584 [(match_operand:SF 0 "register_operand" "")
9585 (match_operand:SF 1 "nonmemory_operand" "")
9586 (match_operand:SF 2 "register_operand" "")]
9589 ix86_expand_copysign (operands);
9593 (define_insn_and_split "copysignsf3_const"
9594 [(set (match_operand:SF 0 "register_operand" "=x")
9596 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9597 (match_operand:SF 2 "register_operand" "0")
9598 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9602 "&& reload_completed"
9605 ix86_split_copysign_const (operands);
9609 (define_insn "copysignsf3_var"
9610 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9612 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9613 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9614 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9615 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9617 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9622 [(set (match_operand:SF 0 "register_operand" "")
9624 [(match_operand:SF 2 "register_operand" "")
9625 (match_operand:SF 3 "register_operand" "")
9626 (match_operand:V4SF 4 "" "")
9627 (match_operand:V4SF 5 "" "")]
9629 (clobber (match_scratch:V4SF 1 ""))]
9630 "TARGET_SSE_MATH && reload_completed"
9633 ix86_split_copysign_var (operands);
9637 (define_expand "negdf2"
9638 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9639 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9640 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9641 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9643 (define_expand "absdf2"
9644 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9645 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9646 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9647 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9649 (define_insn "*absnegdf2_mixed"
9650 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9651 (match_operator:DF 3 "absneg_operator"
9652 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9653 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9654 (clobber (reg:CC FLAGS_REG))]
9655 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9656 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9659 (define_insn "*absnegdf2_sse"
9660 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9661 (match_operator:DF 3 "absneg_operator"
9662 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9663 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9664 (clobber (reg:CC FLAGS_REG))]
9665 "TARGET_SSE2 && TARGET_SSE_MATH
9666 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9669 (define_insn "*absnegdf2_i387"
9670 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9671 (match_operator:DF 3 "absneg_operator"
9672 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9673 (use (match_operand 2 "" ""))
9674 (clobber (reg:CC FLAGS_REG))]
9675 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9676 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9679 (define_expand "copysigndf3"
9680 [(match_operand:DF 0 "register_operand" "")
9681 (match_operand:DF 1 "nonmemory_operand" "")
9682 (match_operand:DF 2 "register_operand" "")]
9683 "TARGET_SSE2 && TARGET_SSE_MATH"
9685 ix86_expand_copysign (operands);
9689 (define_insn_and_split "copysigndf3_const"
9690 [(set (match_operand:DF 0 "register_operand" "=x")
9692 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9693 (match_operand:DF 2 "register_operand" "0")
9694 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9696 "TARGET_SSE2 && TARGET_SSE_MATH"
9698 "&& reload_completed"
9701 ix86_split_copysign_const (operands);
9705 (define_insn "copysigndf3_var"
9706 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9708 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9709 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9710 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9711 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9713 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9714 "TARGET_SSE2 && TARGET_SSE_MATH"
9718 [(set (match_operand:DF 0 "register_operand" "")
9720 [(match_operand:DF 2 "register_operand" "")
9721 (match_operand:DF 3 "register_operand" "")
9722 (match_operand:V2DF 4 "" "")
9723 (match_operand:V2DF 5 "" "")]
9725 (clobber (match_scratch:V2DF 1 ""))]
9726 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9729 ix86_split_copysign_var (operands);
9733 (define_expand "negxf2"
9734 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9735 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9737 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9739 (define_expand "absxf2"
9740 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9741 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9743 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9745 (define_insn "*absnegxf2_i387"
9746 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9747 (match_operator:XF 3 "absneg_operator"
9748 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9749 (use (match_operand 2 "" ""))
9750 (clobber (reg:CC FLAGS_REG))]
9752 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9755 ;; Splitters for fp abs and neg.
9758 [(set (match_operand 0 "fp_register_operand" "")
9759 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9760 (use (match_operand 2 "" ""))
9761 (clobber (reg:CC FLAGS_REG))]
9763 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9766 [(set (match_operand 0 "register_operand" "")
9767 (match_operator 3 "absneg_operator"
9768 [(match_operand 1 "register_operand" "")]))
9769 (use (match_operand 2 "nonimmediate_operand" ""))
9770 (clobber (reg:CC FLAGS_REG))]
9771 "reload_completed && SSE_REG_P (operands[0])"
9772 [(set (match_dup 0) (match_dup 3))]
9774 enum machine_mode mode = GET_MODE (operands[0]);
9775 enum machine_mode vmode = GET_MODE (operands[2]);
9778 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9779 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9780 if (operands_match_p (operands[0], operands[2]))
9783 operands[1] = operands[2];
9786 if (GET_CODE (operands[3]) == ABS)
9787 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9789 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9794 [(set (match_operand:SF 0 "register_operand" "")
9795 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9796 (use (match_operand:V4SF 2 "" ""))
9797 (clobber (reg:CC FLAGS_REG))]
9799 [(parallel [(set (match_dup 0) (match_dup 1))
9800 (clobber (reg:CC FLAGS_REG))])]
9803 operands[0] = gen_lowpart (SImode, operands[0]);
9804 if (GET_CODE (operands[1]) == ABS)
9806 tmp = gen_int_mode (0x7fffffff, SImode);
9807 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9811 tmp = gen_int_mode (0x80000000, SImode);
9812 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9818 [(set (match_operand:DF 0 "register_operand" "")
9819 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9820 (use (match_operand 2 "" ""))
9821 (clobber (reg:CC FLAGS_REG))]
9823 [(parallel [(set (match_dup 0) (match_dup 1))
9824 (clobber (reg:CC FLAGS_REG))])]
9829 tmp = gen_lowpart (DImode, operands[0]);
9830 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9833 if (GET_CODE (operands[1]) == ABS)
9836 tmp = gen_rtx_NOT (DImode, tmp);
9840 operands[0] = gen_highpart (SImode, operands[0]);
9841 if (GET_CODE (operands[1]) == ABS)
9843 tmp = gen_int_mode (0x7fffffff, SImode);
9844 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9848 tmp = gen_int_mode (0x80000000, SImode);
9849 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9856 [(set (match_operand:XF 0 "register_operand" "")
9857 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9858 (use (match_operand 2 "" ""))
9859 (clobber (reg:CC FLAGS_REG))]
9861 [(parallel [(set (match_dup 0) (match_dup 1))
9862 (clobber (reg:CC FLAGS_REG))])]
9865 operands[0] = gen_rtx_REG (SImode,
9866 true_regnum (operands[0])
9867 + (TARGET_64BIT ? 1 : 2));
9868 if (GET_CODE (operands[1]) == ABS)
9870 tmp = GEN_INT (0x7fff);
9871 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9875 tmp = GEN_INT (0x8000);
9876 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9882 [(set (match_operand 0 "memory_operand" "")
9883 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9884 (use (match_operand 2 "" ""))
9885 (clobber (reg:CC FLAGS_REG))]
9887 [(parallel [(set (match_dup 0) (match_dup 1))
9888 (clobber (reg:CC FLAGS_REG))])]
9890 enum machine_mode mode = GET_MODE (operands[0]);
9891 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9894 operands[0] = adjust_address (operands[0], QImode, size - 1);
9895 if (GET_CODE (operands[1]) == ABS)
9897 tmp = gen_int_mode (0x7f, QImode);
9898 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9902 tmp = gen_int_mode (0x80, QImode);
9903 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9908 ;; Conditionalize these after reload. If they match before reload, we
9909 ;; lose the clobber and ability to use integer instructions.
9911 (define_insn "*negsf2_1"
9912 [(set (match_operand:SF 0 "register_operand" "=f")
9913 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9914 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9916 [(set_attr "type" "fsgn")
9917 (set_attr "mode" "SF")])
9919 (define_insn "*negdf2_1"
9920 [(set (match_operand:DF 0 "register_operand" "=f")
9921 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9922 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9924 [(set_attr "type" "fsgn")
9925 (set_attr "mode" "DF")])
9927 (define_insn "*negxf2_1"
9928 [(set (match_operand:XF 0 "register_operand" "=f")
9929 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9932 [(set_attr "type" "fsgn")
9933 (set_attr "mode" "XF")])
9935 (define_insn "*abssf2_1"
9936 [(set (match_operand:SF 0 "register_operand" "=f")
9937 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9938 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9940 [(set_attr "type" "fsgn")
9941 (set_attr "mode" "SF")])
9943 (define_insn "*absdf2_1"
9944 [(set (match_operand:DF 0 "register_operand" "=f")
9945 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9946 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9948 [(set_attr "type" "fsgn")
9949 (set_attr "mode" "DF")])
9951 (define_insn "*absxf2_1"
9952 [(set (match_operand:XF 0 "register_operand" "=f")
9953 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9956 [(set_attr "type" "fsgn")
9957 (set_attr "mode" "DF")])
9959 (define_insn "*negextendsfdf2"
9960 [(set (match_operand:DF 0 "register_operand" "=f")
9961 (neg:DF (float_extend:DF
9962 (match_operand:SF 1 "register_operand" "0"))))]
9963 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9965 [(set_attr "type" "fsgn")
9966 (set_attr "mode" "DF")])
9968 (define_insn "*negextenddfxf2"
9969 [(set (match_operand:XF 0 "register_operand" "=f")
9970 (neg:XF (float_extend:XF
9971 (match_operand:DF 1 "register_operand" "0"))))]
9974 [(set_attr "type" "fsgn")
9975 (set_attr "mode" "XF")])
9977 (define_insn "*negextendsfxf2"
9978 [(set (match_operand:XF 0 "register_operand" "=f")
9979 (neg:XF (float_extend:XF
9980 (match_operand:SF 1 "register_operand" "0"))))]
9983 [(set_attr "type" "fsgn")
9984 (set_attr "mode" "XF")])
9986 (define_insn "*absextendsfdf2"
9987 [(set (match_operand:DF 0 "register_operand" "=f")
9988 (abs:DF (float_extend:DF
9989 (match_operand:SF 1 "register_operand" "0"))))]
9990 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9992 [(set_attr "type" "fsgn")
9993 (set_attr "mode" "DF")])
9995 (define_insn "*absextenddfxf2"
9996 [(set (match_operand:XF 0 "register_operand" "=f")
9997 (abs:XF (float_extend:XF
9998 (match_operand:DF 1 "register_operand" "0"))))]
10001 [(set_attr "type" "fsgn")
10002 (set_attr "mode" "XF")])
10004 (define_insn "*absextendsfxf2"
10005 [(set (match_operand:XF 0 "register_operand" "=f")
10006 (abs:XF (float_extend:XF
10007 (match_operand:SF 1 "register_operand" "0"))))]
10010 [(set_attr "type" "fsgn")
10011 (set_attr "mode" "XF")])
10013 ;; One complement instructions
10015 (define_expand "one_cmpldi2"
10016 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10017 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10019 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10021 (define_insn "*one_cmpldi2_1_rex64"
10022 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10023 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10024 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10026 [(set_attr "type" "negnot")
10027 (set_attr "mode" "DI")])
10029 (define_insn "*one_cmpldi2_2_rex64"
10030 [(set (reg FLAGS_REG)
10031 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10033 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10034 (not:DI (match_dup 1)))]
10035 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10036 && ix86_unary_operator_ok (NOT, DImode, operands)"
10038 [(set_attr "type" "alu1")
10039 (set_attr "mode" "DI")])
10042 [(set (match_operand 0 "flags_reg_operand" "")
10043 (match_operator 2 "compare_operator"
10044 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10046 (set (match_operand:DI 1 "nonimmediate_operand" "")
10047 (not:DI (match_dup 3)))]
10048 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10049 [(parallel [(set (match_dup 0)
10051 [(xor:DI (match_dup 3) (const_int -1))
10054 (xor:DI (match_dup 3) (const_int -1)))])]
10057 (define_expand "one_cmplsi2"
10058 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10059 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10061 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10063 (define_insn "*one_cmplsi2_1"
10064 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10065 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10066 "ix86_unary_operator_ok (NOT, SImode, operands)"
10068 [(set_attr "type" "negnot")
10069 (set_attr "mode" "SI")])
10071 ;; ??? Currently never generated - xor is used instead.
10072 (define_insn "*one_cmplsi2_1_zext"
10073 [(set (match_operand:DI 0 "register_operand" "=r")
10074 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10075 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10077 [(set_attr "type" "negnot")
10078 (set_attr "mode" "SI")])
10080 (define_insn "*one_cmplsi2_2"
10081 [(set (reg FLAGS_REG)
10082 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10084 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10085 (not:SI (match_dup 1)))]
10086 "ix86_match_ccmode (insn, CCNOmode)
10087 && ix86_unary_operator_ok (NOT, SImode, operands)"
10089 [(set_attr "type" "alu1")
10090 (set_attr "mode" "SI")])
10093 [(set (match_operand 0 "flags_reg_operand" "")
10094 (match_operator 2 "compare_operator"
10095 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10097 (set (match_operand:SI 1 "nonimmediate_operand" "")
10098 (not:SI (match_dup 3)))]
10099 "ix86_match_ccmode (insn, CCNOmode)"
10100 [(parallel [(set (match_dup 0)
10101 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10104 (xor:SI (match_dup 3) (const_int -1)))])]
10107 ;; ??? Currently never generated - xor is used instead.
10108 (define_insn "*one_cmplsi2_2_zext"
10109 [(set (reg FLAGS_REG)
10110 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10112 (set (match_operand:DI 0 "register_operand" "=r")
10113 (zero_extend:DI (not:SI (match_dup 1))))]
10114 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10115 && ix86_unary_operator_ok (NOT, SImode, operands)"
10117 [(set_attr "type" "alu1")
10118 (set_attr "mode" "SI")])
10121 [(set (match_operand 0 "flags_reg_operand" "")
10122 (match_operator 2 "compare_operator"
10123 [(not:SI (match_operand:SI 3 "register_operand" ""))
10125 (set (match_operand:DI 1 "register_operand" "")
10126 (zero_extend:DI (not:SI (match_dup 3))))]
10127 "ix86_match_ccmode (insn, CCNOmode)"
10128 [(parallel [(set (match_dup 0)
10129 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10132 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10135 (define_expand "one_cmplhi2"
10136 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10137 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10138 "TARGET_HIMODE_MATH"
10139 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10141 (define_insn "*one_cmplhi2_1"
10142 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10143 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10144 "ix86_unary_operator_ok (NOT, HImode, operands)"
10146 [(set_attr "type" "negnot")
10147 (set_attr "mode" "HI")])
10149 (define_insn "*one_cmplhi2_2"
10150 [(set (reg FLAGS_REG)
10151 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10153 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10154 (not:HI (match_dup 1)))]
10155 "ix86_match_ccmode (insn, CCNOmode)
10156 && ix86_unary_operator_ok (NEG, HImode, operands)"
10158 [(set_attr "type" "alu1")
10159 (set_attr "mode" "HI")])
10162 [(set (match_operand 0 "flags_reg_operand" "")
10163 (match_operator 2 "compare_operator"
10164 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10166 (set (match_operand:HI 1 "nonimmediate_operand" "")
10167 (not:HI (match_dup 3)))]
10168 "ix86_match_ccmode (insn, CCNOmode)"
10169 [(parallel [(set (match_dup 0)
10170 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10173 (xor:HI (match_dup 3) (const_int -1)))])]
10176 ;; %%% Potential partial reg stall on alternative 1. What to do?
10177 (define_expand "one_cmplqi2"
10178 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10179 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10180 "TARGET_QIMODE_MATH"
10181 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10183 (define_insn "*one_cmplqi2_1"
10184 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10185 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10186 "ix86_unary_operator_ok (NOT, QImode, operands)"
10190 [(set_attr "type" "negnot")
10191 (set_attr "mode" "QI,SI")])
10193 (define_insn "*one_cmplqi2_2"
10194 [(set (reg FLAGS_REG)
10195 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10197 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10198 (not:QI (match_dup 1)))]
10199 "ix86_match_ccmode (insn, CCNOmode)
10200 && ix86_unary_operator_ok (NOT, QImode, operands)"
10202 [(set_attr "type" "alu1")
10203 (set_attr "mode" "QI")])
10206 [(set (match_operand 0 "flags_reg_operand" "")
10207 (match_operator 2 "compare_operator"
10208 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10210 (set (match_operand:QI 1 "nonimmediate_operand" "")
10211 (not:QI (match_dup 3)))]
10212 "ix86_match_ccmode (insn, CCNOmode)"
10213 [(parallel [(set (match_dup 0)
10214 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10217 (xor:QI (match_dup 3) (const_int -1)))])]
10220 ;; Arithmetic shift instructions
10222 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10223 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10224 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10225 ;; from the assembler input.
10227 ;; This instruction shifts the target reg/mem as usual, but instead of
10228 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10229 ;; is a left shift double, bits are taken from the high order bits of
10230 ;; reg, else if the insn is a shift right double, bits are taken from the
10231 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10232 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10234 ;; Since sh[lr]d does not change the `reg' operand, that is done
10235 ;; separately, making all shifts emit pairs of shift double and normal
10236 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10237 ;; support a 63 bit shift, each shift where the count is in a reg expands
10238 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10240 ;; If the shift count is a constant, we need never emit more than one
10241 ;; shift pair, instead using moves and sign extension for counts greater
10244 (define_expand "ashlti3"
10245 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10246 (ashift:TI (match_operand:TI 1 "register_operand" "")
10247 (match_operand:QI 2 "nonmemory_operand" "")))
10248 (clobber (reg:CC FLAGS_REG))])]
10251 if (! immediate_operand (operands[2], QImode))
10253 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10256 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10260 (define_insn "ashlti3_1"
10261 [(set (match_operand:TI 0 "register_operand" "=r")
10262 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10263 (match_operand:QI 2 "register_operand" "c")))
10264 (clobber (match_scratch:DI 3 "=&r"))
10265 (clobber (reg:CC FLAGS_REG))]
10268 [(set_attr "type" "multi")])
10270 (define_insn "*ashlti3_2"
10271 [(set (match_operand:TI 0 "register_operand" "=r")
10272 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10273 (match_operand:QI 2 "immediate_operand" "O")))
10274 (clobber (reg:CC FLAGS_REG))]
10277 [(set_attr "type" "multi")])
10280 [(set (match_operand:TI 0 "register_operand" "")
10281 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10282 (match_operand:QI 2 "register_operand" "")))
10283 (clobber (match_scratch:DI 3 ""))
10284 (clobber (reg:CC FLAGS_REG))]
10285 "TARGET_64BIT && reload_completed"
10287 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10290 [(set (match_operand:TI 0 "register_operand" "")
10291 (ashift:TI (match_operand:TI 1 "register_operand" "")
10292 (match_operand:QI 2 "immediate_operand" "")))
10293 (clobber (reg:CC FLAGS_REG))]
10294 "TARGET_64BIT && reload_completed"
10296 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10298 (define_insn "x86_64_shld"
10299 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10300 (ior:DI (ashift:DI (match_dup 0)
10301 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10302 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10303 (minus:QI (const_int 64) (match_dup 2)))))
10304 (clobber (reg:CC FLAGS_REG))]
10307 shld{q}\t{%2, %1, %0|%0, %1, %2}
10308 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10309 [(set_attr "type" "ishift")
10310 (set_attr "prefix_0f" "1")
10311 (set_attr "mode" "DI")
10312 (set_attr "athlon_decode" "vector")])
10314 (define_expand "x86_64_shift_adj"
10315 [(set (reg:CCZ FLAGS_REG)
10316 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10319 (set (match_operand:DI 0 "register_operand" "")
10320 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10321 (match_operand:DI 1 "register_operand" "")
10324 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10325 (match_operand:DI 3 "register_operand" "r")
10330 (define_expand "ashldi3"
10331 [(set (match_operand:DI 0 "shiftdi_operand" "")
10332 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10333 (match_operand:QI 2 "nonmemory_operand" "")))]
10335 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10337 (define_insn "*ashldi3_1_rex64"
10338 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10339 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10340 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10341 (clobber (reg:CC FLAGS_REG))]
10342 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10344 switch (get_attr_type (insn))
10347 gcc_assert (operands[2] == const1_rtx);
10348 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10349 return "add{q}\t{%0, %0|%0, %0}";
10352 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10353 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10354 operands[1] = gen_rtx_MULT (DImode, operands[1],
10355 GEN_INT (1 << INTVAL (operands[2])));
10356 return "lea{q}\t{%a1, %0|%0, %a1}";
10359 if (REG_P (operands[2]))
10360 return "sal{q}\t{%b2, %0|%0, %b2}";
10361 else if (operands[2] == const1_rtx
10362 && (TARGET_SHIFT1 || optimize_size))
10363 return "sal{q}\t%0";
10365 return "sal{q}\t{%2, %0|%0, %2}";
10368 [(set (attr "type")
10369 (cond [(eq_attr "alternative" "1")
10370 (const_string "lea")
10371 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10373 (match_operand 0 "register_operand" ""))
10374 (match_operand 2 "const1_operand" ""))
10375 (const_string "alu")
10377 (const_string "ishift")))
10378 (set_attr "mode" "DI")])
10380 ;; Convert lea to the lea pattern to avoid flags dependency.
10382 [(set (match_operand:DI 0 "register_operand" "")
10383 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10384 (match_operand:QI 2 "immediate_operand" "")))
10385 (clobber (reg:CC FLAGS_REG))]
10386 "TARGET_64BIT && reload_completed
10387 && true_regnum (operands[0]) != true_regnum (operands[1])"
10388 [(set (match_dup 0)
10389 (mult:DI (match_dup 1)
10391 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10393 ;; This pattern can't accept a variable shift count, since shifts by
10394 ;; zero don't affect the flags. We assume that shifts by constant
10395 ;; zero are optimized away.
10396 (define_insn "*ashldi3_cmp_rex64"
10397 [(set (reg FLAGS_REG)
10399 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10400 (match_operand:QI 2 "immediate_operand" "e"))
10402 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10403 (ashift:DI (match_dup 1) (match_dup 2)))]
10404 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10405 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10407 || !TARGET_PARTIAL_FLAG_REG_STALL
10408 || (operands[2] == const1_rtx
10410 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10412 switch (get_attr_type (insn))
10415 gcc_assert (operands[2] == const1_rtx);
10416 return "add{q}\t{%0, %0|%0, %0}";
10419 if (REG_P (operands[2]))
10420 return "sal{q}\t{%b2, %0|%0, %b2}";
10421 else if (operands[2] == const1_rtx
10422 && (TARGET_SHIFT1 || optimize_size))
10423 return "sal{q}\t%0";
10425 return "sal{q}\t{%2, %0|%0, %2}";
10428 [(set (attr "type")
10429 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10431 (match_operand 0 "register_operand" ""))
10432 (match_operand 2 "const1_operand" ""))
10433 (const_string "alu")
10435 (const_string "ishift")))
10436 (set_attr "mode" "DI")])
10438 (define_insn "*ashldi3_cconly_rex64"
10439 [(set (reg FLAGS_REG)
10441 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10442 (match_operand:QI 2 "immediate_operand" "e"))
10444 (clobber (match_scratch:DI 0 "=r"))]
10445 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10446 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10448 || !TARGET_PARTIAL_FLAG_REG_STALL
10449 || (operands[2] == const1_rtx
10451 || TARGET_DOUBLE_WITH_ADD)))"
10453 switch (get_attr_type (insn))
10456 gcc_assert (operands[2] == const1_rtx);
10457 return "add{q}\t{%0, %0|%0, %0}";
10460 if (REG_P (operands[2]))
10461 return "sal{q}\t{%b2, %0|%0, %b2}";
10462 else if (operands[2] == const1_rtx
10463 && (TARGET_SHIFT1 || optimize_size))
10464 return "sal{q}\t%0";
10466 return "sal{q}\t{%2, %0|%0, %2}";
10469 [(set (attr "type")
10470 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10472 (match_operand 0 "register_operand" ""))
10473 (match_operand 2 "const1_operand" ""))
10474 (const_string "alu")
10476 (const_string "ishift")))
10477 (set_attr "mode" "DI")])
10479 (define_insn "*ashldi3_1"
10480 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10481 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10482 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10483 (clobber (reg:CC FLAGS_REG))]
10486 [(set_attr "type" "multi")])
10488 ;; By default we don't ask for a scratch register, because when DImode
10489 ;; values are manipulated, registers are already at a premium. But if
10490 ;; we have one handy, we won't turn it away.
10492 [(match_scratch:SI 3 "r")
10493 (parallel [(set (match_operand:DI 0 "register_operand" "")
10494 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10495 (match_operand:QI 2 "nonmemory_operand" "")))
10496 (clobber (reg:CC FLAGS_REG))])
10498 "!TARGET_64BIT && TARGET_CMOVE"
10500 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10503 [(set (match_operand:DI 0 "register_operand" "")
10504 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10505 (match_operand:QI 2 "nonmemory_operand" "")))
10506 (clobber (reg:CC FLAGS_REG))]
10507 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10508 ? flow2_completed : reload_completed)"
10510 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10512 (define_insn "x86_shld_1"
10513 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10514 (ior:SI (ashift:SI (match_dup 0)
10515 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10516 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10517 (minus:QI (const_int 32) (match_dup 2)))))
10518 (clobber (reg:CC FLAGS_REG))]
10521 shld{l}\t{%2, %1, %0|%0, %1, %2}
10522 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10523 [(set_attr "type" "ishift")
10524 (set_attr "prefix_0f" "1")
10525 (set_attr "mode" "SI")
10526 (set_attr "pent_pair" "np")
10527 (set_attr "athlon_decode" "vector")])
10529 (define_expand "x86_shift_adj_1"
10530 [(set (reg:CCZ FLAGS_REG)
10531 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10534 (set (match_operand:SI 0 "register_operand" "")
10535 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10536 (match_operand:SI 1 "register_operand" "")
10539 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10540 (match_operand:SI 3 "register_operand" "r")
10545 (define_expand "x86_shift_adj_2"
10546 [(use (match_operand:SI 0 "register_operand" ""))
10547 (use (match_operand:SI 1 "register_operand" ""))
10548 (use (match_operand:QI 2 "register_operand" ""))]
10551 rtx label = gen_label_rtx ();
10554 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10556 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10557 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10558 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10559 gen_rtx_LABEL_REF (VOIDmode, label),
10561 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10562 JUMP_LABEL (tmp) = label;
10564 emit_move_insn (operands[0], operands[1]);
10565 ix86_expand_clear (operands[1]);
10567 emit_label (label);
10568 LABEL_NUSES (label) = 1;
10573 (define_expand "ashlsi3"
10574 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10575 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10576 (match_operand:QI 2 "nonmemory_operand" "")))
10577 (clobber (reg:CC FLAGS_REG))]
10579 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10581 (define_insn "*ashlsi3_1"
10582 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10583 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10584 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10585 (clobber (reg:CC FLAGS_REG))]
10586 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10588 switch (get_attr_type (insn))
10591 gcc_assert (operands[2] == const1_rtx);
10592 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10593 return "add{l}\t{%0, %0|%0, %0}";
10599 if (REG_P (operands[2]))
10600 return "sal{l}\t{%b2, %0|%0, %b2}";
10601 else if (operands[2] == const1_rtx
10602 && (TARGET_SHIFT1 || optimize_size))
10603 return "sal{l}\t%0";
10605 return "sal{l}\t{%2, %0|%0, %2}";
10608 [(set (attr "type")
10609 (cond [(eq_attr "alternative" "1")
10610 (const_string "lea")
10611 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10613 (match_operand 0 "register_operand" ""))
10614 (match_operand 2 "const1_operand" ""))
10615 (const_string "alu")
10617 (const_string "ishift")))
10618 (set_attr "mode" "SI")])
10620 ;; Convert lea to the lea pattern to avoid flags dependency.
10622 [(set (match_operand 0 "register_operand" "")
10623 (ashift (match_operand 1 "index_register_operand" "")
10624 (match_operand:QI 2 "const_int_operand" "")))
10625 (clobber (reg:CC FLAGS_REG))]
10627 && true_regnum (operands[0]) != true_regnum (operands[1])
10628 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10632 enum machine_mode mode = GET_MODE (operands[0]);
10634 if (GET_MODE_SIZE (mode) < 4)
10635 operands[0] = gen_lowpart (SImode, operands[0]);
10637 operands[1] = gen_lowpart (Pmode, operands[1]);
10638 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10640 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10641 if (Pmode != SImode)
10642 pat = gen_rtx_SUBREG (SImode, pat, 0);
10643 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10647 ;; Rare case of shifting RSP is handled by generating move and shift
10649 [(set (match_operand 0 "register_operand" "")
10650 (ashift (match_operand 1 "register_operand" "")
10651 (match_operand:QI 2 "const_int_operand" "")))
10652 (clobber (reg:CC FLAGS_REG))]
10654 && true_regnum (operands[0]) != true_regnum (operands[1])"
10658 emit_move_insn (operands[0], operands[1]);
10659 pat = gen_rtx_SET (VOIDmode, operands[0],
10660 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10661 operands[0], operands[2]));
10662 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10663 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10667 (define_insn "*ashlsi3_1_zext"
10668 [(set (match_operand:DI 0 "register_operand" "=r,r")
10669 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10670 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10671 (clobber (reg:CC FLAGS_REG))]
10672 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10674 switch (get_attr_type (insn))
10677 gcc_assert (operands[2] == const1_rtx);
10678 return "add{l}\t{%k0, %k0|%k0, %k0}";
10684 if (REG_P (operands[2]))
10685 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10686 else if (operands[2] == const1_rtx
10687 && (TARGET_SHIFT1 || optimize_size))
10688 return "sal{l}\t%k0";
10690 return "sal{l}\t{%2, %k0|%k0, %2}";
10693 [(set (attr "type")
10694 (cond [(eq_attr "alternative" "1")
10695 (const_string "lea")
10696 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10698 (match_operand 2 "const1_operand" ""))
10699 (const_string "alu")
10701 (const_string "ishift")))
10702 (set_attr "mode" "SI")])
10704 ;; Convert lea to the lea pattern to avoid flags dependency.
10706 [(set (match_operand:DI 0 "register_operand" "")
10707 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10708 (match_operand:QI 2 "const_int_operand" ""))))
10709 (clobber (reg:CC FLAGS_REG))]
10710 "TARGET_64BIT && reload_completed
10711 && true_regnum (operands[0]) != true_regnum (operands[1])"
10712 [(set (match_dup 0) (zero_extend:DI
10713 (subreg:SI (mult:SI (match_dup 1)
10714 (match_dup 2)) 0)))]
10716 operands[1] = gen_lowpart (Pmode, operands[1]);
10717 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10720 ;; This pattern can't accept a variable shift count, since shifts by
10721 ;; zero don't affect the flags. We assume that shifts by constant
10722 ;; zero are optimized away.
10723 (define_insn "*ashlsi3_cmp"
10724 [(set (reg FLAGS_REG)
10726 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10727 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10729 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10730 (ashift:SI (match_dup 1) (match_dup 2)))]
10731 "ix86_match_ccmode (insn, CCGOCmode)
10732 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10734 || !TARGET_PARTIAL_FLAG_REG_STALL
10735 || (operands[2] == const1_rtx
10737 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10739 switch (get_attr_type (insn))
10742 gcc_assert (operands[2] == const1_rtx);
10743 return "add{l}\t{%0, %0|%0, %0}";
10746 if (REG_P (operands[2]))
10747 return "sal{l}\t{%b2, %0|%0, %b2}";
10748 else if (operands[2] == const1_rtx
10749 && (TARGET_SHIFT1 || optimize_size))
10750 return "sal{l}\t%0";
10752 return "sal{l}\t{%2, %0|%0, %2}";
10755 [(set (attr "type")
10756 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10758 (match_operand 0 "register_operand" ""))
10759 (match_operand 2 "const1_operand" ""))
10760 (const_string "alu")
10762 (const_string "ishift")))
10763 (set_attr "mode" "SI")])
10765 (define_insn "*ashlsi3_cconly"
10766 [(set (reg FLAGS_REG)
10768 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10769 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10771 (clobber (match_scratch:SI 0 "=r"))]
10772 "ix86_match_ccmode (insn, CCGOCmode)
10773 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10775 || !TARGET_PARTIAL_FLAG_REG_STALL
10776 || (operands[2] == const1_rtx
10778 || TARGET_DOUBLE_WITH_ADD)))"
10780 switch (get_attr_type (insn))
10783 gcc_assert (operands[2] == const1_rtx);
10784 return "add{l}\t{%0, %0|%0, %0}";
10787 if (REG_P (operands[2]))
10788 return "sal{l}\t{%b2, %0|%0, %b2}";
10789 else if (operands[2] == const1_rtx
10790 && (TARGET_SHIFT1 || optimize_size))
10791 return "sal{l}\t%0";
10793 return "sal{l}\t{%2, %0|%0, %2}";
10796 [(set (attr "type")
10797 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10799 (match_operand 0 "register_operand" ""))
10800 (match_operand 2 "const1_operand" ""))
10801 (const_string "alu")
10803 (const_string "ishift")))
10804 (set_attr "mode" "SI")])
10806 (define_insn "*ashlsi3_cmp_zext"
10807 [(set (reg FLAGS_REG)
10809 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10810 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10812 (set (match_operand:DI 0 "register_operand" "=r")
10813 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10814 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10815 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10817 || !TARGET_PARTIAL_FLAG_REG_STALL
10818 || (operands[2] == const1_rtx
10820 || TARGET_DOUBLE_WITH_ADD)))"
10822 switch (get_attr_type (insn))
10825 gcc_assert (operands[2] == const1_rtx);
10826 return "add{l}\t{%k0, %k0|%k0, %k0}";
10829 if (REG_P (operands[2]))
10830 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10831 else if (operands[2] == const1_rtx
10832 && (TARGET_SHIFT1 || optimize_size))
10833 return "sal{l}\t%k0";
10835 return "sal{l}\t{%2, %k0|%k0, %2}";
10838 [(set (attr "type")
10839 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10841 (match_operand 2 "const1_operand" ""))
10842 (const_string "alu")
10844 (const_string "ishift")))
10845 (set_attr "mode" "SI")])
10847 (define_expand "ashlhi3"
10848 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10849 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10850 (match_operand:QI 2 "nonmemory_operand" "")))
10851 (clobber (reg:CC FLAGS_REG))]
10852 "TARGET_HIMODE_MATH"
10853 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10855 (define_insn "*ashlhi3_1_lea"
10856 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10857 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10858 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10859 (clobber (reg:CC FLAGS_REG))]
10860 "!TARGET_PARTIAL_REG_STALL
10861 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10863 switch (get_attr_type (insn))
10868 gcc_assert (operands[2] == const1_rtx);
10869 return "add{w}\t{%0, %0|%0, %0}";
10872 if (REG_P (operands[2]))
10873 return "sal{w}\t{%b2, %0|%0, %b2}";
10874 else if (operands[2] == const1_rtx
10875 && (TARGET_SHIFT1 || optimize_size))
10876 return "sal{w}\t%0";
10878 return "sal{w}\t{%2, %0|%0, %2}";
10881 [(set (attr "type")
10882 (cond [(eq_attr "alternative" "1")
10883 (const_string "lea")
10884 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10886 (match_operand 0 "register_operand" ""))
10887 (match_operand 2 "const1_operand" ""))
10888 (const_string "alu")
10890 (const_string "ishift")))
10891 (set_attr "mode" "HI,SI")])
10893 (define_insn "*ashlhi3_1"
10894 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10895 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10896 (match_operand:QI 2 "nonmemory_operand" "cI")))
10897 (clobber (reg:CC FLAGS_REG))]
10898 "TARGET_PARTIAL_REG_STALL
10899 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10901 switch (get_attr_type (insn))
10904 gcc_assert (operands[2] == const1_rtx);
10905 return "add{w}\t{%0, %0|%0, %0}";
10908 if (REG_P (operands[2]))
10909 return "sal{w}\t{%b2, %0|%0, %b2}";
10910 else if (operands[2] == const1_rtx
10911 && (TARGET_SHIFT1 || optimize_size))
10912 return "sal{w}\t%0";
10914 return "sal{w}\t{%2, %0|%0, %2}";
10917 [(set (attr "type")
10918 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10920 (match_operand 0 "register_operand" ""))
10921 (match_operand 2 "const1_operand" ""))
10922 (const_string "alu")
10924 (const_string "ishift")))
10925 (set_attr "mode" "HI")])
10927 ;; This pattern can't accept a variable shift count, since shifts by
10928 ;; zero don't affect the flags. We assume that shifts by constant
10929 ;; zero are optimized away.
10930 (define_insn "*ashlhi3_cmp"
10931 [(set (reg FLAGS_REG)
10933 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10934 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10936 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10937 (ashift:HI (match_dup 1) (match_dup 2)))]
10938 "ix86_match_ccmode (insn, CCGOCmode)
10939 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10941 || !TARGET_PARTIAL_FLAG_REG_STALL
10942 || (operands[2] == const1_rtx
10944 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10946 switch (get_attr_type (insn))
10949 gcc_assert (operands[2] == const1_rtx);
10950 return "add{w}\t{%0, %0|%0, %0}";
10953 if (REG_P (operands[2]))
10954 return "sal{w}\t{%b2, %0|%0, %b2}";
10955 else if (operands[2] == const1_rtx
10956 && (TARGET_SHIFT1 || optimize_size))
10957 return "sal{w}\t%0";
10959 return "sal{w}\t{%2, %0|%0, %2}";
10962 [(set (attr "type")
10963 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10965 (match_operand 0 "register_operand" ""))
10966 (match_operand 2 "const1_operand" ""))
10967 (const_string "alu")
10969 (const_string "ishift")))
10970 (set_attr "mode" "HI")])
10972 (define_insn "*ashlhi3_cconly"
10973 [(set (reg FLAGS_REG)
10975 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10976 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10978 (clobber (match_scratch:HI 0 "=r"))]
10979 "ix86_match_ccmode (insn, CCGOCmode)
10980 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10982 || !TARGET_PARTIAL_FLAG_REG_STALL
10983 || (operands[2] == const1_rtx
10985 || TARGET_DOUBLE_WITH_ADD)))"
10987 switch (get_attr_type (insn))
10990 gcc_assert (operands[2] == const1_rtx);
10991 return "add{w}\t{%0, %0|%0, %0}";
10994 if (REG_P (operands[2]))
10995 return "sal{w}\t{%b2, %0|%0, %b2}";
10996 else if (operands[2] == const1_rtx
10997 && (TARGET_SHIFT1 || optimize_size))
10998 return "sal{w}\t%0";
11000 return "sal{w}\t{%2, %0|%0, %2}";
11003 [(set (attr "type")
11004 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11006 (match_operand 0 "register_operand" ""))
11007 (match_operand 2 "const1_operand" ""))
11008 (const_string "alu")
11010 (const_string "ishift")))
11011 (set_attr "mode" "HI")])
11013 (define_expand "ashlqi3"
11014 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11015 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11016 (match_operand:QI 2 "nonmemory_operand" "")))
11017 (clobber (reg:CC FLAGS_REG))]
11018 "TARGET_QIMODE_MATH"
11019 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11021 ;; %%% Potential partial reg stall on alternative 2. What to do?
11023 (define_insn "*ashlqi3_1_lea"
11024 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11025 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11026 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11027 (clobber (reg:CC FLAGS_REG))]
11028 "!TARGET_PARTIAL_REG_STALL
11029 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11031 switch (get_attr_type (insn))
11036 gcc_assert (operands[2] == const1_rtx);
11037 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11038 return "add{l}\t{%k0, %k0|%k0, %k0}";
11040 return "add{b}\t{%0, %0|%0, %0}";
11043 if (REG_P (operands[2]))
11045 if (get_attr_mode (insn) == MODE_SI)
11046 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11048 return "sal{b}\t{%b2, %0|%0, %b2}";
11050 else if (operands[2] == const1_rtx
11051 && (TARGET_SHIFT1 || optimize_size))
11053 if (get_attr_mode (insn) == MODE_SI)
11054 return "sal{l}\t%0";
11056 return "sal{b}\t%0";
11060 if (get_attr_mode (insn) == MODE_SI)
11061 return "sal{l}\t{%2, %k0|%k0, %2}";
11063 return "sal{b}\t{%2, %0|%0, %2}";
11067 [(set (attr "type")
11068 (cond [(eq_attr "alternative" "2")
11069 (const_string "lea")
11070 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11072 (match_operand 0 "register_operand" ""))
11073 (match_operand 2 "const1_operand" ""))
11074 (const_string "alu")
11076 (const_string "ishift")))
11077 (set_attr "mode" "QI,SI,SI")])
11079 (define_insn "*ashlqi3_1"
11080 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11081 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11082 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11083 (clobber (reg:CC FLAGS_REG))]
11084 "TARGET_PARTIAL_REG_STALL
11085 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11087 switch (get_attr_type (insn))
11090 gcc_assert (operands[2] == const1_rtx);
11091 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11092 return "add{l}\t{%k0, %k0|%k0, %k0}";
11094 return "add{b}\t{%0, %0|%0, %0}";
11097 if (REG_P (operands[2]))
11099 if (get_attr_mode (insn) == MODE_SI)
11100 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11102 return "sal{b}\t{%b2, %0|%0, %b2}";
11104 else if (operands[2] == const1_rtx
11105 && (TARGET_SHIFT1 || optimize_size))
11107 if (get_attr_mode (insn) == MODE_SI)
11108 return "sal{l}\t%0";
11110 return "sal{b}\t%0";
11114 if (get_attr_mode (insn) == MODE_SI)
11115 return "sal{l}\t{%2, %k0|%k0, %2}";
11117 return "sal{b}\t{%2, %0|%0, %2}";
11121 [(set (attr "type")
11122 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11124 (match_operand 0 "register_operand" ""))
11125 (match_operand 2 "const1_operand" ""))
11126 (const_string "alu")
11128 (const_string "ishift")))
11129 (set_attr "mode" "QI,SI")])
11131 ;; This pattern can't accept a variable shift count, since shifts by
11132 ;; zero don't affect the flags. We assume that shifts by constant
11133 ;; zero are optimized away.
11134 (define_insn "*ashlqi3_cmp"
11135 [(set (reg FLAGS_REG)
11137 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11138 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11140 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11141 (ashift:QI (match_dup 1) (match_dup 2)))]
11142 "ix86_match_ccmode (insn, CCGOCmode)
11143 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11145 || !TARGET_PARTIAL_FLAG_REG_STALL
11146 || (operands[2] == const1_rtx
11148 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11150 switch (get_attr_type (insn))
11153 gcc_assert (operands[2] == const1_rtx);
11154 return "add{b}\t{%0, %0|%0, %0}";
11157 if (REG_P (operands[2]))
11158 return "sal{b}\t{%b2, %0|%0, %b2}";
11159 else if (operands[2] == const1_rtx
11160 && (TARGET_SHIFT1 || optimize_size))
11161 return "sal{b}\t%0";
11163 return "sal{b}\t{%2, %0|%0, %2}";
11166 [(set (attr "type")
11167 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11169 (match_operand 0 "register_operand" ""))
11170 (match_operand 2 "const1_operand" ""))
11171 (const_string "alu")
11173 (const_string "ishift")))
11174 (set_attr "mode" "QI")])
11176 (define_insn "*ashlqi3_cconly"
11177 [(set (reg FLAGS_REG)
11179 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11180 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11182 (clobber (match_scratch:QI 0 "=q"))]
11183 "ix86_match_ccmode (insn, CCGOCmode)
11184 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11186 || !TARGET_PARTIAL_FLAG_REG_STALL
11187 || (operands[2] == const1_rtx
11189 || TARGET_DOUBLE_WITH_ADD)))"
11191 switch (get_attr_type (insn))
11194 gcc_assert (operands[2] == const1_rtx);
11195 return "add{b}\t{%0, %0|%0, %0}";
11198 if (REG_P (operands[2]))
11199 return "sal{b}\t{%b2, %0|%0, %b2}";
11200 else if (operands[2] == const1_rtx
11201 && (TARGET_SHIFT1 || optimize_size))
11202 return "sal{b}\t%0";
11204 return "sal{b}\t{%2, %0|%0, %2}";
11207 [(set (attr "type")
11208 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11210 (match_operand 0 "register_operand" ""))
11211 (match_operand 2 "const1_operand" ""))
11212 (const_string "alu")
11214 (const_string "ishift")))
11215 (set_attr "mode" "QI")])
11217 ;; See comment above `ashldi3' about how this works.
11219 (define_expand "ashrti3"
11220 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11221 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11222 (match_operand:QI 2 "nonmemory_operand" "")))
11223 (clobber (reg:CC FLAGS_REG))])]
11226 if (! immediate_operand (operands[2], QImode))
11228 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11231 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11235 (define_insn "ashrti3_1"
11236 [(set (match_operand:TI 0 "register_operand" "=r")
11237 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11238 (match_operand:QI 2 "register_operand" "c")))
11239 (clobber (match_scratch:DI 3 "=&r"))
11240 (clobber (reg:CC FLAGS_REG))]
11243 [(set_attr "type" "multi")])
11245 (define_insn "*ashrti3_2"
11246 [(set (match_operand:TI 0 "register_operand" "=r")
11247 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11248 (match_operand:QI 2 "immediate_operand" "O")))
11249 (clobber (reg:CC FLAGS_REG))]
11252 [(set_attr "type" "multi")])
11255 [(set (match_operand:TI 0 "register_operand" "")
11256 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11257 (match_operand:QI 2 "register_operand" "")))
11258 (clobber (match_scratch:DI 3 ""))
11259 (clobber (reg:CC FLAGS_REG))]
11260 "TARGET_64BIT && reload_completed"
11262 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11265 [(set (match_operand:TI 0 "register_operand" "")
11266 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11267 (match_operand:QI 2 "immediate_operand" "")))
11268 (clobber (reg:CC FLAGS_REG))]
11269 "TARGET_64BIT && reload_completed"
11271 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11273 (define_insn "x86_64_shrd"
11274 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11275 (ior:DI (ashiftrt:DI (match_dup 0)
11276 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11277 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11278 (minus:QI (const_int 64) (match_dup 2)))))
11279 (clobber (reg:CC FLAGS_REG))]
11282 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11283 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11284 [(set_attr "type" "ishift")
11285 (set_attr "prefix_0f" "1")
11286 (set_attr "mode" "DI")
11287 (set_attr "athlon_decode" "vector")])
11289 (define_expand "ashrdi3"
11290 [(set (match_operand:DI 0 "shiftdi_operand" "")
11291 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11292 (match_operand:QI 2 "nonmemory_operand" "")))]
11294 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11296 (define_insn "*ashrdi3_63_rex64"
11297 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11298 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11299 (match_operand:DI 2 "const_int_operand" "i,i")))
11300 (clobber (reg:CC FLAGS_REG))]
11301 "TARGET_64BIT && INTVAL (operands[2]) == 63
11302 && (TARGET_USE_CLTD || optimize_size)
11303 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11306 sar{q}\t{%2, %0|%0, %2}"
11307 [(set_attr "type" "imovx,ishift")
11308 (set_attr "prefix_0f" "0,*")
11309 (set_attr "length_immediate" "0,*")
11310 (set_attr "modrm" "0,1")
11311 (set_attr "mode" "DI")])
11313 (define_insn "*ashrdi3_1_one_bit_rex64"
11314 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11315 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11316 (match_operand:QI 2 "const1_operand" "")))
11317 (clobber (reg:CC FLAGS_REG))]
11318 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11319 && (TARGET_SHIFT1 || optimize_size)"
11321 [(set_attr "type" "ishift")
11322 (set (attr "length")
11323 (if_then_else (match_operand:DI 0 "register_operand" "")
11325 (const_string "*")))])
11327 (define_insn "*ashrdi3_1_rex64"
11328 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11329 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11330 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11331 (clobber (reg:CC FLAGS_REG))]
11332 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11334 sar{q}\t{%2, %0|%0, %2}
11335 sar{q}\t{%b2, %0|%0, %b2}"
11336 [(set_attr "type" "ishift")
11337 (set_attr "mode" "DI")])
11339 ;; This pattern can't accept a variable shift count, since shifts by
11340 ;; zero don't affect the flags. We assume that shifts by constant
11341 ;; zero are optimized away.
11342 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11343 [(set (reg FLAGS_REG)
11345 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11346 (match_operand:QI 2 "const1_operand" ""))
11348 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11349 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11350 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11351 && (TARGET_SHIFT1 || optimize_size)
11352 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11354 [(set_attr "type" "ishift")
11355 (set (attr "length")
11356 (if_then_else (match_operand:DI 0 "register_operand" "")
11358 (const_string "*")))])
11360 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11361 [(set (reg FLAGS_REG)
11363 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11364 (match_operand:QI 2 "const1_operand" ""))
11366 (clobber (match_scratch:DI 0 "=r"))]
11367 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11368 && (TARGET_SHIFT1 || optimize_size)
11369 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11371 [(set_attr "type" "ishift")
11372 (set_attr "length" "2")])
11374 ;; This pattern can't accept a variable shift count, since shifts by
11375 ;; zero don't affect the flags. We assume that shifts by constant
11376 ;; zero are optimized away.
11377 (define_insn "*ashrdi3_cmp_rex64"
11378 [(set (reg FLAGS_REG)
11380 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11381 (match_operand:QI 2 "const_int_operand" "n"))
11383 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11384 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11385 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11386 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11388 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11389 "sar{q}\t{%2, %0|%0, %2}"
11390 [(set_attr "type" "ishift")
11391 (set_attr "mode" "DI")])
11393 (define_insn "*ashrdi3_cconly_rex64"
11394 [(set (reg FLAGS_REG)
11396 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11397 (match_operand:QI 2 "const_int_operand" "n"))
11399 (clobber (match_scratch:DI 0 "=r"))]
11400 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11401 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11403 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11404 "sar{q}\t{%2, %0|%0, %2}"
11405 [(set_attr "type" "ishift")
11406 (set_attr "mode" "DI")])
11408 (define_insn "*ashrdi3_1"
11409 [(set (match_operand:DI 0 "register_operand" "=r")
11410 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11411 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11412 (clobber (reg:CC FLAGS_REG))]
11415 [(set_attr "type" "multi")])
11417 ;; By default we don't ask for a scratch register, because when DImode
11418 ;; values are manipulated, registers are already at a premium. But if
11419 ;; we have one handy, we won't turn it away.
11421 [(match_scratch:SI 3 "r")
11422 (parallel [(set (match_operand:DI 0 "register_operand" "")
11423 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11424 (match_operand:QI 2 "nonmemory_operand" "")))
11425 (clobber (reg:CC FLAGS_REG))])
11427 "!TARGET_64BIT && TARGET_CMOVE"
11429 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11432 [(set (match_operand:DI 0 "register_operand" "")
11433 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11434 (match_operand:QI 2 "nonmemory_operand" "")))
11435 (clobber (reg:CC FLAGS_REG))]
11436 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11437 ? flow2_completed : reload_completed)"
11439 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11441 (define_insn "x86_shrd_1"
11442 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11443 (ior:SI (ashiftrt:SI (match_dup 0)
11444 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11445 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11446 (minus:QI (const_int 32) (match_dup 2)))))
11447 (clobber (reg:CC FLAGS_REG))]
11450 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11451 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11452 [(set_attr "type" "ishift")
11453 (set_attr "prefix_0f" "1")
11454 (set_attr "pent_pair" "np")
11455 (set_attr "mode" "SI")])
11457 (define_expand "x86_shift_adj_3"
11458 [(use (match_operand:SI 0 "register_operand" ""))
11459 (use (match_operand:SI 1 "register_operand" ""))
11460 (use (match_operand:QI 2 "register_operand" ""))]
11463 rtx label = gen_label_rtx ();
11466 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11468 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11469 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11470 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11471 gen_rtx_LABEL_REF (VOIDmode, label),
11473 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11474 JUMP_LABEL (tmp) = label;
11476 emit_move_insn (operands[0], operands[1]);
11477 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11479 emit_label (label);
11480 LABEL_NUSES (label) = 1;
11485 (define_insn "ashrsi3_31"
11486 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11487 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11488 (match_operand:SI 2 "const_int_operand" "i,i")))
11489 (clobber (reg:CC FLAGS_REG))]
11490 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11491 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11494 sar{l}\t{%2, %0|%0, %2}"
11495 [(set_attr "type" "imovx,ishift")
11496 (set_attr "prefix_0f" "0,*")
11497 (set_attr "length_immediate" "0,*")
11498 (set_attr "modrm" "0,1")
11499 (set_attr "mode" "SI")])
11501 (define_insn "*ashrsi3_31_zext"
11502 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11503 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11504 (match_operand:SI 2 "const_int_operand" "i,i"))))
11505 (clobber (reg:CC FLAGS_REG))]
11506 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11507 && INTVAL (operands[2]) == 31
11508 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11511 sar{l}\t{%2, %k0|%k0, %2}"
11512 [(set_attr "type" "imovx,ishift")
11513 (set_attr "prefix_0f" "0,*")
11514 (set_attr "length_immediate" "0,*")
11515 (set_attr "modrm" "0,1")
11516 (set_attr "mode" "SI")])
11518 (define_expand "ashrsi3"
11519 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11520 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11521 (match_operand:QI 2 "nonmemory_operand" "")))
11522 (clobber (reg:CC FLAGS_REG))]
11524 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11526 (define_insn "*ashrsi3_1_one_bit"
11527 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11528 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11529 (match_operand:QI 2 "const1_operand" "")))
11530 (clobber (reg:CC FLAGS_REG))]
11531 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11532 && (TARGET_SHIFT1 || optimize_size)"
11534 [(set_attr "type" "ishift")
11535 (set (attr "length")
11536 (if_then_else (match_operand:SI 0 "register_operand" "")
11538 (const_string "*")))])
11540 (define_insn "*ashrsi3_1_one_bit_zext"
11541 [(set (match_operand:DI 0 "register_operand" "=r")
11542 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11543 (match_operand:QI 2 "const1_operand" ""))))
11544 (clobber (reg:CC FLAGS_REG))]
11545 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11546 && (TARGET_SHIFT1 || optimize_size)"
11548 [(set_attr "type" "ishift")
11549 (set_attr "length" "2")])
11551 (define_insn "*ashrsi3_1"
11552 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11553 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11554 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11555 (clobber (reg:CC FLAGS_REG))]
11556 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11558 sar{l}\t{%2, %0|%0, %2}
11559 sar{l}\t{%b2, %0|%0, %b2}"
11560 [(set_attr "type" "ishift")
11561 (set_attr "mode" "SI")])
11563 (define_insn "*ashrsi3_1_zext"
11564 [(set (match_operand:DI 0 "register_operand" "=r,r")
11565 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11566 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11567 (clobber (reg:CC FLAGS_REG))]
11568 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11570 sar{l}\t{%2, %k0|%k0, %2}
11571 sar{l}\t{%b2, %k0|%k0, %b2}"
11572 [(set_attr "type" "ishift")
11573 (set_attr "mode" "SI")])
11575 ;; This pattern can't accept a variable shift count, since shifts by
11576 ;; zero don't affect the flags. We assume that shifts by constant
11577 ;; zero are optimized away.
11578 (define_insn "*ashrsi3_one_bit_cmp"
11579 [(set (reg FLAGS_REG)
11581 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11582 (match_operand:QI 2 "const1_operand" ""))
11584 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11585 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11586 "ix86_match_ccmode (insn, CCGOCmode)
11587 && (TARGET_SHIFT1 || optimize_size)
11588 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11590 [(set_attr "type" "ishift")
11591 (set (attr "length")
11592 (if_then_else (match_operand:SI 0 "register_operand" "")
11594 (const_string "*")))])
11596 (define_insn "*ashrsi3_one_bit_cconly"
11597 [(set (reg FLAGS_REG)
11599 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11600 (match_operand:QI 2 "const1_operand" ""))
11602 (clobber (match_scratch:SI 0 "=r"))]
11603 "ix86_match_ccmode (insn, CCGOCmode)
11604 && (TARGET_SHIFT1 || optimize_size)
11605 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11607 [(set_attr "type" "ishift")
11608 (set_attr "length" "2")])
11610 (define_insn "*ashrsi3_one_bit_cmp_zext"
11611 [(set (reg FLAGS_REG)
11613 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11614 (match_operand:QI 2 "const1_operand" ""))
11616 (set (match_operand:DI 0 "register_operand" "=r")
11617 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11618 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11619 && (TARGET_SHIFT1 || optimize_size)
11620 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11622 [(set_attr "type" "ishift")
11623 (set_attr "length" "2")])
11625 ;; This pattern can't accept a variable shift count, since shifts by
11626 ;; zero don't affect the flags. We assume that shifts by constant
11627 ;; zero are optimized away.
11628 (define_insn "*ashrsi3_cmp"
11629 [(set (reg FLAGS_REG)
11631 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11632 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11634 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11635 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11636 "ix86_match_ccmode (insn, CCGOCmode)
11637 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11639 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11640 "sar{l}\t{%2, %0|%0, %2}"
11641 [(set_attr "type" "ishift")
11642 (set_attr "mode" "SI")])
11644 (define_insn "*ashrsi3_cconly"
11645 [(set (reg FLAGS_REG)
11647 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11648 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11650 (clobber (match_scratch:SI 0 "=r"))]
11651 "ix86_match_ccmode (insn, CCGOCmode)
11652 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11654 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11655 "sar{l}\t{%2, %0|%0, %2}"
11656 [(set_attr "type" "ishift")
11657 (set_attr "mode" "SI")])
11659 (define_insn "*ashrsi3_cmp_zext"
11660 [(set (reg FLAGS_REG)
11662 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11663 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11665 (set (match_operand:DI 0 "register_operand" "=r")
11666 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11667 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11668 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11670 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11671 "sar{l}\t{%2, %k0|%k0, %2}"
11672 [(set_attr "type" "ishift")
11673 (set_attr "mode" "SI")])
11675 (define_expand "ashrhi3"
11676 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11677 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11678 (match_operand:QI 2 "nonmemory_operand" "")))
11679 (clobber (reg:CC FLAGS_REG))]
11680 "TARGET_HIMODE_MATH"
11681 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11683 (define_insn "*ashrhi3_1_one_bit"
11684 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11685 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11686 (match_operand:QI 2 "const1_operand" "")))
11687 (clobber (reg:CC FLAGS_REG))]
11688 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11689 && (TARGET_SHIFT1 || optimize_size)"
11691 [(set_attr "type" "ishift")
11692 (set (attr "length")
11693 (if_then_else (match_operand 0 "register_operand" "")
11695 (const_string "*")))])
11697 (define_insn "*ashrhi3_1"
11698 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11699 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11700 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11701 (clobber (reg:CC FLAGS_REG))]
11702 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11704 sar{w}\t{%2, %0|%0, %2}
11705 sar{w}\t{%b2, %0|%0, %b2}"
11706 [(set_attr "type" "ishift")
11707 (set_attr "mode" "HI")])
11709 ;; This pattern can't accept a variable shift count, since shifts by
11710 ;; zero don't affect the flags. We assume that shifts by constant
11711 ;; zero are optimized away.
11712 (define_insn "*ashrhi3_one_bit_cmp"
11713 [(set (reg FLAGS_REG)
11715 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11716 (match_operand:QI 2 "const1_operand" ""))
11718 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11719 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11720 "ix86_match_ccmode (insn, CCGOCmode)
11721 && (TARGET_SHIFT1 || optimize_size)
11722 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11724 [(set_attr "type" "ishift")
11725 (set (attr "length")
11726 (if_then_else (match_operand 0 "register_operand" "")
11728 (const_string "*")))])
11730 (define_insn "*ashrhi3_one_bit_cconly"
11731 [(set (reg FLAGS_REG)
11733 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11734 (match_operand:QI 2 "const1_operand" ""))
11736 (clobber (match_scratch:HI 0 "=r"))]
11737 "ix86_match_ccmode (insn, CCGOCmode)
11738 && (TARGET_SHIFT1 || optimize_size)
11739 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11741 [(set_attr "type" "ishift")
11742 (set_attr "length" "2")])
11744 ;; This pattern can't accept a variable shift count, since shifts by
11745 ;; zero don't affect the flags. We assume that shifts by constant
11746 ;; zero are optimized away.
11747 (define_insn "*ashrhi3_cmp"
11748 [(set (reg FLAGS_REG)
11750 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11751 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11753 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11754 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11755 "ix86_match_ccmode (insn, CCGOCmode)
11756 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11758 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11759 "sar{w}\t{%2, %0|%0, %2}"
11760 [(set_attr "type" "ishift")
11761 (set_attr "mode" "HI")])
11763 (define_insn "*ashrhi3_cconly"
11764 [(set (reg FLAGS_REG)
11766 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11767 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11769 (clobber (match_scratch:HI 0 "=r"))]
11770 "ix86_match_ccmode (insn, CCGOCmode)
11771 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11773 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11774 "sar{w}\t{%2, %0|%0, %2}"
11775 [(set_attr "type" "ishift")
11776 (set_attr "mode" "HI")])
11778 (define_expand "ashrqi3"
11779 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11780 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11781 (match_operand:QI 2 "nonmemory_operand" "")))
11782 (clobber (reg:CC FLAGS_REG))]
11783 "TARGET_QIMODE_MATH"
11784 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11786 (define_insn "*ashrqi3_1_one_bit"
11787 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11788 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11789 (match_operand:QI 2 "const1_operand" "")))
11790 (clobber (reg:CC FLAGS_REG))]
11791 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11792 && (TARGET_SHIFT1 || optimize_size)"
11794 [(set_attr "type" "ishift")
11795 (set (attr "length")
11796 (if_then_else (match_operand 0 "register_operand" "")
11798 (const_string "*")))])
11800 (define_insn "*ashrqi3_1_one_bit_slp"
11801 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11802 (ashiftrt:QI (match_dup 0)
11803 (match_operand:QI 1 "const1_operand" "")))
11804 (clobber (reg:CC FLAGS_REG))]
11805 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11806 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11807 && (TARGET_SHIFT1 || optimize_size)"
11809 [(set_attr "type" "ishift1")
11810 (set (attr "length")
11811 (if_then_else (match_operand 0 "register_operand" "")
11813 (const_string "*")))])
11815 (define_insn "*ashrqi3_1"
11816 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11817 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11818 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11819 (clobber (reg:CC FLAGS_REG))]
11820 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11822 sar{b}\t{%2, %0|%0, %2}
11823 sar{b}\t{%b2, %0|%0, %b2}"
11824 [(set_attr "type" "ishift")
11825 (set_attr "mode" "QI")])
11827 (define_insn "*ashrqi3_1_slp"
11828 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11829 (ashiftrt:QI (match_dup 0)
11830 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11831 (clobber (reg:CC FLAGS_REG))]
11832 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11833 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11835 sar{b}\t{%1, %0|%0, %1}
11836 sar{b}\t{%b1, %0|%0, %b1}"
11837 [(set_attr "type" "ishift1")
11838 (set_attr "mode" "QI")])
11840 ;; This pattern can't accept a variable shift count, since shifts by
11841 ;; zero don't affect the flags. We assume that shifts by constant
11842 ;; zero are optimized away.
11843 (define_insn "*ashrqi3_one_bit_cmp"
11844 [(set (reg FLAGS_REG)
11846 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11847 (match_operand:QI 2 "const1_operand" "I"))
11849 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11850 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11851 "ix86_match_ccmode (insn, CCGOCmode)
11852 && (TARGET_SHIFT1 || optimize_size)
11853 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11855 [(set_attr "type" "ishift")
11856 (set (attr "length")
11857 (if_then_else (match_operand 0 "register_operand" "")
11859 (const_string "*")))])
11861 (define_insn "*ashrqi3_one_bit_cconly"
11862 [(set (reg FLAGS_REG)
11864 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11865 (match_operand:QI 2 "const1_operand" "I"))
11867 (clobber (match_scratch:QI 0 "=q"))]
11868 "ix86_match_ccmode (insn, CCGOCmode)
11869 && (TARGET_SHIFT1 || optimize_size)
11870 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11872 [(set_attr "type" "ishift")
11873 (set_attr "length" "2")])
11875 ;; This pattern can't accept a variable shift count, since shifts by
11876 ;; zero don't affect the flags. We assume that shifts by constant
11877 ;; zero are optimized away.
11878 (define_insn "*ashrqi3_cmp"
11879 [(set (reg FLAGS_REG)
11881 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11882 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11884 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11885 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11886 "ix86_match_ccmode (insn, CCGOCmode)
11887 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11889 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11890 "sar{b}\t{%2, %0|%0, %2}"
11891 [(set_attr "type" "ishift")
11892 (set_attr "mode" "QI")])
11894 (define_insn "*ashrqi3_cconly"
11895 [(set (reg FLAGS_REG)
11897 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11898 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11900 (clobber (match_scratch:QI 0 "=q"))]
11901 "ix86_match_ccmode (insn, CCGOCmode)
11902 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11904 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11905 "sar{b}\t{%2, %0|%0, %2}"
11906 [(set_attr "type" "ishift")
11907 (set_attr "mode" "QI")])
11910 ;; Logical shift instructions
11912 ;; See comment above `ashldi3' about how this works.
11914 (define_expand "lshrti3"
11915 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11916 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11917 (match_operand:QI 2 "nonmemory_operand" "")))
11918 (clobber (reg:CC FLAGS_REG))])]
11921 if (! immediate_operand (operands[2], QImode))
11923 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11926 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11930 (define_insn "lshrti3_1"
11931 [(set (match_operand:TI 0 "register_operand" "=r")
11932 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11933 (match_operand:QI 2 "register_operand" "c")))
11934 (clobber (match_scratch:DI 3 "=&r"))
11935 (clobber (reg:CC FLAGS_REG))]
11938 [(set_attr "type" "multi")])
11940 (define_insn "*lshrti3_2"
11941 [(set (match_operand:TI 0 "register_operand" "=r")
11942 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11943 (match_operand:QI 2 "immediate_operand" "O")))
11944 (clobber (reg:CC FLAGS_REG))]
11947 [(set_attr "type" "multi")])
11950 [(set (match_operand:TI 0 "register_operand" "")
11951 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11952 (match_operand:QI 2 "register_operand" "")))
11953 (clobber (match_scratch:DI 3 ""))
11954 (clobber (reg:CC FLAGS_REG))]
11955 "TARGET_64BIT && reload_completed"
11957 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11960 [(set (match_operand:TI 0 "register_operand" "")
11961 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11962 (match_operand:QI 2 "immediate_operand" "")))
11963 (clobber (reg:CC FLAGS_REG))]
11964 "TARGET_64BIT && reload_completed"
11966 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11968 (define_expand "lshrdi3"
11969 [(set (match_operand:DI 0 "shiftdi_operand" "")
11970 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11971 (match_operand:QI 2 "nonmemory_operand" "")))]
11973 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11975 (define_insn "*lshrdi3_1_one_bit_rex64"
11976 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11977 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11978 (match_operand:QI 2 "const1_operand" "")))
11979 (clobber (reg:CC FLAGS_REG))]
11980 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11981 && (TARGET_SHIFT1 || optimize_size)"
11983 [(set_attr "type" "ishift")
11984 (set (attr "length")
11985 (if_then_else (match_operand:DI 0 "register_operand" "")
11987 (const_string "*")))])
11989 (define_insn "*lshrdi3_1_rex64"
11990 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11991 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11992 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11993 (clobber (reg:CC FLAGS_REG))]
11994 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11996 shr{q}\t{%2, %0|%0, %2}
11997 shr{q}\t{%b2, %0|%0, %b2}"
11998 [(set_attr "type" "ishift")
11999 (set_attr "mode" "DI")])
12001 ;; This pattern can't accept a variable shift count, since shifts by
12002 ;; zero don't affect the flags. We assume that shifts by constant
12003 ;; zero are optimized away.
12004 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12005 [(set (reg FLAGS_REG)
12007 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12008 (match_operand:QI 2 "const1_operand" ""))
12010 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12011 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12012 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12013 && (TARGET_SHIFT1 || optimize_size)
12014 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12016 [(set_attr "type" "ishift")
12017 (set (attr "length")
12018 (if_then_else (match_operand:DI 0 "register_operand" "")
12020 (const_string "*")))])
12022 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12023 [(set (reg FLAGS_REG)
12025 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12026 (match_operand:QI 2 "const1_operand" ""))
12028 (clobber (match_scratch:DI 0 "=r"))]
12029 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12030 && (TARGET_SHIFT1 || optimize_size)
12031 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12033 [(set_attr "type" "ishift")
12034 (set_attr "length" "2")])
12036 ;; This pattern can't accept a variable shift count, since shifts by
12037 ;; zero don't affect the flags. We assume that shifts by constant
12038 ;; zero are optimized away.
12039 (define_insn "*lshrdi3_cmp_rex64"
12040 [(set (reg FLAGS_REG)
12042 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12043 (match_operand:QI 2 "const_int_operand" "e"))
12045 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12046 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12047 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12048 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12050 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12051 "shr{q}\t{%2, %0|%0, %2}"
12052 [(set_attr "type" "ishift")
12053 (set_attr "mode" "DI")])
12055 (define_insn "*lshrdi3_cconly_rex64"
12056 [(set (reg FLAGS_REG)
12058 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12059 (match_operand:QI 2 "const_int_operand" "e"))
12061 (clobber (match_scratch:DI 0 "=r"))]
12062 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12063 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12065 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12066 "shr{q}\t{%2, %0|%0, %2}"
12067 [(set_attr "type" "ishift")
12068 (set_attr "mode" "DI")])
12070 (define_insn "*lshrdi3_1"
12071 [(set (match_operand:DI 0 "register_operand" "=r")
12072 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12073 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12074 (clobber (reg:CC FLAGS_REG))]
12077 [(set_attr "type" "multi")])
12079 ;; By default we don't ask for a scratch register, because when DImode
12080 ;; values are manipulated, registers are already at a premium. But if
12081 ;; we have one handy, we won't turn it away.
12083 [(match_scratch:SI 3 "r")
12084 (parallel [(set (match_operand:DI 0 "register_operand" "")
12085 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12086 (match_operand:QI 2 "nonmemory_operand" "")))
12087 (clobber (reg:CC FLAGS_REG))])
12089 "!TARGET_64BIT && TARGET_CMOVE"
12091 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12094 [(set (match_operand:DI 0 "register_operand" "")
12095 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12096 (match_operand:QI 2 "nonmemory_operand" "")))
12097 (clobber (reg:CC FLAGS_REG))]
12098 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12099 ? flow2_completed : reload_completed)"
12101 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12103 (define_expand "lshrsi3"
12104 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12105 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12106 (match_operand:QI 2 "nonmemory_operand" "")))
12107 (clobber (reg:CC FLAGS_REG))]
12109 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12111 (define_insn "*lshrsi3_1_one_bit"
12112 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12113 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12114 (match_operand:QI 2 "const1_operand" "")))
12115 (clobber (reg:CC FLAGS_REG))]
12116 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12117 && (TARGET_SHIFT1 || optimize_size)"
12119 [(set_attr "type" "ishift")
12120 (set (attr "length")
12121 (if_then_else (match_operand:SI 0 "register_operand" "")
12123 (const_string "*")))])
12125 (define_insn "*lshrsi3_1_one_bit_zext"
12126 [(set (match_operand:DI 0 "register_operand" "=r")
12127 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12128 (match_operand:QI 2 "const1_operand" "")))
12129 (clobber (reg:CC FLAGS_REG))]
12130 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12131 && (TARGET_SHIFT1 || optimize_size)"
12133 [(set_attr "type" "ishift")
12134 (set_attr "length" "2")])
12136 (define_insn "*lshrsi3_1"
12137 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12138 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12139 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12140 (clobber (reg:CC FLAGS_REG))]
12141 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12143 shr{l}\t{%2, %0|%0, %2}
12144 shr{l}\t{%b2, %0|%0, %b2}"
12145 [(set_attr "type" "ishift")
12146 (set_attr "mode" "SI")])
12148 (define_insn "*lshrsi3_1_zext"
12149 [(set (match_operand:DI 0 "register_operand" "=r,r")
12151 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12152 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12153 (clobber (reg:CC FLAGS_REG))]
12154 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12156 shr{l}\t{%2, %k0|%k0, %2}
12157 shr{l}\t{%b2, %k0|%k0, %b2}"
12158 [(set_attr "type" "ishift")
12159 (set_attr "mode" "SI")])
12161 ;; This pattern can't accept a variable shift count, since shifts by
12162 ;; zero don't affect the flags. We assume that shifts by constant
12163 ;; zero are optimized away.
12164 (define_insn "*lshrsi3_one_bit_cmp"
12165 [(set (reg FLAGS_REG)
12167 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12168 (match_operand:QI 2 "const1_operand" ""))
12170 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12171 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12172 "ix86_match_ccmode (insn, CCGOCmode)
12173 && (TARGET_SHIFT1 || optimize_size)
12174 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12176 [(set_attr "type" "ishift")
12177 (set (attr "length")
12178 (if_then_else (match_operand:SI 0 "register_operand" "")
12180 (const_string "*")))])
12182 (define_insn "*lshrsi3_one_bit_cconly"
12183 [(set (reg FLAGS_REG)
12185 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12186 (match_operand:QI 2 "const1_operand" ""))
12188 (clobber (match_scratch:SI 0 "=r"))]
12189 "ix86_match_ccmode (insn, CCGOCmode)
12190 && (TARGET_SHIFT1 || optimize_size)
12191 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12193 [(set_attr "type" "ishift")
12194 (set_attr "length" "2")])
12196 (define_insn "*lshrsi3_cmp_one_bit_zext"
12197 [(set (reg FLAGS_REG)
12199 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12200 (match_operand:QI 2 "const1_operand" ""))
12202 (set (match_operand:DI 0 "register_operand" "=r")
12203 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12204 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12205 && (TARGET_SHIFT1 || optimize_size)
12206 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12208 [(set_attr "type" "ishift")
12209 (set_attr "length" "2")])
12211 ;; This pattern can't accept a variable shift count, since shifts by
12212 ;; zero don't affect the flags. We assume that shifts by constant
12213 ;; zero are optimized away.
12214 (define_insn "*lshrsi3_cmp"
12215 [(set (reg FLAGS_REG)
12217 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12218 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12220 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12221 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12222 "ix86_match_ccmode (insn, CCGOCmode)
12223 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12225 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12226 "shr{l}\t{%2, %0|%0, %2}"
12227 [(set_attr "type" "ishift")
12228 (set_attr "mode" "SI")])
12230 (define_insn "*lshrsi3_cconly"
12231 [(set (reg FLAGS_REG)
12233 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12234 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12236 (clobber (match_scratch:SI 0 "=r"))]
12237 "ix86_match_ccmode (insn, CCGOCmode)
12238 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12240 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12241 "shr{l}\t{%2, %0|%0, %2}"
12242 [(set_attr "type" "ishift")
12243 (set_attr "mode" "SI")])
12245 (define_insn "*lshrsi3_cmp_zext"
12246 [(set (reg FLAGS_REG)
12248 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12249 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12251 (set (match_operand:DI 0 "register_operand" "=r")
12252 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12253 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12254 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12256 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12257 "shr{l}\t{%2, %k0|%k0, %2}"
12258 [(set_attr "type" "ishift")
12259 (set_attr "mode" "SI")])
12261 (define_expand "lshrhi3"
12262 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12263 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12264 (match_operand:QI 2 "nonmemory_operand" "")))
12265 (clobber (reg:CC FLAGS_REG))]
12266 "TARGET_HIMODE_MATH"
12267 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12269 (define_insn "*lshrhi3_1_one_bit"
12270 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12271 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12272 (match_operand:QI 2 "const1_operand" "")))
12273 (clobber (reg:CC FLAGS_REG))]
12274 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12275 && (TARGET_SHIFT1 || optimize_size)"
12277 [(set_attr "type" "ishift")
12278 (set (attr "length")
12279 (if_then_else (match_operand 0 "register_operand" "")
12281 (const_string "*")))])
12283 (define_insn "*lshrhi3_1"
12284 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12285 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12286 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12287 (clobber (reg:CC FLAGS_REG))]
12288 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12290 shr{w}\t{%2, %0|%0, %2}
12291 shr{w}\t{%b2, %0|%0, %b2}"
12292 [(set_attr "type" "ishift")
12293 (set_attr "mode" "HI")])
12295 ;; This pattern can't accept a variable shift count, since shifts by
12296 ;; zero don't affect the flags. We assume that shifts by constant
12297 ;; zero are optimized away.
12298 (define_insn "*lshrhi3_one_bit_cmp"
12299 [(set (reg FLAGS_REG)
12301 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12302 (match_operand:QI 2 "const1_operand" ""))
12304 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12305 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12306 "ix86_match_ccmode (insn, CCGOCmode)
12307 && (TARGET_SHIFT1 || optimize_size)
12308 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12310 [(set_attr "type" "ishift")
12311 (set (attr "length")
12312 (if_then_else (match_operand:SI 0 "register_operand" "")
12314 (const_string "*")))])
12316 (define_insn "*lshrhi3_one_bit_cconly"
12317 [(set (reg FLAGS_REG)
12319 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12320 (match_operand:QI 2 "const1_operand" ""))
12322 (clobber (match_scratch:HI 0 "=r"))]
12323 "ix86_match_ccmode (insn, CCGOCmode)
12324 && (TARGET_SHIFT1 || optimize_size)
12325 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12327 [(set_attr "type" "ishift")
12328 (set_attr "length" "2")])
12330 ;; This pattern can't accept a variable shift count, since shifts by
12331 ;; zero don't affect the flags. We assume that shifts by constant
12332 ;; zero are optimized away.
12333 (define_insn "*lshrhi3_cmp"
12334 [(set (reg FLAGS_REG)
12336 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12337 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12339 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12340 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12341 "ix86_match_ccmode (insn, CCGOCmode)
12342 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12344 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12345 "shr{w}\t{%2, %0|%0, %2}"
12346 [(set_attr "type" "ishift")
12347 (set_attr "mode" "HI")])
12349 (define_insn "*lshrhi3_cconly"
12350 [(set (reg FLAGS_REG)
12352 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12353 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12355 (clobber (match_scratch:HI 0 "=r"))]
12356 "ix86_match_ccmode (insn, CCGOCmode)
12357 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12359 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12360 "shr{w}\t{%2, %0|%0, %2}"
12361 [(set_attr "type" "ishift")
12362 (set_attr "mode" "HI")])
12364 (define_expand "lshrqi3"
12365 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12366 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12367 (match_operand:QI 2 "nonmemory_operand" "")))
12368 (clobber (reg:CC FLAGS_REG))]
12369 "TARGET_QIMODE_MATH"
12370 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12372 (define_insn "*lshrqi3_1_one_bit"
12373 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12374 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12375 (match_operand:QI 2 "const1_operand" "")))
12376 (clobber (reg:CC FLAGS_REG))]
12377 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12378 && (TARGET_SHIFT1 || optimize_size)"
12380 [(set_attr "type" "ishift")
12381 (set (attr "length")
12382 (if_then_else (match_operand 0 "register_operand" "")
12384 (const_string "*")))])
12386 (define_insn "*lshrqi3_1_one_bit_slp"
12387 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12388 (lshiftrt:QI (match_dup 0)
12389 (match_operand:QI 1 "const1_operand" "")))
12390 (clobber (reg:CC FLAGS_REG))]
12391 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12392 && (TARGET_SHIFT1 || optimize_size)"
12394 [(set_attr "type" "ishift1")
12395 (set (attr "length")
12396 (if_then_else (match_operand 0 "register_operand" "")
12398 (const_string "*")))])
12400 (define_insn "*lshrqi3_1"
12401 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12402 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12403 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12404 (clobber (reg:CC FLAGS_REG))]
12405 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12407 shr{b}\t{%2, %0|%0, %2}
12408 shr{b}\t{%b2, %0|%0, %b2}"
12409 [(set_attr "type" "ishift")
12410 (set_attr "mode" "QI")])
12412 (define_insn "*lshrqi3_1_slp"
12413 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12414 (lshiftrt:QI (match_dup 0)
12415 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12416 (clobber (reg:CC FLAGS_REG))]
12417 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12418 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12420 shr{b}\t{%1, %0|%0, %1}
12421 shr{b}\t{%b1, %0|%0, %b1}"
12422 [(set_attr "type" "ishift1")
12423 (set_attr "mode" "QI")])
12425 ;; This pattern can't accept a variable shift count, since shifts by
12426 ;; zero don't affect the flags. We assume that shifts by constant
12427 ;; zero are optimized away.
12428 (define_insn "*lshrqi2_one_bit_cmp"
12429 [(set (reg FLAGS_REG)
12431 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12432 (match_operand:QI 2 "const1_operand" ""))
12434 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12435 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12436 "ix86_match_ccmode (insn, CCGOCmode)
12437 && (TARGET_SHIFT1 || optimize_size)
12438 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12440 [(set_attr "type" "ishift")
12441 (set (attr "length")
12442 (if_then_else (match_operand:SI 0 "register_operand" "")
12444 (const_string "*")))])
12446 (define_insn "*lshrqi2_one_bit_cconly"
12447 [(set (reg FLAGS_REG)
12449 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12450 (match_operand:QI 2 "const1_operand" ""))
12452 (clobber (match_scratch:QI 0 "=q"))]
12453 "ix86_match_ccmode (insn, CCGOCmode)
12454 && (TARGET_SHIFT1 || optimize_size)
12455 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12457 [(set_attr "type" "ishift")
12458 (set_attr "length" "2")])
12460 ;; This pattern can't accept a variable shift count, since shifts by
12461 ;; zero don't affect the flags. We assume that shifts by constant
12462 ;; zero are optimized away.
12463 (define_insn "*lshrqi2_cmp"
12464 [(set (reg FLAGS_REG)
12466 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12467 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12469 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12470 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12471 "ix86_match_ccmode (insn, CCGOCmode)
12472 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12474 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12475 "shr{b}\t{%2, %0|%0, %2}"
12476 [(set_attr "type" "ishift")
12477 (set_attr "mode" "QI")])
12479 (define_insn "*lshrqi2_cconly"
12480 [(set (reg FLAGS_REG)
12482 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12483 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12485 (clobber (match_scratch:QI 0 "=q"))]
12486 "ix86_match_ccmode (insn, CCGOCmode)
12487 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12489 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12490 "shr{b}\t{%2, %0|%0, %2}"
12491 [(set_attr "type" "ishift")
12492 (set_attr "mode" "QI")])
12494 ;; Rotate instructions
12496 (define_expand "rotldi3"
12497 [(set (match_operand:DI 0 "shiftdi_operand" "")
12498 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12499 (match_operand:QI 2 "nonmemory_operand" "")))
12500 (clobber (reg:CC FLAGS_REG))]
12505 ix86_expand_binary_operator (ROTATE, DImode, operands);
12508 if (!const_1_to_31_operand (operands[2], VOIDmode))
12510 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12514 ;; Implement rotation using two double-precision shift instructions
12515 ;; and a scratch register.
12516 (define_insn_and_split "ix86_rotldi3"
12517 [(set (match_operand:DI 0 "register_operand" "=r")
12518 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12519 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12520 (clobber (reg:CC FLAGS_REG))
12521 (clobber (match_scratch:SI 3 "=&r"))]
12524 "&& reload_completed"
12525 [(set (match_dup 3) (match_dup 4))
12527 [(set (match_dup 4)
12528 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12529 (lshiftrt:SI (match_dup 5)
12530 (minus:QI (const_int 32) (match_dup 2)))))
12531 (clobber (reg:CC FLAGS_REG))])
12533 [(set (match_dup 5)
12534 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12535 (lshiftrt:SI (match_dup 3)
12536 (minus:QI (const_int 32) (match_dup 2)))))
12537 (clobber (reg:CC FLAGS_REG))])]
12538 "split_di (operands, 1, operands + 4, operands + 5);")
12540 (define_insn "*rotlsi3_1_one_bit_rex64"
12541 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12542 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12543 (match_operand:QI 2 "const1_operand" "")))
12544 (clobber (reg:CC FLAGS_REG))]
12545 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12546 && (TARGET_SHIFT1 || optimize_size)"
12548 [(set_attr "type" "rotate")
12549 (set (attr "length")
12550 (if_then_else (match_operand:DI 0 "register_operand" "")
12552 (const_string "*")))])
12554 (define_insn "*rotldi3_1_rex64"
12555 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12556 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12557 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12558 (clobber (reg:CC FLAGS_REG))]
12559 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12561 rol{q}\t{%2, %0|%0, %2}
12562 rol{q}\t{%b2, %0|%0, %b2}"
12563 [(set_attr "type" "rotate")
12564 (set_attr "mode" "DI")])
12566 (define_expand "rotlsi3"
12567 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12568 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12569 (match_operand:QI 2 "nonmemory_operand" "")))
12570 (clobber (reg:CC FLAGS_REG))]
12572 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12574 (define_insn "*rotlsi3_1_one_bit"
12575 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12576 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12577 (match_operand:QI 2 "const1_operand" "")))
12578 (clobber (reg:CC FLAGS_REG))]
12579 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12580 && (TARGET_SHIFT1 || optimize_size)"
12582 [(set_attr "type" "rotate")
12583 (set (attr "length")
12584 (if_then_else (match_operand:SI 0 "register_operand" "")
12586 (const_string "*")))])
12588 (define_insn "*rotlsi3_1_one_bit_zext"
12589 [(set (match_operand:DI 0 "register_operand" "=r")
12591 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12592 (match_operand:QI 2 "const1_operand" ""))))
12593 (clobber (reg:CC FLAGS_REG))]
12594 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12595 && (TARGET_SHIFT1 || optimize_size)"
12597 [(set_attr "type" "rotate")
12598 (set_attr "length" "2")])
12600 (define_insn "*rotlsi3_1"
12601 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12602 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12603 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12604 (clobber (reg:CC FLAGS_REG))]
12605 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12607 rol{l}\t{%2, %0|%0, %2}
12608 rol{l}\t{%b2, %0|%0, %b2}"
12609 [(set_attr "type" "rotate")
12610 (set_attr "mode" "SI")])
12612 (define_insn "*rotlsi3_1_zext"
12613 [(set (match_operand:DI 0 "register_operand" "=r,r")
12615 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12616 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12617 (clobber (reg:CC FLAGS_REG))]
12618 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12620 rol{l}\t{%2, %k0|%k0, %2}
12621 rol{l}\t{%b2, %k0|%k0, %b2}"
12622 [(set_attr "type" "rotate")
12623 (set_attr "mode" "SI")])
12625 (define_expand "rotlhi3"
12626 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12627 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12628 (match_operand:QI 2 "nonmemory_operand" "")))
12629 (clobber (reg:CC FLAGS_REG))]
12630 "TARGET_HIMODE_MATH"
12631 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12633 (define_insn "*rotlhi3_1_one_bit"
12634 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12635 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12636 (match_operand:QI 2 "const1_operand" "")))
12637 (clobber (reg:CC FLAGS_REG))]
12638 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12639 && (TARGET_SHIFT1 || optimize_size)"
12641 [(set_attr "type" "rotate")
12642 (set (attr "length")
12643 (if_then_else (match_operand 0 "register_operand" "")
12645 (const_string "*")))])
12647 (define_insn "*rotlhi3_1"
12648 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12649 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12650 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12651 (clobber (reg:CC FLAGS_REG))]
12652 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12654 rol{w}\t{%2, %0|%0, %2}
12655 rol{w}\t{%b2, %0|%0, %b2}"
12656 [(set_attr "type" "rotate")
12657 (set_attr "mode" "HI")])
12659 (define_expand "rotlqi3"
12660 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12661 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12662 (match_operand:QI 2 "nonmemory_operand" "")))
12663 (clobber (reg:CC FLAGS_REG))]
12664 "TARGET_QIMODE_MATH"
12665 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12667 (define_insn "*rotlqi3_1_one_bit_slp"
12668 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12669 (rotate:QI (match_dup 0)
12670 (match_operand:QI 1 "const1_operand" "")))
12671 (clobber (reg:CC FLAGS_REG))]
12672 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12673 && (TARGET_SHIFT1 || optimize_size)"
12675 [(set_attr "type" "rotate1")
12676 (set (attr "length")
12677 (if_then_else (match_operand 0 "register_operand" "")
12679 (const_string "*")))])
12681 (define_insn "*rotlqi3_1_one_bit"
12682 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12683 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12684 (match_operand:QI 2 "const1_operand" "")))
12685 (clobber (reg:CC FLAGS_REG))]
12686 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12687 && (TARGET_SHIFT1 || optimize_size)"
12689 [(set_attr "type" "rotate")
12690 (set (attr "length")
12691 (if_then_else (match_operand 0 "register_operand" "")
12693 (const_string "*")))])
12695 (define_insn "*rotlqi3_1_slp"
12696 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12697 (rotate:QI (match_dup 0)
12698 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12699 (clobber (reg:CC FLAGS_REG))]
12700 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12701 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12703 rol{b}\t{%1, %0|%0, %1}
12704 rol{b}\t{%b1, %0|%0, %b1}"
12705 [(set_attr "type" "rotate1")
12706 (set_attr "mode" "QI")])
12708 (define_insn "*rotlqi3_1"
12709 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12710 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12711 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12712 (clobber (reg:CC FLAGS_REG))]
12713 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12715 rol{b}\t{%2, %0|%0, %2}
12716 rol{b}\t{%b2, %0|%0, %b2}"
12717 [(set_attr "type" "rotate")
12718 (set_attr "mode" "QI")])
12720 (define_expand "rotrdi3"
12721 [(set (match_operand:DI 0 "shiftdi_operand" "")
12722 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12723 (match_operand:QI 2 "nonmemory_operand" "")))
12724 (clobber (reg:CC FLAGS_REG))]
12729 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12732 if (!const_1_to_31_operand (operands[2], VOIDmode))
12734 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12738 ;; Implement rotation using two double-precision shift instructions
12739 ;; and a scratch register.
12740 (define_insn_and_split "ix86_rotrdi3"
12741 [(set (match_operand:DI 0 "register_operand" "=r")
12742 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12743 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12744 (clobber (reg:CC FLAGS_REG))
12745 (clobber (match_scratch:SI 3 "=&r"))]
12748 "&& reload_completed"
12749 [(set (match_dup 3) (match_dup 4))
12751 [(set (match_dup 4)
12752 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12753 (ashift:SI (match_dup 5)
12754 (minus:QI (const_int 32) (match_dup 2)))))
12755 (clobber (reg:CC FLAGS_REG))])
12757 [(set (match_dup 5)
12758 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12759 (ashift:SI (match_dup 3)
12760 (minus:QI (const_int 32) (match_dup 2)))))
12761 (clobber (reg:CC FLAGS_REG))])]
12762 "split_di (operands, 1, operands + 4, operands + 5);")
12764 (define_insn "*rotrdi3_1_one_bit_rex64"
12765 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12766 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12767 (match_operand:QI 2 "const1_operand" "")))
12768 (clobber (reg:CC FLAGS_REG))]
12769 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12770 && (TARGET_SHIFT1 || optimize_size)"
12772 [(set_attr "type" "rotate")
12773 (set (attr "length")
12774 (if_then_else (match_operand:DI 0 "register_operand" "")
12776 (const_string "*")))])
12778 (define_insn "*rotrdi3_1_rex64"
12779 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12780 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12781 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12782 (clobber (reg:CC FLAGS_REG))]
12783 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12785 ror{q}\t{%2, %0|%0, %2}
12786 ror{q}\t{%b2, %0|%0, %b2}"
12787 [(set_attr "type" "rotate")
12788 (set_attr "mode" "DI")])
12790 (define_expand "rotrsi3"
12791 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12792 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12793 (match_operand:QI 2 "nonmemory_operand" "")))
12794 (clobber (reg:CC FLAGS_REG))]
12796 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12798 (define_insn "*rotrsi3_1_one_bit"
12799 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12800 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12801 (match_operand:QI 2 "const1_operand" "")))
12802 (clobber (reg:CC FLAGS_REG))]
12803 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12804 && (TARGET_SHIFT1 || optimize_size)"
12806 [(set_attr "type" "rotate")
12807 (set (attr "length")
12808 (if_then_else (match_operand:SI 0 "register_operand" "")
12810 (const_string "*")))])
12812 (define_insn "*rotrsi3_1_one_bit_zext"
12813 [(set (match_operand:DI 0 "register_operand" "=r")
12815 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12816 (match_operand:QI 2 "const1_operand" ""))))
12817 (clobber (reg:CC FLAGS_REG))]
12818 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12819 && (TARGET_SHIFT1 || optimize_size)"
12821 [(set_attr "type" "rotate")
12822 (set (attr "length")
12823 (if_then_else (match_operand:SI 0 "register_operand" "")
12825 (const_string "*")))])
12827 (define_insn "*rotrsi3_1"
12828 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12829 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12830 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12831 (clobber (reg:CC FLAGS_REG))]
12832 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12834 ror{l}\t{%2, %0|%0, %2}
12835 ror{l}\t{%b2, %0|%0, %b2}"
12836 [(set_attr "type" "rotate")
12837 (set_attr "mode" "SI")])
12839 (define_insn "*rotrsi3_1_zext"
12840 [(set (match_operand:DI 0 "register_operand" "=r,r")
12842 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12843 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12844 (clobber (reg:CC FLAGS_REG))]
12845 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12847 ror{l}\t{%2, %k0|%k0, %2}
12848 ror{l}\t{%b2, %k0|%k0, %b2}"
12849 [(set_attr "type" "rotate")
12850 (set_attr "mode" "SI")])
12852 (define_expand "rotrhi3"
12853 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12854 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12855 (match_operand:QI 2 "nonmemory_operand" "")))
12856 (clobber (reg:CC FLAGS_REG))]
12857 "TARGET_HIMODE_MATH"
12858 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12860 (define_insn "*rotrhi3_one_bit"
12861 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12862 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12863 (match_operand:QI 2 "const1_operand" "")))
12864 (clobber (reg:CC FLAGS_REG))]
12865 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12866 && (TARGET_SHIFT1 || optimize_size)"
12868 [(set_attr "type" "rotate")
12869 (set (attr "length")
12870 (if_then_else (match_operand 0 "register_operand" "")
12872 (const_string "*")))])
12874 (define_insn "*rotrhi3"
12875 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12876 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12877 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12878 (clobber (reg:CC FLAGS_REG))]
12879 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12881 ror{w}\t{%2, %0|%0, %2}
12882 ror{w}\t{%b2, %0|%0, %b2}"
12883 [(set_attr "type" "rotate")
12884 (set_attr "mode" "HI")])
12886 (define_expand "rotrqi3"
12887 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12888 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12889 (match_operand:QI 2 "nonmemory_operand" "")))
12890 (clobber (reg:CC FLAGS_REG))]
12891 "TARGET_QIMODE_MATH"
12892 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12894 (define_insn "*rotrqi3_1_one_bit"
12895 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12896 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12897 (match_operand:QI 2 "const1_operand" "")))
12898 (clobber (reg:CC FLAGS_REG))]
12899 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12900 && (TARGET_SHIFT1 || optimize_size)"
12902 [(set_attr "type" "rotate")
12903 (set (attr "length")
12904 (if_then_else (match_operand 0 "register_operand" "")
12906 (const_string "*")))])
12908 (define_insn "*rotrqi3_1_one_bit_slp"
12909 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12910 (rotatert:QI (match_dup 0)
12911 (match_operand:QI 1 "const1_operand" "")))
12912 (clobber (reg:CC FLAGS_REG))]
12913 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12914 && (TARGET_SHIFT1 || optimize_size)"
12916 [(set_attr "type" "rotate1")
12917 (set (attr "length")
12918 (if_then_else (match_operand 0 "register_operand" "")
12920 (const_string "*")))])
12922 (define_insn "*rotrqi3_1"
12923 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12924 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12925 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12926 (clobber (reg:CC FLAGS_REG))]
12927 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12929 ror{b}\t{%2, %0|%0, %2}
12930 ror{b}\t{%b2, %0|%0, %b2}"
12931 [(set_attr "type" "rotate")
12932 (set_attr "mode" "QI")])
12934 (define_insn "*rotrqi3_1_slp"
12935 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12936 (rotatert:QI (match_dup 0)
12937 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12938 (clobber (reg:CC FLAGS_REG))]
12939 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12940 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12942 ror{b}\t{%1, %0|%0, %1}
12943 ror{b}\t{%b1, %0|%0, %b1}"
12944 [(set_attr "type" "rotate1")
12945 (set_attr "mode" "QI")])
12947 ;; Bit set / bit test instructions
12949 (define_expand "extv"
12950 [(set (match_operand:SI 0 "register_operand" "")
12951 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12952 (match_operand:SI 2 "const8_operand" "")
12953 (match_operand:SI 3 "const8_operand" "")))]
12956 /* Handle extractions from %ah et al. */
12957 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12960 /* From mips.md: extract_bit_field doesn't verify that our source
12961 matches the predicate, so check it again here. */
12962 if (! ext_register_operand (operands[1], VOIDmode))
12966 (define_expand "extzv"
12967 [(set (match_operand:SI 0 "register_operand" "")
12968 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12969 (match_operand:SI 2 "const8_operand" "")
12970 (match_operand:SI 3 "const8_operand" "")))]
12973 /* Handle extractions from %ah et al. */
12974 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12977 /* From mips.md: extract_bit_field doesn't verify that our source
12978 matches the predicate, so check it again here. */
12979 if (! ext_register_operand (operands[1], VOIDmode))
12983 (define_expand "insv"
12984 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12985 (match_operand 1 "const8_operand" "")
12986 (match_operand 2 "const8_operand" ""))
12987 (match_operand 3 "register_operand" ""))]
12990 /* Handle insertions to %ah et al. */
12991 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12994 /* From mips.md: insert_bit_field doesn't verify that our source
12995 matches the predicate, so check it again here. */
12996 if (! ext_register_operand (operands[0], VOIDmode))
13000 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13002 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13007 ;; %%% bts, btr, btc, bt.
13008 ;; In general these instructions are *slow* when applied to memory,
13009 ;; since they enforce atomic operation. When applied to registers,
13010 ;; it depends on the cpu implementation. They're never faster than
13011 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13012 ;; no point. But in 64-bit, we can't hold the relevant immediates
13013 ;; within the instruction itself, so operating on bits in the high
13014 ;; 32-bits of a register becomes easier.
13016 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13017 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13018 ;; negdf respectively, so they can never be disabled entirely.
13020 (define_insn "*btsq"
13021 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13023 (match_operand:DI 1 "const_0_to_63_operand" ""))
13025 (clobber (reg:CC FLAGS_REG))]
13026 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13028 [(set_attr "type" "alu1")])
13030 (define_insn "*btrq"
13031 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13033 (match_operand:DI 1 "const_0_to_63_operand" ""))
13035 (clobber (reg:CC FLAGS_REG))]
13036 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13038 [(set_attr "type" "alu1")])
13040 (define_insn "*btcq"
13041 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13043 (match_operand:DI 1 "const_0_to_63_operand" ""))
13044 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13045 (clobber (reg:CC FLAGS_REG))]
13046 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13048 [(set_attr "type" "alu1")])
13050 ;; Allow Nocona to avoid these instructions if a register is available.
13053 [(match_scratch:DI 2 "r")
13054 (parallel [(set (zero_extract:DI
13055 (match_operand:DI 0 "register_operand" "")
13057 (match_operand:DI 1 "const_0_to_63_operand" ""))
13059 (clobber (reg:CC FLAGS_REG))])]
13060 "TARGET_64BIT && !TARGET_USE_BT"
13063 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13066 if (HOST_BITS_PER_WIDE_INT >= 64)
13067 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13068 else if (i < HOST_BITS_PER_WIDE_INT)
13069 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13071 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13073 op1 = immed_double_const (lo, hi, DImode);
13076 emit_move_insn (operands[2], op1);
13080 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13085 [(match_scratch:DI 2 "r")
13086 (parallel [(set (zero_extract:DI
13087 (match_operand:DI 0 "register_operand" "")
13089 (match_operand:DI 1 "const_0_to_63_operand" ""))
13091 (clobber (reg:CC FLAGS_REG))])]
13092 "TARGET_64BIT && !TARGET_USE_BT"
13095 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13098 if (HOST_BITS_PER_WIDE_INT >= 64)
13099 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13100 else if (i < HOST_BITS_PER_WIDE_INT)
13101 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13103 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13105 op1 = immed_double_const (~lo, ~hi, DImode);
13108 emit_move_insn (operands[2], op1);
13112 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13117 [(match_scratch:DI 2 "r")
13118 (parallel [(set (zero_extract:DI
13119 (match_operand:DI 0 "register_operand" "")
13121 (match_operand:DI 1 "const_0_to_63_operand" ""))
13122 (not:DI (zero_extract:DI
13123 (match_dup 0) (const_int 1) (match_dup 1))))
13124 (clobber (reg:CC FLAGS_REG))])]
13125 "TARGET_64BIT && !TARGET_USE_BT"
13128 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13131 if (HOST_BITS_PER_WIDE_INT >= 64)
13132 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13133 else if (i < HOST_BITS_PER_WIDE_INT)
13134 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13136 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13138 op1 = immed_double_const (lo, hi, DImode);
13141 emit_move_insn (operands[2], op1);
13145 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13149 ;; Store-flag instructions.
13151 ;; For all sCOND expanders, also expand the compare or test insn that
13152 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13154 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13155 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13156 ;; way, which can later delete the movzx if only QImode is needed.
13158 (define_expand "seq"
13159 [(set (match_operand:QI 0 "register_operand" "")
13160 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13162 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13164 (define_expand "sne"
13165 [(set (match_operand:QI 0 "register_operand" "")
13166 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13168 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13170 (define_expand "sgt"
13171 [(set (match_operand:QI 0 "register_operand" "")
13172 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13174 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13176 (define_expand "sgtu"
13177 [(set (match_operand:QI 0 "register_operand" "")
13178 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13180 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13182 (define_expand "slt"
13183 [(set (match_operand:QI 0 "register_operand" "")
13184 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13186 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13188 (define_expand "sltu"
13189 [(set (match_operand:QI 0 "register_operand" "")
13190 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13192 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13194 (define_expand "sge"
13195 [(set (match_operand:QI 0 "register_operand" "")
13196 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13198 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13200 (define_expand "sgeu"
13201 [(set (match_operand:QI 0 "register_operand" "")
13202 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13204 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13206 (define_expand "sle"
13207 [(set (match_operand:QI 0 "register_operand" "")
13208 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13210 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13212 (define_expand "sleu"
13213 [(set (match_operand:QI 0 "register_operand" "")
13214 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13216 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13218 (define_expand "sunordered"
13219 [(set (match_operand:QI 0 "register_operand" "")
13220 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13221 "TARGET_80387 || TARGET_SSE"
13222 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13224 (define_expand "sordered"
13225 [(set (match_operand:QI 0 "register_operand" "")
13226 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13228 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13230 (define_expand "suneq"
13231 [(set (match_operand:QI 0 "register_operand" "")
13232 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13233 "TARGET_80387 || TARGET_SSE"
13234 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13236 (define_expand "sunge"
13237 [(set (match_operand:QI 0 "register_operand" "")
13238 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13239 "TARGET_80387 || TARGET_SSE"
13240 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13242 (define_expand "sungt"
13243 [(set (match_operand:QI 0 "register_operand" "")
13244 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13245 "TARGET_80387 || TARGET_SSE"
13246 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13248 (define_expand "sunle"
13249 [(set (match_operand:QI 0 "register_operand" "")
13250 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13251 "TARGET_80387 || TARGET_SSE"
13252 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13254 (define_expand "sunlt"
13255 [(set (match_operand:QI 0 "register_operand" "")
13256 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257 "TARGET_80387 || TARGET_SSE"
13258 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13260 (define_expand "sltgt"
13261 [(set (match_operand:QI 0 "register_operand" "")
13262 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13263 "TARGET_80387 || TARGET_SSE"
13264 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13266 (define_insn "*setcc_1"
13267 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13268 (match_operator:QI 1 "ix86_comparison_operator"
13269 [(reg FLAGS_REG) (const_int 0)]))]
13272 [(set_attr "type" "setcc")
13273 (set_attr "mode" "QI")])
13275 (define_insn "*setcc_2"
13276 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13277 (match_operator:QI 1 "ix86_comparison_operator"
13278 [(reg FLAGS_REG) (const_int 0)]))]
13281 [(set_attr "type" "setcc")
13282 (set_attr "mode" "QI")])
13284 ;; In general it is not safe to assume too much about CCmode registers,
13285 ;; so simplify-rtx stops when it sees a second one. Under certain
13286 ;; conditions this is safe on x86, so help combine not create
13293 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13294 (ne:QI (match_operator 1 "ix86_comparison_operator"
13295 [(reg FLAGS_REG) (const_int 0)])
13298 [(set (match_dup 0) (match_dup 1))]
13300 PUT_MODE (operands[1], QImode);
13304 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13305 (ne:QI (match_operator 1 "ix86_comparison_operator"
13306 [(reg FLAGS_REG) (const_int 0)])
13309 [(set (match_dup 0) (match_dup 1))]
13311 PUT_MODE (operands[1], QImode);
13315 [(set (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))
13335 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13336 (eq:QI (match_operator 1 "ix86_comparison_operator"
13337 [(reg FLAGS_REG) (const_int 0)])
13340 [(set (match_dup 0) (match_dup 1))]
13342 rtx new_op1 = copy_rtx (operands[1]);
13343 operands[1] = new_op1;
13344 PUT_MODE (new_op1, QImode);
13345 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13346 GET_MODE (XEXP (new_op1, 0))));
13348 /* Make sure that (a) the CCmode we have for the flags is strong
13349 enough for the reversed compare or (b) we have a valid FP compare. */
13350 if (! ix86_comparison_operator (new_op1, VOIDmode))
13354 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13355 ;; subsequent logical operations are used to imitate conditional moves.
13356 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13359 (define_insn "*sse_setccsf"
13360 [(set (match_operand:SF 0 "register_operand" "=x")
13361 (match_operator:SF 1 "sse_comparison_operator"
13362 [(match_operand:SF 2 "register_operand" "0")
13363 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13365 "cmp%D1ss\t{%3, %0|%0, %3}"
13366 [(set_attr "type" "ssecmp")
13367 (set_attr "mode" "SF")])
13369 (define_insn "*sse_setccdf"
13370 [(set (match_operand:DF 0 "register_operand" "=Y")
13371 (match_operator:DF 1 "sse_comparison_operator"
13372 [(match_operand:DF 2 "register_operand" "0")
13373 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13375 "cmp%D1sd\t{%3, %0|%0, %3}"
13376 [(set_attr "type" "ssecmp")
13377 (set_attr "mode" "DF")])
13379 ;; Basic conditional jump instructions.
13380 ;; We ignore the overflow flag for signed branch instructions.
13382 ;; For all bCOND expanders, also expand the compare or test insn that
13383 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13385 (define_expand "beq"
13387 (if_then_else (match_dup 1)
13388 (label_ref (match_operand 0 "" ""))
13391 "ix86_expand_branch (EQ, operands[0]); DONE;")
13393 (define_expand "bne"
13395 (if_then_else (match_dup 1)
13396 (label_ref (match_operand 0 "" ""))
13399 "ix86_expand_branch (NE, operands[0]); DONE;")
13401 (define_expand "bgt"
13403 (if_then_else (match_dup 1)
13404 (label_ref (match_operand 0 "" ""))
13407 "ix86_expand_branch (GT, operands[0]); DONE;")
13409 (define_expand "bgtu"
13411 (if_then_else (match_dup 1)
13412 (label_ref (match_operand 0 "" ""))
13415 "ix86_expand_branch (GTU, operands[0]); DONE;")
13417 (define_expand "blt"
13419 (if_then_else (match_dup 1)
13420 (label_ref (match_operand 0 "" ""))
13423 "ix86_expand_branch (LT, operands[0]); DONE;")
13425 (define_expand "bltu"
13427 (if_then_else (match_dup 1)
13428 (label_ref (match_operand 0 "" ""))
13431 "ix86_expand_branch (LTU, operands[0]); DONE;")
13433 (define_expand "bge"
13435 (if_then_else (match_dup 1)
13436 (label_ref (match_operand 0 "" ""))
13439 "ix86_expand_branch (GE, operands[0]); DONE;")
13441 (define_expand "bgeu"
13443 (if_then_else (match_dup 1)
13444 (label_ref (match_operand 0 "" ""))
13447 "ix86_expand_branch (GEU, operands[0]); DONE;")
13449 (define_expand "ble"
13451 (if_then_else (match_dup 1)
13452 (label_ref (match_operand 0 "" ""))
13455 "ix86_expand_branch (LE, operands[0]); DONE;")
13457 (define_expand "bleu"
13459 (if_then_else (match_dup 1)
13460 (label_ref (match_operand 0 "" ""))
13463 "ix86_expand_branch (LEU, operands[0]); DONE;")
13465 (define_expand "bunordered"
13467 (if_then_else (match_dup 1)
13468 (label_ref (match_operand 0 "" ""))
13470 "TARGET_80387 || TARGET_SSE_MATH"
13471 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13473 (define_expand "bordered"
13475 (if_then_else (match_dup 1)
13476 (label_ref (match_operand 0 "" ""))
13478 "TARGET_80387 || TARGET_SSE_MATH"
13479 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13481 (define_expand "buneq"
13483 (if_then_else (match_dup 1)
13484 (label_ref (match_operand 0 "" ""))
13486 "TARGET_80387 || TARGET_SSE_MATH"
13487 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13489 (define_expand "bunge"
13491 (if_then_else (match_dup 1)
13492 (label_ref (match_operand 0 "" ""))
13494 "TARGET_80387 || TARGET_SSE_MATH"
13495 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13497 (define_expand "bungt"
13499 (if_then_else (match_dup 1)
13500 (label_ref (match_operand 0 "" ""))
13502 "TARGET_80387 || TARGET_SSE_MATH"
13503 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13505 (define_expand "bunle"
13507 (if_then_else (match_dup 1)
13508 (label_ref (match_operand 0 "" ""))
13510 "TARGET_80387 || TARGET_SSE_MATH"
13511 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13513 (define_expand "bunlt"
13515 (if_then_else (match_dup 1)
13516 (label_ref (match_operand 0 "" ""))
13518 "TARGET_80387 || TARGET_SSE_MATH"
13519 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13521 (define_expand "bltgt"
13523 (if_then_else (match_dup 1)
13524 (label_ref (match_operand 0 "" ""))
13526 "TARGET_80387 || TARGET_SSE_MATH"
13527 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13529 (define_insn "*jcc_1"
13531 (if_then_else (match_operator 1 "ix86_comparison_operator"
13532 [(reg FLAGS_REG) (const_int 0)])
13533 (label_ref (match_operand 0 "" ""))
13537 [(set_attr "type" "ibr")
13538 (set_attr "modrm" "0")
13539 (set (attr "length")
13540 (if_then_else (and (ge (minus (match_dup 0) (pc))
13542 (lt (minus (match_dup 0) (pc))
13547 (define_insn "*jcc_2"
13549 (if_then_else (match_operator 1 "ix86_comparison_operator"
13550 [(reg FLAGS_REG) (const_int 0)])
13552 (label_ref (match_operand 0 "" ""))))]
13555 [(set_attr "type" "ibr")
13556 (set_attr "modrm" "0")
13557 (set (attr "length")
13558 (if_then_else (and (ge (minus (match_dup 0) (pc))
13560 (lt (minus (match_dup 0) (pc))
13565 ;; In general it is not safe to assume too much about CCmode registers,
13566 ;; so simplify-rtx stops when it sees a second one. Under certain
13567 ;; conditions this is safe on x86, so help combine not create
13575 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13576 [(reg FLAGS_REG) (const_int 0)])
13578 (label_ref (match_operand 1 "" ""))
13582 (if_then_else (match_dup 0)
13583 (label_ref (match_dup 1))
13586 PUT_MODE (operands[0], VOIDmode);
13591 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13592 [(reg FLAGS_REG) (const_int 0)])
13594 (label_ref (match_operand 1 "" ""))
13598 (if_then_else (match_dup 0)
13599 (label_ref (match_dup 1))
13602 rtx new_op0 = copy_rtx (operands[0]);
13603 operands[0] = new_op0;
13604 PUT_MODE (new_op0, VOIDmode);
13605 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13606 GET_MODE (XEXP (new_op0, 0))));
13608 /* Make sure that (a) the CCmode we have for the flags is strong
13609 enough for the reversed compare or (b) we have a valid FP compare. */
13610 if (! ix86_comparison_operator (new_op0, VOIDmode))
13614 ;; Define combination compare-and-branch fp compare instructions to use
13615 ;; during early optimization. Splitting the operation apart early makes
13616 ;; for bad code when we want to reverse the operation.
13618 (define_insn "*fp_jcc_1_mixed"
13620 (if_then_else (match_operator 0 "comparison_operator"
13621 [(match_operand 1 "register_operand" "f,x")
13622 (match_operand 2 "nonimmediate_operand" "f,xm")])
13623 (label_ref (match_operand 3 "" ""))
13625 (clobber (reg:CCFP FPSR_REG))
13626 (clobber (reg:CCFP FLAGS_REG))]
13627 "TARGET_MIX_SSE_I387
13628 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13629 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13630 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13633 (define_insn "*fp_jcc_1_sse"
13635 (if_then_else (match_operator 0 "comparison_operator"
13636 [(match_operand 1 "register_operand" "x")
13637 (match_operand 2 "nonimmediate_operand" "xm")])
13638 (label_ref (match_operand 3 "" ""))
13640 (clobber (reg:CCFP FPSR_REG))
13641 (clobber (reg:CCFP FLAGS_REG))]
13643 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13644 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13645 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13648 (define_insn "*fp_jcc_1_387"
13650 (if_then_else (match_operator 0 "comparison_operator"
13651 [(match_operand 1 "register_operand" "f")
13652 (match_operand 2 "register_operand" "f")])
13653 (label_ref (match_operand 3 "" ""))
13655 (clobber (reg:CCFP FPSR_REG))
13656 (clobber (reg:CCFP FLAGS_REG))]
13657 "TARGET_CMOVE && TARGET_80387
13658 && FLOAT_MODE_P (GET_MODE (operands[1]))
13659 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13660 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13663 (define_insn "*fp_jcc_2_mixed"
13665 (if_then_else (match_operator 0 "comparison_operator"
13666 [(match_operand 1 "register_operand" "f,x")
13667 (match_operand 2 "nonimmediate_operand" "f,xm")])
13669 (label_ref (match_operand 3 "" ""))))
13670 (clobber (reg:CCFP FPSR_REG))
13671 (clobber (reg:CCFP FLAGS_REG))]
13672 "TARGET_MIX_SSE_I387
13673 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13674 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13675 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13678 (define_insn "*fp_jcc_2_sse"
13680 (if_then_else (match_operator 0 "comparison_operator"
13681 [(match_operand 1 "register_operand" "x")
13682 (match_operand 2 "nonimmediate_operand" "xm")])
13684 (label_ref (match_operand 3 "" ""))))
13685 (clobber (reg:CCFP FPSR_REG))
13686 (clobber (reg:CCFP FLAGS_REG))]
13688 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13689 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13690 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13693 (define_insn "*fp_jcc_2_387"
13695 (if_then_else (match_operator 0 "comparison_operator"
13696 [(match_operand 1 "register_operand" "f")
13697 (match_operand 2 "register_operand" "f")])
13699 (label_ref (match_operand 3 "" ""))))
13700 (clobber (reg:CCFP FPSR_REG))
13701 (clobber (reg:CCFP FLAGS_REG))]
13702 "TARGET_CMOVE && TARGET_80387
13703 && FLOAT_MODE_P (GET_MODE (operands[1]))
13704 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13705 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13708 (define_insn "*fp_jcc_3_387"
13710 (if_then_else (match_operator 0 "comparison_operator"
13711 [(match_operand 1 "register_operand" "f")
13712 (match_operand 2 "nonimmediate_operand" "fm")])
13713 (label_ref (match_operand 3 "" ""))
13715 (clobber (reg:CCFP FPSR_REG))
13716 (clobber (reg:CCFP FLAGS_REG))
13717 (clobber (match_scratch:HI 4 "=a"))]
13719 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13720 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13721 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13722 && SELECT_CC_MODE (GET_CODE (operands[0]),
13723 operands[1], operands[2]) == CCFPmode
13724 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13727 (define_insn "*fp_jcc_4_387"
13729 (if_then_else (match_operator 0 "comparison_operator"
13730 [(match_operand 1 "register_operand" "f")
13731 (match_operand 2 "nonimmediate_operand" "fm")])
13733 (label_ref (match_operand 3 "" ""))))
13734 (clobber (reg:CCFP FPSR_REG))
13735 (clobber (reg:CCFP FLAGS_REG))
13736 (clobber (match_scratch:HI 4 "=a"))]
13738 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13739 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13740 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13741 && SELECT_CC_MODE (GET_CODE (operands[0]),
13742 operands[1], operands[2]) == CCFPmode
13743 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13746 (define_insn "*fp_jcc_5_387"
13748 (if_then_else (match_operator 0 "comparison_operator"
13749 [(match_operand 1 "register_operand" "f")
13750 (match_operand 2 "register_operand" "f")])
13751 (label_ref (match_operand 3 "" ""))
13753 (clobber (reg:CCFP FPSR_REG))
13754 (clobber (reg:CCFP FLAGS_REG))
13755 (clobber (match_scratch:HI 4 "=a"))]
13757 && FLOAT_MODE_P (GET_MODE (operands[1]))
13758 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13759 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13762 (define_insn "*fp_jcc_6_387"
13764 (if_then_else (match_operator 0 "comparison_operator"
13765 [(match_operand 1 "register_operand" "f")
13766 (match_operand 2 "register_operand" "f")])
13768 (label_ref (match_operand 3 "" ""))))
13769 (clobber (reg:CCFP FPSR_REG))
13770 (clobber (reg:CCFP FLAGS_REG))
13771 (clobber (match_scratch:HI 4 "=a"))]
13773 && FLOAT_MODE_P (GET_MODE (operands[1]))
13774 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13775 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13778 (define_insn "*fp_jcc_7_387"
13780 (if_then_else (match_operator 0 "comparison_operator"
13781 [(match_operand 1 "register_operand" "f")
13782 (match_operand 2 "const0_operand" "X")])
13783 (label_ref (match_operand 3 "" ""))
13785 (clobber (reg:CCFP FPSR_REG))
13786 (clobber (reg:CCFP FLAGS_REG))
13787 (clobber (match_scratch:HI 4 "=a"))]
13789 && FLOAT_MODE_P (GET_MODE (operands[1]))
13790 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13791 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13792 && SELECT_CC_MODE (GET_CODE (operands[0]),
13793 operands[1], operands[2]) == CCFPmode
13794 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13797 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13798 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13799 ;; with a precedence over other operators and is always put in the first
13800 ;; place. Swap condition and operands to match ficom instruction.
13802 (define_insn "*fp_jcc_8<mode>_387"
13804 (if_then_else (match_operator 0 "comparison_operator"
13805 [(match_operator 1 "float_operator"
13806 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13807 (match_operand 3 "register_operand" "f,f")])
13808 (label_ref (match_operand 4 "" ""))
13810 (clobber (reg:CCFP FPSR_REG))
13811 (clobber (reg:CCFP FLAGS_REG))
13812 (clobber (match_scratch:HI 5 "=a,a"))]
13813 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13814 && FLOAT_MODE_P (GET_MODE (operands[3]))
13815 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13816 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13817 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13818 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13823 (if_then_else (match_operator 0 "comparison_operator"
13824 [(match_operand 1 "register_operand" "")
13825 (match_operand 2 "nonimmediate_operand" "")])
13826 (match_operand 3 "" "")
13827 (match_operand 4 "" "")))
13828 (clobber (reg:CCFP FPSR_REG))
13829 (clobber (reg:CCFP FLAGS_REG))]
13833 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13834 operands[3], operands[4], NULL_RTX, NULL_RTX);
13840 (if_then_else (match_operator 0 "comparison_operator"
13841 [(match_operand 1 "register_operand" "")
13842 (match_operand 2 "general_operand" "")])
13843 (match_operand 3 "" "")
13844 (match_operand 4 "" "")))
13845 (clobber (reg:CCFP FPSR_REG))
13846 (clobber (reg:CCFP FLAGS_REG))
13847 (clobber (match_scratch:HI 5 "=a"))]
13851 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13852 operands[3], operands[4], operands[5], NULL_RTX);
13858 (if_then_else (match_operator 0 "comparison_operator"
13859 [(match_operator 1 "float_operator"
13860 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13861 (match_operand 3 "register_operand" "")])
13862 (match_operand 4 "" "")
13863 (match_operand 5 "" "")))
13864 (clobber (reg:CCFP FPSR_REG))
13865 (clobber (reg:CCFP FLAGS_REG))
13866 (clobber (match_scratch:HI 6 "=a"))]
13870 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13871 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13872 operands[3], operands[7],
13873 operands[4], operands[5], operands[6], NULL_RTX);
13877 ;; %%% Kill this when reload knows how to do it.
13880 (if_then_else (match_operator 0 "comparison_operator"
13881 [(match_operator 1 "float_operator"
13882 [(match_operand:X87MODEI12 2 "register_operand" "")])
13883 (match_operand 3 "register_operand" "")])
13884 (match_operand 4 "" "")
13885 (match_operand 5 "" "")))
13886 (clobber (reg:CCFP FPSR_REG))
13887 (clobber (reg:CCFP FLAGS_REG))
13888 (clobber (match_scratch:HI 6 "=a"))]
13892 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13893 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13894 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13895 operands[3], operands[7],
13896 operands[4], operands[5], operands[6], operands[2]);
13900 ;; Unconditional and other jump instructions
13902 (define_insn "jump"
13904 (label_ref (match_operand 0 "" "")))]
13907 [(set_attr "type" "ibr")
13908 (set (attr "length")
13909 (if_then_else (and (ge (minus (match_dup 0) (pc))
13911 (lt (minus (match_dup 0) (pc))
13915 (set_attr "modrm" "0")])
13917 (define_expand "indirect_jump"
13918 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13922 (define_insn "*indirect_jump"
13923 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13926 [(set_attr "type" "ibr")
13927 (set_attr "length_immediate" "0")])
13929 (define_insn "*indirect_jump_rtx64"
13930 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13933 [(set_attr "type" "ibr")
13934 (set_attr "length_immediate" "0")])
13936 (define_expand "tablejump"
13937 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13938 (use (label_ref (match_operand 1 "" "")))])]
13941 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13942 relative. Convert the relative address to an absolute address. */
13946 enum rtx_code code;
13952 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13954 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13958 op1 = pic_offset_table_rtx;
13963 op0 = pic_offset_table_rtx;
13967 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13972 (define_insn "*tablejump_1"
13973 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13974 (use (label_ref (match_operand 1 "" "")))]
13977 [(set_attr "type" "ibr")
13978 (set_attr "length_immediate" "0")])
13980 (define_insn "*tablejump_1_rtx64"
13981 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13982 (use (label_ref (match_operand 1 "" "")))]
13985 [(set_attr "type" "ibr")
13986 (set_attr "length_immediate" "0")])
13988 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13991 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13992 (set (match_operand:QI 1 "register_operand" "")
13993 (match_operator:QI 2 "ix86_comparison_operator"
13994 [(reg FLAGS_REG) (const_int 0)]))
13995 (set (match_operand 3 "q_regs_operand" "")
13996 (zero_extend (match_dup 1)))]
13997 "(peep2_reg_dead_p (3, operands[1])
13998 || operands_match_p (operands[1], operands[3]))
13999 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14000 [(set (match_dup 4) (match_dup 0))
14001 (set (strict_low_part (match_dup 5))
14004 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14005 operands[5] = gen_lowpart (QImode, operands[3]);
14006 ix86_expand_clear (operands[3]);
14009 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14012 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14013 (set (match_operand:QI 1 "register_operand" "")
14014 (match_operator:QI 2 "ix86_comparison_operator"
14015 [(reg FLAGS_REG) (const_int 0)]))
14016 (parallel [(set (match_operand 3 "q_regs_operand" "")
14017 (zero_extend (match_dup 1)))
14018 (clobber (reg:CC FLAGS_REG))])]
14019 "(peep2_reg_dead_p (3, operands[1])
14020 || operands_match_p (operands[1], operands[3]))
14021 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14022 [(set (match_dup 4) (match_dup 0))
14023 (set (strict_low_part (match_dup 5))
14026 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14027 operands[5] = gen_lowpart (QImode, operands[3]);
14028 ix86_expand_clear (operands[3]);
14031 ;; Call instructions.
14033 ;; The predicates normally associated with named expanders are not properly
14034 ;; checked for calls. This is a bug in the generic code, but it isn't that
14035 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14037 ;; Call subroutine returning no value.
14039 (define_expand "call_pop"
14040 [(parallel [(call (match_operand:QI 0 "" "")
14041 (match_operand:SI 1 "" ""))
14042 (set (reg:SI SP_REG)
14043 (plus:SI (reg:SI SP_REG)
14044 (match_operand:SI 3 "" "")))])]
14047 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14051 (define_insn "*call_pop_0"
14052 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14053 (match_operand:SI 1 "" ""))
14054 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14055 (match_operand:SI 2 "immediate_operand" "")))]
14058 if (SIBLING_CALL_P (insn))
14061 return "call\t%P0";
14063 [(set_attr "type" "call")])
14065 (define_insn "*call_pop_1"
14066 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14067 (match_operand:SI 1 "" ""))
14068 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14069 (match_operand:SI 2 "immediate_operand" "i")))]
14072 if (constant_call_address_operand (operands[0], Pmode))
14074 if (SIBLING_CALL_P (insn))
14077 return "call\t%P0";
14079 if (SIBLING_CALL_P (insn))
14082 return "call\t%A0";
14084 [(set_attr "type" "call")])
14086 (define_expand "call"
14087 [(call (match_operand:QI 0 "" "")
14088 (match_operand 1 "" ""))
14089 (use (match_operand 2 "" ""))]
14092 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14096 (define_expand "sibcall"
14097 [(call (match_operand:QI 0 "" "")
14098 (match_operand 1 "" ""))
14099 (use (match_operand 2 "" ""))]
14102 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14106 (define_insn "*call_0"
14107 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14108 (match_operand 1 "" ""))]
14111 if (SIBLING_CALL_P (insn))
14114 return "call\t%P0";
14116 [(set_attr "type" "call")])
14118 (define_insn "*call_1"
14119 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14120 (match_operand 1 "" ""))]
14121 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14123 if (constant_call_address_operand (operands[0], Pmode))
14124 return "call\t%P0";
14125 return "call\t%A0";
14127 [(set_attr "type" "call")])
14129 (define_insn "*sibcall_1"
14130 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14131 (match_operand 1 "" ""))]
14132 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14134 if (constant_call_address_operand (operands[0], Pmode))
14138 [(set_attr "type" "call")])
14140 (define_insn "*call_1_rex64"
14141 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14142 (match_operand 1 "" ""))]
14143 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14145 if (constant_call_address_operand (operands[0], Pmode))
14146 return "call\t%P0";
14147 return "call\t%A0";
14149 [(set_attr "type" "call")])
14151 (define_insn "*sibcall_1_rex64"
14152 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14153 (match_operand 1 "" ""))]
14154 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14156 [(set_attr "type" "call")])
14158 (define_insn "*sibcall_1_rex64_v"
14159 [(call (mem:QI (reg:DI 40))
14160 (match_operand 0 "" ""))]
14161 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14163 [(set_attr "type" "call")])
14166 ;; Call subroutine, returning value in operand 0
14168 (define_expand "call_value_pop"
14169 [(parallel [(set (match_operand 0 "" "")
14170 (call (match_operand:QI 1 "" "")
14171 (match_operand:SI 2 "" "")))
14172 (set (reg:SI SP_REG)
14173 (plus:SI (reg:SI SP_REG)
14174 (match_operand:SI 4 "" "")))])]
14177 ix86_expand_call (operands[0], operands[1], operands[2],
14178 operands[3], operands[4], 0);
14182 (define_expand "call_value"
14183 [(set (match_operand 0 "" "")
14184 (call (match_operand:QI 1 "" "")
14185 (match_operand:SI 2 "" "")))
14186 (use (match_operand:SI 3 "" ""))]
14187 ;; Operand 2 not used on the i386.
14190 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14194 (define_expand "sibcall_value"
14195 [(set (match_operand 0 "" "")
14196 (call (match_operand:QI 1 "" "")
14197 (match_operand:SI 2 "" "")))
14198 (use (match_operand:SI 3 "" ""))]
14199 ;; Operand 2 not used on the i386.
14202 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14206 ;; Call subroutine returning any type.
14208 (define_expand "untyped_call"
14209 [(parallel [(call (match_operand 0 "" "")
14211 (match_operand 1 "" "")
14212 (match_operand 2 "" "")])]
14217 /* In order to give reg-stack an easier job in validating two
14218 coprocessor registers as containing a possible return value,
14219 simply pretend the untyped call returns a complex long double
14222 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14223 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14224 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14227 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14229 rtx set = XVECEXP (operands[2], 0, i);
14230 emit_move_insn (SET_DEST (set), SET_SRC (set));
14233 /* The optimizer does not know that the call sets the function value
14234 registers we stored in the result block. We avoid problems by
14235 claiming that all hard registers are used and clobbered at this
14237 emit_insn (gen_blockage (const0_rtx));
14242 ;; Prologue and epilogue instructions
14244 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14245 ;; all of memory. This blocks insns from being moved across this point.
14247 (define_insn "blockage"
14248 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14251 [(set_attr "length" "0")])
14253 ;; Insn emitted into the body of a function to return from a function.
14254 ;; This is only done if the function's epilogue is known to be simple.
14255 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14257 (define_expand "return"
14259 "ix86_can_use_return_insn_p ()"
14261 if (current_function_pops_args)
14263 rtx popc = GEN_INT (current_function_pops_args);
14264 emit_jump_insn (gen_return_pop_internal (popc));
14269 (define_insn "return_internal"
14273 [(set_attr "length" "1")
14274 (set_attr "length_immediate" "0")
14275 (set_attr "modrm" "0")])
14277 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14278 ;; instruction Athlon and K8 have.
14280 (define_insn "return_internal_long"
14282 (unspec [(const_int 0)] UNSPEC_REP)]
14285 [(set_attr "length" "1")
14286 (set_attr "length_immediate" "0")
14287 (set_attr "prefix_rep" "1")
14288 (set_attr "modrm" "0")])
14290 (define_insn "return_pop_internal"
14292 (use (match_operand:SI 0 "const_int_operand" ""))]
14295 [(set_attr "length" "3")
14296 (set_attr "length_immediate" "2")
14297 (set_attr "modrm" "0")])
14299 (define_insn "return_indirect_internal"
14301 (use (match_operand:SI 0 "register_operand" "r"))]
14304 [(set_attr "type" "ibr")
14305 (set_attr "length_immediate" "0")])
14311 [(set_attr "length" "1")
14312 (set_attr "length_immediate" "0")
14313 (set_attr "modrm" "0")])
14315 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14316 ;; branch prediction penalty for the third jump in a 16-byte
14319 (define_insn "align"
14320 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14323 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14324 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14326 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14327 The align insn is used to avoid 3 jump instructions in the row to improve
14328 branch prediction and the benefits hardly outweigh the cost of extra 8
14329 nops on the average inserted by full alignment pseudo operation. */
14333 [(set_attr "length" "16")])
14335 (define_expand "prologue"
14338 "ix86_expand_prologue (); DONE;")
14340 (define_insn "set_got"
14341 [(set (match_operand:SI 0 "register_operand" "=r")
14342 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14343 (clobber (reg:CC FLAGS_REG))]
14345 { return output_set_got (operands[0], NULL_RTX); }
14346 [(set_attr "type" "multi")
14347 (set_attr "length" "12")])
14349 (define_insn "set_got_labelled"
14350 [(set (match_operand:SI 0 "register_operand" "=r")
14351 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14353 (clobber (reg:CC FLAGS_REG))]
14355 { return output_set_got (operands[0], operands[1]); }
14356 [(set_attr "type" "multi")
14357 (set_attr "length" "12")])
14359 (define_insn "set_got_rex64"
14360 [(set (match_operand:DI 0 "register_operand" "=r")
14361 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14363 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14364 [(set_attr "type" "lea")
14365 (set_attr "length" "6")])
14367 (define_expand "epilogue"
14370 "ix86_expand_epilogue (1); DONE;")
14372 (define_expand "sibcall_epilogue"
14375 "ix86_expand_epilogue (0); DONE;")
14377 (define_expand "eh_return"
14378 [(use (match_operand 0 "register_operand" ""))]
14381 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14383 /* Tricky bit: we write the address of the handler to which we will
14384 be returning into someone else's stack frame, one word below the
14385 stack address we wish to restore. */
14386 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14387 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14388 tmp = gen_rtx_MEM (Pmode, tmp);
14389 emit_move_insn (tmp, ra);
14391 if (Pmode == SImode)
14392 emit_jump_insn (gen_eh_return_si (sa));
14394 emit_jump_insn (gen_eh_return_di (sa));
14399 (define_insn_and_split "eh_return_si"
14401 (unspec [(match_operand:SI 0 "register_operand" "c")]
14402 UNSPEC_EH_RETURN))]
14407 "ix86_expand_epilogue (2); DONE;")
14409 (define_insn_and_split "eh_return_di"
14411 (unspec [(match_operand:DI 0 "register_operand" "c")]
14412 UNSPEC_EH_RETURN))]
14417 "ix86_expand_epilogue (2); DONE;")
14419 (define_insn "leave"
14420 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14421 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14422 (clobber (mem:BLK (scratch)))]
14425 [(set_attr "type" "leave")])
14427 (define_insn "leave_rex64"
14428 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14429 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14430 (clobber (mem:BLK (scratch)))]
14433 [(set_attr "type" "leave")])
14435 (define_expand "ffssi2"
14437 [(set (match_operand:SI 0 "register_operand" "")
14438 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14439 (clobber (match_scratch:SI 2 ""))
14440 (clobber (reg:CC FLAGS_REG))])]
14444 (define_insn_and_split "*ffs_cmove"
14445 [(set (match_operand:SI 0 "register_operand" "=r")
14446 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14447 (clobber (match_scratch:SI 2 "=&r"))
14448 (clobber (reg:CC FLAGS_REG))]
14451 "&& reload_completed"
14452 [(set (match_dup 2) (const_int -1))
14453 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14454 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14455 (set (match_dup 0) (if_then_else:SI
14456 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14459 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14460 (clobber (reg:CC FLAGS_REG))])]
14463 (define_insn_and_split "*ffs_no_cmove"
14464 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14465 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14466 (clobber (match_scratch:SI 2 "=&q"))
14467 (clobber (reg:CC FLAGS_REG))]
14471 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14472 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14473 (set (strict_low_part (match_dup 3))
14474 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14475 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14476 (clobber (reg:CC FLAGS_REG))])
14477 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14478 (clobber (reg:CC FLAGS_REG))])
14479 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14480 (clobber (reg:CC FLAGS_REG))])]
14482 operands[3] = gen_lowpart (QImode, operands[2]);
14483 ix86_expand_clear (operands[2]);
14486 (define_insn "*ffssi_1"
14487 [(set (reg:CCZ FLAGS_REG)
14488 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14490 (set (match_operand:SI 0 "register_operand" "=r")
14491 (ctz:SI (match_dup 1)))]
14493 "bsf{l}\t{%1, %0|%0, %1}"
14494 [(set_attr "prefix_0f" "1")])
14496 (define_expand "ffsdi2"
14498 [(set (match_operand:DI 0 "register_operand" "")
14499 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14500 (clobber (match_scratch:DI 2 ""))
14501 (clobber (reg:CC FLAGS_REG))])]
14502 "TARGET_64BIT && TARGET_CMOVE"
14505 (define_insn_and_split "*ffs_rex64"
14506 [(set (match_operand:DI 0 "register_operand" "=r")
14507 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14508 (clobber (match_scratch:DI 2 "=&r"))
14509 (clobber (reg:CC FLAGS_REG))]
14510 "TARGET_64BIT && TARGET_CMOVE"
14512 "&& reload_completed"
14513 [(set (match_dup 2) (const_int -1))
14514 (parallel [(set (reg:CCZ FLAGS_REG)
14515 (compare:CCZ (match_dup 1) (const_int 0)))
14516 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14517 (set (match_dup 0) (if_then_else:DI
14518 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14521 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14522 (clobber (reg:CC FLAGS_REG))])]
14525 (define_insn "*ffsdi_1"
14526 [(set (reg:CCZ FLAGS_REG)
14527 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14529 (set (match_operand:DI 0 "register_operand" "=r")
14530 (ctz:DI (match_dup 1)))]
14532 "bsf{q}\t{%1, %0|%0, %1}"
14533 [(set_attr "prefix_0f" "1")])
14535 (define_insn "ctzsi2"
14536 [(set (match_operand:SI 0 "register_operand" "=r")
14537 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14538 (clobber (reg:CC FLAGS_REG))]
14540 "bsf{l}\t{%1, %0|%0, %1}"
14541 [(set_attr "prefix_0f" "1")])
14543 (define_insn "ctzdi2"
14544 [(set (match_operand:DI 0 "register_operand" "=r")
14545 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14546 (clobber (reg:CC FLAGS_REG))]
14548 "bsf{q}\t{%1, %0|%0, %1}"
14549 [(set_attr "prefix_0f" "1")])
14551 (define_expand "clzsi2"
14553 [(set (match_operand:SI 0 "register_operand" "")
14554 (minus:SI (const_int 31)
14555 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14556 (clobber (reg:CC FLAGS_REG))])
14558 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14559 (clobber (reg:CC FLAGS_REG))])]
14563 (define_insn "*bsr"
14564 [(set (match_operand:SI 0 "register_operand" "=r")
14565 (minus:SI (const_int 31)
14566 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14567 (clobber (reg:CC FLAGS_REG))]
14569 "bsr{l}\t{%1, %0|%0, %1}"
14570 [(set_attr "prefix_0f" "1")])
14572 (define_expand "clzdi2"
14574 [(set (match_operand:DI 0 "register_operand" "")
14575 (minus:DI (const_int 63)
14576 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14577 (clobber (reg:CC FLAGS_REG))])
14579 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14580 (clobber (reg:CC FLAGS_REG))])]
14584 (define_insn "*bsr_rex64"
14585 [(set (match_operand:DI 0 "register_operand" "=r")
14586 (minus:DI (const_int 63)
14587 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14588 (clobber (reg:CC FLAGS_REG))]
14590 "bsr{q}\t{%1, %0|%0, %1}"
14591 [(set_attr "prefix_0f" "1")])
14593 ;; Thread-local storage patterns for ELF.
14595 ;; Note that these code sequences must appear exactly as shown
14596 ;; in order to allow linker relaxation.
14598 (define_insn "*tls_global_dynamic_32_gnu"
14599 [(set (match_operand:SI 0 "register_operand" "=a")
14600 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14601 (match_operand:SI 2 "tls_symbolic_operand" "")
14602 (match_operand:SI 3 "call_insn_operand" "")]
14604 (clobber (match_scratch:SI 4 "=d"))
14605 (clobber (match_scratch:SI 5 "=c"))
14606 (clobber (reg:CC FLAGS_REG))]
14607 "!TARGET_64BIT && TARGET_GNU_TLS"
14608 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14609 [(set_attr "type" "multi")
14610 (set_attr "length" "12")])
14612 (define_insn "*tls_global_dynamic_32_sun"
14613 [(set (match_operand:SI 0 "register_operand" "=a")
14614 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14615 (match_operand:SI 2 "tls_symbolic_operand" "")
14616 (match_operand:SI 3 "call_insn_operand" "")]
14618 (clobber (match_scratch:SI 4 "=d"))
14619 (clobber (match_scratch:SI 5 "=c"))
14620 (clobber (reg:CC FLAGS_REG))]
14621 "!TARGET_64BIT && TARGET_SUN_TLS"
14622 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14623 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14624 [(set_attr "type" "multi")
14625 (set_attr "length" "14")])
14627 (define_expand "tls_global_dynamic_32"
14628 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14631 (match_operand:SI 1 "tls_symbolic_operand" "")
14634 (clobber (match_scratch:SI 4 ""))
14635 (clobber (match_scratch:SI 5 ""))
14636 (clobber (reg:CC FLAGS_REG))])]
14640 operands[2] = pic_offset_table_rtx;
14643 operands[2] = gen_reg_rtx (Pmode);
14644 emit_insn (gen_set_got (operands[2]));
14646 if (TARGET_GNU2_TLS)
14648 emit_insn (gen_tls_dynamic_gnu2_32
14649 (operands[0], operands[1], operands[2]));
14652 operands[3] = ix86_tls_get_addr ();
14655 (define_insn "*tls_global_dynamic_64"
14656 [(set (match_operand:DI 0 "register_operand" "=a")
14657 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14658 (match_operand:DI 3 "" "")))
14659 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14662 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14663 [(set_attr "type" "multi")
14664 (set_attr "length" "16")])
14666 (define_expand "tls_global_dynamic_64"
14667 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14668 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14669 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14673 if (TARGET_GNU2_TLS)
14675 emit_insn (gen_tls_dynamic_gnu2_64
14676 (operands[0], operands[1]));
14679 operands[2] = ix86_tls_get_addr ();
14682 (define_insn "*tls_local_dynamic_base_32_gnu"
14683 [(set (match_operand:SI 0 "register_operand" "=a")
14684 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14685 (match_operand:SI 2 "call_insn_operand" "")]
14686 UNSPEC_TLS_LD_BASE))
14687 (clobber (match_scratch:SI 3 "=d"))
14688 (clobber (match_scratch:SI 4 "=c"))
14689 (clobber (reg:CC FLAGS_REG))]
14690 "!TARGET_64BIT && TARGET_GNU_TLS"
14691 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14692 [(set_attr "type" "multi")
14693 (set_attr "length" "11")])
14695 (define_insn "*tls_local_dynamic_base_32_sun"
14696 [(set (match_operand:SI 0 "register_operand" "=a")
14697 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14698 (match_operand:SI 2 "call_insn_operand" "")]
14699 UNSPEC_TLS_LD_BASE))
14700 (clobber (match_scratch:SI 3 "=d"))
14701 (clobber (match_scratch:SI 4 "=c"))
14702 (clobber (reg:CC FLAGS_REG))]
14703 "!TARGET_64BIT && TARGET_SUN_TLS"
14704 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14705 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14706 [(set_attr "type" "multi")
14707 (set_attr "length" "13")])
14709 (define_expand "tls_local_dynamic_base_32"
14710 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14711 (unspec:SI [(match_dup 1) (match_dup 2)]
14712 UNSPEC_TLS_LD_BASE))
14713 (clobber (match_scratch:SI 3 ""))
14714 (clobber (match_scratch:SI 4 ""))
14715 (clobber (reg:CC FLAGS_REG))])]
14719 operands[1] = pic_offset_table_rtx;
14722 operands[1] = gen_reg_rtx (Pmode);
14723 emit_insn (gen_set_got (operands[1]));
14725 if (TARGET_GNU2_TLS)
14727 emit_insn (gen_tls_dynamic_gnu2_32
14728 (operands[0], ix86_tls_module_base (), operands[1]));
14731 operands[2] = ix86_tls_get_addr ();
14734 (define_insn "*tls_local_dynamic_base_64"
14735 [(set (match_operand:DI 0 "register_operand" "=a")
14736 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14737 (match_operand:DI 2 "" "")))
14738 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14740 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14741 [(set_attr "type" "multi")
14742 (set_attr "length" "12")])
14744 (define_expand "tls_local_dynamic_base_64"
14745 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14746 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14747 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14750 if (TARGET_GNU2_TLS)
14752 emit_insn (gen_tls_dynamic_gnu2_64
14753 (operands[0], ix86_tls_module_base ()));
14756 operands[1] = ix86_tls_get_addr ();
14759 ;; Local dynamic of a single variable is a lose. Show combine how
14760 ;; to convert that back to global dynamic.
14762 (define_insn_and_split "*tls_local_dynamic_32_once"
14763 [(set (match_operand:SI 0 "register_operand" "=a")
14764 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14765 (match_operand:SI 2 "call_insn_operand" "")]
14766 UNSPEC_TLS_LD_BASE)
14767 (const:SI (unspec:SI
14768 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14770 (clobber (match_scratch:SI 4 "=d"))
14771 (clobber (match_scratch:SI 5 "=c"))
14772 (clobber (reg:CC FLAGS_REG))]
14776 [(parallel [(set (match_dup 0)
14777 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14779 (clobber (match_dup 4))
14780 (clobber (match_dup 5))
14781 (clobber (reg:CC FLAGS_REG))])]
14784 ;; Load and add the thread base pointer from %gs:0.
14786 (define_insn "*load_tp_si"
14787 [(set (match_operand:SI 0 "register_operand" "=r")
14788 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14790 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14791 [(set_attr "type" "imov")
14792 (set_attr "modrm" "0")
14793 (set_attr "length" "7")
14794 (set_attr "memory" "load")
14795 (set_attr "imm_disp" "false")])
14797 (define_insn "*add_tp_si"
14798 [(set (match_operand:SI 0 "register_operand" "=r")
14799 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14800 (match_operand:SI 1 "register_operand" "0")))
14801 (clobber (reg:CC FLAGS_REG))]
14803 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14804 [(set_attr "type" "alu")
14805 (set_attr "modrm" "0")
14806 (set_attr "length" "7")
14807 (set_attr "memory" "load")
14808 (set_attr "imm_disp" "false")])
14810 (define_insn "*load_tp_di"
14811 [(set (match_operand:DI 0 "register_operand" "=r")
14812 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14814 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14815 [(set_attr "type" "imov")
14816 (set_attr "modrm" "0")
14817 (set_attr "length" "7")
14818 (set_attr "memory" "load")
14819 (set_attr "imm_disp" "false")])
14821 (define_insn "*add_tp_di"
14822 [(set (match_operand:DI 0 "register_operand" "=r")
14823 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14824 (match_operand:DI 1 "register_operand" "0")))
14825 (clobber (reg:CC FLAGS_REG))]
14827 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14828 [(set_attr "type" "alu")
14829 (set_attr "modrm" "0")
14830 (set_attr "length" "7")
14831 (set_attr "memory" "load")
14832 (set_attr "imm_disp" "false")])
14834 ;; GNU2 TLS patterns can be split.
14836 (define_expand "tls_dynamic_gnu2_32"
14837 [(set (match_dup 3)
14838 (plus:SI (match_operand:SI 2 "register_operand" "")
14840 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14843 [(set (match_operand:SI 0 "register_operand" "")
14844 (unspec:SI [(match_dup 1) (match_dup 3)
14845 (match_dup 2) (reg:SI SP_REG)]
14847 (clobber (reg:CC FLAGS_REG))])]
14848 "!TARGET_64BIT && TARGET_GNU2_TLS"
14850 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14851 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14854 (define_insn "*tls_dynamic_lea_32"
14855 [(set (match_operand:SI 0 "register_operand" "=r")
14856 (plus:SI (match_operand:SI 1 "register_operand" "b")
14858 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14859 UNSPEC_TLSDESC))))]
14860 "!TARGET_64BIT && TARGET_GNU2_TLS"
14861 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14862 [(set_attr "type" "lea")
14863 (set_attr "mode" "SI")
14864 (set_attr "length" "6")
14865 (set_attr "length_address" "4")])
14867 (define_insn "*tls_dynamic_call_32"
14868 [(set (match_operand:SI 0 "register_operand" "=a")
14869 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14870 (match_operand:SI 2 "register_operand" "0")
14871 ;; we have to make sure %ebx still points to the GOT
14872 (match_operand:SI 3 "register_operand" "b")
14875 (clobber (reg:CC FLAGS_REG))]
14876 "!TARGET_64BIT && TARGET_GNU2_TLS"
14877 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14878 [(set_attr "type" "call")
14879 (set_attr "length" "2")
14880 (set_attr "length_address" "0")])
14882 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14883 [(set (match_operand:SI 0 "register_operand" "=&a")
14885 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14886 (match_operand:SI 4 "" "")
14887 (match_operand:SI 2 "register_operand" "b")
14890 (const:SI (unspec:SI
14891 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14893 (clobber (reg:CC FLAGS_REG))]
14894 "!TARGET_64BIT && TARGET_GNU2_TLS"
14897 [(set (match_dup 0) (match_dup 5))]
14899 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14900 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14903 (define_expand "tls_dynamic_gnu2_64"
14904 [(set (match_dup 2)
14905 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14908 [(set (match_operand:DI 0 "register_operand" "")
14909 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14911 (clobber (reg:CC FLAGS_REG))])]
14912 "TARGET_64BIT && TARGET_GNU2_TLS"
14914 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14915 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14918 (define_insn "*tls_dynamic_lea_64"
14919 [(set (match_operand:DI 0 "register_operand" "=r")
14920 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14922 "TARGET_64BIT && TARGET_GNU2_TLS"
14923 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14924 [(set_attr "type" "lea")
14925 (set_attr "mode" "DI")
14926 (set_attr "length" "7")
14927 (set_attr "length_address" "4")])
14929 (define_insn "*tls_dynamic_call_64"
14930 [(set (match_operand:DI 0 "register_operand" "=a")
14931 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14932 (match_operand:DI 2 "register_operand" "0")
14935 (clobber (reg:CC FLAGS_REG))]
14936 "TARGET_64BIT && TARGET_GNU2_TLS"
14937 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14938 [(set_attr "type" "call")
14939 (set_attr "length" "2")
14940 (set_attr "length_address" "0")])
14942 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14943 [(set (match_operand:DI 0 "register_operand" "=&a")
14945 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14946 (match_operand:DI 3 "" "")
14949 (const:DI (unspec:DI
14950 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14952 (clobber (reg:CC FLAGS_REG))]
14953 "TARGET_64BIT && TARGET_GNU2_TLS"
14956 [(set (match_dup 0) (match_dup 4))]
14958 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14959 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14964 ;; These patterns match the binary 387 instructions for addM3, subM3,
14965 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14966 ;; SFmode. The first is the normal insn, the second the same insn but
14967 ;; with one operand a conversion, and the third the same insn but with
14968 ;; the other operand a conversion. The conversion may be SFmode or
14969 ;; SImode if the target mode DFmode, but only SImode if the target mode
14972 ;; Gcc is slightly more smart about handling normal two address instructions
14973 ;; so use special patterns for add and mull.
14975 (define_insn "*fop_sf_comm_mixed"
14976 [(set (match_operand:SF 0 "register_operand" "=f,x")
14977 (match_operator:SF 3 "binary_fp_operator"
14978 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14979 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14980 "TARGET_MIX_SSE_I387
14981 && COMMUTATIVE_ARITH_P (operands[3])
14982 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14983 "* return output_387_binary_op (insn, operands);"
14984 [(set (attr "type")
14985 (if_then_else (eq_attr "alternative" "1")
14986 (if_then_else (match_operand:SF 3 "mult_operator" "")
14987 (const_string "ssemul")
14988 (const_string "sseadd"))
14989 (if_then_else (match_operand:SF 3 "mult_operator" "")
14990 (const_string "fmul")
14991 (const_string "fop"))))
14992 (set_attr "mode" "SF")])
14994 (define_insn "*fop_sf_comm_sse"
14995 [(set (match_operand:SF 0 "register_operand" "=x")
14996 (match_operator:SF 3 "binary_fp_operator"
14997 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14998 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15000 && COMMUTATIVE_ARITH_P (operands[3])
15001 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15002 "* return output_387_binary_op (insn, operands);"
15003 [(set (attr "type")
15004 (if_then_else (match_operand:SF 3 "mult_operator" "")
15005 (const_string "ssemul")
15006 (const_string "sseadd")))
15007 (set_attr "mode" "SF")])
15009 (define_insn "*fop_sf_comm_i387"
15010 [(set (match_operand:SF 0 "register_operand" "=f")
15011 (match_operator:SF 3 "binary_fp_operator"
15012 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15013 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15015 && COMMUTATIVE_ARITH_P (operands[3])
15016 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15017 "* return output_387_binary_op (insn, operands);"
15018 [(set (attr "type")
15019 (if_then_else (match_operand:SF 3 "mult_operator" "")
15020 (const_string "fmul")
15021 (const_string "fop")))
15022 (set_attr "mode" "SF")])
15024 (define_insn "*fop_sf_1_mixed"
15025 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15026 (match_operator:SF 3 "binary_fp_operator"
15027 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15028 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15029 "TARGET_MIX_SSE_I387
15030 && !COMMUTATIVE_ARITH_P (operands[3])
15031 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15032 "* return output_387_binary_op (insn, operands);"
15033 [(set (attr "type")
15034 (cond [(and (eq_attr "alternative" "2")
15035 (match_operand:SF 3 "mult_operator" ""))
15036 (const_string "ssemul")
15037 (and (eq_attr "alternative" "2")
15038 (match_operand:SF 3 "div_operator" ""))
15039 (const_string "ssediv")
15040 (eq_attr "alternative" "2")
15041 (const_string "sseadd")
15042 (match_operand:SF 3 "mult_operator" "")
15043 (const_string "fmul")
15044 (match_operand:SF 3 "div_operator" "")
15045 (const_string "fdiv")
15047 (const_string "fop")))
15048 (set_attr "mode" "SF")])
15050 (define_insn "*fop_sf_1_sse"
15051 [(set (match_operand:SF 0 "register_operand" "=x")
15052 (match_operator:SF 3 "binary_fp_operator"
15053 [(match_operand:SF 1 "register_operand" "0")
15054 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15056 && !COMMUTATIVE_ARITH_P (operands[3])"
15057 "* return output_387_binary_op (insn, operands);"
15058 [(set (attr "type")
15059 (cond [(match_operand:SF 3 "mult_operator" "")
15060 (const_string "ssemul")
15061 (match_operand:SF 3 "div_operator" "")
15062 (const_string "ssediv")
15064 (const_string "sseadd")))
15065 (set_attr "mode" "SF")])
15067 ;; This pattern is not fully shadowed by the pattern above.
15068 (define_insn "*fop_sf_1_i387"
15069 [(set (match_operand:SF 0 "register_operand" "=f,f")
15070 (match_operator:SF 3 "binary_fp_operator"
15071 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15072 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15073 "TARGET_80387 && !TARGET_SSE_MATH
15074 && !COMMUTATIVE_ARITH_P (operands[3])
15075 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15076 "* return output_387_binary_op (insn, operands);"
15077 [(set (attr "type")
15078 (cond [(match_operand:SF 3 "mult_operator" "")
15079 (const_string "fmul")
15080 (match_operand:SF 3 "div_operator" "")
15081 (const_string "fdiv")
15083 (const_string "fop")))
15084 (set_attr "mode" "SF")])
15086 ;; ??? Add SSE splitters for these!
15087 (define_insn "*fop_sf_2<mode>_i387"
15088 [(set (match_operand:SF 0 "register_operand" "=f,f")
15089 (match_operator:SF 3 "binary_fp_operator"
15090 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15091 (match_operand:SF 2 "register_operand" "0,0")]))]
15092 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15093 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15094 [(set (attr "type")
15095 (cond [(match_operand:SF 3 "mult_operator" "")
15096 (const_string "fmul")
15097 (match_operand:SF 3 "div_operator" "")
15098 (const_string "fdiv")
15100 (const_string "fop")))
15101 (set_attr "fp_int_src" "true")
15102 (set_attr "mode" "<MODE>")])
15104 (define_insn "*fop_sf_3<mode>_i387"
15105 [(set (match_operand:SF 0 "register_operand" "=f,f")
15106 (match_operator:SF 3 "binary_fp_operator"
15107 [(match_operand:SF 1 "register_operand" "0,0")
15108 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15109 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15110 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15111 [(set (attr "type")
15112 (cond [(match_operand:SF 3 "mult_operator" "")
15113 (const_string "fmul")
15114 (match_operand:SF 3 "div_operator" "")
15115 (const_string "fdiv")
15117 (const_string "fop")))
15118 (set_attr "fp_int_src" "true")
15119 (set_attr "mode" "<MODE>")])
15121 (define_insn "*fop_df_comm_mixed"
15122 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15123 (match_operator:DF 3 "binary_fp_operator"
15124 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15125 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15126 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15127 && COMMUTATIVE_ARITH_P (operands[3])
15128 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15129 "* return output_387_binary_op (insn, operands);"
15130 [(set (attr "type")
15131 (if_then_else (eq_attr "alternative" "1")
15132 (if_then_else (match_operand:DF 3 "mult_operator" "")
15133 (const_string "ssemul")
15134 (const_string "sseadd"))
15135 (if_then_else (match_operand:DF 3 "mult_operator" "")
15136 (const_string "fmul")
15137 (const_string "fop"))))
15138 (set_attr "mode" "DF")])
15140 (define_insn "*fop_df_comm_sse"
15141 [(set (match_operand:DF 0 "register_operand" "=Y")
15142 (match_operator:DF 3 "binary_fp_operator"
15143 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15144 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15145 "TARGET_SSE2 && TARGET_SSE_MATH
15146 && COMMUTATIVE_ARITH_P (operands[3])
15147 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15148 "* return output_387_binary_op (insn, operands);"
15149 [(set (attr "type")
15150 (if_then_else (match_operand:DF 3 "mult_operator" "")
15151 (const_string "ssemul")
15152 (const_string "sseadd")))
15153 (set_attr "mode" "DF")])
15155 (define_insn "*fop_df_comm_i387"
15156 [(set (match_operand:DF 0 "register_operand" "=f")
15157 (match_operator:DF 3 "binary_fp_operator"
15158 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15159 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15161 && COMMUTATIVE_ARITH_P (operands[3])
15162 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15163 "* return output_387_binary_op (insn, operands);"
15164 [(set (attr "type")
15165 (if_then_else (match_operand:DF 3 "mult_operator" "")
15166 (const_string "fmul")
15167 (const_string "fop")))
15168 (set_attr "mode" "DF")])
15170 (define_insn "*fop_df_1_mixed"
15171 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15172 (match_operator:DF 3 "binary_fp_operator"
15173 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15174 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15175 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15176 && !COMMUTATIVE_ARITH_P (operands[3])
15177 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15178 "* return output_387_binary_op (insn, operands);"
15179 [(set (attr "type")
15180 (cond [(and (eq_attr "alternative" "2")
15181 (match_operand:DF 3 "mult_operator" ""))
15182 (const_string "ssemul")
15183 (and (eq_attr "alternative" "2")
15184 (match_operand:DF 3 "div_operator" ""))
15185 (const_string "ssediv")
15186 (eq_attr "alternative" "2")
15187 (const_string "sseadd")
15188 (match_operand:DF 3 "mult_operator" "")
15189 (const_string "fmul")
15190 (match_operand:DF 3 "div_operator" "")
15191 (const_string "fdiv")
15193 (const_string "fop")))
15194 (set_attr "mode" "DF")])
15196 (define_insn "*fop_df_1_sse"
15197 [(set (match_operand:DF 0 "register_operand" "=Y")
15198 (match_operator:DF 3 "binary_fp_operator"
15199 [(match_operand:DF 1 "register_operand" "0")
15200 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15201 "TARGET_SSE2 && TARGET_SSE_MATH
15202 && !COMMUTATIVE_ARITH_P (operands[3])"
15203 "* return output_387_binary_op (insn, operands);"
15204 [(set_attr "mode" "DF")
15206 (cond [(match_operand:DF 3 "mult_operator" "")
15207 (const_string "ssemul")
15208 (match_operand:DF 3 "div_operator" "")
15209 (const_string "ssediv")
15211 (const_string "sseadd")))])
15213 ;; This pattern is not fully shadowed by the pattern above.
15214 (define_insn "*fop_df_1_i387"
15215 [(set (match_operand:DF 0 "register_operand" "=f,f")
15216 (match_operator:DF 3 "binary_fp_operator"
15217 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15218 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15219 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15220 && !COMMUTATIVE_ARITH_P (operands[3])
15221 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15222 "* return output_387_binary_op (insn, operands);"
15223 [(set (attr "type")
15224 (cond [(match_operand:DF 3 "mult_operator" "")
15225 (const_string "fmul")
15226 (match_operand:DF 3 "div_operator" "")
15227 (const_string "fdiv")
15229 (const_string "fop")))
15230 (set_attr "mode" "DF")])
15232 ;; ??? Add SSE splitters for these!
15233 (define_insn "*fop_df_2<mode>_i387"
15234 [(set (match_operand:DF 0 "register_operand" "=f,f")
15235 (match_operator:DF 3 "binary_fp_operator"
15236 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15237 (match_operand:DF 2 "register_operand" "0,0")]))]
15238 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15239 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15240 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15241 [(set (attr "type")
15242 (cond [(match_operand:DF 3 "mult_operator" "")
15243 (const_string "fmul")
15244 (match_operand:DF 3 "div_operator" "")
15245 (const_string "fdiv")
15247 (const_string "fop")))
15248 (set_attr "fp_int_src" "true")
15249 (set_attr "mode" "<MODE>")])
15251 (define_insn "*fop_df_3<mode>_i387"
15252 [(set (match_operand:DF 0 "register_operand" "=f,f")
15253 (match_operator:DF 3 "binary_fp_operator"
15254 [(match_operand:DF 1 "register_operand" "0,0")
15255 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15256 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15257 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15258 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15259 [(set (attr "type")
15260 (cond [(match_operand:DF 3 "mult_operator" "")
15261 (const_string "fmul")
15262 (match_operand:DF 3 "div_operator" "")
15263 (const_string "fdiv")
15265 (const_string "fop")))
15266 (set_attr "fp_int_src" "true")
15267 (set_attr "mode" "<MODE>")])
15269 (define_insn "*fop_df_4_i387"
15270 [(set (match_operand:DF 0 "register_operand" "=f,f")
15271 (match_operator:DF 3 "binary_fp_operator"
15272 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15273 (match_operand:DF 2 "register_operand" "0,f")]))]
15274 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15275 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15276 "* return output_387_binary_op (insn, operands);"
15277 [(set (attr "type")
15278 (cond [(match_operand:DF 3 "mult_operator" "")
15279 (const_string "fmul")
15280 (match_operand:DF 3 "div_operator" "")
15281 (const_string "fdiv")
15283 (const_string "fop")))
15284 (set_attr "mode" "SF")])
15286 (define_insn "*fop_df_5_i387"
15287 [(set (match_operand:DF 0 "register_operand" "=f,f")
15288 (match_operator:DF 3 "binary_fp_operator"
15289 [(match_operand:DF 1 "register_operand" "0,f")
15291 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15292 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15293 "* return output_387_binary_op (insn, operands);"
15294 [(set (attr "type")
15295 (cond [(match_operand:DF 3 "mult_operator" "")
15296 (const_string "fmul")
15297 (match_operand:DF 3 "div_operator" "")
15298 (const_string "fdiv")
15300 (const_string "fop")))
15301 (set_attr "mode" "SF")])
15303 (define_insn "*fop_df_6_i387"
15304 [(set (match_operand:DF 0 "register_operand" "=f,f")
15305 (match_operator:DF 3 "binary_fp_operator"
15307 (match_operand:SF 1 "register_operand" "0,f"))
15309 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15310 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15311 "* return output_387_binary_op (insn, operands);"
15312 [(set (attr "type")
15313 (cond [(match_operand:DF 3 "mult_operator" "")
15314 (const_string "fmul")
15315 (match_operand:DF 3 "div_operator" "")
15316 (const_string "fdiv")
15318 (const_string "fop")))
15319 (set_attr "mode" "SF")])
15321 (define_insn "*fop_xf_comm_i387"
15322 [(set (match_operand:XF 0 "register_operand" "=f")
15323 (match_operator:XF 3 "binary_fp_operator"
15324 [(match_operand:XF 1 "register_operand" "%0")
15325 (match_operand:XF 2 "register_operand" "f")]))]
15327 && COMMUTATIVE_ARITH_P (operands[3])"
15328 "* return output_387_binary_op (insn, operands);"
15329 [(set (attr "type")
15330 (if_then_else (match_operand:XF 3 "mult_operator" "")
15331 (const_string "fmul")
15332 (const_string "fop")))
15333 (set_attr "mode" "XF")])
15335 (define_insn "*fop_xf_1_i387"
15336 [(set (match_operand:XF 0 "register_operand" "=f,f")
15337 (match_operator:XF 3 "binary_fp_operator"
15338 [(match_operand:XF 1 "register_operand" "0,f")
15339 (match_operand:XF 2 "register_operand" "f,0")]))]
15341 && !COMMUTATIVE_ARITH_P (operands[3])"
15342 "* return output_387_binary_op (insn, operands);"
15343 [(set (attr "type")
15344 (cond [(match_operand:XF 3 "mult_operator" "")
15345 (const_string "fmul")
15346 (match_operand:XF 3 "div_operator" "")
15347 (const_string "fdiv")
15349 (const_string "fop")))
15350 (set_attr "mode" "XF")])
15352 (define_insn "*fop_xf_2<mode>_i387"
15353 [(set (match_operand:XF 0 "register_operand" "=f,f")
15354 (match_operator:XF 3 "binary_fp_operator"
15355 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15356 (match_operand:XF 2 "register_operand" "0,0")]))]
15357 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15358 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15359 [(set (attr "type")
15360 (cond [(match_operand:XF 3 "mult_operator" "")
15361 (const_string "fmul")
15362 (match_operand:XF 3 "div_operator" "")
15363 (const_string "fdiv")
15365 (const_string "fop")))
15366 (set_attr "fp_int_src" "true")
15367 (set_attr "mode" "<MODE>")])
15369 (define_insn "*fop_xf_3<mode>_i387"
15370 [(set (match_operand:XF 0 "register_operand" "=f,f")
15371 (match_operator:XF 3 "binary_fp_operator"
15372 [(match_operand:XF 1 "register_operand" "0,0")
15373 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15374 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15375 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15376 [(set (attr "type")
15377 (cond [(match_operand:XF 3 "mult_operator" "")
15378 (const_string "fmul")
15379 (match_operand:XF 3 "div_operator" "")
15380 (const_string "fdiv")
15382 (const_string "fop")))
15383 (set_attr "fp_int_src" "true")
15384 (set_attr "mode" "<MODE>")])
15386 (define_insn "*fop_xf_4_i387"
15387 [(set (match_operand:XF 0 "register_operand" "=f,f")
15388 (match_operator:XF 3 "binary_fp_operator"
15389 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15390 (match_operand:XF 2 "register_operand" "0,f")]))]
15392 "* return output_387_binary_op (insn, operands);"
15393 [(set (attr "type")
15394 (cond [(match_operand:XF 3 "mult_operator" "")
15395 (const_string "fmul")
15396 (match_operand:XF 3 "div_operator" "")
15397 (const_string "fdiv")
15399 (const_string "fop")))
15400 (set_attr "mode" "SF")])
15402 (define_insn "*fop_xf_5_i387"
15403 [(set (match_operand:XF 0 "register_operand" "=f,f")
15404 (match_operator:XF 3 "binary_fp_operator"
15405 [(match_operand:XF 1 "register_operand" "0,f")
15407 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15409 "* return output_387_binary_op (insn, operands);"
15410 [(set (attr "type")
15411 (cond [(match_operand:XF 3 "mult_operator" "")
15412 (const_string "fmul")
15413 (match_operand:XF 3 "div_operator" "")
15414 (const_string "fdiv")
15416 (const_string "fop")))
15417 (set_attr "mode" "SF")])
15419 (define_insn "*fop_xf_6_i387"
15420 [(set (match_operand:XF 0 "register_operand" "=f,f")
15421 (match_operator:XF 3 "binary_fp_operator"
15423 (match_operand 1 "register_operand" "0,f"))
15425 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15427 "* return output_387_binary_op (insn, operands);"
15428 [(set (attr "type")
15429 (cond [(match_operand:XF 3 "mult_operator" "")
15430 (const_string "fmul")
15431 (match_operand:XF 3 "div_operator" "")
15432 (const_string "fdiv")
15434 (const_string "fop")))
15435 (set_attr "mode" "SF")])
15438 [(set (match_operand 0 "register_operand" "")
15439 (match_operator 3 "binary_fp_operator"
15440 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15441 (match_operand 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[1]), operands[1]);
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[1]));
15458 [(set (match_operand 0 "register_operand" "")
15459 (match_operator 3 "binary_fp_operator"
15460 [(match_operand 1 "register_operand" "")
15461 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15462 "TARGET_80387 && reload_completed
15463 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15466 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15467 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15468 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15469 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15470 GET_MODE (operands[3]),
15473 ix86_free_from_memory (GET_MODE (operands[2]));
15477 ;; FPU special functions.
15479 (define_expand "sqrtsf2"
15480 [(set (match_operand:SF 0 "register_operand" "")
15481 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15482 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15484 if (!TARGET_SSE_MATH)
15485 operands[1] = force_reg (SFmode, operands[1]);
15488 (define_insn "*sqrtsf2_mixed"
15489 [(set (match_operand:SF 0 "register_operand" "=f,x")
15490 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15491 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15494 sqrtss\t{%1, %0|%0, %1}"
15495 [(set_attr "type" "fpspc,sse")
15496 (set_attr "mode" "SF,SF")
15497 (set_attr "athlon_decode" "direct,*")])
15499 (define_insn "*sqrtsf2_sse"
15500 [(set (match_operand:SF 0 "register_operand" "=x")
15501 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15503 "sqrtss\t{%1, %0|%0, %1}"
15504 [(set_attr "type" "sse")
15505 (set_attr "mode" "SF")
15506 (set_attr "athlon_decode" "*")])
15508 (define_insn "*sqrtsf2_i387"
15509 [(set (match_operand:SF 0 "register_operand" "=f")
15510 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15511 "TARGET_USE_FANCY_MATH_387"
15513 [(set_attr "type" "fpspc")
15514 (set_attr "mode" "SF")
15515 (set_attr "athlon_decode" "direct")])
15517 (define_expand "sqrtdf2"
15518 [(set (match_operand:DF 0 "register_operand" "")
15519 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15520 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15522 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15523 operands[1] = force_reg (DFmode, operands[1]);
15526 (define_insn "*sqrtdf2_mixed"
15527 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15528 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15529 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15532 sqrtsd\t{%1, %0|%0, %1}"
15533 [(set_attr "type" "fpspc,sse")
15534 (set_attr "mode" "DF,DF")
15535 (set_attr "athlon_decode" "direct,*")])
15537 (define_insn "*sqrtdf2_sse"
15538 [(set (match_operand:DF 0 "register_operand" "=Y")
15539 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15540 "TARGET_SSE2 && TARGET_SSE_MATH"
15541 "sqrtsd\t{%1, %0|%0, %1}"
15542 [(set_attr "type" "sse")
15543 (set_attr "mode" "DF")
15544 (set_attr "athlon_decode" "*")])
15546 (define_insn "*sqrtdf2_i387"
15547 [(set (match_operand:DF 0 "register_operand" "=f")
15548 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15549 "TARGET_USE_FANCY_MATH_387"
15551 [(set_attr "type" "fpspc")
15552 (set_attr "mode" "DF")
15553 (set_attr "athlon_decode" "direct")])
15555 (define_insn "*sqrtextendsfdf2_i387"
15556 [(set (match_operand:DF 0 "register_operand" "=f")
15557 (sqrt:DF (float_extend:DF
15558 (match_operand:SF 1 "register_operand" "0"))))]
15559 "TARGET_USE_FANCY_MATH_387
15560 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15562 [(set_attr "type" "fpspc")
15563 (set_attr "mode" "DF")
15564 (set_attr "athlon_decode" "direct")])
15566 (define_insn "sqrtxf2"
15567 [(set (match_operand:XF 0 "register_operand" "=f")
15568 (sqrt:XF (match_operand:XF 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 "*sqrtextendsfxf2_i387"
15576 [(set (match_operand:XF 0 "register_operand" "=f")
15577 (sqrt:XF (float_extend:XF
15578 (match_operand:SF 1 "register_operand" "0"))))]
15579 "TARGET_USE_FANCY_MATH_387"
15581 [(set_attr "type" "fpspc")
15582 (set_attr "mode" "XF")
15583 (set_attr "athlon_decode" "direct")])
15585 (define_insn "*sqrtextenddfxf2_i387"
15586 [(set (match_operand:XF 0 "register_operand" "=f")
15587 (sqrt:XF (float_extend:XF
15588 (match_operand:DF 1 "register_operand" "0"))))]
15589 "TARGET_USE_FANCY_MATH_387"
15591 [(set_attr "type" "fpspc")
15592 (set_attr "mode" "XF")
15593 (set_attr "athlon_decode" "direct")])
15595 (define_insn "fpremxf4"
15596 [(set (match_operand:XF 0 "register_operand" "=f")
15597 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15598 (match_operand:XF 3 "register_operand" "1")]
15600 (set (match_operand:XF 1 "register_operand" "=u")
15601 (unspec:XF [(match_dup 2) (match_dup 3)]
15603 (set (reg:CCFP FPSR_REG)
15604 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15605 "TARGET_USE_FANCY_MATH_387
15606 && flag_unsafe_math_optimizations"
15608 [(set_attr "type" "fpspc")
15609 (set_attr "mode" "XF")])
15611 (define_expand "fmodsf3"
15612 [(use (match_operand:SF 0 "register_operand" ""))
15613 (use (match_operand:SF 1 "register_operand" ""))
15614 (use (match_operand:SF 2 "register_operand" ""))]
15615 "TARGET_USE_FANCY_MATH_387
15616 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15617 && flag_unsafe_math_optimizations"
15619 rtx label = gen_label_rtx ();
15621 rtx op1 = gen_reg_rtx (XFmode);
15622 rtx op2 = gen_reg_rtx (XFmode);
15624 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15625 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15627 emit_label (label);
15629 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15630 ix86_emit_fp_unordered_jump (label);
15632 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15636 (define_expand "fmoddf3"
15637 [(use (match_operand:DF 0 "register_operand" ""))
15638 (use (match_operand:DF 1 "register_operand" ""))
15639 (use (match_operand:DF 2 "register_operand" ""))]
15640 "TARGET_USE_FANCY_MATH_387
15641 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15642 && flag_unsafe_math_optimizations"
15644 rtx label = gen_label_rtx ();
15646 rtx op1 = gen_reg_rtx (XFmode);
15647 rtx op2 = gen_reg_rtx (XFmode);
15649 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15650 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15652 emit_label (label);
15654 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15655 ix86_emit_fp_unordered_jump (label);
15657 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15661 (define_expand "fmodxf3"
15662 [(use (match_operand:XF 0 "register_operand" ""))
15663 (use (match_operand:XF 1 "register_operand" ""))
15664 (use (match_operand:XF 2 "register_operand" ""))]
15665 "TARGET_USE_FANCY_MATH_387
15666 && flag_unsafe_math_optimizations"
15668 rtx label = gen_label_rtx ();
15670 emit_label (label);
15672 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15673 operands[1], operands[2]));
15674 ix86_emit_fp_unordered_jump (label);
15676 emit_move_insn (operands[0], operands[1]);
15680 (define_insn "fprem1xf4"
15681 [(set (match_operand:XF 0 "register_operand" "=f")
15682 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15683 (match_operand:XF 3 "register_operand" "1")]
15685 (set (match_operand:XF 1 "register_operand" "=u")
15686 (unspec:XF [(match_dup 2) (match_dup 3)]
15688 (set (reg:CCFP FPSR_REG)
15689 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15690 "TARGET_USE_FANCY_MATH_387
15691 && flag_unsafe_math_optimizations"
15693 [(set_attr "type" "fpspc")
15694 (set_attr "mode" "XF")])
15696 (define_expand "dremsf3"
15697 [(use (match_operand:SF 0 "register_operand" ""))
15698 (use (match_operand:SF 1 "register_operand" ""))
15699 (use (match_operand:SF 2 "register_operand" ""))]
15700 "TARGET_USE_FANCY_MATH_387
15701 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15702 && flag_unsafe_math_optimizations"
15704 rtx label = gen_label_rtx ();
15706 rtx op1 = gen_reg_rtx (XFmode);
15707 rtx op2 = gen_reg_rtx (XFmode);
15709 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15710 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15712 emit_label (label);
15714 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15715 ix86_emit_fp_unordered_jump (label);
15717 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15721 (define_expand "dremdf3"
15722 [(use (match_operand:DF 0 "register_operand" ""))
15723 (use (match_operand:DF 1 "register_operand" ""))
15724 (use (match_operand:DF 2 "register_operand" ""))]
15725 "TARGET_USE_FANCY_MATH_387
15726 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15727 && flag_unsafe_math_optimizations"
15729 rtx label = gen_label_rtx ();
15731 rtx op1 = gen_reg_rtx (XFmode);
15732 rtx op2 = gen_reg_rtx (XFmode);
15734 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15735 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15737 emit_label (label);
15739 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15740 ix86_emit_fp_unordered_jump (label);
15742 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15746 (define_expand "dremxf3"
15747 [(use (match_operand:XF 0 "register_operand" ""))
15748 (use (match_operand:XF 1 "register_operand" ""))
15749 (use (match_operand:XF 2 "register_operand" ""))]
15750 "TARGET_USE_FANCY_MATH_387
15751 && flag_unsafe_math_optimizations"
15753 rtx label = gen_label_rtx ();
15755 emit_label (label);
15757 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15758 operands[1], operands[2]));
15759 ix86_emit_fp_unordered_jump (label);
15761 emit_move_insn (operands[0], operands[1]);
15765 (define_insn "*sindf2"
15766 [(set (match_operand:DF 0 "register_operand" "=f")
15767 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15768 "TARGET_USE_FANCY_MATH_387
15769 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15770 && flag_unsafe_math_optimizations"
15772 [(set_attr "type" "fpspc")
15773 (set_attr "mode" "DF")])
15775 (define_insn "*sinsf2"
15776 [(set (match_operand:SF 0 "register_operand" "=f")
15777 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15778 "TARGET_USE_FANCY_MATH_387
15779 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15780 && flag_unsafe_math_optimizations"
15782 [(set_attr "type" "fpspc")
15783 (set_attr "mode" "SF")])
15785 (define_insn "*sinextendsfdf2"
15786 [(set (match_operand:DF 0 "register_operand" "=f")
15787 (unspec:DF [(float_extend:DF
15788 (match_operand:SF 1 "register_operand" "0"))]
15790 "TARGET_USE_FANCY_MATH_387
15791 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15792 && flag_unsafe_math_optimizations"
15794 [(set_attr "type" "fpspc")
15795 (set_attr "mode" "DF")])
15797 (define_insn "*sinxf2"
15798 [(set (match_operand:XF 0 "register_operand" "=f")
15799 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15800 "TARGET_USE_FANCY_MATH_387
15801 && flag_unsafe_math_optimizations"
15803 [(set_attr "type" "fpspc")
15804 (set_attr "mode" "XF")])
15806 (define_insn "*cosdf2"
15807 [(set (match_operand:DF 0 "register_operand" "=f")
15808 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15809 "TARGET_USE_FANCY_MATH_387
15810 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15811 && flag_unsafe_math_optimizations"
15813 [(set_attr "type" "fpspc")
15814 (set_attr "mode" "DF")])
15816 (define_insn "*cossf2"
15817 [(set (match_operand:SF 0 "register_operand" "=f")
15818 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15819 "TARGET_USE_FANCY_MATH_387
15820 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15821 && flag_unsafe_math_optimizations"
15823 [(set_attr "type" "fpspc")
15824 (set_attr "mode" "SF")])
15826 (define_insn "*cosextendsfdf2"
15827 [(set (match_operand:DF 0 "register_operand" "=f")
15828 (unspec:DF [(float_extend:DF
15829 (match_operand:SF 1 "register_operand" "0"))]
15831 "TARGET_USE_FANCY_MATH_387
15832 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15833 && flag_unsafe_math_optimizations"
15835 [(set_attr "type" "fpspc")
15836 (set_attr "mode" "DF")])
15838 (define_insn "*cosxf2"
15839 [(set (match_operand:XF 0 "register_operand" "=f")
15840 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15841 "TARGET_USE_FANCY_MATH_387
15842 && flag_unsafe_math_optimizations"
15844 [(set_attr "type" "fpspc")
15845 (set_attr "mode" "XF")])
15847 ;; With sincos pattern defined, sin and cos builtin function will be
15848 ;; expanded to sincos pattern with one of its outputs left unused.
15849 ;; Cse pass will detected, if two sincos patterns can be combined,
15850 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15851 ;; depending on the unused output.
15853 (define_insn "sincosdf3"
15854 [(set (match_operand:DF 0 "register_operand" "=f")
15855 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15856 UNSPEC_SINCOS_COS))
15857 (set (match_operand:DF 1 "register_operand" "=u")
15858 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15859 "TARGET_USE_FANCY_MATH_387
15860 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15861 && flag_unsafe_math_optimizations"
15863 [(set_attr "type" "fpspc")
15864 (set_attr "mode" "DF")])
15867 [(set (match_operand:DF 0 "register_operand" "")
15868 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15869 UNSPEC_SINCOS_COS))
15870 (set (match_operand:DF 1 "register_operand" "")
15871 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15872 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15873 && !reload_completed && !reload_in_progress"
15874 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15878 [(set (match_operand:DF 0 "register_operand" "")
15879 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15880 UNSPEC_SINCOS_COS))
15881 (set (match_operand:DF 1 "register_operand" "")
15882 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15883 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15884 && !reload_completed && !reload_in_progress"
15885 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15888 (define_insn "sincossf3"
15889 [(set (match_operand:SF 0 "register_operand" "=f")
15890 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15891 UNSPEC_SINCOS_COS))
15892 (set (match_operand:SF 1 "register_operand" "=u")
15893 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15894 "TARGET_USE_FANCY_MATH_387
15895 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15896 && flag_unsafe_math_optimizations"
15898 [(set_attr "type" "fpspc")
15899 (set_attr "mode" "SF")])
15902 [(set (match_operand:SF 0 "register_operand" "")
15903 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15904 UNSPEC_SINCOS_COS))
15905 (set (match_operand:SF 1 "register_operand" "")
15906 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15907 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15908 && !reload_completed && !reload_in_progress"
15909 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15913 [(set (match_operand:SF 0 "register_operand" "")
15914 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15915 UNSPEC_SINCOS_COS))
15916 (set (match_operand:SF 1 "register_operand" "")
15917 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15918 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15919 && !reload_completed && !reload_in_progress"
15920 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15923 (define_insn "*sincosextendsfdf3"
15924 [(set (match_operand:DF 0 "register_operand" "=f")
15925 (unspec:DF [(float_extend:DF
15926 (match_operand:SF 2 "register_operand" "0"))]
15927 UNSPEC_SINCOS_COS))
15928 (set (match_operand:DF 1 "register_operand" "=u")
15929 (unspec:DF [(float_extend:DF
15930 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15931 "TARGET_USE_FANCY_MATH_387
15932 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15933 && flag_unsafe_math_optimizations"
15935 [(set_attr "type" "fpspc")
15936 (set_attr "mode" "DF")])
15939 [(set (match_operand:DF 0 "register_operand" "")
15940 (unspec:DF [(float_extend:DF
15941 (match_operand:SF 2 "register_operand" ""))]
15942 UNSPEC_SINCOS_COS))
15943 (set (match_operand:DF 1 "register_operand" "")
15944 (unspec:DF [(float_extend:DF
15945 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15946 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15947 && !reload_completed && !reload_in_progress"
15948 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15949 (match_dup 2))] UNSPEC_SIN))]
15953 [(set (match_operand:DF 0 "register_operand" "")
15954 (unspec:DF [(float_extend:DF
15955 (match_operand:SF 2 "register_operand" ""))]
15956 UNSPEC_SINCOS_COS))
15957 (set (match_operand:DF 1 "register_operand" "")
15958 (unspec:DF [(float_extend:DF
15959 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15960 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15961 && !reload_completed && !reload_in_progress"
15962 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15963 (match_dup 2))] UNSPEC_COS))]
15966 (define_insn "sincosxf3"
15967 [(set (match_operand:XF 0 "register_operand" "=f")
15968 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15969 UNSPEC_SINCOS_COS))
15970 (set (match_operand:XF 1 "register_operand" "=u")
15971 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15972 "TARGET_USE_FANCY_MATH_387
15973 && flag_unsafe_math_optimizations"
15975 [(set_attr "type" "fpspc")
15976 (set_attr "mode" "XF")])
15979 [(set (match_operand:XF 0 "register_operand" "")
15980 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15981 UNSPEC_SINCOS_COS))
15982 (set (match_operand:XF 1 "register_operand" "")
15983 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15984 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15985 && !reload_completed && !reload_in_progress"
15986 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15990 [(set (match_operand:XF 0 "register_operand" "")
15991 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15992 UNSPEC_SINCOS_COS))
15993 (set (match_operand:XF 1 "register_operand" "")
15994 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15995 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15996 && !reload_completed && !reload_in_progress"
15997 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16000 (define_insn "*tandf3_1"
16001 [(set (match_operand:DF 0 "register_operand" "=f")
16002 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16004 (set (match_operand:DF 1 "register_operand" "=u")
16005 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16006 "TARGET_USE_FANCY_MATH_387
16007 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16008 && flag_unsafe_math_optimizations"
16010 [(set_attr "type" "fpspc")
16011 (set_attr "mode" "DF")])
16013 ;; optimize sequence: fptan
16016 ;; into fptan insn.
16019 [(parallel[(set (match_operand:DF 0 "register_operand" "")
16020 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16022 (set (match_operand:DF 1 "register_operand" "")
16023 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16025 (match_operand:DF 3 "immediate_operand" ""))]
16026 "standard_80387_constant_p (operands[3]) == 2"
16027 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16028 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16031 (define_expand "tandf2"
16032 [(parallel [(set (match_dup 2)
16033 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16035 (set (match_operand:DF 0 "register_operand" "")
16036 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16037 "TARGET_USE_FANCY_MATH_387
16038 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16039 && flag_unsafe_math_optimizations"
16041 operands[2] = gen_reg_rtx (DFmode);
16044 (define_insn "*tansf3_1"
16045 [(set (match_operand:SF 0 "register_operand" "=f")
16046 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16048 (set (match_operand:SF 1 "register_operand" "=u")
16049 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16050 "TARGET_USE_FANCY_MATH_387
16051 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16052 && flag_unsafe_math_optimizations"
16054 [(set_attr "type" "fpspc")
16055 (set_attr "mode" "SF")])
16057 ;; optimize sequence: fptan
16060 ;; into fptan insn.
16063 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16064 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16066 (set (match_operand:SF 1 "register_operand" "")
16067 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16069 (match_operand:SF 3 "immediate_operand" ""))]
16070 "standard_80387_constant_p (operands[3]) == 2"
16071 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16072 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16075 (define_expand "tansf2"
16076 [(parallel [(set (match_dup 2)
16077 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16079 (set (match_operand:SF 0 "register_operand" "")
16080 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16081 "TARGET_USE_FANCY_MATH_387
16082 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16083 && flag_unsafe_math_optimizations"
16085 operands[2] = gen_reg_rtx (SFmode);
16088 (define_insn "*tanxf3_1"
16089 [(set (match_operand:XF 0 "register_operand" "=f")
16090 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16092 (set (match_operand:XF 1 "register_operand" "=u")
16093 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16094 "TARGET_USE_FANCY_MATH_387
16095 && flag_unsafe_math_optimizations"
16097 [(set_attr "type" "fpspc")
16098 (set_attr "mode" "XF")])
16100 ;; optimize sequence: fptan
16103 ;; into fptan insn.
16106 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16107 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16109 (set (match_operand:XF 1 "register_operand" "")
16110 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16112 (match_operand:XF 3 "immediate_operand" ""))]
16113 "standard_80387_constant_p (operands[3]) == 2"
16114 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16115 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16118 (define_expand "tanxf2"
16119 [(parallel [(set (match_dup 2)
16120 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16122 (set (match_operand:XF 0 "register_operand" "")
16123 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16124 "TARGET_USE_FANCY_MATH_387
16125 && flag_unsafe_math_optimizations"
16127 operands[2] = gen_reg_rtx (XFmode);
16130 (define_insn "atan2df3_1"
16131 [(set (match_operand:DF 0 "register_operand" "=f")
16132 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16133 (match_operand:DF 1 "register_operand" "u")]
16135 (clobber (match_scratch:DF 3 "=1"))]
16136 "TARGET_USE_FANCY_MATH_387
16137 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16138 && flag_unsafe_math_optimizations"
16140 [(set_attr "type" "fpspc")
16141 (set_attr "mode" "DF")])
16143 (define_expand "atan2df3"
16144 [(use (match_operand:DF 0 "register_operand" ""))
16145 (use (match_operand:DF 2 "register_operand" ""))
16146 (use (match_operand:DF 1 "register_operand" ""))]
16147 "TARGET_USE_FANCY_MATH_387
16148 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16149 && flag_unsafe_math_optimizations"
16151 rtx copy = gen_reg_rtx (DFmode);
16152 emit_move_insn (copy, operands[1]);
16153 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16157 (define_expand "atandf2"
16158 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16159 (unspec:DF [(match_dup 2)
16160 (match_operand:DF 1 "register_operand" "")]
16162 (clobber (match_scratch:DF 3 ""))])]
16163 "TARGET_USE_FANCY_MATH_387
16164 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16165 && flag_unsafe_math_optimizations"
16167 operands[2] = gen_reg_rtx (DFmode);
16168 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16171 (define_insn "atan2sf3_1"
16172 [(set (match_operand:SF 0 "register_operand" "=f")
16173 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16174 (match_operand:SF 1 "register_operand" "u")]
16176 (clobber (match_scratch:SF 3 "=1"))]
16177 "TARGET_USE_FANCY_MATH_387
16178 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16179 && flag_unsafe_math_optimizations"
16181 [(set_attr "type" "fpspc")
16182 (set_attr "mode" "SF")])
16184 (define_expand "atan2sf3"
16185 [(use (match_operand:SF 0 "register_operand" ""))
16186 (use (match_operand:SF 2 "register_operand" ""))
16187 (use (match_operand:SF 1 "register_operand" ""))]
16188 "TARGET_USE_FANCY_MATH_387
16189 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16190 && flag_unsafe_math_optimizations"
16192 rtx copy = gen_reg_rtx (SFmode);
16193 emit_move_insn (copy, operands[1]);
16194 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16198 (define_expand "atansf2"
16199 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16200 (unspec:SF [(match_dup 2)
16201 (match_operand:SF 1 "register_operand" "")]
16203 (clobber (match_scratch:SF 3 ""))])]
16204 "TARGET_USE_FANCY_MATH_387
16205 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16206 && flag_unsafe_math_optimizations"
16208 operands[2] = gen_reg_rtx (SFmode);
16209 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16212 (define_insn "atan2xf3_1"
16213 [(set (match_operand:XF 0 "register_operand" "=f")
16214 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16215 (match_operand:XF 1 "register_operand" "u")]
16217 (clobber (match_scratch:XF 3 "=1"))]
16218 "TARGET_USE_FANCY_MATH_387
16219 && flag_unsafe_math_optimizations"
16221 [(set_attr "type" "fpspc")
16222 (set_attr "mode" "XF")])
16224 (define_expand "atan2xf3"
16225 [(use (match_operand:XF 0 "register_operand" ""))
16226 (use (match_operand:XF 2 "register_operand" ""))
16227 (use (match_operand:XF 1 "register_operand" ""))]
16228 "TARGET_USE_FANCY_MATH_387
16229 && flag_unsafe_math_optimizations"
16231 rtx copy = gen_reg_rtx (XFmode);
16232 emit_move_insn (copy, operands[1]);
16233 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16237 (define_expand "atanxf2"
16238 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16239 (unspec:XF [(match_dup 2)
16240 (match_operand:XF 1 "register_operand" "")]
16242 (clobber (match_scratch:XF 3 ""))])]
16243 "TARGET_USE_FANCY_MATH_387
16244 && flag_unsafe_math_optimizations"
16246 operands[2] = gen_reg_rtx (XFmode);
16247 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16250 (define_expand "asindf2"
16251 [(set (match_dup 2)
16252 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16253 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16254 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16255 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16256 (parallel [(set (match_dup 7)
16257 (unspec:XF [(match_dup 6) (match_dup 2)]
16259 (clobber (match_scratch:XF 8 ""))])
16260 (set (match_operand:DF 0 "register_operand" "")
16261 (float_truncate:DF (match_dup 7)))]
16262 "TARGET_USE_FANCY_MATH_387
16263 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16264 && flag_unsafe_math_optimizations"
16268 for (i=2; i<8; i++)
16269 operands[i] = gen_reg_rtx (XFmode);
16271 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16274 (define_expand "asinsf2"
16275 [(set (match_dup 2)
16276 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16277 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16278 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16279 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16280 (parallel [(set (match_dup 7)
16281 (unspec:XF [(match_dup 6) (match_dup 2)]
16283 (clobber (match_scratch:XF 8 ""))])
16284 (set (match_operand:SF 0 "register_operand" "")
16285 (float_truncate:SF (match_dup 7)))]
16286 "TARGET_USE_FANCY_MATH_387
16287 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16288 && flag_unsafe_math_optimizations"
16292 for (i=2; i<8; i++)
16293 operands[i] = gen_reg_rtx (XFmode);
16295 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16298 (define_expand "asinxf2"
16299 [(set (match_dup 2)
16300 (mult:XF (match_operand:XF 1 "register_operand" "")
16302 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16303 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16304 (parallel [(set (match_operand:XF 0 "register_operand" "")
16305 (unspec:XF [(match_dup 5) (match_dup 1)]
16307 (clobber (match_scratch:XF 6 ""))])]
16308 "TARGET_USE_FANCY_MATH_387
16309 && flag_unsafe_math_optimizations"
16313 for (i=2; i<6; i++)
16314 operands[i] = gen_reg_rtx (XFmode);
16316 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16319 (define_expand "acosdf2"
16320 [(set (match_dup 2)
16321 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16322 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16323 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16324 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16325 (parallel [(set (match_dup 7)
16326 (unspec:XF [(match_dup 2) (match_dup 6)]
16328 (clobber (match_scratch:XF 8 ""))])
16329 (set (match_operand:DF 0 "register_operand" "")
16330 (float_truncate:DF (match_dup 7)))]
16331 "TARGET_USE_FANCY_MATH_387
16332 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16333 && flag_unsafe_math_optimizations"
16337 for (i=2; i<8; i++)
16338 operands[i] = gen_reg_rtx (XFmode);
16340 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16343 (define_expand "acossf2"
16344 [(set (match_dup 2)
16345 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16346 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16347 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16348 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16349 (parallel [(set (match_dup 7)
16350 (unspec:XF [(match_dup 2) (match_dup 6)]
16352 (clobber (match_scratch:XF 8 ""))])
16353 (set (match_operand:SF 0 "register_operand" "")
16354 (float_truncate:SF (match_dup 7)))]
16355 "TARGET_USE_FANCY_MATH_387
16356 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16357 && flag_unsafe_math_optimizations"
16361 for (i=2; i<8; i++)
16362 operands[i] = gen_reg_rtx (XFmode);
16364 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16367 (define_expand "acosxf2"
16368 [(set (match_dup 2)
16369 (mult:XF (match_operand:XF 1 "register_operand" "")
16371 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16372 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16373 (parallel [(set (match_operand:XF 0 "register_operand" "")
16374 (unspec:XF [(match_dup 1) (match_dup 5)]
16376 (clobber (match_scratch:XF 6 ""))])]
16377 "TARGET_USE_FANCY_MATH_387
16378 && flag_unsafe_math_optimizations"
16382 for (i=2; i<6; i++)
16383 operands[i] = gen_reg_rtx (XFmode);
16385 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16388 (define_insn "fyl2x_xf3"
16389 [(set (match_operand:XF 0 "register_operand" "=f")
16390 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16391 (match_operand:XF 1 "register_operand" "u")]
16393 (clobber (match_scratch:XF 3 "=1"))]
16394 "TARGET_USE_FANCY_MATH_387
16395 && flag_unsafe_math_optimizations"
16397 [(set_attr "type" "fpspc")
16398 (set_attr "mode" "XF")])
16400 (define_expand "logsf2"
16401 [(set (match_dup 2)
16402 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16403 (parallel [(set (match_dup 4)
16404 (unspec:XF [(match_dup 2)
16405 (match_dup 3)] UNSPEC_FYL2X))
16406 (clobber (match_scratch:XF 5 ""))])
16407 (set (match_operand:SF 0 "register_operand" "")
16408 (float_truncate:SF (match_dup 4)))]
16409 "TARGET_USE_FANCY_MATH_387
16410 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16411 && flag_unsafe_math_optimizations"
16415 operands[2] = gen_reg_rtx (XFmode);
16416 operands[3] = gen_reg_rtx (XFmode);
16417 operands[4] = gen_reg_rtx (XFmode);
16419 temp = standard_80387_constant_rtx (4); /* fldln2 */
16420 emit_move_insn (operands[3], temp);
16423 (define_expand "logdf2"
16424 [(set (match_dup 2)
16425 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16426 (parallel [(set (match_dup 4)
16427 (unspec:XF [(match_dup 2)
16428 (match_dup 3)] UNSPEC_FYL2X))
16429 (clobber (match_scratch:XF 5 ""))])
16430 (set (match_operand:DF 0 "register_operand" "")
16431 (float_truncate:DF (match_dup 4)))]
16432 "TARGET_USE_FANCY_MATH_387
16433 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16434 && flag_unsafe_math_optimizations"
16438 operands[2] = gen_reg_rtx (XFmode);
16439 operands[3] = gen_reg_rtx (XFmode);
16440 operands[4] = gen_reg_rtx (XFmode);
16442 temp = standard_80387_constant_rtx (4); /* fldln2 */
16443 emit_move_insn (operands[3], temp);
16446 (define_expand "logxf2"
16447 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16448 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16449 (match_dup 2)] UNSPEC_FYL2X))
16450 (clobber (match_scratch:XF 3 ""))])]
16451 "TARGET_USE_FANCY_MATH_387
16452 && flag_unsafe_math_optimizations"
16456 operands[2] = gen_reg_rtx (XFmode);
16457 temp = standard_80387_constant_rtx (4); /* fldln2 */
16458 emit_move_insn (operands[2], temp);
16461 (define_expand "log10sf2"
16462 [(set (match_dup 2)
16463 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16464 (parallel [(set (match_dup 4)
16465 (unspec:XF [(match_dup 2)
16466 (match_dup 3)] UNSPEC_FYL2X))
16467 (clobber (match_scratch:XF 5 ""))])
16468 (set (match_operand:SF 0 "register_operand" "")
16469 (float_truncate:SF (match_dup 4)))]
16470 "TARGET_USE_FANCY_MATH_387
16471 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16472 && flag_unsafe_math_optimizations"
16476 operands[2] = gen_reg_rtx (XFmode);
16477 operands[3] = gen_reg_rtx (XFmode);
16478 operands[4] = gen_reg_rtx (XFmode);
16480 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16481 emit_move_insn (operands[3], temp);
16484 (define_expand "log10df2"
16485 [(set (match_dup 2)
16486 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16487 (parallel [(set (match_dup 4)
16488 (unspec:XF [(match_dup 2)
16489 (match_dup 3)] UNSPEC_FYL2X))
16490 (clobber (match_scratch:XF 5 ""))])
16491 (set (match_operand:DF 0 "register_operand" "")
16492 (float_truncate:DF (match_dup 4)))]
16493 "TARGET_USE_FANCY_MATH_387
16494 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16495 && flag_unsafe_math_optimizations"
16499 operands[2] = gen_reg_rtx (XFmode);
16500 operands[3] = gen_reg_rtx (XFmode);
16501 operands[4] = gen_reg_rtx (XFmode);
16503 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16504 emit_move_insn (operands[3], temp);
16507 (define_expand "log10xf2"
16508 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16509 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16510 (match_dup 2)] UNSPEC_FYL2X))
16511 (clobber (match_scratch:XF 3 ""))])]
16512 "TARGET_USE_FANCY_MATH_387
16513 && flag_unsafe_math_optimizations"
16517 operands[2] = gen_reg_rtx (XFmode);
16518 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16519 emit_move_insn (operands[2], temp);
16522 (define_expand "log2sf2"
16523 [(set (match_dup 2)
16524 (float_extend:XF (match_operand:SF 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:SF 0 "register_operand" "")
16530 (float_truncate:SF (match_dup 4)))]
16531 "TARGET_USE_FANCY_MATH_387
16532 && (!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 "log2df2"
16543 [(set (match_dup 2)
16544 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16545 (parallel [(set (match_dup 4)
16546 (unspec:XF [(match_dup 2)
16547 (match_dup 3)] UNSPEC_FYL2X))
16548 (clobber (match_scratch:XF 5 ""))])
16549 (set (match_operand:DF 0 "register_operand" "")
16550 (float_truncate:DF (match_dup 4)))]
16551 "TARGET_USE_FANCY_MATH_387
16552 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16553 && flag_unsafe_math_optimizations"
16555 operands[2] = gen_reg_rtx (XFmode);
16556 operands[3] = gen_reg_rtx (XFmode);
16557 operands[4] = gen_reg_rtx (XFmode);
16559 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16562 (define_expand "log2xf2"
16563 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16564 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16565 (match_dup 2)] UNSPEC_FYL2X))
16566 (clobber (match_scratch:XF 3 ""))])]
16567 "TARGET_USE_FANCY_MATH_387
16568 && flag_unsafe_math_optimizations"
16570 operands[2] = gen_reg_rtx (XFmode);
16571 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16574 (define_insn "fyl2xp1_xf3"
16575 [(set (match_operand:XF 0 "register_operand" "=f")
16576 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16577 (match_operand:XF 1 "register_operand" "u")]
16579 (clobber (match_scratch:XF 3 "=1"))]
16580 "TARGET_USE_FANCY_MATH_387
16581 && flag_unsafe_math_optimizations"
16583 [(set_attr "type" "fpspc")
16584 (set_attr "mode" "XF")])
16586 (define_expand "log1psf2"
16587 [(use (match_operand:SF 0 "register_operand" ""))
16588 (use (match_operand:SF 1 "register_operand" ""))]
16589 "TARGET_USE_FANCY_MATH_387
16590 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16591 && flag_unsafe_math_optimizations"
16593 rtx op0 = gen_reg_rtx (XFmode);
16594 rtx op1 = gen_reg_rtx (XFmode);
16596 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16597 ix86_emit_i387_log1p (op0, op1);
16598 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16602 (define_expand "log1pdf2"
16603 [(use (match_operand:DF 0 "register_operand" ""))
16604 (use (match_operand:DF 1 "register_operand" ""))]
16605 "TARGET_USE_FANCY_MATH_387
16606 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16607 && flag_unsafe_math_optimizations"
16609 rtx op0 = gen_reg_rtx (XFmode);
16610 rtx op1 = gen_reg_rtx (XFmode);
16612 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16613 ix86_emit_i387_log1p (op0, op1);
16614 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16618 (define_expand "log1pxf2"
16619 [(use (match_operand:XF 0 "register_operand" ""))
16620 (use (match_operand:XF 1 "register_operand" ""))]
16621 "TARGET_USE_FANCY_MATH_387
16622 && flag_unsafe_math_optimizations"
16624 ix86_emit_i387_log1p (operands[0], operands[1]);
16628 (define_insn "*fxtractxf3"
16629 [(set (match_operand:XF 0 "register_operand" "=f")
16630 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16631 UNSPEC_XTRACT_FRACT))
16632 (set (match_operand:XF 1 "register_operand" "=u")
16633 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16634 "TARGET_USE_FANCY_MATH_387
16635 && flag_unsafe_math_optimizations"
16637 [(set_attr "type" "fpspc")
16638 (set_attr "mode" "XF")])
16640 (define_expand "logbsf2"
16641 [(set (match_dup 2)
16642 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16643 (parallel [(set (match_dup 3)
16644 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16646 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16647 (set (match_operand:SF 0 "register_operand" "")
16648 (float_truncate:SF (match_dup 4)))]
16649 "TARGET_USE_FANCY_MATH_387
16650 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16651 && flag_unsafe_math_optimizations"
16653 operands[2] = gen_reg_rtx (XFmode);
16654 operands[3] = gen_reg_rtx (XFmode);
16655 operands[4] = gen_reg_rtx (XFmode);
16658 (define_expand "logbdf2"
16659 [(set (match_dup 2)
16660 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16661 (parallel [(set (match_dup 3)
16662 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16664 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16665 (set (match_operand:DF 0 "register_operand" "")
16666 (float_truncate:DF (match_dup 4)))]
16667 "TARGET_USE_FANCY_MATH_387
16668 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16669 && flag_unsafe_math_optimizations"
16671 operands[2] = gen_reg_rtx (XFmode);
16672 operands[3] = gen_reg_rtx (XFmode);
16673 operands[4] = gen_reg_rtx (XFmode);
16676 (define_expand "logbxf2"
16677 [(parallel [(set (match_dup 2)
16678 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16679 UNSPEC_XTRACT_FRACT))
16680 (set (match_operand:XF 0 "register_operand" "")
16681 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16682 "TARGET_USE_FANCY_MATH_387
16683 && flag_unsafe_math_optimizations"
16685 operands[2] = gen_reg_rtx (XFmode);
16688 (define_expand "ilogbsi2"
16689 [(parallel [(set (match_dup 2)
16690 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16691 UNSPEC_XTRACT_FRACT))
16692 (set (match_operand:XF 3 "register_operand" "")
16693 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16694 (parallel [(set (match_operand:SI 0 "register_operand" "")
16695 (fix:SI (match_dup 3)))
16696 (clobber (reg:CC FLAGS_REG))])]
16697 "TARGET_USE_FANCY_MATH_387
16698 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16699 && flag_unsafe_math_optimizations"
16701 operands[2] = gen_reg_rtx (XFmode);
16702 operands[3] = gen_reg_rtx (XFmode);
16705 (define_insn "*f2xm1xf2"
16706 [(set (match_operand:XF 0 "register_operand" "=f")
16707 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16709 "TARGET_USE_FANCY_MATH_387
16710 && flag_unsafe_math_optimizations"
16712 [(set_attr "type" "fpspc")
16713 (set_attr "mode" "XF")])
16715 (define_insn "*fscalexf4"
16716 [(set (match_operand:XF 0 "register_operand" "=f")
16717 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16718 (match_operand:XF 3 "register_operand" "1")]
16719 UNSPEC_FSCALE_FRACT))
16720 (set (match_operand:XF 1 "register_operand" "=u")
16721 (unspec:XF [(match_dup 2) (match_dup 3)]
16722 UNSPEC_FSCALE_EXP))]
16723 "TARGET_USE_FANCY_MATH_387
16724 && flag_unsafe_math_optimizations"
16726 [(set_attr "type" "fpspc")
16727 (set_attr "mode" "XF")])
16729 (define_expand "expsf2"
16730 [(set (match_dup 2)
16731 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16732 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16733 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16734 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16735 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16736 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16737 (parallel [(set (match_dup 10)
16738 (unspec:XF [(match_dup 9) (match_dup 5)]
16739 UNSPEC_FSCALE_FRACT))
16740 (set (match_dup 11)
16741 (unspec:XF [(match_dup 9) (match_dup 5)]
16742 UNSPEC_FSCALE_EXP))])
16743 (set (match_operand:SF 0 "register_operand" "")
16744 (float_truncate:SF (match_dup 10)))]
16745 "TARGET_USE_FANCY_MATH_387
16746 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16747 && flag_unsafe_math_optimizations"
16752 for (i=2; i<12; i++)
16753 operands[i] = gen_reg_rtx (XFmode);
16754 temp = standard_80387_constant_rtx (5); /* fldl2e */
16755 emit_move_insn (operands[3], temp);
16756 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16759 (define_expand "expdf2"
16760 [(set (match_dup 2)
16761 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16762 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16763 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16764 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16765 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16766 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16767 (parallel [(set (match_dup 10)
16768 (unspec:XF [(match_dup 9) (match_dup 5)]
16769 UNSPEC_FSCALE_FRACT))
16770 (set (match_dup 11)
16771 (unspec:XF [(match_dup 9) (match_dup 5)]
16772 UNSPEC_FSCALE_EXP))])
16773 (set (match_operand:DF 0 "register_operand" "")
16774 (float_truncate:DF (match_dup 10)))]
16775 "TARGET_USE_FANCY_MATH_387
16776 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16777 && flag_unsafe_math_optimizations"
16782 for (i=2; i<12; i++)
16783 operands[i] = gen_reg_rtx (XFmode);
16784 temp = standard_80387_constant_rtx (5); /* fldl2e */
16785 emit_move_insn (operands[3], temp);
16786 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16789 (define_expand "expxf2"
16790 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16792 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16793 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16794 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16795 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16796 (parallel [(set (match_operand:XF 0 "register_operand" "")
16797 (unspec:XF [(match_dup 8) (match_dup 4)]
16798 UNSPEC_FSCALE_FRACT))
16800 (unspec:XF [(match_dup 8) (match_dup 4)]
16801 UNSPEC_FSCALE_EXP))])]
16802 "TARGET_USE_FANCY_MATH_387
16803 && flag_unsafe_math_optimizations"
16808 for (i=2; i<10; i++)
16809 operands[i] = gen_reg_rtx (XFmode);
16810 temp = standard_80387_constant_rtx (5); /* fldl2e */
16811 emit_move_insn (operands[2], temp);
16812 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16815 (define_expand "exp10sf2"
16816 [(set (match_dup 2)
16817 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16818 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16819 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16820 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16821 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16822 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16823 (parallel [(set (match_dup 10)
16824 (unspec:XF [(match_dup 9) (match_dup 5)]
16825 UNSPEC_FSCALE_FRACT))
16826 (set (match_dup 11)
16827 (unspec:XF [(match_dup 9) (match_dup 5)]
16828 UNSPEC_FSCALE_EXP))])
16829 (set (match_operand:SF 0 "register_operand" "")
16830 (float_truncate:SF (match_dup 10)))]
16831 "TARGET_USE_FANCY_MATH_387
16832 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16833 && flag_unsafe_math_optimizations"
16838 for (i=2; i<12; i++)
16839 operands[i] = gen_reg_rtx (XFmode);
16840 temp = standard_80387_constant_rtx (6); /* fldl2t */
16841 emit_move_insn (operands[3], temp);
16842 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16845 (define_expand "exp10df2"
16846 [(set (match_dup 2)
16847 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16848 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16849 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16850 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16851 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16852 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16853 (parallel [(set (match_dup 10)
16854 (unspec:XF [(match_dup 9) (match_dup 5)]
16855 UNSPEC_FSCALE_FRACT))
16856 (set (match_dup 11)
16857 (unspec:XF [(match_dup 9) (match_dup 5)]
16858 UNSPEC_FSCALE_EXP))])
16859 (set (match_operand:DF 0 "register_operand" "")
16860 (float_truncate:DF (match_dup 10)))]
16861 "TARGET_USE_FANCY_MATH_387
16862 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16863 && flag_unsafe_math_optimizations"
16868 for (i=2; i<12; i++)
16869 operands[i] = gen_reg_rtx (XFmode);
16870 temp = standard_80387_constant_rtx (6); /* fldl2t */
16871 emit_move_insn (operands[3], temp);
16872 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16875 (define_expand "exp10xf2"
16876 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16878 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16879 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16880 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16881 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16882 (parallel [(set (match_operand:XF 0 "register_operand" "")
16883 (unspec:XF [(match_dup 8) (match_dup 4)]
16884 UNSPEC_FSCALE_FRACT))
16886 (unspec:XF [(match_dup 8) (match_dup 4)]
16887 UNSPEC_FSCALE_EXP))])]
16888 "TARGET_USE_FANCY_MATH_387
16889 && flag_unsafe_math_optimizations"
16894 for (i=2; i<10; i++)
16895 operands[i] = gen_reg_rtx (XFmode);
16896 temp = standard_80387_constant_rtx (6); /* fldl2t */
16897 emit_move_insn (operands[2], temp);
16898 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16901 (define_expand "exp2sf2"
16902 [(set (match_dup 2)
16903 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16904 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16905 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16906 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16907 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16908 (parallel [(set (match_dup 8)
16909 (unspec:XF [(match_dup 7) (match_dup 3)]
16910 UNSPEC_FSCALE_FRACT))
16912 (unspec:XF [(match_dup 7) (match_dup 3)]
16913 UNSPEC_FSCALE_EXP))])
16914 (set (match_operand:SF 0 "register_operand" "")
16915 (float_truncate:SF (match_dup 8)))]
16916 "TARGET_USE_FANCY_MATH_387
16917 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16918 && flag_unsafe_math_optimizations"
16922 for (i=2; i<10; i++)
16923 operands[i] = gen_reg_rtx (XFmode);
16924 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16927 (define_expand "exp2df2"
16928 [(set (match_dup 2)
16929 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16930 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16931 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16932 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16933 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16934 (parallel [(set (match_dup 8)
16935 (unspec:XF [(match_dup 7) (match_dup 3)]
16936 UNSPEC_FSCALE_FRACT))
16938 (unspec:XF [(match_dup 7) (match_dup 3)]
16939 UNSPEC_FSCALE_EXP))])
16940 (set (match_operand:DF 0 "register_operand" "")
16941 (float_truncate:DF (match_dup 8)))]
16942 "TARGET_USE_FANCY_MATH_387
16943 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16944 && flag_unsafe_math_optimizations"
16948 for (i=2; i<10; i++)
16949 operands[i] = gen_reg_rtx (XFmode);
16950 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16953 (define_expand "exp2xf2"
16954 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16955 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16956 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16957 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16958 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16959 (parallel [(set (match_operand:XF 0 "register_operand" "")
16960 (unspec:XF [(match_dup 7) (match_dup 3)]
16961 UNSPEC_FSCALE_FRACT))
16963 (unspec:XF [(match_dup 7) (match_dup 3)]
16964 UNSPEC_FSCALE_EXP))])]
16965 "TARGET_USE_FANCY_MATH_387
16966 && flag_unsafe_math_optimizations"
16970 for (i=2; i<9; i++)
16971 operands[i] = gen_reg_rtx (XFmode);
16972 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16975 (define_expand "expm1df2"
16976 [(set (match_dup 2)
16977 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16978 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16979 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16980 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16981 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16982 (parallel [(set (match_dup 8)
16983 (unspec:XF [(match_dup 7) (match_dup 5)]
16984 UNSPEC_FSCALE_FRACT))
16986 (unspec:XF [(match_dup 7) (match_dup 5)]
16987 UNSPEC_FSCALE_EXP))])
16988 (parallel [(set (match_dup 11)
16989 (unspec:XF [(match_dup 10) (match_dup 9)]
16990 UNSPEC_FSCALE_FRACT))
16991 (set (match_dup 12)
16992 (unspec:XF [(match_dup 10) (match_dup 9)]
16993 UNSPEC_FSCALE_EXP))])
16994 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16995 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16996 (set (match_operand:DF 0 "register_operand" "")
16997 (float_truncate:DF (match_dup 14)))]
16998 "TARGET_USE_FANCY_MATH_387
16999 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17000 && flag_unsafe_math_optimizations"
17005 for (i=2; i<15; i++)
17006 operands[i] = gen_reg_rtx (XFmode);
17007 temp = standard_80387_constant_rtx (5); /* fldl2e */
17008 emit_move_insn (operands[3], temp);
17009 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17012 (define_expand "expm1sf2"
17013 [(set (match_dup 2)
17014 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17015 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17016 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17017 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17018 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17019 (parallel [(set (match_dup 8)
17020 (unspec:XF [(match_dup 7) (match_dup 5)]
17021 UNSPEC_FSCALE_FRACT))
17023 (unspec:XF [(match_dup 7) (match_dup 5)]
17024 UNSPEC_FSCALE_EXP))])
17025 (parallel [(set (match_dup 11)
17026 (unspec:XF [(match_dup 10) (match_dup 9)]
17027 UNSPEC_FSCALE_FRACT))
17028 (set (match_dup 12)
17029 (unspec:XF [(match_dup 10) (match_dup 9)]
17030 UNSPEC_FSCALE_EXP))])
17031 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17032 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17033 (set (match_operand:SF 0 "register_operand" "")
17034 (float_truncate:SF (match_dup 14)))]
17035 "TARGET_USE_FANCY_MATH_387
17036 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17037 && flag_unsafe_math_optimizations"
17042 for (i=2; i<15; i++)
17043 operands[i] = gen_reg_rtx (XFmode);
17044 temp = standard_80387_constant_rtx (5); /* fldl2e */
17045 emit_move_insn (operands[3], temp);
17046 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17049 (define_expand "expm1xf2"
17050 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17052 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17053 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17054 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17055 (parallel [(set (match_dup 7)
17056 (unspec:XF [(match_dup 6) (match_dup 4)]
17057 UNSPEC_FSCALE_FRACT))
17059 (unspec:XF [(match_dup 6) (match_dup 4)]
17060 UNSPEC_FSCALE_EXP))])
17061 (parallel [(set (match_dup 10)
17062 (unspec:XF [(match_dup 9) (match_dup 8)]
17063 UNSPEC_FSCALE_FRACT))
17064 (set (match_dup 11)
17065 (unspec:XF [(match_dup 9) (match_dup 8)]
17066 UNSPEC_FSCALE_EXP))])
17067 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17068 (set (match_operand:XF 0 "register_operand" "")
17069 (plus:XF (match_dup 12) (match_dup 7)))]
17070 "TARGET_USE_FANCY_MATH_387
17071 && flag_unsafe_math_optimizations"
17076 for (i=2; i<13; i++)
17077 operands[i] = gen_reg_rtx (XFmode);
17078 temp = standard_80387_constant_rtx (5); /* fldl2e */
17079 emit_move_insn (operands[2], temp);
17080 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17083 (define_expand "ldexpdf3"
17084 [(set (match_dup 3)
17085 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17087 (float:XF (match_operand:SI 2 "register_operand" "")))
17088 (parallel [(set (match_dup 5)
17089 (unspec:XF [(match_dup 3) (match_dup 4)]
17090 UNSPEC_FSCALE_FRACT))
17092 (unspec:XF [(match_dup 3) (match_dup 4)]
17093 UNSPEC_FSCALE_EXP))])
17094 (set (match_operand:DF 0 "register_operand" "")
17095 (float_truncate:DF (match_dup 5)))]
17096 "TARGET_USE_FANCY_MATH_387
17097 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17098 && flag_unsafe_math_optimizations"
17102 for (i=3; i<7; i++)
17103 operands[i] = gen_reg_rtx (XFmode);
17106 (define_expand "ldexpsf3"
17107 [(set (match_dup 3)
17108 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17110 (float:XF (match_operand:SI 2 "register_operand" "")))
17111 (parallel [(set (match_dup 5)
17112 (unspec:XF [(match_dup 3) (match_dup 4)]
17113 UNSPEC_FSCALE_FRACT))
17115 (unspec:XF [(match_dup 3) (match_dup 4)]
17116 UNSPEC_FSCALE_EXP))])
17117 (set (match_operand:SF 0 "register_operand" "")
17118 (float_truncate:SF (match_dup 5)))]
17119 "TARGET_USE_FANCY_MATH_387
17120 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17121 && flag_unsafe_math_optimizations"
17125 for (i=3; i<7; i++)
17126 operands[i] = gen_reg_rtx (XFmode);
17129 (define_expand "ldexpxf3"
17130 [(set (match_dup 3)
17131 (float:XF (match_operand:SI 2 "register_operand" "")))
17132 (parallel [(set (match_operand:XF 0 " register_operand" "")
17133 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17135 UNSPEC_FSCALE_FRACT))
17137 (unspec:XF [(match_dup 1) (match_dup 3)]
17138 UNSPEC_FSCALE_EXP))])]
17139 "TARGET_USE_FANCY_MATH_387
17140 && flag_unsafe_math_optimizations"
17144 for (i=3; i<5; i++)
17145 operands[i] = gen_reg_rtx (XFmode);
17149 (define_insn "frndintxf2"
17150 [(set (match_operand:XF 0 "register_operand" "=f")
17151 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17153 "TARGET_USE_FANCY_MATH_387
17154 && flag_unsafe_math_optimizations"
17156 [(set_attr "type" "fpspc")
17157 (set_attr "mode" "XF")])
17159 (define_expand "rintdf2"
17160 [(use (match_operand:DF 0 "register_operand" ""))
17161 (use (match_operand:DF 1 "register_operand" ""))]
17162 "TARGET_USE_FANCY_MATH_387
17163 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17164 && flag_unsafe_math_optimizations"
17166 rtx op0 = gen_reg_rtx (XFmode);
17167 rtx op1 = gen_reg_rtx (XFmode);
17169 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17170 emit_insn (gen_frndintxf2 (op0, op1));
17172 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17176 (define_expand "rintsf2"
17177 [(use (match_operand:SF 0 "register_operand" ""))
17178 (use (match_operand:SF 1 "register_operand" ""))]
17179 "TARGET_USE_FANCY_MATH_387
17180 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17181 && flag_unsafe_math_optimizations"
17183 rtx op0 = gen_reg_rtx (XFmode);
17184 rtx op1 = gen_reg_rtx (XFmode);
17186 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17187 emit_insn (gen_frndintxf2 (op0, op1));
17189 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17193 (define_expand "rintxf2"
17194 [(use (match_operand:XF 0 "register_operand" ""))
17195 (use (match_operand:XF 1 "register_operand" ""))]
17196 "TARGET_USE_FANCY_MATH_387
17197 && flag_unsafe_math_optimizations"
17199 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17203 (define_insn_and_split "*fistdi2_1"
17204 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17205 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17207 "TARGET_USE_FANCY_MATH_387
17208 && flag_unsafe_math_optimizations
17209 && !(reload_completed || reload_in_progress)"
17214 if (memory_operand (operands[0], VOIDmode))
17215 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17218 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17219 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17224 [(set_attr "type" "fpspc")
17225 (set_attr "mode" "DI")])
17227 (define_insn "fistdi2"
17228 [(set (match_operand:DI 0 "memory_operand" "=m")
17229 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17231 (clobber (match_scratch:XF 2 "=&1f"))]
17232 "TARGET_USE_FANCY_MATH_387
17233 && flag_unsafe_math_optimizations"
17234 "* return output_fix_trunc (insn, operands, 0);"
17235 [(set_attr "type" "fpspc")
17236 (set_attr "mode" "DI")])
17238 (define_insn "fistdi2_with_temp"
17239 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17240 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17242 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17243 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17244 "TARGET_USE_FANCY_MATH_387
17245 && flag_unsafe_math_optimizations"
17247 [(set_attr "type" "fpspc")
17248 (set_attr "mode" "DI")])
17251 [(set (match_operand:DI 0 "register_operand" "")
17252 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17254 (clobber (match_operand:DI 2 "memory_operand" ""))
17255 (clobber (match_scratch 3 ""))]
17257 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17258 (clobber (match_dup 3))])
17259 (set (match_dup 0) (match_dup 2))]
17263 [(set (match_operand:DI 0 "memory_operand" "")
17264 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17266 (clobber (match_operand:DI 2 "memory_operand" ""))
17267 (clobber (match_scratch 3 ""))]
17269 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17270 (clobber (match_dup 3))])]
17273 (define_insn_and_split "*fist<mode>2_1"
17274 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17275 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17277 "TARGET_USE_FANCY_MATH_387
17278 && flag_unsafe_math_optimizations
17279 && !(reload_completed || reload_in_progress)"
17284 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17285 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17289 [(set_attr "type" "fpspc")
17290 (set_attr "mode" "<MODE>")])
17292 (define_insn "fist<mode>2"
17293 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17294 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17296 "TARGET_USE_FANCY_MATH_387
17297 && flag_unsafe_math_optimizations"
17298 "* return output_fix_trunc (insn, operands, 0);"
17299 [(set_attr "type" "fpspc")
17300 (set_attr "mode" "<MODE>")])
17302 (define_insn "fist<mode>2_with_temp"
17303 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17304 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17306 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17307 "TARGET_USE_FANCY_MATH_387
17308 && flag_unsafe_math_optimizations"
17310 [(set_attr "type" "fpspc")
17311 (set_attr "mode" "<MODE>")])
17314 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17315 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17317 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17319 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17321 (set (match_dup 0) (match_dup 2))]
17325 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17326 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17328 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17330 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17334 (define_expand "lrint<mode>2"
17335 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17336 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17338 "TARGET_USE_FANCY_MATH_387
17339 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17340 && flag_unsafe_math_optimizations"
17343 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17344 (define_insn_and_split "frndintxf2_floor"
17345 [(set (match_operand:XF 0 "register_operand" "=f")
17346 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17347 UNSPEC_FRNDINT_FLOOR))
17348 (clobber (reg:CC FLAGS_REG))]
17349 "TARGET_USE_FANCY_MATH_387
17350 && flag_unsafe_math_optimizations
17351 && !(reload_completed || reload_in_progress)"
17356 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17358 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17359 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17361 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17362 operands[2], operands[3]));
17365 [(set_attr "type" "frndint")
17366 (set_attr "i387_cw" "floor")
17367 (set_attr "mode" "XF")])
17369 (define_insn "frndintxf2_floor_i387"
17370 [(set (match_operand:XF 0 "register_operand" "=f")
17371 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17372 UNSPEC_FRNDINT_FLOOR))
17373 (use (match_operand:HI 2 "memory_operand" "m"))
17374 (use (match_operand:HI 3 "memory_operand" "m"))]
17375 "TARGET_USE_FANCY_MATH_387
17376 && flag_unsafe_math_optimizations"
17377 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17378 [(set_attr "type" "frndint")
17379 (set_attr "i387_cw" "floor")
17380 (set_attr "mode" "XF")])
17382 (define_expand "floorxf2"
17383 [(use (match_operand:XF 0 "register_operand" ""))
17384 (use (match_operand:XF 1 "register_operand" ""))]
17385 "TARGET_USE_FANCY_MATH_387
17386 && flag_unsafe_math_optimizations"
17388 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17392 (define_expand "floordf2"
17393 [(use (match_operand:DF 0 "register_operand" ""))
17394 (use (match_operand:DF 1 "register_operand" ""))]
17395 "TARGET_USE_FANCY_MATH_387
17396 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17397 && flag_unsafe_math_optimizations"
17399 rtx op0 = gen_reg_rtx (XFmode);
17400 rtx op1 = gen_reg_rtx (XFmode);
17402 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17403 emit_insn (gen_frndintxf2_floor (op0, op1));
17405 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17409 (define_expand "floorsf2"
17410 [(use (match_operand:SF 0 "register_operand" ""))
17411 (use (match_operand:SF 1 "register_operand" ""))]
17412 "TARGET_USE_FANCY_MATH_387
17413 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17414 && flag_unsafe_math_optimizations"
17416 rtx op0 = gen_reg_rtx (XFmode);
17417 rtx op1 = gen_reg_rtx (XFmode);
17419 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17420 emit_insn (gen_frndintxf2_floor (op0, op1));
17422 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17426 (define_insn_and_split "*fist<mode>2_floor_1"
17427 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17428 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17429 UNSPEC_FIST_FLOOR))
17430 (clobber (reg:CC FLAGS_REG))]
17431 "TARGET_USE_FANCY_MATH_387
17432 && flag_unsafe_math_optimizations
17433 && !(reload_completed || reload_in_progress)"
17438 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17440 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17441 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17442 if (memory_operand (operands[0], VOIDmode))
17443 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17444 operands[2], operands[3]));
17447 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17448 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17449 operands[2], operands[3],
17454 [(set_attr "type" "fistp")
17455 (set_attr "i387_cw" "floor")
17456 (set_attr "mode" "<MODE>")])
17458 (define_insn "fistdi2_floor"
17459 [(set (match_operand:DI 0 "memory_operand" "=m")
17460 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17461 UNSPEC_FIST_FLOOR))
17462 (use (match_operand:HI 2 "memory_operand" "m"))
17463 (use (match_operand:HI 3 "memory_operand" "m"))
17464 (clobber (match_scratch:XF 4 "=&1f"))]
17465 "TARGET_USE_FANCY_MATH_387
17466 && flag_unsafe_math_optimizations"
17467 "* return output_fix_trunc (insn, operands, 0);"
17468 [(set_attr "type" "fistp")
17469 (set_attr "i387_cw" "floor")
17470 (set_attr "mode" "DI")])
17472 (define_insn "fistdi2_floor_with_temp"
17473 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17474 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17475 UNSPEC_FIST_FLOOR))
17476 (use (match_operand:HI 2 "memory_operand" "m,m"))
17477 (use (match_operand:HI 3 "memory_operand" "m,m"))
17478 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17479 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17480 "TARGET_USE_FANCY_MATH_387
17481 && flag_unsafe_math_optimizations"
17483 [(set_attr "type" "fistp")
17484 (set_attr "i387_cw" "floor")
17485 (set_attr "mode" "DI")])
17488 [(set (match_operand:DI 0 "register_operand" "")
17489 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17490 UNSPEC_FIST_FLOOR))
17491 (use (match_operand:HI 2 "memory_operand" ""))
17492 (use (match_operand:HI 3 "memory_operand" ""))
17493 (clobber (match_operand:DI 4 "memory_operand" ""))
17494 (clobber (match_scratch 5 ""))]
17496 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17497 (use (match_dup 2))
17498 (use (match_dup 3))
17499 (clobber (match_dup 5))])
17500 (set (match_dup 0) (match_dup 4))]
17504 [(set (match_operand:DI 0 "memory_operand" "")
17505 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17506 UNSPEC_FIST_FLOOR))
17507 (use (match_operand:HI 2 "memory_operand" ""))
17508 (use (match_operand:HI 3 "memory_operand" ""))
17509 (clobber (match_operand:DI 4 "memory_operand" ""))
17510 (clobber (match_scratch 5 ""))]
17512 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17513 (use (match_dup 2))
17514 (use (match_dup 3))
17515 (clobber (match_dup 5))])]
17518 (define_insn "fist<mode>2_floor"
17519 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17520 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17521 UNSPEC_FIST_FLOOR))
17522 (use (match_operand:HI 2 "memory_operand" "m"))
17523 (use (match_operand:HI 3 "memory_operand" "m"))]
17524 "TARGET_USE_FANCY_MATH_387
17525 && flag_unsafe_math_optimizations"
17526 "* return output_fix_trunc (insn, operands, 0);"
17527 [(set_attr "type" "fistp")
17528 (set_attr "i387_cw" "floor")
17529 (set_attr "mode" "<MODE>")])
17531 (define_insn "fist<mode>2_floor_with_temp"
17532 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17533 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17534 UNSPEC_FIST_FLOOR))
17535 (use (match_operand:HI 2 "memory_operand" "m,m"))
17536 (use (match_operand:HI 3 "memory_operand" "m,m"))
17537 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17538 "TARGET_USE_FANCY_MATH_387
17539 && flag_unsafe_math_optimizations"
17541 [(set_attr "type" "fistp")
17542 (set_attr "i387_cw" "floor")
17543 (set_attr "mode" "<MODE>")])
17546 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17547 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17548 UNSPEC_FIST_FLOOR))
17549 (use (match_operand:HI 2 "memory_operand" ""))
17550 (use (match_operand:HI 3 "memory_operand" ""))
17551 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17553 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17554 UNSPEC_FIST_FLOOR))
17555 (use (match_dup 2))
17556 (use (match_dup 3))])
17557 (set (match_dup 0) (match_dup 4))]
17561 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17562 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17563 UNSPEC_FIST_FLOOR))
17564 (use (match_operand:HI 2 "memory_operand" ""))
17565 (use (match_operand:HI 3 "memory_operand" ""))
17566 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17568 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17569 UNSPEC_FIST_FLOOR))
17570 (use (match_dup 2))
17571 (use (match_dup 3))])]
17574 (define_expand "lfloor<mode>2"
17575 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17576 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17577 UNSPEC_FIST_FLOOR))
17578 (clobber (reg:CC FLAGS_REG))])]
17579 "TARGET_USE_FANCY_MATH_387
17580 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17581 && flag_unsafe_math_optimizations"
17584 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17585 (define_insn_and_split "frndintxf2_ceil"
17586 [(set (match_operand:XF 0 "register_operand" "=f")
17587 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17588 UNSPEC_FRNDINT_CEIL))
17589 (clobber (reg:CC FLAGS_REG))]
17590 "TARGET_USE_FANCY_MATH_387
17591 && flag_unsafe_math_optimizations
17592 && !(reload_completed || reload_in_progress)"
17597 ix86_optimize_mode_switching[I387_CEIL] = 1;
17599 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17600 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17602 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17603 operands[2], operands[3]));
17606 [(set_attr "type" "frndint")
17607 (set_attr "i387_cw" "ceil")
17608 (set_attr "mode" "XF")])
17610 (define_insn "frndintxf2_ceil_i387"
17611 [(set (match_operand:XF 0 "register_operand" "=f")
17612 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17613 UNSPEC_FRNDINT_CEIL))
17614 (use (match_operand:HI 2 "memory_operand" "m"))
17615 (use (match_operand:HI 3 "memory_operand" "m"))]
17616 "TARGET_USE_FANCY_MATH_387
17617 && flag_unsafe_math_optimizations"
17618 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17619 [(set_attr "type" "frndint")
17620 (set_attr "i387_cw" "ceil")
17621 (set_attr "mode" "XF")])
17623 (define_expand "ceilxf2"
17624 [(use (match_operand:XF 0 "register_operand" ""))
17625 (use (match_operand:XF 1 "register_operand" ""))]
17626 "TARGET_USE_FANCY_MATH_387
17627 && flag_unsafe_math_optimizations"
17629 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17633 (define_expand "ceildf2"
17634 [(use (match_operand:DF 0 "register_operand" ""))
17635 (use (match_operand:DF 1 "register_operand" ""))]
17636 "TARGET_USE_FANCY_MATH_387
17637 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17638 && flag_unsafe_math_optimizations"
17640 rtx op0 = gen_reg_rtx (XFmode);
17641 rtx op1 = gen_reg_rtx (XFmode);
17643 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17644 emit_insn (gen_frndintxf2_ceil (op0, op1));
17646 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17650 (define_expand "ceilsf2"
17651 [(use (match_operand:SF 0 "register_operand" ""))
17652 (use (match_operand:SF 1 "register_operand" ""))]
17653 "TARGET_USE_FANCY_MATH_387
17654 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17655 && flag_unsafe_math_optimizations"
17657 rtx op0 = gen_reg_rtx (XFmode);
17658 rtx op1 = gen_reg_rtx (XFmode);
17660 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17661 emit_insn (gen_frndintxf2_ceil (op0, op1));
17663 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17667 (define_insn_and_split "*fist<mode>2_ceil_1"
17668 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17669 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17671 (clobber (reg:CC FLAGS_REG))]
17672 "TARGET_USE_FANCY_MATH_387
17673 && flag_unsafe_math_optimizations
17674 && !(reload_completed || reload_in_progress)"
17679 ix86_optimize_mode_switching[I387_CEIL] = 1;
17681 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17682 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17683 if (memory_operand (operands[0], VOIDmode))
17684 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17685 operands[2], operands[3]));
17688 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17689 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17690 operands[2], operands[3],
17695 [(set_attr "type" "fistp")
17696 (set_attr "i387_cw" "ceil")
17697 (set_attr "mode" "<MODE>")])
17699 (define_insn "fistdi2_ceil"
17700 [(set (match_operand:DI 0 "memory_operand" "=m")
17701 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17703 (use (match_operand:HI 2 "memory_operand" "m"))
17704 (use (match_operand:HI 3 "memory_operand" "m"))
17705 (clobber (match_scratch:XF 4 "=&1f"))]
17706 "TARGET_USE_FANCY_MATH_387
17707 && flag_unsafe_math_optimizations"
17708 "* return output_fix_trunc (insn, operands, 0);"
17709 [(set_attr "type" "fistp")
17710 (set_attr "i387_cw" "ceil")
17711 (set_attr "mode" "DI")])
17713 (define_insn "fistdi2_ceil_with_temp"
17714 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17715 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17717 (use (match_operand:HI 2 "memory_operand" "m,m"))
17718 (use (match_operand:HI 3 "memory_operand" "m,m"))
17719 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17720 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17721 "TARGET_USE_FANCY_MATH_387
17722 && flag_unsafe_math_optimizations"
17724 [(set_attr "type" "fistp")
17725 (set_attr "i387_cw" "ceil")
17726 (set_attr "mode" "DI")])
17729 [(set (match_operand:DI 0 "register_operand" "")
17730 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17732 (use (match_operand:HI 2 "memory_operand" ""))
17733 (use (match_operand:HI 3 "memory_operand" ""))
17734 (clobber (match_operand:DI 4 "memory_operand" ""))
17735 (clobber (match_scratch 5 ""))]
17737 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17738 (use (match_dup 2))
17739 (use (match_dup 3))
17740 (clobber (match_dup 5))])
17741 (set (match_dup 0) (match_dup 4))]
17745 [(set (match_operand:DI 0 "memory_operand" "")
17746 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17748 (use (match_operand:HI 2 "memory_operand" ""))
17749 (use (match_operand:HI 3 "memory_operand" ""))
17750 (clobber (match_operand:DI 4 "memory_operand" ""))
17751 (clobber (match_scratch 5 ""))]
17753 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17754 (use (match_dup 2))
17755 (use (match_dup 3))
17756 (clobber (match_dup 5))])]
17759 (define_insn "fist<mode>2_ceil"
17760 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17761 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17763 (use (match_operand:HI 2 "memory_operand" "m"))
17764 (use (match_operand:HI 3 "memory_operand" "m"))]
17765 "TARGET_USE_FANCY_MATH_387
17766 && flag_unsafe_math_optimizations"
17767 "* return output_fix_trunc (insn, operands, 0);"
17768 [(set_attr "type" "fistp")
17769 (set_attr "i387_cw" "ceil")
17770 (set_attr "mode" "<MODE>")])
17772 (define_insn "fist<mode>2_ceil_with_temp"
17773 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17774 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17776 (use (match_operand:HI 2 "memory_operand" "m,m"))
17777 (use (match_operand:HI 3 "memory_operand" "m,m"))
17778 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17779 "TARGET_USE_FANCY_MATH_387
17780 && flag_unsafe_math_optimizations"
17782 [(set_attr "type" "fistp")
17783 (set_attr "i387_cw" "ceil")
17784 (set_attr "mode" "<MODE>")])
17787 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17788 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17790 (use (match_operand:HI 2 "memory_operand" ""))
17791 (use (match_operand:HI 3 "memory_operand" ""))
17792 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17794 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17796 (use (match_dup 2))
17797 (use (match_dup 3))])
17798 (set (match_dup 0) (match_dup 4))]
17802 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17803 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17805 (use (match_operand:HI 2 "memory_operand" ""))
17806 (use (match_operand:HI 3 "memory_operand" ""))
17807 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17809 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17811 (use (match_dup 2))
17812 (use (match_dup 3))])]
17815 (define_expand "lceil<mode>2"
17816 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17817 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17819 (clobber (reg:CC FLAGS_REG))])]
17820 "TARGET_USE_FANCY_MATH_387
17821 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17822 && flag_unsafe_math_optimizations"
17825 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17826 (define_insn_and_split "frndintxf2_trunc"
17827 [(set (match_operand:XF 0 "register_operand" "=f")
17828 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17829 UNSPEC_FRNDINT_TRUNC))
17830 (clobber (reg:CC FLAGS_REG))]
17831 "TARGET_USE_FANCY_MATH_387
17832 && flag_unsafe_math_optimizations
17833 && !(reload_completed || reload_in_progress)"
17838 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17840 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17841 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17843 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17844 operands[2], operands[3]));
17847 [(set_attr "type" "frndint")
17848 (set_attr "i387_cw" "trunc")
17849 (set_attr "mode" "XF")])
17851 (define_insn "frndintxf2_trunc_i387"
17852 [(set (match_operand:XF 0 "register_operand" "=f")
17853 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17854 UNSPEC_FRNDINT_TRUNC))
17855 (use (match_operand:HI 2 "memory_operand" "m"))
17856 (use (match_operand:HI 3 "memory_operand" "m"))]
17857 "TARGET_USE_FANCY_MATH_387
17858 && flag_unsafe_math_optimizations"
17859 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17860 [(set_attr "type" "frndint")
17861 (set_attr "i387_cw" "trunc")
17862 (set_attr "mode" "XF")])
17864 (define_expand "btruncxf2"
17865 [(use (match_operand:XF 0 "register_operand" ""))
17866 (use (match_operand:XF 1 "register_operand" ""))]
17867 "TARGET_USE_FANCY_MATH_387
17868 && flag_unsafe_math_optimizations"
17870 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17874 (define_expand "btruncdf2"
17875 [(use (match_operand:DF 0 "register_operand" ""))
17876 (use (match_operand:DF 1 "register_operand" ""))]
17877 "TARGET_USE_FANCY_MATH_387
17878 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17879 && flag_unsafe_math_optimizations"
17881 rtx op0 = gen_reg_rtx (XFmode);
17882 rtx op1 = gen_reg_rtx (XFmode);
17884 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17885 emit_insn (gen_frndintxf2_trunc (op0, op1));
17887 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17891 (define_expand "btruncsf2"
17892 [(use (match_operand:SF 0 "register_operand" ""))
17893 (use (match_operand:SF 1 "register_operand" ""))]
17894 "TARGET_USE_FANCY_MATH_387
17895 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17896 && flag_unsafe_math_optimizations"
17898 rtx op0 = gen_reg_rtx (XFmode);
17899 rtx op1 = gen_reg_rtx (XFmode);
17901 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17902 emit_insn (gen_frndintxf2_trunc (op0, op1));
17904 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17908 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17909 (define_insn_and_split "frndintxf2_mask_pm"
17910 [(set (match_operand:XF 0 "register_operand" "=f")
17911 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17912 UNSPEC_FRNDINT_MASK_PM))
17913 (clobber (reg:CC FLAGS_REG))]
17914 "TARGET_USE_FANCY_MATH_387
17915 && flag_unsafe_math_optimizations
17916 && !(reload_completed || reload_in_progress)"
17921 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17923 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17924 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17926 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17927 operands[2], operands[3]));
17930 [(set_attr "type" "frndint")
17931 (set_attr "i387_cw" "mask_pm")
17932 (set_attr "mode" "XF")])
17934 (define_insn "frndintxf2_mask_pm_i387"
17935 [(set (match_operand:XF 0 "register_operand" "=f")
17936 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17937 UNSPEC_FRNDINT_MASK_PM))
17938 (use (match_operand:HI 2 "memory_operand" "m"))
17939 (use (match_operand:HI 3 "memory_operand" "m"))]
17940 "TARGET_USE_FANCY_MATH_387
17941 && flag_unsafe_math_optimizations"
17942 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17943 [(set_attr "type" "frndint")
17944 (set_attr "i387_cw" "mask_pm")
17945 (set_attr "mode" "XF")])
17947 (define_expand "nearbyintxf2"
17948 [(use (match_operand:XF 0 "register_operand" ""))
17949 (use (match_operand:XF 1 "register_operand" ""))]
17950 "TARGET_USE_FANCY_MATH_387
17951 && flag_unsafe_math_optimizations"
17953 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17958 (define_expand "nearbyintdf2"
17959 [(use (match_operand:DF 0 "register_operand" ""))
17960 (use (match_operand:DF 1 "register_operand" ""))]
17961 "TARGET_USE_FANCY_MATH_387
17962 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17963 && flag_unsafe_math_optimizations"
17965 rtx op0 = gen_reg_rtx (XFmode);
17966 rtx op1 = gen_reg_rtx (XFmode);
17968 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17969 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17971 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17975 (define_expand "nearbyintsf2"
17976 [(use (match_operand:SF 0 "register_operand" ""))
17977 (use (match_operand:SF 1 "register_operand" ""))]
17978 "TARGET_USE_FANCY_MATH_387
17979 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17980 && flag_unsafe_math_optimizations"
17982 rtx op0 = gen_reg_rtx (XFmode);
17983 rtx op1 = gen_reg_rtx (XFmode);
17985 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17986 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17988 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17993 ;; Block operation instructions
17996 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17999 [(set_attr "type" "cld")])
18001 (define_expand "movmemsi"
18002 [(use (match_operand:BLK 0 "memory_operand" ""))
18003 (use (match_operand:BLK 1 "memory_operand" ""))
18004 (use (match_operand:SI 2 "nonmemory_operand" ""))
18005 (use (match_operand:SI 3 "const_int_operand" ""))]
18006 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18008 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18014 (define_expand "movmemdi"
18015 [(use (match_operand:BLK 0 "memory_operand" ""))
18016 (use (match_operand:BLK 1 "memory_operand" ""))
18017 (use (match_operand:DI 2 "nonmemory_operand" ""))
18018 (use (match_operand:DI 3 "const_int_operand" ""))]
18021 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18027 ;; Most CPUs don't like single string operations
18028 ;; Handle this case here to simplify previous expander.
18030 (define_expand "strmov"
18031 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18032 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18033 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18034 (clobber (reg:CC FLAGS_REG))])
18035 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18036 (clobber (reg:CC FLAGS_REG))])]
18039 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18041 /* If .md ever supports :P for Pmode, these can be directly
18042 in the pattern above. */
18043 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18044 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18046 if (TARGET_SINGLE_STRINGOP || optimize_size)
18048 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18049 operands[2], operands[3],
18050 operands[5], operands[6]));
18054 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18057 (define_expand "strmov_singleop"
18058 [(parallel [(set (match_operand 1 "memory_operand" "")
18059 (match_operand 3 "memory_operand" ""))
18060 (set (match_operand 0 "register_operand" "")
18061 (match_operand 4 "" ""))
18062 (set (match_operand 2 "register_operand" "")
18063 (match_operand 5 "" ""))
18064 (use (reg:SI DIRFLAG_REG))])]
18065 "TARGET_SINGLE_STRINGOP || optimize_size"
18068 (define_insn "*strmovdi_rex_1"
18069 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18070 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18071 (set (match_operand:DI 0 "register_operand" "=D")
18072 (plus:DI (match_dup 2)
18074 (set (match_operand:DI 1 "register_operand" "=S")
18075 (plus:DI (match_dup 3)
18077 (use (reg:SI DIRFLAG_REG))]
18078 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18080 [(set_attr "type" "str")
18081 (set_attr "mode" "DI")
18082 (set_attr "memory" "both")])
18084 (define_insn "*strmovsi_1"
18085 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18086 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18087 (set (match_operand:SI 0 "register_operand" "=D")
18088 (plus:SI (match_dup 2)
18090 (set (match_operand:SI 1 "register_operand" "=S")
18091 (plus:SI (match_dup 3)
18093 (use (reg:SI DIRFLAG_REG))]
18094 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18096 [(set_attr "type" "str")
18097 (set_attr "mode" "SI")
18098 (set_attr "memory" "both")])
18100 (define_insn "*strmovsi_rex_1"
18101 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18102 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18103 (set (match_operand:DI 0 "register_operand" "=D")
18104 (plus:DI (match_dup 2)
18106 (set (match_operand:DI 1 "register_operand" "=S")
18107 (plus:DI (match_dup 3)
18109 (use (reg:SI DIRFLAG_REG))]
18110 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18112 [(set_attr "type" "str")
18113 (set_attr "mode" "SI")
18114 (set_attr "memory" "both")])
18116 (define_insn "*strmovhi_1"
18117 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18118 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18119 (set (match_operand:SI 0 "register_operand" "=D")
18120 (plus:SI (match_dup 2)
18122 (set (match_operand:SI 1 "register_operand" "=S")
18123 (plus:SI (match_dup 3)
18125 (use (reg:SI DIRFLAG_REG))]
18126 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18128 [(set_attr "type" "str")
18129 (set_attr "memory" "both")
18130 (set_attr "mode" "HI")])
18132 (define_insn "*strmovhi_rex_1"
18133 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18134 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18135 (set (match_operand:DI 0 "register_operand" "=D")
18136 (plus:DI (match_dup 2)
18138 (set (match_operand:DI 1 "register_operand" "=S")
18139 (plus:DI (match_dup 3)
18141 (use (reg:SI DIRFLAG_REG))]
18142 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18144 [(set_attr "type" "str")
18145 (set_attr "memory" "both")
18146 (set_attr "mode" "HI")])
18148 (define_insn "*strmovqi_1"
18149 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18150 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18151 (set (match_operand:SI 0 "register_operand" "=D")
18152 (plus:SI (match_dup 2)
18154 (set (match_operand:SI 1 "register_operand" "=S")
18155 (plus:SI (match_dup 3)
18157 (use (reg:SI DIRFLAG_REG))]
18158 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18160 [(set_attr "type" "str")
18161 (set_attr "memory" "both")
18162 (set_attr "mode" "QI")])
18164 (define_insn "*strmovqi_rex_1"
18165 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18166 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18167 (set (match_operand:DI 0 "register_operand" "=D")
18168 (plus:DI (match_dup 2)
18170 (set (match_operand:DI 1 "register_operand" "=S")
18171 (plus:DI (match_dup 3)
18173 (use (reg:SI DIRFLAG_REG))]
18174 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18176 [(set_attr "type" "str")
18177 (set_attr "memory" "both")
18178 (set_attr "mode" "QI")])
18180 (define_expand "rep_mov"
18181 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18182 (set (match_operand 0 "register_operand" "")
18183 (match_operand 5 "" ""))
18184 (set (match_operand 2 "register_operand" "")
18185 (match_operand 6 "" ""))
18186 (set (match_operand 1 "memory_operand" "")
18187 (match_operand 3 "memory_operand" ""))
18188 (use (match_dup 4))
18189 (use (reg:SI DIRFLAG_REG))])]
18193 (define_insn "*rep_movdi_rex64"
18194 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18195 (set (match_operand:DI 0 "register_operand" "=D")
18196 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18198 (match_operand:DI 3 "register_operand" "0")))
18199 (set (match_operand:DI 1 "register_operand" "=S")
18200 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18201 (match_operand:DI 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\;movsq|rep movsq}"
18208 [(set_attr "type" "str")
18209 (set_attr "prefix_rep" "1")
18210 (set_attr "memory" "both")
18211 (set_attr "mode" "DI")])
18213 (define_insn "*rep_movsi"
18214 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18215 (set (match_operand:SI 0 "register_operand" "=D")
18216 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18218 (match_operand:SI 3 "register_operand" "0")))
18219 (set (match_operand:SI 1 "register_operand" "=S")
18220 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18221 (match_operand:SI 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_movsi_rex64"
18234 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18235 (set (match_operand:DI 0 "register_operand" "=D")
18236 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18238 (match_operand:DI 3 "register_operand" "0")))
18239 (set (match_operand:DI 1 "register_operand" "=S")
18240 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18241 (match_operand:DI 4 "register_operand" "1")))
18242 (set (mem:BLK (match_dup 3))
18243 (mem:BLK (match_dup 4)))
18244 (use (match_dup 5))
18245 (use (reg:SI DIRFLAG_REG))]
18247 "{rep\;movsl|rep movsd}"
18248 [(set_attr "type" "str")
18249 (set_attr "prefix_rep" "1")
18250 (set_attr "memory" "both")
18251 (set_attr "mode" "SI")])
18253 (define_insn "*rep_movqi"
18254 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18255 (set (match_operand:SI 0 "register_operand" "=D")
18256 (plus:SI (match_operand:SI 3 "register_operand" "0")
18257 (match_operand:SI 5 "register_operand" "2")))
18258 (set (match_operand:SI 1 "register_operand" "=S")
18259 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18260 (set (mem:BLK (match_dup 3))
18261 (mem:BLK (match_dup 4)))
18262 (use (match_dup 5))
18263 (use (reg:SI DIRFLAG_REG))]
18265 "{rep\;movsb|rep movsb}"
18266 [(set_attr "type" "str")
18267 (set_attr "prefix_rep" "1")
18268 (set_attr "memory" "both")
18269 (set_attr "mode" "SI")])
18271 (define_insn "*rep_movqi_rex64"
18272 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18273 (set (match_operand:DI 0 "register_operand" "=D")
18274 (plus:DI (match_operand:DI 3 "register_operand" "0")
18275 (match_operand:DI 5 "register_operand" "2")))
18276 (set (match_operand:DI 1 "register_operand" "=S")
18277 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18278 (set (mem:BLK (match_dup 3))
18279 (mem:BLK (match_dup 4)))
18280 (use (match_dup 5))
18281 (use (reg:SI DIRFLAG_REG))]
18283 "{rep\;movsb|rep movsb}"
18284 [(set_attr "type" "str")
18285 (set_attr "prefix_rep" "1")
18286 (set_attr "memory" "both")
18287 (set_attr "mode" "SI")])
18289 (define_expand "setmemsi"
18290 [(use (match_operand:BLK 0 "memory_operand" ""))
18291 (use (match_operand:SI 1 "nonmemory_operand" ""))
18292 (use (match_operand 2 "const_int_operand" ""))
18293 (use (match_operand 3 "const_int_operand" ""))]
18296 /* If value to set is not zero, use the library routine. */
18297 if (operands[2] != const0_rtx)
18300 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18306 (define_expand "setmemdi"
18307 [(use (match_operand:BLK 0 "memory_operand" ""))
18308 (use (match_operand:DI 1 "nonmemory_operand" ""))
18309 (use (match_operand 2 "const_int_operand" ""))
18310 (use (match_operand 3 "const_int_operand" ""))]
18313 /* If value to set is not zero, use the library routine. */
18314 if (operands[2] != const0_rtx)
18317 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18323 ;; Most CPUs don't like single string operations
18324 ;; Handle this case here to simplify previous expander.
18326 (define_expand "strset"
18327 [(set (match_operand 1 "memory_operand" "")
18328 (match_operand 2 "register_operand" ""))
18329 (parallel [(set (match_operand 0 "register_operand" "")
18331 (clobber (reg:CC FLAGS_REG))])]
18334 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18335 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18337 /* If .md ever supports :P for Pmode, this can be directly
18338 in the pattern above. */
18339 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18340 GEN_INT (GET_MODE_SIZE (GET_MODE
18342 if (TARGET_SINGLE_STRINGOP || optimize_size)
18344 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18350 (define_expand "strset_singleop"
18351 [(parallel [(set (match_operand 1 "memory_operand" "")
18352 (match_operand 2 "register_operand" ""))
18353 (set (match_operand 0 "register_operand" "")
18354 (match_operand 3 "" ""))
18355 (use (reg:SI DIRFLAG_REG))])]
18356 "TARGET_SINGLE_STRINGOP || optimize_size"
18359 (define_insn "*strsetdi_rex_1"
18360 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18361 (match_operand:DI 2 "register_operand" "a"))
18362 (set (match_operand:DI 0 "register_operand" "=D")
18363 (plus:DI (match_dup 1)
18365 (use (reg:SI DIRFLAG_REG))]
18366 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18368 [(set_attr "type" "str")
18369 (set_attr "memory" "store")
18370 (set_attr "mode" "DI")])
18372 (define_insn "*strsetsi_1"
18373 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18374 (match_operand:SI 2 "register_operand" "a"))
18375 (set (match_operand:SI 0 "register_operand" "=D")
18376 (plus:SI (match_dup 1)
18378 (use (reg:SI DIRFLAG_REG))]
18379 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18381 [(set_attr "type" "str")
18382 (set_attr "memory" "store")
18383 (set_attr "mode" "SI")])
18385 (define_insn "*strsetsi_rex_1"
18386 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18387 (match_operand:SI 2 "register_operand" "a"))
18388 (set (match_operand:DI 0 "register_operand" "=D")
18389 (plus:DI (match_dup 1)
18391 (use (reg:SI DIRFLAG_REG))]
18392 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18394 [(set_attr "type" "str")
18395 (set_attr "memory" "store")
18396 (set_attr "mode" "SI")])
18398 (define_insn "*strsethi_1"
18399 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18400 (match_operand:HI 2 "register_operand" "a"))
18401 (set (match_operand:SI 0 "register_operand" "=D")
18402 (plus:SI (match_dup 1)
18404 (use (reg:SI DIRFLAG_REG))]
18405 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18407 [(set_attr "type" "str")
18408 (set_attr "memory" "store")
18409 (set_attr "mode" "HI")])
18411 (define_insn "*strsethi_rex_1"
18412 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18413 (match_operand:HI 2 "register_operand" "a"))
18414 (set (match_operand:DI 0 "register_operand" "=D")
18415 (plus:DI (match_dup 1)
18417 (use (reg:SI DIRFLAG_REG))]
18418 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18420 [(set_attr "type" "str")
18421 (set_attr "memory" "store")
18422 (set_attr "mode" "HI")])
18424 (define_insn "*strsetqi_1"
18425 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18426 (match_operand:QI 2 "register_operand" "a"))
18427 (set (match_operand:SI 0 "register_operand" "=D")
18428 (plus:SI (match_dup 1)
18430 (use (reg:SI DIRFLAG_REG))]
18431 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18433 [(set_attr "type" "str")
18434 (set_attr "memory" "store")
18435 (set_attr "mode" "QI")])
18437 (define_insn "*strsetqi_rex_1"
18438 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18439 (match_operand:QI 2 "register_operand" "a"))
18440 (set (match_operand:DI 0 "register_operand" "=D")
18441 (plus:DI (match_dup 1)
18443 (use (reg:SI DIRFLAG_REG))]
18444 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18446 [(set_attr "type" "str")
18447 (set_attr "memory" "store")
18448 (set_attr "mode" "QI")])
18450 (define_expand "rep_stos"
18451 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18452 (set (match_operand 0 "register_operand" "")
18453 (match_operand 4 "" ""))
18454 (set (match_operand 2 "memory_operand" "") (const_int 0))
18455 (use (match_operand 3 "register_operand" ""))
18456 (use (match_dup 1))
18457 (use (reg:SI DIRFLAG_REG))])]
18461 (define_insn "*rep_stosdi_rex64"
18462 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18463 (set (match_operand:DI 0 "register_operand" "=D")
18464 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18466 (match_operand:DI 3 "register_operand" "0")))
18467 (set (mem:BLK (match_dup 3))
18469 (use (match_operand:DI 2 "register_operand" "a"))
18470 (use (match_dup 4))
18471 (use (reg:SI DIRFLAG_REG))]
18473 "{rep\;stosq|rep stosq}"
18474 [(set_attr "type" "str")
18475 (set_attr "prefix_rep" "1")
18476 (set_attr "memory" "store")
18477 (set_attr "mode" "DI")])
18479 (define_insn "*rep_stossi"
18480 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18481 (set (match_operand:SI 0 "register_operand" "=D")
18482 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18484 (match_operand:SI 3 "register_operand" "0")))
18485 (set (mem:BLK (match_dup 3))
18487 (use (match_operand:SI 2 "register_operand" "a"))
18488 (use (match_dup 4))
18489 (use (reg:SI DIRFLAG_REG))]
18491 "{rep\;stosl|rep stosd}"
18492 [(set_attr "type" "str")
18493 (set_attr "prefix_rep" "1")
18494 (set_attr "memory" "store")
18495 (set_attr "mode" "SI")])
18497 (define_insn "*rep_stossi_rex64"
18498 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18499 (set (match_operand:DI 0 "register_operand" "=D")
18500 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18502 (match_operand:DI 3 "register_operand" "0")))
18503 (set (mem:BLK (match_dup 3))
18505 (use (match_operand:SI 2 "register_operand" "a"))
18506 (use (match_dup 4))
18507 (use (reg:SI DIRFLAG_REG))]
18509 "{rep\;stosl|rep stosd}"
18510 [(set_attr "type" "str")
18511 (set_attr "prefix_rep" "1")
18512 (set_attr "memory" "store")
18513 (set_attr "mode" "SI")])
18515 (define_insn "*rep_stosqi"
18516 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18517 (set (match_operand:SI 0 "register_operand" "=D")
18518 (plus:SI (match_operand:SI 3 "register_operand" "0")
18519 (match_operand:SI 4 "register_operand" "1")))
18520 (set (mem:BLK (match_dup 3))
18522 (use (match_operand:QI 2 "register_operand" "a"))
18523 (use (match_dup 4))
18524 (use (reg:SI DIRFLAG_REG))]
18526 "{rep\;stosb|rep stosb}"
18527 [(set_attr "type" "str")
18528 (set_attr "prefix_rep" "1")
18529 (set_attr "memory" "store")
18530 (set_attr "mode" "QI")])
18532 (define_insn "*rep_stosqi_rex64"
18533 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18534 (set (match_operand:DI 0 "register_operand" "=D")
18535 (plus:DI (match_operand:DI 3 "register_operand" "0")
18536 (match_operand:DI 4 "register_operand" "1")))
18537 (set (mem:BLK (match_dup 3))
18539 (use (match_operand:QI 2 "register_operand" "a"))
18540 (use (match_dup 4))
18541 (use (reg:SI DIRFLAG_REG))]
18543 "{rep\;stosb|rep stosb}"
18544 [(set_attr "type" "str")
18545 (set_attr "prefix_rep" "1")
18546 (set_attr "memory" "store")
18547 (set_attr "mode" "QI")])
18549 (define_expand "cmpstrnsi"
18550 [(set (match_operand:SI 0 "register_operand" "")
18551 (compare:SI (match_operand:BLK 1 "general_operand" "")
18552 (match_operand:BLK 2 "general_operand" "")))
18553 (use (match_operand 3 "general_operand" ""))
18554 (use (match_operand 4 "immediate_operand" ""))]
18555 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18557 rtx addr1, addr2, out, outlow, count, countreg, align;
18559 /* Can't use this if the user has appropriated esi or edi. */
18560 if (global_regs[4] || global_regs[5])
18564 if (GET_CODE (out) != REG)
18565 out = gen_reg_rtx (SImode);
18567 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18568 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18569 if (addr1 != XEXP (operands[1], 0))
18570 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18571 if (addr2 != XEXP (operands[2], 0))
18572 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18574 count = operands[3];
18575 countreg = ix86_zero_extend_to_Pmode (count);
18577 /* %%% Iff we are testing strict equality, we can use known alignment
18578 to good advantage. This may be possible with combine, particularly
18579 once cc0 is dead. */
18580 align = operands[4];
18582 emit_insn (gen_cld ());
18583 if (GET_CODE (count) == CONST_INT)
18585 if (INTVAL (count) == 0)
18587 emit_move_insn (operands[0], const0_rtx);
18590 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18591 operands[1], operands[2]));
18596 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18598 emit_insn (gen_cmpsi_1 (countreg, countreg));
18599 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18600 operands[1], operands[2]));
18603 outlow = gen_lowpart (QImode, out);
18604 emit_insn (gen_cmpintqi (outlow));
18605 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18607 if (operands[0] != out)
18608 emit_move_insn (operands[0], out);
18613 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18615 (define_expand "cmpintqi"
18616 [(set (match_dup 1)
18617 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18619 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18620 (parallel [(set (match_operand:QI 0 "register_operand" "")
18621 (minus:QI (match_dup 1)
18623 (clobber (reg:CC FLAGS_REG))])]
18625 "operands[1] = gen_reg_rtx (QImode);
18626 operands[2] = gen_reg_rtx (QImode);")
18628 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18629 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18631 (define_expand "cmpstrnqi_nz_1"
18632 [(parallel [(set (reg:CC FLAGS_REG)
18633 (compare:CC (match_operand 4 "memory_operand" "")
18634 (match_operand 5 "memory_operand" "")))
18635 (use (match_operand 2 "register_operand" ""))
18636 (use (match_operand:SI 3 "immediate_operand" ""))
18637 (use (reg:SI DIRFLAG_REG))
18638 (clobber (match_operand 0 "register_operand" ""))
18639 (clobber (match_operand 1 "register_operand" ""))
18640 (clobber (match_dup 2))])]
18644 (define_insn "*cmpstrnqi_nz_1"
18645 [(set (reg:CC FLAGS_REG)
18646 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18647 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18648 (use (match_operand:SI 6 "register_operand" "2"))
18649 (use (match_operand:SI 3 "immediate_operand" "i"))
18650 (use (reg:SI DIRFLAG_REG))
18651 (clobber (match_operand:SI 0 "register_operand" "=S"))
18652 (clobber (match_operand:SI 1 "register_operand" "=D"))
18653 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18656 [(set_attr "type" "str")
18657 (set_attr "mode" "QI")
18658 (set_attr "prefix_rep" "1")])
18660 (define_insn "*cmpstrnqi_nz_rex_1"
18661 [(set (reg:CC FLAGS_REG)
18662 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18663 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18664 (use (match_operand:DI 6 "register_operand" "2"))
18665 (use (match_operand:SI 3 "immediate_operand" "i"))
18666 (use (reg:SI DIRFLAG_REG))
18667 (clobber (match_operand:DI 0 "register_operand" "=S"))
18668 (clobber (match_operand:DI 1 "register_operand" "=D"))
18669 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18672 [(set_attr "type" "str")
18673 (set_attr "mode" "QI")
18674 (set_attr "prefix_rep" "1")])
18676 ;; The same, but the count is not known to not be zero.
18678 (define_expand "cmpstrnqi_1"
18679 [(parallel [(set (reg:CC FLAGS_REG)
18680 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18682 (compare:CC (match_operand 4 "memory_operand" "")
18683 (match_operand 5 "memory_operand" ""))
18685 (use (match_operand:SI 3 "immediate_operand" ""))
18686 (use (reg:CC FLAGS_REG))
18687 (use (reg:SI DIRFLAG_REG))
18688 (clobber (match_operand 0 "register_operand" ""))
18689 (clobber (match_operand 1 "register_operand" ""))
18690 (clobber (match_dup 2))])]
18694 (define_insn "*cmpstrnqi_1"
18695 [(set (reg:CC FLAGS_REG)
18696 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18698 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18699 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18701 (use (match_operand:SI 3 "immediate_operand" "i"))
18702 (use (reg:CC FLAGS_REG))
18703 (use (reg:SI DIRFLAG_REG))
18704 (clobber (match_operand:SI 0 "register_operand" "=S"))
18705 (clobber (match_operand:SI 1 "register_operand" "=D"))
18706 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18709 [(set_attr "type" "str")
18710 (set_attr "mode" "QI")
18711 (set_attr "prefix_rep" "1")])
18713 (define_insn "*cmpstrnqi_rex_1"
18714 [(set (reg:CC FLAGS_REG)
18715 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18717 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18718 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18720 (use (match_operand:SI 3 "immediate_operand" "i"))
18721 (use (reg:CC FLAGS_REG))
18722 (use (reg:SI DIRFLAG_REG))
18723 (clobber (match_operand:DI 0 "register_operand" "=S"))
18724 (clobber (match_operand:DI 1 "register_operand" "=D"))
18725 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18728 [(set_attr "type" "str")
18729 (set_attr "mode" "QI")
18730 (set_attr "prefix_rep" "1")])
18732 (define_expand "strlensi"
18733 [(set (match_operand:SI 0 "register_operand" "")
18734 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18735 (match_operand:QI 2 "immediate_operand" "")
18736 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18739 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18745 (define_expand "strlendi"
18746 [(set (match_operand:DI 0 "register_operand" "")
18747 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18748 (match_operand:QI 2 "immediate_operand" "")
18749 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18752 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18758 (define_expand "strlenqi_1"
18759 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18760 (use (reg:SI DIRFLAG_REG))
18761 (clobber (match_operand 1 "register_operand" ""))
18762 (clobber (reg:CC FLAGS_REG))])]
18766 (define_insn "*strlenqi_1"
18767 [(set (match_operand:SI 0 "register_operand" "=&c")
18768 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18769 (match_operand:QI 2 "register_operand" "a")
18770 (match_operand:SI 3 "immediate_operand" "i")
18771 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18772 (use (reg:SI DIRFLAG_REG))
18773 (clobber (match_operand:SI 1 "register_operand" "=D"))
18774 (clobber (reg:CC FLAGS_REG))]
18777 [(set_attr "type" "str")
18778 (set_attr "mode" "QI")
18779 (set_attr "prefix_rep" "1")])
18781 (define_insn "*strlenqi_rex_1"
18782 [(set (match_operand:DI 0 "register_operand" "=&c")
18783 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18784 (match_operand:QI 2 "register_operand" "a")
18785 (match_operand:DI 3 "immediate_operand" "i")
18786 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18787 (use (reg:SI DIRFLAG_REG))
18788 (clobber (match_operand:DI 1 "register_operand" "=D"))
18789 (clobber (reg:CC FLAGS_REG))]
18792 [(set_attr "type" "str")
18793 (set_attr "mode" "QI")
18794 (set_attr "prefix_rep" "1")])
18796 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18797 ;; handled in combine, but it is not currently up to the task.
18798 ;; When used for their truth value, the cmpstrn* expanders generate
18807 ;; The intermediate three instructions are unnecessary.
18809 ;; This one handles cmpstrn*_nz_1...
18812 (set (reg:CC FLAGS_REG)
18813 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18814 (mem:BLK (match_operand 5 "register_operand" ""))))
18815 (use (match_operand 6 "register_operand" ""))
18816 (use (match_operand:SI 3 "immediate_operand" ""))
18817 (use (reg:SI DIRFLAG_REG))
18818 (clobber (match_operand 0 "register_operand" ""))
18819 (clobber (match_operand 1 "register_operand" ""))
18820 (clobber (match_operand 2 "register_operand" ""))])
18821 (set (match_operand:QI 7 "register_operand" "")
18822 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18823 (set (match_operand:QI 8 "register_operand" "")
18824 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18825 (set (reg FLAGS_REG)
18826 (compare (match_dup 7) (match_dup 8)))
18828 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18830 (set (reg:CC FLAGS_REG)
18831 (compare:CC (mem:BLK (match_dup 4))
18832 (mem:BLK (match_dup 5))))
18833 (use (match_dup 6))
18834 (use (match_dup 3))
18835 (use (reg:SI DIRFLAG_REG))
18836 (clobber (match_dup 0))
18837 (clobber (match_dup 1))
18838 (clobber (match_dup 2))])]
18841 ;; ...and this one handles cmpstrn*_1.
18844 (set (reg:CC FLAGS_REG)
18845 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18847 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18848 (mem:BLK (match_operand 5 "register_operand" "")))
18850 (use (match_operand:SI 3 "immediate_operand" ""))
18851 (use (reg:CC FLAGS_REG))
18852 (use (reg:SI DIRFLAG_REG))
18853 (clobber (match_operand 0 "register_operand" ""))
18854 (clobber (match_operand 1 "register_operand" ""))
18855 (clobber (match_operand 2 "register_operand" ""))])
18856 (set (match_operand:QI 7 "register_operand" "")
18857 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18858 (set (match_operand:QI 8 "register_operand" "")
18859 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18860 (set (reg FLAGS_REG)
18861 (compare (match_dup 7) (match_dup 8)))
18863 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18865 (set (reg:CC FLAGS_REG)
18866 (if_then_else:CC (ne (match_dup 6)
18868 (compare:CC (mem:BLK (match_dup 4))
18869 (mem:BLK (match_dup 5)))
18871 (use (match_dup 3))
18872 (use (reg:CC FLAGS_REG))
18873 (use (reg:SI DIRFLAG_REG))
18874 (clobber (match_dup 0))
18875 (clobber (match_dup 1))
18876 (clobber (match_dup 2))])]
18881 ;; Conditional move instructions.
18883 (define_expand "movdicc"
18884 [(set (match_operand:DI 0 "register_operand" "")
18885 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18886 (match_operand:DI 2 "general_operand" "")
18887 (match_operand:DI 3 "general_operand" "")))]
18889 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18891 (define_insn "x86_movdicc_0_m1_rex64"
18892 [(set (match_operand:DI 0 "register_operand" "=r")
18893 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18896 (clobber (reg:CC FLAGS_REG))]
18899 ; Since we don't have the proper number of operands for an alu insn,
18900 ; fill in all the blanks.
18901 [(set_attr "type" "alu")
18902 (set_attr "pent_pair" "pu")
18903 (set_attr "memory" "none")
18904 (set_attr "imm_disp" "false")
18905 (set_attr "mode" "DI")
18906 (set_attr "length_immediate" "0")])
18908 (define_insn "*movdicc_c_rex64"
18909 [(set (match_operand:DI 0 "register_operand" "=r,r")
18910 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18911 [(reg FLAGS_REG) (const_int 0)])
18912 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18913 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18914 "TARGET_64BIT && TARGET_CMOVE
18915 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18917 cmov%O2%C1\t{%2, %0|%0, %2}
18918 cmov%O2%c1\t{%3, %0|%0, %3}"
18919 [(set_attr "type" "icmov")
18920 (set_attr "mode" "DI")])
18922 (define_expand "movsicc"
18923 [(set (match_operand:SI 0 "register_operand" "")
18924 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18925 (match_operand:SI 2 "general_operand" "")
18926 (match_operand:SI 3 "general_operand" "")))]
18928 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18930 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18931 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18932 ;; So just document what we're doing explicitly.
18934 (define_insn "x86_movsicc_0_m1"
18935 [(set (match_operand:SI 0 "register_operand" "=r")
18936 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18939 (clobber (reg:CC FLAGS_REG))]
18942 ; Since we don't have the proper number of operands for an alu insn,
18943 ; fill in all the blanks.
18944 [(set_attr "type" "alu")
18945 (set_attr "pent_pair" "pu")
18946 (set_attr "memory" "none")
18947 (set_attr "imm_disp" "false")
18948 (set_attr "mode" "SI")
18949 (set_attr "length_immediate" "0")])
18951 (define_insn "*movsicc_noc"
18952 [(set (match_operand:SI 0 "register_operand" "=r,r")
18953 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18954 [(reg FLAGS_REG) (const_int 0)])
18955 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18956 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18958 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18960 cmov%O2%C1\t{%2, %0|%0, %2}
18961 cmov%O2%c1\t{%3, %0|%0, %3}"
18962 [(set_attr "type" "icmov")
18963 (set_attr "mode" "SI")])
18965 (define_expand "movhicc"
18966 [(set (match_operand:HI 0 "register_operand" "")
18967 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18968 (match_operand:HI 2 "general_operand" "")
18969 (match_operand:HI 3 "general_operand" "")))]
18970 "TARGET_HIMODE_MATH"
18971 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18973 (define_insn "*movhicc_noc"
18974 [(set (match_operand:HI 0 "register_operand" "=r,r")
18975 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18976 [(reg FLAGS_REG) (const_int 0)])
18977 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18978 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18980 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18982 cmov%O2%C1\t{%2, %0|%0, %2}
18983 cmov%O2%c1\t{%3, %0|%0, %3}"
18984 [(set_attr "type" "icmov")
18985 (set_attr "mode" "HI")])
18987 (define_expand "movqicc"
18988 [(set (match_operand:QI 0 "register_operand" "")
18989 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18990 (match_operand:QI 2 "general_operand" "")
18991 (match_operand:QI 3 "general_operand" "")))]
18992 "TARGET_QIMODE_MATH"
18993 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18995 (define_insn_and_split "*movqicc_noc"
18996 [(set (match_operand:QI 0 "register_operand" "=r,r")
18997 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18998 [(match_operand 4 "flags_reg_operand" "")
19000 (match_operand:QI 2 "register_operand" "r,0")
19001 (match_operand:QI 3 "register_operand" "0,r")))]
19002 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19004 "&& reload_completed"
19005 [(set (match_dup 0)
19006 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19009 "operands[0] = gen_lowpart (SImode, operands[0]);
19010 operands[2] = gen_lowpart (SImode, operands[2]);
19011 operands[3] = gen_lowpart (SImode, operands[3]);"
19012 [(set_attr "type" "icmov")
19013 (set_attr "mode" "SI")])
19015 (define_expand "movsfcc"
19016 [(set (match_operand:SF 0 "register_operand" "")
19017 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19018 (match_operand:SF 2 "register_operand" "")
19019 (match_operand:SF 3 "register_operand" "")))]
19020 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19021 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19023 (define_insn "*movsfcc_1_387"
19024 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19025 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19026 [(reg FLAGS_REG) (const_int 0)])
19027 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19028 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19029 "TARGET_80387 && TARGET_CMOVE
19030 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19032 fcmov%F1\t{%2, %0|%0, %2}
19033 fcmov%f1\t{%3, %0|%0, %3}
19034 cmov%O2%C1\t{%2, %0|%0, %2}
19035 cmov%O2%c1\t{%3, %0|%0, %3}"
19036 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19037 (set_attr "mode" "SF,SF,SI,SI")])
19039 (define_expand "movdfcc"
19040 [(set (match_operand:DF 0 "register_operand" "")
19041 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19042 (match_operand:DF 2 "register_operand" "")
19043 (match_operand:DF 3 "register_operand" "")))]
19044 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19045 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19047 (define_insn "*movdfcc_1"
19048 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19049 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19050 [(reg FLAGS_REG) (const_int 0)])
19051 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19052 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19053 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19054 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19056 fcmov%F1\t{%2, %0|%0, %2}
19057 fcmov%f1\t{%3, %0|%0, %3}
19060 [(set_attr "type" "fcmov,fcmov,multi,multi")
19061 (set_attr "mode" "DF")])
19063 (define_insn "*movdfcc_1_rex64"
19064 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19065 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19066 [(reg FLAGS_REG) (const_int 0)])
19067 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19068 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19069 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19070 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19072 fcmov%F1\t{%2, %0|%0, %2}
19073 fcmov%f1\t{%3, %0|%0, %3}
19074 cmov%O2%C1\t{%2, %0|%0, %2}
19075 cmov%O2%c1\t{%3, %0|%0, %3}"
19076 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19077 (set_attr "mode" "DF")])
19080 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19081 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19082 [(match_operand 4 "flags_reg_operand" "")
19084 (match_operand:DF 2 "nonimmediate_operand" "")
19085 (match_operand:DF 3 "nonimmediate_operand" "")))]
19086 "!TARGET_64BIT && reload_completed"
19087 [(set (match_dup 2)
19088 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19092 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19095 "split_di (operands+2, 1, operands+5, operands+6);
19096 split_di (operands+3, 1, operands+7, operands+8);
19097 split_di (operands, 1, operands+2, operands+3);")
19099 (define_expand "movxfcc"
19100 [(set (match_operand:XF 0 "register_operand" "")
19101 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19102 (match_operand:XF 2 "register_operand" "")
19103 (match_operand:XF 3 "register_operand" "")))]
19104 "TARGET_80387 && TARGET_CMOVE"
19105 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19107 (define_insn "*movxfcc_1"
19108 [(set (match_operand:XF 0 "register_operand" "=f,f")
19109 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19110 [(reg FLAGS_REG) (const_int 0)])
19111 (match_operand:XF 2 "register_operand" "f,0")
19112 (match_operand:XF 3 "register_operand" "0,f")))]
19113 "TARGET_80387 && TARGET_CMOVE"
19115 fcmov%F1\t{%2, %0|%0, %2}
19116 fcmov%f1\t{%3, %0|%0, %3}"
19117 [(set_attr "type" "fcmov")
19118 (set_attr "mode" "XF")])
19120 ;; These versions of the min/max patterns are intentionally ignorant of
19121 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19122 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19123 ;; are undefined in this condition, we're certain this is correct.
19125 (define_insn "sminsf3"
19126 [(set (match_operand:SF 0 "register_operand" "=x")
19127 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19128 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19130 "minss\t{%2, %0|%0, %2}"
19131 [(set_attr "type" "sseadd")
19132 (set_attr "mode" "SF")])
19134 (define_insn "smaxsf3"
19135 [(set (match_operand:SF 0 "register_operand" "=x")
19136 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19137 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19139 "maxss\t{%2, %0|%0, %2}"
19140 [(set_attr "type" "sseadd")
19141 (set_attr "mode" "SF")])
19143 (define_insn "smindf3"
19144 [(set (match_operand:DF 0 "register_operand" "=x")
19145 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19146 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19147 "TARGET_SSE2 && TARGET_SSE_MATH"
19148 "minsd\t{%2, %0|%0, %2}"
19149 [(set_attr "type" "sseadd")
19150 (set_attr "mode" "DF")])
19152 (define_insn "smaxdf3"
19153 [(set (match_operand:DF 0 "register_operand" "=x")
19154 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19155 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19156 "TARGET_SSE2 && TARGET_SSE_MATH"
19157 "maxsd\t{%2, %0|%0, %2}"
19158 [(set_attr "type" "sseadd")
19159 (set_attr "mode" "DF")])
19161 ;; These versions of the min/max patterns implement exactly the operations
19162 ;; min = (op1 < op2 ? op1 : op2)
19163 ;; max = (!(op1 < op2) ? op1 : op2)
19164 ;; Their operands are not commutative, and thus they may be used in the
19165 ;; presence of -0.0 and NaN.
19167 (define_insn "*ieee_sminsf3"
19168 [(set (match_operand:SF 0 "register_operand" "=x")
19169 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19170 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19173 "minss\t{%2, %0|%0, %2}"
19174 [(set_attr "type" "sseadd")
19175 (set_attr "mode" "SF")])
19177 (define_insn "*ieee_smaxsf3"
19178 [(set (match_operand:SF 0 "register_operand" "=x")
19179 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19180 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19183 "maxss\t{%2, %0|%0, %2}"
19184 [(set_attr "type" "sseadd")
19185 (set_attr "mode" "SF")])
19187 (define_insn "*ieee_smindf3"
19188 [(set (match_operand:DF 0 "register_operand" "=x")
19189 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19190 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19192 "TARGET_SSE2 && TARGET_SSE_MATH"
19193 "minsd\t{%2, %0|%0, %2}"
19194 [(set_attr "type" "sseadd")
19195 (set_attr "mode" "DF")])
19197 (define_insn "*ieee_smaxdf3"
19198 [(set (match_operand:DF 0 "register_operand" "=x")
19199 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19200 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19202 "TARGET_SSE2 && TARGET_SSE_MATH"
19203 "maxsd\t{%2, %0|%0, %2}"
19204 [(set_attr "type" "sseadd")
19205 (set_attr "mode" "DF")])
19207 ;; Make two stack loads independent:
19209 ;; fld %st(0) -> fld bb
19210 ;; fmul bb fmul %st(1), %st
19212 ;; Actually we only match the last two instructions for simplicity.
19214 [(set (match_operand 0 "fp_register_operand" "")
19215 (match_operand 1 "fp_register_operand" ""))
19217 (match_operator 2 "binary_fp_operator"
19219 (match_operand 3 "memory_operand" "")]))]
19220 "REGNO (operands[0]) != REGNO (operands[1])"
19221 [(set (match_dup 0) (match_dup 3))
19222 (set (match_dup 0) (match_dup 4))]
19224 ;; The % modifier is not operational anymore in peephole2's, so we have to
19225 ;; swap the operands manually in the case of addition and multiplication.
19226 "if (COMMUTATIVE_ARITH_P (operands[2]))
19227 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19228 operands[0], operands[1]);
19230 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19231 operands[1], operands[0]);")
19233 ;; Conditional addition patterns
19234 (define_expand "addqicc"
19235 [(match_operand:QI 0 "register_operand" "")
19236 (match_operand 1 "comparison_operator" "")
19237 (match_operand:QI 2 "register_operand" "")
19238 (match_operand:QI 3 "const_int_operand" "")]
19240 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19242 (define_expand "addhicc"
19243 [(match_operand:HI 0 "register_operand" "")
19244 (match_operand 1 "comparison_operator" "")
19245 (match_operand:HI 2 "register_operand" "")
19246 (match_operand:HI 3 "const_int_operand" "")]
19248 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19250 (define_expand "addsicc"
19251 [(match_operand:SI 0 "register_operand" "")
19252 (match_operand 1 "comparison_operator" "")
19253 (match_operand:SI 2 "register_operand" "")
19254 (match_operand:SI 3 "const_int_operand" "")]
19256 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19258 (define_expand "adddicc"
19259 [(match_operand:DI 0 "register_operand" "")
19260 (match_operand 1 "comparison_operator" "")
19261 (match_operand:DI 2 "register_operand" "")
19262 (match_operand:DI 3 "const_int_operand" "")]
19264 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19267 ;; Misc patterns (?)
19269 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19270 ;; Otherwise there will be nothing to keep
19272 ;; [(set (reg ebp) (reg esp))]
19273 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19274 ;; (clobber (eflags)]
19275 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19277 ;; in proper program order.
19278 (define_insn "pro_epilogue_adjust_stack_1"
19279 [(set (match_operand:SI 0 "register_operand" "=r,r")
19280 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19281 (match_operand:SI 2 "immediate_operand" "i,i")))
19282 (clobber (reg:CC FLAGS_REG))
19283 (clobber (mem:BLK (scratch)))]
19286 switch (get_attr_type (insn))
19289 return "mov{l}\t{%1, %0|%0, %1}";
19292 if (GET_CODE (operands[2]) == CONST_INT
19293 && (INTVAL (operands[2]) == 128
19294 || (INTVAL (operands[2]) < 0
19295 && INTVAL (operands[2]) != -128)))
19297 operands[2] = GEN_INT (-INTVAL (operands[2]));
19298 return "sub{l}\t{%2, %0|%0, %2}";
19300 return "add{l}\t{%2, %0|%0, %2}";
19303 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19304 return "lea{l}\t{%a2, %0|%0, %a2}";
19307 gcc_unreachable ();
19310 [(set (attr "type")
19311 (cond [(eq_attr "alternative" "0")
19312 (const_string "alu")
19313 (match_operand:SI 2 "const0_operand" "")
19314 (const_string "imov")
19316 (const_string "lea")))
19317 (set_attr "mode" "SI")])
19319 (define_insn "pro_epilogue_adjust_stack_rex64"
19320 [(set (match_operand:DI 0 "register_operand" "=r,r")
19321 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19322 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19323 (clobber (reg:CC FLAGS_REG))
19324 (clobber (mem:BLK (scratch)))]
19327 switch (get_attr_type (insn))
19330 return "mov{q}\t{%1, %0|%0, %1}";
19333 if (GET_CODE (operands[2]) == CONST_INT
19334 /* Avoid overflows. */
19335 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19336 && (INTVAL (operands[2]) == 128
19337 || (INTVAL (operands[2]) < 0
19338 && INTVAL (operands[2]) != -128)))
19340 operands[2] = GEN_INT (-INTVAL (operands[2]));
19341 return "sub{q}\t{%2, %0|%0, %2}";
19343 return "add{q}\t{%2, %0|%0, %2}";
19346 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19347 return "lea{q}\t{%a2, %0|%0, %a2}";
19350 gcc_unreachable ();
19353 [(set (attr "type")
19354 (cond [(eq_attr "alternative" "0")
19355 (const_string "alu")
19356 (match_operand:DI 2 "const0_operand" "")
19357 (const_string "imov")
19359 (const_string "lea")))
19360 (set_attr "mode" "DI")])
19362 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19363 [(set (match_operand:DI 0 "register_operand" "=r,r")
19364 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19365 (match_operand:DI 3 "immediate_operand" "i,i")))
19366 (use (match_operand:DI 2 "register_operand" "r,r"))
19367 (clobber (reg:CC FLAGS_REG))
19368 (clobber (mem:BLK (scratch)))]
19371 switch (get_attr_type (insn))
19374 return "add{q}\t{%2, %0|%0, %2}";
19377 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19378 return "lea{q}\t{%a2, %0|%0, %a2}";
19381 gcc_unreachable ();
19384 [(set_attr "type" "alu,lea")
19385 (set_attr "mode" "DI")])
19387 (define_expand "allocate_stack_worker"
19388 [(match_operand:SI 0 "register_operand" "")]
19389 "TARGET_STACK_PROBE"
19391 if (reload_completed)
19394 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19396 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19401 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19403 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19408 (define_insn "allocate_stack_worker_1"
19409 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19410 UNSPECV_STACK_PROBE)
19411 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19412 (clobber (match_scratch:SI 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_postreload"
19420 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19421 UNSPECV_STACK_PROBE)
19422 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19423 (clobber (match_dup 0))
19424 (clobber (reg:CC FLAGS_REG))])]
19428 (define_insn "allocate_stack_worker_rex64"
19429 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19430 UNSPECV_STACK_PROBE)
19431 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19432 (clobber (match_scratch:DI 1 "=0"))
19433 (clobber (reg:CC FLAGS_REG))]
19434 "TARGET_64BIT && TARGET_STACK_PROBE"
19436 [(set_attr "type" "multi")
19437 (set_attr "length" "5")])
19439 (define_expand "allocate_stack_worker_rex64_postreload"
19440 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19441 UNSPECV_STACK_PROBE)
19442 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19443 (clobber (match_dup 0))
19444 (clobber (reg:CC FLAGS_REG))])]
19448 (define_expand "allocate_stack"
19449 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19450 (minus:SI (reg:SI SP_REG)
19451 (match_operand:SI 1 "general_operand" "")))
19452 (clobber (reg:CC FLAGS_REG))])
19453 (parallel [(set (reg:SI SP_REG)
19454 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19455 (clobber (reg:CC FLAGS_REG))])]
19456 "TARGET_STACK_PROBE"
19458 #ifdef CHECK_STACK_LIMIT
19459 if (GET_CODE (operands[1]) == CONST_INT
19460 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19461 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19465 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19468 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19472 (define_expand "builtin_setjmp_receiver"
19473 [(label_ref (match_operand 0 "" ""))]
19474 "!TARGET_64BIT && flag_pic"
19479 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19480 rtx label_rtx = gen_label_rtx ();
19481 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19482 xops[0] = xops[1] = picreg;
19483 xops[2] = gen_rtx_CONST (SImode,
19484 gen_rtx_MINUS (SImode,
19485 gen_rtx_LABEL_REF (SImode, label_rtx),
19486 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19487 ix86_expand_binary_operator (MINUS, SImode, xops);
19490 emit_insn (gen_set_got (pic_offset_table_rtx));
19494 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19497 [(set (match_operand 0 "register_operand" "")
19498 (match_operator 3 "promotable_binary_operator"
19499 [(match_operand 1 "register_operand" "")
19500 (match_operand 2 "aligned_operand" "")]))
19501 (clobber (reg:CC FLAGS_REG))]
19502 "! TARGET_PARTIAL_REG_STALL && reload_completed
19503 && ((GET_MODE (operands[0]) == HImode
19504 && ((!optimize_size && !TARGET_FAST_PREFIX)
19505 /* ??? next two lines just !satisfies_constraint_K (...) */
19506 || GET_CODE (operands[2]) != CONST_INT
19507 || satisfies_constraint_K (operands[2])))
19508 || (GET_MODE (operands[0]) == QImode
19509 && (TARGET_PROMOTE_QImode || optimize_size)))"
19510 [(parallel [(set (match_dup 0)
19511 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19512 (clobber (reg:CC FLAGS_REG))])]
19513 "operands[0] = gen_lowpart (SImode, operands[0]);
19514 operands[1] = gen_lowpart (SImode, operands[1]);
19515 if (GET_CODE (operands[3]) != ASHIFT)
19516 operands[2] = gen_lowpart (SImode, operands[2]);
19517 PUT_MODE (operands[3], SImode);")
19519 ; Promote the QImode tests, as i386 has encoding of the AND
19520 ; instruction with 32-bit sign-extended immediate and thus the
19521 ; instruction size is unchanged, except in the %eax case for
19522 ; which it is increased by one byte, hence the ! optimize_size.
19524 [(set (match_operand 0 "flags_reg_operand" "")
19525 (match_operator 2 "compare_operator"
19526 [(and (match_operand 3 "aligned_operand" "")
19527 (match_operand 4 "const_int_operand" ""))
19529 (set (match_operand 1 "register_operand" "")
19530 (and (match_dup 3) (match_dup 4)))]
19531 "! TARGET_PARTIAL_REG_STALL && reload_completed
19532 /* Ensure that the operand will remain sign-extended immediate. */
19533 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19535 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19536 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19537 [(parallel [(set (match_dup 0)
19538 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19541 (and:SI (match_dup 3) (match_dup 4)))])]
19544 = gen_int_mode (INTVAL (operands[4])
19545 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19546 operands[1] = gen_lowpart (SImode, operands[1]);
19547 operands[3] = gen_lowpart (SImode, operands[3]);
19550 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19551 ; the TEST instruction with 32-bit sign-extended immediate and thus
19552 ; the instruction size would at least double, which is not what we
19553 ; want even with ! optimize_size.
19555 [(set (match_operand 0 "flags_reg_operand" "")
19556 (match_operator 1 "compare_operator"
19557 [(and (match_operand:HI 2 "aligned_operand" "")
19558 (match_operand:HI 3 "const_int_operand" ""))
19560 "! TARGET_PARTIAL_REG_STALL && reload_completed
19561 /* Ensure that the operand will remain sign-extended immediate. */
19562 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19563 && ! TARGET_FAST_PREFIX
19564 && ! optimize_size"
19565 [(set (match_dup 0)
19566 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19570 = gen_int_mode (INTVAL (operands[3])
19571 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19572 operands[2] = gen_lowpart (SImode, operands[2]);
19576 [(set (match_operand 0 "register_operand" "")
19577 (neg (match_operand 1 "register_operand" "")))
19578 (clobber (reg:CC FLAGS_REG))]
19579 "! TARGET_PARTIAL_REG_STALL && reload_completed
19580 && (GET_MODE (operands[0]) == HImode
19581 || (GET_MODE (operands[0]) == QImode
19582 && (TARGET_PROMOTE_QImode || optimize_size)))"
19583 [(parallel [(set (match_dup 0)
19584 (neg:SI (match_dup 1)))
19585 (clobber (reg:CC FLAGS_REG))])]
19586 "operands[0] = gen_lowpart (SImode, operands[0]);
19587 operands[1] = gen_lowpart (SImode, operands[1]);")
19590 [(set (match_operand 0 "register_operand" "")
19591 (not (match_operand 1 "register_operand" "")))]
19592 "! TARGET_PARTIAL_REG_STALL && reload_completed
19593 && (GET_MODE (operands[0]) == HImode
19594 || (GET_MODE (operands[0]) == QImode
19595 && (TARGET_PROMOTE_QImode || optimize_size)))"
19596 [(set (match_dup 0)
19597 (not:SI (match_dup 1)))]
19598 "operands[0] = gen_lowpart (SImode, operands[0]);
19599 operands[1] = gen_lowpart (SImode, operands[1]);")
19602 [(set (match_operand 0 "register_operand" "")
19603 (if_then_else (match_operator 1 "comparison_operator"
19604 [(reg FLAGS_REG) (const_int 0)])
19605 (match_operand 2 "register_operand" "")
19606 (match_operand 3 "register_operand" "")))]
19607 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19608 && (GET_MODE (operands[0]) == HImode
19609 || (GET_MODE (operands[0]) == QImode
19610 && (TARGET_PROMOTE_QImode || optimize_size)))"
19611 [(set (match_dup 0)
19612 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19613 "operands[0] = gen_lowpart (SImode, operands[0]);
19614 operands[2] = gen_lowpart (SImode, operands[2]);
19615 operands[3] = gen_lowpart (SImode, operands[3]);")
19618 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19619 ;; transform a complex memory operation into two memory to register operations.
19621 ;; Don't push memory operands
19623 [(set (match_operand:SI 0 "push_operand" "")
19624 (match_operand:SI 1 "memory_operand" ""))
19625 (match_scratch:SI 2 "r")]
19626 "!optimize_size && !TARGET_PUSH_MEMORY
19627 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19628 [(set (match_dup 2) (match_dup 1))
19629 (set (match_dup 0) (match_dup 2))]
19633 [(set (match_operand:DI 0 "push_operand" "")
19634 (match_operand:DI 1 "memory_operand" ""))
19635 (match_scratch:DI 2 "r")]
19636 "!optimize_size && !TARGET_PUSH_MEMORY
19637 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19638 [(set (match_dup 2) (match_dup 1))
19639 (set (match_dup 0) (match_dup 2))]
19642 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19645 [(set (match_operand:SF 0 "push_operand" "")
19646 (match_operand:SF 1 "memory_operand" ""))
19647 (match_scratch:SF 2 "r")]
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))]
19655 [(set (match_operand:HI 0 "push_operand" "")
19656 (match_operand:HI 1 "memory_operand" ""))
19657 (match_scratch:HI 2 "r")]
19658 "!optimize_size && !TARGET_PUSH_MEMORY
19659 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19660 [(set (match_dup 2) (match_dup 1))
19661 (set (match_dup 0) (match_dup 2))]
19665 [(set (match_operand:QI 0 "push_operand" "")
19666 (match_operand:QI 1 "memory_operand" ""))
19667 (match_scratch:QI 2 "q")]
19668 "!optimize_size && !TARGET_PUSH_MEMORY
19669 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19670 [(set (match_dup 2) (match_dup 1))
19671 (set (match_dup 0) (match_dup 2))]
19674 ;; Don't move an immediate directly to memory when the instruction
19677 [(match_scratch:SI 1 "r")
19678 (set (match_operand:SI 0 "memory_operand" "")
19681 && ! TARGET_USE_MOV0
19682 && TARGET_SPLIT_LONG_MOVES
19683 && get_attr_length (insn) >= ix86_cost->large_insn
19684 && peep2_regno_dead_p (0, FLAGS_REG)"
19685 [(parallel [(set (match_dup 1) (const_int 0))
19686 (clobber (reg:CC FLAGS_REG))])
19687 (set (match_dup 0) (match_dup 1))]
19691 [(match_scratch:HI 1 "r")
19692 (set (match_operand:HI 0 "memory_operand" "")
19695 && ! TARGET_USE_MOV0
19696 && TARGET_SPLIT_LONG_MOVES
19697 && get_attr_length (insn) >= ix86_cost->large_insn
19698 && peep2_regno_dead_p (0, FLAGS_REG)"
19699 [(parallel [(set (match_dup 2) (const_int 0))
19700 (clobber (reg:CC FLAGS_REG))])
19701 (set (match_dup 0) (match_dup 1))]
19702 "operands[2] = gen_lowpart (SImode, operands[1]);")
19705 [(match_scratch:QI 1 "q")
19706 (set (match_operand:QI 0 "memory_operand" "")
19709 && ! TARGET_USE_MOV0
19710 && TARGET_SPLIT_LONG_MOVES
19711 && get_attr_length (insn) >= ix86_cost->large_insn
19712 && peep2_regno_dead_p (0, FLAGS_REG)"
19713 [(parallel [(set (match_dup 2) (const_int 0))
19714 (clobber (reg:CC FLAGS_REG))])
19715 (set (match_dup 0) (match_dup 1))]
19716 "operands[2] = gen_lowpart (SImode, operands[1]);")
19719 [(match_scratch:SI 2 "r")
19720 (set (match_operand:SI 0 "memory_operand" "")
19721 (match_operand:SI 1 "immediate_operand" ""))]
19723 && 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))]
19730 [(match_scratch:HI 2 "r")
19731 (set (match_operand:HI 0 "memory_operand" "")
19732 (match_operand:HI 1 "immediate_operand" ""))]
19733 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19734 && TARGET_SPLIT_LONG_MOVES"
19735 [(set (match_dup 2) (match_dup 1))
19736 (set (match_dup 0) (match_dup 2))]
19740 [(match_scratch:QI 2 "q")
19741 (set (match_operand:QI 0 "memory_operand" "")
19742 (match_operand:QI 1 "immediate_operand" ""))]
19743 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19744 && TARGET_SPLIT_LONG_MOVES"
19745 [(set (match_dup 2) (match_dup 1))
19746 (set (match_dup 0) (match_dup 2))]
19749 ;; Don't compare memory with zero, load and use a test instead.
19751 [(set (match_operand 0 "flags_reg_operand" "")
19752 (match_operator 1 "compare_operator"
19753 [(match_operand:SI 2 "memory_operand" "")
19755 (match_scratch:SI 3 "r")]
19756 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19757 [(set (match_dup 3) (match_dup 2))
19758 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19761 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19762 ;; Don't split NOTs with a displacement operand, because resulting XOR
19763 ;; will not be pairable anyway.
19765 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19766 ;; represented using a modRM byte. The XOR replacement is long decoded,
19767 ;; so this split helps here as well.
19769 ;; Note: Can't do this as a regular split because we can't get proper
19770 ;; lifetime information then.
19773 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19774 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19776 && peep2_regno_dead_p (0, FLAGS_REG)
19777 && ((TARGET_PENTIUM
19778 && (GET_CODE (operands[0]) != MEM
19779 || !memory_displacement_operand (operands[0], SImode)))
19780 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19781 [(parallel [(set (match_dup 0)
19782 (xor:SI (match_dup 1) (const_int -1)))
19783 (clobber (reg:CC FLAGS_REG))])]
19787 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19788 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19790 && peep2_regno_dead_p (0, FLAGS_REG)
19791 && ((TARGET_PENTIUM
19792 && (GET_CODE (operands[0]) != MEM
19793 || !memory_displacement_operand (operands[0], HImode)))
19794 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19795 [(parallel [(set (match_dup 0)
19796 (xor:HI (match_dup 1) (const_int -1)))
19797 (clobber (reg:CC FLAGS_REG))])]
19801 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19802 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19804 && peep2_regno_dead_p (0, FLAGS_REG)
19805 && ((TARGET_PENTIUM
19806 && (GET_CODE (operands[0]) != MEM
19807 || !memory_displacement_operand (operands[0], QImode)))
19808 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19809 [(parallel [(set (match_dup 0)
19810 (xor:QI (match_dup 1) (const_int -1)))
19811 (clobber (reg:CC FLAGS_REG))])]
19814 ;; Non pairable "test imm, reg" instructions can be translated to
19815 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19816 ;; byte opcode instead of two, have a short form for byte operands),
19817 ;; so do it for other CPUs as well. Given that the value was dead,
19818 ;; this should not create any new dependencies. Pass on the sub-word
19819 ;; versions if we're concerned about partial register stalls.
19822 [(set (match_operand 0 "flags_reg_operand" "")
19823 (match_operator 1 "compare_operator"
19824 [(and:SI (match_operand:SI 2 "register_operand" "")
19825 (match_operand:SI 3 "immediate_operand" ""))
19827 "ix86_match_ccmode (insn, CCNOmode)
19828 && (true_regnum (operands[2]) != 0
19829 || satisfies_constraint_K (operands[3]))
19830 && peep2_reg_dead_p (1, operands[2])"
19832 [(set (match_dup 0)
19833 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19836 (and:SI (match_dup 2) (match_dup 3)))])]
19839 ;; We don't need to handle HImode case, because it will be promoted to SImode
19840 ;; on ! TARGET_PARTIAL_REG_STALL
19843 [(set (match_operand 0 "flags_reg_operand" "")
19844 (match_operator 1 "compare_operator"
19845 [(and:QI (match_operand:QI 2 "register_operand" "")
19846 (match_operand:QI 3 "immediate_operand" ""))
19848 "! TARGET_PARTIAL_REG_STALL
19849 && ix86_match_ccmode (insn, CCNOmode)
19850 && true_regnum (operands[2]) != 0
19851 && peep2_reg_dead_p (1, operands[2])"
19853 [(set (match_dup 0)
19854 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19857 (and:QI (match_dup 2) (match_dup 3)))])]
19861 [(set (match_operand 0 "flags_reg_operand" "")
19862 (match_operator 1 "compare_operator"
19865 (match_operand 2 "ext_register_operand" "")
19868 (match_operand 3 "const_int_operand" ""))
19870 "! TARGET_PARTIAL_REG_STALL
19871 && ix86_match_ccmode (insn, CCNOmode)
19872 && true_regnum (operands[2]) != 0
19873 && peep2_reg_dead_p (1, operands[2])"
19874 [(parallel [(set (match_dup 0)
19883 (set (zero_extract:SI (match_dup 2)
19894 ;; Don't do logical operations with memory inputs.
19896 [(match_scratch:SI 2 "r")
19897 (parallel [(set (match_operand:SI 0 "register_operand" "")
19898 (match_operator:SI 3 "arith_or_logical_operator"
19900 (match_operand:SI 1 "memory_operand" "")]))
19901 (clobber (reg:CC FLAGS_REG))])]
19902 "! optimize_size && ! TARGET_READ_MODIFY"
19903 [(set (match_dup 2) (match_dup 1))
19904 (parallel [(set (match_dup 0)
19905 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19906 (clobber (reg:CC FLAGS_REG))])]
19910 [(match_scratch:SI 2 "r")
19911 (parallel [(set (match_operand:SI 0 "register_operand" "")
19912 (match_operator:SI 3 "arith_or_logical_operator"
19913 [(match_operand:SI 1 "memory_operand" "")
19915 (clobber (reg:CC FLAGS_REG))])]
19916 "! optimize_size && ! TARGET_READ_MODIFY"
19917 [(set (match_dup 2) (match_dup 1))
19918 (parallel [(set (match_dup 0)
19919 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19920 (clobber (reg:CC FLAGS_REG))])]
19923 ; Don't do logical operations with memory outputs
19925 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19926 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19927 ; the same decoder scheduling characteristics as the original.
19930 [(match_scratch:SI 2 "r")
19931 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19932 (match_operator:SI 3 "arith_or_logical_operator"
19934 (match_operand:SI 1 "nonmemory_operand" "")]))
19935 (clobber (reg:CC FLAGS_REG))])]
19936 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19937 [(set (match_dup 2) (match_dup 0))
19938 (parallel [(set (match_dup 2)
19939 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19940 (clobber (reg:CC FLAGS_REG))])
19941 (set (match_dup 0) (match_dup 2))]
19945 [(match_scratch:SI 2 "r")
19946 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19947 (match_operator:SI 3 "arith_or_logical_operator"
19948 [(match_operand:SI 1 "nonmemory_operand" "")
19950 (clobber (reg:CC FLAGS_REG))])]
19951 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19952 [(set (match_dup 2) (match_dup 0))
19953 (parallel [(set (match_dup 2)
19954 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19955 (clobber (reg:CC FLAGS_REG))])
19956 (set (match_dup 0) (match_dup 2))]
19959 ;; Attempt to always use XOR for zeroing registers.
19961 [(set (match_operand 0 "register_operand" "")
19962 (match_operand 1 "const0_operand" ""))]
19963 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19964 && (! TARGET_USE_MOV0 || optimize_size)
19965 && GENERAL_REG_P (operands[0])
19966 && peep2_regno_dead_p (0, FLAGS_REG)"
19967 [(parallel [(set (match_dup 0) (const_int 0))
19968 (clobber (reg:CC FLAGS_REG))])]
19970 operands[0] = gen_lowpart (word_mode, operands[0]);
19974 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19976 "(GET_MODE (operands[0]) == QImode
19977 || GET_MODE (operands[0]) == HImode)
19978 && (! TARGET_USE_MOV0 || optimize_size)
19979 && peep2_regno_dead_p (0, FLAGS_REG)"
19980 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19981 (clobber (reg:CC FLAGS_REG))])])
19983 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19985 [(set (match_operand 0 "register_operand" "")
19987 "(GET_MODE (operands[0]) == HImode
19988 || GET_MODE (operands[0]) == SImode
19989 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19990 && (optimize_size || TARGET_PENTIUM)
19991 && peep2_regno_dead_p (0, FLAGS_REG)"
19992 [(parallel [(set (match_dup 0) (const_int -1))
19993 (clobber (reg:CC FLAGS_REG))])]
19994 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19997 ;; Attempt to convert simple leas to adds. These can be created by
20000 [(set (match_operand:SI 0 "register_operand" "")
20001 (plus:SI (match_dup 0)
20002 (match_operand:SI 1 "nonmemory_operand" "")))]
20003 "peep2_regno_dead_p (0, FLAGS_REG)"
20004 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20005 (clobber (reg:CC FLAGS_REG))])]
20009 [(set (match_operand:SI 0 "register_operand" "")
20010 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20011 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20012 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20013 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20014 (clobber (reg:CC FLAGS_REG))])]
20015 "operands[2] = gen_lowpart (SImode, operands[2]);")
20018 [(set (match_operand:DI 0 "register_operand" "")
20019 (plus:DI (match_dup 0)
20020 (match_operand:DI 1 "x86_64_general_operand" "")))]
20021 "peep2_regno_dead_p (0, FLAGS_REG)"
20022 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20023 (clobber (reg:CC FLAGS_REG))])]
20027 [(set (match_operand:SI 0 "register_operand" "")
20028 (mult:SI (match_dup 0)
20029 (match_operand:SI 1 "const_int_operand" "")))]
20030 "exact_log2 (INTVAL (operands[1])) >= 0
20031 && peep2_regno_dead_p (0, FLAGS_REG)"
20032 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20033 (clobber (reg:CC FLAGS_REG))])]
20034 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20037 [(set (match_operand:DI 0 "register_operand" "")
20038 (mult:DI (match_dup 0)
20039 (match_operand:DI 1 "const_int_operand" "")))]
20040 "exact_log2 (INTVAL (operands[1])) >= 0
20041 && peep2_regno_dead_p (0, FLAGS_REG)"
20042 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20043 (clobber (reg:CC FLAGS_REG))])]
20044 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20047 [(set (match_operand:SI 0 "register_operand" "")
20048 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20049 (match_operand:DI 2 "const_int_operand" "")) 0))]
20050 "exact_log2 (INTVAL (operands[2])) >= 0
20051 && REGNO (operands[0]) == REGNO (operands[1])
20052 && peep2_regno_dead_p (0, FLAGS_REG)"
20053 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20054 (clobber (reg:CC FLAGS_REG))])]
20055 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20057 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20058 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20059 ;; many CPUs it is also faster, since special hardware to avoid esp
20060 ;; dependencies is present.
20062 ;; While some of these conversions may be done using splitters, we use peepholes
20063 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20065 ;; Convert prologue esp subtractions to push.
20066 ;; We need register to push. In order to keep verify_flow_info happy we have
20068 ;; - use scratch and clobber it in order to avoid dependencies
20069 ;; - use already live register
20070 ;; We can't use the second way right now, since there is no reliable way how to
20071 ;; verify that given register is live. First choice will also most likely in
20072 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20073 ;; call clobbered registers are dead. We may want to use base pointer as an
20074 ;; alternative when no register is available later.
20077 [(match_scratch:SI 0 "r")
20078 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20079 (clobber (reg:CC FLAGS_REG))
20080 (clobber (mem:BLK (scratch)))])]
20081 "optimize_size || !TARGET_SUB_ESP_4"
20082 [(clobber (match_dup 0))
20083 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20084 (clobber (mem:BLK (scratch)))])])
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 (clobber (mem:BLK (scratch)))])]
20091 "optimize_size || !TARGET_SUB_ESP_8"
20092 [(clobber (match_dup 0))
20093 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20094 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20095 (clobber (mem:BLK (scratch)))])])
20097 ;; Convert esp subtractions to push.
20099 [(match_scratch:SI 0 "r")
20100 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20101 (clobber (reg:CC FLAGS_REG))])]
20102 "optimize_size || !TARGET_SUB_ESP_4"
20103 [(clobber (match_dup 0))
20104 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20107 [(match_scratch:SI 0 "r")
20108 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20109 (clobber (reg:CC FLAGS_REG))])]
20110 "optimize_size || !TARGET_SUB_ESP_8"
20111 [(clobber (match_dup 0))
20112 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20113 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20115 ;; Convert epilogue deallocator to pop.
20117 [(match_scratch:SI 0 "r")
20118 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20119 (clobber (reg:CC FLAGS_REG))
20120 (clobber (mem:BLK (scratch)))])]
20121 "optimize_size || !TARGET_ADD_ESP_4"
20122 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20123 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20124 (clobber (mem:BLK (scratch)))])]
20127 ;; Two pops case is tricky, since pop causes dependency on destination register.
20128 ;; We use two registers if available.
20130 [(match_scratch:SI 0 "r")
20131 (match_scratch:SI 1 "r")
20132 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20133 (clobber (reg:CC FLAGS_REG))
20134 (clobber (mem:BLK (scratch)))])]
20135 "optimize_size || !TARGET_ADD_ESP_8"
20136 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20137 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20138 (clobber (mem:BLK (scratch)))])
20139 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20140 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20144 [(match_scratch:SI 0 "r")
20145 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20146 (clobber (reg:CC FLAGS_REG))
20147 (clobber (mem:BLK (scratch)))])]
20149 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20150 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20151 (clobber (mem:BLK (scratch)))])
20152 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20153 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20156 ;; Convert esp additions to pop.
20158 [(match_scratch:SI 0 "r")
20159 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20160 (clobber (reg:CC FLAGS_REG))])]
20162 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20163 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20166 ;; Two pops case is tricky, since pop causes dependency on destination register.
20167 ;; We use two registers if available.
20169 [(match_scratch:SI 0 "r")
20170 (match_scratch:SI 1 "r")
20171 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20172 (clobber (reg:CC FLAGS_REG))])]
20174 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20175 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20176 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20177 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20181 [(match_scratch:SI 0 "r")
20182 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20183 (clobber (reg:CC FLAGS_REG))])]
20185 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20186 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20187 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20188 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20191 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20192 ;; required and register dies. Similarly for 128 to plus -128.
20194 [(set (match_operand 0 "flags_reg_operand" "")
20195 (match_operator 1 "compare_operator"
20196 [(match_operand 2 "register_operand" "")
20197 (match_operand 3 "const_int_operand" "")]))]
20198 "(INTVAL (operands[3]) == -1
20199 || INTVAL (operands[3]) == 1
20200 || INTVAL (operands[3]) == 128)
20201 && ix86_match_ccmode (insn, CCGCmode)
20202 && peep2_reg_dead_p (1, operands[2])"
20203 [(parallel [(set (match_dup 0)
20204 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20205 (clobber (match_dup 2))])]
20209 [(match_scratch:DI 0 "r")
20210 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20211 (clobber (reg:CC FLAGS_REG))
20212 (clobber (mem:BLK (scratch)))])]
20213 "optimize_size || !TARGET_SUB_ESP_4"
20214 [(clobber (match_dup 0))
20215 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20216 (clobber (mem:BLK (scratch)))])])
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 (clobber (mem:BLK (scratch)))])]
20223 "optimize_size || !TARGET_SUB_ESP_8"
20224 [(clobber (match_dup 0))
20225 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20226 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20227 (clobber (mem:BLK (scratch)))])])
20229 ;; Convert esp subtractions to push.
20231 [(match_scratch:DI 0 "r")
20232 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20233 (clobber (reg:CC FLAGS_REG))])]
20234 "optimize_size || !TARGET_SUB_ESP_4"
20235 [(clobber (match_dup 0))
20236 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20239 [(match_scratch:DI 0 "r")
20240 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20241 (clobber (reg:CC FLAGS_REG))])]
20242 "optimize_size || !TARGET_SUB_ESP_8"
20243 [(clobber (match_dup 0))
20244 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20245 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20247 ;; Convert epilogue deallocator to pop.
20249 [(match_scratch:DI 0 "r")
20250 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20251 (clobber (reg:CC FLAGS_REG))
20252 (clobber (mem:BLK (scratch)))])]
20253 "optimize_size || !TARGET_ADD_ESP_4"
20254 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20255 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20256 (clobber (mem:BLK (scratch)))])]
20259 ;; Two pops case is tricky, since pop causes dependency on destination register.
20260 ;; We use two registers if available.
20262 [(match_scratch:DI 0 "r")
20263 (match_scratch:DI 1 "r")
20264 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20265 (clobber (reg:CC FLAGS_REG))
20266 (clobber (mem:BLK (scratch)))])]
20267 "optimize_size || !TARGET_ADD_ESP_8"
20268 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20269 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20270 (clobber (mem:BLK (scratch)))])
20271 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20272 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20276 [(match_scratch:DI 0 "r")
20277 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20278 (clobber (reg:CC FLAGS_REG))
20279 (clobber (mem:BLK (scratch)))])]
20281 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20282 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20283 (clobber (mem:BLK (scratch)))])
20284 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20285 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20288 ;; Convert esp additions to pop.
20290 [(match_scratch:DI 0 "r")
20291 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20292 (clobber (reg:CC FLAGS_REG))])]
20294 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20295 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20298 ;; Two pops case is tricky, since pop causes dependency on destination register.
20299 ;; We use two registers if available.
20301 [(match_scratch:DI 0 "r")
20302 (match_scratch:DI 1 "r")
20303 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20304 (clobber (reg:CC FLAGS_REG))])]
20306 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20307 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20308 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20309 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20313 [(match_scratch:DI 0 "r")
20314 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20315 (clobber (reg:CC FLAGS_REG))])]
20317 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20318 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20319 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20320 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20323 ;; Convert imul by three, five and nine into lea
20326 [(set (match_operand:SI 0 "register_operand" "")
20327 (mult:SI (match_operand:SI 1 "register_operand" "")
20328 (match_operand:SI 2 "const_int_operand" "")))
20329 (clobber (reg:CC FLAGS_REG))])]
20330 "INTVAL (operands[2]) == 3
20331 || INTVAL (operands[2]) == 5
20332 || INTVAL (operands[2]) == 9"
20333 [(set (match_dup 0)
20334 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20336 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20340 [(set (match_operand:SI 0 "register_operand" "")
20341 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20342 (match_operand:SI 2 "const_int_operand" "")))
20343 (clobber (reg:CC FLAGS_REG))])]
20345 && (INTVAL (operands[2]) == 3
20346 || INTVAL (operands[2]) == 5
20347 || INTVAL (operands[2]) == 9)"
20348 [(set (match_dup 0) (match_dup 1))
20350 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20352 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20356 [(set (match_operand:DI 0 "register_operand" "")
20357 (mult:DI (match_operand:DI 1 "register_operand" "")
20358 (match_operand:DI 2 "const_int_operand" "")))
20359 (clobber (reg:CC FLAGS_REG))])]
20361 && (INTVAL (operands[2]) == 3
20362 || INTVAL (operands[2]) == 5
20363 || INTVAL (operands[2]) == 9)"
20364 [(set (match_dup 0)
20365 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20367 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20371 [(set (match_operand:DI 0 "register_operand" "")
20372 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20373 (match_operand:DI 2 "const_int_operand" "")))
20374 (clobber (reg:CC FLAGS_REG))])]
20377 && (INTVAL (operands[2]) == 3
20378 || INTVAL (operands[2]) == 5
20379 || INTVAL (operands[2]) == 9)"
20380 [(set (match_dup 0) (match_dup 1))
20382 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20384 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20386 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20387 ;; imul $32bit_imm, reg, reg is direct decoded.
20389 [(match_scratch:DI 3 "r")
20390 (parallel [(set (match_operand:DI 0 "register_operand" "")
20391 (mult:DI (match_operand:DI 1 "memory_operand" "")
20392 (match_operand:DI 2 "immediate_operand" "")))
20393 (clobber (reg:CC FLAGS_REG))])]
20394 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20395 && !satisfies_constraint_K (operands[2])"
20396 [(set (match_dup 3) (match_dup 1))
20397 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20398 (clobber (reg:CC FLAGS_REG))])]
20402 [(match_scratch:SI 3 "r")
20403 (parallel [(set (match_operand:SI 0 "register_operand" "")
20404 (mult:SI (match_operand:SI 1 "memory_operand" "")
20405 (match_operand:SI 2 "immediate_operand" "")))
20406 (clobber (reg:CC FLAGS_REG))])]
20407 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20408 && !satisfies_constraint_K (operands[2])"
20409 [(set (match_dup 3) (match_dup 1))
20410 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20411 (clobber (reg:CC FLAGS_REG))])]
20415 [(match_scratch:SI 3 "r")
20416 (parallel [(set (match_operand:DI 0 "register_operand" "")
20418 (mult:SI (match_operand:SI 1 "memory_operand" "")
20419 (match_operand:SI 2 "immediate_operand" ""))))
20420 (clobber (reg:CC FLAGS_REG))])]
20421 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20422 && !satisfies_constraint_K (operands[2])"
20423 [(set (match_dup 3) (match_dup 1))
20424 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20425 (clobber (reg:CC FLAGS_REG))])]
20428 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20429 ;; Convert it into imul reg, reg
20430 ;; It would be better to force assembler to encode instruction using long
20431 ;; immediate, but there is apparently no way to do so.
20433 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20434 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20435 (match_operand:DI 2 "const_int_operand" "")))
20436 (clobber (reg:CC FLAGS_REG))])
20437 (match_scratch:DI 3 "r")]
20438 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20439 && satisfies_constraint_K (operands[2])"
20440 [(set (match_dup 3) (match_dup 2))
20441 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20442 (clobber (reg:CC FLAGS_REG))])]
20444 if (!rtx_equal_p (operands[0], operands[1]))
20445 emit_move_insn (operands[0], operands[1]);
20449 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20450 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20451 (match_operand:SI 2 "const_int_operand" "")))
20452 (clobber (reg:CC FLAGS_REG))])
20453 (match_scratch:SI 3 "r")]
20454 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20455 && satisfies_constraint_K (operands[2])"
20456 [(set (match_dup 3) (match_dup 2))
20457 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20458 (clobber (reg:CC FLAGS_REG))])]
20460 if (!rtx_equal_p (operands[0], operands[1]))
20461 emit_move_insn (operands[0], operands[1]);
20465 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20466 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20467 (match_operand:HI 2 "immediate_operand" "")))
20468 (clobber (reg:CC FLAGS_REG))])
20469 (match_scratch:HI 3 "r")]
20470 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20471 [(set (match_dup 3) (match_dup 2))
20472 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20473 (clobber (reg:CC FLAGS_REG))])]
20475 if (!rtx_equal_p (operands[0], operands[1]))
20476 emit_move_insn (operands[0], operands[1]);
20479 ;; After splitting up read-modify operations, array accesses with memory
20480 ;; operands might end up in form:
20482 ;; movl 4(%esp), %edx
20484 ;; instead of pre-splitting:
20486 ;; addl 4(%esp), %eax
20488 ;; movl 4(%esp), %edx
20489 ;; leal (%edx,%eax,4), %eax
20492 [(parallel [(set (match_operand 0 "register_operand" "")
20493 (ashift (match_operand 1 "register_operand" "")
20494 (match_operand 2 "const_int_operand" "")))
20495 (clobber (reg:CC FLAGS_REG))])
20496 (set (match_operand 3 "register_operand")
20497 (match_operand 4 "x86_64_general_operand" ""))
20498 (parallel [(set (match_operand 5 "register_operand" "")
20499 (plus (match_operand 6 "register_operand" "")
20500 (match_operand 7 "register_operand" "")))
20501 (clobber (reg:CC FLAGS_REG))])]
20502 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20503 /* Validate MODE for lea. */
20504 && ((!TARGET_PARTIAL_REG_STALL
20505 && (GET_MODE (operands[0]) == QImode
20506 || GET_MODE (operands[0]) == HImode))
20507 || GET_MODE (operands[0]) == SImode
20508 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20509 /* We reorder load and the shift. */
20510 && !rtx_equal_p (operands[1], operands[3])
20511 && !reg_overlap_mentioned_p (operands[0], operands[4])
20512 /* Last PLUS must consist of operand 0 and 3. */
20513 && !rtx_equal_p (operands[0], operands[3])
20514 && (rtx_equal_p (operands[3], operands[6])
20515 || rtx_equal_p (operands[3], operands[7]))
20516 && (rtx_equal_p (operands[0], operands[6])
20517 || rtx_equal_p (operands[0], operands[7]))
20518 /* The intermediate operand 0 must die or be same as output. */
20519 && (rtx_equal_p (operands[0], operands[5])
20520 || peep2_reg_dead_p (3, operands[0]))"
20521 [(set (match_dup 3) (match_dup 4))
20522 (set (match_dup 0) (match_dup 1))]
20524 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20525 int scale = 1 << INTVAL (operands[2]);
20526 rtx index = gen_lowpart (Pmode, operands[1]);
20527 rtx base = gen_lowpart (Pmode, operands[3]);
20528 rtx dest = gen_lowpart (mode, operands[5]);
20530 operands[1] = gen_rtx_PLUS (Pmode, base,
20531 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20533 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20534 operands[0] = dest;
20537 ;; Call-value patterns last so that the wildcard operand does not
20538 ;; disrupt insn-recog's switch tables.
20540 (define_insn "*call_value_pop_0"
20541 [(set (match_operand 0 "" "")
20542 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20543 (match_operand:SI 2 "" "")))
20544 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20545 (match_operand:SI 3 "immediate_operand" "")))]
20548 if (SIBLING_CALL_P (insn))
20551 return "call\t%P1";
20553 [(set_attr "type" "callv")])
20555 (define_insn "*call_value_pop_1"
20556 [(set (match_operand 0 "" "")
20557 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20558 (match_operand:SI 2 "" "")))
20559 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20560 (match_operand:SI 3 "immediate_operand" "i")))]
20563 if (constant_call_address_operand (operands[1], Pmode))
20565 if (SIBLING_CALL_P (insn))
20568 return "call\t%P1";
20570 if (SIBLING_CALL_P (insn))
20573 return "call\t%A1";
20575 [(set_attr "type" "callv")])
20577 (define_insn "*call_value_0"
20578 [(set (match_operand 0 "" "")
20579 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20580 (match_operand:SI 2 "" "")))]
20583 if (SIBLING_CALL_P (insn))
20586 return "call\t%P1";
20588 [(set_attr "type" "callv")])
20590 (define_insn "*call_value_0_rex64"
20591 [(set (match_operand 0 "" "")
20592 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20593 (match_operand:DI 2 "const_int_operand" "")))]
20596 if (SIBLING_CALL_P (insn))
20599 return "call\t%P1";
20601 [(set_attr "type" "callv")])
20603 (define_insn "*call_value_1"
20604 [(set (match_operand 0 "" "")
20605 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20606 (match_operand:SI 2 "" "")))]
20607 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20609 if (constant_call_address_operand (operands[1], Pmode))
20610 return "call\t%P1";
20611 return "call\t%A1";
20613 [(set_attr "type" "callv")])
20615 (define_insn "*sibcall_value_1"
20616 [(set (match_operand 0 "" "")
20617 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20618 (match_operand:SI 2 "" "")))]
20619 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20621 if (constant_call_address_operand (operands[1], Pmode))
20625 [(set_attr "type" "callv")])
20627 (define_insn "*call_value_1_rex64"
20628 [(set (match_operand 0 "" "")
20629 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20630 (match_operand:DI 2 "" "")))]
20631 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20633 if (constant_call_address_operand (operands[1], Pmode))
20634 return "call\t%P1";
20635 return "call\t%A1";
20637 [(set_attr "type" "callv")])
20639 (define_insn "*sibcall_value_1_rex64"
20640 [(set (match_operand 0 "" "")
20641 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20642 (match_operand:DI 2 "" "")))]
20643 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20645 [(set_attr "type" "callv")])
20647 (define_insn "*sibcall_value_1_rex64_v"
20648 [(set (match_operand 0 "" "")
20649 (call (mem:QI (reg:DI 40))
20650 (match_operand:DI 1 "" "")))]
20651 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20653 [(set_attr "type" "callv")])
20655 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20656 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20657 ;; caught for use by garbage collectors and the like. Using an insn that
20658 ;; maps to SIGILL makes it more likely the program will rightfully die.
20659 ;; Keeping with tradition, "6" is in honor of #UD.
20660 (define_insn "trap"
20661 [(trap_if (const_int 1) (const_int 6))]
20663 { return ASM_SHORT "0x0b0f"; }
20664 [(set_attr "length" "2")])
20666 (define_expand "sse_prologue_save"
20667 [(parallel [(set (match_operand:BLK 0 "" "")
20668 (unspec:BLK [(reg:DI 21)
20675 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20676 (use (match_operand:DI 1 "register_operand" ""))
20677 (use (match_operand:DI 2 "immediate_operand" ""))
20678 (use (label_ref:DI (match_operand 3 "" "")))])]
20682 (define_insn "*sse_prologue_save_insn"
20683 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20684 (match_operand:DI 4 "const_int_operand" "n")))
20685 (unspec:BLK [(reg:DI 21)
20692 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20693 (use (match_operand:DI 1 "register_operand" "r"))
20694 (use (match_operand:DI 2 "const_int_operand" "i"))
20695 (use (label_ref:DI (match_operand 3 "" "X")))]
20697 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20698 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20702 operands[0] = gen_rtx_MEM (Pmode,
20703 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20704 output_asm_insn (\"jmp\\t%A1\", operands);
20705 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20707 operands[4] = adjust_address (operands[0], DImode, i*16);
20708 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20709 PUT_MODE (operands[4], TImode);
20710 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20711 output_asm_insn (\"rex\", operands);
20712 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20714 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20715 CODE_LABEL_NUMBER (operands[3]));
20719 [(set_attr "type" "other")
20720 (set_attr "length_immediate" "0")
20721 (set_attr "length_address" "0")
20722 (set_attr "length" "135")
20723 (set_attr "memory" "store")
20724 (set_attr "modrm" "0")
20725 (set_attr "mode" "DI")])
20727 (define_expand "prefetch"
20728 [(prefetch (match_operand 0 "address_operand" "")
20729 (match_operand:SI 1 "const_int_operand" "")
20730 (match_operand:SI 2 "const_int_operand" ""))]
20731 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20733 int rw = INTVAL (operands[1]);
20734 int locality = INTVAL (operands[2]);
20736 gcc_assert (rw == 0 || rw == 1);
20737 gcc_assert (locality >= 0 && locality <= 3);
20738 gcc_assert (GET_MODE (operands[0]) == Pmode
20739 || GET_MODE (operands[0]) == VOIDmode);
20741 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20742 supported by SSE counterpart or the SSE prefetch is not available
20743 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20745 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20746 operands[2] = GEN_INT (3);
20748 operands[1] = const0_rtx;
20751 (define_insn "*prefetch_sse"
20752 [(prefetch (match_operand:SI 0 "address_operand" "p")
20754 (match_operand:SI 1 "const_int_operand" ""))]
20755 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20757 static const char * const patterns[4] = {
20758 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20761 int locality = INTVAL (operands[1]);
20762 gcc_assert (locality >= 0 && locality <= 3);
20764 return patterns[locality];
20766 [(set_attr "type" "sse")
20767 (set_attr "memory" "none")])
20769 (define_insn "*prefetch_sse_rex"
20770 [(prefetch (match_operand:DI 0 "address_operand" "p")
20772 (match_operand:SI 1 "const_int_operand" ""))]
20773 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20775 static const char * const patterns[4] = {
20776 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20779 int locality = INTVAL (operands[1]);
20780 gcc_assert (locality >= 0 && locality <= 3);
20782 return patterns[locality];
20784 [(set_attr "type" "sse")
20785 (set_attr "memory" "none")])
20787 (define_insn "*prefetch_3dnow"
20788 [(prefetch (match_operand:SI 0 "address_operand" "p")
20789 (match_operand:SI 1 "const_int_operand" "n")
20791 "TARGET_3DNOW && !TARGET_64BIT"
20793 if (INTVAL (operands[1]) == 0)
20794 return "prefetch\t%a0";
20796 return "prefetchw\t%a0";
20798 [(set_attr "type" "mmx")
20799 (set_attr "memory" "none")])
20801 (define_insn "*prefetch_3dnow_rex"
20802 [(prefetch (match_operand:DI 0 "address_operand" "p")
20803 (match_operand:SI 1 "const_int_operand" "n")
20805 "TARGET_3DNOW && TARGET_64BIT"
20807 if (INTVAL (operands[1]) == 0)
20808 return "prefetch\t%a0";
20810 return "prefetchw\t%a0";
20812 [(set_attr "type" "mmx")
20813 (set_attr "memory" "none")])
20815 (define_expand "stack_protect_set"
20816 [(match_operand 0 "memory_operand" "")
20817 (match_operand 1 "memory_operand" "")]
20820 #ifdef TARGET_THREAD_SSP_OFFSET
20822 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20823 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20825 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20826 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20829 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20831 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20836 (define_insn "stack_protect_set_si"
20837 [(set (match_operand:SI 0 "memory_operand" "=m")
20838 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20839 (set (match_scratch:SI 2 "=&r") (const_int 0))
20840 (clobber (reg:CC FLAGS_REG))]
20842 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20843 [(set_attr "type" "multi")])
20845 (define_insn "stack_protect_set_di"
20846 [(set (match_operand:DI 0 "memory_operand" "=m")
20847 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20848 (set (match_scratch:DI 2 "=&r") (const_int 0))
20849 (clobber (reg:CC FLAGS_REG))]
20851 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20852 [(set_attr "type" "multi")])
20854 (define_insn "stack_tls_protect_set_si"
20855 [(set (match_operand:SI 0 "memory_operand" "=m")
20856 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20857 (set (match_scratch:SI 2 "=&r") (const_int 0))
20858 (clobber (reg:CC FLAGS_REG))]
20860 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20861 [(set_attr "type" "multi")])
20863 (define_insn "stack_tls_protect_set_di"
20864 [(set (match_operand:DI 0 "memory_operand" "=m")
20865 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20866 (set (match_scratch:DI 2 "=&r") (const_int 0))
20867 (clobber (reg:CC FLAGS_REG))]
20870 /* The kernel uses a different segment register for performance reasons; a
20871 system call would not have to trash the userspace segment register,
20872 which would be expensive */
20873 if (ix86_cmodel != CM_KERNEL)
20874 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20876 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20878 [(set_attr "type" "multi")])
20880 (define_expand "stack_protect_test"
20881 [(match_operand 0 "memory_operand" "")
20882 (match_operand 1 "memory_operand" "")
20883 (match_operand 2 "" "")]
20886 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20887 ix86_compare_op0 = operands[0];
20888 ix86_compare_op1 = operands[1];
20889 ix86_compare_emitted = flags;
20891 #ifdef TARGET_THREAD_SSP_OFFSET
20893 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20894 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20896 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20897 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20900 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20902 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20904 emit_jump_insn (gen_beq (operands[2]));
20908 (define_insn "stack_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 "memory_operand" "m")]
20913 (clobber (match_scratch:SI 3 "=&r"))]
20915 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20916 [(set_attr "type" "multi")])
20918 (define_insn "stack_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 "memory_operand" "m")]
20923 (clobber (match_scratch:DI 3 "=&r"))]
20925 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20926 [(set_attr "type" "multi")])
20928 (define_insn "stack_tls_protect_test_si"
20929 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20930 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20931 (match_operand:SI 2 "const_int_operand" "i")]
20932 UNSPEC_SP_TLS_TEST))
20933 (clobber (match_scratch:SI 3 "=r"))]
20935 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20936 [(set_attr "type" "multi")])
20938 (define_insn "stack_tls_protect_test_di"
20939 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20940 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20941 (match_operand:DI 2 "const_int_operand" "i")]
20942 UNSPEC_SP_TLS_TEST))
20943 (clobber (match_scratch:DI 3 "=r"))]
20946 /* The kernel uses a different segment register for performance reasons; a
20947 system call would not have to trash the userspace segment register,
20948 which would be expensive */
20949 if (ix86_cmodel != CM_KERNEL)
20950 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20952 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20954 [(set_attr "type" "multi")])
20958 (include "sync.md")