1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
77 ; Other random patterns
87 ; For SSE/MMX support:
88 (UNSPEC_FIX_NOTRUNC 30)
96 (UNSPEC_NOP 38) ; prevents combiner cleverness
107 ; Generic math support
109 (UNSPEC_IEEE_MIN 51) ; not commutative
110 (UNSPEC_IEEE_MAX 52) ; not commutative
123 (UNSPEC_FRNDINT_FLOOR 70)
124 (UNSPEC_FRNDINT_CEIL 71)
125 (UNSPEC_FRNDINT_TRUNC 72)
126 (UNSPEC_FRNDINT_MASK_PM 73)
127 (UNSPEC_FIST_FLOOR 74)
128 (UNSPEC_FIST_CEIL 75)
130 ; x87 Double output FP
131 (UNSPEC_SINCOS_COS 80)
132 (UNSPEC_SINCOS_SIN 81)
135 (UNSPEC_XTRACT_FRACT 84)
136 (UNSPEC_XTRACT_EXP 85)
137 (UNSPEC_FSCALE_FRACT 86)
138 (UNSPEC_FSCALE_EXP 87)
147 (UNSPEC_SP_TLS_SET 102)
148 (UNSPEC_SP_TLS_TEST 103)
152 [(UNSPECV_BLOCKAGE 0)
153 (UNSPECV_STACK_PROBE 1)
162 (UNSPECV_CMPXCHG_1 10)
163 (UNSPECV_CMPXCHG_2 11)
168 ;; Registers by name.
177 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
180 ;; In C guard expressions, put expressions which may be compile-time
181 ;; constants first. This allows for better optimization. For
182 ;; example, write "TARGET_64BIT && reload_completed", not
183 ;; "reload_completed && TARGET_64BIT".
186 ;; Processor type. This attribute must exactly match the processor_type
187 ;; enumeration in i386.h.
188 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
189 (const (symbol_ref "ix86_tune")))
191 ;; A basic instruction type. Refinements due to arguments to be
192 ;; provided in other attributes.
195 alu,alu1,negnot,imov,imovx,lea,
196 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
197 icmp,test,ibr,setcc,icmov,
198 push,pop,call,callv,leave,
200 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
201 sselog,sselog1,sseiadd,sseishft,sseimul,
202 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
203 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
204 (const_string "other"))
206 ;; Main data type used by the insn
208 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
209 (const_string "unknown"))
211 ;; The CPU unit operations uses.
212 (define_attr "unit" "integer,i387,sse,mmx,unknown"
213 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
214 (const_string "i387")
215 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
216 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
218 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
220 (eq_attr "type" "other")
221 (const_string "unknown")]
222 (const_string "integer")))
224 ;; The (bounding maximum) length of an instruction immediate.
225 (define_attr "length_immediate" ""
226 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
228 (eq_attr "unit" "i387,sse,mmx")
230 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
232 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
233 (eq_attr "type" "imov,test")
234 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
235 (eq_attr "type" "call")
236 (if_then_else (match_operand 0 "constant_call_address_operand" "")
239 (eq_attr "type" "callv")
240 (if_then_else (match_operand 1 "constant_call_address_operand" "")
243 ;; We don't know the size before shorten_branches. Expect
244 ;; the instruction to fit for better scheduling.
245 (eq_attr "type" "ibr")
248 (symbol_ref "/* Update immediate_length and other attributes! */
249 gcc_unreachable (),1")))
251 ;; The (bounding maximum) length of an instruction address.
252 (define_attr "length_address" ""
253 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
255 (and (eq_attr "type" "call")
256 (match_operand 0 "constant_call_address_operand" ""))
258 (and (eq_attr "type" "callv")
259 (match_operand 1 "constant_call_address_operand" ""))
262 (symbol_ref "ix86_attr_length_address_default (insn)")))
264 ;; Set when length prefix is used.
265 (define_attr "prefix_data16" ""
266 (if_then_else (ior (eq_attr "mode" "HI")
267 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
271 ;; Set when string REP prefix is used.
272 (define_attr "prefix_rep" ""
273 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
277 ;; Set when 0f opcode prefix is used.
278 (define_attr "prefix_0f" ""
280 (ior (eq_attr "type" "imovx,setcc,icmov")
281 (eq_attr "unit" "sse,mmx"))
285 ;; Set when REX opcode prefix is used.
286 (define_attr "prefix_rex" ""
287 (cond [(and (eq_attr "mode" "DI")
288 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
290 (and (eq_attr "mode" "QI")
291 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
294 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
300 ;; Set when modrm byte is used.
301 (define_attr "modrm" ""
302 (cond [(eq_attr "type" "str,cld,leave")
304 (eq_attr "unit" "i387")
306 (and (eq_attr "type" "incdec")
307 (ior (match_operand:SI 1 "register_operand" "")
308 (match_operand:HI 1 "register_operand" "")))
310 (and (eq_attr "type" "push")
311 (not (match_operand 1 "memory_operand" "")))
313 (and (eq_attr "type" "pop")
314 (not (match_operand 0 "memory_operand" "")))
316 (and (eq_attr "type" "imov")
317 (and (match_operand 0 "register_operand" "")
318 (match_operand 1 "immediate_operand" "")))
320 (and (eq_attr "type" "call")
321 (match_operand 0 "constant_call_address_operand" ""))
323 (and (eq_attr "type" "callv")
324 (match_operand 1 "constant_call_address_operand" ""))
329 ;; The (bounding maximum) length of an instruction in bytes.
330 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
331 ;; Later we may want to split them and compute proper length as for
333 (define_attr "length" ""
334 (cond [(eq_attr "type" "other,multi,fistp,frndint")
336 (eq_attr "type" "fcmp")
338 (eq_attr "unit" "i387")
340 (plus (attr "prefix_data16")
341 (attr "length_address")))]
342 (plus (plus (attr "modrm")
343 (plus (attr "prefix_0f")
344 (plus (attr "prefix_rex")
346 (plus (attr "prefix_rep")
347 (plus (attr "prefix_data16")
348 (plus (attr "length_immediate")
349 (attr "length_address")))))))
351 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
352 ;; `store' if there is a simple memory reference therein, or `unknown'
353 ;; if the instruction is complex.
355 (define_attr "memory" "none,load,store,both,unknown"
356 (cond [(eq_attr "type" "other,multi,str")
357 (const_string "unknown")
358 (eq_attr "type" "lea,fcmov,fpspc,cld")
359 (const_string "none")
360 (eq_attr "type" "fistp,leave")
361 (const_string "both")
362 (eq_attr "type" "frndint")
363 (const_string "load")
364 (eq_attr "type" "push")
365 (if_then_else (match_operand 1 "memory_operand" "")
366 (const_string "both")
367 (const_string "store"))
368 (eq_attr "type" "pop")
369 (if_then_else (match_operand 0 "memory_operand" "")
370 (const_string "both")
371 (const_string "load"))
372 (eq_attr "type" "setcc")
373 (if_then_else (match_operand 0 "memory_operand" "")
374 (const_string "store")
375 (const_string "none"))
376 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
377 (if_then_else (ior (match_operand 0 "memory_operand" "")
378 (match_operand 1 "memory_operand" ""))
379 (const_string "load")
380 (const_string "none"))
381 (eq_attr "type" "ibr")
382 (if_then_else (match_operand 0 "memory_operand" "")
383 (const_string "load")
384 (const_string "none"))
385 (eq_attr "type" "call")
386 (if_then_else (match_operand 0 "constant_call_address_operand" "")
387 (const_string "none")
388 (const_string "load"))
389 (eq_attr "type" "callv")
390 (if_then_else (match_operand 1 "constant_call_address_operand" "")
391 (const_string "none")
392 (const_string "load"))
393 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
394 (match_operand 1 "memory_operand" ""))
395 (const_string "both")
396 (and (match_operand 0 "memory_operand" "")
397 (match_operand 1 "memory_operand" ""))
398 (const_string "both")
399 (match_operand 0 "memory_operand" "")
400 (const_string "store")
401 (match_operand 1 "memory_operand" "")
402 (const_string "load")
404 "!alu1,negnot,ishift1,
405 imov,imovx,icmp,test,
407 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
408 mmx,mmxmov,mmxcmp,mmxcvt")
409 (match_operand 2 "memory_operand" ""))
410 (const_string "load")
411 (and (eq_attr "type" "icmov")
412 (match_operand 3 "memory_operand" ""))
413 (const_string "load")
415 (const_string "none")))
417 ;; Indicates if an instruction has both an immediate and a displacement.
419 (define_attr "imm_disp" "false,true,unknown"
420 (cond [(eq_attr "type" "other,multi")
421 (const_string "unknown")
422 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
423 (and (match_operand 0 "memory_displacement_operand" "")
424 (match_operand 1 "immediate_operand" "")))
425 (const_string "true")
426 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
427 (and (match_operand 0 "memory_displacement_operand" "")
428 (match_operand 2 "immediate_operand" "")))
429 (const_string "true")
431 (const_string "false")))
433 ;; Indicates if an FP operation has an integer source.
435 (define_attr "fp_int_src" "false,true"
436 (const_string "false"))
438 ;; Defines rounding mode of an FP operation.
440 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
441 (const_string "any"))
443 ;; Describe a user's asm statement.
444 (define_asm_attributes
445 [(set_attr "length" "128")
446 (set_attr "type" "multi")])
448 ;; All x87 floating point modes
449 (define_mode_macro X87MODEF [SF DF XF])
451 ;; All integer modes handled by x87 fisttp operator.
452 (define_mode_macro X87MODEI [HI SI DI])
454 ;; All integer modes handled by integer x87 operators.
455 (define_mode_macro X87MODEI12 [HI SI])
457 ;; All SSE floating point modes
458 (define_mode_macro SSEMODEF [SF DF])
460 ;; All integer modes handled by SSE cvtts?2si* operators.
461 (define_mode_macro SSEMODEI24 [SI DI])
464 ;; Scheduling descriptions
466 (include "pentium.md")
469 (include "athlon.md")
472 ;; Operand and operator predicates
474 (include "predicates.md")
477 ;; Compare instructions.
479 ;; All compare insns have expanders that save the operands away without
480 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
481 ;; after the cmp) will actually emit the cmpM.
483 (define_expand "cmpti"
484 [(set (reg:CC FLAGS_REG)
485 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
486 (match_operand:TI 1 "x86_64_general_operand" "")))]
489 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
490 operands[0] = force_reg (TImode, operands[0]);
491 ix86_compare_op0 = operands[0];
492 ix86_compare_op1 = operands[1];
496 (define_expand "cmpdi"
497 [(set (reg:CC FLAGS_REG)
498 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
499 (match_operand:DI 1 "x86_64_general_operand" "")))]
502 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
503 operands[0] = force_reg (DImode, operands[0]);
504 ix86_compare_op0 = operands[0];
505 ix86_compare_op1 = operands[1];
509 (define_expand "cmpsi"
510 [(set (reg:CC FLAGS_REG)
511 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
512 (match_operand:SI 1 "general_operand" "")))]
515 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
516 operands[0] = force_reg (SImode, operands[0]);
517 ix86_compare_op0 = operands[0];
518 ix86_compare_op1 = operands[1];
522 (define_expand "cmphi"
523 [(set (reg:CC FLAGS_REG)
524 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
525 (match_operand:HI 1 "general_operand" "")))]
528 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
529 operands[0] = force_reg (HImode, operands[0]);
530 ix86_compare_op0 = operands[0];
531 ix86_compare_op1 = operands[1];
535 (define_expand "cmpqi"
536 [(set (reg:CC FLAGS_REG)
537 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
538 (match_operand:QI 1 "general_operand" "")))]
541 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
542 operands[0] = force_reg (QImode, operands[0]);
543 ix86_compare_op0 = operands[0];
544 ix86_compare_op1 = operands[1];
548 (define_insn "cmpdi_ccno_1_rex64"
549 [(set (reg FLAGS_REG)
550 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
551 (match_operand:DI 1 "const0_operand" "n,n")))]
552 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
554 test{q}\t{%0, %0|%0, %0}
555 cmp{q}\t{%1, %0|%0, %1}"
556 [(set_attr "type" "test,icmp")
557 (set_attr "length_immediate" "0,1")
558 (set_attr "mode" "DI")])
560 (define_insn "*cmpdi_minus_1_rex64"
561 [(set (reg FLAGS_REG)
562 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
563 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
565 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
566 "cmp{q}\t{%1, %0|%0, %1}"
567 [(set_attr "type" "icmp")
568 (set_attr "mode" "DI")])
570 (define_expand "cmpdi_1_rex64"
571 [(set (reg:CC FLAGS_REG)
572 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
573 (match_operand:DI 1 "general_operand" "")))]
577 (define_insn "cmpdi_1_insn_rex64"
578 [(set (reg FLAGS_REG)
579 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
580 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
581 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
582 "cmp{q}\t{%1, %0|%0, %1}"
583 [(set_attr "type" "icmp")
584 (set_attr "mode" "DI")])
587 (define_insn "*cmpsi_ccno_1"
588 [(set (reg FLAGS_REG)
589 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
590 (match_operand:SI 1 "const0_operand" "n,n")))]
591 "ix86_match_ccmode (insn, CCNOmode)"
593 test{l}\t{%0, %0|%0, %0}
594 cmp{l}\t{%1, %0|%0, %1}"
595 [(set_attr "type" "test,icmp")
596 (set_attr "length_immediate" "0,1")
597 (set_attr "mode" "SI")])
599 (define_insn "*cmpsi_minus_1"
600 [(set (reg FLAGS_REG)
601 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
602 (match_operand:SI 1 "general_operand" "ri,mr"))
604 "ix86_match_ccmode (insn, CCGOCmode)"
605 "cmp{l}\t{%1, %0|%0, %1}"
606 [(set_attr "type" "icmp")
607 (set_attr "mode" "SI")])
609 (define_expand "cmpsi_1"
610 [(set (reg:CC FLAGS_REG)
611 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
612 (match_operand:SI 1 "general_operand" "ri,mr")))]
616 (define_insn "*cmpsi_1_insn"
617 [(set (reg FLAGS_REG)
618 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
619 (match_operand:SI 1 "general_operand" "ri,mr")))]
620 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
621 && ix86_match_ccmode (insn, CCmode)"
622 "cmp{l}\t{%1, %0|%0, %1}"
623 [(set_attr "type" "icmp")
624 (set_attr "mode" "SI")])
626 (define_insn "*cmphi_ccno_1"
627 [(set (reg FLAGS_REG)
628 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
629 (match_operand:HI 1 "const0_operand" "n,n")))]
630 "ix86_match_ccmode (insn, CCNOmode)"
632 test{w}\t{%0, %0|%0, %0}
633 cmp{w}\t{%1, %0|%0, %1}"
634 [(set_attr "type" "test,icmp")
635 (set_attr "length_immediate" "0,1")
636 (set_attr "mode" "HI")])
638 (define_insn "*cmphi_minus_1"
639 [(set (reg FLAGS_REG)
640 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
641 (match_operand:HI 1 "general_operand" "ri,mr"))
643 "ix86_match_ccmode (insn, CCGOCmode)"
644 "cmp{w}\t{%1, %0|%0, %1}"
645 [(set_attr "type" "icmp")
646 (set_attr "mode" "HI")])
648 (define_insn "*cmphi_1"
649 [(set (reg FLAGS_REG)
650 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
651 (match_operand:HI 1 "general_operand" "ri,mr")))]
652 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
653 && ix86_match_ccmode (insn, CCmode)"
654 "cmp{w}\t{%1, %0|%0, %1}"
655 [(set_attr "type" "icmp")
656 (set_attr "mode" "HI")])
658 (define_insn "*cmpqi_ccno_1"
659 [(set (reg FLAGS_REG)
660 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
661 (match_operand:QI 1 "const0_operand" "n,n")))]
662 "ix86_match_ccmode (insn, CCNOmode)"
664 test{b}\t{%0, %0|%0, %0}
665 cmp{b}\t{$0, %0|%0, 0}"
666 [(set_attr "type" "test,icmp")
667 (set_attr "length_immediate" "0,1")
668 (set_attr "mode" "QI")])
670 (define_insn "*cmpqi_1"
671 [(set (reg FLAGS_REG)
672 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
673 (match_operand:QI 1 "general_operand" "qi,mq")))]
674 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
675 && ix86_match_ccmode (insn, CCmode)"
676 "cmp{b}\t{%1, %0|%0, %1}"
677 [(set_attr "type" "icmp")
678 (set_attr "mode" "QI")])
680 (define_insn "*cmpqi_minus_1"
681 [(set (reg FLAGS_REG)
682 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
683 (match_operand:QI 1 "general_operand" "qi,mq"))
685 "ix86_match_ccmode (insn, CCGOCmode)"
686 "cmp{b}\t{%1, %0|%0, %1}"
687 [(set_attr "type" "icmp")
688 (set_attr "mode" "QI")])
690 (define_insn "*cmpqi_ext_1"
691 [(set (reg FLAGS_REG)
693 (match_operand:QI 0 "general_operand" "Qm")
696 (match_operand 1 "ext_register_operand" "Q")
699 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
700 "cmp{b}\t{%h1, %0|%0, %h1}"
701 [(set_attr "type" "icmp")
702 (set_attr "mode" "QI")])
704 (define_insn "*cmpqi_ext_1_rex64"
705 [(set (reg FLAGS_REG)
707 (match_operand:QI 0 "register_operand" "Q")
710 (match_operand 1 "ext_register_operand" "Q")
713 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
714 "cmp{b}\t{%h1, %0|%0, %h1}"
715 [(set_attr "type" "icmp")
716 (set_attr "mode" "QI")])
718 (define_insn "*cmpqi_ext_2"
719 [(set (reg FLAGS_REG)
723 (match_operand 0 "ext_register_operand" "Q")
726 (match_operand:QI 1 "const0_operand" "n")))]
727 "ix86_match_ccmode (insn, CCNOmode)"
729 [(set_attr "type" "test")
730 (set_attr "length_immediate" "0")
731 (set_attr "mode" "QI")])
733 (define_expand "cmpqi_ext_3"
734 [(set (reg:CC FLAGS_REG)
738 (match_operand 0 "ext_register_operand" "")
741 (match_operand:QI 1 "general_operand" "")))]
745 (define_insn "cmpqi_ext_3_insn"
746 [(set (reg FLAGS_REG)
750 (match_operand 0 "ext_register_operand" "Q")
753 (match_operand:QI 1 "general_operand" "Qmn")))]
754 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
755 "cmp{b}\t{%1, %h0|%h0, %1}"
756 [(set_attr "type" "icmp")
757 (set_attr "mode" "QI")])
759 (define_insn "cmpqi_ext_3_insn_rex64"
760 [(set (reg FLAGS_REG)
764 (match_operand 0 "ext_register_operand" "Q")
767 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
768 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
769 "cmp{b}\t{%1, %h0|%h0, %1}"
770 [(set_attr "type" "icmp")
771 (set_attr "mode" "QI")])
773 (define_insn "*cmpqi_ext_4"
774 [(set (reg FLAGS_REG)
778 (match_operand 0 "ext_register_operand" "Q")
783 (match_operand 1 "ext_register_operand" "Q")
786 "ix86_match_ccmode (insn, CCmode)"
787 "cmp{b}\t{%h1, %h0|%h0, %h1}"
788 [(set_attr "type" "icmp")
789 (set_attr "mode" "QI")])
791 ;; These implement float point compares.
792 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
793 ;; which would allow mix and match FP modes on the compares. Which is what
794 ;; the old patterns did, but with many more of them.
796 (define_expand "cmpxf"
797 [(set (reg:CC FLAGS_REG)
798 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
799 (match_operand:XF 1 "nonmemory_operand" "")))]
802 ix86_compare_op0 = operands[0];
803 ix86_compare_op1 = operands[1];
807 (define_expand "cmpdf"
808 [(set (reg:CC FLAGS_REG)
809 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
810 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
811 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
813 ix86_compare_op0 = operands[0];
814 ix86_compare_op1 = operands[1];
818 (define_expand "cmpsf"
819 [(set (reg:CC FLAGS_REG)
820 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
821 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
822 "TARGET_80387 || TARGET_SSE_MATH"
824 ix86_compare_op0 = operands[0];
825 ix86_compare_op1 = operands[1];
829 ;; FP compares, step 1:
830 ;; Set the FP condition codes.
832 ;; CCFPmode compare with exceptions
833 ;; CCFPUmode compare with no exceptions
835 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
836 ;; used to manage the reg stack popping would not be preserved.
838 (define_insn "*cmpfp_0"
839 [(set (match_operand:HI 0 "register_operand" "=a")
842 (match_operand 1 "register_operand" "f")
843 (match_operand 2 "const0_operand" "X"))]
846 && FLOAT_MODE_P (GET_MODE (operands[1]))
847 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
848 "* return output_fp_compare (insn, operands, 0, 0);"
849 [(set_attr "type" "multi")
850 (set_attr "unit" "i387")
852 (cond [(match_operand:SF 1 "" "")
854 (match_operand:DF 1 "" "")
857 (const_string "XF")))])
859 (define_insn "*cmpfp_sf"
860 [(set (match_operand:HI 0 "register_operand" "=a")
863 (match_operand:SF 1 "register_operand" "f")
864 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
867 "* return output_fp_compare (insn, operands, 0, 0);"
868 [(set_attr "type" "multi")
869 (set_attr "unit" "i387")
870 (set_attr "mode" "SF")])
872 (define_insn "*cmpfp_df"
873 [(set (match_operand:HI 0 "register_operand" "=a")
876 (match_operand:DF 1 "register_operand" "f")
877 (match_operand:DF 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" "DF")])
885 (define_insn "*cmpfp_xf"
886 [(set (match_operand:HI 0 "register_operand" "=a")
889 (match_operand:XF 1 "register_operand" "f")
890 (match_operand:XF 2 "register_operand" "f"))]
893 "* return output_fp_compare (insn, operands, 0, 0);"
894 [(set_attr "type" "multi")
895 (set_attr "unit" "i387")
896 (set_attr "mode" "XF")])
898 (define_insn "*cmpfp_u"
899 [(set (match_operand:HI 0 "register_operand" "=a")
902 (match_operand 1 "register_operand" "f")
903 (match_operand 2 "register_operand" "f"))]
906 && FLOAT_MODE_P (GET_MODE (operands[1]))
907 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
908 "* return output_fp_compare (insn, operands, 0, 1);"
909 [(set_attr "type" "multi")
910 (set_attr "unit" "i387")
912 (cond [(match_operand:SF 1 "" "")
914 (match_operand:DF 1 "" "")
917 (const_string "XF")))])
919 (define_insn "*cmpfp_<mode>"
920 [(set (match_operand:HI 0 "register_operand" "=a")
923 (match_operand 1 "register_operand" "f")
924 (match_operator 3 "float_operator"
925 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
927 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
928 && FLOAT_MODE_P (GET_MODE (operands[1]))
929 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
930 "* return output_fp_compare (insn, operands, 0, 0);"
931 [(set_attr "type" "multi")
932 (set_attr "unit" "i387")
933 (set_attr "fp_int_src" "true")
934 (set_attr "mode" "<MODE>")])
936 ;; FP compares, step 2
937 ;; Move the fpsw to ax.
939 (define_insn "x86_fnstsw_1"
940 [(set (match_operand:HI 0 "register_operand" "=a")
941 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
944 [(set_attr "length" "2")
945 (set_attr "mode" "SI")
946 (set_attr "unit" "i387")])
948 ;; FP compares, step 3
949 ;; Get ax into flags, general case.
951 (define_insn "x86_sahf_1"
952 [(set (reg:CC FLAGS_REG)
953 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
956 [(set_attr "length" "1")
957 (set_attr "athlon_decode" "vector")
958 (set_attr "mode" "SI")])
960 ;; Pentium Pro can do steps 1 through 3 in one go.
962 (define_insn "*cmpfp_i_mixed"
963 [(set (reg:CCFP FLAGS_REG)
964 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
965 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
967 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
968 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
969 "* return output_fp_compare (insn, operands, 1, 0);"
970 [(set_attr "type" "fcmp,ssecomi")
972 (if_then_else (match_operand:SF 1 "" "")
974 (const_string "DF")))
975 (set_attr "athlon_decode" "vector")])
977 (define_insn "*cmpfp_i_sse"
978 [(set (reg:CCFP FLAGS_REG)
979 (compare:CCFP (match_operand 0 "register_operand" "x")
980 (match_operand 1 "nonimmediate_operand" "xm")))]
982 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
983 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
984 "* return output_fp_compare (insn, operands, 1, 0);"
985 [(set_attr "type" "ssecomi")
987 (if_then_else (match_operand:SF 1 "" "")
989 (const_string "DF")))
990 (set_attr "athlon_decode" "vector")])
992 (define_insn "*cmpfp_i_i387"
993 [(set (reg:CCFP FLAGS_REG)
994 (compare:CCFP (match_operand 0 "register_operand" "f")
995 (match_operand 1 "register_operand" "f")))]
996 "TARGET_80387 && TARGET_CMOVE
997 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
998 && FLOAT_MODE_P (GET_MODE (operands[0]))
999 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1000 "* return output_fp_compare (insn, operands, 1, 0);"
1001 [(set_attr "type" "fcmp")
1003 (cond [(match_operand:SF 1 "" "")
1005 (match_operand:DF 1 "" "")
1008 (const_string "XF")))
1009 (set_attr "athlon_decode" "vector")])
1011 (define_insn "*cmpfp_iu_mixed"
1012 [(set (reg:CCFPU FLAGS_REG)
1013 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1014 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1015 "TARGET_MIX_SSE_I387
1016 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1017 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1018 "* return output_fp_compare (insn, operands, 1, 1);"
1019 [(set_attr "type" "fcmp,ssecomi")
1021 (if_then_else (match_operand:SF 1 "" "")
1023 (const_string "DF")))
1024 (set_attr "athlon_decode" "vector")])
1026 (define_insn "*cmpfp_iu_sse"
1027 [(set (reg:CCFPU FLAGS_REG)
1028 (compare:CCFPU (match_operand 0 "register_operand" "x")
1029 (match_operand 1 "nonimmediate_operand" "xm")))]
1031 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1032 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033 "* return output_fp_compare (insn, operands, 1, 1);"
1034 [(set_attr "type" "ssecomi")
1036 (if_then_else (match_operand:SF 1 "" "")
1038 (const_string "DF")))
1039 (set_attr "athlon_decode" "vector")])
1041 (define_insn "*cmpfp_iu_387"
1042 [(set (reg:CCFPU FLAGS_REG)
1043 (compare:CCFPU (match_operand 0 "register_operand" "f")
1044 (match_operand 1 "register_operand" "f")))]
1045 "TARGET_80387 && TARGET_CMOVE
1046 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1047 && FLOAT_MODE_P (GET_MODE (operands[0]))
1048 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1049 "* return output_fp_compare (insn, operands, 1, 1);"
1050 [(set_attr "type" "fcmp")
1052 (cond [(match_operand:SF 1 "" "")
1054 (match_operand:DF 1 "" "")
1057 (const_string "XF")))
1058 (set_attr "athlon_decode" "vector")])
1060 ;; Move instructions.
1062 ;; General case of fullword move.
1064 (define_expand "movsi"
1065 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1066 (match_operand:SI 1 "general_operand" ""))]
1068 "ix86_expand_move (SImode, operands); DONE;")
1070 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1073 ;; %%% We don't use a post-inc memory reference because x86 is not a
1074 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1075 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1076 ;; targets without our curiosities, and it is just as easy to represent
1077 ;; this differently.
1079 (define_insn "*pushsi2"
1080 [(set (match_operand:SI 0 "push_operand" "=<")
1081 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1084 [(set_attr "type" "push")
1085 (set_attr "mode" "SI")])
1087 ;; For 64BIT abi we always round up to 8 bytes.
1088 (define_insn "*pushsi2_rex64"
1089 [(set (match_operand:SI 0 "push_operand" "=X")
1090 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1093 [(set_attr "type" "push")
1094 (set_attr "mode" "SI")])
1096 (define_insn "*pushsi2_prologue"
1097 [(set (match_operand:SI 0 "push_operand" "=<")
1098 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1099 (clobber (mem:BLK (scratch)))]
1102 [(set_attr "type" "push")
1103 (set_attr "mode" "SI")])
1105 (define_insn "*popsi1_epilogue"
1106 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1107 (mem:SI (reg:SI SP_REG)))
1108 (set (reg:SI SP_REG)
1109 (plus:SI (reg:SI SP_REG) (const_int 4)))
1110 (clobber (mem:BLK (scratch)))]
1113 [(set_attr "type" "pop")
1114 (set_attr "mode" "SI")])
1116 (define_insn "popsi1"
1117 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1118 (mem:SI (reg:SI SP_REG)))
1119 (set (reg:SI SP_REG)
1120 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1123 [(set_attr "type" "pop")
1124 (set_attr "mode" "SI")])
1126 (define_insn "*movsi_xor"
1127 [(set (match_operand:SI 0 "register_operand" "=r")
1128 (match_operand:SI 1 "const0_operand" "i"))
1129 (clobber (reg:CC FLAGS_REG))]
1130 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1131 "xor{l}\t{%0, %0|%0, %0}"
1132 [(set_attr "type" "alu1")
1133 (set_attr "mode" "SI")
1134 (set_attr "length_immediate" "0")])
1136 (define_insn "*movsi_or"
1137 [(set (match_operand:SI 0 "register_operand" "=r")
1138 (match_operand:SI 1 "immediate_operand" "i"))
1139 (clobber (reg:CC FLAGS_REG))]
1141 && operands[1] == constm1_rtx
1142 && (TARGET_PENTIUM || optimize_size)"
1144 operands[1] = constm1_rtx;
1145 return "or{l}\t{%1, %0|%0, %1}";
1147 [(set_attr "type" "alu1")
1148 (set_attr "mode" "SI")
1149 (set_attr "length_immediate" "1")])
1151 (define_insn "*movsi_1"
1152 [(set (match_operand:SI 0 "nonimmediate_operand"
1153 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1154 (match_operand:SI 1 "general_operand"
1155 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1156 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1158 switch (get_attr_type (insn))
1161 if (get_attr_mode (insn) == MODE_TI)
1162 return "pxor\t%0, %0";
1163 return "xorps\t%0, %0";
1166 switch (get_attr_mode (insn))
1169 return "movdqa\t{%1, %0|%0, %1}";
1171 return "movaps\t{%1, %0|%0, %1}";
1173 return "movd\t{%1, %0|%0, %1}";
1175 return "movss\t{%1, %0|%0, %1}";
1181 return "pxor\t%0, %0";
1184 if (get_attr_mode (insn) == MODE_DI)
1185 return "movq\t{%1, %0|%0, %1}";
1186 return "movd\t{%1, %0|%0, %1}";
1189 return "lea{l}\t{%1, %0|%0, %1}";
1192 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1193 return "mov{l}\t{%1, %0|%0, %1}";
1197 (cond [(eq_attr "alternative" "2")
1198 (const_string "mmxadd")
1199 (eq_attr "alternative" "3,4,5")
1200 (const_string "mmxmov")
1201 (eq_attr "alternative" "6")
1202 (const_string "sselog1")
1203 (eq_attr "alternative" "7,8,9,10,11")
1204 (const_string "ssemov")
1205 (match_operand:DI 1 "pic_32bit_operand" "")
1206 (const_string "lea")
1208 (const_string "imov")))
1210 (cond [(eq_attr "alternative" "2,3")
1212 (eq_attr "alternative" "6,7")
1214 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1215 (const_string "V4SF")
1216 (const_string "TI"))
1217 (and (eq_attr "alternative" "8,9,10,11")
1218 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1221 (const_string "SI")))])
1223 ;; Stores and loads of ax to arbitrary constant address.
1224 ;; We fake an second form of instruction to force reload to load address
1225 ;; into register when rax is not available
1226 (define_insn "*movabssi_1_rex64"
1227 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1228 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1229 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1231 movabs{l}\t{%1, %P0|%P0, %1}
1232 mov{l}\t{%1, %a0|%a0, %1}"
1233 [(set_attr "type" "imov")
1234 (set_attr "modrm" "0,*")
1235 (set_attr "length_address" "8,0")
1236 (set_attr "length_immediate" "0,*")
1237 (set_attr "memory" "store")
1238 (set_attr "mode" "SI")])
1240 (define_insn "*movabssi_2_rex64"
1241 [(set (match_operand:SI 0 "register_operand" "=a,r")
1242 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1243 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1245 movabs{l}\t{%P1, %0|%0, %P1}
1246 mov{l}\t{%a1, %0|%0, %a1}"
1247 [(set_attr "type" "imov")
1248 (set_attr "modrm" "0,*")
1249 (set_attr "length_address" "8,0")
1250 (set_attr "length_immediate" "0")
1251 (set_attr "memory" "load")
1252 (set_attr "mode" "SI")])
1254 (define_insn "*swapsi"
1255 [(set (match_operand:SI 0 "register_operand" "+r")
1256 (match_operand:SI 1 "register_operand" "+r"))
1261 [(set_attr "type" "imov")
1262 (set_attr "mode" "SI")
1263 (set_attr "pent_pair" "np")
1264 (set_attr "athlon_decode" "vector")])
1266 (define_expand "movhi"
1267 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1268 (match_operand:HI 1 "general_operand" ""))]
1270 "ix86_expand_move (HImode, operands); DONE;")
1272 (define_insn "*pushhi2"
1273 [(set (match_operand:HI 0 "push_operand" "=<,<")
1274 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1277 push{w}\t{|WORD PTR }%1
1279 [(set_attr "type" "push")
1280 (set_attr "mode" "HI")])
1282 ;; For 64BIT abi we always round up to 8 bytes.
1283 (define_insn "*pushhi2_rex64"
1284 [(set (match_operand:HI 0 "push_operand" "=X")
1285 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1288 [(set_attr "type" "push")
1289 (set_attr "mode" "QI")])
1291 (define_insn "*movhi_1"
1292 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1293 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1294 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1296 switch (get_attr_type (insn))
1299 /* movzwl is faster than movw on p2 due to partial word stalls,
1300 though not as fast as an aligned movl. */
1301 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1303 if (get_attr_mode (insn) == MODE_SI)
1304 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1306 return "mov{w}\t{%1, %0|%0, %1}";
1310 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1311 (const_string "imov")
1312 (and (eq_attr "alternative" "0")
1313 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1315 (eq (symbol_ref "TARGET_HIMODE_MATH")
1317 (const_string "imov")
1318 (and (eq_attr "alternative" "1,2")
1319 (match_operand:HI 1 "aligned_operand" ""))
1320 (const_string "imov")
1321 (and (ne (symbol_ref "TARGET_MOVX")
1323 (eq_attr "alternative" "0,2"))
1324 (const_string "imovx")
1326 (const_string "imov")))
1328 (cond [(eq_attr "type" "imovx")
1330 (and (eq_attr "alternative" "1,2")
1331 (match_operand:HI 1 "aligned_operand" ""))
1333 (and (eq_attr "alternative" "0")
1334 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1336 (eq (symbol_ref "TARGET_HIMODE_MATH")
1340 (const_string "HI")))])
1342 ;; Stores and loads of ax to arbitrary constant address.
1343 ;; We fake an second form of instruction to force reload to load address
1344 ;; into register when rax is not available
1345 (define_insn "*movabshi_1_rex64"
1346 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1347 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1348 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1350 movabs{w}\t{%1, %P0|%P0, %1}
1351 mov{w}\t{%1, %a0|%a0, %1}"
1352 [(set_attr "type" "imov")
1353 (set_attr "modrm" "0,*")
1354 (set_attr "length_address" "8,0")
1355 (set_attr "length_immediate" "0,*")
1356 (set_attr "memory" "store")
1357 (set_attr "mode" "HI")])
1359 (define_insn "*movabshi_2_rex64"
1360 [(set (match_operand:HI 0 "register_operand" "=a,r")
1361 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1362 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1364 movabs{w}\t{%P1, %0|%0, %P1}
1365 mov{w}\t{%a1, %0|%0, %a1}"
1366 [(set_attr "type" "imov")
1367 (set_attr "modrm" "0,*")
1368 (set_attr "length_address" "8,0")
1369 (set_attr "length_immediate" "0")
1370 (set_attr "memory" "load")
1371 (set_attr "mode" "HI")])
1373 (define_insn "*swaphi_1"
1374 [(set (match_operand:HI 0 "register_operand" "+r")
1375 (match_operand:HI 1 "register_operand" "+r"))
1378 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1380 [(set_attr "type" "imov")
1381 (set_attr "mode" "SI")
1382 (set_attr "pent_pair" "np")
1383 (set_attr "athlon_decode" "vector")])
1385 (define_insn "*swaphi_2"
1386 [(set (match_operand:HI 0 "register_operand" "+r")
1387 (match_operand:HI 1 "register_operand" "+r"))
1390 "TARGET_PARTIAL_REG_STALL"
1392 [(set_attr "type" "imov")
1393 (set_attr "mode" "HI")
1394 (set_attr "pent_pair" "np")
1395 (set_attr "athlon_decode" "vector")])
1397 (define_expand "movstricthi"
1398 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1399 (match_operand:HI 1 "general_operand" ""))]
1400 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1402 /* Don't generate memory->memory moves, go through a register */
1403 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1404 operands[1] = force_reg (HImode, operands[1]);
1407 (define_insn "*movstricthi_1"
1408 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1409 (match_operand:HI 1 "general_operand" "rn,m"))]
1410 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1411 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1412 "mov{w}\t{%1, %0|%0, %1}"
1413 [(set_attr "type" "imov")
1414 (set_attr "mode" "HI")])
1416 (define_insn "*movstricthi_xor"
1417 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1418 (match_operand:HI 1 "const0_operand" "i"))
1419 (clobber (reg:CC FLAGS_REG))]
1421 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1422 "xor{w}\t{%0, %0|%0, %0}"
1423 [(set_attr "type" "alu1")
1424 (set_attr "mode" "HI")
1425 (set_attr "length_immediate" "0")])
1427 (define_expand "movqi"
1428 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1429 (match_operand:QI 1 "general_operand" ""))]
1431 "ix86_expand_move (QImode, operands); DONE;")
1433 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1434 ;; "push a byte". But actually we use pushw, which has the effect
1435 ;; of rounding the amount pushed up to a halfword.
1437 (define_insn "*pushqi2"
1438 [(set (match_operand:QI 0 "push_operand" "=X,X")
1439 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1442 push{w}\t{|word ptr }%1
1444 [(set_attr "type" "push")
1445 (set_attr "mode" "HI")])
1447 ;; For 64BIT abi we always round up to 8 bytes.
1448 (define_insn "*pushqi2_rex64"
1449 [(set (match_operand:QI 0 "push_operand" "=X")
1450 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1453 [(set_attr "type" "push")
1454 (set_attr "mode" "QI")])
1456 ;; Situation is quite tricky about when to choose full sized (SImode) move
1457 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1458 ;; partial register dependency machines (such as AMD Athlon), where QImode
1459 ;; moves issue extra dependency and for partial register stalls machines
1460 ;; that don't use QImode patterns (and QImode move cause stall on the next
1463 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1464 ;; register stall machines with, where we use QImode instructions, since
1465 ;; partial register stall can be caused there. Then we use movzx.
1466 (define_insn "*movqi_1"
1467 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1468 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,m ,qn"))]
1469 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1471 switch (get_attr_type (insn))
1474 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1475 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1477 if (get_attr_mode (insn) == MODE_SI)
1478 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1480 return "mov{b}\t{%1, %0|%0, %1}";
1484 (cond [(eq_attr "alternative" "5")
1485 (const_string "imovx")
1486 (ne (symbol_ref "optimize_size") (const_int 0))
1487 (const_string "imov")
1488 (and (eq_attr "alternative" "3")
1489 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1491 (eq (symbol_ref "TARGET_QIMODE_MATH")
1493 (const_string "imov")
1494 (eq_attr "alternative" "3")
1495 (const_string "imovx")
1496 (and (ne (symbol_ref "TARGET_MOVX")
1498 (eq_attr "alternative" "2"))
1499 (const_string "imovx")
1501 (const_string "imov")))
1503 (cond [(eq_attr "alternative" "3,4,5")
1505 (eq_attr "alternative" "6")
1507 (eq_attr "type" "imovx")
1509 (and (eq_attr "type" "imov")
1510 (and (eq_attr "alternative" "0,1")
1511 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1514 ;; Avoid partial register stalls when not using QImode arithmetic
1515 (and (eq_attr "type" "imov")
1516 (and (eq_attr "alternative" "0,1")
1517 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1519 (eq (symbol_ref "TARGET_QIMODE_MATH")
1523 (const_string "QI")))])
1525 (define_expand "reload_outqi"
1526 [(parallel [(match_operand:QI 0 "" "=m")
1527 (match_operand:QI 1 "register_operand" "r")
1528 (match_operand:QI 2 "register_operand" "=&q")])]
1532 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1534 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1535 if (! q_regs_operand (op1, QImode))
1537 emit_insn (gen_movqi (op2, op1));
1540 emit_insn (gen_movqi (op0, op1));
1544 (define_insn "*swapqi_1"
1545 [(set (match_operand:QI 0 "register_operand" "+r")
1546 (match_operand:QI 1 "register_operand" "+r"))
1549 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1551 [(set_attr "type" "imov")
1552 (set_attr "mode" "SI")
1553 (set_attr "pent_pair" "np")
1554 (set_attr "athlon_decode" "vector")])
1556 (define_insn "*swapqi_2"
1557 [(set (match_operand:QI 0 "register_operand" "+q")
1558 (match_operand:QI 1 "register_operand" "+q"))
1561 "TARGET_PARTIAL_REG_STALL"
1563 [(set_attr "type" "imov")
1564 (set_attr "mode" "QI")
1565 (set_attr "pent_pair" "np")
1566 (set_attr "athlon_decode" "vector")])
1568 (define_expand "movstrictqi"
1569 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1570 (match_operand:QI 1 "general_operand" ""))]
1571 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1573 /* Don't generate memory->memory moves, go through a register. */
1574 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1575 operands[1] = force_reg (QImode, operands[1]);
1578 (define_insn "*movstrictqi_1"
1579 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1580 (match_operand:QI 1 "general_operand" "*qn,m"))]
1581 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1582 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1583 "mov{b}\t{%1, %0|%0, %1}"
1584 [(set_attr "type" "imov")
1585 (set_attr "mode" "QI")])
1587 (define_insn "*movstrictqi_xor"
1588 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1589 (match_operand:QI 1 "const0_operand" "i"))
1590 (clobber (reg:CC FLAGS_REG))]
1591 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1592 "xor{b}\t{%0, %0|%0, %0}"
1593 [(set_attr "type" "alu1")
1594 (set_attr "mode" "QI")
1595 (set_attr "length_immediate" "0")])
1597 (define_insn "*movsi_extv_1"
1598 [(set (match_operand:SI 0 "register_operand" "=R")
1599 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1603 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1604 [(set_attr "type" "imovx")
1605 (set_attr "mode" "SI")])
1607 (define_insn "*movhi_extv_1"
1608 [(set (match_operand:HI 0 "register_operand" "=R")
1609 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1613 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1614 [(set_attr "type" "imovx")
1615 (set_attr "mode" "SI")])
1617 (define_insn "*movqi_extv_1"
1618 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1619 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1624 switch (get_attr_type (insn))
1627 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1629 return "mov{b}\t{%h1, %0|%0, %h1}";
1633 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1634 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1635 (ne (symbol_ref "TARGET_MOVX")
1637 (const_string "imovx")
1638 (const_string "imov")))
1640 (if_then_else (eq_attr "type" "imovx")
1642 (const_string "QI")))])
1644 (define_insn "*movqi_extv_1_rex64"
1645 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1646 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1651 switch (get_attr_type (insn))
1654 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1656 return "mov{b}\t{%h1, %0|%0, %h1}";
1660 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1661 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1662 (ne (symbol_ref "TARGET_MOVX")
1664 (const_string "imovx")
1665 (const_string "imov")))
1667 (if_then_else (eq_attr "type" "imovx")
1669 (const_string "QI")))])
1671 ;; Stores and loads of ax to arbitrary constant address.
1672 ;; We fake an second form of instruction to force reload to load address
1673 ;; into register when rax is not available
1674 (define_insn "*movabsqi_1_rex64"
1675 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1676 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1677 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1679 movabs{b}\t{%1, %P0|%P0, %1}
1680 mov{b}\t{%1, %a0|%a0, %1}"
1681 [(set_attr "type" "imov")
1682 (set_attr "modrm" "0,*")
1683 (set_attr "length_address" "8,0")
1684 (set_attr "length_immediate" "0,*")
1685 (set_attr "memory" "store")
1686 (set_attr "mode" "QI")])
1688 (define_insn "*movabsqi_2_rex64"
1689 [(set (match_operand:QI 0 "register_operand" "=a,r")
1690 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1691 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1693 movabs{b}\t{%P1, %0|%0, %P1}
1694 mov{b}\t{%a1, %0|%0, %a1}"
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" "load")
1700 (set_attr "mode" "QI")])
1702 (define_insn "*movdi_extzv_1"
1703 [(set (match_operand:DI 0 "register_operand" "=R")
1704 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1708 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1709 [(set_attr "type" "imovx")
1710 (set_attr "mode" "DI")])
1712 (define_insn "*movsi_extzv_1"
1713 [(set (match_operand:SI 0 "register_operand" "=R")
1714 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1718 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1719 [(set_attr "type" "imovx")
1720 (set_attr "mode" "SI")])
1722 (define_insn "*movqi_extzv_2"
1723 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1724 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1729 switch (get_attr_type (insn))
1732 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1734 return "mov{b}\t{%h1, %0|%0, %h1}";
1738 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1739 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1740 (ne (symbol_ref "TARGET_MOVX")
1742 (const_string "imovx")
1743 (const_string "imov")))
1745 (if_then_else (eq_attr "type" "imovx")
1747 (const_string "QI")))])
1749 (define_insn "*movqi_extzv_2_rex64"
1750 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1751 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1756 switch (get_attr_type (insn))
1759 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1761 return "mov{b}\t{%h1, %0|%0, %h1}";
1765 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1766 (ne (symbol_ref "TARGET_MOVX")
1768 (const_string "imovx")
1769 (const_string "imov")))
1771 (if_then_else (eq_attr "type" "imovx")
1773 (const_string "QI")))])
1775 (define_insn "movsi_insv_1"
1776 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1779 (match_operand:SI 1 "general_operand" "Qmn"))]
1781 "mov{b}\t{%b1, %h0|%h0, %b1}"
1782 [(set_attr "type" "imov")
1783 (set_attr "mode" "QI")])
1785 (define_insn "movdi_insv_1_rex64"
1786 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1789 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1791 "mov{b}\t{%b1, %h0|%h0, %b1}"
1792 [(set_attr "type" "imov")
1793 (set_attr "mode" "QI")])
1795 (define_insn "*movqi_insv_2"
1796 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1799 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1802 "mov{b}\t{%h1, %h0|%h0, %h1}"
1803 [(set_attr "type" "imov")
1804 (set_attr "mode" "QI")])
1806 (define_expand "movdi"
1807 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1808 (match_operand:DI 1 "general_operand" ""))]
1810 "ix86_expand_move (DImode, operands); DONE;")
1812 (define_insn "*pushdi"
1813 [(set (match_operand:DI 0 "push_operand" "=<")
1814 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1818 (define_insn "*pushdi2_rex64"
1819 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1820 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1825 [(set_attr "type" "push,multi")
1826 (set_attr "mode" "DI")])
1828 ;; Convert impossible pushes of immediate to existing instructions.
1829 ;; First try to get scratch register and go through it. In case this
1830 ;; fails, push sign extended lower part first and then overwrite
1831 ;; upper part by 32bit move.
1833 [(match_scratch:DI 2 "r")
1834 (set (match_operand:DI 0 "push_operand" "")
1835 (match_operand:DI 1 "immediate_operand" ""))]
1836 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1837 && !x86_64_immediate_operand (operands[1], DImode)"
1838 [(set (match_dup 2) (match_dup 1))
1839 (set (match_dup 0) (match_dup 2))]
1842 ;; We need to define this as both peepholer and splitter for case
1843 ;; peephole2 pass is not run.
1844 ;; "&& 1" is needed to keep it from matching the previous pattern.
1846 [(set (match_operand:DI 0 "push_operand" "")
1847 (match_operand:DI 1 "immediate_operand" ""))]
1848 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1849 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1850 [(set (match_dup 0) (match_dup 1))
1851 (set (match_dup 2) (match_dup 3))]
1852 "split_di (operands + 1, 1, operands + 2, operands + 3);
1853 operands[1] = gen_lowpart (DImode, operands[2]);
1854 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1859 [(set (match_operand:DI 0 "push_operand" "")
1860 (match_operand:DI 1 "immediate_operand" ""))]
1861 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1862 ? flow2_completed : reload_completed)
1863 && !symbolic_operand (operands[1], DImode)
1864 && !x86_64_immediate_operand (operands[1], DImode)"
1865 [(set (match_dup 0) (match_dup 1))
1866 (set (match_dup 2) (match_dup 3))]
1867 "split_di (operands + 1, 1, operands + 2, operands + 3);
1868 operands[1] = gen_lowpart (DImode, operands[2]);
1869 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1873 (define_insn "*pushdi2_prologue_rex64"
1874 [(set (match_operand:DI 0 "push_operand" "=<")
1875 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1876 (clobber (mem:BLK (scratch)))]
1879 [(set_attr "type" "push")
1880 (set_attr "mode" "DI")])
1882 (define_insn "*popdi1_epilogue_rex64"
1883 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1884 (mem:DI (reg:DI SP_REG)))
1885 (set (reg:DI SP_REG)
1886 (plus:DI (reg:DI SP_REG) (const_int 8)))
1887 (clobber (mem:BLK (scratch)))]
1890 [(set_attr "type" "pop")
1891 (set_attr "mode" "DI")])
1893 (define_insn "popdi1"
1894 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1895 (mem:DI (reg:DI SP_REG)))
1896 (set (reg:DI SP_REG)
1897 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1900 [(set_attr "type" "pop")
1901 (set_attr "mode" "DI")])
1903 (define_insn "*movdi_xor_rex64"
1904 [(set (match_operand:DI 0 "register_operand" "=r")
1905 (match_operand:DI 1 "const0_operand" "i"))
1906 (clobber (reg:CC FLAGS_REG))]
1907 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1908 && reload_completed"
1909 "xor{l}\t{%k0, %k0|%k0, %k0}"
1910 [(set_attr "type" "alu1")
1911 (set_attr "mode" "SI")
1912 (set_attr "length_immediate" "0")])
1914 (define_insn "*movdi_or_rex64"
1915 [(set (match_operand:DI 0 "register_operand" "=r")
1916 (match_operand:DI 1 "const_int_operand" "i"))
1917 (clobber (reg:CC FLAGS_REG))]
1918 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1920 && operands[1] == constm1_rtx"
1922 operands[1] = constm1_rtx;
1923 return "or{q}\t{%1, %0|%0, %1}";
1925 [(set_attr "type" "alu1")
1926 (set_attr "mode" "DI")
1927 (set_attr "length_immediate" "1")])
1929 (define_insn "*movdi_2"
1930 [(set (match_operand:DI 0 "nonimmediate_operand"
1931 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1932 (match_operand:DI 1 "general_operand"
1933 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1934 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1939 movq\t{%1, %0|%0, %1}
1940 movq\t{%1, %0|%0, %1}
1942 movq\t{%1, %0|%0, %1}
1943 movdqa\t{%1, %0|%0, %1}
1944 movq\t{%1, %0|%0, %1}
1946 movlps\t{%1, %0|%0, %1}
1947 movaps\t{%1, %0|%0, %1}
1948 movlps\t{%1, %0|%0, %1}"
1949 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1950 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1953 [(set (match_operand:DI 0 "push_operand" "")
1954 (match_operand:DI 1 "general_operand" ""))]
1955 "!TARGET_64BIT && reload_completed
1956 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1958 "ix86_split_long_move (operands); DONE;")
1960 ;; %%% This multiword shite has got to go.
1962 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1963 (match_operand:DI 1 "general_operand" ""))]
1964 "!TARGET_64BIT && reload_completed
1965 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1966 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1968 "ix86_split_long_move (operands); DONE;")
1970 (define_insn "*movdi_1_rex64"
1971 [(set (match_operand:DI 0 "nonimmediate_operand"
1972 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1973 (match_operand:DI 1 "general_operand"
1974 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1975 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1977 switch (get_attr_type (insn))
1980 if (which_alternative == 13)
1981 return "movq2dq\t{%1, %0|%0, %1}";
1983 return "movdq2q\t{%1, %0|%0, %1}";
1985 if (get_attr_mode (insn) == MODE_TI)
1986 return "movdqa\t{%1, %0|%0, %1}";
1989 /* Moves from and into integer register is done using movd opcode with
1991 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1992 return "movd\t{%1, %0|%0, %1}";
1993 return "movq\t{%1, %0|%0, %1}";
1996 return "pxor\t%0, %0";
2000 return "lea{q}\t{%a1, %0|%0, %a1}";
2002 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2003 if (get_attr_mode (insn) == MODE_SI)
2004 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2005 else if (which_alternative == 2)
2006 return "movabs{q}\t{%1, %0|%0, %1}";
2008 return "mov{q}\t{%1, %0|%0, %1}";
2012 (cond [(eq_attr "alternative" "5")
2013 (const_string "mmxadd")
2014 (eq_attr "alternative" "6,7,8")
2015 (const_string "mmxmov")
2016 (eq_attr "alternative" "9")
2017 (const_string "sselog1")
2018 (eq_attr "alternative" "10,11,12")
2019 (const_string "ssemov")
2020 (eq_attr "alternative" "13,14")
2021 (const_string "ssecvt")
2022 (eq_attr "alternative" "4")
2023 (const_string "multi")
2024 (match_operand:DI 1 "pic_32bit_operand" "")
2025 (const_string "lea")
2027 (const_string "imov")))
2028 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2029 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2030 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2032 ;; Stores and loads of ax to arbitrary constant address.
2033 ;; We fake an second form of instruction to force reload to load address
2034 ;; into register when rax is not available
2035 (define_insn "*movabsdi_1_rex64"
2036 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2037 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2038 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2040 movabs{q}\t{%1, %P0|%P0, %1}
2041 mov{q}\t{%1, %a0|%a0, %1}"
2042 [(set_attr "type" "imov")
2043 (set_attr "modrm" "0,*")
2044 (set_attr "length_address" "8,0")
2045 (set_attr "length_immediate" "0,*")
2046 (set_attr "memory" "store")
2047 (set_attr "mode" "DI")])
2049 (define_insn "*movabsdi_2_rex64"
2050 [(set (match_operand:DI 0 "register_operand" "=a,r")
2051 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2052 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2054 movabs{q}\t{%P1, %0|%0, %P1}
2055 mov{q}\t{%a1, %0|%0, %a1}"
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" "load")
2061 (set_attr "mode" "DI")])
2063 ;; Convert impossible stores of immediate to existing instructions.
2064 ;; First try to get scratch register and go through it. In case this
2065 ;; fails, move by 32bit parts.
2067 [(match_scratch:DI 2 "r")
2068 (set (match_operand:DI 0 "memory_operand" "")
2069 (match_operand:DI 1 "immediate_operand" ""))]
2070 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2071 && !x86_64_immediate_operand (operands[1], DImode)"
2072 [(set (match_dup 2) (match_dup 1))
2073 (set (match_dup 0) (match_dup 2))]
2076 ;; We need to define this as both peepholer and splitter for case
2077 ;; peephole2 pass is not run.
2078 ;; "&& 1" is needed to keep it from matching the previous pattern.
2080 [(set (match_operand:DI 0 "memory_operand" "")
2081 (match_operand:DI 1 "immediate_operand" ""))]
2082 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2083 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2084 [(set (match_dup 2) (match_dup 3))
2085 (set (match_dup 4) (match_dup 5))]
2086 "split_di (operands, 2, operands + 2, operands + 4);")
2089 [(set (match_operand:DI 0 "memory_operand" "")
2090 (match_operand:DI 1 "immediate_operand" ""))]
2091 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2092 ? flow2_completed : reload_completed)
2093 && !symbolic_operand (operands[1], DImode)
2094 && !x86_64_immediate_operand (operands[1], DImode)"
2095 [(set (match_dup 2) (match_dup 3))
2096 (set (match_dup 4) (match_dup 5))]
2097 "split_di (operands, 2, operands + 2, operands + 4);")
2099 (define_insn "*swapdi_rex64"
2100 [(set (match_operand:DI 0 "register_operand" "+r")
2101 (match_operand:DI 1 "register_operand" "+r"))
2106 [(set_attr "type" "imov")
2107 (set_attr "mode" "DI")
2108 (set_attr "pent_pair" "np")
2109 (set_attr "athlon_decode" "vector")])
2111 (define_expand "movti"
2112 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2113 (match_operand:TI 1 "nonimmediate_operand" ""))]
2114 "TARGET_SSE || TARGET_64BIT"
2117 ix86_expand_move (TImode, operands);
2119 ix86_expand_vector_move (TImode, operands);
2123 (define_insn "*movti_internal"
2124 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2125 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2126 "TARGET_SSE && !TARGET_64BIT
2127 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2129 switch (which_alternative)
2132 if (get_attr_mode (insn) == MODE_V4SF)
2133 return "xorps\t%0, %0";
2135 return "pxor\t%0, %0";
2138 if (get_attr_mode (insn) == MODE_V4SF)
2139 return "movaps\t{%1, %0|%0, %1}";
2141 return "movdqa\t{%1, %0|%0, %1}";
2146 [(set_attr "type" "ssemov,ssemov,ssemov")
2148 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2149 (const_string "V4SF")
2151 (eq_attr "alternative" "0,1")
2153 (ne (symbol_ref "optimize_size")
2155 (const_string "V4SF")
2156 (const_string "TI"))
2157 (eq_attr "alternative" "2")
2159 (ne (symbol_ref "optimize_size")
2161 (const_string "V4SF")
2162 (const_string "TI"))]
2163 (const_string "TI")))])
2165 (define_insn "*movti_rex64"
2166 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2167 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2169 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2171 switch (which_alternative)
2177 if (get_attr_mode (insn) == MODE_V4SF)
2178 return "xorps\t%0, %0";
2180 return "pxor\t%0, %0";
2183 if (get_attr_mode (insn) == MODE_V4SF)
2184 return "movaps\t{%1, %0|%0, %1}";
2186 return "movdqa\t{%1, %0|%0, %1}";
2191 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2193 (cond [(eq_attr "alternative" "2,3")
2195 (ne (symbol_ref "optimize_size")
2197 (const_string "V4SF")
2198 (const_string "TI"))
2199 (eq_attr "alternative" "4")
2201 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2203 (ne (symbol_ref "optimize_size")
2205 (const_string "V4SF")
2206 (const_string "TI"))]
2207 (const_string "DI")))])
2210 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2211 (match_operand:TI 1 "general_operand" ""))]
2212 "reload_completed && !SSE_REG_P (operands[0])
2213 && !SSE_REG_P (operands[1])"
2215 "ix86_split_long_move (operands); DONE;")
2217 (define_expand "movsf"
2218 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2219 (match_operand:SF 1 "general_operand" ""))]
2221 "ix86_expand_move (SFmode, operands); DONE;")
2223 (define_insn "*pushsf"
2224 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2225 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2228 /* Anything else should be already split before reg-stack. */
2229 gcc_assert (which_alternative == 1);
2230 return "push{l}\t%1";
2232 [(set_attr "type" "multi,push,multi")
2233 (set_attr "unit" "i387,*,*")
2234 (set_attr "mode" "SF,SI,SF")])
2236 (define_insn "*pushsf_rex64"
2237 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2238 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2241 /* Anything else should be already split before reg-stack. */
2242 gcc_assert (which_alternative == 1);
2243 return "push{q}\t%q1";
2245 [(set_attr "type" "multi,push,multi")
2246 (set_attr "unit" "i387,*,*")
2247 (set_attr "mode" "SF,DI,SF")])
2250 [(set (match_operand:SF 0 "push_operand" "")
2251 (match_operand:SF 1 "memory_operand" ""))]
2253 && GET_CODE (operands[1]) == MEM
2254 && constant_pool_reference_p (operands[1])"
2257 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2260 ;; %%% Kill this when call knows how to work this out.
2262 [(set (match_operand:SF 0 "push_operand" "")
2263 (match_operand:SF 1 "any_fp_register_operand" ""))]
2265 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2266 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2269 [(set (match_operand:SF 0 "push_operand" "")
2270 (match_operand:SF 1 "any_fp_register_operand" ""))]
2272 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2273 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2275 (define_insn "*movsf_1"
2276 [(set (match_operand:SF 0 "nonimmediate_operand"
2277 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2278 (match_operand:SF 1 "general_operand"
2279 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2280 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2281 && (reload_in_progress || reload_completed
2282 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2283 || GET_CODE (operands[1]) != CONST_DOUBLE
2284 || memory_operand (operands[0], SFmode))"
2286 switch (which_alternative)
2289 return output_387_reg_move (insn, operands);
2292 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2293 return "fstp%z0\t%y0";
2295 return "fst%z0\t%y0";
2298 return standard_80387_constant_opcode (operands[1]);
2302 return "mov{l}\t{%1, %0|%0, %1}";
2304 if (get_attr_mode (insn) == MODE_TI)
2305 return "pxor\t%0, %0";
2307 return "xorps\t%0, %0";
2309 if (get_attr_mode (insn) == MODE_V4SF)
2310 return "movaps\t{%1, %0|%0, %1}";
2312 return "movss\t{%1, %0|%0, %1}";
2315 return "movss\t{%1, %0|%0, %1}";
2319 return "movd\t{%1, %0|%0, %1}";
2322 return "movq\t{%1, %0|%0, %1}";
2328 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2330 (cond [(eq_attr "alternative" "3,4,9,10")
2332 (eq_attr "alternative" "5")
2334 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2336 (ne (symbol_ref "TARGET_SSE2")
2338 (eq (symbol_ref "optimize_size")
2341 (const_string "V4SF"))
2342 /* For architectures resolving dependencies on
2343 whole SSE registers use APS move to break dependency
2344 chains, otherwise use short move to avoid extra work.
2346 Do the same for architectures resolving dependencies on
2347 the parts. While in DF mode it is better to always handle
2348 just register parts, the SF mode is different due to lack
2349 of instructions to load just part of the register. It is
2350 better to maintain the whole registers in single format
2351 to avoid problems on using packed logical operations. */
2352 (eq_attr "alternative" "6")
2354 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2356 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2358 (const_string "V4SF")
2359 (const_string "SF"))
2360 (eq_attr "alternative" "11")
2361 (const_string "DI")]
2362 (const_string "SF")))])
2364 (define_insn "*swapsf"
2365 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2366 (match_operand:SF 1 "fp_register_operand" "+f"))
2369 "reload_completed || TARGET_80387"
2371 if (STACK_TOP_P (operands[0]))
2376 [(set_attr "type" "fxch")
2377 (set_attr "mode" "SF")])
2379 (define_expand "movdf"
2380 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2381 (match_operand:DF 1 "general_operand" ""))]
2383 "ix86_expand_move (DFmode, operands); DONE;")
2385 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2386 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2387 ;; On the average, pushdf using integers can be still shorter. Allow this
2388 ;; pattern for optimize_size too.
2390 (define_insn "*pushdf_nointeger"
2391 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2392 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2393 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2395 /* This insn should be already split before reg-stack. */
2398 [(set_attr "type" "multi")
2399 (set_attr "unit" "i387,*,*,*")
2400 (set_attr "mode" "DF,SI,SI,DF")])
2402 (define_insn "*pushdf_integer"
2403 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2404 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2405 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2407 /* This insn should be already split before reg-stack. */
2410 [(set_attr "type" "multi")
2411 (set_attr "unit" "i387,*,*")
2412 (set_attr "mode" "DF,SI,DF")])
2414 ;; %%% Kill this when call knows how to work this out.
2416 [(set (match_operand:DF 0 "push_operand" "")
2417 (match_operand:DF 1 "any_fp_register_operand" ""))]
2418 "!TARGET_64BIT && reload_completed"
2419 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2420 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2424 [(set (match_operand:DF 0 "push_operand" "")
2425 (match_operand:DF 1 "any_fp_register_operand" ""))]
2426 "TARGET_64BIT && reload_completed"
2427 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2428 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2432 [(set (match_operand:DF 0 "push_operand" "")
2433 (match_operand:DF 1 "general_operand" ""))]
2436 "ix86_split_long_move (operands); DONE;")
2438 ;; Moving is usually shorter when only FP registers are used. This separate
2439 ;; movdf pattern avoids the use of integer registers for FP operations
2440 ;; when optimizing for size.
2442 (define_insn "*movdf_nointeger"
2443 [(set (match_operand:DF 0 "nonimmediate_operand"
2444 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ")
2445 (match_operand:DF 1 "general_operand"
2446 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))]
2447 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2448 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2449 && (reload_in_progress || reload_completed
2450 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2451 || GET_CODE (operands[1]) != CONST_DOUBLE
2452 || memory_operand (operands[0], DFmode))"
2454 switch (which_alternative)
2457 return output_387_reg_move (insn, operands);
2460 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2461 return "fstp%z0\t%y0";
2463 return "fst%z0\t%y0";
2466 return standard_80387_constant_opcode (operands[1]);
2472 switch (get_attr_mode (insn))
2475 return "xorps\t%0, %0";
2477 return "xorpd\t%0, %0";
2479 return "pxor\t%0, %0";
2486 switch (get_attr_mode (insn))
2489 return "movaps\t{%1, %0|%0, %1}";
2491 return "movapd\t{%1, %0|%0, %1}";
2493 return "movdqa\t{%1, %0|%0, %1}";
2495 return "movq\t{%1, %0|%0, %1}";
2497 return "movsd\t{%1, %0|%0, %1}";
2499 return "movlpd\t{%1, %0|%0, %1}";
2501 return "movlps\t{%1, %0|%0, %1}";
2510 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2512 (cond [(eq_attr "alternative" "0,1,2")
2514 (eq_attr "alternative" "3,4")
2517 /* For SSE1, we have many fewer alternatives. */
2518 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2519 (cond [(eq_attr "alternative" "5,6")
2520 (const_string "V4SF")
2522 (const_string "V2SF"))
2524 /* xorps is one byte shorter. */
2525 (eq_attr "alternative" "5")
2526 (cond [(ne (symbol_ref "optimize_size")
2528 (const_string "V4SF")
2529 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2533 (const_string "V2DF"))
2535 /* For architectures resolving dependencies on
2536 whole SSE registers use APD move to break dependency
2537 chains, otherwise use short move to avoid extra work.
2539 movaps encodes one byte shorter. */
2540 (eq_attr "alternative" "6")
2542 [(ne (symbol_ref "optimize_size")
2544 (const_string "V4SF")
2545 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2547 (const_string "V2DF")
2549 (const_string "DF"))
2550 /* For architectures resolving dependencies on register
2551 parts we may avoid extra work to zero out upper part
2553 (eq_attr "alternative" "7")
2555 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2557 (const_string "V1DF")
2558 (const_string "DF"))
2560 (const_string "DF")))])
2562 (define_insn "*movdf_integer"
2563 [(set (match_operand:DF 0 "nonimmediate_operand"
2564 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2565 (match_operand:DF 1 "general_operand"
2566 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))]
2567 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2568 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2569 && (reload_in_progress || reload_completed
2570 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2571 || GET_CODE (operands[1]) != CONST_DOUBLE
2572 || memory_operand (operands[0], DFmode))"
2574 switch (which_alternative)
2577 return output_387_reg_move (insn, operands);
2580 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2581 return "fstp%z0\t%y0";
2583 return "fst%z0\t%y0";
2586 return standard_80387_constant_opcode (operands[1]);
2593 switch (get_attr_mode (insn))
2596 return "xorps\t%0, %0";
2598 return "xorpd\t%0, %0";
2600 return "pxor\t%0, %0";
2607 switch (get_attr_mode (insn))
2610 return "movaps\t{%1, %0|%0, %1}";
2612 return "movapd\t{%1, %0|%0, %1}";
2614 return "movdqa\t{%1, %0|%0, %1}";
2616 return "movq\t{%1, %0|%0, %1}";
2618 return "movsd\t{%1, %0|%0, %1}";
2620 return "movlpd\t{%1, %0|%0, %1}";
2622 return "movlps\t{%1, %0|%0, %1}";
2631 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2633 (cond [(eq_attr "alternative" "0,1,2")
2635 (eq_attr "alternative" "3,4")
2638 /* For SSE1, we have many fewer alternatives. */
2639 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2640 (cond [(eq_attr "alternative" "5,6")
2641 (const_string "V4SF")
2643 (const_string "V2SF"))
2645 /* xorps is one byte shorter. */
2646 (eq_attr "alternative" "5")
2647 (cond [(ne (symbol_ref "optimize_size")
2649 (const_string "V4SF")
2650 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2654 (const_string "V2DF"))
2656 /* For architectures resolving dependencies on
2657 whole SSE registers use APD move to break dependency
2658 chains, otherwise use short move to avoid extra work.
2660 movaps encodes one byte shorter. */
2661 (eq_attr "alternative" "6")
2663 [(ne (symbol_ref "optimize_size")
2665 (const_string "V4SF")
2666 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2668 (const_string "V2DF")
2670 (const_string "DF"))
2671 /* For architectures resolving dependencies on register
2672 parts we may avoid extra work to zero out upper part
2674 (eq_attr "alternative" "7")
2676 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2678 (const_string "V1DF")
2679 (const_string "DF"))
2681 (const_string "DF")))])
2684 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2685 (match_operand:DF 1 "general_operand" ""))]
2687 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2688 && ! (ANY_FP_REG_P (operands[0]) ||
2689 (GET_CODE (operands[0]) == SUBREG
2690 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2691 && ! (ANY_FP_REG_P (operands[1]) ||
2692 (GET_CODE (operands[1]) == SUBREG
2693 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2695 "ix86_split_long_move (operands); DONE;")
2697 (define_insn "*swapdf"
2698 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2699 (match_operand:DF 1 "fp_register_operand" "+f"))
2702 "reload_completed || TARGET_80387"
2704 if (STACK_TOP_P (operands[0]))
2709 [(set_attr "type" "fxch")
2710 (set_attr "mode" "DF")])
2712 (define_expand "movxf"
2713 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2714 (match_operand:XF 1 "general_operand" ""))]
2716 "ix86_expand_move (XFmode, operands); DONE;")
2718 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2719 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2720 ;; Pushing using integer instructions is longer except for constants
2721 ;; and direct memory references.
2722 ;; (assuming that any given constant is pushed only once, but this ought to be
2723 ;; handled elsewhere).
2725 (define_insn "*pushxf_nointeger"
2726 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2727 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2730 /* This insn should be already split before reg-stack. */
2733 [(set_attr "type" "multi")
2734 (set_attr "unit" "i387,*,*")
2735 (set_attr "mode" "XF,SI,SI")])
2737 (define_insn "*pushxf_integer"
2738 [(set (match_operand:XF 0 "push_operand" "=<,<")
2739 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2742 /* This insn should be already split before reg-stack. */
2745 [(set_attr "type" "multi")
2746 (set_attr "unit" "i387,*")
2747 (set_attr "mode" "XF,SI")])
2750 [(set (match_operand 0 "push_operand" "")
2751 (match_operand 1 "general_operand" ""))]
2753 && (GET_MODE (operands[0]) == XFmode
2754 || GET_MODE (operands[0]) == DFmode)
2755 && !ANY_FP_REG_P (operands[1])"
2757 "ix86_split_long_move (operands); DONE;")
2760 [(set (match_operand:XF 0 "push_operand" "")
2761 (match_operand:XF 1 "any_fp_register_operand" ""))]
2763 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2764 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2765 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2768 [(set (match_operand:XF 0 "push_operand" "")
2769 (match_operand:XF 1 "any_fp_register_operand" ""))]
2771 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2772 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2773 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2775 ;; Do not use integer registers when optimizing for size
2776 (define_insn "*movxf_nointeger"
2777 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2778 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2780 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2781 && (reload_in_progress || reload_completed
2782 || GET_CODE (operands[1]) != CONST_DOUBLE
2783 || memory_operand (operands[0], XFmode))"
2785 switch (which_alternative)
2788 return output_387_reg_move (insn, operands);
2791 /* There is no non-popping store to memory for XFmode. So if
2792 we need one, follow the store with a load. */
2793 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2794 return "fstp%z0\t%y0\;fld%z0\t%y0";
2796 return "fstp%z0\t%y0";
2799 return standard_80387_constant_opcode (operands[1]);
2807 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2808 (set_attr "mode" "XF,XF,XF,SI,SI")])
2810 (define_insn "*movxf_integer"
2811 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2812 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2814 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2815 && (reload_in_progress || reload_completed
2816 || GET_CODE (operands[1]) != CONST_DOUBLE
2817 || memory_operand (operands[0], XFmode))"
2819 switch (which_alternative)
2822 return output_387_reg_move (insn, operands);
2825 /* There is no non-popping store to memory for XFmode. So if
2826 we need one, follow the store with a load. */
2827 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2828 return "fstp%z0\t%y0\;fld%z0\t%y0";
2830 return "fstp%z0\t%y0";
2833 return standard_80387_constant_opcode (operands[1]);
2842 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2843 (set_attr "mode" "XF,XF,XF,SI,SI")])
2846 [(set (match_operand 0 "nonimmediate_operand" "")
2847 (match_operand 1 "general_operand" ""))]
2849 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2850 && GET_MODE (operands[0]) == XFmode
2851 && ! (ANY_FP_REG_P (operands[0]) ||
2852 (GET_CODE (operands[0]) == SUBREG
2853 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2854 && ! (ANY_FP_REG_P (operands[1]) ||
2855 (GET_CODE (operands[1]) == SUBREG
2856 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2858 "ix86_split_long_move (operands); DONE;")
2861 [(set (match_operand 0 "register_operand" "")
2862 (match_operand 1 "memory_operand" ""))]
2864 && GET_CODE (operands[1]) == MEM
2865 && (GET_MODE (operands[0]) == XFmode
2866 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2867 && constant_pool_reference_p (operands[1])"
2868 [(set (match_dup 0) (match_dup 1))]
2870 rtx c = avoid_constant_pool_reference (operands[1]);
2871 rtx r = operands[0];
2873 if (GET_CODE (r) == SUBREG)
2878 if (!standard_sse_constant_p (c))
2881 else if (FP_REG_P (r))
2883 if (!standard_80387_constant_p (c))
2886 else if (MMX_REG_P (r))
2892 (define_insn "swapxf"
2893 [(set (match_operand:XF 0 "register_operand" "+f")
2894 (match_operand:XF 1 "register_operand" "+f"))
2899 if (STACK_TOP_P (operands[0]))
2904 [(set_attr "type" "fxch")
2905 (set_attr "mode" "XF")])
2907 (define_expand "movtf"
2908 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2909 (match_operand:TF 1 "nonimmediate_operand" ""))]
2912 ix86_expand_move (TFmode, operands);
2916 (define_insn "*movtf_internal"
2917 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2918 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2920 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2922 switch (which_alternative)
2928 if (get_attr_mode (insn) == MODE_V4SF)
2929 return "xorps\t%0, %0";
2931 return "pxor\t%0, %0";
2934 if (get_attr_mode (insn) == MODE_V4SF)
2935 return "movaps\t{%1, %0|%0, %1}";
2937 return "movdqa\t{%1, %0|%0, %1}";
2942 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2944 (cond [(eq_attr "alternative" "2,3")
2946 (ne (symbol_ref "optimize_size")
2948 (const_string "V4SF")
2949 (const_string "TI"))
2950 (eq_attr "alternative" "4")
2952 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2954 (ne (symbol_ref "optimize_size")
2956 (const_string "V4SF")
2957 (const_string "TI"))]
2958 (const_string "DI")))])
2961 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2962 (match_operand:TF 1 "general_operand" ""))]
2963 "reload_completed && !SSE_REG_P (operands[0])
2964 && !SSE_REG_P (operands[1])"
2966 "ix86_split_long_move (operands); DONE;")
2968 ;; Zero extension instructions
2970 (define_expand "zero_extendhisi2"
2971 [(set (match_operand:SI 0 "register_operand" "")
2972 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2975 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2977 operands[1] = force_reg (HImode, operands[1]);
2978 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2983 (define_insn "zero_extendhisi2_and"
2984 [(set (match_operand:SI 0 "register_operand" "=r")
2985 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2986 (clobber (reg:CC FLAGS_REG))]
2987 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2989 [(set_attr "type" "alu1")
2990 (set_attr "mode" "SI")])
2993 [(set (match_operand:SI 0 "register_operand" "")
2994 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2995 (clobber (reg:CC FLAGS_REG))]
2996 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2998 (clobber (reg:CC FLAGS_REG))])]
3001 (define_insn "*zero_extendhisi2_movzwl"
3002 [(set (match_operand:SI 0 "register_operand" "=r")
3003 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3004 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3005 "movz{wl|x}\t{%1, %0|%0, %1}"
3006 [(set_attr "type" "imovx")
3007 (set_attr "mode" "SI")])
3009 (define_expand "zero_extendqihi2"
3011 [(set (match_operand:HI 0 "register_operand" "")
3012 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3013 (clobber (reg:CC FLAGS_REG))])]
3017 (define_insn "*zero_extendqihi2_and"
3018 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3019 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3020 (clobber (reg:CC FLAGS_REG))]
3021 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3023 [(set_attr "type" "alu1")
3024 (set_attr "mode" "HI")])
3026 (define_insn "*zero_extendqihi2_movzbw_and"
3027 [(set (match_operand:HI 0 "register_operand" "=r,r")
3028 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3029 (clobber (reg:CC FLAGS_REG))]
3030 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3032 [(set_attr "type" "imovx,alu1")
3033 (set_attr "mode" "HI")])
3035 (define_insn "*zero_extendqihi2_movzbw"
3036 [(set (match_operand:HI 0 "register_operand" "=r")
3037 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3038 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3039 "movz{bw|x}\t{%1, %0|%0, %1}"
3040 [(set_attr "type" "imovx")
3041 (set_attr "mode" "HI")])
3043 ;; For the movzbw case strip only the clobber
3045 [(set (match_operand:HI 0 "register_operand" "")
3046 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3047 (clobber (reg:CC FLAGS_REG))]
3049 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3050 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3051 [(set (match_operand:HI 0 "register_operand" "")
3052 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3054 ;; When source and destination does not overlap, clear destination
3055 ;; first and then do the movb
3057 [(set (match_operand:HI 0 "register_operand" "")
3058 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3059 (clobber (reg:CC FLAGS_REG))]
3061 && ANY_QI_REG_P (operands[0])
3062 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3063 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3064 [(set (match_dup 0) (const_int 0))
3065 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3066 "operands[2] = gen_lowpart (QImode, operands[0]);")
3068 ;; Rest is handled by single and.
3070 [(set (match_operand:HI 0 "register_operand" "")
3071 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3072 (clobber (reg:CC FLAGS_REG))]
3074 && true_regnum (operands[0]) == true_regnum (operands[1])"
3075 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3076 (clobber (reg:CC FLAGS_REG))])]
3079 (define_expand "zero_extendqisi2"
3081 [(set (match_operand:SI 0 "register_operand" "")
3082 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3083 (clobber (reg:CC FLAGS_REG))])]
3087 (define_insn "*zero_extendqisi2_and"
3088 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3089 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3090 (clobber (reg:CC FLAGS_REG))]
3091 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3093 [(set_attr "type" "alu1")
3094 (set_attr "mode" "SI")])
3096 (define_insn "*zero_extendqisi2_movzbw_and"
3097 [(set (match_operand:SI 0 "register_operand" "=r,r")
3098 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3099 (clobber (reg:CC FLAGS_REG))]
3100 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3102 [(set_attr "type" "imovx,alu1")
3103 (set_attr "mode" "SI")])
3105 (define_insn "*zero_extendqisi2_movzbw"
3106 [(set (match_operand:SI 0 "register_operand" "=r")
3107 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3108 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3109 "movz{bl|x}\t{%1, %0|%0, %1}"
3110 [(set_attr "type" "imovx")
3111 (set_attr "mode" "SI")])
3113 ;; For the movzbl case strip only the clobber
3115 [(set (match_operand:SI 0 "register_operand" "")
3116 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3117 (clobber (reg:CC FLAGS_REG))]
3119 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3120 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3122 (zero_extend:SI (match_dup 1)))])
3124 ;; When source and destination does not overlap, clear destination
3125 ;; first and then do the movb
3127 [(set (match_operand:SI 0 "register_operand" "")
3128 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3129 (clobber (reg:CC FLAGS_REG))]
3131 && ANY_QI_REG_P (operands[0])
3132 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3133 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3134 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3135 [(set (match_dup 0) (const_int 0))
3136 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3137 "operands[2] = gen_lowpart (QImode, operands[0]);")
3139 ;; Rest is handled by single and.
3141 [(set (match_operand:SI 0 "register_operand" "")
3142 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3143 (clobber (reg:CC FLAGS_REG))]
3145 && true_regnum (operands[0]) == true_regnum (operands[1])"
3146 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3147 (clobber (reg:CC FLAGS_REG))])]
3150 ;; %%% Kill me once multi-word ops are sane.
3151 (define_expand "zero_extendsidi2"
3152 [(set (match_operand:DI 0 "register_operand" "=r")
3153 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3157 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3162 (define_insn "zero_extendsidi2_32"
3163 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3164 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3165 (clobber (reg:CC FLAGS_REG))]
3171 movd\t{%1, %0|%0, %1}
3172 movd\t{%1, %0|%0, %1}"
3173 [(set_attr "mode" "SI,SI,SI,DI,TI")
3174 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3176 (define_insn "zero_extendsidi2_rex64"
3177 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3178 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3181 mov\t{%k1, %k0|%k0, %k1}
3183 movd\t{%1, %0|%0, %1}
3184 movd\t{%1, %0|%0, %1}"
3185 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3186 (set_attr "mode" "SI,DI,SI,SI")])
3189 [(set (match_operand:DI 0 "memory_operand" "")
3190 (zero_extend:DI (match_dup 0)))]
3192 [(set (match_dup 4) (const_int 0))]
3193 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3196 [(set (match_operand:DI 0 "register_operand" "")
3197 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3198 (clobber (reg:CC FLAGS_REG))]
3199 "!TARGET_64BIT && reload_completed
3200 && true_regnum (operands[0]) == true_regnum (operands[1])"
3201 [(set (match_dup 4) (const_int 0))]
3202 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3206 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3207 (clobber (reg:CC FLAGS_REG))]
3208 "!TARGET_64BIT && reload_completed
3209 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3210 [(set (match_dup 3) (match_dup 1))
3211 (set (match_dup 4) (const_int 0))]
3212 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3214 (define_insn "zero_extendhidi2"
3215 [(set (match_operand:DI 0 "register_operand" "=r")
3216 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3218 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3219 [(set_attr "type" "imovx")
3220 (set_attr "mode" "DI")])
3222 (define_insn "zero_extendqidi2"
3223 [(set (match_operand:DI 0 "register_operand" "=r")
3224 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3226 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3227 [(set_attr "type" "imovx")
3228 (set_attr "mode" "DI")])
3230 ;; Sign extension instructions
3232 (define_expand "extendsidi2"
3233 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3234 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3235 (clobber (reg:CC FLAGS_REG))
3236 (clobber (match_scratch:SI 2 ""))])]
3241 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3246 (define_insn "*extendsidi2_1"
3247 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3248 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3249 (clobber (reg:CC FLAGS_REG))
3250 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3254 (define_insn "extendsidi2_rex64"
3255 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3256 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3260 movs{lq|x}\t{%1,%0|%0, %1}"
3261 [(set_attr "type" "imovx")
3262 (set_attr "mode" "DI")
3263 (set_attr "prefix_0f" "0")
3264 (set_attr "modrm" "0,1")])
3266 (define_insn "extendhidi2"
3267 [(set (match_operand:DI 0 "register_operand" "=r")
3268 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3270 "movs{wq|x}\t{%1,%0|%0, %1}"
3271 [(set_attr "type" "imovx")
3272 (set_attr "mode" "DI")])
3274 (define_insn "extendqidi2"
3275 [(set (match_operand:DI 0 "register_operand" "=r")
3276 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278 "movs{bq|x}\t{%1,%0|%0, %1}"
3279 [(set_attr "type" "imovx")
3280 (set_attr "mode" "DI")])
3282 ;; Extend to memory case when source register does die.
3284 [(set (match_operand:DI 0 "memory_operand" "")
3285 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3286 (clobber (reg:CC FLAGS_REG))
3287 (clobber (match_operand:SI 2 "register_operand" ""))]
3289 && dead_or_set_p (insn, operands[1])
3290 && !reg_mentioned_p (operands[1], operands[0]))"
3291 [(set (match_dup 3) (match_dup 1))
3292 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3293 (clobber (reg:CC FLAGS_REG))])
3294 (set (match_dup 4) (match_dup 1))]
3295 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3297 ;; Extend to memory case when source register does not die.
3299 [(set (match_operand:DI 0 "memory_operand" "")
3300 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3301 (clobber (reg:CC FLAGS_REG))
3302 (clobber (match_operand:SI 2 "register_operand" ""))]
3306 split_di (&operands[0], 1, &operands[3], &operands[4]);
3308 emit_move_insn (operands[3], operands[1]);
3310 /* Generate a cltd if possible and doing so it profitable. */
3311 if (true_regnum (operands[1]) == 0
3312 && true_regnum (operands[2]) == 1
3313 && (optimize_size || TARGET_USE_CLTD))
3315 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3319 emit_move_insn (operands[2], operands[1]);
3320 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3322 emit_move_insn (operands[4], operands[2]);
3326 ;; Extend to register case. Optimize case where source and destination
3327 ;; registers match and cases where we can use cltd.
3329 [(set (match_operand:DI 0 "register_operand" "")
3330 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3331 (clobber (reg:CC FLAGS_REG))
3332 (clobber (match_scratch:SI 2 ""))]
3336 split_di (&operands[0], 1, &operands[3], &operands[4]);
3338 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3339 emit_move_insn (operands[3], operands[1]);
3341 /* Generate a cltd if possible and doing so it profitable. */
3342 if (true_regnum (operands[3]) == 0
3343 && (optimize_size || TARGET_USE_CLTD))
3345 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3349 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3350 emit_move_insn (operands[4], operands[1]);
3352 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3356 (define_insn "extendhisi2"
3357 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3358 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3361 switch (get_attr_prefix_0f (insn))
3364 return "{cwtl|cwde}";
3366 return "movs{wl|x}\t{%1,%0|%0, %1}";
3369 [(set_attr "type" "imovx")
3370 (set_attr "mode" "SI")
3371 (set (attr "prefix_0f")
3372 ;; movsx is short decodable while cwtl is vector decoded.
3373 (if_then_else (and (eq_attr "cpu" "!k6")
3374 (eq_attr "alternative" "0"))
3376 (const_string "1")))
3378 (if_then_else (eq_attr "prefix_0f" "0")
3380 (const_string "1")))])
3382 (define_insn "*extendhisi2_zext"
3383 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3385 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3388 switch (get_attr_prefix_0f (insn))
3391 return "{cwtl|cwde}";
3393 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3396 [(set_attr "type" "imovx")
3397 (set_attr "mode" "SI")
3398 (set (attr "prefix_0f")
3399 ;; movsx is short decodable while cwtl is vector decoded.
3400 (if_then_else (and (eq_attr "cpu" "!k6")
3401 (eq_attr "alternative" "0"))
3403 (const_string "1")))
3405 (if_then_else (eq_attr "prefix_0f" "0")
3407 (const_string "1")))])
3409 (define_insn "extendqihi2"
3410 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3411 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3414 switch (get_attr_prefix_0f (insn))
3417 return "{cbtw|cbw}";
3419 return "movs{bw|x}\t{%1,%0|%0, %1}";
3422 [(set_attr "type" "imovx")
3423 (set_attr "mode" "HI")
3424 (set (attr "prefix_0f")
3425 ;; movsx is short decodable while cwtl is vector decoded.
3426 (if_then_else (and (eq_attr "cpu" "!k6")
3427 (eq_attr "alternative" "0"))
3429 (const_string "1")))
3431 (if_then_else (eq_attr "prefix_0f" "0")
3433 (const_string "1")))])
3435 (define_insn "extendqisi2"
3436 [(set (match_operand:SI 0 "register_operand" "=r")
3437 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3439 "movs{bl|x}\t{%1,%0|%0, %1}"
3440 [(set_attr "type" "imovx")
3441 (set_attr "mode" "SI")])
3443 (define_insn "*extendqisi2_zext"
3444 [(set (match_operand:DI 0 "register_operand" "=r")
3446 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3448 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3449 [(set_attr "type" "imovx")
3450 (set_attr "mode" "SI")])
3452 ;; Conversions between float and double.
3454 ;; These are all no-ops in the model used for the 80387. So just
3457 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3458 (define_insn "*dummy_extendsfdf2"
3459 [(set (match_operand:DF 0 "push_operand" "=<")
3460 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3465 [(set (match_operand:DF 0 "push_operand" "")
3466 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3468 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3469 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3472 [(set (match_operand:DF 0 "push_operand" "")
3473 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3475 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3476 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3478 (define_insn "*dummy_extendsfxf2"
3479 [(set (match_operand:XF 0 "push_operand" "=<")
3480 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3485 [(set (match_operand:XF 0 "push_operand" "")
3486 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3488 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3489 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3490 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3493 [(set (match_operand:XF 0 "push_operand" "")
3494 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3496 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3497 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3498 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3501 [(set (match_operand:XF 0 "push_operand" "")
3502 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3504 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3505 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3506 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3509 [(set (match_operand:XF 0 "push_operand" "")
3510 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3512 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3513 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3514 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3516 (define_expand "extendsfdf2"
3517 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3518 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3519 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3521 /* ??? Needed for compress_float_constant since all fp constants
3522 are LEGITIMATE_CONSTANT_P. */
3523 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3524 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3525 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3526 operands[1] = force_reg (SFmode, operands[1]);
3529 (define_insn "*extendsfdf2_mixed"
3530 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3531 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3532 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3533 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3535 switch (which_alternative)
3538 return output_387_reg_move (insn, operands);
3541 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3542 return "fstp%z0\t%y0";
3544 return "fst%z0\t%y0";
3547 return "cvtss2sd\t{%1, %0|%0, %1}";
3553 [(set_attr "type" "fmov,fmov,ssecvt")
3554 (set_attr "mode" "SF,XF,DF")])
3556 (define_insn "*extendsfdf2_sse"
3557 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3558 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3559 "TARGET_SSE2 && TARGET_SSE_MATH
3560 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3561 "cvtss2sd\t{%1, %0|%0, %1}"
3562 [(set_attr "type" "ssecvt")
3563 (set_attr "mode" "DF")])
3565 (define_insn "*extendsfdf2_i387"
3566 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3567 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3569 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3571 switch (which_alternative)
3574 return output_387_reg_move (insn, operands);
3577 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3578 return "fstp%z0\t%y0";
3580 return "fst%z0\t%y0";
3586 [(set_attr "type" "fmov")
3587 (set_attr "mode" "SF,XF")])
3589 (define_expand "extendsfxf2"
3590 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3591 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3594 /* ??? Needed for compress_float_constant since all fp constants
3595 are LEGITIMATE_CONSTANT_P. */
3596 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3597 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3598 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3599 operands[1] = force_reg (SFmode, operands[1]);
3602 (define_insn "*extendsfxf2_i387"
3603 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3604 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3606 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3608 switch (which_alternative)
3611 return output_387_reg_move (insn, operands);
3614 /* There is no non-popping store to memory for XFmode. So if
3615 we need one, follow the store with a load. */
3616 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3617 return "fstp%z0\t%y0";
3619 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3625 [(set_attr "type" "fmov")
3626 (set_attr "mode" "SF,XF")])
3628 (define_expand "extenddfxf2"
3629 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3630 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3633 /* ??? Needed for compress_float_constant since all fp constants
3634 are LEGITIMATE_CONSTANT_P. */
3635 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3636 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3637 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3638 operands[1] = force_reg (DFmode, operands[1]);
3641 (define_insn "*extenddfxf2_i387"
3642 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3643 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3645 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3647 switch (which_alternative)
3650 return output_387_reg_move (insn, operands);
3653 /* There is no non-popping store to memory for XFmode. So if
3654 we need one, follow the store with a load. */
3655 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3656 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3658 return "fstp%z0\t%y0";
3664 [(set_attr "type" "fmov")
3665 (set_attr "mode" "DF,XF")])
3667 ;; %%% This seems bad bad news.
3668 ;; This cannot output into an f-reg because there is no way to be sure
3669 ;; of truncating in that case. Otherwise this is just like a simple move
3670 ;; insn. So we pretend we can output to a reg in order to get better
3671 ;; register preferencing, but we really use a stack slot.
3673 ;; Conversion from DFmode to SFmode.
3675 (define_expand "truncdfsf2"
3676 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3678 (match_operand:DF 1 "nonimmediate_operand" "")))]
3679 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3681 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3682 operands[1] = force_reg (DFmode, operands[1]);
3684 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3686 else if (flag_unsafe_math_optimizations)
3690 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3691 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3696 (define_expand "truncdfsf2_with_temp"
3697 [(parallel [(set (match_operand:SF 0 "" "")
3698 (float_truncate:SF (match_operand:DF 1 "" "")))
3699 (clobber (match_operand:SF 2 "" ""))])]
3702 (define_insn "*truncdfsf_fast_mixed"
3703 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3705 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3706 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3708 switch (which_alternative)
3711 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712 return "fstp%z0\t%y0";
3714 return "fst%z0\t%y0";
3716 return output_387_reg_move (insn, operands);
3718 return "cvtsd2ss\t{%1, %0|%0, %1}";
3723 [(set_attr "type" "fmov,fmov,ssecvt")
3724 (set_attr "mode" "SF")])
3726 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3727 ;; because nothing we do here is unsafe.
3728 (define_insn "*truncdfsf_fast_sse"
3729 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3731 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3732 "TARGET_SSE2 && TARGET_SSE_MATH"
3733 "cvtsd2ss\t{%1, %0|%0, %1}"
3734 [(set_attr "type" "ssecvt")
3735 (set_attr "mode" "SF")])
3737 (define_insn "*truncdfsf_fast_i387"
3738 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3740 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3741 "TARGET_80387 && flag_unsafe_math_optimizations"
3742 "* return output_387_reg_move (insn, operands);"
3743 [(set_attr "type" "fmov")
3744 (set_attr "mode" "SF")])
3746 (define_insn "*truncdfsf_mixed"
3747 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3749 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3750 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3751 "TARGET_MIX_SSE_I387"
3753 switch (which_alternative)
3756 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3757 return "fstp%z0\t%y0";
3759 return "fst%z0\t%y0";
3763 return "cvtsd2ss\t{%1, %0|%0, %1}";
3768 [(set_attr "type" "fmov,multi,ssecvt")
3769 (set_attr "unit" "*,i387,*")
3770 (set_attr "mode" "SF")])
3772 (define_insn "*truncdfsf_i387"
3773 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3775 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3776 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3779 switch (which_alternative)
3782 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3783 return "fstp%z0\t%y0";
3785 return "fst%z0\t%y0";
3792 [(set_attr "type" "fmov,multi")
3793 (set_attr "unit" "*,i387")
3794 (set_attr "mode" "SF")])
3796 (define_insn "*truncdfsf2_i387_1"
3797 [(set (match_operand:SF 0 "memory_operand" "=m")
3799 (match_operand:DF 1 "register_operand" "f")))]
3801 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3802 && !TARGET_MIX_SSE_I387"
3804 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3805 return "fstp%z0\t%y0";
3807 return "fst%z0\t%y0";
3809 [(set_attr "type" "fmov")
3810 (set_attr "mode" "SF")])
3813 [(set (match_operand:SF 0 "register_operand" "")
3815 (match_operand:DF 1 "fp_register_operand" "")))
3816 (clobber (match_operand 2 "" ""))]
3818 [(set (match_dup 2) (match_dup 1))
3819 (set (match_dup 0) (match_dup 2))]
3821 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3824 ;; Conversion from XFmode to SFmode.
3826 (define_expand "truncxfsf2"
3827 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3829 (match_operand:XF 1 "register_operand" "")))
3830 (clobber (match_dup 2))])]
3833 if (flag_unsafe_math_optimizations)
3835 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3836 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3837 if (reg != operands[0])
3838 emit_move_insn (operands[0], reg);
3842 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3845 (define_insn "*truncxfsf2_mixed"
3846 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3848 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3849 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3850 "TARGET_MIX_SSE_I387"
3852 gcc_assert (!which_alternative);
3853 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3854 return "fstp%z0\t%y0";
3856 return "fst%z0\t%y0";
3858 [(set_attr "type" "fmov,multi,multi,multi")
3859 (set_attr "unit" "*,i387,i387,i387")
3860 (set_attr "mode" "SF")])
3862 (define_insn "truncxfsf2_i387_noop"
3863 [(set (match_operand:SF 0 "register_operand" "=f")
3864 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3865 "TARGET_80387 && flag_unsafe_math_optimizations"
3867 return output_387_reg_move (insn, operands);
3869 [(set_attr "type" "fmov")
3870 (set_attr "mode" "SF")])
3872 (define_insn "*truncxfsf2_i387"
3873 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3875 (match_operand:XF 1 "register_operand" "f,f,f")))
3876 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3879 gcc_assert (!which_alternative);
3880 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3881 return "fstp%z0\t%y0";
3883 return "fst%z0\t%y0";
3885 [(set_attr "type" "fmov,multi,multi")
3886 (set_attr "unit" "*,i387,i387")
3887 (set_attr "mode" "SF")])
3889 (define_insn "*truncxfsf2_i387_1"
3890 [(set (match_operand:SF 0 "memory_operand" "=m")
3892 (match_operand:XF 1 "register_operand" "f")))]
3895 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3896 return "fstp%z0\t%y0";
3898 return "fst%z0\t%y0";
3900 [(set_attr "type" "fmov")
3901 (set_attr "mode" "SF")])
3904 [(set (match_operand:SF 0 "register_operand" "")
3906 (match_operand:XF 1 "register_operand" "")))
3907 (clobber (match_operand:SF 2 "memory_operand" ""))]
3908 "TARGET_80387 && reload_completed"
3909 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3910 (set (match_dup 0) (match_dup 2))]
3914 [(set (match_operand:SF 0 "memory_operand" "")
3916 (match_operand:XF 1 "register_operand" "")))
3917 (clobber (match_operand:SF 2 "memory_operand" ""))]
3919 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3922 ;; Conversion from XFmode to DFmode.
3924 (define_expand "truncxfdf2"
3925 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3927 (match_operand:XF 1 "register_operand" "")))
3928 (clobber (match_dup 2))])]
3931 if (flag_unsafe_math_optimizations)
3933 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3934 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3935 if (reg != operands[0])
3936 emit_move_insn (operands[0], reg);
3940 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3943 (define_insn "*truncxfdf2_mixed"
3944 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3946 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3947 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3948 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3950 gcc_assert (!which_alternative);
3951 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3952 return "fstp%z0\t%y0";
3954 return "fst%z0\t%y0";
3956 [(set_attr "type" "fmov,multi,multi,multi")
3957 (set_attr "unit" "*,i387,i387,i387")
3958 (set_attr "mode" "DF")])
3960 (define_insn "truncxfdf2_i387_noop"
3961 [(set (match_operand:DF 0 "register_operand" "=f")
3962 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3963 "TARGET_80387 && flag_unsafe_math_optimizations"
3965 return output_387_reg_move (insn, operands);
3967 [(set_attr "type" "fmov")
3968 (set_attr "mode" "DF")])
3970 (define_insn "*truncxfdf2_i387"
3971 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3973 (match_operand:XF 1 "register_operand" "f,f,f")))
3974 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3977 gcc_assert (!which_alternative);
3978 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3979 return "fstp%z0\t%y0";
3981 return "fst%z0\t%y0";
3983 [(set_attr "type" "fmov,multi,multi")
3984 (set_attr "unit" "*,i387,i387")
3985 (set_attr "mode" "DF")])
3987 (define_insn "*truncxfdf2_i387_1"
3988 [(set (match_operand:DF 0 "memory_operand" "=m")
3990 (match_operand:XF 1 "register_operand" "f")))]
3993 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3994 return "fstp%z0\t%y0";
3996 return "fst%z0\t%y0";
3998 [(set_attr "type" "fmov")
3999 (set_attr "mode" "DF")])
4002 [(set (match_operand:DF 0 "register_operand" "")
4004 (match_operand:XF 1 "register_operand" "")))
4005 (clobber (match_operand:DF 2 "memory_operand" ""))]
4006 "TARGET_80387 && reload_completed"
4007 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4008 (set (match_dup 0) (match_dup 2))]
4012 [(set (match_operand:DF 0 "memory_operand" "")
4014 (match_operand:XF 1 "register_operand" "")))
4015 (clobber (match_operand:DF 2 "memory_operand" ""))]
4017 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4020 ;; Signed conversion to DImode.
4022 (define_expand "fix_truncxfdi2"
4023 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4024 (fix:DI (match_operand:XF 1 "register_operand" "")))
4025 (clobber (reg:CC FLAGS_REG))])]
4030 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4035 (define_expand "fix_trunc<mode>di2"
4036 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4037 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4038 (clobber (reg:CC FLAGS_REG))])]
4039 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4042 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4044 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4047 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4049 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4050 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4051 if (out != operands[0])
4052 emit_move_insn (operands[0], out);
4057 ;; Signed conversion to SImode.
4059 (define_expand "fix_truncxfsi2"
4060 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4061 (fix:SI (match_operand:XF 1 "register_operand" "")))
4062 (clobber (reg:CC FLAGS_REG))])]
4067 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4072 (define_expand "fix_trunc<mode>si2"
4073 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4074 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4075 (clobber (reg:CC FLAGS_REG))])]
4076 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4079 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4081 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4084 if (SSE_FLOAT_MODE_P (<MODE>mode))
4086 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4087 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4088 if (out != operands[0])
4089 emit_move_insn (operands[0], out);
4094 ;; Signed conversion to HImode.
4096 (define_expand "fix_trunc<mode>hi2"
4097 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4098 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4099 (clobber (reg:CC FLAGS_REG))])]
4101 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4105 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4110 ;; When SSE is available, it is always faster to use it!
4111 (define_insn "fix_truncsfdi_sse"
4112 [(set (match_operand:DI 0 "register_operand" "=r,r")
4113 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4114 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4115 "cvttss2si{q}\t{%1, %0|%0, %1}"
4116 [(set_attr "type" "sseicvt")
4117 (set_attr "mode" "SF")
4118 (set_attr "athlon_decode" "double,vector")])
4120 (define_insn "fix_truncdfdi_sse"
4121 [(set (match_operand:DI 0 "register_operand" "=r,r")
4122 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4123 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4124 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4125 [(set_attr "type" "sseicvt")
4126 (set_attr "mode" "DF")
4127 (set_attr "athlon_decode" "double,vector")])
4129 (define_insn "fix_truncsfsi_sse"
4130 [(set (match_operand:SI 0 "register_operand" "=r,r")
4131 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4132 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4133 "cvttss2si\t{%1, %0|%0, %1}"
4134 [(set_attr "type" "sseicvt")
4135 (set_attr "mode" "DF")
4136 (set_attr "athlon_decode" "double,vector")])
4138 (define_insn "fix_truncdfsi_sse"
4139 [(set (match_operand:SI 0 "register_operand" "=r,r")
4140 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4141 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4142 "cvttsd2si\t{%1, %0|%0, %1}"
4143 [(set_attr "type" "sseicvt")
4144 (set_attr "mode" "DF")
4145 (set_attr "athlon_decode" "double,vector")])
4147 ;; Avoid vector decoded forms of the instruction.
4149 [(match_scratch:DF 2 "Y")
4150 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4151 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4152 "TARGET_K8 && !optimize_size"
4153 [(set (match_dup 2) (match_dup 1))
4154 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4158 [(match_scratch:SF 2 "x")
4159 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4160 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4161 "TARGET_K8 && !optimize_size"
4162 [(set (match_dup 2) (match_dup 1))
4163 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4166 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4167 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4168 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4170 && FLOAT_MODE_P (GET_MODE (operands[1]))
4171 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4172 && (TARGET_64BIT || <MODE>mode != DImode))
4174 && !(reload_completed || reload_in_progress)"
4179 if (memory_operand (operands[0], VOIDmode))
4180 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4183 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4184 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4190 [(set_attr "type" "fisttp")
4191 (set_attr "mode" "<MODE>")])
4193 (define_insn "fix_trunc<mode>_i387_fisttp"
4194 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4195 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4196 (clobber (match_scratch:XF 2 "=&1f"))]
4198 && FLOAT_MODE_P (GET_MODE (operands[1]))
4199 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4200 && (TARGET_64BIT || <MODE>mode != DImode))
4201 && TARGET_SSE_MATH)"
4202 "* return output_fix_trunc (insn, operands, 1);"
4203 [(set_attr "type" "fisttp")
4204 (set_attr "mode" "<MODE>")])
4206 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4207 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4208 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4209 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4210 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4212 && FLOAT_MODE_P (GET_MODE (operands[1]))
4213 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4214 && (TARGET_64BIT || <MODE>mode != DImode))
4215 && TARGET_SSE_MATH)"
4217 [(set_attr "type" "fisttp")
4218 (set_attr "mode" "<MODE>")])
4221 [(set (match_operand:X87MODEI 0 "register_operand" "")
4222 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4223 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4224 (clobber (match_scratch 3 ""))]
4226 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4227 (clobber (match_dup 3))])
4228 (set (match_dup 0) (match_dup 2))]
4232 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4233 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4234 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4235 (clobber (match_scratch 3 ""))]
4237 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4238 (clobber (match_dup 3))])]
4241 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4242 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4243 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4244 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4245 ;; function in i386.c.
4246 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4247 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4248 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4249 (clobber (reg:CC FLAGS_REG))]
4250 "TARGET_80387 && !TARGET_FISTTP
4251 && FLOAT_MODE_P (GET_MODE (operands[1]))
4252 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4253 && (TARGET_64BIT || <MODE>mode != DImode))
4254 && !(reload_completed || reload_in_progress)"
4259 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4261 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4262 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4263 if (memory_operand (operands[0], VOIDmode))
4264 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4265 operands[2], operands[3]));
4268 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4269 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4270 operands[2], operands[3],
4275 [(set_attr "type" "fistp")
4276 (set_attr "i387_cw" "trunc")
4277 (set_attr "mode" "<MODE>")])
4279 (define_insn "fix_truncdi_i387"
4280 [(set (match_operand:DI 0 "memory_operand" "=m")
4281 (fix:DI (match_operand 1 "register_operand" "f")))
4282 (use (match_operand:HI 2 "memory_operand" "m"))
4283 (use (match_operand:HI 3 "memory_operand" "m"))
4284 (clobber (match_scratch:XF 4 "=&1f"))]
4285 "TARGET_80387 && !TARGET_FISTTP
4286 && FLOAT_MODE_P (GET_MODE (operands[1]))
4287 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4288 "* return output_fix_trunc (insn, operands, 0);"
4289 [(set_attr "type" "fistp")
4290 (set_attr "i387_cw" "trunc")
4291 (set_attr "mode" "DI")])
4293 (define_insn "fix_truncdi_i387_with_temp"
4294 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4295 (fix:DI (match_operand 1 "register_operand" "f,f")))
4296 (use (match_operand:HI 2 "memory_operand" "m,m"))
4297 (use (match_operand:HI 3 "memory_operand" "m,m"))
4298 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4299 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4300 "TARGET_80387 && !TARGET_FISTTP
4301 && FLOAT_MODE_P (GET_MODE (operands[1]))
4302 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4304 [(set_attr "type" "fistp")
4305 (set_attr "i387_cw" "trunc")
4306 (set_attr "mode" "DI")])
4309 [(set (match_operand:DI 0 "register_operand" "")
4310 (fix:DI (match_operand 1 "register_operand" "")))
4311 (use (match_operand:HI 2 "memory_operand" ""))
4312 (use (match_operand:HI 3 "memory_operand" ""))
4313 (clobber (match_operand:DI 4 "memory_operand" ""))
4314 (clobber (match_scratch 5 ""))]
4316 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4319 (clobber (match_dup 5))])
4320 (set (match_dup 0) (match_dup 4))]
4324 [(set (match_operand:DI 0 "memory_operand" "")
4325 (fix:DI (match_operand 1 "register_operand" "")))
4326 (use (match_operand:HI 2 "memory_operand" ""))
4327 (use (match_operand:HI 3 "memory_operand" ""))
4328 (clobber (match_operand:DI 4 "memory_operand" ""))
4329 (clobber (match_scratch 5 ""))]
4331 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4334 (clobber (match_dup 5))])]
4337 (define_insn "fix_trunc<mode>_i387"
4338 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4339 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4340 (use (match_operand:HI 2 "memory_operand" "m"))
4341 (use (match_operand:HI 3 "memory_operand" "m"))]
4342 "TARGET_80387 && !TARGET_FISTTP
4343 && FLOAT_MODE_P (GET_MODE (operands[1]))
4344 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4345 "* return output_fix_trunc (insn, operands, 0);"
4346 [(set_attr "type" "fistp")
4347 (set_attr "i387_cw" "trunc")
4348 (set_attr "mode" "<MODE>")])
4350 (define_insn "fix_trunc<mode>_i387_with_temp"
4351 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4352 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4353 (use (match_operand:HI 2 "memory_operand" "m,m"))
4354 (use (match_operand:HI 3 "memory_operand" "m,m"))
4355 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4356 "TARGET_80387 && !TARGET_FISTTP
4357 && FLOAT_MODE_P (GET_MODE (operands[1]))
4358 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4360 [(set_attr "type" "fistp")
4361 (set_attr "i387_cw" "trunc")
4362 (set_attr "mode" "<MODE>")])
4365 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4366 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4367 (use (match_operand:HI 2 "memory_operand" ""))
4368 (use (match_operand:HI 3 "memory_operand" ""))
4369 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4371 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4373 (use (match_dup 3))])
4374 (set (match_dup 0) (match_dup 4))]
4378 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4379 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4380 (use (match_operand:HI 2 "memory_operand" ""))
4381 (use (match_operand:HI 3 "memory_operand" ""))
4382 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4384 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4386 (use (match_dup 3))])]
4389 (define_insn "x86_fnstcw_1"
4390 [(set (match_operand:HI 0 "memory_operand" "=m")
4391 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4394 [(set_attr "length" "2")
4395 (set_attr "mode" "HI")
4396 (set_attr "unit" "i387")])
4398 (define_insn "x86_fldcw_1"
4399 [(set (reg:HI FPSR_REG)
4400 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4403 [(set_attr "length" "2")
4404 (set_attr "mode" "HI")
4405 (set_attr "unit" "i387")
4406 (set_attr "athlon_decode" "vector")])
4408 ;; Conversion between fixed point and floating point.
4410 ;; Even though we only accept memory inputs, the backend _really_
4411 ;; wants to be able to do this between registers.
4413 (define_expand "floathisf2"
4414 [(set (match_operand:SF 0 "register_operand" "")
4415 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4416 "TARGET_80387 || TARGET_SSE_MATH"
4418 if (TARGET_SSE_MATH)
4420 emit_insn (gen_floatsisf2 (operands[0],
4421 convert_to_mode (SImode, operands[1], 0)));
4426 (define_insn "*floathisf2_i387"
4427 [(set (match_operand:SF 0 "register_operand" "=f,f")
4428 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4429 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4433 [(set_attr "type" "fmov,multi")
4434 (set_attr "mode" "SF")
4435 (set_attr "unit" "*,i387")
4436 (set_attr "fp_int_src" "true")])
4438 (define_expand "floatsisf2"
4439 [(set (match_operand:SF 0 "register_operand" "")
4440 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4441 "TARGET_80387 || TARGET_SSE_MATH"
4444 (define_insn "*floatsisf2_mixed"
4445 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4446 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4447 "TARGET_MIX_SSE_I387"
4451 cvtsi2ss\t{%1, %0|%0, %1}
4452 cvtsi2ss\t{%1, %0|%0, %1}"
4453 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4454 (set_attr "mode" "SF")
4455 (set_attr "unit" "*,i387,*,*")
4456 (set_attr "athlon_decode" "*,*,vector,double")
4457 (set_attr "fp_int_src" "true")])
4459 (define_insn "*floatsisf2_sse"
4460 [(set (match_operand:SF 0 "register_operand" "=x,x")
4461 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4463 "cvtsi2ss\t{%1, %0|%0, %1}"
4464 [(set_attr "type" "sseicvt")
4465 (set_attr "mode" "SF")
4466 (set_attr "athlon_decode" "vector,double")
4467 (set_attr "fp_int_src" "true")])
4469 (define_insn "*floatsisf2_i387"
4470 [(set (match_operand:SF 0 "register_operand" "=f,f")
4471 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4476 [(set_attr "type" "fmov,multi")
4477 (set_attr "mode" "SF")
4478 (set_attr "unit" "*,i387")
4479 (set_attr "fp_int_src" "true")])
4481 (define_expand "floatdisf2"
4482 [(set (match_operand:SF 0 "register_operand" "")
4483 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4484 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4487 (define_insn "*floatdisf2_mixed"
4488 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4489 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4490 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4494 cvtsi2ss{q}\t{%1, %0|%0, %1}
4495 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4496 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4497 (set_attr "mode" "SF")
4498 (set_attr "unit" "*,i387,*,*")
4499 (set_attr "athlon_decode" "*,*,vector,double")
4500 (set_attr "fp_int_src" "true")])
4502 (define_insn "*floatdisf2_sse"
4503 [(set (match_operand:SF 0 "register_operand" "=x,x")
4504 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4505 "TARGET_64BIT && TARGET_SSE_MATH"
4506 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4507 [(set_attr "type" "sseicvt")
4508 (set_attr "mode" "SF")
4509 (set_attr "athlon_decode" "vector,double")
4510 (set_attr "fp_int_src" "true")])
4512 (define_insn "*floatdisf2_i387"
4513 [(set (match_operand:SF 0 "register_operand" "=f,f")
4514 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4519 [(set_attr "type" "fmov,multi")
4520 (set_attr "mode" "SF")
4521 (set_attr "unit" "*,i387")
4522 (set_attr "fp_int_src" "true")])
4524 (define_expand "floathidf2"
4525 [(set (match_operand:DF 0 "register_operand" "")
4526 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4527 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4529 if (TARGET_SSE2 && TARGET_SSE_MATH)
4531 emit_insn (gen_floatsidf2 (operands[0],
4532 convert_to_mode (SImode, operands[1], 0)));
4537 (define_insn "*floathidf2_i387"
4538 [(set (match_operand:DF 0 "register_operand" "=f,f")
4539 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4540 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4544 [(set_attr "type" "fmov,multi")
4545 (set_attr "mode" "DF")
4546 (set_attr "unit" "*,i387")
4547 (set_attr "fp_int_src" "true")])
4549 (define_expand "floatsidf2"
4550 [(set (match_operand:DF 0 "register_operand" "")
4551 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4552 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4555 (define_insn "*floatsidf2_mixed"
4556 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4557 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4558 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4562 cvtsi2sd\t{%1, %0|%0, %1}
4563 cvtsi2sd\t{%1, %0|%0, %1}"
4564 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4565 (set_attr "mode" "DF")
4566 (set_attr "unit" "*,i387,*,*")
4567 (set_attr "athlon_decode" "*,*,double,direct")
4568 (set_attr "fp_int_src" "true")])
4570 (define_insn "*floatsidf2_sse"
4571 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4572 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4573 "TARGET_SSE2 && TARGET_SSE_MATH"
4574 "cvtsi2sd\t{%1, %0|%0, %1}"
4575 [(set_attr "type" "sseicvt")
4576 (set_attr "mode" "DF")
4577 (set_attr "athlon_decode" "double,direct")
4578 (set_attr "fp_int_src" "true")])
4580 (define_insn "*floatsidf2_i387"
4581 [(set (match_operand:DF 0 "register_operand" "=f,f")
4582 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4587 [(set_attr "type" "fmov,multi")
4588 (set_attr "mode" "DF")
4589 (set_attr "unit" "*,i387")
4590 (set_attr "fp_int_src" "true")])
4592 (define_expand "floatdidf2"
4593 [(set (match_operand:DF 0 "register_operand" "")
4594 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4595 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4598 (define_insn "*floatdidf2_mixed"
4599 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4600 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4601 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4605 cvtsi2sd{q}\t{%1, %0|%0, %1}
4606 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4607 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4608 (set_attr "mode" "DF")
4609 (set_attr "unit" "*,i387,*,*")
4610 (set_attr "athlon_decode" "*,*,double,direct")
4611 (set_attr "fp_int_src" "true")])
4613 (define_insn "*floatdidf2_sse"
4614 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4615 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4616 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4617 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4618 [(set_attr "type" "sseicvt")
4619 (set_attr "mode" "DF")
4620 (set_attr "athlon_decode" "double,direct")
4621 (set_attr "fp_int_src" "true")])
4623 (define_insn "*floatdidf2_i387"
4624 [(set (match_operand:DF 0 "register_operand" "=f,f")
4625 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4630 [(set_attr "type" "fmov,multi")
4631 (set_attr "mode" "DF")
4632 (set_attr "unit" "*,i387")
4633 (set_attr "fp_int_src" "true")])
4635 (define_insn "floathixf2"
4636 [(set (match_operand:XF 0 "register_operand" "=f,f")
4637 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4642 [(set_attr "type" "fmov,multi")
4643 (set_attr "mode" "XF")
4644 (set_attr "unit" "*,i387")
4645 (set_attr "fp_int_src" "true")])
4647 (define_insn "floatsixf2"
4648 [(set (match_operand:XF 0 "register_operand" "=f,f")
4649 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4654 [(set_attr "type" "fmov,multi")
4655 (set_attr "mode" "XF")
4656 (set_attr "unit" "*,i387")
4657 (set_attr "fp_int_src" "true")])
4659 (define_insn "floatdixf2"
4660 [(set (match_operand:XF 0 "register_operand" "=f,f")
4661 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4666 [(set_attr "type" "fmov,multi")
4667 (set_attr "mode" "XF")
4668 (set_attr "unit" "*,i387")
4669 (set_attr "fp_int_src" "true")])
4671 ;; %%% Kill these when reload knows how to do it.
4673 [(set (match_operand 0 "fp_register_operand" "")
4674 (float (match_operand 1 "register_operand" "")))]
4677 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4680 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4681 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4682 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4683 ix86_free_from_memory (GET_MODE (operands[1]));
4687 (define_expand "floatunssisf2"
4688 [(use (match_operand:SF 0 "register_operand" ""))
4689 (use (match_operand:SI 1 "register_operand" ""))]
4690 "!TARGET_64BIT && TARGET_SSE_MATH"
4691 "x86_emit_floatuns (operands); DONE;")
4693 (define_expand "floatunsdisf2"
4694 [(use (match_operand:SF 0 "register_operand" ""))
4695 (use (match_operand:DI 1 "register_operand" ""))]
4696 "TARGET_64BIT && TARGET_SSE_MATH"
4697 "x86_emit_floatuns (operands); DONE;")
4699 (define_expand "floatunsdidf2"
4700 [(use (match_operand:DF 0 "register_operand" ""))
4701 (use (match_operand:DI 1 "register_operand" ""))]
4702 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4703 "x86_emit_floatuns (operands); DONE;")
4705 ;; SSE extract/set expanders
4710 ;; %%% splits for addditi3
4712 (define_expand "addti3"
4713 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4714 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4715 (match_operand:TI 2 "x86_64_general_operand" "")))
4716 (clobber (reg:CC FLAGS_REG))]
4718 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4720 (define_insn "*addti3_1"
4721 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4722 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4723 (match_operand:TI 2 "general_operand" "roiF,riF")))
4724 (clobber (reg:CC FLAGS_REG))]
4725 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4729 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4730 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4731 (match_operand:TI 2 "general_operand" "")))
4732 (clobber (reg:CC FLAGS_REG))]
4733 "TARGET_64BIT && reload_completed"
4734 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4736 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4737 (parallel [(set (match_dup 3)
4738 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4741 (clobber (reg:CC FLAGS_REG))])]
4742 "split_ti (operands+0, 1, operands+0, operands+3);
4743 split_ti (operands+1, 1, operands+1, operands+4);
4744 split_ti (operands+2, 1, operands+2, operands+5);")
4746 ;; %%% splits for addsidi3
4747 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4748 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4749 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4751 (define_expand "adddi3"
4752 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4753 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4754 (match_operand:DI 2 "x86_64_general_operand" "")))
4755 (clobber (reg:CC FLAGS_REG))]
4757 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4759 (define_insn "*adddi3_1"
4760 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4761 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4762 (match_operand:DI 2 "general_operand" "roiF,riF")))
4763 (clobber (reg:CC FLAGS_REG))]
4764 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4768 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4769 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4770 (match_operand:DI 2 "general_operand" "")))
4771 (clobber (reg:CC FLAGS_REG))]
4772 "!TARGET_64BIT && reload_completed"
4773 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4775 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4776 (parallel [(set (match_dup 3)
4777 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4780 (clobber (reg:CC FLAGS_REG))])]
4781 "split_di (operands+0, 1, operands+0, operands+3);
4782 split_di (operands+1, 1, operands+1, operands+4);
4783 split_di (operands+2, 1, operands+2, operands+5);")
4785 (define_insn "adddi3_carry_rex64"
4786 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4787 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4788 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4789 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4790 (clobber (reg:CC FLAGS_REG))]
4791 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4792 "adc{q}\t{%2, %0|%0, %2}"
4793 [(set_attr "type" "alu")
4794 (set_attr "pent_pair" "pu")
4795 (set_attr "mode" "DI")])
4797 (define_insn "*adddi3_cc_rex64"
4798 [(set (reg:CC FLAGS_REG)
4799 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4800 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4802 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4803 (plus:DI (match_dup 1) (match_dup 2)))]
4804 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4805 "add{q}\t{%2, %0|%0, %2}"
4806 [(set_attr "type" "alu")
4807 (set_attr "mode" "DI")])
4809 (define_insn "addqi3_carry"
4810 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4811 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4812 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4813 (match_operand:QI 2 "general_operand" "qi,qm")))
4814 (clobber (reg:CC FLAGS_REG))]
4815 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4816 "adc{b}\t{%2, %0|%0, %2}"
4817 [(set_attr "type" "alu")
4818 (set_attr "pent_pair" "pu")
4819 (set_attr "mode" "QI")])
4821 (define_insn "addhi3_carry"
4822 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4823 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4824 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4825 (match_operand:HI 2 "general_operand" "ri,rm")))
4826 (clobber (reg:CC FLAGS_REG))]
4827 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4828 "adc{w}\t{%2, %0|%0, %2}"
4829 [(set_attr "type" "alu")
4830 (set_attr "pent_pair" "pu")
4831 (set_attr "mode" "HI")])
4833 (define_insn "addsi3_carry"
4834 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4835 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4836 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4837 (match_operand:SI 2 "general_operand" "ri,rm")))
4838 (clobber (reg:CC FLAGS_REG))]
4839 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4840 "adc{l}\t{%2, %0|%0, %2}"
4841 [(set_attr "type" "alu")
4842 (set_attr "pent_pair" "pu")
4843 (set_attr "mode" "SI")])
4845 (define_insn "*addsi3_carry_zext"
4846 [(set (match_operand:DI 0 "register_operand" "=r")
4848 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4849 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4850 (match_operand:SI 2 "general_operand" "rim"))))
4851 (clobber (reg:CC FLAGS_REG))]
4852 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4853 "adc{l}\t{%2, %k0|%k0, %2}"
4854 [(set_attr "type" "alu")
4855 (set_attr "pent_pair" "pu")
4856 (set_attr "mode" "SI")])
4858 (define_insn "*addsi3_cc"
4859 [(set (reg:CC FLAGS_REG)
4860 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4861 (match_operand:SI 2 "general_operand" "ri,rm")]
4863 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4864 (plus:SI (match_dup 1) (match_dup 2)))]
4865 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4866 "add{l}\t{%2, %0|%0, %2}"
4867 [(set_attr "type" "alu")
4868 (set_attr "mode" "SI")])
4870 (define_insn "addqi3_cc"
4871 [(set (reg:CC FLAGS_REG)
4872 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4873 (match_operand:QI 2 "general_operand" "qi,qm")]
4875 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4876 (plus:QI (match_dup 1) (match_dup 2)))]
4877 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4878 "add{b}\t{%2, %0|%0, %2}"
4879 [(set_attr "type" "alu")
4880 (set_attr "mode" "QI")])
4882 (define_expand "addsi3"
4883 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4884 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4885 (match_operand:SI 2 "general_operand" "")))
4886 (clobber (reg:CC FLAGS_REG))])]
4888 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4890 (define_insn "*lea_1"
4891 [(set (match_operand:SI 0 "register_operand" "=r")
4892 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4894 "lea{l}\t{%a1, %0|%0, %a1}"
4895 [(set_attr "type" "lea")
4896 (set_attr "mode" "SI")])
4898 (define_insn "*lea_1_rex64"
4899 [(set (match_operand:SI 0 "register_operand" "=r")
4900 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4902 "lea{l}\t{%a1, %0|%0, %a1}"
4903 [(set_attr "type" "lea")
4904 (set_attr "mode" "SI")])
4906 (define_insn "*lea_1_zext"
4907 [(set (match_operand:DI 0 "register_operand" "=r")
4909 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4911 "lea{l}\t{%a1, %k0|%k0, %a1}"
4912 [(set_attr "type" "lea")
4913 (set_attr "mode" "SI")])
4915 (define_insn "*lea_2_rex64"
4916 [(set (match_operand:DI 0 "register_operand" "=r")
4917 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4919 "lea{q}\t{%a1, %0|%0, %a1}"
4920 [(set_attr "type" "lea")
4921 (set_attr "mode" "DI")])
4923 ;; The lea patterns for non-Pmodes needs to be matched by several
4924 ;; insns converted to real lea by splitters.
4926 (define_insn_and_split "*lea_general_1"
4927 [(set (match_operand 0 "register_operand" "=r")
4928 (plus (plus (match_operand 1 "index_register_operand" "l")
4929 (match_operand 2 "register_operand" "r"))
4930 (match_operand 3 "immediate_operand" "i")))]
4931 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4932 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4933 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4934 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4935 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4936 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4937 || GET_MODE (operands[3]) == VOIDmode)"
4939 "&& reload_completed"
4943 operands[0] = gen_lowpart (SImode, operands[0]);
4944 operands[1] = gen_lowpart (Pmode, operands[1]);
4945 operands[2] = gen_lowpart (Pmode, operands[2]);
4946 operands[3] = gen_lowpart (Pmode, operands[3]);
4947 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4949 if (Pmode != SImode)
4950 pat = gen_rtx_SUBREG (SImode, pat, 0);
4951 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4954 [(set_attr "type" "lea")
4955 (set_attr "mode" "SI")])
4957 (define_insn_and_split "*lea_general_1_zext"
4958 [(set (match_operand:DI 0 "register_operand" "=r")
4960 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4961 (match_operand:SI 2 "register_operand" "r"))
4962 (match_operand:SI 3 "immediate_operand" "i"))))]
4965 "&& reload_completed"
4967 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4969 (match_dup 3)) 0)))]
4971 operands[1] = gen_lowpart (Pmode, operands[1]);
4972 operands[2] = gen_lowpart (Pmode, operands[2]);
4973 operands[3] = gen_lowpart (Pmode, operands[3]);
4975 [(set_attr "type" "lea")
4976 (set_attr "mode" "SI")])
4978 (define_insn_and_split "*lea_general_2"
4979 [(set (match_operand 0 "register_operand" "=r")
4980 (plus (mult (match_operand 1 "index_register_operand" "l")
4981 (match_operand 2 "const248_operand" "i"))
4982 (match_operand 3 "nonmemory_operand" "ri")))]
4983 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4984 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4985 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4986 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4987 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4988 || GET_MODE (operands[3]) == VOIDmode)"
4990 "&& reload_completed"
4994 operands[0] = gen_lowpart (SImode, operands[0]);
4995 operands[1] = gen_lowpart (Pmode, operands[1]);
4996 operands[3] = gen_lowpart (Pmode, operands[3]);
4997 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4999 if (Pmode != SImode)
5000 pat = gen_rtx_SUBREG (SImode, pat, 0);
5001 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5004 [(set_attr "type" "lea")
5005 (set_attr "mode" "SI")])
5007 (define_insn_and_split "*lea_general_2_zext"
5008 [(set (match_operand:DI 0 "register_operand" "=r")
5010 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5011 (match_operand:SI 2 "const248_operand" "n"))
5012 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5015 "&& reload_completed"
5017 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5019 (match_dup 3)) 0)))]
5021 operands[1] = gen_lowpart (Pmode, operands[1]);
5022 operands[3] = gen_lowpart (Pmode, operands[3]);
5024 [(set_attr "type" "lea")
5025 (set_attr "mode" "SI")])
5027 (define_insn_and_split "*lea_general_3"
5028 [(set (match_operand 0 "register_operand" "=r")
5029 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5030 (match_operand 2 "const248_operand" "i"))
5031 (match_operand 3 "register_operand" "r"))
5032 (match_operand 4 "immediate_operand" "i")))]
5033 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5034 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5035 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5036 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5037 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5039 "&& reload_completed"
5043 operands[0] = gen_lowpart (SImode, operands[0]);
5044 operands[1] = gen_lowpart (Pmode, operands[1]);
5045 operands[3] = gen_lowpart (Pmode, operands[3]);
5046 operands[4] = gen_lowpart (Pmode, operands[4]);
5047 pat = gen_rtx_PLUS (Pmode,
5048 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5052 if (Pmode != SImode)
5053 pat = gen_rtx_SUBREG (SImode, pat, 0);
5054 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5057 [(set_attr "type" "lea")
5058 (set_attr "mode" "SI")])
5060 (define_insn_and_split "*lea_general_3_zext"
5061 [(set (match_operand:DI 0 "register_operand" "=r")
5063 (plus:SI (plus:SI (mult:SI
5064 (match_operand:SI 1 "index_register_operand" "l")
5065 (match_operand:SI 2 "const248_operand" "n"))
5066 (match_operand:SI 3 "register_operand" "r"))
5067 (match_operand:SI 4 "immediate_operand" "i"))))]
5070 "&& reload_completed"
5072 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5075 (match_dup 4)) 0)))]
5077 operands[1] = gen_lowpart (Pmode, operands[1]);
5078 operands[3] = gen_lowpart (Pmode, operands[3]);
5079 operands[4] = gen_lowpart (Pmode, operands[4]);
5081 [(set_attr "type" "lea")
5082 (set_attr "mode" "SI")])
5084 (define_insn "*adddi_1_rex64"
5085 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5086 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5087 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5088 (clobber (reg:CC FLAGS_REG))]
5089 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5091 switch (get_attr_type (insn))
5094 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5095 return "lea{q}\t{%a2, %0|%0, %a2}";
5098 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5099 if (operands[2] == const1_rtx)
5100 return "inc{q}\t%0";
5103 gcc_assert (operands[2] == constm1_rtx);
5104 return "dec{q}\t%0";
5108 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5110 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5111 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5112 if (GET_CODE (operands[2]) == CONST_INT
5113 /* Avoid overflows. */
5114 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5115 && (INTVAL (operands[2]) == 128
5116 || (INTVAL (operands[2]) < 0
5117 && INTVAL (operands[2]) != -128)))
5119 operands[2] = GEN_INT (-INTVAL (operands[2]));
5120 return "sub{q}\t{%2, %0|%0, %2}";
5122 return "add{q}\t{%2, %0|%0, %2}";
5126 (cond [(eq_attr "alternative" "2")
5127 (const_string "lea")
5128 ; Current assemblers are broken and do not allow @GOTOFF in
5129 ; ought but a memory context.
5130 (match_operand:DI 2 "pic_symbolic_operand" "")
5131 (const_string "lea")
5132 (match_operand:DI 2 "incdec_operand" "")
5133 (const_string "incdec")
5135 (const_string "alu")))
5136 (set_attr "mode" "DI")])
5138 ;; Convert lea to the lea pattern to avoid flags dependency.
5140 [(set (match_operand:DI 0 "register_operand" "")
5141 (plus:DI (match_operand:DI 1 "register_operand" "")
5142 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5143 (clobber (reg:CC FLAGS_REG))]
5144 "TARGET_64BIT && reload_completed
5145 && true_regnum (operands[0]) != true_regnum (operands[1])"
5147 (plus:DI (match_dup 1)
5151 (define_insn "*adddi_2_rex64"
5152 [(set (reg FLAGS_REG)
5154 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5155 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5157 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5158 (plus:DI (match_dup 1) (match_dup 2)))]
5159 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5160 && ix86_binary_operator_ok (PLUS, DImode, operands)
5161 /* Current assemblers are broken and do not allow @GOTOFF in
5162 ought but a memory context. */
5163 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5165 switch (get_attr_type (insn))
5168 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5169 if (operands[2] == const1_rtx)
5170 return "inc{q}\t%0";
5173 gcc_assert (operands[2] == constm1_rtx);
5174 return "dec{q}\t%0";
5178 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5179 /* ???? We ought to handle there the 32bit case too
5180 - do we need new constraint? */
5181 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5182 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5183 if (GET_CODE (operands[2]) == CONST_INT
5184 /* Avoid overflows. */
5185 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5186 && (INTVAL (operands[2]) == 128
5187 || (INTVAL (operands[2]) < 0
5188 && INTVAL (operands[2]) != -128)))
5190 operands[2] = GEN_INT (-INTVAL (operands[2]));
5191 return "sub{q}\t{%2, %0|%0, %2}";
5193 return "add{q}\t{%2, %0|%0, %2}";
5197 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5198 (const_string "incdec")
5199 (const_string "alu")))
5200 (set_attr "mode" "DI")])
5202 (define_insn "*adddi_3_rex64"
5203 [(set (reg FLAGS_REG)
5204 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5205 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5206 (clobber (match_scratch:DI 0 "=r"))]
5208 && ix86_match_ccmode (insn, CCZmode)
5209 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5210 /* Current assemblers are broken and do not allow @GOTOFF in
5211 ought but a memory context. */
5212 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5214 switch (get_attr_type (insn))
5217 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5218 if (operands[2] == const1_rtx)
5219 return "inc{q}\t%0";
5222 gcc_assert (operands[2] == constm1_rtx);
5223 return "dec{q}\t%0";
5227 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5228 /* ???? We ought to handle there the 32bit case too
5229 - do we need new constraint? */
5230 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5231 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5232 if (GET_CODE (operands[2]) == CONST_INT
5233 /* Avoid overflows. */
5234 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5235 && (INTVAL (operands[2]) == 128
5236 || (INTVAL (operands[2]) < 0
5237 && INTVAL (operands[2]) != -128)))
5239 operands[2] = GEN_INT (-INTVAL (operands[2]));
5240 return "sub{q}\t{%2, %0|%0, %2}";
5242 return "add{q}\t{%2, %0|%0, %2}";
5246 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5247 (const_string "incdec")
5248 (const_string "alu")))
5249 (set_attr "mode" "DI")])
5251 ; For comparisons against 1, -1 and 128, we may generate better code
5252 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5253 ; is matched then. We can't accept general immediate, because for
5254 ; case of overflows, the result is messed up.
5255 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5257 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5258 ; only for comparisons not depending on it.
5259 (define_insn "*adddi_4_rex64"
5260 [(set (reg FLAGS_REG)
5261 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5262 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5263 (clobber (match_scratch:DI 0 "=rm"))]
5265 && ix86_match_ccmode (insn, CCGCmode)"
5267 switch (get_attr_type (insn))
5270 if (operands[2] == constm1_rtx)
5271 return "inc{q}\t%0";
5274 gcc_assert (operands[2] == const1_rtx);
5275 return "dec{q}\t%0";
5279 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5280 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5281 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5282 if ((INTVAL (operands[2]) == -128
5283 || (INTVAL (operands[2]) > 0
5284 && INTVAL (operands[2]) != 128))
5285 /* Avoid overflows. */
5286 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5287 return "sub{q}\t{%2, %0|%0, %2}";
5288 operands[2] = GEN_INT (-INTVAL (operands[2]));
5289 return "add{q}\t{%2, %0|%0, %2}";
5293 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5294 (const_string "incdec")
5295 (const_string "alu")))
5296 (set_attr "mode" "DI")])
5298 (define_insn "*adddi_5_rex64"
5299 [(set (reg FLAGS_REG)
5301 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5302 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5304 (clobber (match_scratch:DI 0 "=r"))]
5306 && ix86_match_ccmode (insn, CCGOCmode)
5307 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5308 /* Current assemblers are broken and do not allow @GOTOFF in
5309 ought but a memory context. */
5310 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5312 switch (get_attr_type (insn))
5315 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5316 if (operands[2] == const1_rtx)
5317 return "inc{q}\t%0";
5320 gcc_assert (operands[2] == constm1_rtx);
5321 return "dec{q}\t%0";
5325 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5326 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5327 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5328 if (GET_CODE (operands[2]) == CONST_INT
5329 /* Avoid overflows. */
5330 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5331 && (INTVAL (operands[2]) == 128
5332 || (INTVAL (operands[2]) < 0
5333 && INTVAL (operands[2]) != -128)))
5335 operands[2] = GEN_INT (-INTVAL (operands[2]));
5336 return "sub{q}\t{%2, %0|%0, %2}";
5338 return "add{q}\t{%2, %0|%0, %2}";
5342 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5343 (const_string "incdec")
5344 (const_string "alu")))
5345 (set_attr "mode" "DI")])
5348 (define_insn "*addsi_1"
5349 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5350 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5351 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5352 (clobber (reg:CC FLAGS_REG))]
5353 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5355 switch (get_attr_type (insn))
5358 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5359 return "lea{l}\t{%a2, %0|%0, %a2}";
5362 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5363 if (operands[2] == const1_rtx)
5364 return "inc{l}\t%0";
5367 gcc_assert (operands[2] == constm1_rtx);
5368 return "dec{l}\t%0";
5372 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5374 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5375 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5376 if (GET_CODE (operands[2]) == CONST_INT
5377 && (INTVAL (operands[2]) == 128
5378 || (INTVAL (operands[2]) < 0
5379 && INTVAL (operands[2]) != -128)))
5381 operands[2] = GEN_INT (-INTVAL (operands[2]));
5382 return "sub{l}\t{%2, %0|%0, %2}";
5384 return "add{l}\t{%2, %0|%0, %2}";
5388 (cond [(eq_attr "alternative" "2")
5389 (const_string "lea")
5390 ; Current assemblers are broken and do not allow @GOTOFF in
5391 ; ought but a memory context.
5392 (match_operand:SI 2 "pic_symbolic_operand" "")
5393 (const_string "lea")
5394 (match_operand:SI 2 "incdec_operand" "")
5395 (const_string "incdec")
5397 (const_string "alu")))
5398 (set_attr "mode" "SI")])
5400 ;; Convert lea to the lea pattern to avoid flags dependency.
5402 [(set (match_operand 0 "register_operand" "")
5403 (plus (match_operand 1 "register_operand" "")
5404 (match_operand 2 "nonmemory_operand" "")))
5405 (clobber (reg:CC FLAGS_REG))]
5407 && true_regnum (operands[0]) != true_regnum (operands[1])"
5411 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5412 may confuse gen_lowpart. */
5413 if (GET_MODE (operands[0]) != Pmode)
5415 operands[1] = gen_lowpart (Pmode, operands[1]);
5416 operands[2] = gen_lowpart (Pmode, operands[2]);
5418 operands[0] = gen_lowpart (SImode, operands[0]);
5419 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5420 if (Pmode != SImode)
5421 pat = gen_rtx_SUBREG (SImode, pat, 0);
5422 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5426 ;; It may seem that nonimmediate operand is proper one for operand 1.
5427 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5428 ;; we take care in ix86_binary_operator_ok to not allow two memory
5429 ;; operands so proper swapping will be done in reload. This allow
5430 ;; patterns constructed from addsi_1 to match.
5431 (define_insn "addsi_1_zext"
5432 [(set (match_operand:DI 0 "register_operand" "=r,r")
5434 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5435 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5436 (clobber (reg:CC FLAGS_REG))]
5437 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5439 switch (get_attr_type (insn))
5442 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5443 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5446 if (operands[2] == const1_rtx)
5447 return "inc{l}\t%k0";
5450 gcc_assert (operands[2] == constm1_rtx);
5451 return "dec{l}\t%k0";
5455 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5456 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5457 if (GET_CODE (operands[2]) == CONST_INT
5458 && (INTVAL (operands[2]) == 128
5459 || (INTVAL (operands[2]) < 0
5460 && INTVAL (operands[2]) != -128)))
5462 operands[2] = GEN_INT (-INTVAL (operands[2]));
5463 return "sub{l}\t{%2, %k0|%k0, %2}";
5465 return "add{l}\t{%2, %k0|%k0, %2}";
5469 (cond [(eq_attr "alternative" "1")
5470 (const_string "lea")
5471 ; Current assemblers are broken and do not allow @GOTOFF in
5472 ; ought but a memory context.
5473 (match_operand:SI 2 "pic_symbolic_operand" "")
5474 (const_string "lea")
5475 (match_operand:SI 2 "incdec_operand" "")
5476 (const_string "incdec")
5478 (const_string "alu")))
5479 (set_attr "mode" "SI")])
5481 ;; Convert lea to the lea pattern to avoid flags dependency.
5483 [(set (match_operand:DI 0 "register_operand" "")
5485 (plus:SI (match_operand:SI 1 "register_operand" "")
5486 (match_operand:SI 2 "nonmemory_operand" ""))))
5487 (clobber (reg:CC FLAGS_REG))]
5488 "TARGET_64BIT && reload_completed
5489 && true_regnum (operands[0]) != true_regnum (operands[1])"
5491 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5493 operands[1] = gen_lowpart (Pmode, operands[1]);
5494 operands[2] = gen_lowpart (Pmode, operands[2]);
5497 (define_insn "*addsi_2"
5498 [(set (reg FLAGS_REG)
5500 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5501 (match_operand:SI 2 "general_operand" "rmni,rni"))
5503 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5504 (plus:SI (match_dup 1) (match_dup 2)))]
5505 "ix86_match_ccmode (insn, CCGOCmode)
5506 && ix86_binary_operator_ok (PLUS, SImode, operands)
5507 /* Current assemblers are broken and do not allow @GOTOFF in
5508 ought but a memory context. */
5509 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5511 switch (get_attr_type (insn))
5514 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515 if (operands[2] == const1_rtx)
5516 return "inc{l}\t%0";
5519 gcc_assert (operands[2] == constm1_rtx);
5520 return "dec{l}\t%0";
5524 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5525 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5526 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5527 if (GET_CODE (operands[2]) == CONST_INT
5528 && (INTVAL (operands[2]) == 128
5529 || (INTVAL (operands[2]) < 0
5530 && INTVAL (operands[2]) != -128)))
5532 operands[2] = GEN_INT (-INTVAL (operands[2]));
5533 return "sub{l}\t{%2, %0|%0, %2}";
5535 return "add{l}\t{%2, %0|%0, %2}";
5539 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5540 (const_string "incdec")
5541 (const_string "alu")))
5542 (set_attr "mode" "SI")])
5544 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5545 (define_insn "*addsi_2_zext"
5546 [(set (reg FLAGS_REG)
5548 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5549 (match_operand:SI 2 "general_operand" "rmni"))
5551 (set (match_operand:DI 0 "register_operand" "=r")
5552 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5553 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5554 && ix86_binary_operator_ok (PLUS, SImode, operands)
5555 /* Current assemblers are broken and do not allow @GOTOFF in
5556 ought but a memory context. */
5557 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5559 switch (get_attr_type (insn))
5562 if (operands[2] == const1_rtx)
5563 return "inc{l}\t%k0";
5566 gcc_assert (operands[2] == constm1_rtx);
5567 return "dec{l}\t%k0";
5571 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5572 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5573 if (GET_CODE (operands[2]) == CONST_INT
5574 && (INTVAL (operands[2]) == 128
5575 || (INTVAL (operands[2]) < 0
5576 && INTVAL (operands[2]) != -128)))
5578 operands[2] = GEN_INT (-INTVAL (operands[2]));
5579 return "sub{l}\t{%2, %k0|%k0, %2}";
5581 return "add{l}\t{%2, %k0|%k0, %2}";
5585 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5586 (const_string "incdec")
5587 (const_string "alu")))
5588 (set_attr "mode" "SI")])
5590 (define_insn "*addsi_3"
5591 [(set (reg FLAGS_REG)
5592 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5593 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5594 (clobber (match_scratch:SI 0 "=r"))]
5595 "ix86_match_ccmode (insn, CCZmode)
5596 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5597 /* Current assemblers are broken and do not allow @GOTOFF in
5598 ought but a memory context. */
5599 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5601 switch (get_attr_type (insn))
5604 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5605 if (operands[2] == const1_rtx)
5606 return "inc{l}\t%0";
5609 gcc_assert (operands[2] == constm1_rtx);
5610 return "dec{l}\t%0";
5614 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5615 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5616 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5617 if (GET_CODE (operands[2]) == CONST_INT
5618 && (INTVAL (operands[2]) == 128
5619 || (INTVAL (operands[2]) < 0
5620 && INTVAL (operands[2]) != -128)))
5622 operands[2] = GEN_INT (-INTVAL (operands[2]));
5623 return "sub{l}\t{%2, %0|%0, %2}";
5625 return "add{l}\t{%2, %0|%0, %2}";
5629 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5630 (const_string "incdec")
5631 (const_string "alu")))
5632 (set_attr "mode" "SI")])
5634 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5635 (define_insn "*addsi_3_zext"
5636 [(set (reg FLAGS_REG)
5637 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5638 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5639 (set (match_operand:DI 0 "register_operand" "=r")
5640 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5641 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5642 && ix86_binary_operator_ok (PLUS, SImode, operands)
5643 /* Current assemblers are broken and do not allow @GOTOFF in
5644 ought but a memory context. */
5645 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5647 switch (get_attr_type (insn))
5650 if (operands[2] == const1_rtx)
5651 return "inc{l}\t%k0";
5654 gcc_assert (operands[2] == constm1_rtx);
5655 return "dec{l}\t%k0";
5659 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5660 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5661 if (GET_CODE (operands[2]) == CONST_INT
5662 && (INTVAL (operands[2]) == 128
5663 || (INTVAL (operands[2]) < 0
5664 && INTVAL (operands[2]) != -128)))
5666 operands[2] = GEN_INT (-INTVAL (operands[2]));
5667 return "sub{l}\t{%2, %k0|%k0, %2}";
5669 return "add{l}\t{%2, %k0|%k0, %2}";
5673 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5674 (const_string "incdec")
5675 (const_string "alu")))
5676 (set_attr "mode" "SI")])
5678 ; For comparisons against 1, -1 and 128, we may generate better code
5679 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5680 ; is matched then. We can't accept general immediate, because for
5681 ; case of overflows, the result is messed up.
5682 ; This pattern also don't hold of 0x80000000, since the value overflows
5684 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5685 ; only for comparisons not depending on it.
5686 (define_insn "*addsi_4"
5687 [(set (reg FLAGS_REG)
5688 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5689 (match_operand:SI 2 "const_int_operand" "n")))
5690 (clobber (match_scratch:SI 0 "=rm"))]
5691 "ix86_match_ccmode (insn, CCGCmode)
5692 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5694 switch (get_attr_type (insn))
5697 if (operands[2] == constm1_rtx)
5698 return "inc{l}\t%0";
5701 gcc_assert (operands[2] == const1_rtx);
5702 return "dec{l}\t%0";
5706 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5707 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5708 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5709 if ((INTVAL (operands[2]) == -128
5710 || (INTVAL (operands[2]) > 0
5711 && INTVAL (operands[2]) != 128)))
5712 return "sub{l}\t{%2, %0|%0, %2}";
5713 operands[2] = GEN_INT (-INTVAL (operands[2]));
5714 return "add{l}\t{%2, %0|%0, %2}";
5718 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5719 (const_string "incdec")
5720 (const_string "alu")))
5721 (set_attr "mode" "SI")])
5723 (define_insn "*addsi_5"
5724 [(set (reg FLAGS_REG)
5726 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5727 (match_operand:SI 2 "general_operand" "rmni"))
5729 (clobber (match_scratch:SI 0 "=r"))]
5730 "ix86_match_ccmode (insn, CCGOCmode)
5731 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5732 /* Current assemblers are broken and do not allow @GOTOFF in
5733 ought but a memory context. */
5734 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5736 switch (get_attr_type (insn))
5739 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5740 if (operands[2] == const1_rtx)
5741 return "inc{l}\t%0";
5744 gcc_assert (operands[2] == constm1_rtx);
5745 return "dec{l}\t%0";
5749 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5750 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5751 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5752 if (GET_CODE (operands[2]) == CONST_INT
5753 && (INTVAL (operands[2]) == 128
5754 || (INTVAL (operands[2]) < 0
5755 && INTVAL (operands[2]) != -128)))
5757 operands[2] = GEN_INT (-INTVAL (operands[2]));
5758 return "sub{l}\t{%2, %0|%0, %2}";
5760 return "add{l}\t{%2, %0|%0, %2}";
5764 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5765 (const_string "incdec")
5766 (const_string "alu")))
5767 (set_attr "mode" "SI")])
5769 (define_expand "addhi3"
5770 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5771 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5772 (match_operand:HI 2 "general_operand" "")))
5773 (clobber (reg:CC FLAGS_REG))])]
5774 "TARGET_HIMODE_MATH"
5775 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5777 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5778 ;; type optimizations enabled by define-splits. This is not important
5779 ;; for PII, and in fact harmful because of partial register stalls.
5781 (define_insn "*addhi_1_lea"
5782 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5783 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5784 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5785 (clobber (reg:CC FLAGS_REG))]
5786 "!TARGET_PARTIAL_REG_STALL
5787 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5789 switch (get_attr_type (insn))
5794 if (operands[2] == const1_rtx)
5795 return "inc{w}\t%0";
5798 gcc_assert (operands[2] == constm1_rtx);
5799 return "dec{w}\t%0";
5803 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5804 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5805 if (GET_CODE (operands[2]) == CONST_INT
5806 && (INTVAL (operands[2]) == 128
5807 || (INTVAL (operands[2]) < 0
5808 && INTVAL (operands[2]) != -128)))
5810 operands[2] = GEN_INT (-INTVAL (operands[2]));
5811 return "sub{w}\t{%2, %0|%0, %2}";
5813 return "add{w}\t{%2, %0|%0, %2}";
5817 (if_then_else (eq_attr "alternative" "2")
5818 (const_string "lea")
5819 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5820 (const_string "incdec")
5821 (const_string "alu"))))
5822 (set_attr "mode" "HI,HI,SI")])
5824 (define_insn "*addhi_1"
5825 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5826 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5827 (match_operand:HI 2 "general_operand" "ri,rm")))
5828 (clobber (reg:CC FLAGS_REG))]
5829 "TARGET_PARTIAL_REG_STALL
5830 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5832 switch (get_attr_type (insn))
5835 if (operands[2] == const1_rtx)
5836 return "inc{w}\t%0";
5839 gcc_assert (operands[2] == constm1_rtx);
5840 return "dec{w}\t%0";
5844 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5845 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5846 if (GET_CODE (operands[2]) == CONST_INT
5847 && (INTVAL (operands[2]) == 128
5848 || (INTVAL (operands[2]) < 0
5849 && INTVAL (operands[2]) != -128)))
5851 operands[2] = GEN_INT (-INTVAL (operands[2]));
5852 return "sub{w}\t{%2, %0|%0, %2}";
5854 return "add{w}\t{%2, %0|%0, %2}";
5858 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5859 (const_string "incdec")
5860 (const_string "alu")))
5861 (set_attr "mode" "HI")])
5863 (define_insn "*addhi_2"
5864 [(set (reg FLAGS_REG)
5866 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5867 (match_operand:HI 2 "general_operand" "rmni,rni"))
5869 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5870 (plus:HI (match_dup 1) (match_dup 2)))]
5871 "ix86_match_ccmode (insn, CCGOCmode)
5872 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5874 switch (get_attr_type (insn))
5877 if (operands[2] == const1_rtx)
5878 return "inc{w}\t%0";
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return "dec{w}\t%0";
5886 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5887 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5888 if (GET_CODE (operands[2]) == CONST_INT
5889 && (INTVAL (operands[2]) == 128
5890 || (INTVAL (operands[2]) < 0
5891 && INTVAL (operands[2]) != -128)))
5893 operands[2] = GEN_INT (-INTVAL (operands[2]));
5894 return "sub{w}\t{%2, %0|%0, %2}";
5896 return "add{w}\t{%2, %0|%0, %2}";
5900 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set_attr "mode" "HI")])
5905 (define_insn "*addhi_3"
5906 [(set (reg FLAGS_REG)
5907 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5908 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5909 (clobber (match_scratch:HI 0 "=r"))]
5910 "ix86_match_ccmode (insn, CCZmode)
5911 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5913 switch (get_attr_type (insn))
5916 if (operands[2] == const1_rtx)
5917 return "inc{w}\t%0";
5920 gcc_assert (operands[2] == constm1_rtx);
5921 return "dec{w}\t%0";
5925 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5926 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5927 if (GET_CODE (operands[2]) == CONST_INT
5928 && (INTVAL (operands[2]) == 128
5929 || (INTVAL (operands[2]) < 0
5930 && INTVAL (operands[2]) != -128)))
5932 operands[2] = GEN_INT (-INTVAL (operands[2]));
5933 return "sub{w}\t{%2, %0|%0, %2}";
5935 return "add{w}\t{%2, %0|%0, %2}";
5939 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5940 (const_string "incdec")
5941 (const_string "alu")))
5942 (set_attr "mode" "HI")])
5944 ; See comments above addsi_4 for details.
5945 (define_insn "*addhi_4"
5946 [(set (reg FLAGS_REG)
5947 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5948 (match_operand:HI 2 "const_int_operand" "n")))
5949 (clobber (match_scratch:HI 0 "=rm"))]
5950 "ix86_match_ccmode (insn, CCGCmode)
5951 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5953 switch (get_attr_type (insn))
5956 if (operands[2] == constm1_rtx)
5957 return "inc{w}\t%0";
5960 gcc_assert (operands[2] == const1_rtx);
5961 return "dec{w}\t%0";
5965 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5966 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5967 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5968 if ((INTVAL (operands[2]) == -128
5969 || (INTVAL (operands[2]) > 0
5970 && INTVAL (operands[2]) != 128)))
5971 return "sub{w}\t{%2, %0|%0, %2}";
5972 operands[2] = GEN_INT (-INTVAL (operands[2]));
5973 return "add{w}\t{%2, %0|%0, %2}";
5977 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5978 (const_string "incdec")
5979 (const_string "alu")))
5980 (set_attr "mode" "SI")])
5983 (define_insn "*addhi_5"
5984 [(set (reg FLAGS_REG)
5986 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5987 (match_operand:HI 2 "general_operand" "rmni"))
5989 (clobber (match_scratch:HI 0 "=r"))]
5990 "ix86_match_ccmode (insn, CCGOCmode)
5991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5993 switch (get_attr_type (insn))
5996 if (operands[2] == const1_rtx)
5997 return "inc{w}\t%0";
6000 gcc_assert (operands[2] == constm1_rtx);
6001 return "dec{w}\t%0";
6005 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6006 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6007 if (GET_CODE (operands[2]) == CONST_INT
6008 && (INTVAL (operands[2]) == 128
6009 || (INTVAL (operands[2]) < 0
6010 && INTVAL (operands[2]) != -128)))
6012 operands[2] = GEN_INT (-INTVAL (operands[2]));
6013 return "sub{w}\t{%2, %0|%0, %2}";
6015 return "add{w}\t{%2, %0|%0, %2}";
6019 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6020 (const_string "incdec")
6021 (const_string "alu")))
6022 (set_attr "mode" "HI")])
6024 (define_expand "addqi3"
6025 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6026 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6027 (match_operand:QI 2 "general_operand" "")))
6028 (clobber (reg:CC FLAGS_REG))])]
6029 "TARGET_QIMODE_MATH"
6030 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6032 ;; %%% Potential partial reg stall on alternative 2. What to do?
6033 (define_insn "*addqi_1_lea"
6034 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6035 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6036 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6037 (clobber (reg:CC FLAGS_REG))]
6038 "!TARGET_PARTIAL_REG_STALL
6039 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6041 int widen = (which_alternative == 2);
6042 switch (get_attr_type (insn))
6047 if (operands[2] == const1_rtx)
6048 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6051 gcc_assert (operands[2] == constm1_rtx);
6052 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6056 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6057 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6058 if (GET_CODE (operands[2]) == CONST_INT
6059 && (INTVAL (operands[2]) == 128
6060 || (INTVAL (operands[2]) < 0
6061 && INTVAL (operands[2]) != -128)))
6063 operands[2] = GEN_INT (-INTVAL (operands[2]));
6065 return "sub{l}\t{%2, %k0|%k0, %2}";
6067 return "sub{b}\t{%2, %0|%0, %2}";
6070 return "add{l}\t{%k2, %k0|%k0, %k2}";
6072 return "add{b}\t{%2, %0|%0, %2}";
6076 (if_then_else (eq_attr "alternative" "3")
6077 (const_string "lea")
6078 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6079 (const_string "incdec")
6080 (const_string "alu"))))
6081 (set_attr "mode" "QI,QI,SI,SI")])
6083 (define_insn "*addqi_1"
6084 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6085 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6086 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6087 (clobber (reg:CC FLAGS_REG))]
6088 "TARGET_PARTIAL_REG_STALL
6089 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6091 int widen = (which_alternative == 2);
6092 switch (get_attr_type (insn))
6095 if (operands[2] == const1_rtx)
6096 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6099 gcc_assert (operands[2] == constm1_rtx);
6100 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6104 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6105 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6106 if (GET_CODE (operands[2]) == CONST_INT
6107 && (INTVAL (operands[2]) == 128
6108 || (INTVAL (operands[2]) < 0
6109 && INTVAL (operands[2]) != -128)))
6111 operands[2] = GEN_INT (-INTVAL (operands[2]));
6113 return "sub{l}\t{%2, %k0|%k0, %2}";
6115 return "sub{b}\t{%2, %0|%0, %2}";
6118 return "add{l}\t{%k2, %k0|%k0, %k2}";
6120 return "add{b}\t{%2, %0|%0, %2}";
6124 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6125 (const_string "incdec")
6126 (const_string "alu")))
6127 (set_attr "mode" "QI,QI,SI")])
6129 (define_insn "*addqi_1_slp"
6130 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6131 (plus:QI (match_dup 0)
6132 (match_operand:QI 1 "general_operand" "qn,qnm")))
6133 (clobber (reg:CC FLAGS_REG))]
6134 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6135 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6137 switch (get_attr_type (insn))
6140 if (operands[1] == const1_rtx)
6141 return "inc{b}\t%0";
6144 gcc_assert (operands[1] == constm1_rtx);
6145 return "dec{b}\t%0";
6149 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6150 if (GET_CODE (operands[1]) == CONST_INT
6151 && INTVAL (operands[1]) < 0)
6153 operands[1] = GEN_INT (-INTVAL (operands[1]));
6154 return "sub{b}\t{%1, %0|%0, %1}";
6156 return "add{b}\t{%1, %0|%0, %1}";
6160 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6161 (const_string "incdec")
6162 (const_string "alu1")))
6163 (set (attr "memory")
6164 (if_then_else (match_operand 1 "memory_operand" "")
6165 (const_string "load")
6166 (const_string "none")))
6167 (set_attr "mode" "QI")])
6169 (define_insn "*addqi_2"
6170 [(set (reg FLAGS_REG)
6172 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6173 (match_operand:QI 2 "general_operand" "qmni,qni"))
6175 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6176 (plus:QI (match_dup 1) (match_dup 2)))]
6177 "ix86_match_ccmode (insn, CCGOCmode)
6178 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6180 switch (get_attr_type (insn))
6183 if (operands[2] == const1_rtx)
6184 return "inc{b}\t%0";
6187 gcc_assert (operands[2] == constm1_rtx
6188 || (GET_CODE (operands[2]) == CONST_INT
6189 && INTVAL (operands[2]) == 255));
6190 return "dec{b}\t%0";
6194 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6195 if (GET_CODE (operands[2]) == CONST_INT
6196 && INTVAL (operands[2]) < 0)
6198 operands[2] = GEN_INT (-INTVAL (operands[2]));
6199 return "sub{b}\t{%2, %0|%0, %2}";
6201 return "add{b}\t{%2, %0|%0, %2}";
6205 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6206 (const_string "incdec")
6207 (const_string "alu")))
6208 (set_attr "mode" "QI")])
6210 (define_insn "*addqi_3"
6211 [(set (reg FLAGS_REG)
6212 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6213 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6214 (clobber (match_scratch:QI 0 "=q"))]
6215 "ix86_match_ccmode (insn, CCZmode)
6216 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6218 switch (get_attr_type (insn))
6221 if (operands[2] == const1_rtx)
6222 return "inc{b}\t%0";
6225 gcc_assert (operands[2] == constm1_rtx
6226 || (GET_CODE (operands[2]) == CONST_INT
6227 && INTVAL (operands[2]) == 255));
6228 return "dec{b}\t%0";
6232 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6233 if (GET_CODE (operands[2]) == CONST_INT
6234 && INTVAL (operands[2]) < 0)
6236 operands[2] = GEN_INT (-INTVAL (operands[2]));
6237 return "sub{b}\t{%2, %0|%0, %2}";
6239 return "add{b}\t{%2, %0|%0, %2}";
6243 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6244 (const_string "incdec")
6245 (const_string "alu")))
6246 (set_attr "mode" "QI")])
6248 ; See comments above addsi_4 for details.
6249 (define_insn "*addqi_4"
6250 [(set (reg FLAGS_REG)
6251 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6252 (match_operand:QI 2 "const_int_operand" "n")))
6253 (clobber (match_scratch:QI 0 "=qm"))]
6254 "ix86_match_ccmode (insn, CCGCmode)
6255 && (INTVAL (operands[2]) & 0xff) != 0x80"
6257 switch (get_attr_type (insn))
6260 if (operands[2] == constm1_rtx
6261 || (GET_CODE (operands[2]) == CONST_INT
6262 && INTVAL (operands[2]) == 255))
6263 return "inc{b}\t%0";
6266 gcc_assert (operands[2] == const1_rtx);
6267 return "dec{b}\t%0";
6271 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6272 if (INTVAL (operands[2]) < 0)
6274 operands[2] = GEN_INT (-INTVAL (operands[2]));
6275 return "add{b}\t{%2, %0|%0, %2}";
6277 return "sub{b}\t{%2, %0|%0, %2}";
6281 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6282 (const_string "incdec")
6283 (const_string "alu")))
6284 (set_attr "mode" "QI")])
6287 (define_insn "*addqi_5"
6288 [(set (reg FLAGS_REG)
6290 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6291 (match_operand:QI 2 "general_operand" "qmni"))
6293 (clobber (match_scratch:QI 0 "=q"))]
6294 "ix86_match_ccmode (insn, CCGOCmode)
6295 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6297 switch (get_attr_type (insn))
6300 if (operands[2] == const1_rtx)
6301 return "inc{b}\t%0";
6304 gcc_assert (operands[2] == constm1_rtx
6305 || (GET_CODE (operands[2]) == CONST_INT
6306 && INTVAL (operands[2]) == 255));
6307 return "dec{b}\t%0";
6311 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6312 if (GET_CODE (operands[2]) == CONST_INT
6313 && INTVAL (operands[2]) < 0)
6315 operands[2] = GEN_INT (-INTVAL (operands[2]));
6316 return "sub{b}\t{%2, %0|%0, %2}";
6318 return "add{b}\t{%2, %0|%0, %2}";
6322 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6323 (const_string "incdec")
6324 (const_string "alu")))
6325 (set_attr "mode" "QI")])
6328 (define_insn "addqi_ext_1"
6329 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6334 (match_operand 1 "ext_register_operand" "0")
6337 (match_operand:QI 2 "general_operand" "Qmn")))
6338 (clobber (reg:CC FLAGS_REG))]
6341 switch (get_attr_type (insn))
6344 if (operands[2] == const1_rtx)
6345 return "inc{b}\t%h0";
6348 gcc_assert (operands[2] == constm1_rtx
6349 || (GET_CODE (operands[2]) == CONST_INT
6350 && INTVAL (operands[2]) == 255));
6351 return "dec{b}\t%h0";
6355 return "add{b}\t{%2, %h0|%h0, %2}";
6359 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6360 (const_string "incdec")
6361 (const_string "alu")))
6362 (set_attr "mode" "QI")])
6364 (define_insn "*addqi_ext_1_rex64"
6365 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6370 (match_operand 1 "ext_register_operand" "0")
6373 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6374 (clobber (reg:CC FLAGS_REG))]
6377 switch (get_attr_type (insn))
6380 if (operands[2] == const1_rtx)
6381 return "inc{b}\t%h0";
6384 gcc_assert (operands[2] == constm1_rtx
6385 || (GET_CODE (operands[2]) == CONST_INT
6386 && INTVAL (operands[2]) == 255));
6387 return "dec{b}\t%h0";
6391 return "add{b}\t{%2, %h0|%h0, %2}";
6395 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6396 (const_string "incdec")
6397 (const_string "alu")))
6398 (set_attr "mode" "QI")])
6400 (define_insn "*addqi_ext_2"
6401 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6406 (match_operand 1 "ext_register_operand" "%0")
6410 (match_operand 2 "ext_register_operand" "Q")
6413 (clobber (reg:CC FLAGS_REG))]
6415 "add{b}\t{%h2, %h0|%h0, %h2}"
6416 [(set_attr "type" "alu")
6417 (set_attr "mode" "QI")])
6419 ;; The patterns that match these are at the end of this file.
6421 (define_expand "addxf3"
6422 [(set (match_operand:XF 0 "register_operand" "")
6423 (plus:XF (match_operand:XF 1 "register_operand" "")
6424 (match_operand:XF 2 "register_operand" "")))]
6428 (define_expand "adddf3"
6429 [(set (match_operand:DF 0 "register_operand" "")
6430 (plus:DF (match_operand:DF 1 "register_operand" "")
6431 (match_operand:DF 2 "nonimmediate_operand" "")))]
6432 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6435 (define_expand "addsf3"
6436 [(set (match_operand:SF 0 "register_operand" "")
6437 (plus:SF (match_operand:SF 1 "register_operand" "")
6438 (match_operand:SF 2 "nonimmediate_operand" "")))]
6439 "TARGET_80387 || TARGET_SSE_MATH"
6442 ;; Subtract instructions
6444 ;; %%% splits for subditi3
6446 (define_expand "subti3"
6447 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6448 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6449 (match_operand:TI 2 "x86_64_general_operand" "")))
6450 (clobber (reg:CC FLAGS_REG))])]
6452 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6454 (define_insn "*subti3_1"
6455 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6456 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6457 (match_operand:TI 2 "general_operand" "roiF,riF")))
6458 (clobber (reg:CC FLAGS_REG))]
6459 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6463 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6464 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6465 (match_operand:TI 2 "general_operand" "")))
6466 (clobber (reg:CC FLAGS_REG))]
6467 "TARGET_64BIT && reload_completed"
6468 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6469 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6470 (parallel [(set (match_dup 3)
6471 (minus:DI (match_dup 4)
6472 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6474 (clobber (reg:CC FLAGS_REG))])]
6475 "split_ti (operands+0, 1, operands+0, operands+3);
6476 split_ti (operands+1, 1, operands+1, operands+4);
6477 split_ti (operands+2, 1, operands+2, operands+5);")
6479 ;; %%% splits for subsidi3
6481 (define_expand "subdi3"
6482 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6483 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6484 (match_operand:DI 2 "x86_64_general_operand" "")))
6485 (clobber (reg:CC FLAGS_REG))])]
6487 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6489 (define_insn "*subdi3_1"
6490 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6491 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6492 (match_operand:DI 2 "general_operand" "roiF,riF")))
6493 (clobber (reg:CC FLAGS_REG))]
6494 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6498 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6499 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6500 (match_operand:DI 2 "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:SI (match_dup 1) (match_dup 2)))])
6505 (parallel [(set (match_dup 3)
6506 (minus:SI (match_dup 4)
6507 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6509 (clobber (reg:CC FLAGS_REG))])]
6510 "split_di (operands+0, 1, operands+0, operands+3);
6511 split_di (operands+1, 1, operands+1, operands+4);
6512 split_di (operands+2, 1, operands+2, operands+5);")
6514 (define_insn "subdi3_carry_rex64"
6515 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6516 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6517 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6518 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6519 (clobber (reg:CC FLAGS_REG))]
6520 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6521 "sbb{q}\t{%2, %0|%0, %2}"
6522 [(set_attr "type" "alu")
6523 (set_attr "pent_pair" "pu")
6524 (set_attr "mode" "DI")])
6526 (define_insn "*subdi_1_rex64"
6527 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6528 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6529 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6530 (clobber (reg:CC FLAGS_REG))]
6531 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6532 "sub{q}\t{%2, %0|%0, %2}"
6533 [(set_attr "type" "alu")
6534 (set_attr "mode" "DI")])
6536 (define_insn "*subdi_2_rex64"
6537 [(set (reg FLAGS_REG)
6539 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6540 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6542 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6543 (minus:DI (match_dup 1) (match_dup 2)))]
6544 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6545 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6546 "sub{q}\t{%2, %0|%0, %2}"
6547 [(set_attr "type" "alu")
6548 (set_attr "mode" "DI")])
6550 (define_insn "*subdi_3_rex63"
6551 [(set (reg FLAGS_REG)
6552 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6553 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6554 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6555 (minus:DI (match_dup 1) (match_dup 2)))]
6556 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6557 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6558 "sub{q}\t{%2, %0|%0, %2}"
6559 [(set_attr "type" "alu")
6560 (set_attr "mode" "DI")])
6562 (define_insn "subqi3_carry"
6563 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6564 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6565 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6566 (match_operand:QI 2 "general_operand" "qi,qm"))))
6567 (clobber (reg:CC FLAGS_REG))]
6568 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6569 "sbb{b}\t{%2, %0|%0, %2}"
6570 [(set_attr "type" "alu")
6571 (set_attr "pent_pair" "pu")
6572 (set_attr "mode" "QI")])
6574 (define_insn "subhi3_carry"
6575 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6576 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6577 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6578 (match_operand:HI 2 "general_operand" "ri,rm"))))
6579 (clobber (reg:CC FLAGS_REG))]
6580 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6581 "sbb{w}\t{%2, %0|%0, %2}"
6582 [(set_attr "type" "alu")
6583 (set_attr "pent_pair" "pu")
6584 (set_attr "mode" "HI")])
6586 (define_insn "subsi3_carry"
6587 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6588 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6589 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6590 (match_operand:SI 2 "general_operand" "ri,rm"))))
6591 (clobber (reg:CC FLAGS_REG))]
6592 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6593 "sbb{l}\t{%2, %0|%0, %2}"
6594 [(set_attr "type" "alu")
6595 (set_attr "pent_pair" "pu")
6596 (set_attr "mode" "SI")])
6598 (define_insn "subsi3_carry_zext"
6599 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6601 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6602 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6603 (match_operand:SI 2 "general_operand" "ri,rm")))))
6604 (clobber (reg:CC FLAGS_REG))]
6605 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6606 "sbb{l}\t{%2, %k0|%k0, %2}"
6607 [(set_attr "type" "alu")
6608 (set_attr "pent_pair" "pu")
6609 (set_attr "mode" "SI")])
6611 (define_expand "subsi3"
6612 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6613 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6614 (match_operand:SI 2 "general_operand" "")))
6615 (clobber (reg:CC FLAGS_REG))])]
6617 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6619 (define_insn "*subsi_1"
6620 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6621 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6622 (match_operand:SI 2 "general_operand" "ri,rm")))
6623 (clobber (reg:CC FLAGS_REG))]
6624 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6625 "sub{l}\t{%2, %0|%0, %2}"
6626 [(set_attr "type" "alu")
6627 (set_attr "mode" "SI")])
6629 (define_insn "*subsi_1_zext"
6630 [(set (match_operand:DI 0 "register_operand" "=r")
6632 (minus:SI (match_operand:SI 1 "register_operand" "0")
6633 (match_operand:SI 2 "general_operand" "rim"))))
6634 (clobber (reg:CC FLAGS_REG))]
6635 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6636 "sub{l}\t{%2, %k0|%k0, %2}"
6637 [(set_attr "type" "alu")
6638 (set_attr "mode" "SI")])
6640 (define_insn "*subsi_2"
6641 [(set (reg FLAGS_REG)
6643 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6644 (match_operand:SI 2 "general_operand" "ri,rm"))
6646 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6647 (minus:SI (match_dup 1) (match_dup 2)))]
6648 "ix86_match_ccmode (insn, CCGOCmode)
6649 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650 "sub{l}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "mode" "SI")])
6654 (define_insn "*subsi_2_zext"
6655 [(set (reg FLAGS_REG)
6657 (minus:SI (match_operand:SI 1 "register_operand" "0")
6658 (match_operand:SI 2 "general_operand" "rim"))
6660 (set (match_operand:DI 0 "register_operand" "=r")
6662 (minus:SI (match_dup 1)
6664 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6665 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6666 "sub{l}\t{%2, %k0|%k0, %2}"
6667 [(set_attr "type" "alu")
6668 (set_attr "mode" "SI")])
6670 (define_insn "*subsi_3"
6671 [(set (reg FLAGS_REG)
6672 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673 (match_operand:SI 2 "general_operand" "ri,rm")))
6674 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6675 (minus:SI (match_dup 1) (match_dup 2)))]
6676 "ix86_match_ccmode (insn, CCmode)
6677 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6678 "sub{l}\t{%2, %0|%0, %2}"
6679 [(set_attr "type" "alu")
6680 (set_attr "mode" "SI")])
6682 (define_insn "*subsi_3_zext"
6683 [(set (reg FLAGS_REG)
6684 (compare (match_operand:SI 1 "register_operand" "0")
6685 (match_operand:SI 2 "general_operand" "rim")))
6686 (set (match_operand:DI 0 "register_operand" "=r")
6688 (minus:SI (match_dup 1)
6690 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6691 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6692 "sub{q}\t{%2, %0|%0, %2}"
6693 [(set_attr "type" "alu")
6694 (set_attr "mode" "DI")])
6696 (define_expand "subhi3"
6697 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6698 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6699 (match_operand:HI 2 "general_operand" "")))
6700 (clobber (reg:CC FLAGS_REG))])]
6701 "TARGET_HIMODE_MATH"
6702 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6704 (define_insn "*subhi_1"
6705 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6706 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6707 (match_operand:HI 2 "general_operand" "ri,rm")))
6708 (clobber (reg:CC FLAGS_REG))]
6709 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6710 "sub{w}\t{%2, %0|%0, %2}"
6711 [(set_attr "type" "alu")
6712 (set_attr "mode" "HI")])
6714 (define_insn "*subhi_2"
6715 [(set (reg FLAGS_REG)
6717 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6718 (match_operand:HI 2 "general_operand" "ri,rm"))
6720 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6721 (minus:HI (match_dup 1) (match_dup 2)))]
6722 "ix86_match_ccmode (insn, CCGOCmode)
6723 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6724 "sub{w}\t{%2, %0|%0, %2}"
6725 [(set_attr "type" "alu")
6726 (set_attr "mode" "HI")])
6728 (define_insn "*subhi_3"
6729 [(set (reg FLAGS_REG)
6730 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6731 (match_operand:HI 2 "general_operand" "ri,rm")))
6732 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6733 (minus:HI (match_dup 1) (match_dup 2)))]
6734 "ix86_match_ccmode (insn, CCmode)
6735 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6736 "sub{w}\t{%2, %0|%0, %2}"
6737 [(set_attr "type" "alu")
6738 (set_attr "mode" "HI")])
6740 (define_expand "subqi3"
6741 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6742 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6743 (match_operand:QI 2 "general_operand" "")))
6744 (clobber (reg:CC FLAGS_REG))])]
6745 "TARGET_QIMODE_MATH"
6746 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6748 (define_insn "*subqi_1"
6749 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6750 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6751 (match_operand:QI 2 "general_operand" "qn,qmn")))
6752 (clobber (reg:CC FLAGS_REG))]
6753 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6754 "sub{b}\t{%2, %0|%0, %2}"
6755 [(set_attr "type" "alu")
6756 (set_attr "mode" "QI")])
6758 (define_insn "*subqi_1_slp"
6759 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6760 (minus:QI (match_dup 0)
6761 (match_operand:QI 1 "general_operand" "qn,qmn")))
6762 (clobber (reg:CC FLAGS_REG))]
6763 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6764 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6765 "sub{b}\t{%1, %0|%0, %1}"
6766 [(set_attr "type" "alu1")
6767 (set_attr "mode" "QI")])
6769 (define_insn "*subqi_2"
6770 [(set (reg FLAGS_REG)
6772 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6773 (match_operand:QI 2 "general_operand" "qi,qm"))
6775 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6776 (minus:HI (match_dup 1) (match_dup 2)))]
6777 "ix86_match_ccmode (insn, CCGOCmode)
6778 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6779 "sub{b}\t{%2, %0|%0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "QI")])
6783 (define_insn "*subqi_3"
6784 [(set (reg FLAGS_REG)
6785 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6786 (match_operand:QI 2 "general_operand" "qi,qm")))
6787 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6788 (minus:HI (match_dup 1) (match_dup 2)))]
6789 "ix86_match_ccmode (insn, CCmode)
6790 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6791 "sub{b}\t{%2, %0|%0, %2}"
6792 [(set_attr "type" "alu")
6793 (set_attr "mode" "QI")])
6795 ;; The patterns that match these are at the end of this file.
6797 (define_expand "subxf3"
6798 [(set (match_operand:XF 0 "register_operand" "")
6799 (minus:XF (match_operand:XF 1 "register_operand" "")
6800 (match_operand:XF 2 "register_operand" "")))]
6804 (define_expand "subdf3"
6805 [(set (match_operand:DF 0 "register_operand" "")
6806 (minus:DF (match_operand:DF 1 "register_operand" "")
6807 (match_operand:DF 2 "nonimmediate_operand" "")))]
6808 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6811 (define_expand "subsf3"
6812 [(set (match_operand:SF 0 "register_operand" "")
6813 (minus:SF (match_operand:SF 1 "register_operand" "")
6814 (match_operand:SF 2 "nonimmediate_operand" "")))]
6815 "TARGET_80387 || TARGET_SSE_MATH"
6818 ;; Multiply instructions
6820 (define_expand "muldi3"
6821 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6822 (mult:DI (match_operand:DI 1 "register_operand" "")
6823 (match_operand:DI 2 "x86_64_general_operand" "")))
6824 (clobber (reg:CC FLAGS_REG))])]
6828 (define_insn "*muldi3_1_rex64"
6829 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6830 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6831 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6832 (clobber (reg:CC FLAGS_REG))]
6834 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6836 imul{q}\t{%2, %1, %0|%0, %1, %2}
6837 imul{q}\t{%2, %1, %0|%0, %1, %2}
6838 imul{q}\t{%2, %0|%0, %2}"
6839 [(set_attr "type" "imul")
6840 (set_attr "prefix_0f" "0,0,1")
6841 (set (attr "athlon_decode")
6842 (cond [(eq_attr "cpu" "athlon")
6843 (const_string "vector")
6844 (eq_attr "alternative" "1")
6845 (const_string "vector")
6846 (and (eq_attr "alternative" "2")
6847 (match_operand 1 "memory_operand" ""))
6848 (const_string "vector")]
6849 (const_string "direct")))
6850 (set_attr "mode" "DI")])
6852 (define_expand "mulsi3"
6853 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6854 (mult:SI (match_operand:SI 1 "register_operand" "")
6855 (match_operand:SI 2 "general_operand" "")))
6856 (clobber (reg:CC FLAGS_REG))])]
6860 (define_insn "*mulsi3_1"
6861 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6862 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6863 (match_operand:SI 2 "general_operand" "K,i,mr")))
6864 (clobber (reg:CC FLAGS_REG))]
6865 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6867 imul{l}\t{%2, %1, %0|%0, %1, %2}
6868 imul{l}\t{%2, %1, %0|%0, %1, %2}
6869 imul{l}\t{%2, %0|%0, %2}"
6870 [(set_attr "type" "imul")
6871 (set_attr "prefix_0f" "0,0,1")
6872 (set (attr "athlon_decode")
6873 (cond [(eq_attr "cpu" "athlon")
6874 (const_string "vector")
6875 (eq_attr "alternative" "1")
6876 (const_string "vector")
6877 (and (eq_attr "alternative" "2")
6878 (match_operand 1 "memory_operand" ""))
6879 (const_string "vector")]
6880 (const_string "direct")))
6881 (set_attr "mode" "SI")])
6883 (define_insn "*mulsi3_1_zext"
6884 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6886 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6887 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6888 (clobber (reg:CC FLAGS_REG))]
6890 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6892 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6893 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6894 imul{l}\t{%2, %k0|%k0, %2}"
6895 [(set_attr "type" "imul")
6896 (set_attr "prefix_0f" "0,0,1")
6897 (set (attr "athlon_decode")
6898 (cond [(eq_attr "cpu" "athlon")
6899 (const_string "vector")
6900 (eq_attr "alternative" "1")
6901 (const_string "vector")
6902 (and (eq_attr "alternative" "2")
6903 (match_operand 1 "memory_operand" ""))
6904 (const_string "vector")]
6905 (const_string "direct")))
6906 (set_attr "mode" "SI")])
6908 (define_expand "mulhi3"
6909 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6910 (mult:HI (match_operand:HI 1 "register_operand" "")
6911 (match_operand:HI 2 "general_operand" "")))
6912 (clobber (reg:CC FLAGS_REG))])]
6913 "TARGET_HIMODE_MATH"
6916 (define_insn "*mulhi3_1"
6917 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6918 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6919 (match_operand:HI 2 "general_operand" "K,i,mr")))
6920 (clobber (reg:CC FLAGS_REG))]
6921 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6923 imul{w}\t{%2, %1, %0|%0, %1, %2}
6924 imul{w}\t{%2, %1, %0|%0, %1, %2}
6925 imul{w}\t{%2, %0|%0, %2}"
6926 [(set_attr "type" "imul")
6927 (set_attr "prefix_0f" "0,0,1")
6928 (set (attr "athlon_decode")
6929 (cond [(eq_attr "cpu" "athlon")
6930 (const_string "vector")
6931 (eq_attr "alternative" "1,2")
6932 (const_string "vector")]
6933 (const_string "direct")))
6934 (set_attr "mode" "HI")])
6936 (define_expand "mulqi3"
6937 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6938 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6939 (match_operand:QI 2 "register_operand" "")))
6940 (clobber (reg:CC FLAGS_REG))])]
6941 "TARGET_QIMODE_MATH"
6944 (define_insn "*mulqi3_1"
6945 [(set (match_operand:QI 0 "register_operand" "=a")
6946 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6947 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6948 (clobber (reg:CC FLAGS_REG))]
6950 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6952 [(set_attr "type" "imul")
6953 (set_attr "length_immediate" "0")
6954 (set (attr "athlon_decode")
6955 (if_then_else (eq_attr "cpu" "athlon")
6956 (const_string "vector")
6957 (const_string "direct")))
6958 (set_attr "mode" "QI")])
6960 (define_expand "umulqihi3"
6961 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6962 (mult:HI (zero_extend:HI
6963 (match_operand:QI 1 "nonimmediate_operand" ""))
6965 (match_operand:QI 2 "register_operand" ""))))
6966 (clobber (reg:CC FLAGS_REG))])]
6967 "TARGET_QIMODE_MATH"
6970 (define_insn "*umulqihi3_1"
6971 [(set (match_operand:HI 0 "register_operand" "=a")
6972 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6973 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6974 (clobber (reg:CC FLAGS_REG))]
6976 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6978 [(set_attr "type" "imul")
6979 (set_attr "length_immediate" "0")
6980 (set (attr "athlon_decode")
6981 (if_then_else (eq_attr "cpu" "athlon")
6982 (const_string "vector")
6983 (const_string "direct")))
6984 (set_attr "mode" "QI")])
6986 (define_expand "mulqihi3"
6987 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6988 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6989 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6990 (clobber (reg:CC FLAGS_REG))])]
6991 "TARGET_QIMODE_MATH"
6994 (define_insn "*mulqihi3_insn"
6995 [(set (match_operand:HI 0 "register_operand" "=a")
6996 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6997 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6998 (clobber (reg:CC FLAGS_REG))]
7000 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7002 [(set_attr "type" "imul")
7003 (set_attr "length_immediate" "0")
7004 (set (attr "athlon_decode")
7005 (if_then_else (eq_attr "cpu" "athlon")
7006 (const_string "vector")
7007 (const_string "direct")))
7008 (set_attr "mode" "QI")])
7010 (define_expand "umulditi3"
7011 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7012 (mult:TI (zero_extend:TI
7013 (match_operand:DI 1 "nonimmediate_operand" ""))
7015 (match_operand:DI 2 "register_operand" ""))))
7016 (clobber (reg:CC FLAGS_REG))])]
7020 (define_insn "*umulditi3_insn"
7021 [(set (match_operand:TI 0 "register_operand" "=A")
7022 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7023 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7024 (clobber (reg:CC FLAGS_REG))]
7026 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7028 [(set_attr "type" "imul")
7029 (set_attr "length_immediate" "0")
7030 (set (attr "athlon_decode")
7031 (if_then_else (eq_attr "cpu" "athlon")
7032 (const_string "vector")
7033 (const_string "double")))
7034 (set_attr "mode" "DI")])
7036 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7037 (define_expand "umulsidi3"
7038 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7039 (mult:DI (zero_extend:DI
7040 (match_operand:SI 1 "nonimmediate_operand" ""))
7042 (match_operand:SI 2 "register_operand" ""))))
7043 (clobber (reg:CC FLAGS_REG))])]
7047 (define_insn "*umulsidi3_insn"
7048 [(set (match_operand:DI 0 "register_operand" "=A")
7049 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7050 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7051 (clobber (reg:CC FLAGS_REG))]
7053 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7055 [(set_attr "type" "imul")
7056 (set_attr "length_immediate" "0")
7057 (set (attr "athlon_decode")
7058 (if_then_else (eq_attr "cpu" "athlon")
7059 (const_string "vector")
7060 (const_string "double")))
7061 (set_attr "mode" "SI")])
7063 (define_expand "mulditi3"
7064 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7065 (mult:TI (sign_extend:TI
7066 (match_operand:DI 1 "nonimmediate_operand" ""))
7068 (match_operand:DI 2 "register_operand" ""))))
7069 (clobber (reg:CC FLAGS_REG))])]
7073 (define_insn "*mulditi3_insn"
7074 [(set (match_operand:TI 0 "register_operand" "=A")
7075 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7076 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7077 (clobber (reg:CC FLAGS_REG))]
7079 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7081 [(set_attr "type" "imul")
7082 (set_attr "length_immediate" "0")
7083 (set (attr "athlon_decode")
7084 (if_then_else (eq_attr "cpu" "athlon")
7085 (const_string "vector")
7086 (const_string "double")))
7087 (set_attr "mode" "DI")])
7089 (define_expand "mulsidi3"
7090 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7091 (mult:DI (sign_extend:DI
7092 (match_operand:SI 1 "nonimmediate_operand" ""))
7094 (match_operand:SI 2 "register_operand" ""))))
7095 (clobber (reg:CC FLAGS_REG))])]
7099 (define_insn "*mulsidi3_insn"
7100 [(set (match_operand:DI 0 "register_operand" "=A")
7101 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7102 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7103 (clobber (reg:CC FLAGS_REG))]
7105 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7107 [(set_attr "type" "imul")
7108 (set_attr "length_immediate" "0")
7109 (set (attr "athlon_decode")
7110 (if_then_else (eq_attr "cpu" "athlon")
7111 (const_string "vector")
7112 (const_string "double")))
7113 (set_attr "mode" "SI")])
7115 (define_expand "umuldi3_highpart"
7116 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7119 (mult:TI (zero_extend:TI
7120 (match_operand:DI 1 "nonimmediate_operand" ""))
7122 (match_operand:DI 2 "register_operand" "")))
7124 (clobber (match_scratch:DI 3 ""))
7125 (clobber (reg:CC FLAGS_REG))])]
7129 (define_insn "*umuldi3_highpart_rex64"
7130 [(set (match_operand:DI 0 "register_operand" "=d")
7133 (mult:TI (zero_extend:TI
7134 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7136 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7138 (clobber (match_scratch:DI 3 "=1"))
7139 (clobber (reg:CC FLAGS_REG))]
7141 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7143 [(set_attr "type" "imul")
7144 (set_attr "length_immediate" "0")
7145 (set (attr "athlon_decode")
7146 (if_then_else (eq_attr "cpu" "athlon")
7147 (const_string "vector")
7148 (const_string "double")))
7149 (set_attr "mode" "DI")])
7151 (define_expand "umulsi3_highpart"
7152 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7155 (mult:DI (zero_extend:DI
7156 (match_operand:SI 1 "nonimmediate_operand" ""))
7158 (match_operand:SI 2 "register_operand" "")))
7160 (clobber (match_scratch:SI 3 ""))
7161 (clobber (reg:CC FLAGS_REG))])]
7165 (define_insn "*umulsi3_highpart_insn"
7166 [(set (match_operand:SI 0 "register_operand" "=d")
7169 (mult:DI (zero_extend:DI
7170 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7172 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7174 (clobber (match_scratch:SI 3 "=1"))
7175 (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" "SI")])
7186 (define_insn "*umulsi3_highpart_zext"
7187 [(set (match_operand:DI 0 "register_operand" "=d")
7188 (zero_extend:DI (truncate:SI
7190 (mult:DI (zero_extend:DI
7191 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7193 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7195 (clobber (match_scratch:SI 3 "=1"))
7196 (clobber (reg:CC FLAGS_REG))]
7198 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7200 [(set_attr "type" "imul")
7201 (set_attr "length_immediate" "0")
7202 (set (attr "athlon_decode")
7203 (if_then_else (eq_attr "cpu" "athlon")
7204 (const_string "vector")
7205 (const_string "double")))
7206 (set_attr "mode" "SI")])
7208 (define_expand "smuldi3_highpart"
7209 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7212 (mult:TI (sign_extend:TI
7213 (match_operand:DI 1 "nonimmediate_operand" ""))
7215 (match_operand:DI 2 "register_operand" "")))
7217 (clobber (match_scratch:DI 3 ""))
7218 (clobber (reg:CC FLAGS_REG))])]
7222 (define_insn "*smuldi3_highpart_rex64"
7223 [(set (match_operand:DI 0 "register_operand" "=d")
7226 (mult:TI (sign_extend:TI
7227 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7229 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7231 (clobber (match_scratch:DI 3 "=1"))
7232 (clobber (reg:CC FLAGS_REG))]
7234 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7236 [(set_attr "type" "imul")
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" "DI")])
7243 (define_expand "smulsi3_highpart"
7244 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7247 (mult:DI (sign_extend:DI
7248 (match_operand:SI 1 "nonimmediate_operand" ""))
7250 (match_operand:SI 2 "register_operand" "")))
7252 (clobber (match_scratch:SI 3 ""))
7253 (clobber (reg:CC FLAGS_REG))])]
7257 (define_insn "*smulsi3_highpart_insn"
7258 [(set (match_operand:SI 0 "register_operand" "=d")
7261 (mult:DI (sign_extend:DI
7262 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7264 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7266 (clobber (match_scratch:SI 3 "=1"))
7267 (clobber (reg:CC FLAGS_REG))]
7268 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7270 [(set_attr "type" "imul")
7271 (set (attr "athlon_decode")
7272 (if_then_else (eq_attr "cpu" "athlon")
7273 (const_string "vector")
7274 (const_string "double")))
7275 (set_attr "mode" "SI")])
7277 (define_insn "*smulsi3_highpart_zext"
7278 [(set (match_operand:DI 0 "register_operand" "=d")
7279 (zero_extend:DI (truncate:SI
7281 (mult:DI (sign_extend:DI
7282 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7284 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7286 (clobber (match_scratch:SI 3 "=1"))
7287 (clobber (reg:CC FLAGS_REG))]
7289 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7291 [(set_attr "type" "imul")
7292 (set (attr "athlon_decode")
7293 (if_then_else (eq_attr "cpu" "athlon")
7294 (const_string "vector")
7295 (const_string "double")))
7296 (set_attr "mode" "SI")])
7298 ;; The patterns that match these are at the end of this file.
7300 (define_expand "mulxf3"
7301 [(set (match_operand:XF 0 "register_operand" "")
7302 (mult:XF (match_operand:XF 1 "register_operand" "")
7303 (match_operand:XF 2 "register_operand" "")))]
7307 (define_expand "muldf3"
7308 [(set (match_operand:DF 0 "register_operand" "")
7309 (mult:DF (match_operand:DF 1 "register_operand" "")
7310 (match_operand:DF 2 "nonimmediate_operand" "")))]
7311 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7314 (define_expand "mulsf3"
7315 [(set (match_operand:SF 0 "register_operand" "")
7316 (mult:SF (match_operand:SF 1 "register_operand" "")
7317 (match_operand:SF 2 "nonimmediate_operand" "")))]
7318 "TARGET_80387 || TARGET_SSE_MATH"
7321 ;; Divide instructions
7323 (define_insn "divqi3"
7324 [(set (match_operand:QI 0 "register_operand" "=a")
7325 (div:QI (match_operand:HI 1 "register_operand" "0")
7326 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7327 (clobber (reg:CC FLAGS_REG))]
7328 "TARGET_QIMODE_MATH"
7330 [(set_attr "type" "idiv")
7331 (set_attr "mode" "QI")])
7333 (define_insn "udivqi3"
7334 [(set (match_operand:QI 0 "register_operand" "=a")
7335 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7336 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7337 (clobber (reg:CC FLAGS_REG))]
7338 "TARGET_QIMODE_MATH"
7340 [(set_attr "type" "idiv")
7341 (set_attr "mode" "QI")])
7343 ;; The patterns that match these are at the end of this file.
7345 (define_expand "divxf3"
7346 [(set (match_operand:XF 0 "register_operand" "")
7347 (div:XF (match_operand:XF 1 "register_operand" "")
7348 (match_operand:XF 2 "register_operand" "")))]
7352 (define_expand "divdf3"
7353 [(set (match_operand:DF 0 "register_operand" "")
7354 (div:DF (match_operand:DF 1 "register_operand" "")
7355 (match_operand:DF 2 "nonimmediate_operand" "")))]
7356 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7359 (define_expand "divsf3"
7360 [(set (match_operand:SF 0 "register_operand" "")
7361 (div:SF (match_operand:SF 1 "register_operand" "")
7362 (match_operand:SF 2 "nonimmediate_operand" "")))]
7363 "TARGET_80387 || TARGET_SSE_MATH"
7366 ;; Remainder instructions.
7368 (define_expand "divmoddi4"
7369 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7370 (div:DI (match_operand:DI 1 "register_operand" "")
7371 (match_operand:DI 2 "nonimmediate_operand" "")))
7372 (set (match_operand:DI 3 "register_operand" "")
7373 (mod:DI (match_dup 1) (match_dup 2)))
7374 (clobber (reg:CC FLAGS_REG))])]
7378 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7379 ;; Penalize eax case slightly because it results in worse scheduling
7381 (define_insn "*divmoddi4_nocltd_rex64"
7382 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7383 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7384 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7385 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7386 (mod:DI (match_dup 2) (match_dup 3)))
7387 (clobber (reg:CC FLAGS_REG))]
7388 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7390 [(set_attr "type" "multi")])
7392 (define_insn "*divmoddi4_cltd_rex64"
7393 [(set (match_operand:DI 0 "register_operand" "=a")
7394 (div:DI (match_operand:DI 2 "register_operand" "a")
7395 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7396 (set (match_operand:DI 1 "register_operand" "=&d")
7397 (mod:DI (match_dup 2) (match_dup 3)))
7398 (clobber (reg:CC FLAGS_REG))]
7399 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7401 [(set_attr "type" "multi")])
7403 (define_insn "*divmoddi_noext_rex64"
7404 [(set (match_operand:DI 0 "register_operand" "=a")
7405 (div:DI (match_operand:DI 1 "register_operand" "0")
7406 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7407 (set (match_operand:DI 3 "register_operand" "=d")
7408 (mod:DI (match_dup 1) (match_dup 2)))
7409 (use (match_operand:DI 4 "register_operand" "3"))
7410 (clobber (reg:CC FLAGS_REG))]
7413 [(set_attr "type" "idiv")
7414 (set_attr "mode" "DI")])
7417 [(set (match_operand:DI 0 "register_operand" "")
7418 (div:DI (match_operand:DI 1 "register_operand" "")
7419 (match_operand:DI 2 "nonimmediate_operand" "")))
7420 (set (match_operand:DI 3 "register_operand" "")
7421 (mod:DI (match_dup 1) (match_dup 2)))
7422 (clobber (reg:CC FLAGS_REG))]
7423 "TARGET_64BIT && reload_completed"
7424 [(parallel [(set (match_dup 3)
7425 (ashiftrt:DI (match_dup 4) (const_int 63)))
7426 (clobber (reg:CC FLAGS_REG))])
7427 (parallel [(set (match_dup 0)
7428 (div:DI (reg:DI 0) (match_dup 2)))
7430 (mod:DI (reg:DI 0) (match_dup 2)))
7432 (clobber (reg:CC FLAGS_REG))])]
7434 /* Avoid use of cltd in favor of a mov+shift. */
7435 if (!TARGET_USE_CLTD && !optimize_size)
7437 if (true_regnum (operands[1]))
7438 emit_move_insn (operands[0], operands[1]);
7440 emit_move_insn (operands[3], operands[1]);
7441 operands[4] = operands[3];
7445 gcc_assert (!true_regnum (operands[1]));
7446 operands[4] = operands[1];
7451 (define_expand "divmodsi4"
7452 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7453 (div:SI (match_operand:SI 1 "register_operand" "")
7454 (match_operand:SI 2 "nonimmediate_operand" "")))
7455 (set (match_operand:SI 3 "register_operand" "")
7456 (mod:SI (match_dup 1) (match_dup 2)))
7457 (clobber (reg:CC FLAGS_REG))])]
7461 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7462 ;; Penalize eax case slightly because it results in worse scheduling
7464 (define_insn "*divmodsi4_nocltd"
7465 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7466 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7467 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7468 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7469 (mod:SI (match_dup 2) (match_dup 3)))
7470 (clobber (reg:CC FLAGS_REG))]
7471 "!optimize_size && !TARGET_USE_CLTD"
7473 [(set_attr "type" "multi")])
7475 (define_insn "*divmodsi4_cltd"
7476 [(set (match_operand:SI 0 "register_operand" "=a")
7477 (div:SI (match_operand:SI 2 "register_operand" "a")
7478 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7479 (set (match_operand:SI 1 "register_operand" "=&d")
7480 (mod:SI (match_dup 2) (match_dup 3)))
7481 (clobber (reg:CC FLAGS_REG))]
7482 "optimize_size || TARGET_USE_CLTD"
7484 [(set_attr "type" "multi")])
7486 (define_insn "*divmodsi_noext"
7487 [(set (match_operand:SI 0 "register_operand" "=a")
7488 (div:SI (match_operand:SI 1 "register_operand" "0")
7489 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7490 (set (match_operand:SI 3 "register_operand" "=d")
7491 (mod:SI (match_dup 1) (match_dup 2)))
7492 (use (match_operand:SI 4 "register_operand" "3"))
7493 (clobber (reg:CC FLAGS_REG))]
7496 [(set_attr "type" "idiv")
7497 (set_attr "mode" "SI")])
7500 [(set (match_operand:SI 0 "register_operand" "")
7501 (div:SI (match_operand:SI 1 "register_operand" "")
7502 (match_operand:SI 2 "nonimmediate_operand" "")))
7503 (set (match_operand:SI 3 "register_operand" "")
7504 (mod:SI (match_dup 1) (match_dup 2)))
7505 (clobber (reg:CC FLAGS_REG))]
7507 [(parallel [(set (match_dup 3)
7508 (ashiftrt:SI (match_dup 4) (const_int 31)))
7509 (clobber (reg:CC FLAGS_REG))])
7510 (parallel [(set (match_dup 0)
7511 (div:SI (reg:SI 0) (match_dup 2)))
7513 (mod:SI (reg:SI 0) (match_dup 2)))
7515 (clobber (reg:CC FLAGS_REG))])]
7517 /* Avoid use of cltd in favor of a mov+shift. */
7518 if (!TARGET_USE_CLTD && !optimize_size)
7520 if (true_regnum (operands[1]))
7521 emit_move_insn (operands[0], operands[1]);
7523 emit_move_insn (operands[3], operands[1]);
7524 operands[4] = operands[3];
7528 gcc_assert (!true_regnum (operands[1]));
7529 operands[4] = operands[1];
7533 (define_insn "divmodhi4"
7534 [(set (match_operand:HI 0 "register_operand" "=a")
7535 (div:HI (match_operand:HI 1 "register_operand" "0")
7536 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7537 (set (match_operand:HI 3 "register_operand" "=&d")
7538 (mod:HI (match_dup 1) (match_dup 2)))
7539 (clobber (reg:CC FLAGS_REG))]
7540 "TARGET_HIMODE_MATH"
7542 [(set_attr "type" "multi")
7543 (set_attr "length_immediate" "0")
7544 (set_attr "mode" "SI")])
7546 (define_insn "udivmoddi4"
7547 [(set (match_operand:DI 0 "register_operand" "=a")
7548 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7549 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7550 (set (match_operand:DI 3 "register_operand" "=&d")
7551 (umod:DI (match_dup 1) (match_dup 2)))
7552 (clobber (reg:CC FLAGS_REG))]
7554 "xor{q}\t%3, %3\;div{q}\t%2"
7555 [(set_attr "type" "multi")
7556 (set_attr "length_immediate" "0")
7557 (set_attr "mode" "DI")])
7559 (define_insn "*udivmoddi4_noext"
7560 [(set (match_operand:DI 0 "register_operand" "=a")
7561 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7562 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7563 (set (match_operand:DI 3 "register_operand" "=d")
7564 (umod:DI (match_dup 1) (match_dup 2)))
7566 (clobber (reg:CC FLAGS_REG))]
7569 [(set_attr "type" "idiv")
7570 (set_attr "mode" "DI")])
7573 [(set (match_operand:DI 0 "register_operand" "")
7574 (udiv:DI (match_operand:DI 1 "register_operand" "")
7575 (match_operand:DI 2 "nonimmediate_operand" "")))
7576 (set (match_operand:DI 3 "register_operand" "")
7577 (umod:DI (match_dup 1) (match_dup 2)))
7578 (clobber (reg:CC FLAGS_REG))]
7579 "TARGET_64BIT && reload_completed"
7580 [(set (match_dup 3) (const_int 0))
7581 (parallel [(set (match_dup 0)
7582 (udiv:DI (match_dup 1) (match_dup 2)))
7584 (umod:DI (match_dup 1) (match_dup 2)))
7586 (clobber (reg:CC FLAGS_REG))])]
7589 (define_insn "udivmodsi4"
7590 [(set (match_operand:SI 0 "register_operand" "=a")
7591 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7592 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7593 (set (match_operand:SI 3 "register_operand" "=&d")
7594 (umod:SI (match_dup 1) (match_dup 2)))
7595 (clobber (reg:CC FLAGS_REG))]
7597 "xor{l}\t%3, %3\;div{l}\t%2"
7598 [(set_attr "type" "multi")
7599 (set_attr "length_immediate" "0")
7600 (set_attr "mode" "SI")])
7602 (define_insn "*udivmodsi4_noext"
7603 [(set (match_operand:SI 0 "register_operand" "=a")
7604 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7605 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7606 (set (match_operand:SI 3 "register_operand" "=d")
7607 (umod:SI (match_dup 1) (match_dup 2)))
7609 (clobber (reg:CC FLAGS_REG))]
7612 [(set_attr "type" "idiv")
7613 (set_attr "mode" "SI")])
7616 [(set (match_operand:SI 0 "register_operand" "")
7617 (udiv:SI (match_operand:SI 1 "register_operand" "")
7618 (match_operand:SI 2 "nonimmediate_operand" "")))
7619 (set (match_operand:SI 3 "register_operand" "")
7620 (umod:SI (match_dup 1) (match_dup 2)))
7621 (clobber (reg:CC FLAGS_REG))]
7623 [(set (match_dup 3) (const_int 0))
7624 (parallel [(set (match_dup 0)
7625 (udiv:SI (match_dup 1) (match_dup 2)))
7627 (umod:SI (match_dup 1) (match_dup 2)))
7629 (clobber (reg:CC FLAGS_REG))])]
7632 (define_expand "udivmodhi4"
7633 [(set (match_dup 4) (const_int 0))
7634 (parallel [(set (match_operand:HI 0 "register_operand" "")
7635 (udiv:HI (match_operand:HI 1 "register_operand" "")
7636 (match_operand:HI 2 "nonimmediate_operand" "")))
7637 (set (match_operand:HI 3 "register_operand" "")
7638 (umod:HI (match_dup 1) (match_dup 2)))
7640 (clobber (reg:CC FLAGS_REG))])]
7641 "TARGET_HIMODE_MATH"
7642 "operands[4] = gen_reg_rtx (HImode);")
7644 (define_insn "*udivmodhi_noext"
7645 [(set (match_operand:HI 0 "register_operand" "=a")
7646 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7647 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7648 (set (match_operand:HI 3 "register_operand" "=d")
7649 (umod:HI (match_dup 1) (match_dup 2)))
7650 (use (match_operand:HI 4 "register_operand" "3"))
7651 (clobber (reg:CC FLAGS_REG))]
7654 [(set_attr "type" "idiv")
7655 (set_attr "mode" "HI")])
7657 ;; We cannot use div/idiv for double division, because it causes
7658 ;; "division by zero" on the overflow and that's not what we expect
7659 ;; from truncate. Because true (non truncating) double division is
7660 ;; never generated, we can't create this insn anyway.
7663 ; [(set (match_operand:SI 0 "register_operand" "=a")
7665 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7667 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7668 ; (set (match_operand:SI 3 "register_operand" "=d")
7670 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7671 ; (clobber (reg:CC FLAGS_REG))]
7673 ; "div{l}\t{%2, %0|%0, %2}"
7674 ; [(set_attr "type" "idiv")])
7676 ;;- Logical AND instructions
7678 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7679 ;; Note that this excludes ah.
7681 (define_insn "*testdi_1_rex64"
7682 [(set (reg FLAGS_REG)
7684 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7685 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7687 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7688 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7690 test{l}\t{%k1, %k0|%k0, %k1}
7691 test{l}\t{%k1, %k0|%k0, %k1}
7692 test{q}\t{%1, %0|%0, %1}
7693 test{q}\t{%1, %0|%0, %1}
7694 test{q}\t{%1, %0|%0, %1}"
7695 [(set_attr "type" "test")
7696 (set_attr "modrm" "0,1,0,1,1")
7697 (set_attr "mode" "SI,SI,DI,DI,DI")
7698 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7700 (define_insn "testsi_1"
7701 [(set (reg FLAGS_REG)
7703 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7704 (match_operand:SI 1 "general_operand" "in,in,rin"))
7706 "ix86_match_ccmode (insn, CCNOmode)
7707 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7708 "test{l}\t{%1, %0|%0, %1}"
7709 [(set_attr "type" "test")
7710 (set_attr "modrm" "0,1,1")
7711 (set_attr "mode" "SI")
7712 (set_attr "pent_pair" "uv,np,uv")])
7714 (define_expand "testsi_ccno_1"
7715 [(set (reg:CCNO FLAGS_REG)
7717 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7718 (match_operand:SI 1 "nonmemory_operand" ""))
7723 (define_insn "*testhi_1"
7724 [(set (reg FLAGS_REG)
7725 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7726 (match_operand:HI 1 "general_operand" "n,n,rn"))
7728 "ix86_match_ccmode (insn, CCNOmode)
7729 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7730 "test{w}\t{%1, %0|%0, %1}"
7731 [(set_attr "type" "test")
7732 (set_attr "modrm" "0,1,1")
7733 (set_attr "mode" "HI")
7734 (set_attr "pent_pair" "uv,np,uv")])
7736 (define_expand "testqi_ccz_1"
7737 [(set (reg:CCZ FLAGS_REG)
7738 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7739 (match_operand:QI 1 "nonmemory_operand" ""))
7744 (define_insn "*testqi_1_maybe_si"
7745 [(set (reg FLAGS_REG)
7748 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7749 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7751 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7752 && ix86_match_ccmode (insn,
7753 GET_CODE (operands[1]) == CONST_INT
7754 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7756 if (which_alternative == 3)
7758 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7759 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7760 return "test{l}\t{%1, %k0|%k0, %1}";
7762 return "test{b}\t{%1, %0|%0, %1}";
7764 [(set_attr "type" "test")
7765 (set_attr "modrm" "0,1,1,1")
7766 (set_attr "mode" "QI,QI,QI,SI")
7767 (set_attr "pent_pair" "uv,np,uv,np")])
7769 (define_insn "*testqi_1"
7770 [(set (reg FLAGS_REG)
7773 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7774 (match_operand:QI 1 "general_operand" "n,n,qn"))
7776 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7777 && ix86_match_ccmode (insn, CCNOmode)"
7778 "test{b}\t{%1, %0|%0, %1}"
7779 [(set_attr "type" "test")
7780 (set_attr "modrm" "0,1,1")
7781 (set_attr "mode" "QI")
7782 (set_attr "pent_pair" "uv,np,uv")])
7784 (define_expand "testqi_ext_ccno_0"
7785 [(set (reg:CCNO FLAGS_REG)
7789 (match_operand 0 "ext_register_operand" "")
7792 (match_operand 1 "const_int_operand" ""))
7797 (define_insn "*testqi_ext_0"
7798 [(set (reg FLAGS_REG)
7802 (match_operand 0 "ext_register_operand" "Q")
7805 (match_operand 1 "const_int_operand" "n"))
7807 "ix86_match_ccmode (insn, CCNOmode)"
7808 "test{b}\t{%1, %h0|%h0, %1}"
7809 [(set_attr "type" "test")
7810 (set_attr "mode" "QI")
7811 (set_attr "length_immediate" "1")
7812 (set_attr "pent_pair" "np")])
7814 (define_insn "*testqi_ext_1"
7815 [(set (reg FLAGS_REG)
7819 (match_operand 0 "ext_register_operand" "Q")
7823 (match_operand:QI 1 "general_operand" "Qm")))
7825 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7826 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7827 "test{b}\t{%1, %h0|%h0, %1}"
7828 [(set_attr "type" "test")
7829 (set_attr "mode" "QI")])
7831 (define_insn "*testqi_ext_1_rex64"
7832 [(set (reg FLAGS_REG)
7836 (match_operand 0 "ext_register_operand" "Q")
7840 (match_operand:QI 1 "register_operand" "Q")))
7842 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7843 "test{b}\t{%1, %h0|%h0, %1}"
7844 [(set_attr "type" "test")
7845 (set_attr "mode" "QI")])
7847 (define_insn "*testqi_ext_2"
7848 [(set (reg FLAGS_REG)
7852 (match_operand 0 "ext_register_operand" "Q")
7856 (match_operand 1 "ext_register_operand" "Q")
7860 "ix86_match_ccmode (insn, CCNOmode)"
7861 "test{b}\t{%h1, %h0|%h0, %h1}"
7862 [(set_attr "type" "test")
7863 (set_attr "mode" "QI")])
7865 ;; Combine likes to form bit extractions for some tests. Humor it.
7866 (define_insn "*testqi_ext_3"
7867 [(set (reg FLAGS_REG)
7868 (compare (zero_extract:SI
7869 (match_operand 0 "nonimmediate_operand" "rm")
7870 (match_operand:SI 1 "const_int_operand" "")
7871 (match_operand:SI 2 "const_int_operand" ""))
7873 "ix86_match_ccmode (insn, CCNOmode)
7874 && (GET_MODE (operands[0]) == SImode
7875 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7876 || GET_MODE (operands[0]) == HImode
7877 || GET_MODE (operands[0]) == QImode)"
7880 (define_insn "*testqi_ext_3_rex64"
7881 [(set (reg FLAGS_REG)
7882 (compare (zero_extract:DI
7883 (match_operand 0 "nonimmediate_operand" "rm")
7884 (match_operand:DI 1 "const_int_operand" "")
7885 (match_operand:DI 2 "const_int_operand" ""))
7888 && ix86_match_ccmode (insn, CCNOmode)
7889 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7890 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7891 /* Ensure that resulting mask is zero or sign extended operand. */
7892 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7893 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7894 && INTVAL (operands[1]) > 32))
7895 && (GET_MODE (operands[0]) == SImode
7896 || GET_MODE (operands[0]) == DImode
7897 || GET_MODE (operands[0]) == HImode
7898 || GET_MODE (operands[0]) == QImode)"
7902 [(set (match_operand 0 "flags_reg_operand" "")
7903 (match_operator 1 "compare_operator"
7905 (match_operand 2 "nonimmediate_operand" "")
7906 (match_operand 3 "const_int_operand" "")
7907 (match_operand 4 "const_int_operand" ""))
7909 "ix86_match_ccmode (insn, CCNOmode)"
7910 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7912 rtx val = operands[2];
7913 HOST_WIDE_INT len = INTVAL (operands[3]);
7914 HOST_WIDE_INT pos = INTVAL (operands[4]);
7916 enum machine_mode mode, submode;
7918 mode = GET_MODE (val);
7919 if (GET_CODE (val) == MEM)
7921 /* ??? Combine likes to put non-volatile mem extractions in QImode
7922 no matter the size of the test. So find a mode that works. */
7923 if (! MEM_VOLATILE_P (val))
7925 mode = smallest_mode_for_size (pos + len, MODE_INT);
7926 val = adjust_address (val, mode, 0);
7929 else if (GET_CODE (val) == SUBREG
7930 && (submode = GET_MODE (SUBREG_REG (val)),
7931 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7932 && pos + len <= GET_MODE_BITSIZE (submode))
7934 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7936 val = SUBREG_REG (val);
7938 else if (mode == HImode && pos + len <= 8)
7940 /* Small HImode tests can be converted to QImode. */
7942 val = gen_lowpart (QImode, val);
7945 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7946 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7948 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7951 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7952 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7953 ;; this is relatively important trick.
7954 ;; Do the conversion only post-reload to avoid limiting of the register class
7957 [(set (match_operand 0 "flags_reg_operand" "")
7958 (match_operator 1 "compare_operator"
7959 [(and (match_operand 2 "register_operand" "")
7960 (match_operand 3 "const_int_operand" ""))
7963 && QI_REG_P (operands[2])
7964 && GET_MODE (operands[2]) != QImode
7965 && ((ix86_match_ccmode (insn, CCZmode)
7966 && !(INTVAL (operands[3]) & ~(255 << 8)))
7967 || (ix86_match_ccmode (insn, CCNOmode)
7968 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7971 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7974 "operands[2] = gen_lowpart (SImode, operands[2]);
7975 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7978 [(set (match_operand 0 "flags_reg_operand" "")
7979 (match_operator 1 "compare_operator"
7980 [(and (match_operand 2 "nonimmediate_operand" "")
7981 (match_operand 3 "const_int_operand" ""))
7984 && GET_MODE (operands[2]) != QImode
7985 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7986 && ((ix86_match_ccmode (insn, CCZmode)
7987 && !(INTVAL (operands[3]) & ~255))
7988 || (ix86_match_ccmode (insn, CCNOmode)
7989 && !(INTVAL (operands[3]) & ~127)))"
7991 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7993 "operands[2] = gen_lowpart (QImode, operands[2]);
7994 operands[3] = gen_lowpart (QImode, operands[3]);")
7997 ;; %%% This used to optimize known byte-wide and operations to memory,
7998 ;; and sometimes to QImode registers. If this is considered useful,
7999 ;; it should be done with splitters.
8001 (define_expand "anddi3"
8002 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8003 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8004 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8005 (clobber (reg:CC FLAGS_REG))]
8007 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8009 (define_insn "*anddi_1_rex64"
8010 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8011 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8012 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8013 (clobber (reg:CC FLAGS_REG))]
8014 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8016 switch (get_attr_type (insn))
8020 enum machine_mode mode;
8022 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8023 if (INTVAL (operands[2]) == 0xff)
8027 gcc_assert (INTVAL (operands[2]) == 0xffff);
8031 operands[1] = gen_lowpart (mode, operands[1]);
8033 return "movz{bq|x}\t{%1,%0|%0, %1}";
8035 return "movz{wq|x}\t{%1,%0|%0, %1}";
8039 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8040 if (get_attr_mode (insn) == MODE_SI)
8041 return "and{l}\t{%k2, %k0|%k0, %k2}";
8043 return "and{q}\t{%2, %0|%0, %2}";
8046 [(set_attr "type" "alu,alu,alu,imovx")
8047 (set_attr "length_immediate" "*,*,*,0")
8048 (set_attr "mode" "SI,DI,DI,DI")])
8050 (define_insn "*anddi_2"
8051 [(set (reg FLAGS_REG)
8052 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8053 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8055 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8056 (and:DI (match_dup 1) (match_dup 2)))]
8057 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8058 && ix86_binary_operator_ok (AND, DImode, operands)"
8060 and{l}\t{%k2, %k0|%k0, %k2}
8061 and{q}\t{%2, %0|%0, %2}
8062 and{q}\t{%2, %0|%0, %2}"
8063 [(set_attr "type" "alu")
8064 (set_attr "mode" "SI,DI,DI")])
8066 (define_expand "andsi3"
8067 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8068 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8069 (match_operand:SI 2 "general_operand" "")))
8070 (clobber (reg:CC FLAGS_REG))]
8072 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8074 (define_insn "*andsi_1"
8075 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8076 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8077 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8078 (clobber (reg:CC FLAGS_REG))]
8079 "ix86_binary_operator_ok (AND, SImode, operands)"
8081 switch (get_attr_type (insn))
8085 enum machine_mode mode;
8087 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8088 if (INTVAL (operands[2]) == 0xff)
8092 gcc_assert (INTVAL (operands[2]) == 0xffff);
8096 operands[1] = gen_lowpart (mode, operands[1]);
8098 return "movz{bl|x}\t{%1,%0|%0, %1}";
8100 return "movz{wl|x}\t{%1,%0|%0, %1}";
8104 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8105 return "and{l}\t{%2, %0|%0, %2}";
8108 [(set_attr "type" "alu,alu,imovx")
8109 (set_attr "length_immediate" "*,*,0")
8110 (set_attr "mode" "SI")])
8113 [(set (match_operand 0 "register_operand" "")
8115 (const_int -65536)))
8116 (clobber (reg:CC FLAGS_REG))]
8117 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8118 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8119 "operands[1] = gen_lowpart (HImode, operands[0]);")
8122 [(set (match_operand 0 "ext_register_operand" "")
8125 (clobber (reg:CC FLAGS_REG))]
8126 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8127 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8128 "operands[1] = gen_lowpart (QImode, operands[0]);")
8131 [(set (match_operand 0 "ext_register_operand" "")
8133 (const_int -65281)))
8134 (clobber (reg:CC FLAGS_REG))]
8135 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8136 [(parallel [(set (zero_extract:SI (match_dup 0)
8140 (zero_extract:SI (match_dup 0)
8143 (zero_extract:SI (match_dup 0)
8146 (clobber (reg:CC FLAGS_REG))])]
8147 "operands[0] = gen_lowpart (SImode, operands[0]);")
8149 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8150 (define_insn "*andsi_1_zext"
8151 [(set (match_operand:DI 0 "register_operand" "=r")
8153 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8154 (match_operand:SI 2 "general_operand" "rim"))))
8155 (clobber (reg:CC FLAGS_REG))]
8156 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8157 "and{l}\t{%2, %k0|%k0, %2}"
8158 [(set_attr "type" "alu")
8159 (set_attr "mode" "SI")])
8161 (define_insn "*andsi_2"
8162 [(set (reg FLAGS_REG)
8163 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8164 (match_operand:SI 2 "general_operand" "rim,ri"))
8166 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8167 (and:SI (match_dup 1) (match_dup 2)))]
8168 "ix86_match_ccmode (insn, CCNOmode)
8169 && ix86_binary_operator_ok (AND, SImode, operands)"
8170 "and{l}\t{%2, %0|%0, %2}"
8171 [(set_attr "type" "alu")
8172 (set_attr "mode" "SI")])
8174 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8175 (define_insn "*andsi_2_zext"
8176 [(set (reg FLAGS_REG)
8177 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8178 (match_operand:SI 2 "general_operand" "rim"))
8180 (set (match_operand:DI 0 "register_operand" "=r")
8181 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8182 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8183 && ix86_binary_operator_ok (AND, SImode, operands)"
8184 "and{l}\t{%2, %k0|%k0, %2}"
8185 [(set_attr "type" "alu")
8186 (set_attr "mode" "SI")])
8188 (define_expand "andhi3"
8189 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8190 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8191 (match_operand:HI 2 "general_operand" "")))
8192 (clobber (reg:CC FLAGS_REG))]
8193 "TARGET_HIMODE_MATH"
8194 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8196 (define_insn "*andhi_1"
8197 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8198 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8199 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8200 (clobber (reg:CC FLAGS_REG))]
8201 "ix86_binary_operator_ok (AND, HImode, operands)"
8203 switch (get_attr_type (insn))
8206 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8207 gcc_assert (INTVAL (operands[2]) == 0xff);
8208 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8211 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8213 return "and{w}\t{%2, %0|%0, %2}";
8216 [(set_attr "type" "alu,alu,imovx")
8217 (set_attr "length_immediate" "*,*,0")
8218 (set_attr "mode" "HI,HI,SI")])
8220 (define_insn "*andhi_2"
8221 [(set (reg FLAGS_REG)
8222 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8223 (match_operand:HI 2 "general_operand" "rim,ri"))
8225 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8226 (and:HI (match_dup 1) (match_dup 2)))]
8227 "ix86_match_ccmode (insn, CCNOmode)
8228 && ix86_binary_operator_ok (AND, HImode, operands)"
8229 "and{w}\t{%2, %0|%0, %2}"
8230 [(set_attr "type" "alu")
8231 (set_attr "mode" "HI")])
8233 (define_expand "andqi3"
8234 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8235 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8236 (match_operand:QI 2 "general_operand" "")))
8237 (clobber (reg:CC FLAGS_REG))]
8238 "TARGET_QIMODE_MATH"
8239 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8241 ;; %%% Potential partial reg stall on alternative 2. What to do?
8242 (define_insn "*andqi_1"
8243 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8244 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8245 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8246 (clobber (reg:CC FLAGS_REG))]
8247 "ix86_binary_operator_ok (AND, QImode, operands)"
8249 and{b}\t{%2, %0|%0, %2}
8250 and{b}\t{%2, %0|%0, %2}
8251 and{l}\t{%k2, %k0|%k0, %k2}"
8252 [(set_attr "type" "alu")
8253 (set_attr "mode" "QI,QI,SI")])
8255 (define_insn "*andqi_1_slp"
8256 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8257 (and:QI (match_dup 0)
8258 (match_operand:QI 1 "general_operand" "qi,qmi")))
8259 (clobber (reg:CC FLAGS_REG))]
8260 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8261 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8262 "and{b}\t{%1, %0|%0, %1}"
8263 [(set_attr "type" "alu1")
8264 (set_attr "mode" "QI")])
8266 (define_insn "*andqi_2_maybe_si"
8267 [(set (reg FLAGS_REG)
8269 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8270 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8272 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8273 (and:QI (match_dup 1) (match_dup 2)))]
8274 "ix86_binary_operator_ok (AND, QImode, operands)
8275 && ix86_match_ccmode (insn,
8276 GET_CODE (operands[2]) == CONST_INT
8277 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8279 if (which_alternative == 2)
8281 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8282 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8283 return "and{l}\t{%2, %k0|%k0, %2}";
8285 return "and{b}\t{%2, %0|%0, %2}";
8287 [(set_attr "type" "alu")
8288 (set_attr "mode" "QI,QI,SI")])
8290 (define_insn "*andqi_2"
8291 [(set (reg FLAGS_REG)
8293 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8294 (match_operand:QI 2 "general_operand" "qim,qi"))
8296 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8297 (and:QI (match_dup 1) (match_dup 2)))]
8298 "ix86_match_ccmode (insn, CCNOmode)
8299 && ix86_binary_operator_ok (AND, QImode, operands)"
8300 "and{b}\t{%2, %0|%0, %2}"
8301 [(set_attr "type" "alu")
8302 (set_attr "mode" "QI")])
8304 (define_insn "*andqi_2_slp"
8305 [(set (reg FLAGS_REG)
8307 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8308 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8310 (set (strict_low_part (match_dup 0))
8311 (and:QI (match_dup 0) (match_dup 1)))]
8312 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8313 && ix86_match_ccmode (insn, CCNOmode)
8314 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8315 "and{b}\t{%1, %0|%0, %1}"
8316 [(set_attr "type" "alu1")
8317 (set_attr "mode" "QI")])
8319 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8320 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8321 ;; for a QImode operand, which of course failed.
8323 (define_insn "andqi_ext_0"
8324 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8329 (match_operand 1 "ext_register_operand" "0")
8332 (match_operand 2 "const_int_operand" "n")))
8333 (clobber (reg:CC FLAGS_REG))]
8335 "and{b}\t{%2, %h0|%h0, %2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "length_immediate" "1")
8338 (set_attr "mode" "QI")])
8340 ;; Generated by peephole translating test to and. This shows up
8341 ;; often in fp comparisons.
8343 (define_insn "*andqi_ext_0_cc"
8344 [(set (reg FLAGS_REG)
8348 (match_operand 1 "ext_register_operand" "0")
8351 (match_operand 2 "const_int_operand" "n"))
8353 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8362 "ix86_match_ccmode (insn, CCNOmode)"
8363 "and{b}\t{%2, %h0|%h0, %2}"
8364 [(set_attr "type" "alu")
8365 (set_attr "length_immediate" "1")
8366 (set_attr "mode" "QI")])
8368 (define_insn "*andqi_ext_1"
8369 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8374 (match_operand 1 "ext_register_operand" "0")
8378 (match_operand:QI 2 "general_operand" "Qm"))))
8379 (clobber (reg:CC FLAGS_REG))]
8381 "and{b}\t{%2, %h0|%h0, %2}"
8382 [(set_attr "type" "alu")
8383 (set_attr "length_immediate" "0")
8384 (set_attr "mode" "QI")])
8386 (define_insn "*andqi_ext_1_rex64"
8387 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8392 (match_operand 1 "ext_register_operand" "0")
8396 (match_operand 2 "ext_register_operand" "Q"))))
8397 (clobber (reg:CC FLAGS_REG))]
8399 "and{b}\t{%2, %h0|%h0, %2}"
8400 [(set_attr "type" "alu")
8401 (set_attr "length_immediate" "0")
8402 (set_attr "mode" "QI")])
8404 (define_insn "*andqi_ext_2"
8405 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8410 (match_operand 1 "ext_register_operand" "%0")
8414 (match_operand 2 "ext_register_operand" "Q")
8417 (clobber (reg:CC FLAGS_REG))]
8419 "and{b}\t{%h2, %h0|%h0, %h2}"
8420 [(set_attr "type" "alu")
8421 (set_attr "length_immediate" "0")
8422 (set_attr "mode" "QI")])
8424 ;; Convert wide AND instructions with immediate operand to shorter QImode
8425 ;; equivalents when possible.
8426 ;; Don't do the splitting with memory operands, since it introduces risk
8427 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8428 ;; for size, but that can (should?) be handled by generic code instead.
8430 [(set (match_operand 0 "register_operand" "")
8431 (and (match_operand 1 "register_operand" "")
8432 (match_operand 2 "const_int_operand" "")))
8433 (clobber (reg:CC FLAGS_REG))]
8435 && QI_REG_P (operands[0])
8436 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8437 && !(~INTVAL (operands[2]) & ~(255 << 8))
8438 && GET_MODE (operands[0]) != QImode"
8439 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8440 (and:SI (zero_extract:SI (match_dup 1)
8441 (const_int 8) (const_int 8))
8443 (clobber (reg:CC FLAGS_REG))])]
8444 "operands[0] = gen_lowpart (SImode, operands[0]);
8445 operands[1] = gen_lowpart (SImode, operands[1]);
8446 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8448 ;; Since AND can be encoded with sign extended immediate, this is only
8449 ;; profitable when 7th bit is not set.
8451 [(set (match_operand 0 "register_operand" "")
8452 (and (match_operand 1 "general_operand" "")
8453 (match_operand 2 "const_int_operand" "")))
8454 (clobber (reg:CC FLAGS_REG))]
8456 && ANY_QI_REG_P (operands[0])
8457 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8458 && !(~INTVAL (operands[2]) & ~255)
8459 && !(INTVAL (operands[2]) & 128)
8460 && GET_MODE (operands[0]) != QImode"
8461 [(parallel [(set (strict_low_part (match_dup 0))
8462 (and:QI (match_dup 1)
8464 (clobber (reg:CC FLAGS_REG))])]
8465 "operands[0] = gen_lowpart (QImode, operands[0]);
8466 operands[1] = gen_lowpart (QImode, operands[1]);
8467 operands[2] = gen_lowpart (QImode, operands[2]);")
8469 ;; Logical inclusive OR instructions
8471 ;; %%% This used to optimize known byte-wide and operations to memory.
8472 ;; If this is considered useful, it should be done with splitters.
8474 (define_expand "iordi3"
8475 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8476 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8477 (match_operand:DI 2 "x86_64_general_operand" "")))
8478 (clobber (reg:CC FLAGS_REG))]
8480 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8482 (define_insn "*iordi_1_rex64"
8483 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8484 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8485 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8486 (clobber (reg:CC FLAGS_REG))]
8488 && ix86_binary_operator_ok (IOR, DImode, operands)"
8489 "or{q}\t{%2, %0|%0, %2}"
8490 [(set_attr "type" "alu")
8491 (set_attr "mode" "DI")])
8493 (define_insn "*iordi_2_rex64"
8494 [(set (reg FLAGS_REG)
8495 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8496 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8498 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8499 (ior:DI (match_dup 1) (match_dup 2)))]
8501 && ix86_match_ccmode (insn, CCNOmode)
8502 && ix86_binary_operator_ok (IOR, DImode, operands)"
8503 "or{q}\t{%2, %0|%0, %2}"
8504 [(set_attr "type" "alu")
8505 (set_attr "mode" "DI")])
8507 (define_insn "*iordi_3_rex64"
8508 [(set (reg FLAGS_REG)
8509 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8510 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8512 (clobber (match_scratch:DI 0 "=r"))]
8514 && ix86_match_ccmode (insn, CCNOmode)
8515 && ix86_binary_operator_ok (IOR, DImode, operands)"
8516 "or{q}\t{%2, %0|%0, %2}"
8517 [(set_attr "type" "alu")
8518 (set_attr "mode" "DI")])
8521 (define_expand "iorsi3"
8522 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8523 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8524 (match_operand:SI 2 "general_operand" "")))
8525 (clobber (reg:CC FLAGS_REG))]
8527 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8529 (define_insn "*iorsi_1"
8530 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8531 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8532 (match_operand:SI 2 "general_operand" "ri,rmi")))
8533 (clobber (reg:CC FLAGS_REG))]
8534 "ix86_binary_operator_ok (IOR, SImode, operands)"
8535 "or{l}\t{%2, %0|%0, %2}"
8536 [(set_attr "type" "alu")
8537 (set_attr "mode" "SI")])
8539 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8540 (define_insn "*iorsi_1_zext"
8541 [(set (match_operand:DI 0 "register_operand" "=rm")
8543 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8544 (match_operand:SI 2 "general_operand" "rim"))))
8545 (clobber (reg:CC FLAGS_REG))]
8546 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8547 "or{l}\t{%2, %k0|%k0, %2}"
8548 [(set_attr "type" "alu")
8549 (set_attr "mode" "SI")])
8551 (define_insn "*iorsi_1_zext_imm"
8552 [(set (match_operand:DI 0 "register_operand" "=rm")
8553 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8554 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8555 (clobber (reg:CC FLAGS_REG))]
8557 "or{l}\t{%2, %k0|%k0, %2}"
8558 [(set_attr "type" "alu")
8559 (set_attr "mode" "SI")])
8561 (define_insn "*iorsi_2"
8562 [(set (reg FLAGS_REG)
8563 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8564 (match_operand:SI 2 "general_operand" "rim,ri"))
8566 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8567 (ior:SI (match_dup 1) (match_dup 2)))]
8568 "ix86_match_ccmode (insn, CCNOmode)
8569 && ix86_binary_operator_ok (IOR, SImode, operands)"
8570 "or{l}\t{%2, %0|%0, %2}"
8571 [(set_attr "type" "alu")
8572 (set_attr "mode" "SI")])
8574 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8575 ;; ??? Special case for immediate operand is missing - it is tricky.
8576 (define_insn "*iorsi_2_zext"
8577 [(set (reg FLAGS_REG)
8578 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8579 (match_operand:SI 2 "general_operand" "rim"))
8581 (set (match_operand:DI 0 "register_operand" "=r")
8582 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8583 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8584 && ix86_binary_operator_ok (IOR, SImode, operands)"
8585 "or{l}\t{%2, %k0|%k0, %2}"
8586 [(set_attr "type" "alu")
8587 (set_attr "mode" "SI")])
8589 (define_insn "*iorsi_2_zext_imm"
8590 [(set (reg FLAGS_REG)
8591 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8592 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8594 (set (match_operand:DI 0 "register_operand" "=r")
8595 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8596 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8597 && ix86_binary_operator_ok (IOR, SImode, operands)"
8598 "or{l}\t{%2, %k0|%k0, %2}"
8599 [(set_attr "type" "alu")
8600 (set_attr "mode" "SI")])
8602 (define_insn "*iorsi_3"
8603 [(set (reg FLAGS_REG)
8604 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8605 (match_operand:SI 2 "general_operand" "rim"))
8607 (clobber (match_scratch:SI 0 "=r"))]
8608 "ix86_match_ccmode (insn, CCNOmode)
8609 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8610 "or{l}\t{%2, %0|%0, %2}"
8611 [(set_attr "type" "alu")
8612 (set_attr "mode" "SI")])
8614 (define_expand "iorhi3"
8615 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8616 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8617 (match_operand:HI 2 "general_operand" "")))
8618 (clobber (reg:CC FLAGS_REG))]
8619 "TARGET_HIMODE_MATH"
8620 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8622 (define_insn "*iorhi_1"
8623 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8624 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8625 (match_operand:HI 2 "general_operand" "rmi,ri")))
8626 (clobber (reg:CC FLAGS_REG))]
8627 "ix86_binary_operator_ok (IOR, HImode, operands)"
8628 "or{w}\t{%2, %0|%0, %2}"
8629 [(set_attr "type" "alu")
8630 (set_attr "mode" "HI")])
8632 (define_insn "*iorhi_2"
8633 [(set (reg FLAGS_REG)
8634 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8635 (match_operand:HI 2 "general_operand" "rim,ri"))
8637 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8638 (ior:HI (match_dup 1) (match_dup 2)))]
8639 "ix86_match_ccmode (insn, CCNOmode)
8640 && ix86_binary_operator_ok (IOR, HImode, operands)"
8641 "or{w}\t{%2, %0|%0, %2}"
8642 [(set_attr "type" "alu")
8643 (set_attr "mode" "HI")])
8645 (define_insn "*iorhi_3"
8646 [(set (reg FLAGS_REG)
8647 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8648 (match_operand:HI 2 "general_operand" "rim"))
8650 (clobber (match_scratch:HI 0 "=r"))]
8651 "ix86_match_ccmode (insn, CCNOmode)
8652 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8653 "or{w}\t{%2, %0|%0, %2}"
8654 [(set_attr "type" "alu")
8655 (set_attr "mode" "HI")])
8657 (define_expand "iorqi3"
8658 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8659 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8660 (match_operand:QI 2 "general_operand" "")))
8661 (clobber (reg:CC FLAGS_REG))]
8662 "TARGET_QIMODE_MATH"
8663 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8665 ;; %%% Potential partial reg stall on alternative 2. What to do?
8666 (define_insn "*iorqi_1"
8667 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8668 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8669 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8670 (clobber (reg:CC FLAGS_REG))]
8671 "ix86_binary_operator_ok (IOR, QImode, operands)"
8673 or{b}\t{%2, %0|%0, %2}
8674 or{b}\t{%2, %0|%0, %2}
8675 or{l}\t{%k2, %k0|%k0, %k2}"
8676 [(set_attr "type" "alu")
8677 (set_attr "mode" "QI,QI,SI")])
8679 (define_insn "*iorqi_1_slp"
8680 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8681 (ior:QI (match_dup 0)
8682 (match_operand:QI 1 "general_operand" "qmi,qi")))
8683 (clobber (reg:CC FLAGS_REG))]
8684 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8685 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8686 "or{b}\t{%1, %0|%0, %1}"
8687 [(set_attr "type" "alu1")
8688 (set_attr "mode" "QI")])
8690 (define_insn "*iorqi_2"
8691 [(set (reg FLAGS_REG)
8692 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8693 (match_operand:QI 2 "general_operand" "qim,qi"))
8695 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8696 (ior:QI (match_dup 1) (match_dup 2)))]
8697 "ix86_match_ccmode (insn, CCNOmode)
8698 && ix86_binary_operator_ok (IOR, QImode, operands)"
8699 "or{b}\t{%2, %0|%0, %2}"
8700 [(set_attr "type" "alu")
8701 (set_attr "mode" "QI")])
8703 (define_insn "*iorqi_2_slp"
8704 [(set (reg FLAGS_REG)
8705 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8706 (match_operand:QI 1 "general_operand" "qim,qi"))
8708 (set (strict_low_part (match_dup 0))
8709 (ior:QI (match_dup 0) (match_dup 1)))]
8710 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8711 && ix86_match_ccmode (insn, CCNOmode)
8712 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8713 "or{b}\t{%1, %0|%0, %1}"
8714 [(set_attr "type" "alu1")
8715 (set_attr "mode" "QI")])
8717 (define_insn "*iorqi_3"
8718 [(set (reg FLAGS_REG)
8719 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8720 (match_operand:QI 2 "general_operand" "qim"))
8722 (clobber (match_scratch:QI 0 "=q"))]
8723 "ix86_match_ccmode (insn, CCNOmode)
8724 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8725 "or{b}\t{%2, %0|%0, %2}"
8726 [(set_attr "type" "alu")
8727 (set_attr "mode" "QI")])
8729 (define_insn "iorqi_ext_0"
8730 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8735 (match_operand 1 "ext_register_operand" "0")
8738 (match_operand 2 "const_int_operand" "n")))
8739 (clobber (reg:CC FLAGS_REG))]
8740 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8741 "or{b}\t{%2, %h0|%h0, %2}"
8742 [(set_attr "type" "alu")
8743 (set_attr "length_immediate" "1")
8744 (set_attr "mode" "QI")])
8746 (define_insn "*iorqi_ext_1"
8747 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8752 (match_operand 1 "ext_register_operand" "0")
8756 (match_operand:QI 2 "general_operand" "Qm"))))
8757 (clobber (reg:CC FLAGS_REG))]
8759 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8760 "or{b}\t{%2, %h0|%h0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "length_immediate" "0")
8763 (set_attr "mode" "QI")])
8765 (define_insn "*iorqi_ext_1_rex64"
8766 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8771 (match_operand 1 "ext_register_operand" "0")
8775 (match_operand 2 "ext_register_operand" "Q"))))
8776 (clobber (reg:CC FLAGS_REG))]
8778 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8779 "or{b}\t{%2, %h0|%h0, %2}"
8780 [(set_attr "type" "alu")
8781 (set_attr "length_immediate" "0")
8782 (set_attr "mode" "QI")])
8784 (define_insn "*iorqi_ext_2"
8785 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8789 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8792 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8795 (clobber (reg:CC FLAGS_REG))]
8796 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8797 "ior{b}\t{%h2, %h0|%h0, %h2}"
8798 [(set_attr "type" "alu")
8799 (set_attr "length_immediate" "0")
8800 (set_attr "mode" "QI")])
8803 [(set (match_operand 0 "register_operand" "")
8804 (ior (match_operand 1 "register_operand" "")
8805 (match_operand 2 "const_int_operand" "")))
8806 (clobber (reg:CC FLAGS_REG))]
8808 && QI_REG_P (operands[0])
8809 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8810 && !(INTVAL (operands[2]) & ~(255 << 8))
8811 && GET_MODE (operands[0]) != QImode"
8812 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8813 (ior:SI (zero_extract:SI (match_dup 1)
8814 (const_int 8) (const_int 8))
8816 (clobber (reg:CC FLAGS_REG))])]
8817 "operands[0] = gen_lowpart (SImode, operands[0]);
8818 operands[1] = gen_lowpart (SImode, operands[1]);
8819 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8821 ;; Since OR can be encoded with sign extended immediate, this is only
8822 ;; profitable when 7th bit is set.
8824 [(set (match_operand 0 "register_operand" "")
8825 (ior (match_operand 1 "general_operand" "")
8826 (match_operand 2 "const_int_operand" "")))
8827 (clobber (reg:CC FLAGS_REG))]
8829 && ANY_QI_REG_P (operands[0])
8830 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8831 && !(INTVAL (operands[2]) & ~255)
8832 && (INTVAL (operands[2]) & 128)
8833 && GET_MODE (operands[0]) != QImode"
8834 [(parallel [(set (strict_low_part (match_dup 0))
8835 (ior:QI (match_dup 1)
8837 (clobber (reg:CC FLAGS_REG))])]
8838 "operands[0] = gen_lowpart (QImode, operands[0]);
8839 operands[1] = gen_lowpart (QImode, operands[1]);
8840 operands[2] = gen_lowpart (QImode, operands[2]);")
8842 ;; Logical XOR instructions
8844 ;; %%% This used to optimize known byte-wide and operations to memory.
8845 ;; If this is considered useful, it should be done with splitters.
8847 (define_expand "xordi3"
8848 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8849 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8850 (match_operand:DI 2 "x86_64_general_operand" "")))
8851 (clobber (reg:CC FLAGS_REG))]
8853 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8855 (define_insn "*xordi_1_rex64"
8856 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8857 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8858 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8859 (clobber (reg:CC FLAGS_REG))]
8861 && ix86_binary_operator_ok (XOR, DImode, operands)"
8863 xor{q}\t{%2, %0|%0, %2}
8864 xor{q}\t{%2, %0|%0, %2}"
8865 [(set_attr "type" "alu")
8866 (set_attr "mode" "DI,DI")])
8868 (define_insn "*xordi_2_rex64"
8869 [(set (reg FLAGS_REG)
8870 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8871 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8873 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8874 (xor:DI (match_dup 1) (match_dup 2)))]
8876 && ix86_match_ccmode (insn, CCNOmode)
8877 && ix86_binary_operator_ok (XOR, DImode, operands)"
8879 xor{q}\t{%2, %0|%0, %2}
8880 xor{q}\t{%2, %0|%0, %2}"
8881 [(set_attr "type" "alu")
8882 (set_attr "mode" "DI,DI")])
8884 (define_insn "*xordi_3_rex64"
8885 [(set (reg FLAGS_REG)
8886 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8887 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8889 (clobber (match_scratch:DI 0 "=r"))]
8891 && ix86_match_ccmode (insn, CCNOmode)
8892 && ix86_binary_operator_ok (XOR, DImode, operands)"
8893 "xor{q}\t{%2, %0|%0, %2}"
8894 [(set_attr "type" "alu")
8895 (set_attr "mode" "DI")])
8897 (define_expand "xorsi3"
8898 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8899 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8900 (match_operand:SI 2 "general_operand" "")))
8901 (clobber (reg:CC FLAGS_REG))]
8903 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8905 (define_insn "*xorsi_1"
8906 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8907 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8908 (match_operand:SI 2 "general_operand" "ri,rm")))
8909 (clobber (reg:CC FLAGS_REG))]
8910 "ix86_binary_operator_ok (XOR, SImode, operands)"
8911 "xor{l}\t{%2, %0|%0, %2}"
8912 [(set_attr "type" "alu")
8913 (set_attr "mode" "SI")])
8915 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8916 ;; Add speccase for immediates
8917 (define_insn "*xorsi_1_zext"
8918 [(set (match_operand:DI 0 "register_operand" "=r")
8920 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8921 (match_operand:SI 2 "general_operand" "rim"))))
8922 (clobber (reg:CC FLAGS_REG))]
8923 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8924 "xor{l}\t{%2, %k0|%k0, %2}"
8925 [(set_attr "type" "alu")
8926 (set_attr "mode" "SI")])
8928 (define_insn "*xorsi_1_zext_imm"
8929 [(set (match_operand:DI 0 "register_operand" "=r")
8930 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8931 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8932 (clobber (reg:CC FLAGS_REG))]
8933 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8934 "xor{l}\t{%2, %k0|%k0, %2}"
8935 [(set_attr "type" "alu")
8936 (set_attr "mode" "SI")])
8938 (define_insn "*xorsi_2"
8939 [(set (reg FLAGS_REG)
8940 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8941 (match_operand:SI 2 "general_operand" "rim,ri"))
8943 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8944 (xor:SI (match_dup 1) (match_dup 2)))]
8945 "ix86_match_ccmode (insn, CCNOmode)
8946 && ix86_binary_operator_ok (XOR, SImode, operands)"
8947 "xor{l}\t{%2, %0|%0, %2}"
8948 [(set_attr "type" "alu")
8949 (set_attr "mode" "SI")])
8951 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8952 ;; ??? Special case for immediate operand is missing - it is tricky.
8953 (define_insn "*xorsi_2_zext"
8954 [(set (reg FLAGS_REG)
8955 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956 (match_operand:SI 2 "general_operand" "rim"))
8958 (set (match_operand:DI 0 "register_operand" "=r")
8959 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8960 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8961 && ix86_binary_operator_ok (XOR, SImode, operands)"
8962 "xor{l}\t{%2, %k0|%k0, %2}"
8963 [(set_attr "type" "alu")
8964 (set_attr "mode" "SI")])
8966 (define_insn "*xorsi_2_zext_imm"
8967 [(set (reg FLAGS_REG)
8968 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8969 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8971 (set (match_operand:DI 0 "register_operand" "=r")
8972 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8973 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8974 && 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_3"
8980 [(set (reg FLAGS_REG)
8981 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8982 (match_operand:SI 2 "general_operand" "rim"))
8984 (clobber (match_scratch:SI 0 "=r"))]
8985 "ix86_match_ccmode (insn, CCNOmode)
8986 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8987 "xor{l}\t{%2, %0|%0, %2}"
8988 [(set_attr "type" "alu")
8989 (set_attr "mode" "SI")])
8991 (define_expand "xorhi3"
8992 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8993 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8994 (match_operand:HI 2 "general_operand" "")))
8995 (clobber (reg:CC FLAGS_REG))]
8996 "TARGET_HIMODE_MATH"
8997 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8999 (define_insn "*xorhi_1"
9000 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9001 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9002 (match_operand:HI 2 "general_operand" "rmi,ri")))
9003 (clobber (reg:CC FLAGS_REG))]
9004 "ix86_binary_operator_ok (XOR, HImode, operands)"
9005 "xor{w}\t{%2, %0|%0, %2}"
9006 [(set_attr "type" "alu")
9007 (set_attr "mode" "HI")])
9009 (define_insn "*xorhi_2"
9010 [(set (reg FLAGS_REG)
9011 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9012 (match_operand:HI 2 "general_operand" "rim,ri"))
9014 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9015 (xor:HI (match_dup 1) (match_dup 2)))]
9016 "ix86_match_ccmode (insn, CCNOmode)
9017 && ix86_binary_operator_ok (XOR, HImode, operands)"
9018 "xor{w}\t{%2, %0|%0, %2}"
9019 [(set_attr "type" "alu")
9020 (set_attr "mode" "HI")])
9022 (define_insn "*xorhi_3"
9023 [(set (reg FLAGS_REG)
9024 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9025 (match_operand:HI 2 "general_operand" "rim"))
9027 (clobber (match_scratch:HI 0 "=r"))]
9028 "ix86_match_ccmode (insn, CCNOmode)
9029 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9030 "xor{w}\t{%2, %0|%0, %2}"
9031 [(set_attr "type" "alu")
9032 (set_attr "mode" "HI")])
9034 (define_expand "xorqi3"
9035 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9036 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9037 (match_operand:QI 2 "general_operand" "")))
9038 (clobber (reg:CC FLAGS_REG))]
9039 "TARGET_QIMODE_MATH"
9040 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9042 ;; %%% Potential partial reg stall on alternative 2. What to do?
9043 (define_insn "*xorqi_1"
9044 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9045 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9046 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9047 (clobber (reg:CC FLAGS_REG))]
9048 "ix86_binary_operator_ok (XOR, QImode, operands)"
9050 xor{b}\t{%2, %0|%0, %2}
9051 xor{b}\t{%2, %0|%0, %2}
9052 xor{l}\t{%k2, %k0|%k0, %k2}"
9053 [(set_attr "type" "alu")
9054 (set_attr "mode" "QI,QI,SI")])
9056 (define_insn "*xorqi_1_slp"
9057 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9058 (xor:QI (match_dup 0)
9059 (match_operand:QI 1 "general_operand" "qi,qmi")))
9060 (clobber (reg:CC FLAGS_REG))]
9061 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9062 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9063 "xor{b}\t{%1, %0|%0, %1}"
9064 [(set_attr "type" "alu1")
9065 (set_attr "mode" "QI")])
9067 (define_insn "xorqi_ext_0"
9068 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9073 (match_operand 1 "ext_register_operand" "0")
9076 (match_operand 2 "const_int_operand" "n")))
9077 (clobber (reg:CC FLAGS_REG))]
9078 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9079 "xor{b}\t{%2, %h0|%h0, %2}"
9080 [(set_attr "type" "alu")
9081 (set_attr "length_immediate" "1")
9082 (set_attr "mode" "QI")])
9084 (define_insn "*xorqi_ext_1"
9085 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9090 (match_operand 1 "ext_register_operand" "0")
9094 (match_operand:QI 2 "general_operand" "Qm"))))
9095 (clobber (reg:CC FLAGS_REG))]
9097 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9098 "xor{b}\t{%2, %h0|%h0, %2}"
9099 [(set_attr "type" "alu")
9100 (set_attr "length_immediate" "0")
9101 (set_attr "mode" "QI")])
9103 (define_insn "*xorqi_ext_1_rex64"
9104 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9109 (match_operand 1 "ext_register_operand" "0")
9113 (match_operand 2 "ext_register_operand" "Q"))))
9114 (clobber (reg:CC FLAGS_REG))]
9116 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9117 "xor{b}\t{%2, %h0|%h0, %2}"
9118 [(set_attr "type" "alu")
9119 (set_attr "length_immediate" "0")
9120 (set_attr "mode" "QI")])
9122 (define_insn "*xorqi_ext_2"
9123 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9127 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9130 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9133 (clobber (reg:CC FLAGS_REG))]
9134 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9135 "xor{b}\t{%h2, %h0|%h0, %h2}"
9136 [(set_attr "type" "alu")
9137 (set_attr "length_immediate" "0")
9138 (set_attr "mode" "QI")])
9140 (define_insn "*xorqi_cc_1"
9141 [(set (reg FLAGS_REG)
9143 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9144 (match_operand:QI 2 "general_operand" "qim,qi"))
9146 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9147 (xor:QI (match_dup 1) (match_dup 2)))]
9148 "ix86_match_ccmode (insn, CCNOmode)
9149 && ix86_binary_operator_ok (XOR, QImode, operands)"
9150 "xor{b}\t{%2, %0|%0, %2}"
9151 [(set_attr "type" "alu")
9152 (set_attr "mode" "QI")])
9154 (define_insn "*xorqi_2_slp"
9155 [(set (reg FLAGS_REG)
9156 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9157 (match_operand:QI 1 "general_operand" "qim,qi"))
9159 (set (strict_low_part (match_dup 0))
9160 (xor:QI (match_dup 0) (match_dup 1)))]
9161 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9162 && ix86_match_ccmode (insn, CCNOmode)
9163 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9164 "xor{b}\t{%1, %0|%0, %1}"
9165 [(set_attr "type" "alu1")
9166 (set_attr "mode" "QI")])
9168 (define_insn "*xorqi_cc_2"
9169 [(set (reg FLAGS_REG)
9171 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9172 (match_operand:QI 2 "general_operand" "qim"))
9174 (clobber (match_scratch:QI 0 "=q"))]
9175 "ix86_match_ccmode (insn, CCNOmode)
9176 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9177 "xor{b}\t{%2, %0|%0, %2}"
9178 [(set_attr "type" "alu")
9179 (set_attr "mode" "QI")])
9181 (define_insn "*xorqi_cc_ext_1"
9182 [(set (reg FLAGS_REG)
9186 (match_operand 1 "ext_register_operand" "0")
9189 (match_operand:QI 2 "general_operand" "qmn"))
9191 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9195 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9197 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9198 "xor{b}\t{%2, %h0|%h0, %2}"
9199 [(set_attr "type" "alu")
9200 (set_attr "mode" "QI")])
9202 (define_insn "*xorqi_cc_ext_1_rex64"
9203 [(set (reg FLAGS_REG)
9207 (match_operand 1 "ext_register_operand" "0")
9210 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9212 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9216 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9218 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9219 "xor{b}\t{%2, %h0|%h0, %2}"
9220 [(set_attr "type" "alu")
9221 (set_attr "mode" "QI")])
9223 (define_expand "xorqi_cc_ext_1"
9225 (set (reg:CCNO FLAGS_REG)
9229 (match_operand 1 "ext_register_operand" "")
9232 (match_operand:QI 2 "general_operand" ""))
9234 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9238 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9244 [(set (match_operand 0 "register_operand" "")
9245 (xor (match_operand 1 "register_operand" "")
9246 (match_operand 2 "const_int_operand" "")))
9247 (clobber (reg:CC FLAGS_REG))]
9249 && QI_REG_P (operands[0])
9250 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9251 && !(INTVAL (operands[2]) & ~(255 << 8))
9252 && GET_MODE (operands[0]) != QImode"
9253 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9254 (xor:SI (zero_extract:SI (match_dup 1)
9255 (const_int 8) (const_int 8))
9257 (clobber (reg:CC FLAGS_REG))])]
9258 "operands[0] = gen_lowpart (SImode, operands[0]);
9259 operands[1] = gen_lowpart (SImode, operands[1]);
9260 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9262 ;; Since XOR can be encoded with sign extended immediate, this is only
9263 ;; profitable when 7th bit is set.
9265 [(set (match_operand 0 "register_operand" "")
9266 (xor (match_operand 1 "general_operand" "")
9267 (match_operand 2 "const_int_operand" "")))
9268 (clobber (reg:CC FLAGS_REG))]
9270 && ANY_QI_REG_P (operands[0])
9271 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9272 && !(INTVAL (operands[2]) & ~255)
9273 && (INTVAL (operands[2]) & 128)
9274 && GET_MODE (operands[0]) != QImode"
9275 [(parallel [(set (strict_low_part (match_dup 0))
9276 (xor:QI (match_dup 1)
9278 (clobber (reg:CC FLAGS_REG))])]
9279 "operands[0] = gen_lowpart (QImode, operands[0]);
9280 operands[1] = gen_lowpart (QImode, operands[1]);
9281 operands[2] = gen_lowpart (QImode, operands[2]);")
9283 ;; Negation instructions
9285 (define_expand "negti2"
9286 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9287 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9288 (clobber (reg:CC FLAGS_REG))])]
9290 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9292 (define_insn "*negti2_1"
9293 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9294 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9295 (clobber (reg:CC FLAGS_REG))]
9297 && ix86_unary_operator_ok (NEG, TImode, operands)"
9301 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9302 (neg:TI (match_operand:TI 1 "general_operand" "")))
9303 (clobber (reg:CC FLAGS_REG))]
9304 "TARGET_64BIT && reload_completed"
9306 [(set (reg:CCZ FLAGS_REG)
9307 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9308 (set (match_dup 0) (neg:DI (match_dup 2)))])
9311 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9314 (clobber (reg:CC FLAGS_REG))])
9317 (neg:DI (match_dup 1)))
9318 (clobber (reg:CC FLAGS_REG))])]
9319 "split_ti (operands+1, 1, operands+2, operands+3);
9320 split_ti (operands+0, 1, operands+0, operands+1);")
9322 (define_expand "negdi2"
9323 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9324 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9325 (clobber (reg:CC FLAGS_REG))])]
9327 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9329 (define_insn "*negdi2_1"
9330 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9331 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9332 (clobber (reg:CC FLAGS_REG))]
9334 && ix86_unary_operator_ok (NEG, DImode, operands)"
9338 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9339 (neg:DI (match_operand:DI 1 "general_operand" "")))
9340 (clobber (reg:CC FLAGS_REG))]
9341 "!TARGET_64BIT && reload_completed"
9343 [(set (reg:CCZ FLAGS_REG)
9344 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9345 (set (match_dup 0) (neg:SI (match_dup 2)))])
9348 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9351 (clobber (reg:CC FLAGS_REG))])
9354 (neg:SI (match_dup 1)))
9355 (clobber (reg:CC FLAGS_REG))])]
9356 "split_di (operands+1, 1, operands+2, operands+3);
9357 split_di (operands+0, 1, operands+0, operands+1);")
9359 (define_insn "*negdi2_1_rex64"
9360 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9361 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9362 (clobber (reg:CC FLAGS_REG))]
9363 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9365 [(set_attr "type" "negnot")
9366 (set_attr "mode" "DI")])
9368 ;; The problem with neg is that it does not perform (compare x 0),
9369 ;; it really performs (compare 0 x), which leaves us with the zero
9370 ;; flag being the only useful item.
9372 (define_insn "*negdi2_cmpz_rex64"
9373 [(set (reg:CCZ FLAGS_REG)
9374 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9376 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9377 (neg:DI (match_dup 1)))]
9378 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9380 [(set_attr "type" "negnot")
9381 (set_attr "mode" "DI")])
9384 (define_expand "negsi2"
9385 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9386 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9387 (clobber (reg:CC FLAGS_REG))])]
9389 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9391 (define_insn "*negsi2_1"
9392 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9393 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9394 (clobber (reg:CC FLAGS_REG))]
9395 "ix86_unary_operator_ok (NEG, SImode, operands)"
9397 [(set_attr "type" "negnot")
9398 (set_attr "mode" "SI")])
9400 ;; Combine is quite creative about this pattern.
9401 (define_insn "*negsi2_1_zext"
9402 [(set (match_operand:DI 0 "register_operand" "=r")
9403 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9406 (clobber (reg:CC FLAGS_REG))]
9407 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9409 [(set_attr "type" "negnot")
9410 (set_attr "mode" "SI")])
9412 ;; The problem with neg is that it does not perform (compare x 0),
9413 ;; it really performs (compare 0 x), which leaves us with the zero
9414 ;; flag being the only useful item.
9416 (define_insn "*negsi2_cmpz"
9417 [(set (reg:CCZ FLAGS_REG)
9418 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9420 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9421 (neg:SI (match_dup 1)))]
9422 "ix86_unary_operator_ok (NEG, SImode, operands)"
9424 [(set_attr "type" "negnot")
9425 (set_attr "mode" "SI")])
9427 (define_insn "*negsi2_cmpz_zext"
9428 [(set (reg:CCZ FLAGS_REG)
9429 (compare:CCZ (lshiftrt:DI
9431 (match_operand:DI 1 "register_operand" "0")
9435 (set (match_operand:DI 0 "register_operand" "=r")
9436 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9439 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9441 [(set_attr "type" "negnot")
9442 (set_attr "mode" "SI")])
9444 (define_expand "neghi2"
9445 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9446 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9447 (clobber (reg:CC FLAGS_REG))])]
9448 "TARGET_HIMODE_MATH"
9449 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9451 (define_insn "*neghi2_1"
9452 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9453 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9454 (clobber (reg:CC FLAGS_REG))]
9455 "ix86_unary_operator_ok (NEG, HImode, operands)"
9457 [(set_attr "type" "negnot")
9458 (set_attr "mode" "HI")])
9460 (define_insn "*neghi2_cmpz"
9461 [(set (reg:CCZ FLAGS_REG)
9462 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9464 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9465 (neg:HI (match_dup 1)))]
9466 "ix86_unary_operator_ok (NEG, HImode, operands)"
9468 [(set_attr "type" "negnot")
9469 (set_attr "mode" "HI")])
9471 (define_expand "negqi2"
9472 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9473 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9474 (clobber (reg:CC FLAGS_REG))])]
9475 "TARGET_QIMODE_MATH"
9476 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9478 (define_insn "*negqi2_1"
9479 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9480 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9481 (clobber (reg:CC FLAGS_REG))]
9482 "ix86_unary_operator_ok (NEG, QImode, operands)"
9484 [(set_attr "type" "negnot")
9485 (set_attr "mode" "QI")])
9487 (define_insn "*negqi2_cmpz"
9488 [(set (reg:CCZ FLAGS_REG)
9489 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9491 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9492 (neg:QI (match_dup 1)))]
9493 "ix86_unary_operator_ok (NEG, QImode, operands)"
9495 [(set_attr "type" "negnot")
9496 (set_attr "mode" "QI")])
9498 ;; Changing of sign for FP values is doable using integer unit too.
9500 (define_expand "negsf2"
9501 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9502 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9503 "TARGET_80387 || TARGET_SSE_MATH"
9504 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9506 (define_expand "abssf2"
9507 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9508 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9509 "TARGET_80387 || TARGET_SSE_MATH"
9510 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9512 (define_insn "*absnegsf2_mixed"
9513 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#f,x#f,f#x,rm")
9514 (match_operator:SF 3 "absneg_operator"
9515 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#f,0 ,0")]))
9516 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9517 (clobber (reg:CC FLAGS_REG))]
9518 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9519 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9522 (define_insn "*absnegsf2_sse"
9523 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9524 (match_operator:SF 3 "absneg_operator"
9525 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9526 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9527 (clobber (reg:CC FLAGS_REG))]
9529 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9532 (define_insn "*absnegsf2_i387"
9533 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9534 (match_operator:SF 3 "absneg_operator"
9535 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9536 (use (match_operand 2 "" ""))
9537 (clobber (reg:CC FLAGS_REG))]
9538 "TARGET_80387 && !TARGET_SSE_MATH
9539 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9542 (define_expand "copysignsf3"
9543 [(match_operand:SF 0 "register_operand" "")
9544 (match_operand:SF 1 "nonmemory_operand" "")
9545 (match_operand:SF 2 "register_operand" "")]
9548 ix86_expand_copysign (operands);
9552 (define_insn_and_split "copysignsf3_const"
9553 [(set (match_operand:SF 0 "register_operand" "=x")
9555 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9556 (match_operand:SF 2 "register_operand" "0")
9557 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9561 "&& reload_completed"
9564 ix86_split_copysign_const (operands);
9568 (define_insn "copysignsf3_var"
9569 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9571 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9572 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9573 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9574 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9576 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9581 [(set (match_operand:SF 0 "register_operand" "")
9583 [(match_operand:SF 2 "register_operand" "")
9584 (match_operand:SF 3 "register_operand" "")
9585 (match_operand:V4SF 4 "" "")
9586 (match_operand:V4SF 5 "" "")]
9588 (clobber (match_scratch:V4SF 1 ""))]
9589 "TARGET_SSE_MATH && reload_completed"
9592 ix86_split_copysign_var (operands);
9596 (define_expand "negdf2"
9597 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9598 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9599 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9600 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9602 (define_expand "absdf2"
9603 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9604 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9605 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9606 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9608 (define_insn "*absnegdf2_mixed"
9609 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,f#Y,rm")
9610 (match_operator:DF 3 "absneg_operator"
9611 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#f,0 ,0")]))
9612 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9613 (clobber (reg:CC FLAGS_REG))]
9614 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9615 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9618 (define_insn "*absnegdf2_sse"
9619 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9620 (match_operator:DF 3 "absneg_operator"
9621 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9622 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X"))
9623 (clobber (reg:CC FLAGS_REG))]
9624 "TARGET_SSE2 && TARGET_SSE_MATH
9625 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9628 (define_insn "*absnegdf2_i387"
9629 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9630 (match_operator:DF 3 "absneg_operator"
9631 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9632 (use (match_operand 2 "" ""))
9633 (clobber (reg:CC FLAGS_REG))]
9634 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9635 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9638 (define_expand "copysigndf3"
9639 [(match_operand:DF 0 "register_operand" "")
9640 (match_operand:DF 1 "nonmemory_operand" "")
9641 (match_operand:DF 2 "register_operand" "")]
9642 "TARGET_SSE2 && TARGET_SSE_MATH"
9644 ix86_expand_copysign (operands);
9648 (define_insn_and_split "copysigndf3_const"
9649 [(set (match_operand:DF 0 "register_operand" "=x")
9651 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9652 (match_operand:DF 2 "register_operand" "0")
9653 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9655 "TARGET_SSE2 && TARGET_SSE_MATH"
9657 "&& reload_completed"
9660 ix86_split_copysign_const (operands);
9664 (define_insn "copysigndf3_var"
9665 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9667 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9668 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9669 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9670 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9672 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9673 "TARGET_SSE2 && TARGET_SSE_MATH"
9677 [(set (match_operand:DF 0 "register_operand" "")
9679 [(match_operand:DF 2 "register_operand" "")
9680 (match_operand:DF 3 "register_operand" "")
9681 (match_operand:V2DF 4 "" "")
9682 (match_operand:V2DF 5 "" "")]
9684 (clobber (match_scratch:V2DF 1 ""))]
9685 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9688 ix86_split_copysign_var (operands);
9692 (define_expand "negxf2"
9693 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9694 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9696 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9698 (define_expand "absxf2"
9699 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9700 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9702 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9704 (define_insn "*absnegxf2_i387"
9705 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9706 (match_operator:XF 3 "absneg_operator"
9707 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9708 (use (match_operand 2 "" ""))
9709 (clobber (reg:CC FLAGS_REG))]
9711 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9714 ;; Splitters for fp abs and neg.
9717 [(set (match_operand 0 "fp_register_operand" "")
9718 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9719 (use (match_operand 2 "" ""))
9720 (clobber (reg:CC FLAGS_REG))]
9722 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9725 [(set (match_operand 0 "register_operand" "")
9726 (match_operator 3 "absneg_operator"
9727 [(match_operand 1 "register_operand" "")]))
9728 (use (match_operand 2 "nonimmediate_operand" ""))
9729 (clobber (reg:CC FLAGS_REG))]
9730 "reload_completed && SSE_REG_P (operands[0])"
9731 [(set (match_dup 0) (match_dup 3))]
9733 enum machine_mode mode = GET_MODE (operands[0]);
9734 enum machine_mode vmode = GET_MODE (operands[2]);
9737 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9738 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9739 if (operands_match_p (operands[0], operands[2]))
9742 operands[1] = operands[2];
9745 if (GET_CODE (operands[3]) == ABS)
9746 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9748 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9753 [(set (match_operand:SF 0 "register_operand" "")
9754 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9755 (use (match_operand:V4SF 2 "" ""))
9756 (clobber (reg:CC FLAGS_REG))]
9758 [(parallel [(set (match_dup 0) (match_dup 1))
9759 (clobber (reg:CC FLAGS_REG))])]
9762 operands[0] = gen_lowpart (SImode, operands[0]);
9763 if (GET_CODE (operands[1]) == ABS)
9765 tmp = gen_int_mode (0x7fffffff, SImode);
9766 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9770 tmp = gen_int_mode (0x80000000, SImode);
9771 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9777 [(set (match_operand:DF 0 "register_operand" "")
9778 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9779 (use (match_operand 2 "" ""))
9780 (clobber (reg:CC FLAGS_REG))]
9782 [(parallel [(set (match_dup 0) (match_dup 1))
9783 (clobber (reg:CC FLAGS_REG))])]
9788 tmp = gen_lowpart (DImode, operands[0]);
9789 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9792 if (GET_CODE (operands[1]) == ABS)
9795 tmp = gen_rtx_NOT (DImode, tmp);
9799 operands[0] = gen_highpart (SImode, operands[0]);
9800 if (GET_CODE (operands[1]) == ABS)
9802 tmp = gen_int_mode (0x7fffffff, SImode);
9803 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9807 tmp = gen_int_mode (0x80000000, SImode);
9808 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9815 [(set (match_operand:XF 0 "register_operand" "")
9816 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9817 (use (match_operand 2 "" ""))
9818 (clobber (reg:CC FLAGS_REG))]
9820 [(parallel [(set (match_dup 0) (match_dup 1))
9821 (clobber (reg:CC FLAGS_REG))])]
9824 operands[0] = gen_rtx_REG (SImode,
9825 true_regnum (operands[0])
9826 + (TARGET_64BIT ? 1 : 2));
9827 if (GET_CODE (operands[1]) == ABS)
9829 tmp = GEN_INT (0x7fff);
9830 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9834 tmp = GEN_INT (0x8000);
9835 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9841 [(set (match_operand 0 "memory_operand" "")
9842 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9843 (use (match_operand 2 "" ""))
9844 (clobber (reg:CC FLAGS_REG))]
9846 [(parallel [(set (match_dup 0) (match_dup 1))
9847 (clobber (reg:CC FLAGS_REG))])]
9849 enum machine_mode mode = GET_MODE (operands[0]);
9850 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9853 operands[0] = adjust_address (operands[0], QImode, size - 1);
9854 if (GET_CODE (operands[1]) == ABS)
9856 tmp = gen_int_mode (0x7f, QImode);
9857 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9861 tmp = gen_int_mode (0x80, QImode);
9862 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9867 ;; Conditionalize these after reload. If they match before reload, we
9868 ;; lose the clobber and ability to use integer instructions.
9870 (define_insn "*negsf2_1"
9871 [(set (match_operand:SF 0 "register_operand" "=f")
9872 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9873 "TARGET_80387 && reload_completed"
9875 [(set_attr "type" "fsgn")
9876 (set_attr "mode" "SF")])
9878 (define_insn "*negdf2_1"
9879 [(set (match_operand:DF 0 "register_operand" "=f")
9880 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9881 "TARGET_80387 && reload_completed"
9883 [(set_attr "type" "fsgn")
9884 (set_attr "mode" "DF")])
9886 (define_insn "*negxf2_1"
9887 [(set (match_operand:XF 0 "register_operand" "=f")
9888 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9889 "TARGET_80387 && reload_completed"
9891 [(set_attr "type" "fsgn")
9892 (set_attr "mode" "XF")])
9894 (define_insn "*abssf2_1"
9895 [(set (match_operand:SF 0 "register_operand" "=f")
9896 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9897 "TARGET_80387 && reload_completed"
9899 [(set_attr "type" "fsgn")
9900 (set_attr "mode" "SF")])
9902 (define_insn "*absdf2_1"
9903 [(set (match_operand:DF 0 "register_operand" "=f")
9904 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9905 "TARGET_80387 && reload_completed"
9907 [(set_attr "type" "fsgn")
9908 (set_attr "mode" "DF")])
9910 (define_insn "*absxf2_1"
9911 [(set (match_operand:XF 0 "register_operand" "=f")
9912 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9913 "TARGET_80387 && reload_completed"
9915 [(set_attr "type" "fsgn")
9916 (set_attr "mode" "DF")])
9918 (define_insn "*negextendsfdf2"
9919 [(set (match_operand:DF 0 "register_operand" "=f")
9920 (neg:DF (float_extend:DF
9921 (match_operand:SF 1 "register_operand" "0"))))]
9922 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9924 [(set_attr "type" "fsgn")
9925 (set_attr "mode" "DF")])
9927 (define_insn "*negextenddfxf2"
9928 [(set (match_operand:XF 0 "register_operand" "=f")
9929 (neg:XF (float_extend:XF
9930 (match_operand:DF 1 "register_operand" "0"))))]
9933 [(set_attr "type" "fsgn")
9934 (set_attr "mode" "XF")])
9936 (define_insn "*negextendsfxf2"
9937 [(set (match_operand:XF 0 "register_operand" "=f")
9938 (neg:XF (float_extend:XF
9939 (match_operand:SF 1 "register_operand" "0"))))]
9942 [(set_attr "type" "fsgn")
9943 (set_attr "mode" "XF")])
9945 (define_insn "*absextendsfdf2"
9946 [(set (match_operand:DF 0 "register_operand" "=f")
9947 (abs:DF (float_extend:DF
9948 (match_operand:SF 1 "register_operand" "0"))))]
9949 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9951 [(set_attr "type" "fsgn")
9952 (set_attr "mode" "DF")])
9954 (define_insn "*absextenddfxf2"
9955 [(set (match_operand:XF 0 "register_operand" "=f")
9956 (abs:XF (float_extend:XF
9957 (match_operand:DF 1 "register_operand" "0"))))]
9960 [(set_attr "type" "fsgn")
9961 (set_attr "mode" "XF")])
9963 (define_insn "*absextendsfxf2"
9964 [(set (match_operand:XF 0 "register_operand" "=f")
9965 (abs:XF (float_extend:XF
9966 (match_operand:SF 1 "register_operand" "0"))))]
9969 [(set_attr "type" "fsgn")
9970 (set_attr "mode" "XF")])
9972 ;; One complement instructions
9974 (define_expand "one_cmpldi2"
9975 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9976 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9978 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9980 (define_insn "*one_cmpldi2_1_rex64"
9981 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9982 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9983 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9985 [(set_attr "type" "negnot")
9986 (set_attr "mode" "DI")])
9988 (define_insn "*one_cmpldi2_2_rex64"
9989 [(set (reg FLAGS_REG)
9990 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9992 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9993 (not:DI (match_dup 1)))]
9994 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9995 && ix86_unary_operator_ok (NOT, DImode, operands)"
9997 [(set_attr "type" "alu1")
9998 (set_attr "mode" "DI")])
10001 [(set (match_operand 0 "flags_reg_operand" "")
10002 (match_operator 2 "compare_operator"
10003 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10005 (set (match_operand:DI 1 "nonimmediate_operand" "")
10006 (not:DI (match_dup 3)))]
10007 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10008 [(parallel [(set (match_dup 0)
10010 [(xor:DI (match_dup 3) (const_int -1))
10013 (xor:DI (match_dup 3) (const_int -1)))])]
10016 (define_expand "one_cmplsi2"
10017 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10018 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10020 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10022 (define_insn "*one_cmplsi2_1"
10023 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10024 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10025 "ix86_unary_operator_ok (NOT, SImode, operands)"
10027 [(set_attr "type" "negnot")
10028 (set_attr "mode" "SI")])
10030 ;; ??? Currently never generated - xor is used instead.
10031 (define_insn "*one_cmplsi2_1_zext"
10032 [(set (match_operand:DI 0 "register_operand" "=r")
10033 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10034 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10036 [(set_attr "type" "negnot")
10037 (set_attr "mode" "SI")])
10039 (define_insn "*one_cmplsi2_2"
10040 [(set (reg FLAGS_REG)
10041 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10043 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10044 (not:SI (match_dup 1)))]
10045 "ix86_match_ccmode (insn, CCNOmode)
10046 && ix86_unary_operator_ok (NOT, SImode, operands)"
10048 [(set_attr "type" "alu1")
10049 (set_attr "mode" "SI")])
10052 [(set (match_operand 0 "flags_reg_operand" "")
10053 (match_operator 2 "compare_operator"
10054 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10056 (set (match_operand:SI 1 "nonimmediate_operand" "")
10057 (not:SI (match_dup 3)))]
10058 "ix86_match_ccmode (insn, CCNOmode)"
10059 [(parallel [(set (match_dup 0)
10060 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10063 (xor:SI (match_dup 3) (const_int -1)))])]
10066 ;; ??? Currently never generated - xor is used instead.
10067 (define_insn "*one_cmplsi2_2_zext"
10068 [(set (reg FLAGS_REG)
10069 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10071 (set (match_operand:DI 0 "register_operand" "=r")
10072 (zero_extend:DI (not:SI (match_dup 1))))]
10073 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10074 && ix86_unary_operator_ok (NOT, SImode, operands)"
10076 [(set_attr "type" "alu1")
10077 (set_attr "mode" "SI")])
10080 [(set (match_operand 0 "flags_reg_operand" "")
10081 (match_operator 2 "compare_operator"
10082 [(not:SI (match_operand:SI 3 "register_operand" ""))
10084 (set (match_operand:DI 1 "register_operand" "")
10085 (zero_extend:DI (not:SI (match_dup 3))))]
10086 "ix86_match_ccmode (insn, CCNOmode)"
10087 [(parallel [(set (match_dup 0)
10088 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10091 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10094 (define_expand "one_cmplhi2"
10095 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10096 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10097 "TARGET_HIMODE_MATH"
10098 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10100 (define_insn "*one_cmplhi2_1"
10101 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10102 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10103 "ix86_unary_operator_ok (NOT, HImode, operands)"
10105 [(set_attr "type" "negnot")
10106 (set_attr "mode" "HI")])
10108 (define_insn "*one_cmplhi2_2"
10109 [(set (reg FLAGS_REG)
10110 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10112 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10113 (not:HI (match_dup 1)))]
10114 "ix86_match_ccmode (insn, CCNOmode)
10115 && ix86_unary_operator_ok (NEG, HImode, operands)"
10117 [(set_attr "type" "alu1")
10118 (set_attr "mode" "HI")])
10121 [(set (match_operand 0 "flags_reg_operand" "")
10122 (match_operator 2 "compare_operator"
10123 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10125 (set (match_operand:HI 1 "nonimmediate_operand" "")
10126 (not:HI (match_dup 3)))]
10127 "ix86_match_ccmode (insn, CCNOmode)"
10128 [(parallel [(set (match_dup 0)
10129 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10132 (xor:HI (match_dup 3) (const_int -1)))])]
10135 ;; %%% Potential partial reg stall on alternative 1. What to do?
10136 (define_expand "one_cmplqi2"
10137 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10138 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10139 "TARGET_QIMODE_MATH"
10140 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10142 (define_insn "*one_cmplqi2_1"
10143 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10144 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10145 "ix86_unary_operator_ok (NOT, QImode, operands)"
10149 [(set_attr "type" "negnot")
10150 (set_attr "mode" "QI,SI")])
10152 (define_insn "*one_cmplqi2_2"
10153 [(set (reg FLAGS_REG)
10154 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10156 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10157 (not:QI (match_dup 1)))]
10158 "ix86_match_ccmode (insn, CCNOmode)
10159 && ix86_unary_operator_ok (NOT, QImode, operands)"
10161 [(set_attr "type" "alu1")
10162 (set_attr "mode" "QI")])
10165 [(set (match_operand 0 "flags_reg_operand" "")
10166 (match_operator 2 "compare_operator"
10167 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10169 (set (match_operand:QI 1 "nonimmediate_operand" "")
10170 (not:QI (match_dup 3)))]
10171 "ix86_match_ccmode (insn, CCNOmode)"
10172 [(parallel [(set (match_dup 0)
10173 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10176 (xor:QI (match_dup 3) (const_int -1)))])]
10179 ;; Arithmetic shift instructions
10181 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10182 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10183 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10184 ;; from the assembler input.
10186 ;; This instruction shifts the target reg/mem as usual, but instead of
10187 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10188 ;; is a left shift double, bits are taken from the high order bits of
10189 ;; reg, else if the insn is a shift right double, bits are taken from the
10190 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10191 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10193 ;; Since sh[lr]d does not change the `reg' operand, that is done
10194 ;; separately, making all shifts emit pairs of shift double and normal
10195 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10196 ;; support a 63 bit shift, each shift where the count is in a reg expands
10197 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10199 ;; If the shift count is a constant, we need never emit more than one
10200 ;; shift pair, instead using moves and sign extension for counts greater
10203 (define_expand "ashlti3"
10204 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10205 (ashift:TI (match_operand:TI 1 "register_operand" "")
10206 (match_operand:QI 2 "nonmemory_operand" "")))
10207 (clobber (reg:CC FLAGS_REG))])]
10210 if (! immediate_operand (operands[2], QImode))
10212 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10215 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10219 (define_insn "ashlti3_1"
10220 [(set (match_operand:TI 0 "register_operand" "=r")
10221 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10222 (match_operand:QI 2 "register_operand" "c")))
10223 (clobber (match_scratch:DI 3 "=&r"))
10224 (clobber (reg:CC FLAGS_REG))]
10227 [(set_attr "type" "multi")])
10229 (define_insn "*ashlti3_2"
10230 [(set (match_operand:TI 0 "register_operand" "=r")
10231 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10232 (match_operand:QI 2 "immediate_operand" "O")))
10233 (clobber (reg:CC FLAGS_REG))]
10236 [(set_attr "type" "multi")])
10239 [(set (match_operand:TI 0 "register_operand" "")
10240 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10241 (match_operand:QI 2 "register_operand" "")))
10242 (clobber (match_scratch:DI 3 ""))
10243 (clobber (reg:CC FLAGS_REG))]
10244 "TARGET_64BIT && reload_completed"
10246 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10249 [(set (match_operand:TI 0 "register_operand" "")
10250 (ashift:TI (match_operand:TI 1 "register_operand" "")
10251 (match_operand:QI 2 "immediate_operand" "")))
10252 (clobber (reg:CC FLAGS_REG))]
10253 "TARGET_64BIT && reload_completed"
10255 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10257 (define_insn "x86_64_shld"
10258 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10259 (ior:DI (ashift:DI (match_dup 0)
10260 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10261 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10262 (minus:QI (const_int 64) (match_dup 2)))))
10263 (clobber (reg:CC FLAGS_REG))]
10266 shld{q}\t{%2, %1, %0|%0, %1, %2}
10267 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10268 [(set_attr "type" "ishift")
10269 (set_attr "prefix_0f" "1")
10270 (set_attr "mode" "DI")
10271 (set_attr "athlon_decode" "vector")])
10273 (define_expand "x86_64_shift_adj"
10274 [(set (reg:CCZ FLAGS_REG)
10275 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10278 (set (match_operand:DI 0 "register_operand" "")
10279 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10280 (match_operand:DI 1 "register_operand" "")
10283 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10284 (match_operand:DI 3 "register_operand" "r")
10289 (define_expand "ashldi3"
10290 [(set (match_operand:DI 0 "shiftdi_operand" "")
10291 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10292 (match_operand:QI 2 "nonmemory_operand" "")))]
10294 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10296 (define_insn "*ashldi3_1_rex64"
10297 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10298 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10299 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10300 (clobber (reg:CC FLAGS_REG))]
10301 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10303 switch (get_attr_type (insn))
10306 gcc_assert (operands[2] == const1_rtx);
10307 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10308 return "add{q}\t{%0, %0|%0, %0}";
10311 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10312 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10313 operands[1] = gen_rtx_MULT (DImode, operands[1],
10314 GEN_INT (1 << INTVAL (operands[2])));
10315 return "lea{q}\t{%a1, %0|%0, %a1}";
10318 if (REG_P (operands[2]))
10319 return "sal{q}\t{%b2, %0|%0, %b2}";
10320 else if (operands[2] == const1_rtx
10321 && (TARGET_SHIFT1 || optimize_size))
10322 return "sal{q}\t%0";
10324 return "sal{q}\t{%2, %0|%0, %2}";
10327 [(set (attr "type")
10328 (cond [(eq_attr "alternative" "1")
10329 (const_string "lea")
10330 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10332 (match_operand 0 "register_operand" ""))
10333 (match_operand 2 "const1_operand" ""))
10334 (const_string "alu")
10336 (const_string "ishift")))
10337 (set_attr "mode" "DI")])
10339 ;; Convert lea to the lea pattern to avoid flags dependency.
10341 [(set (match_operand:DI 0 "register_operand" "")
10342 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10343 (match_operand:QI 2 "immediate_operand" "")))
10344 (clobber (reg:CC FLAGS_REG))]
10345 "TARGET_64BIT && reload_completed
10346 && true_regnum (operands[0]) != true_regnum (operands[1])"
10347 [(set (match_dup 0)
10348 (mult:DI (match_dup 1)
10350 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10352 ;; This pattern can't accept a variable shift count, since shifts by
10353 ;; zero don't affect the flags. We assume that shifts by constant
10354 ;; zero are optimized away.
10355 (define_insn "*ashldi3_cmp_rex64"
10356 [(set (reg FLAGS_REG)
10358 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10359 (match_operand:QI 2 "immediate_operand" "e"))
10361 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10362 (ashift:DI (match_dup 1) (match_dup 2)))]
10363 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10364 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10366 switch (get_attr_type (insn))
10369 gcc_assert (operands[2] == const1_rtx);
10370 return "add{q}\t{%0, %0|%0, %0}";
10373 if (REG_P (operands[2]))
10374 return "sal{q}\t{%b2, %0|%0, %b2}";
10375 else if (operands[2] == const1_rtx
10376 && (TARGET_SHIFT1 || optimize_size))
10377 return "sal{q}\t%0";
10379 return "sal{q}\t{%2, %0|%0, %2}";
10382 [(set (attr "type")
10383 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10385 (match_operand 0 "register_operand" ""))
10386 (match_operand 2 "const1_operand" ""))
10387 (const_string "alu")
10389 (const_string "ishift")))
10390 (set_attr "mode" "DI")])
10392 (define_insn "*ashldi3_1"
10393 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10394 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10395 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10396 (clobber (reg:CC FLAGS_REG))]
10399 [(set_attr "type" "multi")])
10401 ;; By default we don't ask for a scratch register, because when DImode
10402 ;; values are manipulated, registers are already at a premium. But if
10403 ;; we have one handy, we won't turn it away.
10405 [(match_scratch:SI 3 "r")
10406 (parallel [(set (match_operand:DI 0 "register_operand" "")
10407 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10408 (match_operand:QI 2 "nonmemory_operand" "")))
10409 (clobber (reg:CC FLAGS_REG))])
10411 "!TARGET_64BIT && TARGET_CMOVE"
10413 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10416 [(set (match_operand:DI 0 "register_operand" "")
10417 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10418 (match_operand:QI 2 "nonmemory_operand" "")))
10419 (clobber (reg:CC FLAGS_REG))]
10420 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10421 ? flow2_completed : reload_completed)"
10423 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10425 (define_insn "x86_shld_1"
10426 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10427 (ior:SI (ashift:SI (match_dup 0)
10428 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10429 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10430 (minus:QI (const_int 32) (match_dup 2)))))
10431 (clobber (reg:CC FLAGS_REG))]
10434 shld{l}\t{%2, %1, %0|%0, %1, %2}
10435 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10436 [(set_attr "type" "ishift")
10437 (set_attr "prefix_0f" "1")
10438 (set_attr "mode" "SI")
10439 (set_attr "pent_pair" "np")
10440 (set_attr "athlon_decode" "vector")])
10442 (define_expand "x86_shift_adj_1"
10443 [(set (reg:CCZ FLAGS_REG)
10444 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10447 (set (match_operand:SI 0 "register_operand" "")
10448 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10449 (match_operand:SI 1 "register_operand" "")
10452 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10453 (match_operand:SI 3 "register_operand" "r")
10458 (define_expand "x86_shift_adj_2"
10459 [(use (match_operand:SI 0 "register_operand" ""))
10460 (use (match_operand:SI 1 "register_operand" ""))
10461 (use (match_operand:QI 2 "register_operand" ""))]
10464 rtx label = gen_label_rtx ();
10467 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10469 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10470 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10471 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10472 gen_rtx_LABEL_REF (VOIDmode, label),
10474 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10475 JUMP_LABEL (tmp) = label;
10477 emit_move_insn (operands[0], operands[1]);
10478 ix86_expand_clear (operands[1]);
10480 emit_label (label);
10481 LABEL_NUSES (label) = 1;
10486 (define_expand "ashlsi3"
10487 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10488 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10489 (match_operand:QI 2 "nonmemory_operand" "")))
10490 (clobber (reg:CC FLAGS_REG))]
10492 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10494 (define_insn "*ashlsi3_1"
10495 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10496 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10497 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10498 (clobber (reg:CC FLAGS_REG))]
10499 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10501 switch (get_attr_type (insn))
10504 gcc_assert (operands[2] == const1_rtx);
10505 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10506 return "add{l}\t{%0, %0|%0, %0}";
10512 if (REG_P (operands[2]))
10513 return "sal{l}\t{%b2, %0|%0, %b2}";
10514 else if (operands[2] == const1_rtx
10515 && (TARGET_SHIFT1 || optimize_size))
10516 return "sal{l}\t%0";
10518 return "sal{l}\t{%2, %0|%0, %2}";
10521 [(set (attr "type")
10522 (cond [(eq_attr "alternative" "1")
10523 (const_string "lea")
10524 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10526 (match_operand 0 "register_operand" ""))
10527 (match_operand 2 "const1_operand" ""))
10528 (const_string "alu")
10530 (const_string "ishift")))
10531 (set_attr "mode" "SI")])
10533 ;; Convert lea to the lea pattern to avoid flags dependency.
10535 [(set (match_operand 0 "register_operand" "")
10536 (ashift (match_operand 1 "index_register_operand" "")
10537 (match_operand:QI 2 "const_int_operand" "")))
10538 (clobber (reg:CC FLAGS_REG))]
10540 && true_regnum (operands[0]) != true_regnum (operands[1])
10541 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10545 enum machine_mode mode = GET_MODE (operands[0]);
10547 if (GET_MODE_SIZE (mode) < 4)
10548 operands[0] = gen_lowpart (SImode, operands[0]);
10550 operands[1] = gen_lowpart (Pmode, operands[1]);
10551 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10553 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10554 if (Pmode != SImode)
10555 pat = gen_rtx_SUBREG (SImode, pat, 0);
10556 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10560 ;; Rare case of shifting RSP is handled by generating move and shift
10562 [(set (match_operand 0 "register_operand" "")
10563 (ashift (match_operand 1 "register_operand" "")
10564 (match_operand:QI 2 "const_int_operand" "")))
10565 (clobber (reg:CC FLAGS_REG))]
10567 && true_regnum (operands[0]) != true_regnum (operands[1])"
10571 emit_move_insn (operands[1], operands[0]);
10572 pat = gen_rtx_SET (VOIDmode, operands[0],
10573 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10574 operands[0], operands[2]));
10575 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10576 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10580 (define_insn "*ashlsi3_1_zext"
10581 [(set (match_operand:DI 0 "register_operand" "=r,r")
10582 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10583 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10584 (clobber (reg:CC FLAGS_REG))]
10585 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10587 switch (get_attr_type (insn))
10590 gcc_assert (operands[2] == const1_rtx);
10591 return "add{l}\t{%k0, %k0|%k0, %k0}";
10597 if (REG_P (operands[2]))
10598 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10599 else if (operands[2] == const1_rtx
10600 && (TARGET_SHIFT1 || optimize_size))
10601 return "sal{l}\t%k0";
10603 return "sal{l}\t{%2, %k0|%k0, %2}";
10606 [(set (attr "type")
10607 (cond [(eq_attr "alternative" "1")
10608 (const_string "lea")
10609 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10611 (match_operand 2 "const1_operand" ""))
10612 (const_string "alu")
10614 (const_string "ishift")))
10615 (set_attr "mode" "SI")])
10617 ;; Convert lea to the lea pattern to avoid flags dependency.
10619 [(set (match_operand:DI 0 "register_operand" "")
10620 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10621 (match_operand:QI 2 "const_int_operand" ""))))
10622 (clobber (reg:CC FLAGS_REG))]
10623 "TARGET_64BIT && reload_completed
10624 && true_regnum (operands[0]) != true_regnum (operands[1])"
10625 [(set (match_dup 0) (zero_extend:DI
10626 (subreg:SI (mult:SI (match_dup 1)
10627 (match_dup 2)) 0)))]
10629 operands[1] = gen_lowpart (Pmode, operands[1]);
10630 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10633 ;; This pattern can't accept a variable shift count, since shifts by
10634 ;; zero don't affect the flags. We assume that shifts by constant
10635 ;; zero are optimized away.
10636 (define_insn "*ashlsi3_cmp"
10637 [(set (reg FLAGS_REG)
10639 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10640 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10642 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10643 (ashift:SI (match_dup 1) (match_dup 2)))]
10644 "ix86_match_ccmode (insn, CCGOCmode)
10645 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10647 switch (get_attr_type (insn))
10650 gcc_assert (operands[2] == const1_rtx);
10651 return "add{l}\t{%0, %0|%0, %0}";
10654 if (REG_P (operands[2]))
10655 return "sal{l}\t{%b2, %0|%0, %b2}";
10656 else if (operands[2] == const1_rtx
10657 && (TARGET_SHIFT1 || optimize_size))
10658 return "sal{l}\t%0";
10660 return "sal{l}\t{%2, %0|%0, %2}";
10663 [(set (attr "type")
10664 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10666 (match_operand 0 "register_operand" ""))
10667 (match_operand 2 "const1_operand" ""))
10668 (const_string "alu")
10670 (const_string "ishift")))
10671 (set_attr "mode" "SI")])
10673 (define_insn "*ashlsi3_cmp_zext"
10674 [(set (reg FLAGS_REG)
10676 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10677 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10679 (set (match_operand:DI 0 "register_operand" "=r")
10680 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10681 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10682 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10684 switch (get_attr_type (insn))
10687 gcc_assert (operands[2] == const1_rtx);
10688 return "add{l}\t{%k0, %k0|%k0, %k0}";
10691 if (REG_P (operands[2]))
10692 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10693 else if (operands[2] == const1_rtx
10694 && (TARGET_SHIFT1 || optimize_size))
10695 return "sal{l}\t%k0";
10697 return "sal{l}\t{%2, %k0|%k0, %2}";
10700 [(set (attr "type")
10701 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10703 (match_operand 2 "const1_operand" ""))
10704 (const_string "alu")
10706 (const_string "ishift")))
10707 (set_attr "mode" "SI")])
10709 (define_expand "ashlhi3"
10710 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10711 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10712 (match_operand:QI 2 "nonmemory_operand" "")))
10713 (clobber (reg:CC FLAGS_REG))]
10714 "TARGET_HIMODE_MATH"
10715 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10717 (define_insn "*ashlhi3_1_lea"
10718 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10719 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10720 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10721 (clobber (reg:CC FLAGS_REG))]
10722 "!TARGET_PARTIAL_REG_STALL
10723 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10725 switch (get_attr_type (insn))
10730 gcc_assert (operands[2] == const1_rtx);
10731 return "add{w}\t{%0, %0|%0, %0}";
10734 if (REG_P (operands[2]))
10735 return "sal{w}\t{%b2, %0|%0, %b2}";
10736 else if (operands[2] == const1_rtx
10737 && (TARGET_SHIFT1 || optimize_size))
10738 return "sal{w}\t%0";
10740 return "sal{w}\t{%2, %0|%0, %2}";
10743 [(set (attr "type")
10744 (cond [(eq_attr "alternative" "1")
10745 (const_string "lea")
10746 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10748 (match_operand 0 "register_operand" ""))
10749 (match_operand 2 "const1_operand" ""))
10750 (const_string "alu")
10752 (const_string "ishift")))
10753 (set_attr "mode" "HI,SI")])
10755 (define_insn "*ashlhi3_1"
10756 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10757 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10758 (match_operand:QI 2 "nonmemory_operand" "cI")))
10759 (clobber (reg:CC FLAGS_REG))]
10760 "TARGET_PARTIAL_REG_STALL
10761 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10763 switch (get_attr_type (insn))
10766 gcc_assert (operands[2] == const1_rtx);
10767 return "add{w}\t{%0, %0|%0, %0}";
10770 if (REG_P (operands[2]))
10771 return "sal{w}\t{%b2, %0|%0, %b2}";
10772 else if (operands[2] == const1_rtx
10773 && (TARGET_SHIFT1 || optimize_size))
10774 return "sal{w}\t%0";
10776 return "sal{w}\t{%2, %0|%0, %2}";
10779 [(set (attr "type")
10780 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10782 (match_operand 0 "register_operand" ""))
10783 (match_operand 2 "const1_operand" ""))
10784 (const_string "alu")
10786 (const_string "ishift")))
10787 (set_attr "mode" "HI")])
10789 ;; This pattern can't accept a variable shift count, since shifts by
10790 ;; zero don't affect the flags. We assume that shifts by constant
10791 ;; zero are optimized away.
10792 (define_insn "*ashlhi3_cmp"
10793 [(set (reg FLAGS_REG)
10795 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10796 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10798 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10799 (ashift:HI (match_dup 1) (match_dup 2)))]
10800 "ix86_match_ccmode (insn, CCGOCmode)
10801 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10803 switch (get_attr_type (insn))
10806 gcc_assert (operands[2] == const1_rtx);
10807 return "add{w}\t{%0, %0|%0, %0}";
10810 if (REG_P (operands[2]))
10811 return "sal{w}\t{%b2, %0|%0, %b2}";
10812 else if (operands[2] == const1_rtx
10813 && (TARGET_SHIFT1 || optimize_size))
10814 return "sal{w}\t%0";
10816 return "sal{w}\t{%2, %0|%0, %2}";
10819 [(set (attr "type")
10820 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10822 (match_operand 0 "register_operand" ""))
10823 (match_operand 2 "const1_operand" ""))
10824 (const_string "alu")
10826 (const_string "ishift")))
10827 (set_attr "mode" "HI")])
10829 (define_expand "ashlqi3"
10830 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10831 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10832 (match_operand:QI 2 "nonmemory_operand" "")))
10833 (clobber (reg:CC FLAGS_REG))]
10834 "TARGET_QIMODE_MATH"
10835 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10837 ;; %%% Potential partial reg stall on alternative 2. What to do?
10839 (define_insn "*ashlqi3_1_lea"
10840 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10841 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10842 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10843 (clobber (reg:CC FLAGS_REG))]
10844 "!TARGET_PARTIAL_REG_STALL
10845 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10847 switch (get_attr_type (insn))
10852 gcc_assert (operands[2] == const1_rtx);
10853 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10854 return "add{l}\t{%k0, %k0|%k0, %k0}";
10856 return "add{b}\t{%0, %0|%0, %0}";
10859 if (REG_P (operands[2]))
10861 if (get_attr_mode (insn) == MODE_SI)
10862 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10864 return "sal{b}\t{%b2, %0|%0, %b2}";
10866 else if (operands[2] == const1_rtx
10867 && (TARGET_SHIFT1 || optimize_size))
10869 if (get_attr_mode (insn) == MODE_SI)
10870 return "sal{l}\t%0";
10872 return "sal{b}\t%0";
10876 if (get_attr_mode (insn) == MODE_SI)
10877 return "sal{l}\t{%2, %k0|%k0, %2}";
10879 return "sal{b}\t{%2, %0|%0, %2}";
10883 [(set (attr "type")
10884 (cond [(eq_attr "alternative" "2")
10885 (const_string "lea")
10886 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10888 (match_operand 0 "register_operand" ""))
10889 (match_operand 2 "const1_operand" ""))
10890 (const_string "alu")
10892 (const_string "ishift")))
10893 (set_attr "mode" "QI,SI,SI")])
10895 (define_insn "*ashlqi3_1"
10896 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10897 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10898 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10899 (clobber (reg:CC FLAGS_REG))]
10900 "TARGET_PARTIAL_REG_STALL
10901 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10903 switch (get_attr_type (insn))
10906 gcc_assert (operands[2] == const1_rtx);
10907 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10908 return "add{l}\t{%k0, %k0|%k0, %k0}";
10910 return "add{b}\t{%0, %0|%0, %0}";
10913 if (REG_P (operands[2]))
10915 if (get_attr_mode (insn) == MODE_SI)
10916 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10918 return "sal{b}\t{%b2, %0|%0, %b2}";
10920 else if (operands[2] == const1_rtx
10921 && (TARGET_SHIFT1 || optimize_size))
10923 if (get_attr_mode (insn) == MODE_SI)
10924 return "sal{l}\t%0";
10926 return "sal{b}\t%0";
10930 if (get_attr_mode (insn) == MODE_SI)
10931 return "sal{l}\t{%2, %k0|%k0, %2}";
10933 return "sal{b}\t{%2, %0|%0, %2}";
10937 [(set (attr "type")
10938 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10940 (match_operand 0 "register_operand" ""))
10941 (match_operand 2 "const1_operand" ""))
10942 (const_string "alu")
10944 (const_string "ishift")))
10945 (set_attr "mode" "QI,SI")])
10947 ;; This pattern can't accept a variable shift count, since shifts by
10948 ;; zero don't affect the flags. We assume that shifts by constant
10949 ;; zero are optimized away.
10950 (define_insn "*ashlqi3_cmp"
10951 [(set (reg FLAGS_REG)
10953 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10954 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10956 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10957 (ashift:QI (match_dup 1) (match_dup 2)))]
10958 "ix86_match_ccmode (insn, CCGOCmode)
10959 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10961 switch (get_attr_type (insn))
10964 gcc_assert (operands[2] == const1_rtx);
10965 return "add{b}\t{%0, %0|%0, %0}";
10968 if (REG_P (operands[2]))
10969 return "sal{b}\t{%b2, %0|%0, %b2}";
10970 else if (operands[2] == const1_rtx
10971 && (TARGET_SHIFT1 || optimize_size))
10972 return "sal{b}\t%0";
10974 return "sal{b}\t{%2, %0|%0, %2}";
10977 [(set (attr "type")
10978 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980 (match_operand 0 "register_operand" ""))
10981 (match_operand 2 "const1_operand" ""))
10982 (const_string "alu")
10984 (const_string "ishift")))
10985 (set_attr "mode" "QI")])
10987 ;; See comment above `ashldi3' about how this works.
10989 (define_expand "ashrti3"
10990 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10991 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10992 (match_operand:QI 2 "nonmemory_operand" "")))
10993 (clobber (reg:CC FLAGS_REG))])]
10996 if (! immediate_operand (operands[2], QImode))
10998 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11001 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11005 (define_insn "ashrti3_1"
11006 [(set (match_operand:TI 0 "register_operand" "=r")
11007 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11008 (match_operand:QI 2 "register_operand" "c")))
11009 (clobber (match_scratch:DI 3 "=&r"))
11010 (clobber (reg:CC FLAGS_REG))]
11013 [(set_attr "type" "multi")])
11015 (define_insn "*ashrti3_2"
11016 [(set (match_operand:TI 0 "register_operand" "=r")
11017 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11018 (match_operand:QI 2 "immediate_operand" "O")))
11019 (clobber (reg:CC FLAGS_REG))]
11022 [(set_attr "type" "multi")])
11025 [(set (match_operand:TI 0 "register_operand" "")
11026 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11027 (match_operand:QI 2 "register_operand" "")))
11028 (clobber (match_scratch:DI 3 ""))
11029 (clobber (reg:CC FLAGS_REG))]
11030 "TARGET_64BIT && reload_completed"
11032 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11035 [(set (match_operand:TI 0 "register_operand" "")
11036 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11037 (match_operand:QI 2 "immediate_operand" "")))
11038 (clobber (reg:CC FLAGS_REG))]
11039 "TARGET_64BIT && reload_completed"
11041 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11043 (define_insn "x86_64_shrd"
11044 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11045 (ior:DI (ashiftrt:DI (match_dup 0)
11046 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11047 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11048 (minus:QI (const_int 64) (match_dup 2)))))
11049 (clobber (reg:CC FLAGS_REG))]
11052 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11053 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11054 [(set_attr "type" "ishift")
11055 (set_attr "prefix_0f" "1")
11056 (set_attr "mode" "DI")
11057 (set_attr "athlon_decode" "vector")])
11059 (define_expand "ashrdi3"
11060 [(set (match_operand:DI 0 "shiftdi_operand" "")
11061 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11062 (match_operand:QI 2 "nonmemory_operand" "")))]
11064 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11066 (define_insn "*ashrdi3_63_rex64"
11067 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11068 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11069 (match_operand:DI 2 "const_int_operand" "i,i")))
11070 (clobber (reg:CC FLAGS_REG))]
11071 "TARGET_64BIT && INTVAL (operands[2]) == 63
11072 && (TARGET_USE_CLTD || optimize_size)
11073 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11076 sar{q}\t{%2, %0|%0, %2}"
11077 [(set_attr "type" "imovx,ishift")
11078 (set_attr "prefix_0f" "0,*")
11079 (set_attr "length_immediate" "0,*")
11080 (set_attr "modrm" "0,1")
11081 (set_attr "mode" "DI")])
11083 (define_insn "*ashrdi3_1_one_bit_rex64"
11084 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11085 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11086 (match_operand:QI 2 "const1_operand" "")))
11087 (clobber (reg:CC FLAGS_REG))]
11088 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11089 && (TARGET_SHIFT1 || optimize_size)"
11091 [(set_attr "type" "ishift")
11092 (set (attr "length")
11093 (if_then_else (match_operand:DI 0 "register_operand" "")
11095 (const_string "*")))])
11097 (define_insn "*ashrdi3_1_rex64"
11098 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11099 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11100 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11101 (clobber (reg:CC FLAGS_REG))]
11102 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11104 sar{q}\t{%2, %0|%0, %2}
11105 sar{q}\t{%b2, %0|%0, %b2}"
11106 [(set_attr "type" "ishift")
11107 (set_attr "mode" "DI")])
11109 ;; This pattern can't accept a variable shift count, since shifts by
11110 ;; zero don't affect the flags. We assume that shifts by constant
11111 ;; zero are optimized away.
11112 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11113 [(set (reg FLAGS_REG)
11115 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11116 (match_operand:QI 2 "const1_operand" ""))
11118 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11119 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11120 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11121 && (TARGET_SHIFT1 || optimize_size)
11122 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11124 [(set_attr "type" "ishift")
11125 (set (attr "length")
11126 (if_then_else (match_operand:DI 0 "register_operand" "")
11128 (const_string "*")))])
11130 ;; This pattern can't accept a variable shift count, since shifts by
11131 ;; zero don't affect the flags. We assume that shifts by constant
11132 ;; zero are optimized away.
11133 (define_insn "*ashrdi3_cmp_rex64"
11134 [(set (reg FLAGS_REG)
11136 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11137 (match_operand:QI 2 "const_int_operand" "n"))
11139 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11140 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11141 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11142 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11143 "sar{q}\t{%2, %0|%0, %2}"
11144 [(set_attr "type" "ishift")
11145 (set_attr "mode" "DI")])
11147 (define_insn "*ashrdi3_1"
11148 [(set (match_operand:DI 0 "register_operand" "=r")
11149 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11150 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11151 (clobber (reg:CC FLAGS_REG))]
11154 [(set_attr "type" "multi")])
11156 ;; By default we don't ask for a scratch register, because when DImode
11157 ;; values are manipulated, registers are already at a premium. But if
11158 ;; we have one handy, we won't turn it away.
11160 [(match_scratch:SI 3 "r")
11161 (parallel [(set (match_operand:DI 0 "register_operand" "")
11162 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11163 (match_operand:QI 2 "nonmemory_operand" "")))
11164 (clobber (reg:CC FLAGS_REG))])
11166 "!TARGET_64BIT && TARGET_CMOVE"
11168 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11171 [(set (match_operand:DI 0 "register_operand" "")
11172 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11173 (match_operand:QI 2 "nonmemory_operand" "")))
11174 (clobber (reg:CC FLAGS_REG))]
11175 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11176 ? flow2_completed : reload_completed)"
11178 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11180 (define_insn "x86_shrd_1"
11181 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11182 (ior:SI (ashiftrt:SI (match_dup 0)
11183 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11184 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11185 (minus:QI (const_int 32) (match_dup 2)))))
11186 (clobber (reg:CC FLAGS_REG))]
11189 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11190 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11191 [(set_attr "type" "ishift")
11192 (set_attr "prefix_0f" "1")
11193 (set_attr "pent_pair" "np")
11194 (set_attr "mode" "SI")])
11196 (define_expand "x86_shift_adj_3"
11197 [(use (match_operand:SI 0 "register_operand" ""))
11198 (use (match_operand:SI 1 "register_operand" ""))
11199 (use (match_operand:QI 2 "register_operand" ""))]
11202 rtx label = gen_label_rtx ();
11205 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11207 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11208 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11209 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11210 gen_rtx_LABEL_REF (VOIDmode, label),
11212 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11213 JUMP_LABEL (tmp) = label;
11215 emit_move_insn (operands[0], operands[1]);
11216 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11218 emit_label (label);
11219 LABEL_NUSES (label) = 1;
11224 (define_insn "ashrsi3_31"
11225 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11226 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11227 (match_operand:SI 2 "const_int_operand" "i,i")))
11228 (clobber (reg:CC FLAGS_REG))]
11229 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11230 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11233 sar{l}\t{%2, %0|%0, %2}"
11234 [(set_attr "type" "imovx,ishift")
11235 (set_attr "prefix_0f" "0,*")
11236 (set_attr "length_immediate" "0,*")
11237 (set_attr "modrm" "0,1")
11238 (set_attr "mode" "SI")])
11240 (define_insn "*ashrsi3_31_zext"
11241 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11242 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11243 (match_operand:SI 2 "const_int_operand" "i,i"))))
11244 (clobber (reg:CC FLAGS_REG))]
11245 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11246 && INTVAL (operands[2]) == 31
11247 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11250 sar{l}\t{%2, %k0|%k0, %2}"
11251 [(set_attr "type" "imovx,ishift")
11252 (set_attr "prefix_0f" "0,*")
11253 (set_attr "length_immediate" "0,*")
11254 (set_attr "modrm" "0,1")
11255 (set_attr "mode" "SI")])
11257 (define_expand "ashrsi3"
11258 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11259 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11260 (match_operand:QI 2 "nonmemory_operand" "")))
11261 (clobber (reg:CC FLAGS_REG))]
11263 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11265 (define_insn "*ashrsi3_1_one_bit"
11266 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11267 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11268 (match_operand:QI 2 "const1_operand" "")))
11269 (clobber (reg:CC FLAGS_REG))]
11270 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11271 && (TARGET_SHIFT1 || optimize_size)"
11273 [(set_attr "type" "ishift")
11274 (set (attr "length")
11275 (if_then_else (match_operand:SI 0 "register_operand" "")
11277 (const_string "*")))])
11279 (define_insn "*ashrsi3_1_one_bit_zext"
11280 [(set (match_operand:DI 0 "register_operand" "=r")
11281 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11282 (match_operand:QI 2 "const1_operand" ""))))
11283 (clobber (reg:CC FLAGS_REG))]
11284 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11285 && (TARGET_SHIFT1 || optimize_size)"
11287 [(set_attr "type" "ishift")
11288 (set_attr "length" "2")])
11290 (define_insn "*ashrsi3_1"
11291 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11292 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11293 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11294 (clobber (reg:CC FLAGS_REG))]
11295 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11297 sar{l}\t{%2, %0|%0, %2}
11298 sar{l}\t{%b2, %0|%0, %b2}"
11299 [(set_attr "type" "ishift")
11300 (set_attr "mode" "SI")])
11302 (define_insn "*ashrsi3_1_zext"
11303 [(set (match_operand:DI 0 "register_operand" "=r,r")
11304 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11305 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11306 (clobber (reg:CC FLAGS_REG))]
11307 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11309 sar{l}\t{%2, %k0|%k0, %2}
11310 sar{l}\t{%b2, %k0|%k0, %b2}"
11311 [(set_attr "type" "ishift")
11312 (set_attr "mode" "SI")])
11314 ;; This pattern can't accept a variable shift count, since shifts by
11315 ;; zero don't affect the flags. We assume that shifts by constant
11316 ;; zero are optimized away.
11317 (define_insn "*ashrsi3_one_bit_cmp"
11318 [(set (reg FLAGS_REG)
11320 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11321 (match_operand:QI 2 "const1_operand" ""))
11323 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11324 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11325 "ix86_match_ccmode (insn, CCGOCmode)
11326 && (TARGET_SHIFT1 || optimize_size)
11327 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11329 [(set_attr "type" "ishift")
11330 (set (attr "length")
11331 (if_then_else (match_operand:SI 0 "register_operand" "")
11333 (const_string "*")))])
11335 (define_insn "*ashrsi3_one_bit_cmp_zext"
11336 [(set (reg FLAGS_REG)
11338 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11339 (match_operand:QI 2 "const1_operand" ""))
11341 (set (match_operand:DI 0 "register_operand" "=r")
11342 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11343 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11344 && (TARGET_SHIFT1 || optimize_size)
11345 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11347 [(set_attr "type" "ishift")
11348 (set_attr "length" "2")])
11350 ;; This pattern can't accept a variable shift count, since shifts by
11351 ;; zero don't affect the flags. We assume that shifts by constant
11352 ;; zero are optimized away.
11353 (define_insn "*ashrsi3_cmp"
11354 [(set (reg FLAGS_REG)
11356 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11357 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11359 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11360 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11361 "ix86_match_ccmode (insn, CCGOCmode)
11362 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11363 "sar{l}\t{%2, %0|%0, %2}"
11364 [(set_attr "type" "ishift")
11365 (set_attr "mode" "SI")])
11367 (define_insn "*ashrsi3_cmp_zext"
11368 [(set (reg FLAGS_REG)
11370 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11371 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11373 (set (match_operand:DI 0 "register_operand" "=r")
11374 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11375 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11376 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11377 "sar{l}\t{%2, %k0|%k0, %2}"
11378 [(set_attr "type" "ishift")
11379 (set_attr "mode" "SI")])
11381 (define_expand "ashrhi3"
11382 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11383 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11384 (match_operand:QI 2 "nonmemory_operand" "")))
11385 (clobber (reg:CC FLAGS_REG))]
11386 "TARGET_HIMODE_MATH"
11387 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11389 (define_insn "*ashrhi3_1_one_bit"
11390 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11391 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11392 (match_operand:QI 2 "const1_operand" "")))
11393 (clobber (reg:CC FLAGS_REG))]
11394 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11395 && (TARGET_SHIFT1 || optimize_size)"
11397 [(set_attr "type" "ishift")
11398 (set (attr "length")
11399 (if_then_else (match_operand 0 "register_operand" "")
11401 (const_string "*")))])
11403 (define_insn "*ashrhi3_1"
11404 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11405 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11406 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11407 (clobber (reg:CC FLAGS_REG))]
11408 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11410 sar{w}\t{%2, %0|%0, %2}
11411 sar{w}\t{%b2, %0|%0, %b2}"
11412 [(set_attr "type" "ishift")
11413 (set_attr "mode" "HI")])
11415 ;; This pattern can't accept a variable shift count, since shifts by
11416 ;; zero don't affect the flags. We assume that shifts by constant
11417 ;; zero are optimized away.
11418 (define_insn "*ashrhi3_one_bit_cmp"
11419 [(set (reg FLAGS_REG)
11421 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11422 (match_operand:QI 2 "const1_operand" ""))
11424 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11425 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11426 "ix86_match_ccmode (insn, CCGOCmode)
11427 && (TARGET_SHIFT1 || optimize_size)
11428 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11430 [(set_attr "type" "ishift")
11431 (set (attr "length")
11432 (if_then_else (match_operand 0 "register_operand" "")
11434 (const_string "*")))])
11436 ;; This pattern can't accept a variable shift count, since shifts by
11437 ;; zero don't affect the flags. We assume that shifts by constant
11438 ;; zero are optimized away.
11439 (define_insn "*ashrhi3_cmp"
11440 [(set (reg FLAGS_REG)
11442 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11443 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11445 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11446 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11447 "ix86_match_ccmode (insn, CCGOCmode)
11448 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11449 "sar{w}\t{%2, %0|%0, %2}"
11450 [(set_attr "type" "ishift")
11451 (set_attr "mode" "HI")])
11453 (define_expand "ashrqi3"
11454 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11455 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11456 (match_operand:QI 2 "nonmemory_operand" "")))
11457 (clobber (reg:CC FLAGS_REG))]
11458 "TARGET_QIMODE_MATH"
11459 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11461 (define_insn "*ashrqi3_1_one_bit"
11462 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11463 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11464 (match_operand:QI 2 "const1_operand" "")))
11465 (clobber (reg:CC FLAGS_REG))]
11466 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11467 && (TARGET_SHIFT1 || optimize_size)"
11469 [(set_attr "type" "ishift")
11470 (set (attr "length")
11471 (if_then_else (match_operand 0 "register_operand" "")
11473 (const_string "*")))])
11475 (define_insn "*ashrqi3_1_one_bit_slp"
11476 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11477 (ashiftrt:QI (match_dup 0)
11478 (match_operand:QI 1 "const1_operand" "")))
11479 (clobber (reg:CC FLAGS_REG))]
11480 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11481 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11482 && (TARGET_SHIFT1 || optimize_size)"
11484 [(set_attr "type" "ishift1")
11485 (set (attr "length")
11486 (if_then_else (match_operand 0 "register_operand" "")
11488 (const_string "*")))])
11490 (define_insn "*ashrqi3_1"
11491 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11492 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11493 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11494 (clobber (reg:CC FLAGS_REG))]
11495 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11497 sar{b}\t{%2, %0|%0, %2}
11498 sar{b}\t{%b2, %0|%0, %b2}"
11499 [(set_attr "type" "ishift")
11500 (set_attr "mode" "QI")])
11502 (define_insn "*ashrqi3_1_slp"
11503 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11504 (ashiftrt:QI (match_dup 0)
11505 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11506 (clobber (reg:CC FLAGS_REG))]
11507 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11508 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11510 sar{b}\t{%1, %0|%0, %1}
11511 sar{b}\t{%b1, %0|%0, %b1}"
11512 [(set_attr "type" "ishift1")
11513 (set_attr "mode" "QI")])
11515 ;; This pattern can't accept a variable shift count, since shifts by
11516 ;; zero don't affect the flags. We assume that shifts by constant
11517 ;; zero are optimized away.
11518 (define_insn "*ashrqi3_one_bit_cmp"
11519 [(set (reg FLAGS_REG)
11521 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11522 (match_operand:QI 2 "const1_operand" "I"))
11524 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11525 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11526 "ix86_match_ccmode (insn, CCGOCmode)
11527 && (TARGET_SHIFT1 || optimize_size)
11528 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11530 [(set_attr "type" "ishift")
11531 (set (attr "length")
11532 (if_then_else (match_operand 0 "register_operand" "")
11534 (const_string "*")))])
11536 ;; This pattern can't accept a variable shift count, since shifts by
11537 ;; zero don't affect the flags. We assume that shifts by constant
11538 ;; zero are optimized away.
11539 (define_insn "*ashrqi3_cmp"
11540 [(set (reg FLAGS_REG)
11542 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11543 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11545 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11546 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11547 "ix86_match_ccmode (insn, CCGOCmode)
11548 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11549 "sar{b}\t{%2, %0|%0, %2}"
11550 [(set_attr "type" "ishift")
11551 (set_attr "mode" "QI")])
11553 ;; Logical shift instructions
11555 ;; See comment above `ashldi3' about how this works.
11557 (define_expand "lshrti3"
11558 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11559 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11560 (match_operand:QI 2 "nonmemory_operand" "")))
11561 (clobber (reg:CC FLAGS_REG))])]
11564 if (! immediate_operand (operands[2], QImode))
11566 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11569 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11573 (define_insn "lshrti3_1"
11574 [(set (match_operand:TI 0 "register_operand" "=r")
11575 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11576 (match_operand:QI 2 "register_operand" "c")))
11577 (clobber (match_scratch:DI 3 "=&r"))
11578 (clobber (reg:CC FLAGS_REG))]
11581 [(set_attr "type" "multi")])
11583 (define_insn "*lshrti3_2"
11584 [(set (match_operand:TI 0 "register_operand" "=r")
11585 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11586 (match_operand:QI 2 "immediate_operand" "O")))
11587 (clobber (reg:CC FLAGS_REG))]
11590 [(set_attr "type" "multi")])
11593 [(set (match_operand:TI 0 "register_operand" "")
11594 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11595 (match_operand:QI 2 "register_operand" "")))
11596 (clobber (match_scratch:DI 3 ""))
11597 (clobber (reg:CC FLAGS_REG))]
11598 "TARGET_64BIT && reload_completed"
11600 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11603 [(set (match_operand:TI 0 "register_operand" "")
11604 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11605 (match_operand:QI 2 "immediate_operand" "")))
11606 (clobber (reg:CC FLAGS_REG))]
11607 "TARGET_64BIT && reload_completed"
11609 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11611 (define_expand "lshrdi3"
11612 [(set (match_operand:DI 0 "shiftdi_operand" "")
11613 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11614 (match_operand:QI 2 "nonmemory_operand" "")))]
11616 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11618 (define_insn "*lshrdi3_1_one_bit_rex64"
11619 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11620 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11621 (match_operand:QI 2 "const1_operand" "")))
11622 (clobber (reg:CC FLAGS_REG))]
11623 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11624 && (TARGET_SHIFT1 || optimize_size)"
11626 [(set_attr "type" "ishift")
11627 (set (attr "length")
11628 (if_then_else (match_operand:DI 0 "register_operand" "")
11630 (const_string "*")))])
11632 (define_insn "*lshrdi3_1_rex64"
11633 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11634 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11635 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11636 (clobber (reg:CC FLAGS_REG))]
11637 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11639 shr{q}\t{%2, %0|%0, %2}
11640 shr{q}\t{%b2, %0|%0, %b2}"
11641 [(set_attr "type" "ishift")
11642 (set_attr "mode" "DI")])
11644 ;; This pattern can't accept a variable shift count, since shifts by
11645 ;; zero don't affect the flags. We assume that shifts by constant
11646 ;; zero are optimized away.
11647 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11648 [(set (reg FLAGS_REG)
11650 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11651 (match_operand:QI 2 "const1_operand" ""))
11653 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11654 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11655 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11656 && (TARGET_SHIFT1 || optimize_size)
11657 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11659 [(set_attr "type" "ishift")
11660 (set (attr "length")
11661 (if_then_else (match_operand:DI 0 "register_operand" "")
11663 (const_string "*")))])
11665 ;; This pattern can't accept a variable shift count, since shifts by
11666 ;; zero don't affect the flags. We assume that shifts by constant
11667 ;; zero are optimized away.
11668 (define_insn "*lshrdi3_cmp_rex64"
11669 [(set (reg FLAGS_REG)
11671 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11672 (match_operand:QI 2 "const_int_operand" "e"))
11674 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11675 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11676 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11677 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11678 "shr{q}\t{%2, %0|%0, %2}"
11679 [(set_attr "type" "ishift")
11680 (set_attr "mode" "DI")])
11682 (define_insn "*lshrdi3_1"
11683 [(set (match_operand:DI 0 "register_operand" "=r")
11684 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11685 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11686 (clobber (reg:CC FLAGS_REG))]
11689 [(set_attr "type" "multi")])
11691 ;; By default we don't ask for a scratch register, because when DImode
11692 ;; values are manipulated, registers are already at a premium. But if
11693 ;; we have one handy, we won't turn it away.
11695 [(match_scratch:SI 3 "r")
11696 (parallel [(set (match_operand:DI 0 "register_operand" "")
11697 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11698 (match_operand:QI 2 "nonmemory_operand" "")))
11699 (clobber (reg:CC FLAGS_REG))])
11701 "!TARGET_64BIT && TARGET_CMOVE"
11703 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11706 [(set (match_operand:DI 0 "register_operand" "")
11707 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11708 (match_operand:QI 2 "nonmemory_operand" "")))
11709 (clobber (reg:CC FLAGS_REG))]
11710 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11711 ? flow2_completed : reload_completed)"
11713 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11715 (define_expand "lshrsi3"
11716 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11717 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11718 (match_operand:QI 2 "nonmemory_operand" "")))
11719 (clobber (reg:CC FLAGS_REG))]
11721 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11723 (define_insn "*lshrsi3_1_one_bit"
11724 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11725 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11726 (match_operand:QI 2 "const1_operand" "")))
11727 (clobber (reg:CC FLAGS_REG))]
11728 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11729 && (TARGET_SHIFT1 || optimize_size)"
11731 [(set_attr "type" "ishift")
11732 (set (attr "length")
11733 (if_then_else (match_operand:SI 0 "register_operand" "")
11735 (const_string "*")))])
11737 (define_insn "*lshrsi3_1_one_bit_zext"
11738 [(set (match_operand:DI 0 "register_operand" "=r")
11739 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11740 (match_operand:QI 2 "const1_operand" "")))
11741 (clobber (reg:CC FLAGS_REG))]
11742 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11743 && (TARGET_SHIFT1 || optimize_size)"
11745 [(set_attr "type" "ishift")
11746 (set_attr "length" "2")])
11748 (define_insn "*lshrsi3_1"
11749 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11750 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11751 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11752 (clobber (reg:CC FLAGS_REG))]
11753 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11755 shr{l}\t{%2, %0|%0, %2}
11756 shr{l}\t{%b2, %0|%0, %b2}"
11757 [(set_attr "type" "ishift")
11758 (set_attr "mode" "SI")])
11760 (define_insn "*lshrsi3_1_zext"
11761 [(set (match_operand:DI 0 "register_operand" "=r,r")
11763 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11764 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11765 (clobber (reg:CC FLAGS_REG))]
11766 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11768 shr{l}\t{%2, %k0|%k0, %2}
11769 shr{l}\t{%b2, %k0|%k0, %b2}"
11770 [(set_attr "type" "ishift")
11771 (set_attr "mode" "SI")])
11773 ;; This pattern can't accept a variable shift count, since shifts by
11774 ;; zero don't affect the flags. We assume that shifts by constant
11775 ;; zero are optimized away.
11776 (define_insn "*lshrsi3_one_bit_cmp"
11777 [(set (reg FLAGS_REG)
11779 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11780 (match_operand:QI 2 "const1_operand" ""))
11782 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11783 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11784 "ix86_match_ccmode (insn, CCGOCmode)
11785 && (TARGET_SHIFT1 || optimize_size)
11786 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11788 [(set_attr "type" "ishift")
11789 (set (attr "length")
11790 (if_then_else (match_operand:SI 0 "register_operand" "")
11792 (const_string "*")))])
11794 (define_insn "*lshrsi3_cmp_one_bit_zext"
11795 [(set (reg FLAGS_REG)
11797 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11798 (match_operand:QI 2 "const1_operand" ""))
11800 (set (match_operand:DI 0 "register_operand" "=r")
11801 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11802 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11803 && (TARGET_SHIFT1 || optimize_size)
11804 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11806 [(set_attr "type" "ishift")
11807 (set_attr "length" "2")])
11809 ;; This pattern can't accept a variable shift count, since shifts by
11810 ;; zero don't affect the flags. We assume that shifts by constant
11811 ;; zero are optimized away.
11812 (define_insn "*lshrsi3_cmp"
11813 [(set (reg FLAGS_REG)
11815 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11816 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11818 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11819 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11820 "ix86_match_ccmode (insn, CCGOCmode)
11821 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11822 "shr{l}\t{%2, %0|%0, %2}"
11823 [(set_attr "type" "ishift")
11824 (set_attr "mode" "SI")])
11826 (define_insn "*lshrsi3_cmp_zext"
11827 [(set (reg FLAGS_REG)
11829 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11830 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11832 (set (match_operand:DI 0 "register_operand" "=r")
11833 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11834 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11835 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11836 "shr{l}\t{%2, %k0|%k0, %2}"
11837 [(set_attr "type" "ishift")
11838 (set_attr "mode" "SI")])
11840 (define_expand "lshrhi3"
11841 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11842 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11843 (match_operand:QI 2 "nonmemory_operand" "")))
11844 (clobber (reg:CC FLAGS_REG))]
11845 "TARGET_HIMODE_MATH"
11846 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11848 (define_insn "*lshrhi3_1_one_bit"
11849 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11850 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11851 (match_operand:QI 2 "const1_operand" "")))
11852 (clobber (reg:CC FLAGS_REG))]
11853 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11854 && (TARGET_SHIFT1 || optimize_size)"
11856 [(set_attr "type" "ishift")
11857 (set (attr "length")
11858 (if_then_else (match_operand 0 "register_operand" "")
11860 (const_string "*")))])
11862 (define_insn "*lshrhi3_1"
11863 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11864 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11865 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11866 (clobber (reg:CC FLAGS_REG))]
11867 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11869 shr{w}\t{%2, %0|%0, %2}
11870 shr{w}\t{%b2, %0|%0, %b2}"
11871 [(set_attr "type" "ishift")
11872 (set_attr "mode" "HI")])
11874 ;; This pattern can't accept a variable shift count, since shifts by
11875 ;; zero don't affect the flags. We assume that shifts by constant
11876 ;; zero are optimized away.
11877 (define_insn "*lshrhi3_one_bit_cmp"
11878 [(set (reg FLAGS_REG)
11880 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11881 (match_operand:QI 2 "const1_operand" ""))
11883 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11884 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11885 "ix86_match_ccmode (insn, CCGOCmode)
11886 && (TARGET_SHIFT1 || optimize_size)
11887 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11889 [(set_attr "type" "ishift")
11890 (set (attr "length")
11891 (if_then_else (match_operand:SI 0 "register_operand" "")
11893 (const_string "*")))])
11895 ;; This pattern can't accept a variable shift count, since shifts by
11896 ;; zero don't affect the flags. We assume that shifts by constant
11897 ;; zero are optimized away.
11898 (define_insn "*lshrhi3_cmp"
11899 [(set (reg FLAGS_REG)
11901 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11902 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11904 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11905 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11906 "ix86_match_ccmode (insn, CCGOCmode)
11907 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11908 "shr{w}\t{%2, %0|%0, %2}"
11909 [(set_attr "type" "ishift")
11910 (set_attr "mode" "HI")])
11912 (define_expand "lshrqi3"
11913 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11914 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11915 (match_operand:QI 2 "nonmemory_operand" "")))
11916 (clobber (reg:CC FLAGS_REG))]
11917 "TARGET_QIMODE_MATH"
11918 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11920 (define_insn "*lshrqi3_1_one_bit"
11921 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11922 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11923 (match_operand:QI 2 "const1_operand" "")))
11924 (clobber (reg:CC FLAGS_REG))]
11925 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11926 && (TARGET_SHIFT1 || optimize_size)"
11928 [(set_attr "type" "ishift")
11929 (set (attr "length")
11930 (if_then_else (match_operand 0 "register_operand" "")
11932 (const_string "*")))])
11934 (define_insn "*lshrqi3_1_one_bit_slp"
11935 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11936 (lshiftrt:QI (match_dup 0)
11937 (match_operand:QI 1 "const1_operand" "")))
11938 (clobber (reg:CC FLAGS_REG))]
11939 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11940 && (TARGET_SHIFT1 || optimize_size)"
11942 [(set_attr "type" "ishift1")
11943 (set (attr "length")
11944 (if_then_else (match_operand 0 "register_operand" "")
11946 (const_string "*")))])
11948 (define_insn "*lshrqi3_1"
11949 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11950 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11951 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11952 (clobber (reg:CC FLAGS_REG))]
11953 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11955 shr{b}\t{%2, %0|%0, %2}
11956 shr{b}\t{%b2, %0|%0, %b2}"
11957 [(set_attr "type" "ishift")
11958 (set_attr "mode" "QI")])
11960 (define_insn "*lshrqi3_1_slp"
11961 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11962 (lshiftrt:QI (match_dup 0)
11963 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11964 (clobber (reg:CC FLAGS_REG))]
11965 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11966 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11968 shr{b}\t{%1, %0|%0, %1}
11969 shr{b}\t{%b1, %0|%0, %b1}"
11970 [(set_attr "type" "ishift1")
11971 (set_attr "mode" "QI")])
11973 ;; This pattern can't accept a variable shift count, since shifts by
11974 ;; zero don't affect the flags. We assume that shifts by constant
11975 ;; zero are optimized away.
11976 (define_insn "*lshrqi2_one_bit_cmp"
11977 [(set (reg FLAGS_REG)
11979 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11980 (match_operand:QI 2 "const1_operand" ""))
11982 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11983 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11984 "ix86_match_ccmode (insn, CCGOCmode)
11985 && (TARGET_SHIFT1 || optimize_size)
11986 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11988 [(set_attr "type" "ishift")
11989 (set (attr "length")
11990 (if_then_else (match_operand:SI 0 "register_operand" "")
11992 (const_string "*")))])
11994 ;; This pattern can't accept a variable shift count, since shifts by
11995 ;; zero don't affect the flags. We assume that shifts by constant
11996 ;; zero are optimized away.
11997 (define_insn "*lshrqi2_cmp"
11998 [(set (reg FLAGS_REG)
12000 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12001 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12003 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12004 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12005 "ix86_match_ccmode (insn, CCGOCmode)
12006 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12007 "shr{b}\t{%2, %0|%0, %2}"
12008 [(set_attr "type" "ishift")
12009 (set_attr "mode" "QI")])
12011 ;; Rotate instructions
12013 (define_expand "rotldi3"
12014 [(set (match_operand:DI 0 "shiftdi_operand" "")
12015 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12016 (match_operand:QI 2 "nonmemory_operand" "")))
12017 (clobber (reg:CC FLAGS_REG))]
12022 ix86_expand_binary_operator (ROTATE, DImode, operands);
12025 if (!const_1_to_31_operand (operands[2], VOIDmode))
12027 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12031 ;; Implement rotation using two double-precision shift instructions
12032 ;; and a scratch register.
12033 (define_insn_and_split "ix86_rotldi3"
12034 [(set (match_operand:DI 0 "register_operand" "=r")
12035 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12036 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12037 (clobber (reg:CC FLAGS_REG))
12038 (clobber (match_scratch:SI 3 "=&r"))]
12041 "&& reload_completed"
12042 [(set (match_dup 3) (match_dup 4))
12044 [(set (match_dup 4)
12045 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12046 (lshiftrt:SI (match_dup 5)
12047 (minus:QI (const_int 32) (match_dup 2)))))
12048 (clobber (reg:CC FLAGS_REG))])
12050 [(set (match_dup 5)
12051 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12052 (lshiftrt:SI (match_dup 3)
12053 (minus:QI (const_int 32) (match_dup 2)))))
12054 (clobber (reg:CC FLAGS_REG))])]
12055 "split_di (operands, 1, operands + 4, operands + 5);")
12057 (define_insn "*rotlsi3_1_one_bit_rex64"
12058 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12059 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12060 (match_operand:QI 2 "const1_operand" "")))
12061 (clobber (reg:CC FLAGS_REG))]
12062 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12063 && (TARGET_SHIFT1 || optimize_size)"
12065 [(set_attr "type" "rotate")
12066 (set (attr "length")
12067 (if_then_else (match_operand:DI 0 "register_operand" "")
12069 (const_string "*")))])
12071 (define_insn "*rotldi3_1_rex64"
12072 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12073 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12074 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12075 (clobber (reg:CC FLAGS_REG))]
12076 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12078 rol{q}\t{%2, %0|%0, %2}
12079 rol{q}\t{%b2, %0|%0, %b2}"
12080 [(set_attr "type" "rotate")
12081 (set_attr "mode" "DI")])
12083 (define_expand "rotlsi3"
12084 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12085 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12086 (match_operand:QI 2 "nonmemory_operand" "")))
12087 (clobber (reg:CC FLAGS_REG))]
12089 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12091 (define_insn "*rotlsi3_1_one_bit"
12092 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12093 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12094 (match_operand:QI 2 "const1_operand" "")))
12095 (clobber (reg:CC FLAGS_REG))]
12096 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12097 && (TARGET_SHIFT1 || optimize_size)"
12099 [(set_attr "type" "rotate")
12100 (set (attr "length")
12101 (if_then_else (match_operand:SI 0 "register_operand" "")
12103 (const_string "*")))])
12105 (define_insn "*rotlsi3_1_one_bit_zext"
12106 [(set (match_operand:DI 0 "register_operand" "=r")
12108 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12109 (match_operand:QI 2 "const1_operand" ""))))
12110 (clobber (reg:CC FLAGS_REG))]
12111 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12112 && (TARGET_SHIFT1 || optimize_size)"
12114 [(set_attr "type" "rotate")
12115 (set_attr "length" "2")])
12117 (define_insn "*rotlsi3_1"
12118 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12119 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12120 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12121 (clobber (reg:CC FLAGS_REG))]
12122 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12124 rol{l}\t{%2, %0|%0, %2}
12125 rol{l}\t{%b2, %0|%0, %b2}"
12126 [(set_attr "type" "rotate")
12127 (set_attr "mode" "SI")])
12129 (define_insn "*rotlsi3_1_zext"
12130 [(set (match_operand:DI 0 "register_operand" "=r,r")
12132 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12133 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12134 (clobber (reg:CC FLAGS_REG))]
12135 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12137 rol{l}\t{%2, %k0|%k0, %2}
12138 rol{l}\t{%b2, %k0|%k0, %b2}"
12139 [(set_attr "type" "rotate")
12140 (set_attr "mode" "SI")])
12142 (define_expand "rotlhi3"
12143 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12144 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12145 (match_operand:QI 2 "nonmemory_operand" "")))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "TARGET_HIMODE_MATH"
12148 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12150 (define_insn "*rotlhi3_1_one_bit"
12151 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12152 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12153 (match_operand:QI 2 "const1_operand" "")))
12154 (clobber (reg:CC FLAGS_REG))]
12155 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12156 && (TARGET_SHIFT1 || optimize_size)"
12158 [(set_attr "type" "rotate")
12159 (set (attr "length")
12160 (if_then_else (match_operand 0 "register_operand" "")
12162 (const_string "*")))])
12164 (define_insn "*rotlhi3_1"
12165 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12166 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12167 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12168 (clobber (reg:CC FLAGS_REG))]
12169 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12171 rol{w}\t{%2, %0|%0, %2}
12172 rol{w}\t{%b2, %0|%0, %b2}"
12173 [(set_attr "type" "rotate")
12174 (set_attr "mode" "HI")])
12176 (define_expand "rotlqi3"
12177 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12178 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12179 (match_operand:QI 2 "nonmemory_operand" "")))
12180 (clobber (reg:CC FLAGS_REG))]
12181 "TARGET_QIMODE_MATH"
12182 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12184 (define_insn "*rotlqi3_1_one_bit_slp"
12185 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12186 (rotate:QI (match_dup 0)
12187 (match_operand:QI 1 "const1_operand" "")))
12188 (clobber (reg:CC FLAGS_REG))]
12189 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12190 && (TARGET_SHIFT1 || optimize_size)"
12192 [(set_attr "type" "rotate1")
12193 (set (attr "length")
12194 (if_then_else (match_operand 0 "register_operand" "")
12196 (const_string "*")))])
12198 (define_insn "*rotlqi3_1_one_bit"
12199 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12200 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12201 (match_operand:QI 2 "const1_operand" "")))
12202 (clobber (reg:CC FLAGS_REG))]
12203 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12204 && (TARGET_SHIFT1 || optimize_size)"
12206 [(set_attr "type" "rotate")
12207 (set (attr "length")
12208 (if_then_else (match_operand 0 "register_operand" "")
12210 (const_string "*")))])
12212 (define_insn "*rotlqi3_1_slp"
12213 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12214 (rotate:QI (match_dup 0)
12215 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12216 (clobber (reg:CC FLAGS_REG))]
12217 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12218 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12220 rol{b}\t{%1, %0|%0, %1}
12221 rol{b}\t{%b1, %0|%0, %b1}"
12222 [(set_attr "type" "rotate1")
12223 (set_attr "mode" "QI")])
12225 (define_insn "*rotlqi3_1"
12226 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12227 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12228 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12229 (clobber (reg:CC FLAGS_REG))]
12230 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12232 rol{b}\t{%2, %0|%0, %2}
12233 rol{b}\t{%b2, %0|%0, %b2}"
12234 [(set_attr "type" "rotate")
12235 (set_attr "mode" "QI")])
12237 (define_expand "rotrdi3"
12238 [(set (match_operand:DI 0 "shiftdi_operand" "")
12239 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12240 (match_operand:QI 2 "nonmemory_operand" "")))
12241 (clobber (reg:CC FLAGS_REG))]
12246 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12249 if (!const_1_to_31_operand (operands[2], VOIDmode))
12251 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12255 ;; Implement rotation using two double-precision shift instructions
12256 ;; and a scratch register.
12257 (define_insn_and_split "ix86_rotrdi3"
12258 [(set (match_operand:DI 0 "register_operand" "=r")
12259 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12260 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12261 (clobber (reg:CC FLAGS_REG))
12262 (clobber (match_scratch:SI 3 "=&r"))]
12265 "&& reload_completed"
12266 [(set (match_dup 3) (match_dup 4))
12268 [(set (match_dup 4)
12269 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12270 (ashift:SI (match_dup 5)
12271 (minus:QI (const_int 32) (match_dup 2)))))
12272 (clobber (reg:CC FLAGS_REG))])
12274 [(set (match_dup 5)
12275 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12276 (ashift:SI (match_dup 3)
12277 (minus:QI (const_int 32) (match_dup 2)))))
12278 (clobber (reg:CC FLAGS_REG))])]
12279 "split_di (operands, 1, operands + 4, operands + 5);")
12281 (define_insn "*rotrdi3_1_one_bit_rex64"
12282 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12283 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12284 (match_operand:QI 2 "const1_operand" "")))
12285 (clobber (reg:CC FLAGS_REG))]
12286 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12287 && (TARGET_SHIFT1 || optimize_size)"
12289 [(set_attr "type" "rotate")
12290 (set (attr "length")
12291 (if_then_else (match_operand:DI 0 "register_operand" "")
12293 (const_string "*")))])
12295 (define_insn "*rotrdi3_1_rex64"
12296 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12297 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12298 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12299 (clobber (reg:CC FLAGS_REG))]
12300 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12302 ror{q}\t{%2, %0|%0, %2}
12303 ror{q}\t{%b2, %0|%0, %b2}"
12304 [(set_attr "type" "rotate")
12305 (set_attr "mode" "DI")])
12307 (define_expand "rotrsi3"
12308 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12309 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12310 (match_operand:QI 2 "nonmemory_operand" "")))
12311 (clobber (reg:CC FLAGS_REG))]
12313 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12315 (define_insn "*rotrsi3_1_one_bit"
12316 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12317 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12318 (match_operand:QI 2 "const1_operand" "")))
12319 (clobber (reg:CC FLAGS_REG))]
12320 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12321 && (TARGET_SHIFT1 || optimize_size)"
12323 [(set_attr "type" "rotate")
12324 (set (attr "length")
12325 (if_then_else (match_operand:SI 0 "register_operand" "")
12327 (const_string "*")))])
12329 (define_insn "*rotrsi3_1_one_bit_zext"
12330 [(set (match_operand:DI 0 "register_operand" "=r")
12332 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12333 (match_operand:QI 2 "const1_operand" ""))))
12334 (clobber (reg:CC FLAGS_REG))]
12335 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12336 && (TARGET_SHIFT1 || optimize_size)"
12338 [(set_attr "type" "rotate")
12339 (set (attr "length")
12340 (if_then_else (match_operand:SI 0 "register_operand" "")
12342 (const_string "*")))])
12344 (define_insn "*rotrsi3_1"
12345 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12346 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12347 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12348 (clobber (reg:CC FLAGS_REG))]
12349 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12351 ror{l}\t{%2, %0|%0, %2}
12352 ror{l}\t{%b2, %0|%0, %b2}"
12353 [(set_attr "type" "rotate")
12354 (set_attr "mode" "SI")])
12356 (define_insn "*rotrsi3_1_zext"
12357 [(set (match_operand:DI 0 "register_operand" "=r,r")
12359 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12360 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12361 (clobber (reg:CC FLAGS_REG))]
12362 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12364 ror{l}\t{%2, %k0|%k0, %2}
12365 ror{l}\t{%b2, %k0|%k0, %b2}"
12366 [(set_attr "type" "rotate")
12367 (set_attr "mode" "SI")])
12369 (define_expand "rotrhi3"
12370 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12371 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12372 (match_operand:QI 2 "nonmemory_operand" "")))
12373 (clobber (reg:CC FLAGS_REG))]
12374 "TARGET_HIMODE_MATH"
12375 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12377 (define_insn "*rotrhi3_one_bit"
12378 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12379 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12380 (match_operand:QI 2 "const1_operand" "")))
12381 (clobber (reg:CC FLAGS_REG))]
12382 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12383 && (TARGET_SHIFT1 || optimize_size)"
12385 [(set_attr "type" "rotate")
12386 (set (attr "length")
12387 (if_then_else (match_operand 0 "register_operand" "")
12389 (const_string "*")))])
12391 (define_insn "*rotrhi3"
12392 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12393 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12394 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12395 (clobber (reg:CC FLAGS_REG))]
12396 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12398 ror{w}\t{%2, %0|%0, %2}
12399 ror{w}\t{%b2, %0|%0, %b2}"
12400 [(set_attr "type" "rotate")
12401 (set_attr "mode" "HI")])
12403 (define_expand "rotrqi3"
12404 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12405 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12406 (match_operand:QI 2 "nonmemory_operand" "")))
12407 (clobber (reg:CC FLAGS_REG))]
12408 "TARGET_QIMODE_MATH"
12409 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12411 (define_insn "*rotrqi3_1_one_bit"
12412 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12413 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12414 (match_operand:QI 2 "const1_operand" "")))
12415 (clobber (reg:CC FLAGS_REG))]
12416 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12417 && (TARGET_SHIFT1 || optimize_size)"
12419 [(set_attr "type" "rotate")
12420 (set (attr "length")
12421 (if_then_else (match_operand 0 "register_operand" "")
12423 (const_string "*")))])
12425 (define_insn "*rotrqi3_1_one_bit_slp"
12426 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12427 (rotatert:QI (match_dup 0)
12428 (match_operand:QI 1 "const1_operand" "")))
12429 (clobber (reg:CC FLAGS_REG))]
12430 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12431 && (TARGET_SHIFT1 || optimize_size)"
12433 [(set_attr "type" "rotate1")
12434 (set (attr "length")
12435 (if_then_else (match_operand 0 "register_operand" "")
12437 (const_string "*")))])
12439 (define_insn "*rotrqi3_1"
12440 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12441 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12442 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12443 (clobber (reg:CC FLAGS_REG))]
12444 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12446 ror{b}\t{%2, %0|%0, %2}
12447 ror{b}\t{%b2, %0|%0, %b2}"
12448 [(set_attr "type" "rotate")
12449 (set_attr "mode" "QI")])
12451 (define_insn "*rotrqi3_1_slp"
12452 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12453 (rotatert:QI (match_dup 0)
12454 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12455 (clobber (reg:CC FLAGS_REG))]
12456 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12457 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12459 ror{b}\t{%1, %0|%0, %1}
12460 ror{b}\t{%b1, %0|%0, %b1}"
12461 [(set_attr "type" "rotate1")
12462 (set_attr "mode" "QI")])
12464 ;; Bit set / bit test instructions
12466 (define_expand "extv"
12467 [(set (match_operand:SI 0 "register_operand" "")
12468 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12469 (match_operand:SI 2 "immediate_operand" "")
12470 (match_operand:SI 3 "immediate_operand" "")))]
12473 /* Handle extractions from %ah et al. */
12474 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12477 /* From mips.md: extract_bit_field doesn't verify that our source
12478 matches the predicate, so check it again here. */
12479 if (! ext_register_operand (operands[1], VOIDmode))
12483 (define_expand "extzv"
12484 [(set (match_operand:SI 0 "register_operand" "")
12485 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12486 (match_operand:SI 2 "immediate_operand" "")
12487 (match_operand:SI 3 "immediate_operand" "")))]
12490 /* Handle extractions from %ah et al. */
12491 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12494 /* From mips.md: extract_bit_field doesn't verify that our source
12495 matches the predicate, so check it again here. */
12496 if (! ext_register_operand (operands[1], VOIDmode))
12500 (define_expand "insv"
12501 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12502 (match_operand 1 "immediate_operand" "")
12503 (match_operand 2 "immediate_operand" ""))
12504 (match_operand 3 "register_operand" ""))]
12507 /* Handle extractions from %ah et al. */
12508 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12511 /* From mips.md: insert_bit_field doesn't verify that our source
12512 matches the predicate, so check it again here. */
12513 if (! ext_register_operand (operands[0], VOIDmode))
12517 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12519 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12524 ;; %%% bts, btr, btc, bt.
12525 ;; In general these instructions are *slow* when applied to memory,
12526 ;; since they enforce atomic operation. When applied to registers,
12527 ;; it depends on the cpu implementation. They're never faster than
12528 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12529 ;; no point. But in 64-bit, we can't hold the relevant immediates
12530 ;; within the instruction itself, so operating on bits in the high
12531 ;; 32-bits of a register becomes easier.
12533 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12534 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12535 ;; negdf respectively, so they can never be disabled entirely.
12537 (define_insn "*btsq"
12538 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12540 (match_operand:DI 1 "const_0_to_63_operand" ""))
12542 (clobber (reg:CC FLAGS_REG))]
12543 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12545 [(set_attr "type" "alu1")])
12547 (define_insn "*btrq"
12548 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12550 (match_operand:DI 1 "const_0_to_63_operand" ""))
12552 (clobber (reg:CC FLAGS_REG))]
12553 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12555 [(set_attr "type" "alu1")])
12557 (define_insn "*btcq"
12558 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12560 (match_operand:DI 1 "const_0_to_63_operand" ""))
12561 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12562 (clobber (reg:CC FLAGS_REG))]
12563 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12565 [(set_attr "type" "alu1")])
12567 ;; Allow Nocona to avoid these instructions if a register is available.
12570 [(match_scratch:DI 2 "r")
12571 (parallel [(set (zero_extract:DI
12572 (match_operand:DI 0 "register_operand" "")
12574 (match_operand:DI 1 "const_0_to_63_operand" ""))
12576 (clobber (reg:CC FLAGS_REG))])]
12577 "TARGET_64BIT && !TARGET_USE_BT"
12580 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12583 if (HOST_BITS_PER_WIDE_INT >= 64)
12584 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12585 else if (i < HOST_BITS_PER_WIDE_INT)
12586 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12588 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12590 op1 = immed_double_const (lo, hi, DImode);
12593 emit_move_insn (operands[2], op1);
12597 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12602 [(match_scratch:DI 2 "r")
12603 (parallel [(set (zero_extract:DI
12604 (match_operand:DI 0 "register_operand" "")
12606 (match_operand:DI 1 "const_0_to_63_operand" ""))
12608 (clobber (reg:CC FLAGS_REG))])]
12609 "TARGET_64BIT && !TARGET_USE_BT"
12612 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12615 if (HOST_BITS_PER_WIDE_INT >= 64)
12616 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12617 else if (i < HOST_BITS_PER_WIDE_INT)
12618 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12620 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12622 op1 = immed_double_const (~lo, ~hi, DImode);
12625 emit_move_insn (operands[2], op1);
12629 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12634 [(match_scratch:DI 2 "r")
12635 (parallel [(set (zero_extract:DI
12636 (match_operand:DI 0 "register_operand" "")
12638 (match_operand:DI 1 "const_0_to_63_operand" ""))
12639 (not:DI (zero_extract:DI
12640 (match_dup 0) (const_int 1) (match_dup 1))))
12641 (clobber (reg:CC FLAGS_REG))])]
12642 "TARGET_64BIT && !TARGET_USE_BT"
12645 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12648 if (HOST_BITS_PER_WIDE_INT >= 64)
12649 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12650 else if (i < HOST_BITS_PER_WIDE_INT)
12651 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12653 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12655 op1 = immed_double_const (lo, hi, DImode);
12658 emit_move_insn (operands[2], op1);
12662 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12666 ;; Store-flag instructions.
12668 ;; For all sCOND expanders, also expand the compare or test insn that
12669 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12671 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12672 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12673 ;; way, which can later delete the movzx if only QImode is needed.
12675 (define_expand "seq"
12676 [(set (match_operand:QI 0 "register_operand" "")
12677 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12679 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12681 (define_expand "sne"
12682 [(set (match_operand:QI 0 "register_operand" "")
12683 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12685 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12687 (define_expand "sgt"
12688 [(set (match_operand:QI 0 "register_operand" "")
12689 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12691 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12693 (define_expand "sgtu"
12694 [(set (match_operand:QI 0 "register_operand" "")
12695 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12697 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12699 (define_expand "slt"
12700 [(set (match_operand:QI 0 "register_operand" "")
12701 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12703 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12705 (define_expand "sltu"
12706 [(set (match_operand:QI 0 "register_operand" "")
12707 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12709 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12711 (define_expand "sge"
12712 [(set (match_operand:QI 0 "register_operand" "")
12713 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12715 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12717 (define_expand "sgeu"
12718 [(set (match_operand:QI 0 "register_operand" "")
12719 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12721 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12723 (define_expand "sle"
12724 [(set (match_operand:QI 0 "register_operand" "")
12725 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12727 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12729 (define_expand "sleu"
12730 [(set (match_operand:QI 0 "register_operand" "")
12731 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12733 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12735 (define_expand "sunordered"
12736 [(set (match_operand:QI 0 "register_operand" "")
12737 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12738 "TARGET_80387 || TARGET_SSE"
12739 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12741 (define_expand "sordered"
12742 [(set (match_operand:QI 0 "register_operand" "")
12743 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12745 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12747 (define_expand "suneq"
12748 [(set (match_operand:QI 0 "register_operand" "")
12749 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12750 "TARGET_80387 || TARGET_SSE"
12751 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12753 (define_expand "sunge"
12754 [(set (match_operand:QI 0 "register_operand" "")
12755 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12756 "TARGET_80387 || TARGET_SSE"
12757 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12759 (define_expand "sungt"
12760 [(set (match_operand:QI 0 "register_operand" "")
12761 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12762 "TARGET_80387 || TARGET_SSE"
12763 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12765 (define_expand "sunle"
12766 [(set (match_operand:QI 0 "register_operand" "")
12767 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12768 "TARGET_80387 || TARGET_SSE"
12769 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12771 (define_expand "sunlt"
12772 [(set (match_operand:QI 0 "register_operand" "")
12773 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12774 "TARGET_80387 || TARGET_SSE"
12775 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12777 (define_expand "sltgt"
12778 [(set (match_operand:QI 0 "register_operand" "")
12779 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12780 "TARGET_80387 || TARGET_SSE"
12781 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12783 (define_insn "*setcc_1"
12784 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12785 (match_operator:QI 1 "ix86_comparison_operator"
12786 [(reg FLAGS_REG) (const_int 0)]))]
12789 [(set_attr "type" "setcc")
12790 (set_attr "mode" "QI")])
12792 (define_insn "*setcc_2"
12793 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12794 (match_operator:QI 1 "ix86_comparison_operator"
12795 [(reg FLAGS_REG) (const_int 0)]))]
12798 [(set_attr "type" "setcc")
12799 (set_attr "mode" "QI")])
12801 ;; In general it is not safe to assume too much about CCmode registers,
12802 ;; so simplify-rtx stops when it sees a second one. Under certain
12803 ;; conditions this is safe on x86, so help combine not create
12810 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12811 (ne:QI (match_operator 1 "ix86_comparison_operator"
12812 [(reg FLAGS_REG) (const_int 0)])
12815 [(set (match_dup 0) (match_dup 1))]
12817 PUT_MODE (operands[1], QImode);
12821 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12822 (ne:QI (match_operator 1 "ix86_comparison_operator"
12823 [(reg FLAGS_REG) (const_int 0)])
12826 [(set (match_dup 0) (match_dup 1))]
12828 PUT_MODE (operands[1], QImode);
12832 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12833 (eq:QI (match_operator 1 "ix86_comparison_operator"
12834 [(reg FLAGS_REG) (const_int 0)])
12837 [(set (match_dup 0) (match_dup 1))]
12839 rtx new_op1 = copy_rtx (operands[1]);
12840 operands[1] = new_op1;
12841 PUT_MODE (new_op1, QImode);
12842 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12843 GET_MODE (XEXP (new_op1, 0))));
12845 /* Make sure that (a) the CCmode we have for the flags is strong
12846 enough for the reversed compare or (b) we have a valid FP compare. */
12847 if (! ix86_comparison_operator (new_op1, VOIDmode))
12852 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12853 (eq:QI (match_operator 1 "ix86_comparison_operator"
12854 [(reg FLAGS_REG) (const_int 0)])
12857 [(set (match_dup 0) (match_dup 1))]
12859 rtx new_op1 = copy_rtx (operands[1]);
12860 operands[1] = new_op1;
12861 PUT_MODE (new_op1, QImode);
12862 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12863 GET_MODE (XEXP (new_op1, 0))));
12865 /* Make sure that (a) the CCmode we have for the flags is strong
12866 enough for the reversed compare or (b) we have a valid FP compare. */
12867 if (! ix86_comparison_operator (new_op1, VOIDmode))
12871 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12872 ;; subsequent logical operations are used to imitate conditional moves.
12873 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12876 (define_insn "*sse_setccsf"
12877 [(set (match_operand:SF 0 "register_operand" "=x")
12878 (match_operator:SF 1 "sse_comparison_operator"
12879 [(match_operand:SF 2 "register_operand" "0")
12880 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12882 "cmp%D1ss\t{%3, %0|%0, %3}"
12883 [(set_attr "type" "ssecmp")
12884 (set_attr "mode" "SF")])
12886 (define_insn "*sse_setccdf"
12887 [(set (match_operand:DF 0 "register_operand" "=Y")
12888 (match_operator:DF 1 "sse_comparison_operator"
12889 [(match_operand:DF 2 "register_operand" "0")
12890 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12892 "cmp%D1sd\t{%3, %0|%0, %3}"
12893 [(set_attr "type" "ssecmp")
12894 (set_attr "mode" "DF")])
12896 ;; Basic conditional jump instructions.
12897 ;; We ignore the overflow flag for signed branch instructions.
12899 ;; For all bCOND expanders, also expand the compare or test insn that
12900 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12902 (define_expand "beq"
12904 (if_then_else (match_dup 1)
12905 (label_ref (match_operand 0 "" ""))
12908 "ix86_expand_branch (EQ, operands[0]); DONE;")
12910 (define_expand "bne"
12912 (if_then_else (match_dup 1)
12913 (label_ref (match_operand 0 "" ""))
12916 "ix86_expand_branch (NE, operands[0]); DONE;")
12918 (define_expand "bgt"
12920 (if_then_else (match_dup 1)
12921 (label_ref (match_operand 0 "" ""))
12924 "ix86_expand_branch (GT, operands[0]); DONE;")
12926 (define_expand "bgtu"
12928 (if_then_else (match_dup 1)
12929 (label_ref (match_operand 0 "" ""))
12932 "ix86_expand_branch (GTU, operands[0]); DONE;")
12934 (define_expand "blt"
12936 (if_then_else (match_dup 1)
12937 (label_ref (match_operand 0 "" ""))
12940 "ix86_expand_branch (LT, operands[0]); DONE;")
12942 (define_expand "bltu"
12944 (if_then_else (match_dup 1)
12945 (label_ref (match_operand 0 "" ""))
12948 "ix86_expand_branch (LTU, operands[0]); DONE;")
12950 (define_expand "bge"
12952 (if_then_else (match_dup 1)
12953 (label_ref (match_operand 0 "" ""))
12956 "ix86_expand_branch (GE, operands[0]); DONE;")
12958 (define_expand "bgeu"
12960 (if_then_else (match_dup 1)
12961 (label_ref (match_operand 0 "" ""))
12964 "ix86_expand_branch (GEU, operands[0]); DONE;")
12966 (define_expand "ble"
12968 (if_then_else (match_dup 1)
12969 (label_ref (match_operand 0 "" ""))
12972 "ix86_expand_branch (LE, operands[0]); DONE;")
12974 (define_expand "bleu"
12976 (if_then_else (match_dup 1)
12977 (label_ref (match_operand 0 "" ""))
12980 "ix86_expand_branch (LEU, operands[0]); DONE;")
12982 (define_expand "bunordered"
12984 (if_then_else (match_dup 1)
12985 (label_ref (match_operand 0 "" ""))
12987 "TARGET_80387 || TARGET_SSE_MATH"
12988 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12990 (define_expand "bordered"
12992 (if_then_else (match_dup 1)
12993 (label_ref (match_operand 0 "" ""))
12995 "TARGET_80387 || TARGET_SSE_MATH"
12996 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12998 (define_expand "buneq"
13000 (if_then_else (match_dup 1)
13001 (label_ref (match_operand 0 "" ""))
13003 "TARGET_80387 || TARGET_SSE_MATH"
13004 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13006 (define_expand "bunge"
13008 (if_then_else (match_dup 1)
13009 (label_ref (match_operand 0 "" ""))
13011 "TARGET_80387 || TARGET_SSE_MATH"
13012 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13014 (define_expand "bungt"
13016 (if_then_else (match_dup 1)
13017 (label_ref (match_operand 0 "" ""))
13019 "TARGET_80387 || TARGET_SSE_MATH"
13020 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13022 (define_expand "bunle"
13024 (if_then_else (match_dup 1)
13025 (label_ref (match_operand 0 "" ""))
13027 "TARGET_80387 || TARGET_SSE_MATH"
13028 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13030 (define_expand "bunlt"
13032 (if_then_else (match_dup 1)
13033 (label_ref (match_operand 0 "" ""))
13035 "TARGET_80387 || TARGET_SSE_MATH"
13036 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13038 (define_expand "bltgt"
13040 (if_then_else (match_dup 1)
13041 (label_ref (match_operand 0 "" ""))
13043 "TARGET_80387 || TARGET_SSE_MATH"
13044 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13046 (define_insn "*jcc_1"
13048 (if_then_else (match_operator 1 "ix86_comparison_operator"
13049 [(reg FLAGS_REG) (const_int 0)])
13050 (label_ref (match_operand 0 "" ""))
13054 [(set_attr "type" "ibr")
13055 (set_attr "modrm" "0")
13056 (set (attr "length")
13057 (if_then_else (and (ge (minus (match_dup 0) (pc))
13059 (lt (minus (match_dup 0) (pc))
13064 (define_insn "*jcc_2"
13066 (if_then_else (match_operator 1 "ix86_comparison_operator"
13067 [(reg FLAGS_REG) (const_int 0)])
13069 (label_ref (match_operand 0 "" ""))))]
13072 [(set_attr "type" "ibr")
13073 (set_attr "modrm" "0")
13074 (set (attr "length")
13075 (if_then_else (and (ge (minus (match_dup 0) (pc))
13077 (lt (minus (match_dup 0) (pc))
13082 ;; In general it is not safe to assume too much about CCmode registers,
13083 ;; so simplify-rtx stops when it sees a second one. Under certain
13084 ;; conditions this is safe on x86, so help combine not create
13092 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13093 [(reg FLAGS_REG) (const_int 0)])
13095 (label_ref (match_operand 1 "" ""))
13099 (if_then_else (match_dup 0)
13100 (label_ref (match_dup 1))
13103 PUT_MODE (operands[0], VOIDmode);
13108 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13109 [(reg FLAGS_REG) (const_int 0)])
13111 (label_ref (match_operand 1 "" ""))
13115 (if_then_else (match_dup 0)
13116 (label_ref (match_dup 1))
13119 rtx new_op0 = copy_rtx (operands[0]);
13120 operands[0] = new_op0;
13121 PUT_MODE (new_op0, VOIDmode);
13122 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13123 GET_MODE (XEXP (new_op0, 0))));
13125 /* Make sure that (a) the CCmode we have for the flags is strong
13126 enough for the reversed compare or (b) we have a valid FP compare. */
13127 if (! ix86_comparison_operator (new_op0, VOIDmode))
13131 ;; Define combination compare-and-branch fp compare instructions to use
13132 ;; during early optimization. Splitting the operation apart early makes
13133 ;; for bad code when we want to reverse the operation.
13135 (define_insn "*fp_jcc_1_mixed"
13137 (if_then_else (match_operator 0 "comparison_operator"
13138 [(match_operand 1 "register_operand" "f#x,x#f")
13139 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13140 (label_ref (match_operand 3 "" ""))
13142 (clobber (reg:CCFP FPSR_REG))
13143 (clobber (reg:CCFP FLAGS_REG))]
13144 "TARGET_MIX_SSE_I387
13145 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13146 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13147 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13150 (define_insn "*fp_jcc_1_sse"
13152 (if_then_else (match_operator 0 "comparison_operator"
13153 [(match_operand 1 "register_operand" "x")
13154 (match_operand 2 "nonimmediate_operand" "xm")])
13155 (label_ref (match_operand 3 "" ""))
13157 (clobber (reg:CCFP FPSR_REG))
13158 (clobber (reg:CCFP FLAGS_REG))]
13160 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13161 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13162 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13165 (define_insn "*fp_jcc_1_387"
13167 (if_then_else (match_operator 0 "comparison_operator"
13168 [(match_operand 1 "register_operand" "f")
13169 (match_operand 2 "register_operand" "f")])
13170 (label_ref (match_operand 3 "" ""))
13172 (clobber (reg:CCFP FPSR_REG))
13173 (clobber (reg:CCFP FLAGS_REG))]
13174 "TARGET_CMOVE && TARGET_80387
13175 && FLOAT_MODE_P (GET_MODE (operands[1]))
13176 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13177 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13180 (define_insn "*fp_jcc_2_mixed"
13182 (if_then_else (match_operator 0 "comparison_operator"
13183 [(match_operand 1 "register_operand" "f#x,x#f")
13184 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13186 (label_ref (match_operand 3 "" ""))))
13187 (clobber (reg:CCFP FPSR_REG))
13188 (clobber (reg:CCFP FLAGS_REG))]
13189 "TARGET_MIX_SSE_I387
13190 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13191 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13192 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13195 (define_insn "*fp_jcc_2_sse"
13197 (if_then_else (match_operator 0 "comparison_operator"
13198 [(match_operand 1 "register_operand" "x")
13199 (match_operand 2 "nonimmediate_operand" "xm")])
13201 (label_ref (match_operand 3 "" ""))))
13202 (clobber (reg:CCFP FPSR_REG))
13203 (clobber (reg:CCFP FLAGS_REG))]
13205 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13206 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13207 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13210 (define_insn "*fp_jcc_2_387"
13212 (if_then_else (match_operator 0 "comparison_operator"
13213 [(match_operand 1 "register_operand" "f")
13214 (match_operand 2 "register_operand" "f")])
13216 (label_ref (match_operand 3 "" ""))))
13217 (clobber (reg:CCFP FPSR_REG))
13218 (clobber (reg:CCFP FLAGS_REG))]
13219 "TARGET_CMOVE && TARGET_80387
13220 && FLOAT_MODE_P (GET_MODE (operands[1]))
13221 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13222 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13225 (define_insn "*fp_jcc_3_387"
13227 (if_then_else (match_operator 0 "comparison_operator"
13228 [(match_operand 1 "register_operand" "f")
13229 (match_operand 2 "nonimmediate_operand" "fm")])
13230 (label_ref (match_operand 3 "" ""))
13232 (clobber (reg:CCFP FPSR_REG))
13233 (clobber (reg:CCFP FLAGS_REG))
13234 (clobber (match_scratch:HI 4 "=a"))]
13236 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13237 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13238 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13239 && SELECT_CC_MODE (GET_CODE (operands[0]),
13240 operands[1], operands[2]) == CCFPmode
13241 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13244 (define_insn "*fp_jcc_4_387"
13246 (if_then_else (match_operator 0 "comparison_operator"
13247 [(match_operand 1 "register_operand" "f")
13248 (match_operand 2 "nonimmediate_operand" "fm")])
13250 (label_ref (match_operand 3 "" ""))))
13251 (clobber (reg:CCFP FPSR_REG))
13252 (clobber (reg:CCFP FLAGS_REG))
13253 (clobber (match_scratch:HI 4 "=a"))]
13255 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13256 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13257 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13258 && SELECT_CC_MODE (GET_CODE (operands[0]),
13259 operands[1], operands[2]) == CCFPmode
13260 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13263 (define_insn "*fp_jcc_5_387"
13265 (if_then_else (match_operator 0 "comparison_operator"
13266 [(match_operand 1 "register_operand" "f")
13267 (match_operand 2 "register_operand" "f")])
13268 (label_ref (match_operand 3 "" ""))
13270 (clobber (reg:CCFP FPSR_REG))
13271 (clobber (reg:CCFP FLAGS_REG))
13272 (clobber (match_scratch:HI 4 "=a"))]
13274 && FLOAT_MODE_P (GET_MODE (operands[1]))
13275 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13276 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13279 (define_insn "*fp_jcc_6_387"
13281 (if_then_else (match_operator 0 "comparison_operator"
13282 [(match_operand 1 "register_operand" "f")
13283 (match_operand 2 "register_operand" "f")])
13285 (label_ref (match_operand 3 "" ""))))
13286 (clobber (reg:CCFP FPSR_REG))
13287 (clobber (reg:CCFP FLAGS_REG))
13288 (clobber (match_scratch:HI 4 "=a"))]
13290 && FLOAT_MODE_P (GET_MODE (operands[1]))
13291 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13292 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13295 (define_insn "*fp_jcc_7_387"
13297 (if_then_else (match_operator 0 "comparison_operator"
13298 [(match_operand 1 "register_operand" "f")
13299 (match_operand 2 "const0_operand" "X")])
13300 (label_ref (match_operand 3 "" ""))
13302 (clobber (reg:CCFP FPSR_REG))
13303 (clobber (reg:CCFP FLAGS_REG))
13304 (clobber (match_scratch:HI 4 "=a"))]
13306 && FLOAT_MODE_P (GET_MODE (operands[1]))
13307 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13308 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13309 && SELECT_CC_MODE (GET_CODE (operands[0]),
13310 operands[1], operands[2]) == CCFPmode
13311 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13314 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13315 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13316 ;; with a precedence over other operators and is always put in the first
13317 ;; place. Swap condition and operands to match ficom instruction.
13319 (define_insn "*fp_jcc_8<mode>_387"
13321 (if_then_else (match_operator 0 "comparison_operator"
13322 [(match_operator 1 "float_operator"
13323 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13324 (match_operand 3 "register_operand" "f,f")])
13325 (label_ref (match_operand 4 "" ""))
13327 (clobber (reg:CCFP FPSR_REG))
13328 (clobber (reg:CCFP FLAGS_REG))
13329 (clobber (match_scratch:HI 5 "=a,a"))]
13330 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13331 && FLOAT_MODE_P (GET_MODE (operands[3]))
13332 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13333 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13334 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13335 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13340 (if_then_else (match_operator 0 "comparison_operator"
13341 [(match_operand 1 "register_operand" "")
13342 (match_operand 2 "nonimmediate_operand" "")])
13343 (match_operand 3 "" "")
13344 (match_operand 4 "" "")))
13345 (clobber (reg:CCFP FPSR_REG))
13346 (clobber (reg:CCFP FLAGS_REG))]
13350 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13351 operands[3], operands[4], NULL_RTX, NULL_RTX);
13357 (if_then_else (match_operator 0 "comparison_operator"
13358 [(match_operand 1 "register_operand" "")
13359 (match_operand 2 "general_operand" "")])
13360 (match_operand 3 "" "")
13361 (match_operand 4 "" "")))
13362 (clobber (reg:CCFP FPSR_REG))
13363 (clobber (reg:CCFP FLAGS_REG))
13364 (clobber (match_scratch:HI 5 "=a"))]
13368 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13369 operands[3], operands[4], operands[5], NULL_RTX);
13375 (if_then_else (match_operator 0 "comparison_operator"
13376 [(match_operator 1 "float_operator"
13377 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13378 (match_operand 3 "register_operand" "")])
13379 (match_operand 4 "" "")
13380 (match_operand 5 "" "")))
13381 (clobber (reg:CCFP FPSR_REG))
13382 (clobber (reg:CCFP FLAGS_REG))
13383 (clobber (match_scratch:HI 6 "=a"))]
13387 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13388 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13389 operands[3], operands[7],
13390 operands[4], operands[5], operands[6], NULL_RTX);
13394 ;; %%% Kill this when reload knows how to do it.
13397 (if_then_else (match_operator 0 "comparison_operator"
13398 [(match_operator 1 "float_operator"
13399 [(match_operand:X87MODEI12 2 "register_operand" "")])
13400 (match_operand 3 "register_operand" "")])
13401 (match_operand 4 "" "")
13402 (match_operand 5 "" "")))
13403 (clobber (reg:CCFP FPSR_REG))
13404 (clobber (reg:CCFP FLAGS_REG))
13405 (clobber (match_scratch:HI 6 "=a"))]
13409 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13410 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13411 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13412 operands[3], operands[7],
13413 operands[4], operands[5], operands[6], operands[2]);
13417 ;; Unconditional and other jump instructions
13419 (define_insn "jump"
13421 (label_ref (match_operand 0 "" "")))]
13424 [(set_attr "type" "ibr")
13425 (set (attr "length")
13426 (if_then_else (and (ge (minus (match_dup 0) (pc))
13428 (lt (minus (match_dup 0) (pc))
13432 (set_attr "modrm" "0")])
13434 (define_expand "indirect_jump"
13435 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13439 (define_insn "*indirect_jump"
13440 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13443 [(set_attr "type" "ibr")
13444 (set_attr "length_immediate" "0")])
13446 (define_insn "*indirect_jump_rtx64"
13447 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13450 [(set_attr "type" "ibr")
13451 (set_attr "length_immediate" "0")])
13453 (define_expand "tablejump"
13454 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13455 (use (label_ref (match_operand 1 "" "")))])]
13458 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13459 relative. Convert the relative address to an absolute address. */
13463 enum rtx_code code;
13469 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13471 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13475 op1 = pic_offset_table_rtx;
13480 op0 = pic_offset_table_rtx;
13484 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13489 (define_insn "*tablejump_1"
13490 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13491 (use (label_ref (match_operand 1 "" "")))]
13494 [(set_attr "type" "ibr")
13495 (set_attr "length_immediate" "0")])
13497 (define_insn "*tablejump_1_rtx64"
13498 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13499 (use (label_ref (match_operand 1 "" "")))]
13502 [(set_attr "type" "ibr")
13503 (set_attr "length_immediate" "0")])
13505 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13508 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13509 (set (match_operand:QI 1 "register_operand" "")
13510 (match_operator:QI 2 "ix86_comparison_operator"
13511 [(reg FLAGS_REG) (const_int 0)]))
13512 (set (match_operand 3 "q_regs_operand" "")
13513 (zero_extend (match_dup 1)))]
13514 "(peep2_reg_dead_p (3, operands[1])
13515 || operands_match_p (operands[1], operands[3]))
13516 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13517 [(set (match_dup 4) (match_dup 0))
13518 (set (strict_low_part (match_dup 5))
13521 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13522 operands[5] = gen_lowpart (QImode, operands[3]);
13523 ix86_expand_clear (operands[3]);
13526 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13529 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13530 (set (match_operand:QI 1 "register_operand" "")
13531 (match_operator:QI 2 "ix86_comparison_operator"
13532 [(reg FLAGS_REG) (const_int 0)]))
13533 (parallel [(set (match_operand 3 "q_regs_operand" "")
13534 (zero_extend (match_dup 1)))
13535 (clobber (reg:CC FLAGS_REG))])]
13536 "(peep2_reg_dead_p (3, operands[1])
13537 || operands_match_p (operands[1], operands[3]))
13538 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13539 [(set (match_dup 4) (match_dup 0))
13540 (set (strict_low_part (match_dup 5))
13543 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13544 operands[5] = gen_lowpart (QImode, operands[3]);
13545 ix86_expand_clear (operands[3]);
13548 ;; Call instructions.
13550 ;; The predicates normally associated with named expanders are not properly
13551 ;; checked for calls. This is a bug in the generic code, but it isn't that
13552 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13554 ;; Call subroutine returning no value.
13556 (define_expand "call_pop"
13557 [(parallel [(call (match_operand:QI 0 "" "")
13558 (match_operand:SI 1 "" ""))
13559 (set (reg:SI SP_REG)
13560 (plus:SI (reg:SI SP_REG)
13561 (match_operand:SI 3 "" "")))])]
13564 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13568 (define_insn "*call_pop_0"
13569 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13570 (match_operand:SI 1 "" ""))
13571 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13572 (match_operand:SI 2 "immediate_operand" "")))]
13575 if (SIBLING_CALL_P (insn))
13578 return "call\t%P0";
13580 [(set_attr "type" "call")])
13582 (define_insn "*call_pop_1"
13583 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13584 (match_operand:SI 1 "" ""))
13585 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13586 (match_operand:SI 2 "immediate_operand" "i")))]
13589 if (constant_call_address_operand (operands[0], Pmode))
13591 if (SIBLING_CALL_P (insn))
13594 return "call\t%P0";
13596 if (SIBLING_CALL_P (insn))
13599 return "call\t%A0";
13601 [(set_attr "type" "call")])
13603 (define_expand "call"
13604 [(call (match_operand:QI 0 "" "")
13605 (match_operand 1 "" ""))
13606 (use (match_operand 2 "" ""))]
13609 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13613 (define_expand "sibcall"
13614 [(call (match_operand:QI 0 "" "")
13615 (match_operand 1 "" ""))
13616 (use (match_operand 2 "" ""))]
13619 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13623 (define_insn "*call_0"
13624 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13625 (match_operand 1 "" ""))]
13628 if (SIBLING_CALL_P (insn))
13631 return "call\t%P0";
13633 [(set_attr "type" "call")])
13635 (define_insn "*call_1"
13636 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13637 (match_operand 1 "" ""))]
13638 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13640 if (constant_call_address_operand (operands[0], Pmode))
13641 return "call\t%P0";
13642 return "call\t%A0";
13644 [(set_attr "type" "call")])
13646 (define_insn "*sibcall_1"
13647 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13648 (match_operand 1 "" ""))]
13649 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13651 if (constant_call_address_operand (operands[0], Pmode))
13655 [(set_attr "type" "call")])
13657 (define_insn "*call_1_rex64"
13658 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13659 (match_operand 1 "" ""))]
13660 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13662 if (constant_call_address_operand (operands[0], Pmode))
13663 return "call\t%P0";
13664 return "call\t%A0";
13666 [(set_attr "type" "call")])
13668 (define_insn "*sibcall_1_rex64"
13669 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13670 (match_operand 1 "" ""))]
13671 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13673 [(set_attr "type" "call")])
13675 (define_insn "*sibcall_1_rex64_v"
13676 [(call (mem:QI (reg:DI 40))
13677 (match_operand 0 "" ""))]
13678 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13680 [(set_attr "type" "call")])
13683 ;; Call subroutine, returning value in operand 0
13685 (define_expand "call_value_pop"
13686 [(parallel [(set (match_operand 0 "" "")
13687 (call (match_operand:QI 1 "" "")
13688 (match_operand:SI 2 "" "")))
13689 (set (reg:SI SP_REG)
13690 (plus:SI (reg:SI SP_REG)
13691 (match_operand:SI 4 "" "")))])]
13694 ix86_expand_call (operands[0], operands[1], operands[2],
13695 operands[3], operands[4], 0);
13699 (define_expand "call_value"
13700 [(set (match_operand 0 "" "")
13701 (call (match_operand:QI 1 "" "")
13702 (match_operand:SI 2 "" "")))
13703 (use (match_operand:SI 3 "" ""))]
13704 ;; Operand 2 not used on the i386.
13707 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13711 (define_expand "sibcall_value"
13712 [(set (match_operand 0 "" "")
13713 (call (match_operand:QI 1 "" "")
13714 (match_operand:SI 2 "" "")))
13715 (use (match_operand:SI 3 "" ""))]
13716 ;; Operand 2 not used on the i386.
13719 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13723 ;; Call subroutine returning any type.
13725 (define_expand "untyped_call"
13726 [(parallel [(call (match_operand 0 "" "")
13728 (match_operand 1 "" "")
13729 (match_operand 2 "" "")])]
13734 /* In order to give reg-stack an easier job in validating two
13735 coprocessor registers as containing a possible return value,
13736 simply pretend the untyped call returns a complex long double
13739 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13740 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13741 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13744 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13746 rtx set = XVECEXP (operands[2], 0, i);
13747 emit_move_insn (SET_DEST (set), SET_SRC (set));
13750 /* The optimizer does not know that the call sets the function value
13751 registers we stored in the result block. We avoid problems by
13752 claiming that all hard registers are used and clobbered at this
13754 emit_insn (gen_blockage (const0_rtx));
13759 ;; Prologue and epilogue instructions
13761 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13762 ;; all of memory. This blocks insns from being moved across this point.
13764 (define_insn "blockage"
13765 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13768 [(set_attr "length" "0")])
13770 ;; Insn emitted into the body of a function to return from a function.
13771 ;; This is only done if the function's epilogue is known to be simple.
13772 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13774 (define_expand "return"
13776 "ix86_can_use_return_insn_p ()"
13778 if (current_function_pops_args)
13780 rtx popc = GEN_INT (current_function_pops_args);
13781 emit_jump_insn (gen_return_pop_internal (popc));
13786 (define_insn "return_internal"
13790 [(set_attr "length" "1")
13791 (set_attr "length_immediate" "0")
13792 (set_attr "modrm" "0")])
13794 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13795 ;; instruction Athlon and K8 have.
13797 (define_insn "return_internal_long"
13799 (unspec [(const_int 0)] UNSPEC_REP)]
13802 [(set_attr "length" "1")
13803 (set_attr "length_immediate" "0")
13804 (set_attr "prefix_rep" "1")
13805 (set_attr "modrm" "0")])
13807 (define_insn "return_pop_internal"
13809 (use (match_operand:SI 0 "const_int_operand" ""))]
13812 [(set_attr "length" "3")
13813 (set_attr "length_immediate" "2")
13814 (set_attr "modrm" "0")])
13816 (define_insn "return_indirect_internal"
13818 (use (match_operand:SI 0 "register_operand" "r"))]
13821 [(set_attr "type" "ibr")
13822 (set_attr "length_immediate" "0")])
13828 [(set_attr "length" "1")
13829 (set_attr "length_immediate" "0")
13830 (set_attr "modrm" "0")])
13832 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13833 ;; branch prediction penalty for the third jump in a 16-byte
13836 (define_insn "align"
13837 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13840 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13841 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13843 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13844 The align insn is used to avoid 3 jump instructions in the row to improve
13845 branch prediction and the benefits hardly outweight the cost of extra 8
13846 nops on the average inserted by full alignment pseudo operation. */
13850 [(set_attr "length" "16")])
13852 (define_expand "prologue"
13855 "ix86_expand_prologue (); DONE;")
13857 (define_insn "set_got"
13858 [(set (match_operand:SI 0 "register_operand" "=r")
13859 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13860 (clobber (reg:CC FLAGS_REG))]
13862 { return output_set_got (operands[0]); }
13863 [(set_attr "type" "multi")
13864 (set_attr "length" "12")])
13866 (define_insn "set_got_rex64"
13867 [(set (match_operand:DI 0 "register_operand" "=r")
13868 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13870 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13871 [(set_attr "type" "lea")
13872 (set_attr "length" "6")])
13874 (define_expand "epilogue"
13877 "ix86_expand_epilogue (1); DONE;")
13879 (define_expand "sibcall_epilogue"
13882 "ix86_expand_epilogue (0); DONE;")
13884 (define_expand "eh_return"
13885 [(use (match_operand 0 "register_operand" ""))]
13888 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13890 /* Tricky bit: we write the address of the handler to which we will
13891 be returning into someone else's stack frame, one word below the
13892 stack address we wish to restore. */
13893 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13894 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13895 tmp = gen_rtx_MEM (Pmode, tmp);
13896 emit_move_insn (tmp, ra);
13898 if (Pmode == SImode)
13899 emit_jump_insn (gen_eh_return_si (sa));
13901 emit_jump_insn (gen_eh_return_di (sa));
13906 (define_insn_and_split "eh_return_si"
13908 (unspec [(match_operand:SI 0 "register_operand" "c")]
13909 UNSPEC_EH_RETURN))]
13914 "ix86_expand_epilogue (2); DONE;")
13916 (define_insn_and_split "eh_return_di"
13918 (unspec [(match_operand:DI 0 "register_operand" "c")]
13919 UNSPEC_EH_RETURN))]
13924 "ix86_expand_epilogue (2); DONE;")
13926 (define_insn "leave"
13927 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13928 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13929 (clobber (mem:BLK (scratch)))]
13932 [(set_attr "type" "leave")])
13934 (define_insn "leave_rex64"
13935 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13936 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13937 (clobber (mem:BLK (scratch)))]
13940 [(set_attr "type" "leave")])
13942 (define_expand "ffssi2"
13944 [(set (match_operand:SI 0 "register_operand" "")
13945 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13946 (clobber (match_scratch:SI 2 ""))
13947 (clobber (reg:CC FLAGS_REG))])]
13951 (define_insn_and_split "*ffs_cmove"
13952 [(set (match_operand:SI 0 "register_operand" "=r")
13953 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13954 (clobber (match_scratch:SI 2 "=&r"))
13955 (clobber (reg:CC FLAGS_REG))]
13958 "&& reload_completed"
13959 [(set (match_dup 2) (const_int -1))
13960 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13961 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13962 (set (match_dup 0) (if_then_else:SI
13963 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13966 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13967 (clobber (reg:CC FLAGS_REG))])]
13970 (define_insn_and_split "*ffs_no_cmove"
13971 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13972 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13973 (clobber (match_scratch:SI 2 "=&q"))
13974 (clobber (reg:CC FLAGS_REG))]
13978 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13979 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13980 (set (strict_low_part (match_dup 3))
13981 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13982 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13983 (clobber (reg:CC FLAGS_REG))])
13984 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13985 (clobber (reg:CC FLAGS_REG))])
13986 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13987 (clobber (reg:CC FLAGS_REG))])]
13989 operands[3] = gen_lowpart (QImode, operands[2]);
13990 ix86_expand_clear (operands[2]);
13993 (define_insn "*ffssi_1"
13994 [(set (reg:CCZ FLAGS_REG)
13995 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13997 (set (match_operand:SI 0 "register_operand" "=r")
13998 (ctz:SI (match_dup 1)))]
14000 "bsf{l}\t{%1, %0|%0, %1}"
14001 [(set_attr "prefix_0f" "1")])
14003 (define_expand "ffsdi2"
14005 [(set (match_operand:DI 0 "register_operand" "")
14006 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14007 (clobber (match_scratch:DI 2 ""))
14008 (clobber (reg:CC FLAGS_REG))])]
14009 "TARGET_64BIT && TARGET_CMOVE"
14012 (define_insn_and_split "*ffs_rex64"
14013 [(set (match_operand:DI 0 "register_operand" "=r")
14014 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14015 (clobber (match_scratch:DI 2 "=&r"))
14016 (clobber (reg:CC FLAGS_REG))]
14017 "TARGET_64BIT && TARGET_CMOVE"
14019 "&& reload_completed"
14020 [(set (match_dup 2) (const_int -1))
14021 (parallel [(set (reg:CCZ FLAGS_REG)
14022 (compare:CCZ (match_dup 1) (const_int 0)))
14023 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14024 (set (match_dup 0) (if_then_else:DI
14025 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14028 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14029 (clobber (reg:CC FLAGS_REG))])]
14032 (define_insn "*ffsdi_1"
14033 [(set (reg:CCZ FLAGS_REG)
14034 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14036 (set (match_operand:DI 0 "register_operand" "=r")
14037 (ctz:DI (match_dup 1)))]
14039 "bsf{q}\t{%1, %0|%0, %1}"
14040 [(set_attr "prefix_0f" "1")])
14042 (define_insn "ctzsi2"
14043 [(set (match_operand:SI 0 "register_operand" "=r")
14044 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14045 (clobber (reg:CC FLAGS_REG))]
14047 "bsf{l}\t{%1, %0|%0, %1}"
14048 [(set_attr "prefix_0f" "1")])
14050 (define_insn "ctzdi2"
14051 [(set (match_operand:DI 0 "register_operand" "=r")
14052 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14053 (clobber (reg:CC FLAGS_REG))]
14055 "bsf{q}\t{%1, %0|%0, %1}"
14056 [(set_attr "prefix_0f" "1")])
14058 (define_expand "clzsi2"
14060 [(set (match_operand:SI 0 "register_operand" "")
14061 (minus:SI (const_int 31)
14062 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14063 (clobber (reg:CC FLAGS_REG))])
14065 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14066 (clobber (reg:CC FLAGS_REG))])]
14070 (define_insn "*bsr"
14071 [(set (match_operand:SI 0 "register_operand" "=r")
14072 (minus:SI (const_int 31)
14073 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14074 (clobber (reg:CC FLAGS_REG))]
14076 "bsr{l}\t{%1, %0|%0, %1}"
14077 [(set_attr "prefix_0f" "1")])
14079 (define_expand "clzdi2"
14081 [(set (match_operand:DI 0 "register_operand" "")
14082 (minus:DI (const_int 63)
14083 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14084 (clobber (reg:CC FLAGS_REG))])
14086 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14087 (clobber (reg:CC FLAGS_REG))])]
14091 (define_insn "*bsr_rex64"
14092 [(set (match_operand:DI 0 "register_operand" "=r")
14093 (minus:DI (const_int 63)
14094 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14095 (clobber (reg:CC FLAGS_REG))]
14097 "bsr{q}\t{%1, %0|%0, %1}"
14098 [(set_attr "prefix_0f" "1")])
14100 ;; Thread-local storage patterns for ELF.
14102 ;; Note that these code sequences must appear exactly as shown
14103 ;; in order to allow linker relaxation.
14105 (define_insn "*tls_global_dynamic_32_gnu"
14106 [(set (match_operand:SI 0 "register_operand" "=a")
14107 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14108 (match_operand:SI 2 "tls_symbolic_operand" "")
14109 (match_operand:SI 3 "call_insn_operand" "")]
14111 (clobber (match_scratch:SI 4 "=d"))
14112 (clobber (match_scratch:SI 5 "=c"))
14113 (clobber (reg:CC FLAGS_REG))]
14114 "!TARGET_64BIT && TARGET_GNU_TLS"
14115 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14116 [(set_attr "type" "multi")
14117 (set_attr "length" "12")])
14119 (define_insn "*tls_global_dynamic_32_sun"
14120 [(set (match_operand:SI 0 "register_operand" "=a")
14121 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14122 (match_operand:SI 2 "tls_symbolic_operand" "")
14123 (match_operand:SI 3 "call_insn_operand" "")]
14125 (clobber (match_scratch:SI 4 "=d"))
14126 (clobber (match_scratch:SI 5 "=c"))
14127 (clobber (reg:CC FLAGS_REG))]
14128 "!TARGET_64BIT && TARGET_SUN_TLS"
14129 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14130 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14131 [(set_attr "type" "multi")
14132 (set_attr "length" "14")])
14134 (define_expand "tls_global_dynamic_32"
14135 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14138 (match_operand:SI 1 "tls_symbolic_operand" "")
14141 (clobber (match_scratch:SI 4 ""))
14142 (clobber (match_scratch:SI 5 ""))
14143 (clobber (reg:CC FLAGS_REG))])]
14147 operands[2] = pic_offset_table_rtx;
14150 operands[2] = gen_reg_rtx (Pmode);
14151 emit_insn (gen_set_got (operands[2]));
14153 operands[3] = ix86_tls_get_addr ();
14156 (define_insn "*tls_global_dynamic_64"
14157 [(set (match_operand:DI 0 "register_operand" "=a")
14158 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14159 (match_operand:DI 3 "" "")))
14160 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14163 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14164 [(set_attr "type" "multi")
14165 (set_attr "length" "16")])
14167 (define_expand "tls_global_dynamic_64"
14168 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14169 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14170 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14174 operands[2] = ix86_tls_get_addr ();
14177 (define_insn "*tls_local_dynamic_base_32_gnu"
14178 [(set (match_operand:SI 0 "register_operand" "=a")
14179 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14180 (match_operand:SI 2 "call_insn_operand" "")]
14181 UNSPEC_TLS_LD_BASE))
14182 (clobber (match_scratch:SI 3 "=d"))
14183 (clobber (match_scratch:SI 4 "=c"))
14184 (clobber (reg:CC FLAGS_REG))]
14185 "!TARGET_64BIT && TARGET_GNU_TLS"
14186 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14187 [(set_attr "type" "multi")
14188 (set_attr "length" "11")])
14190 (define_insn "*tls_local_dynamic_base_32_sun"
14191 [(set (match_operand:SI 0 "register_operand" "=a")
14192 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14193 (match_operand:SI 2 "call_insn_operand" "")]
14194 UNSPEC_TLS_LD_BASE))
14195 (clobber (match_scratch:SI 3 "=d"))
14196 (clobber (match_scratch:SI 4 "=c"))
14197 (clobber (reg:CC FLAGS_REG))]
14198 "!TARGET_64BIT && TARGET_SUN_TLS"
14199 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14200 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14201 [(set_attr "type" "multi")
14202 (set_attr "length" "13")])
14204 (define_expand "tls_local_dynamic_base_32"
14205 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14206 (unspec:SI [(match_dup 1) (match_dup 2)]
14207 UNSPEC_TLS_LD_BASE))
14208 (clobber (match_scratch:SI 3 ""))
14209 (clobber (match_scratch:SI 4 ""))
14210 (clobber (reg:CC FLAGS_REG))])]
14214 operands[1] = pic_offset_table_rtx;
14217 operands[1] = gen_reg_rtx (Pmode);
14218 emit_insn (gen_set_got (operands[1]));
14220 operands[2] = ix86_tls_get_addr ();
14223 (define_insn "*tls_local_dynamic_base_64"
14224 [(set (match_operand:DI 0 "register_operand" "=a")
14225 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14226 (match_operand:DI 2 "" "")))
14227 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14229 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14230 [(set_attr "type" "multi")
14231 (set_attr "length" "12")])
14233 (define_expand "tls_local_dynamic_base_64"
14234 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14235 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14236 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14239 operands[1] = ix86_tls_get_addr ();
14242 ;; Local dynamic of a single variable is a lose. Show combine how
14243 ;; to convert that back to global dynamic.
14245 (define_insn_and_split "*tls_local_dynamic_32_once"
14246 [(set (match_operand:SI 0 "register_operand" "=a")
14247 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14248 (match_operand:SI 2 "call_insn_operand" "")]
14249 UNSPEC_TLS_LD_BASE)
14250 (const:SI (unspec:SI
14251 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14253 (clobber (match_scratch:SI 4 "=d"))
14254 (clobber (match_scratch:SI 5 "=c"))
14255 (clobber (reg:CC FLAGS_REG))]
14259 [(parallel [(set (match_dup 0)
14260 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14262 (clobber (match_dup 4))
14263 (clobber (match_dup 5))
14264 (clobber (reg:CC FLAGS_REG))])]
14267 ;; Load and add the thread base pointer from %gs:0.
14269 (define_insn "*load_tp_si"
14270 [(set (match_operand:SI 0 "register_operand" "=r")
14271 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14273 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14274 [(set_attr "type" "imov")
14275 (set_attr "modrm" "0")
14276 (set_attr "length" "7")
14277 (set_attr "memory" "load")
14278 (set_attr "imm_disp" "false")])
14280 (define_insn "*add_tp_si"
14281 [(set (match_operand:SI 0 "register_operand" "=r")
14282 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14283 (match_operand:SI 1 "register_operand" "0")))
14284 (clobber (reg:CC FLAGS_REG))]
14286 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14287 [(set_attr "type" "alu")
14288 (set_attr "modrm" "0")
14289 (set_attr "length" "7")
14290 (set_attr "memory" "load")
14291 (set_attr "imm_disp" "false")])
14293 (define_insn "*load_tp_di"
14294 [(set (match_operand:DI 0 "register_operand" "=r")
14295 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14297 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14298 [(set_attr "type" "imov")
14299 (set_attr "modrm" "0")
14300 (set_attr "length" "7")
14301 (set_attr "memory" "load")
14302 (set_attr "imm_disp" "false")])
14304 (define_insn "*add_tp_di"
14305 [(set (match_operand:DI 0 "register_operand" "=r")
14306 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14307 (match_operand:DI 1 "register_operand" "0")))
14308 (clobber (reg:CC FLAGS_REG))]
14310 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14311 [(set_attr "type" "alu")
14312 (set_attr "modrm" "0")
14313 (set_attr "length" "7")
14314 (set_attr "memory" "load")
14315 (set_attr "imm_disp" "false")])
14317 ;; These patterns match the binary 387 instructions for addM3, subM3,
14318 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14319 ;; SFmode. The first is the normal insn, the second the same insn but
14320 ;; with one operand a conversion, and the third the same insn but with
14321 ;; the other operand a conversion. The conversion may be SFmode or
14322 ;; SImode if the target mode DFmode, but only SImode if the target mode
14325 ;; Gcc is slightly more smart about handling normal two address instructions
14326 ;; so use special patterns for add and mull.
14328 (define_insn "*fop_sf_comm_mixed"
14329 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14330 (match_operator:SF 3 "binary_fp_operator"
14331 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14332 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14333 "TARGET_MIX_SSE_I387
14334 && COMMUTATIVE_ARITH_P (operands[3])
14335 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14336 "* return output_387_binary_op (insn, operands);"
14337 [(set (attr "type")
14338 (if_then_else (eq_attr "alternative" "1")
14339 (if_then_else (match_operand:SF 3 "mult_operator" "")
14340 (const_string "ssemul")
14341 (const_string "sseadd"))
14342 (if_then_else (match_operand:SF 3 "mult_operator" "")
14343 (const_string "fmul")
14344 (const_string "fop"))))
14345 (set_attr "mode" "SF")])
14347 (define_insn "*fop_sf_comm_sse"
14348 [(set (match_operand:SF 0 "register_operand" "=x")
14349 (match_operator:SF 3 "binary_fp_operator"
14350 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14351 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14353 && COMMUTATIVE_ARITH_P (operands[3])
14354 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14355 "* return output_387_binary_op (insn, operands);"
14356 [(set (attr "type")
14357 (if_then_else (match_operand:SF 3 "mult_operator" "")
14358 (const_string "ssemul")
14359 (const_string "sseadd")))
14360 (set_attr "mode" "SF")])
14362 (define_insn "*fop_sf_comm_i387"
14363 [(set (match_operand:SF 0 "register_operand" "=f")
14364 (match_operator:SF 3 "binary_fp_operator"
14365 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14366 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14368 && COMMUTATIVE_ARITH_P (operands[3])
14369 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14370 "* return output_387_binary_op (insn, operands);"
14371 [(set (attr "type")
14372 (if_then_else (match_operand:SF 3 "mult_operator" "")
14373 (const_string "fmul")
14374 (const_string "fop")))
14375 (set_attr "mode" "SF")])
14377 (define_insn "*fop_sf_1_mixed"
14378 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14379 (match_operator:SF 3 "binary_fp_operator"
14380 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14381 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14382 "TARGET_MIX_SSE_I387
14383 && !COMMUTATIVE_ARITH_P (operands[3])
14384 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14385 "* return output_387_binary_op (insn, operands);"
14386 [(set (attr "type")
14387 (cond [(and (eq_attr "alternative" "2")
14388 (match_operand:SF 3 "mult_operator" ""))
14389 (const_string "ssemul")
14390 (and (eq_attr "alternative" "2")
14391 (match_operand:SF 3 "div_operator" ""))
14392 (const_string "ssediv")
14393 (eq_attr "alternative" "2")
14394 (const_string "sseadd")
14395 (match_operand:SF 3 "mult_operator" "")
14396 (const_string "fmul")
14397 (match_operand:SF 3 "div_operator" "")
14398 (const_string "fdiv")
14400 (const_string "fop")))
14401 (set_attr "mode" "SF")])
14403 (define_insn "*fop_sf_1_sse"
14404 [(set (match_operand:SF 0 "register_operand" "=x")
14405 (match_operator:SF 3 "binary_fp_operator"
14406 [(match_operand:SF 1 "register_operand" "0")
14407 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14409 && !COMMUTATIVE_ARITH_P (operands[3])"
14410 "* return output_387_binary_op (insn, operands);"
14411 [(set (attr "type")
14412 (cond [(match_operand:SF 3 "mult_operator" "")
14413 (const_string "ssemul")
14414 (match_operand:SF 3 "div_operator" "")
14415 (const_string "ssediv")
14417 (const_string "sseadd")))
14418 (set_attr "mode" "SF")])
14420 ;; This pattern is not fully shadowed by the pattern above.
14421 (define_insn "*fop_sf_1_i387"
14422 [(set (match_operand:SF 0 "register_operand" "=f,f")
14423 (match_operator:SF 3 "binary_fp_operator"
14424 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14425 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14426 "TARGET_80387 && !TARGET_SSE_MATH
14427 && !COMMUTATIVE_ARITH_P (operands[3])
14428 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14429 "* return output_387_binary_op (insn, operands);"
14430 [(set (attr "type")
14431 (cond [(match_operand:SF 3 "mult_operator" "")
14432 (const_string "fmul")
14433 (match_operand:SF 3 "div_operator" "")
14434 (const_string "fdiv")
14436 (const_string "fop")))
14437 (set_attr "mode" "SF")])
14439 ;; ??? Add SSE splitters for these!
14440 (define_insn "*fop_sf_2<mode>_i387"
14441 [(set (match_operand:SF 0 "register_operand" "=f,f")
14442 (match_operator:SF 3 "binary_fp_operator"
14443 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14444 (match_operand:SF 2 "register_operand" "0,0")]))]
14445 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14446 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14447 [(set (attr "type")
14448 (cond [(match_operand:SF 3 "mult_operator" "")
14449 (const_string "fmul")
14450 (match_operand:SF 3 "div_operator" "")
14451 (const_string "fdiv")
14453 (const_string "fop")))
14454 (set_attr "fp_int_src" "true")
14455 (set_attr "mode" "<MODE>")])
14457 (define_insn "*fop_sf_3<mode>_i387"
14458 [(set (match_operand:SF 0 "register_operand" "=f,f")
14459 (match_operator:SF 3 "binary_fp_operator"
14460 [(match_operand:SF 1 "register_operand" "0,0")
14461 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14462 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14463 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14464 [(set (attr "type")
14465 (cond [(match_operand:SF 3 "mult_operator" "")
14466 (const_string "fmul")
14467 (match_operand:SF 3 "div_operator" "")
14468 (const_string "fdiv")
14470 (const_string "fop")))
14471 (set_attr "fp_int_src" "true")
14472 (set_attr "mode" "<MODE>")])
14474 (define_insn "*fop_df_comm_mixed"
14475 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14476 (match_operator:DF 3 "binary_fp_operator"
14477 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14478 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14479 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14480 && COMMUTATIVE_ARITH_P (operands[3])
14481 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14482 "* return output_387_binary_op (insn, operands);"
14483 [(set (attr "type")
14484 (if_then_else (eq_attr "alternative" "1")
14485 (if_then_else (match_operand:SF 3 "mult_operator" "")
14486 (const_string "ssemul")
14487 (const_string "sseadd"))
14488 (if_then_else (match_operand:SF 3 "mult_operator" "")
14489 (const_string "fmul")
14490 (const_string "fop"))))
14491 (set_attr "mode" "DF")])
14493 (define_insn "*fop_df_comm_sse"
14494 [(set (match_operand:DF 0 "register_operand" "=Y")
14495 (match_operator:DF 3 "binary_fp_operator"
14496 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14497 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14498 "TARGET_SSE2 && TARGET_SSE_MATH
14499 && COMMUTATIVE_ARITH_P (operands[3])
14500 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14501 "* return output_387_binary_op (insn, operands);"
14502 [(set (attr "type")
14503 (if_then_else (match_operand:SF 3 "mult_operator" "")
14504 (const_string "ssemul")
14505 (const_string "sseadd")))
14506 (set_attr "mode" "DF")])
14508 (define_insn "*fop_df_comm_i387"
14509 [(set (match_operand:DF 0 "register_operand" "=f")
14510 (match_operator:DF 3 "binary_fp_operator"
14511 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14512 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14514 && COMMUTATIVE_ARITH_P (operands[3])
14515 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14516 "* return output_387_binary_op (insn, operands);"
14517 [(set (attr "type")
14518 (if_then_else (match_operand:SF 3 "mult_operator" "")
14519 (const_string "fmul")
14520 (const_string "fop")))
14521 (set_attr "mode" "DF")])
14523 (define_insn "*fop_df_1_mixed"
14524 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14525 (match_operator:DF 3 "binary_fp_operator"
14526 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14527 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14528 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14529 && !COMMUTATIVE_ARITH_P (operands[3])
14530 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14531 "* return output_387_binary_op (insn, operands);"
14532 [(set (attr "type")
14533 (cond [(and (eq_attr "alternative" "2")
14534 (match_operand:SF 3 "mult_operator" ""))
14535 (const_string "ssemul")
14536 (and (eq_attr "alternative" "2")
14537 (match_operand:SF 3 "div_operator" ""))
14538 (const_string "ssediv")
14539 (eq_attr "alternative" "2")
14540 (const_string "sseadd")
14541 (match_operand:DF 3 "mult_operator" "")
14542 (const_string "fmul")
14543 (match_operand:DF 3 "div_operator" "")
14544 (const_string "fdiv")
14546 (const_string "fop")))
14547 (set_attr "mode" "DF")])
14549 (define_insn "*fop_df_1_sse"
14550 [(set (match_operand:DF 0 "register_operand" "=Y")
14551 (match_operator:DF 3 "binary_fp_operator"
14552 [(match_operand:DF 1 "register_operand" "0")
14553 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14554 "TARGET_SSE2 && TARGET_SSE_MATH
14555 && !COMMUTATIVE_ARITH_P (operands[3])"
14556 "* return output_387_binary_op (insn, operands);"
14557 [(set_attr "mode" "DF")
14559 (cond [(match_operand:SF 3 "mult_operator" "")
14560 (const_string "ssemul")
14561 (match_operand:SF 3 "div_operator" "")
14562 (const_string "ssediv")
14564 (const_string "sseadd")))])
14566 ;; This pattern is not fully shadowed by the pattern above.
14567 (define_insn "*fop_df_1_i387"
14568 [(set (match_operand:DF 0 "register_operand" "=f,f")
14569 (match_operator:DF 3 "binary_fp_operator"
14570 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14571 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14572 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14573 && !COMMUTATIVE_ARITH_P (operands[3])
14574 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14575 "* return output_387_binary_op (insn, operands);"
14576 [(set (attr "type")
14577 (cond [(match_operand:DF 3 "mult_operator" "")
14578 (const_string "fmul")
14579 (match_operand:DF 3 "div_operator" "")
14580 (const_string "fdiv")
14582 (const_string "fop")))
14583 (set_attr "mode" "DF")])
14585 ;; ??? Add SSE splitters for these!
14586 (define_insn "*fop_df_2<mode>_i387"
14587 [(set (match_operand:DF 0 "register_operand" "=f,f")
14588 (match_operator:DF 3 "binary_fp_operator"
14589 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14590 (match_operand:DF 2 "register_operand" "0,0")]))]
14591 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14592 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14593 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14594 [(set (attr "type")
14595 (cond [(match_operand:DF 3 "mult_operator" "")
14596 (const_string "fmul")
14597 (match_operand:DF 3 "div_operator" "")
14598 (const_string "fdiv")
14600 (const_string "fop")))
14601 (set_attr "fp_int_src" "true")
14602 (set_attr "mode" "<MODE>")])
14604 (define_insn "*fop_df_3<mode>_i387"
14605 [(set (match_operand:DF 0 "register_operand" "=f,f")
14606 (match_operator:DF 3 "binary_fp_operator"
14607 [(match_operand:DF 1 "register_operand" "0,0")
14608 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14609 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14610 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14611 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14612 [(set (attr "type")
14613 (cond [(match_operand:DF 3 "mult_operator" "")
14614 (const_string "fmul")
14615 (match_operand:DF 3 "div_operator" "")
14616 (const_string "fdiv")
14618 (const_string "fop")))
14619 (set_attr "fp_int_src" "true")
14620 (set_attr "mode" "<MODE>")])
14622 (define_insn "*fop_df_4_i387"
14623 [(set (match_operand:DF 0 "register_operand" "=f,f")
14624 (match_operator:DF 3 "binary_fp_operator"
14625 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14626 (match_operand:DF 2 "register_operand" "0,f")]))]
14627 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14628 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14629 "* return output_387_binary_op (insn, operands);"
14630 [(set (attr "type")
14631 (cond [(match_operand:DF 3 "mult_operator" "")
14632 (const_string "fmul")
14633 (match_operand:DF 3 "div_operator" "")
14634 (const_string "fdiv")
14636 (const_string "fop")))
14637 (set_attr "mode" "SF")])
14639 (define_insn "*fop_df_5_i387"
14640 [(set (match_operand:DF 0 "register_operand" "=f,f")
14641 (match_operator:DF 3 "binary_fp_operator"
14642 [(match_operand:DF 1 "register_operand" "0,f")
14644 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14645 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14646 "* return output_387_binary_op (insn, operands);"
14647 [(set (attr "type")
14648 (cond [(match_operand:DF 3 "mult_operator" "")
14649 (const_string "fmul")
14650 (match_operand:DF 3 "div_operator" "")
14651 (const_string "fdiv")
14653 (const_string "fop")))
14654 (set_attr "mode" "SF")])
14656 (define_insn "*fop_df_6_i387"
14657 [(set (match_operand:DF 0 "register_operand" "=f,f")
14658 (match_operator:DF 3 "binary_fp_operator"
14660 (match_operand:SF 1 "register_operand" "0,f"))
14662 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14663 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14664 "* return output_387_binary_op (insn, operands);"
14665 [(set (attr "type")
14666 (cond [(match_operand:DF 3 "mult_operator" "")
14667 (const_string "fmul")
14668 (match_operand:DF 3 "div_operator" "")
14669 (const_string "fdiv")
14671 (const_string "fop")))
14672 (set_attr "mode" "SF")])
14674 (define_insn "*fop_xf_comm_i387"
14675 [(set (match_operand:XF 0 "register_operand" "=f")
14676 (match_operator:XF 3 "binary_fp_operator"
14677 [(match_operand:XF 1 "register_operand" "%0")
14678 (match_operand:XF 2 "register_operand" "f")]))]
14680 && COMMUTATIVE_ARITH_P (operands[3])"
14681 "* return output_387_binary_op (insn, operands);"
14682 [(set (attr "type")
14683 (if_then_else (match_operand:XF 3 "mult_operator" "")
14684 (const_string "fmul")
14685 (const_string "fop")))
14686 (set_attr "mode" "XF")])
14688 (define_insn "*fop_xf_1_i387"
14689 [(set (match_operand:XF 0 "register_operand" "=f,f")
14690 (match_operator:XF 3 "binary_fp_operator"
14691 [(match_operand:XF 1 "register_operand" "0,f")
14692 (match_operand:XF 2 "register_operand" "f,0")]))]
14694 && !COMMUTATIVE_ARITH_P (operands[3])"
14695 "* return output_387_binary_op (insn, operands);"
14696 [(set (attr "type")
14697 (cond [(match_operand:XF 3 "mult_operator" "")
14698 (const_string "fmul")
14699 (match_operand:XF 3 "div_operator" "")
14700 (const_string "fdiv")
14702 (const_string "fop")))
14703 (set_attr "mode" "XF")])
14705 (define_insn "*fop_xf_2<mode>_i387"
14706 [(set (match_operand:XF 0 "register_operand" "=f,f")
14707 (match_operator:XF 3 "binary_fp_operator"
14708 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14709 (match_operand:XF 2 "register_operand" "0,0")]))]
14710 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14711 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14712 [(set (attr "type")
14713 (cond [(match_operand:XF 3 "mult_operator" "")
14714 (const_string "fmul")
14715 (match_operand:XF 3 "div_operator" "")
14716 (const_string "fdiv")
14718 (const_string "fop")))
14719 (set_attr "fp_int_src" "true")
14720 (set_attr "mode" "<MODE>")])
14722 (define_insn "*fop_xf_3<mode>_i387"
14723 [(set (match_operand:XF 0 "register_operand" "=f,f")
14724 (match_operator:XF 3 "binary_fp_operator"
14725 [(match_operand:XF 1 "register_operand" "0,0")
14726 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14727 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14728 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14729 [(set (attr "type")
14730 (cond [(match_operand:XF 3 "mult_operator" "")
14731 (const_string "fmul")
14732 (match_operand:XF 3 "div_operator" "")
14733 (const_string "fdiv")
14735 (const_string "fop")))
14736 (set_attr "fp_int_src" "true")
14737 (set_attr "mode" "<MODE>")])
14739 (define_insn "*fop_xf_4_i387"
14740 [(set (match_operand:XF 0 "register_operand" "=f,f")
14741 (match_operator:XF 3 "binary_fp_operator"
14742 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14743 (match_operand:XF 2 "register_operand" "0,f")]))]
14745 "* return output_387_binary_op (insn, operands);"
14746 [(set (attr "type")
14747 (cond [(match_operand:XF 3 "mult_operator" "")
14748 (const_string "fmul")
14749 (match_operand:XF 3 "div_operator" "")
14750 (const_string "fdiv")
14752 (const_string "fop")))
14753 (set_attr "mode" "SF")])
14755 (define_insn "*fop_xf_5_i387"
14756 [(set (match_operand:XF 0 "register_operand" "=f,f")
14757 (match_operator:XF 3 "binary_fp_operator"
14758 [(match_operand:XF 1 "register_operand" "0,f")
14760 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14762 "* return output_387_binary_op (insn, operands);"
14763 [(set (attr "type")
14764 (cond [(match_operand:XF 3 "mult_operator" "")
14765 (const_string "fmul")
14766 (match_operand:XF 3 "div_operator" "")
14767 (const_string "fdiv")
14769 (const_string "fop")))
14770 (set_attr "mode" "SF")])
14772 (define_insn "*fop_xf_6_i387"
14773 [(set (match_operand:XF 0 "register_operand" "=f,f")
14774 (match_operator:XF 3 "binary_fp_operator"
14776 (match_operand 1 "register_operand" "0,f"))
14778 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14780 "* return output_387_binary_op (insn, operands);"
14781 [(set (attr "type")
14782 (cond [(match_operand:XF 3 "mult_operator" "")
14783 (const_string "fmul")
14784 (match_operand:XF 3 "div_operator" "")
14785 (const_string "fdiv")
14787 (const_string "fop")))
14788 (set_attr "mode" "SF")])
14791 [(set (match_operand 0 "register_operand" "")
14792 (match_operator 3 "binary_fp_operator"
14793 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14794 (match_operand 2 "register_operand" "")]))]
14795 "TARGET_80387 && reload_completed
14796 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14799 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14800 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14801 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14802 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14803 GET_MODE (operands[3]),
14806 ix86_free_from_memory (GET_MODE (operands[1]));
14811 [(set (match_operand 0 "register_operand" "")
14812 (match_operator 3 "binary_fp_operator"
14813 [(match_operand 1 "register_operand" "")
14814 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14815 "TARGET_80387 && reload_completed
14816 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14819 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14820 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14821 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14822 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14823 GET_MODE (operands[3]),
14826 ix86_free_from_memory (GET_MODE (operands[2]));
14830 ;; FPU special functions.
14832 (define_expand "sqrtsf2"
14833 [(set (match_operand:SF 0 "register_operand" "")
14834 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14835 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14837 if (!TARGET_SSE_MATH)
14838 operands[1] = force_reg (SFmode, operands[1]);
14841 (define_insn "*sqrtsf2_mixed"
14842 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14843 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14844 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14847 sqrtss\t{%1, %0|%0, %1}"
14848 [(set_attr "type" "fpspc,sse")
14849 (set_attr "mode" "SF,SF")
14850 (set_attr "athlon_decode" "direct,*")])
14852 (define_insn "*sqrtsf2_sse"
14853 [(set (match_operand:SF 0 "register_operand" "=x")
14854 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14856 "sqrtss\t{%1, %0|%0, %1}"
14857 [(set_attr "type" "sse")
14858 (set_attr "mode" "SF")
14859 (set_attr "athlon_decode" "*")])
14861 (define_insn "*sqrtsf2_i387"
14862 [(set (match_operand:SF 0 "register_operand" "=f")
14863 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14864 "TARGET_USE_FANCY_MATH_387"
14866 [(set_attr "type" "fpspc")
14867 (set_attr "mode" "SF")
14868 (set_attr "athlon_decode" "direct")])
14870 (define_expand "sqrtdf2"
14871 [(set (match_operand:DF 0 "register_operand" "")
14872 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14873 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14875 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14876 operands[1] = force_reg (DFmode, operands[1]);
14879 (define_insn "*sqrtdf2_mixed"
14880 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14881 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14882 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14885 sqrtsd\t{%1, %0|%0, %1}"
14886 [(set_attr "type" "fpspc,sse")
14887 (set_attr "mode" "DF,DF")
14888 (set_attr "athlon_decode" "direct,*")])
14890 (define_insn "*sqrtdf2_sse"
14891 [(set (match_operand:DF 0 "register_operand" "=Y")
14892 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14893 "TARGET_SSE2 && TARGET_SSE_MATH"
14894 "sqrtsd\t{%1, %0|%0, %1}"
14895 [(set_attr "type" "sse")
14896 (set_attr "mode" "DF")
14897 (set_attr "athlon_decode" "*")])
14899 (define_insn "*sqrtdf2_i387"
14900 [(set (match_operand:DF 0 "register_operand" "=f")
14901 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14902 "TARGET_USE_FANCY_MATH_387"
14904 [(set_attr "type" "fpspc")
14905 (set_attr "mode" "DF")
14906 (set_attr "athlon_decode" "direct")])
14908 (define_insn "*sqrtextendsfdf2_i387"
14909 [(set (match_operand:DF 0 "register_operand" "=f")
14910 (sqrt:DF (float_extend:DF
14911 (match_operand:SF 1 "register_operand" "0"))))]
14912 "TARGET_USE_FANCY_MATH_387
14913 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14915 [(set_attr "type" "fpspc")
14916 (set_attr "mode" "DF")
14917 (set_attr "athlon_decode" "direct")])
14919 (define_insn "sqrtxf2"
14920 [(set (match_operand:XF 0 "register_operand" "=f")
14921 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14922 "TARGET_USE_FANCY_MATH_387
14923 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14925 [(set_attr "type" "fpspc")
14926 (set_attr "mode" "XF")
14927 (set_attr "athlon_decode" "direct")])
14929 (define_insn "*sqrtextendsfxf2_i387"
14930 [(set (match_operand:XF 0 "register_operand" "=f")
14931 (sqrt:XF (float_extend:XF
14932 (match_operand:SF 1 "register_operand" "0"))))]
14933 "TARGET_USE_FANCY_MATH_387"
14935 [(set_attr "type" "fpspc")
14936 (set_attr "mode" "XF")
14937 (set_attr "athlon_decode" "direct")])
14939 (define_insn "*sqrtextenddfxf2_i387"
14940 [(set (match_operand:XF 0 "register_operand" "=f")
14941 (sqrt:XF (float_extend:XF
14942 (match_operand:DF 1 "register_operand" "0"))))]
14943 "TARGET_USE_FANCY_MATH_387"
14945 [(set_attr "type" "fpspc")
14946 (set_attr "mode" "XF")
14947 (set_attr "athlon_decode" "direct")])
14949 (define_insn "fpremxf4"
14950 [(set (match_operand:XF 0 "register_operand" "=f")
14951 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14952 (match_operand:XF 3 "register_operand" "1")]
14954 (set (match_operand:XF 1 "register_operand" "=u")
14955 (unspec:XF [(match_dup 2) (match_dup 3)]
14957 (set (reg:CCFP FPSR_REG)
14958 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14959 "TARGET_USE_FANCY_MATH_387
14960 && flag_unsafe_math_optimizations"
14962 [(set_attr "type" "fpspc")
14963 (set_attr "mode" "XF")])
14965 (define_expand "fmodsf3"
14966 [(use (match_operand:SF 0 "register_operand" ""))
14967 (use (match_operand:SF 1 "register_operand" ""))
14968 (use (match_operand:SF 2 "register_operand" ""))]
14969 "TARGET_USE_FANCY_MATH_387
14970 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14971 && flag_unsafe_math_optimizations"
14973 rtx label = gen_label_rtx ();
14975 rtx op1 = gen_reg_rtx (XFmode);
14976 rtx op2 = gen_reg_rtx (XFmode);
14978 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14979 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14981 emit_label (label);
14983 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14984 ix86_emit_fp_unordered_jump (label);
14986 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14990 (define_expand "fmoddf3"
14991 [(use (match_operand:DF 0 "register_operand" ""))
14992 (use (match_operand:DF 1 "register_operand" ""))
14993 (use (match_operand:DF 2 "register_operand" ""))]
14994 "TARGET_USE_FANCY_MATH_387
14995 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14996 && flag_unsafe_math_optimizations"
14998 rtx label = gen_label_rtx ();
15000 rtx op1 = gen_reg_rtx (XFmode);
15001 rtx op2 = gen_reg_rtx (XFmode);
15003 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15004 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15006 emit_label (label);
15008 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15009 ix86_emit_fp_unordered_jump (label);
15011 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15015 (define_expand "fmodxf3"
15016 [(use (match_operand:XF 0 "register_operand" ""))
15017 (use (match_operand:XF 1 "register_operand" ""))
15018 (use (match_operand:XF 2 "register_operand" ""))]
15019 "TARGET_USE_FANCY_MATH_387
15020 && flag_unsafe_math_optimizations"
15022 rtx label = gen_label_rtx ();
15024 emit_label (label);
15026 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15027 operands[1], operands[2]));
15028 ix86_emit_fp_unordered_jump (label);
15030 emit_move_insn (operands[0], operands[1]);
15034 (define_insn "fprem1xf4"
15035 [(set (match_operand:XF 0 "register_operand" "=f")
15036 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15037 (match_operand:XF 3 "register_operand" "1")]
15039 (set (match_operand:XF 1 "register_operand" "=u")
15040 (unspec:XF [(match_dup 2) (match_dup 3)]
15042 (set (reg:CCFP FPSR_REG)
15043 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15044 "TARGET_USE_FANCY_MATH_387
15045 && flag_unsafe_math_optimizations"
15047 [(set_attr "type" "fpspc")
15048 (set_attr "mode" "XF")])
15050 (define_expand "dremsf3"
15051 [(use (match_operand:SF 0 "register_operand" ""))
15052 (use (match_operand:SF 1 "register_operand" ""))
15053 (use (match_operand:SF 2 "register_operand" ""))]
15054 "TARGET_USE_FANCY_MATH_387
15055 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15056 && flag_unsafe_math_optimizations"
15058 rtx label = gen_label_rtx ();
15060 rtx op1 = gen_reg_rtx (XFmode);
15061 rtx op2 = gen_reg_rtx (XFmode);
15063 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15064 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15066 emit_label (label);
15068 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15069 ix86_emit_fp_unordered_jump (label);
15071 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15075 (define_expand "dremdf3"
15076 [(use (match_operand:DF 0 "register_operand" ""))
15077 (use (match_operand:DF 1 "register_operand" ""))
15078 (use (match_operand:DF 2 "register_operand" ""))]
15079 "TARGET_USE_FANCY_MATH_387
15080 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15081 && flag_unsafe_math_optimizations"
15083 rtx label = gen_label_rtx ();
15085 rtx op1 = gen_reg_rtx (XFmode);
15086 rtx op2 = gen_reg_rtx (XFmode);
15088 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15089 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15091 emit_label (label);
15093 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15094 ix86_emit_fp_unordered_jump (label);
15096 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15100 (define_expand "dremxf3"
15101 [(use (match_operand:XF 0 "register_operand" ""))
15102 (use (match_operand:XF 1 "register_operand" ""))
15103 (use (match_operand:XF 2 "register_operand" ""))]
15104 "TARGET_USE_FANCY_MATH_387
15105 && flag_unsafe_math_optimizations"
15107 rtx label = gen_label_rtx ();
15109 emit_label (label);
15111 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15112 operands[1], operands[2]));
15113 ix86_emit_fp_unordered_jump (label);
15115 emit_move_insn (operands[0], operands[1]);
15119 (define_insn "*sindf2"
15120 [(set (match_operand:DF 0 "register_operand" "=f")
15121 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15122 "TARGET_USE_FANCY_MATH_387
15123 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15124 && flag_unsafe_math_optimizations"
15126 [(set_attr "type" "fpspc")
15127 (set_attr "mode" "DF")])
15129 (define_insn "*sinsf2"
15130 [(set (match_operand:SF 0 "register_operand" "=f")
15131 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15132 "TARGET_USE_FANCY_MATH_387
15133 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15134 && flag_unsafe_math_optimizations"
15136 [(set_attr "type" "fpspc")
15137 (set_attr "mode" "SF")])
15139 (define_insn "*sinextendsfdf2"
15140 [(set (match_operand:DF 0 "register_operand" "=f")
15141 (unspec:DF [(float_extend:DF
15142 (match_operand:SF 1 "register_operand" "0"))]
15144 "TARGET_USE_FANCY_MATH_387
15145 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15146 && flag_unsafe_math_optimizations"
15148 [(set_attr "type" "fpspc")
15149 (set_attr "mode" "DF")])
15151 (define_insn "*sinxf2"
15152 [(set (match_operand:XF 0 "register_operand" "=f")
15153 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15154 "TARGET_USE_FANCY_MATH_387
15155 && flag_unsafe_math_optimizations"
15157 [(set_attr "type" "fpspc")
15158 (set_attr "mode" "XF")])
15160 (define_insn "*cosdf2"
15161 [(set (match_operand:DF 0 "register_operand" "=f")
15162 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15163 "TARGET_USE_FANCY_MATH_387
15164 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15165 && flag_unsafe_math_optimizations"
15167 [(set_attr "type" "fpspc")
15168 (set_attr "mode" "DF")])
15170 (define_insn "*cossf2"
15171 [(set (match_operand:SF 0 "register_operand" "=f")
15172 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15173 "TARGET_USE_FANCY_MATH_387
15174 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15175 && flag_unsafe_math_optimizations"
15177 [(set_attr "type" "fpspc")
15178 (set_attr "mode" "SF")])
15180 (define_insn "*cosextendsfdf2"
15181 [(set (match_operand:DF 0 "register_operand" "=f")
15182 (unspec:DF [(float_extend:DF
15183 (match_operand:SF 1 "register_operand" "0"))]
15185 "TARGET_USE_FANCY_MATH_387
15186 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15187 && flag_unsafe_math_optimizations"
15189 [(set_attr "type" "fpspc")
15190 (set_attr "mode" "DF")])
15192 (define_insn "*cosxf2"
15193 [(set (match_operand:XF 0 "register_operand" "=f")
15194 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15195 "TARGET_USE_FANCY_MATH_387
15196 && flag_unsafe_math_optimizations"
15198 [(set_attr "type" "fpspc")
15199 (set_attr "mode" "XF")])
15201 ;; With sincos pattern defined, sin and cos builtin function will be
15202 ;; expanded to sincos pattern with one of its outputs left unused.
15203 ;; Cse pass will detected, if two sincos patterns can be combined,
15204 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15205 ;; depending on the unused output.
15207 (define_insn "sincosdf3"
15208 [(set (match_operand:DF 0 "register_operand" "=f")
15209 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15210 UNSPEC_SINCOS_COS))
15211 (set (match_operand:DF 1 "register_operand" "=u")
15212 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15213 "TARGET_USE_FANCY_MATH_387
15214 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15215 && flag_unsafe_math_optimizations"
15217 [(set_attr "type" "fpspc")
15218 (set_attr "mode" "DF")])
15221 [(set (match_operand:DF 0 "register_operand" "")
15222 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15223 UNSPEC_SINCOS_COS))
15224 (set (match_operand:DF 1 "register_operand" "")
15225 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15226 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15227 && !reload_completed && !reload_in_progress"
15228 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15232 [(set (match_operand:DF 0 "register_operand" "")
15233 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15234 UNSPEC_SINCOS_COS))
15235 (set (match_operand:DF 1 "register_operand" "")
15236 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15237 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15238 && !reload_completed && !reload_in_progress"
15239 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15242 (define_insn "sincossf3"
15243 [(set (match_operand:SF 0 "register_operand" "=f")
15244 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15245 UNSPEC_SINCOS_COS))
15246 (set (match_operand:SF 1 "register_operand" "=u")
15247 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15248 "TARGET_USE_FANCY_MATH_387
15249 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15250 && flag_unsafe_math_optimizations"
15252 [(set_attr "type" "fpspc")
15253 (set_attr "mode" "SF")])
15256 [(set (match_operand:SF 0 "register_operand" "")
15257 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15258 UNSPEC_SINCOS_COS))
15259 (set (match_operand:SF 1 "register_operand" "")
15260 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15261 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15262 && !reload_completed && !reload_in_progress"
15263 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15267 [(set (match_operand:SF 0 "register_operand" "")
15268 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15269 UNSPEC_SINCOS_COS))
15270 (set (match_operand:SF 1 "register_operand" "")
15271 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15272 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15273 && !reload_completed && !reload_in_progress"
15274 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15277 (define_insn "*sincosextendsfdf3"
15278 [(set (match_operand:DF 0 "register_operand" "=f")
15279 (unspec:DF [(float_extend:DF
15280 (match_operand:SF 2 "register_operand" "0"))]
15281 UNSPEC_SINCOS_COS))
15282 (set (match_operand:DF 1 "register_operand" "=u")
15283 (unspec:DF [(float_extend:DF
15284 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15285 "TARGET_USE_FANCY_MATH_387
15286 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15287 && flag_unsafe_math_optimizations"
15289 [(set_attr "type" "fpspc")
15290 (set_attr "mode" "DF")])
15293 [(set (match_operand:DF 0 "register_operand" "")
15294 (unspec:DF [(float_extend:DF
15295 (match_operand:SF 2 "register_operand" ""))]
15296 UNSPEC_SINCOS_COS))
15297 (set (match_operand:DF 1 "register_operand" "")
15298 (unspec:DF [(float_extend:DF
15299 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15300 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15301 && !reload_completed && !reload_in_progress"
15302 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15303 (match_dup 2))] UNSPEC_SIN))]
15307 [(set (match_operand:DF 0 "register_operand" "")
15308 (unspec:DF [(float_extend:DF
15309 (match_operand:SF 2 "register_operand" ""))]
15310 UNSPEC_SINCOS_COS))
15311 (set (match_operand:DF 1 "register_operand" "")
15312 (unspec:DF [(float_extend:DF
15313 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15314 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15315 && !reload_completed && !reload_in_progress"
15316 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15317 (match_dup 2))] UNSPEC_COS))]
15320 (define_insn "sincosxf3"
15321 [(set (match_operand:XF 0 "register_operand" "=f")
15322 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15323 UNSPEC_SINCOS_COS))
15324 (set (match_operand:XF 1 "register_operand" "=u")
15325 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15326 "TARGET_USE_FANCY_MATH_387
15327 && flag_unsafe_math_optimizations"
15329 [(set_attr "type" "fpspc")
15330 (set_attr "mode" "XF")])
15333 [(set (match_operand:XF 0 "register_operand" "")
15334 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15335 UNSPEC_SINCOS_COS))
15336 (set (match_operand:XF 1 "register_operand" "")
15337 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15338 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15339 && !reload_completed && !reload_in_progress"
15340 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15344 [(set (match_operand:XF 0 "register_operand" "")
15345 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15346 UNSPEC_SINCOS_COS))
15347 (set (match_operand:XF 1 "register_operand" "")
15348 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15349 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15350 && !reload_completed && !reload_in_progress"
15351 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15354 (define_insn "*tandf3_1"
15355 [(set (match_operand:DF 0 "register_operand" "=f")
15356 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15358 (set (match_operand:DF 1 "register_operand" "=u")
15359 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15360 "TARGET_USE_FANCY_MATH_387
15361 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15362 && flag_unsafe_math_optimizations"
15364 [(set_attr "type" "fpspc")
15365 (set_attr "mode" "DF")])
15367 ;; optimize sequence: fptan
15370 ;; into fptan insn.
15373 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15374 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15376 (set (match_operand:DF 1 "register_operand" "")
15377 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15379 (match_operand:DF 3 "immediate_operand" ""))]
15380 "standard_80387_constant_p (operands[3]) == 2"
15381 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15382 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15385 (define_expand "tandf2"
15386 [(parallel [(set (match_dup 2)
15387 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15389 (set (match_operand:DF 0 "register_operand" "")
15390 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15391 "TARGET_USE_FANCY_MATH_387
15392 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15393 && flag_unsafe_math_optimizations"
15395 operands[2] = gen_reg_rtx (DFmode);
15398 (define_insn "*tansf3_1"
15399 [(set (match_operand:SF 0 "register_operand" "=f")
15400 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15402 (set (match_operand:SF 1 "register_operand" "=u")
15403 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15404 "TARGET_USE_FANCY_MATH_387
15405 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15406 && flag_unsafe_math_optimizations"
15408 [(set_attr "type" "fpspc")
15409 (set_attr "mode" "SF")])
15411 ;; optimize sequence: fptan
15414 ;; into fptan insn.
15417 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15418 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15420 (set (match_operand:SF 1 "register_operand" "")
15421 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15423 (match_operand:SF 3 "immediate_operand" ""))]
15424 "standard_80387_constant_p (operands[3]) == 2"
15425 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15426 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15429 (define_expand "tansf2"
15430 [(parallel [(set (match_dup 2)
15431 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15433 (set (match_operand:SF 0 "register_operand" "")
15434 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15435 "TARGET_USE_FANCY_MATH_387
15436 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15437 && flag_unsafe_math_optimizations"
15439 operands[2] = gen_reg_rtx (SFmode);
15442 (define_insn "*tanxf3_1"
15443 [(set (match_operand:XF 0 "register_operand" "=f")
15444 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15446 (set (match_operand:XF 1 "register_operand" "=u")
15447 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15448 "TARGET_USE_FANCY_MATH_387
15449 && flag_unsafe_math_optimizations"
15451 [(set_attr "type" "fpspc")
15452 (set_attr "mode" "XF")])
15454 ;; optimize sequence: fptan
15457 ;; into fptan insn.
15460 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15461 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15463 (set (match_operand:XF 1 "register_operand" "")
15464 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15466 (match_operand:XF 3 "immediate_operand" ""))]
15467 "standard_80387_constant_p (operands[3]) == 2"
15468 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15469 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15472 (define_expand "tanxf2"
15473 [(parallel [(set (match_dup 2)
15474 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15476 (set (match_operand:XF 0 "register_operand" "")
15477 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15478 "TARGET_USE_FANCY_MATH_387
15479 && flag_unsafe_math_optimizations"
15481 operands[2] = gen_reg_rtx (XFmode);
15484 (define_insn "atan2df3_1"
15485 [(set (match_operand:DF 0 "register_operand" "=f")
15486 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15487 (match_operand:DF 1 "register_operand" "u")]
15489 (clobber (match_scratch:DF 3 "=1"))]
15490 "TARGET_USE_FANCY_MATH_387
15491 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15492 && flag_unsafe_math_optimizations"
15494 [(set_attr "type" "fpspc")
15495 (set_attr "mode" "DF")])
15497 (define_expand "atan2df3"
15498 [(use (match_operand:DF 0 "register_operand" ""))
15499 (use (match_operand:DF 2 "register_operand" ""))
15500 (use (match_operand:DF 1 "register_operand" ""))]
15501 "TARGET_USE_FANCY_MATH_387
15502 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15503 && flag_unsafe_math_optimizations"
15505 rtx copy = gen_reg_rtx (DFmode);
15506 emit_move_insn (copy, operands[1]);
15507 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15511 (define_expand "atandf2"
15512 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15513 (unspec:DF [(match_dup 2)
15514 (match_operand:DF 1 "register_operand" "")]
15516 (clobber (match_scratch:DF 3 ""))])]
15517 "TARGET_USE_FANCY_MATH_387
15518 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15519 && flag_unsafe_math_optimizations"
15521 operands[2] = gen_reg_rtx (DFmode);
15522 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15525 (define_insn "atan2sf3_1"
15526 [(set (match_operand:SF 0 "register_operand" "=f")
15527 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15528 (match_operand:SF 1 "register_operand" "u")]
15530 (clobber (match_scratch:SF 3 "=1"))]
15531 "TARGET_USE_FANCY_MATH_387
15532 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15533 && flag_unsafe_math_optimizations"
15535 [(set_attr "type" "fpspc")
15536 (set_attr "mode" "SF")])
15538 (define_expand "atan2sf3"
15539 [(use (match_operand:SF 0 "register_operand" ""))
15540 (use (match_operand:SF 2 "register_operand" ""))
15541 (use (match_operand:SF 1 "register_operand" ""))]
15542 "TARGET_USE_FANCY_MATH_387
15543 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15544 && flag_unsafe_math_optimizations"
15546 rtx copy = gen_reg_rtx (SFmode);
15547 emit_move_insn (copy, operands[1]);
15548 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15552 (define_expand "atansf2"
15553 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15554 (unspec:SF [(match_dup 2)
15555 (match_operand:SF 1 "register_operand" "")]
15557 (clobber (match_scratch:SF 3 ""))])]
15558 "TARGET_USE_FANCY_MATH_387
15559 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15560 && flag_unsafe_math_optimizations"
15562 operands[2] = gen_reg_rtx (SFmode);
15563 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15566 (define_insn "atan2xf3_1"
15567 [(set (match_operand:XF 0 "register_operand" "=f")
15568 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15569 (match_operand:XF 1 "register_operand" "u")]
15571 (clobber (match_scratch:XF 3 "=1"))]
15572 "TARGET_USE_FANCY_MATH_387
15573 && flag_unsafe_math_optimizations"
15575 [(set_attr "type" "fpspc")
15576 (set_attr "mode" "XF")])
15578 (define_expand "atan2xf3"
15579 [(use (match_operand:XF 0 "register_operand" ""))
15580 (use (match_operand:XF 2 "register_operand" ""))
15581 (use (match_operand:XF 1 "register_operand" ""))]
15582 "TARGET_USE_FANCY_MATH_387
15583 && flag_unsafe_math_optimizations"
15585 rtx copy = gen_reg_rtx (XFmode);
15586 emit_move_insn (copy, operands[1]);
15587 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15591 (define_expand "atanxf2"
15592 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15593 (unspec:XF [(match_dup 2)
15594 (match_operand:XF 1 "register_operand" "")]
15596 (clobber (match_scratch:XF 3 ""))])]
15597 "TARGET_USE_FANCY_MATH_387
15598 && flag_unsafe_math_optimizations"
15600 operands[2] = gen_reg_rtx (XFmode);
15601 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15604 (define_expand "asindf2"
15605 [(set (match_dup 2)
15606 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15607 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15608 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15609 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15610 (parallel [(set (match_dup 7)
15611 (unspec:XF [(match_dup 6) (match_dup 2)]
15613 (clobber (match_scratch:XF 8 ""))])
15614 (set (match_operand:DF 0 "register_operand" "")
15615 (float_truncate:DF (match_dup 7)))]
15616 "TARGET_USE_FANCY_MATH_387
15617 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15618 && flag_unsafe_math_optimizations"
15622 for (i=2; i<8; i++)
15623 operands[i] = gen_reg_rtx (XFmode);
15625 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15628 (define_expand "asinsf2"
15629 [(set (match_dup 2)
15630 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15631 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15632 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15633 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15634 (parallel [(set (match_dup 7)
15635 (unspec:XF [(match_dup 6) (match_dup 2)]
15637 (clobber (match_scratch:XF 8 ""))])
15638 (set (match_operand:SF 0 "register_operand" "")
15639 (float_truncate:SF (match_dup 7)))]
15640 "TARGET_USE_FANCY_MATH_387
15641 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15642 && flag_unsafe_math_optimizations"
15646 for (i=2; i<8; i++)
15647 operands[i] = gen_reg_rtx (XFmode);
15649 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15652 (define_expand "asinxf2"
15653 [(set (match_dup 2)
15654 (mult:XF (match_operand:XF 1 "register_operand" "")
15656 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15657 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15658 (parallel [(set (match_operand:XF 0 "register_operand" "")
15659 (unspec:XF [(match_dup 5) (match_dup 1)]
15661 (clobber (match_scratch:XF 6 ""))])]
15662 "TARGET_USE_FANCY_MATH_387
15663 && flag_unsafe_math_optimizations"
15667 for (i=2; i<6; i++)
15668 operands[i] = gen_reg_rtx (XFmode);
15670 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15673 (define_expand "acosdf2"
15674 [(set (match_dup 2)
15675 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15676 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15677 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15678 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15679 (parallel [(set (match_dup 7)
15680 (unspec:XF [(match_dup 2) (match_dup 6)]
15682 (clobber (match_scratch:XF 8 ""))])
15683 (set (match_operand:DF 0 "register_operand" "")
15684 (float_truncate:DF (match_dup 7)))]
15685 "TARGET_USE_FANCY_MATH_387
15686 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15687 && flag_unsafe_math_optimizations"
15691 for (i=2; i<8; i++)
15692 operands[i] = gen_reg_rtx (XFmode);
15694 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15697 (define_expand "acossf2"
15698 [(set (match_dup 2)
15699 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15700 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15701 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15702 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15703 (parallel [(set (match_dup 7)
15704 (unspec:XF [(match_dup 2) (match_dup 6)]
15706 (clobber (match_scratch:XF 8 ""))])
15707 (set (match_operand:SF 0 "register_operand" "")
15708 (float_truncate:SF (match_dup 7)))]
15709 "TARGET_USE_FANCY_MATH_387
15710 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15711 && flag_unsafe_math_optimizations"
15715 for (i=2; i<8; i++)
15716 operands[i] = gen_reg_rtx (XFmode);
15718 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15721 (define_expand "acosxf2"
15722 [(set (match_dup 2)
15723 (mult:XF (match_operand:XF 1 "register_operand" "")
15725 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15726 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15727 (parallel [(set (match_operand:XF 0 "register_operand" "")
15728 (unspec:XF [(match_dup 1) (match_dup 5)]
15730 (clobber (match_scratch:XF 6 ""))])]
15731 "TARGET_USE_FANCY_MATH_387
15732 && flag_unsafe_math_optimizations"
15736 for (i=2; i<6; i++)
15737 operands[i] = gen_reg_rtx (XFmode);
15739 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15742 (define_insn "fyl2x_xf3"
15743 [(set (match_operand:XF 0 "register_operand" "=f")
15744 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15745 (match_operand:XF 1 "register_operand" "u")]
15747 (clobber (match_scratch:XF 3 "=1"))]
15748 "TARGET_USE_FANCY_MATH_387
15749 && flag_unsafe_math_optimizations"
15751 [(set_attr "type" "fpspc")
15752 (set_attr "mode" "XF")])
15754 (define_expand "logsf2"
15755 [(set (match_dup 2)
15756 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15757 (parallel [(set (match_dup 4)
15758 (unspec:XF [(match_dup 2)
15759 (match_dup 3)] UNSPEC_FYL2X))
15760 (clobber (match_scratch:XF 5 ""))])
15761 (set (match_operand:SF 0 "register_operand" "")
15762 (float_truncate:SF (match_dup 4)))]
15763 "TARGET_USE_FANCY_MATH_387
15764 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15765 && flag_unsafe_math_optimizations"
15769 operands[2] = gen_reg_rtx (XFmode);
15770 operands[3] = gen_reg_rtx (XFmode);
15771 operands[4] = gen_reg_rtx (XFmode);
15773 temp = standard_80387_constant_rtx (4); /* fldln2 */
15774 emit_move_insn (operands[3], temp);
15777 (define_expand "logdf2"
15778 [(set (match_dup 2)
15779 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15780 (parallel [(set (match_dup 4)
15781 (unspec:XF [(match_dup 2)
15782 (match_dup 3)] UNSPEC_FYL2X))
15783 (clobber (match_scratch:XF 5 ""))])
15784 (set (match_operand:DF 0 "register_operand" "")
15785 (float_truncate:DF (match_dup 4)))]
15786 "TARGET_USE_FANCY_MATH_387
15787 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15788 && flag_unsafe_math_optimizations"
15792 operands[2] = gen_reg_rtx (XFmode);
15793 operands[3] = gen_reg_rtx (XFmode);
15794 operands[4] = gen_reg_rtx (XFmode);
15796 temp = standard_80387_constant_rtx (4); /* fldln2 */
15797 emit_move_insn (operands[3], temp);
15800 (define_expand "logxf2"
15801 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15802 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15803 (match_dup 2)] UNSPEC_FYL2X))
15804 (clobber (match_scratch:XF 3 ""))])]
15805 "TARGET_USE_FANCY_MATH_387
15806 && flag_unsafe_math_optimizations"
15810 operands[2] = gen_reg_rtx (XFmode);
15811 temp = standard_80387_constant_rtx (4); /* fldln2 */
15812 emit_move_insn (operands[2], temp);
15815 (define_expand "log10sf2"
15816 [(set (match_dup 2)
15817 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15818 (parallel [(set (match_dup 4)
15819 (unspec:XF [(match_dup 2)
15820 (match_dup 3)] UNSPEC_FYL2X))
15821 (clobber (match_scratch:XF 5 ""))])
15822 (set (match_operand:SF 0 "register_operand" "")
15823 (float_truncate:SF (match_dup 4)))]
15824 "TARGET_USE_FANCY_MATH_387
15825 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15826 && flag_unsafe_math_optimizations"
15830 operands[2] = gen_reg_rtx (XFmode);
15831 operands[3] = gen_reg_rtx (XFmode);
15832 operands[4] = gen_reg_rtx (XFmode);
15834 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15835 emit_move_insn (operands[3], temp);
15838 (define_expand "log10df2"
15839 [(set (match_dup 2)
15840 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15841 (parallel [(set (match_dup 4)
15842 (unspec:XF [(match_dup 2)
15843 (match_dup 3)] UNSPEC_FYL2X))
15844 (clobber (match_scratch:XF 5 ""))])
15845 (set (match_operand:DF 0 "register_operand" "")
15846 (float_truncate:DF (match_dup 4)))]
15847 "TARGET_USE_FANCY_MATH_387
15848 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15849 && flag_unsafe_math_optimizations"
15853 operands[2] = gen_reg_rtx (XFmode);
15854 operands[3] = gen_reg_rtx (XFmode);
15855 operands[4] = gen_reg_rtx (XFmode);
15857 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15858 emit_move_insn (operands[3], temp);
15861 (define_expand "log10xf2"
15862 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15863 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15864 (match_dup 2)] UNSPEC_FYL2X))
15865 (clobber (match_scratch:XF 3 ""))])]
15866 "TARGET_USE_FANCY_MATH_387
15867 && flag_unsafe_math_optimizations"
15871 operands[2] = gen_reg_rtx (XFmode);
15872 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15873 emit_move_insn (operands[2], temp);
15876 (define_expand "log2sf2"
15877 [(set (match_dup 2)
15878 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15879 (parallel [(set (match_dup 4)
15880 (unspec:XF [(match_dup 2)
15881 (match_dup 3)] UNSPEC_FYL2X))
15882 (clobber (match_scratch:XF 5 ""))])
15883 (set (match_operand:SF 0 "register_operand" "")
15884 (float_truncate:SF (match_dup 4)))]
15885 "TARGET_USE_FANCY_MATH_387
15886 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15887 && flag_unsafe_math_optimizations"
15889 operands[2] = gen_reg_rtx (XFmode);
15890 operands[3] = gen_reg_rtx (XFmode);
15891 operands[4] = gen_reg_rtx (XFmode);
15893 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15896 (define_expand "log2df2"
15897 [(set (match_dup 2)
15898 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15899 (parallel [(set (match_dup 4)
15900 (unspec:XF [(match_dup 2)
15901 (match_dup 3)] UNSPEC_FYL2X))
15902 (clobber (match_scratch:XF 5 ""))])
15903 (set (match_operand:DF 0 "register_operand" "")
15904 (float_truncate:DF (match_dup 4)))]
15905 "TARGET_USE_FANCY_MATH_387
15906 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15907 && flag_unsafe_math_optimizations"
15909 operands[2] = gen_reg_rtx (XFmode);
15910 operands[3] = gen_reg_rtx (XFmode);
15911 operands[4] = gen_reg_rtx (XFmode);
15913 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15916 (define_expand "log2xf2"
15917 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15918 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15919 (match_dup 2)] UNSPEC_FYL2X))
15920 (clobber (match_scratch:XF 3 ""))])]
15921 "TARGET_USE_FANCY_MATH_387
15922 && flag_unsafe_math_optimizations"
15924 operands[2] = gen_reg_rtx (XFmode);
15925 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15928 (define_insn "fyl2xp1_xf3"
15929 [(set (match_operand:XF 0 "register_operand" "=f")
15930 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15931 (match_operand:XF 1 "register_operand" "u")]
15933 (clobber (match_scratch:XF 3 "=1"))]
15934 "TARGET_USE_FANCY_MATH_387
15935 && flag_unsafe_math_optimizations"
15937 [(set_attr "type" "fpspc")
15938 (set_attr "mode" "XF")])
15940 (define_expand "log1psf2"
15941 [(use (match_operand:SF 0 "register_operand" ""))
15942 (use (match_operand:SF 1 "register_operand" ""))]
15943 "TARGET_USE_FANCY_MATH_387
15944 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15945 && flag_unsafe_math_optimizations"
15947 rtx op0 = gen_reg_rtx (XFmode);
15948 rtx op1 = gen_reg_rtx (XFmode);
15950 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15951 ix86_emit_i387_log1p (op0, op1);
15952 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15956 (define_expand "log1pdf2"
15957 [(use (match_operand:DF 0 "register_operand" ""))
15958 (use (match_operand:DF 1 "register_operand" ""))]
15959 "TARGET_USE_FANCY_MATH_387
15960 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15961 && flag_unsafe_math_optimizations"
15963 rtx op0 = gen_reg_rtx (XFmode);
15964 rtx op1 = gen_reg_rtx (XFmode);
15966 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15967 ix86_emit_i387_log1p (op0, op1);
15968 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15972 (define_expand "log1pxf2"
15973 [(use (match_operand:XF 0 "register_operand" ""))
15974 (use (match_operand:XF 1 "register_operand" ""))]
15975 "TARGET_USE_FANCY_MATH_387
15976 && flag_unsafe_math_optimizations"
15978 ix86_emit_i387_log1p (operands[0], operands[1]);
15982 (define_insn "*fxtractxf3"
15983 [(set (match_operand:XF 0 "register_operand" "=f")
15984 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15985 UNSPEC_XTRACT_FRACT))
15986 (set (match_operand:XF 1 "register_operand" "=u")
15987 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15988 "TARGET_USE_FANCY_MATH_387
15989 && flag_unsafe_math_optimizations"
15991 [(set_attr "type" "fpspc")
15992 (set_attr "mode" "XF")])
15994 (define_expand "logbsf2"
15995 [(set (match_dup 2)
15996 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15997 (parallel [(set (match_dup 3)
15998 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16000 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16001 (set (match_operand:SF 0 "register_operand" "")
16002 (float_truncate:SF (match_dup 4)))]
16003 "TARGET_USE_FANCY_MATH_387
16004 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16005 && flag_unsafe_math_optimizations"
16007 operands[2] = gen_reg_rtx (XFmode);
16008 operands[3] = gen_reg_rtx (XFmode);
16009 operands[4] = gen_reg_rtx (XFmode);
16012 (define_expand "logbdf2"
16013 [(set (match_dup 2)
16014 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16015 (parallel [(set (match_dup 3)
16016 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16018 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16019 (set (match_operand:DF 0 "register_operand" "")
16020 (float_truncate:DF (match_dup 4)))]
16021 "TARGET_USE_FANCY_MATH_387
16022 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16023 && flag_unsafe_math_optimizations"
16025 operands[2] = gen_reg_rtx (XFmode);
16026 operands[3] = gen_reg_rtx (XFmode);
16027 operands[4] = gen_reg_rtx (XFmode);
16030 (define_expand "logbxf2"
16031 [(parallel [(set (match_dup 2)
16032 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16033 UNSPEC_XTRACT_FRACT))
16034 (set (match_operand:XF 0 "register_operand" "")
16035 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16036 "TARGET_USE_FANCY_MATH_387
16037 && flag_unsafe_math_optimizations"
16039 operands[2] = gen_reg_rtx (XFmode);
16042 (define_expand "ilogbsi2"
16043 [(parallel [(set (match_dup 2)
16044 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16045 UNSPEC_XTRACT_FRACT))
16046 (set (match_operand:XF 3 "register_operand" "")
16047 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16048 (parallel [(set (match_operand:SI 0 "register_operand" "")
16049 (fix:SI (match_dup 3)))
16050 (clobber (reg:CC FLAGS_REG))])]
16051 "TARGET_USE_FANCY_MATH_387
16052 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16053 && flag_unsafe_math_optimizations"
16055 operands[2] = gen_reg_rtx (XFmode);
16056 operands[3] = gen_reg_rtx (XFmode);
16059 (define_insn "*f2xm1xf2"
16060 [(set (match_operand:XF 0 "register_operand" "=f")
16061 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16063 "TARGET_USE_FANCY_MATH_387
16064 && flag_unsafe_math_optimizations"
16066 [(set_attr "type" "fpspc")
16067 (set_attr "mode" "XF")])
16069 (define_insn "*fscalexf4"
16070 [(set (match_operand:XF 0 "register_operand" "=f")
16071 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16072 (match_operand:XF 3 "register_operand" "1")]
16073 UNSPEC_FSCALE_FRACT))
16074 (set (match_operand:XF 1 "register_operand" "=u")
16075 (unspec:XF [(match_dup 2) (match_dup 3)]
16076 UNSPEC_FSCALE_EXP))]
16077 "TARGET_USE_FANCY_MATH_387
16078 && flag_unsafe_math_optimizations"
16080 [(set_attr "type" "fpspc")
16081 (set_attr "mode" "XF")])
16083 (define_expand "expsf2"
16084 [(set (match_dup 2)
16085 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16086 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16087 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16088 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16089 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16090 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16091 (parallel [(set (match_dup 10)
16092 (unspec:XF [(match_dup 9) (match_dup 5)]
16093 UNSPEC_FSCALE_FRACT))
16094 (set (match_dup 11)
16095 (unspec:XF [(match_dup 9) (match_dup 5)]
16096 UNSPEC_FSCALE_EXP))])
16097 (set (match_operand:SF 0 "register_operand" "")
16098 (float_truncate:SF (match_dup 10)))]
16099 "TARGET_USE_FANCY_MATH_387
16100 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16101 && flag_unsafe_math_optimizations"
16106 for (i=2; i<12; i++)
16107 operands[i] = gen_reg_rtx (XFmode);
16108 temp = standard_80387_constant_rtx (5); /* fldl2e */
16109 emit_move_insn (operands[3], temp);
16110 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16113 (define_expand "expdf2"
16114 [(set (match_dup 2)
16115 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16116 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16117 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16118 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16119 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16120 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16121 (parallel [(set (match_dup 10)
16122 (unspec:XF [(match_dup 9) (match_dup 5)]
16123 UNSPEC_FSCALE_FRACT))
16124 (set (match_dup 11)
16125 (unspec:XF [(match_dup 9) (match_dup 5)]
16126 UNSPEC_FSCALE_EXP))])
16127 (set (match_operand:DF 0 "register_operand" "")
16128 (float_truncate:DF (match_dup 10)))]
16129 "TARGET_USE_FANCY_MATH_387
16130 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16131 && flag_unsafe_math_optimizations"
16136 for (i=2; i<12; i++)
16137 operands[i] = gen_reg_rtx (XFmode);
16138 temp = standard_80387_constant_rtx (5); /* fldl2e */
16139 emit_move_insn (operands[3], temp);
16140 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16143 (define_expand "expxf2"
16144 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16146 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16147 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16148 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16149 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16150 (parallel [(set (match_operand:XF 0 "register_operand" "")
16151 (unspec:XF [(match_dup 8) (match_dup 4)]
16152 UNSPEC_FSCALE_FRACT))
16154 (unspec:XF [(match_dup 8) (match_dup 4)]
16155 UNSPEC_FSCALE_EXP))])]
16156 "TARGET_USE_FANCY_MATH_387
16157 && flag_unsafe_math_optimizations"
16162 for (i=2; i<10; i++)
16163 operands[i] = gen_reg_rtx (XFmode);
16164 temp = standard_80387_constant_rtx (5); /* fldl2e */
16165 emit_move_insn (operands[2], temp);
16166 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16169 (define_expand "exp10sf2"
16170 [(set (match_dup 2)
16171 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16172 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16173 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16174 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16175 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16176 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16177 (parallel [(set (match_dup 10)
16178 (unspec:XF [(match_dup 9) (match_dup 5)]
16179 UNSPEC_FSCALE_FRACT))
16180 (set (match_dup 11)
16181 (unspec:XF [(match_dup 9) (match_dup 5)]
16182 UNSPEC_FSCALE_EXP))])
16183 (set (match_operand:SF 0 "register_operand" "")
16184 (float_truncate:SF (match_dup 10)))]
16185 "TARGET_USE_FANCY_MATH_387
16186 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16187 && flag_unsafe_math_optimizations"
16192 for (i=2; i<12; i++)
16193 operands[i] = gen_reg_rtx (XFmode);
16194 temp = standard_80387_constant_rtx (6); /* fldl2t */
16195 emit_move_insn (operands[3], temp);
16196 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16199 (define_expand "exp10df2"
16200 [(set (match_dup 2)
16201 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16202 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16203 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16204 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16205 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16206 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16207 (parallel [(set (match_dup 10)
16208 (unspec:XF [(match_dup 9) (match_dup 5)]
16209 UNSPEC_FSCALE_FRACT))
16210 (set (match_dup 11)
16211 (unspec:XF [(match_dup 9) (match_dup 5)]
16212 UNSPEC_FSCALE_EXP))])
16213 (set (match_operand:DF 0 "register_operand" "")
16214 (float_truncate:DF (match_dup 10)))]
16215 "TARGET_USE_FANCY_MATH_387
16216 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16217 && flag_unsafe_math_optimizations"
16222 for (i=2; i<12; i++)
16223 operands[i] = gen_reg_rtx (XFmode);
16224 temp = standard_80387_constant_rtx (6); /* fldl2t */
16225 emit_move_insn (operands[3], temp);
16226 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16229 (define_expand "exp10xf2"
16230 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16232 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16233 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16234 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16235 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16236 (parallel [(set (match_operand:XF 0 "register_operand" "")
16237 (unspec:XF [(match_dup 8) (match_dup 4)]
16238 UNSPEC_FSCALE_FRACT))
16240 (unspec:XF [(match_dup 8) (match_dup 4)]
16241 UNSPEC_FSCALE_EXP))])]
16242 "TARGET_USE_FANCY_MATH_387
16243 && flag_unsafe_math_optimizations"
16248 for (i=2; i<10; i++)
16249 operands[i] = gen_reg_rtx (XFmode);
16250 temp = standard_80387_constant_rtx (6); /* fldl2t */
16251 emit_move_insn (operands[2], temp);
16252 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16255 (define_expand "exp2sf2"
16256 [(set (match_dup 2)
16257 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16258 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16259 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16260 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16261 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16262 (parallel [(set (match_dup 8)
16263 (unspec:XF [(match_dup 7) (match_dup 3)]
16264 UNSPEC_FSCALE_FRACT))
16266 (unspec:XF [(match_dup 7) (match_dup 3)]
16267 UNSPEC_FSCALE_EXP))])
16268 (set (match_operand:SF 0 "register_operand" "")
16269 (float_truncate:SF (match_dup 8)))]
16270 "TARGET_USE_FANCY_MATH_387
16271 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16272 && flag_unsafe_math_optimizations"
16276 for (i=2; i<10; i++)
16277 operands[i] = gen_reg_rtx (XFmode);
16278 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16281 (define_expand "exp2df2"
16282 [(set (match_dup 2)
16283 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16284 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16285 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16286 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16287 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16288 (parallel [(set (match_dup 8)
16289 (unspec:XF [(match_dup 7) (match_dup 3)]
16290 UNSPEC_FSCALE_FRACT))
16292 (unspec:XF [(match_dup 7) (match_dup 3)]
16293 UNSPEC_FSCALE_EXP))])
16294 (set (match_operand:DF 0 "register_operand" "")
16295 (float_truncate:DF (match_dup 8)))]
16296 "TARGET_USE_FANCY_MATH_387
16297 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16298 && flag_unsafe_math_optimizations"
16302 for (i=2; i<10; i++)
16303 operands[i] = gen_reg_rtx (XFmode);
16304 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16307 (define_expand "exp2xf2"
16308 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16309 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16310 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16311 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16312 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16313 (parallel [(set (match_operand:XF 0 "register_operand" "")
16314 (unspec:XF [(match_dup 7) (match_dup 3)]
16315 UNSPEC_FSCALE_FRACT))
16317 (unspec:XF [(match_dup 7) (match_dup 3)]
16318 UNSPEC_FSCALE_EXP))])]
16319 "TARGET_USE_FANCY_MATH_387
16320 && flag_unsafe_math_optimizations"
16324 for (i=2; i<9; i++)
16325 operands[i] = gen_reg_rtx (XFmode);
16326 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16329 (define_expand "expm1df2"
16330 [(set (match_dup 2)
16331 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16332 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16333 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16334 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16335 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16336 (parallel [(set (match_dup 8)
16337 (unspec:XF [(match_dup 7) (match_dup 5)]
16338 UNSPEC_FSCALE_FRACT))
16340 (unspec:XF [(match_dup 7) (match_dup 5)]
16341 UNSPEC_FSCALE_EXP))])
16342 (parallel [(set (match_dup 11)
16343 (unspec:XF [(match_dup 10) (match_dup 9)]
16344 UNSPEC_FSCALE_FRACT))
16345 (set (match_dup 12)
16346 (unspec:XF [(match_dup 10) (match_dup 9)]
16347 UNSPEC_FSCALE_EXP))])
16348 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16349 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16350 (set (match_operand:DF 0 "register_operand" "")
16351 (float_truncate:DF (match_dup 14)))]
16352 "TARGET_USE_FANCY_MATH_387
16353 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16354 && flag_unsafe_math_optimizations"
16359 for (i=2; i<15; i++)
16360 operands[i] = gen_reg_rtx (XFmode);
16361 temp = standard_80387_constant_rtx (5); /* fldl2e */
16362 emit_move_insn (operands[3], temp);
16363 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16366 (define_expand "expm1sf2"
16367 [(set (match_dup 2)
16368 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16369 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16370 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16371 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16372 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16373 (parallel [(set (match_dup 8)
16374 (unspec:XF [(match_dup 7) (match_dup 5)]
16375 UNSPEC_FSCALE_FRACT))
16377 (unspec:XF [(match_dup 7) (match_dup 5)]
16378 UNSPEC_FSCALE_EXP))])
16379 (parallel [(set (match_dup 11)
16380 (unspec:XF [(match_dup 10) (match_dup 9)]
16381 UNSPEC_FSCALE_FRACT))
16382 (set (match_dup 12)
16383 (unspec:XF [(match_dup 10) (match_dup 9)]
16384 UNSPEC_FSCALE_EXP))])
16385 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16386 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16387 (set (match_operand:SF 0 "register_operand" "")
16388 (float_truncate:SF (match_dup 14)))]
16389 "TARGET_USE_FANCY_MATH_387
16390 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16391 && flag_unsafe_math_optimizations"
16396 for (i=2; i<15; i++)
16397 operands[i] = gen_reg_rtx (XFmode);
16398 temp = standard_80387_constant_rtx (5); /* fldl2e */
16399 emit_move_insn (operands[3], temp);
16400 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16403 (define_expand "expm1xf2"
16404 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16406 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16407 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16408 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16409 (parallel [(set (match_dup 7)
16410 (unspec:XF [(match_dup 6) (match_dup 4)]
16411 UNSPEC_FSCALE_FRACT))
16413 (unspec:XF [(match_dup 6) (match_dup 4)]
16414 UNSPEC_FSCALE_EXP))])
16415 (parallel [(set (match_dup 10)
16416 (unspec:XF [(match_dup 9) (match_dup 8)]
16417 UNSPEC_FSCALE_FRACT))
16418 (set (match_dup 11)
16419 (unspec:XF [(match_dup 9) (match_dup 8)]
16420 UNSPEC_FSCALE_EXP))])
16421 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16422 (set (match_operand:XF 0 "register_operand" "")
16423 (plus:XF (match_dup 12) (match_dup 7)))]
16424 "TARGET_USE_FANCY_MATH_387
16425 && flag_unsafe_math_optimizations"
16430 for (i=2; i<13; i++)
16431 operands[i] = gen_reg_rtx (XFmode);
16432 temp = standard_80387_constant_rtx (5); /* fldl2e */
16433 emit_move_insn (operands[2], temp);
16434 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16437 (define_expand "ldexpdf3"
16438 [(set (match_dup 3)
16439 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16441 (float:XF (match_operand:SI 2 "register_operand" "")))
16442 (parallel [(set (match_dup 5)
16443 (unspec:XF [(match_dup 3) (match_dup 4)]
16444 UNSPEC_FSCALE_FRACT))
16446 (unspec:XF [(match_dup 3) (match_dup 4)]
16447 UNSPEC_FSCALE_EXP))])
16448 (set (match_operand:DF 0 "register_operand" "")
16449 (float_truncate:DF (match_dup 5)))]
16450 "TARGET_USE_FANCY_MATH_387
16451 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16452 && flag_unsafe_math_optimizations"
16456 for (i=3; i<7; i++)
16457 operands[i] = gen_reg_rtx (XFmode);
16460 (define_expand "ldexpsf3"
16461 [(set (match_dup 3)
16462 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16464 (float:XF (match_operand:SI 2 "register_operand" "")))
16465 (parallel [(set (match_dup 5)
16466 (unspec:XF [(match_dup 3) (match_dup 4)]
16467 UNSPEC_FSCALE_FRACT))
16469 (unspec:XF [(match_dup 3) (match_dup 4)]
16470 UNSPEC_FSCALE_EXP))])
16471 (set (match_operand:SF 0 "register_operand" "")
16472 (float_truncate:SF (match_dup 5)))]
16473 "TARGET_USE_FANCY_MATH_387
16474 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16475 && flag_unsafe_math_optimizations"
16479 for (i=3; i<7; i++)
16480 operands[i] = gen_reg_rtx (XFmode);
16483 (define_expand "ldexpxf3"
16484 [(set (match_dup 3)
16485 (float:XF (match_operand:SI 2 "register_operand" "")))
16486 (parallel [(set (match_operand:XF 0 " register_operand" "")
16487 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16489 UNSPEC_FSCALE_FRACT))
16491 (unspec:XF [(match_dup 1) (match_dup 3)]
16492 UNSPEC_FSCALE_EXP))])]
16493 "TARGET_USE_FANCY_MATH_387
16494 && flag_unsafe_math_optimizations"
16498 for (i=3; i<5; i++)
16499 operands[i] = gen_reg_rtx (XFmode);
16503 (define_insn "frndintxf2"
16504 [(set (match_operand:XF 0 "register_operand" "=f")
16505 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16507 "TARGET_USE_FANCY_MATH_387
16508 && flag_unsafe_math_optimizations"
16510 [(set_attr "type" "fpspc")
16511 (set_attr "mode" "XF")])
16513 (define_expand "rintdf2"
16514 [(use (match_operand:DF 0 "register_operand" ""))
16515 (use (match_operand:DF 1 "register_operand" ""))]
16516 "TARGET_USE_FANCY_MATH_387
16517 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16518 && flag_unsafe_math_optimizations"
16520 rtx op0 = gen_reg_rtx (XFmode);
16521 rtx op1 = gen_reg_rtx (XFmode);
16523 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16524 emit_insn (gen_frndintxf2 (op0, op1));
16526 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16530 (define_expand "rintsf2"
16531 [(use (match_operand:SF 0 "register_operand" ""))
16532 (use (match_operand:SF 1 "register_operand" ""))]
16533 "TARGET_USE_FANCY_MATH_387
16534 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16535 && flag_unsafe_math_optimizations"
16537 rtx op0 = gen_reg_rtx (XFmode);
16538 rtx op1 = gen_reg_rtx (XFmode);
16540 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16541 emit_insn (gen_frndintxf2 (op0, op1));
16543 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16547 (define_expand "rintxf2"
16548 [(use (match_operand:XF 0 "register_operand" ""))
16549 (use (match_operand:XF 1 "register_operand" ""))]
16550 "TARGET_USE_FANCY_MATH_387
16551 && flag_unsafe_math_optimizations"
16553 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16557 (define_insn_and_split "*fistdi2_1"
16558 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16559 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16561 "TARGET_USE_FANCY_MATH_387
16562 && flag_unsafe_math_optimizations
16563 && !(reload_completed || reload_in_progress)"
16568 if (memory_operand (operands[0], VOIDmode))
16569 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16572 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16573 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16578 [(set_attr "type" "fpspc")
16579 (set_attr "mode" "DI")])
16581 (define_insn "fistdi2"
16582 [(set (match_operand:DI 0 "memory_operand" "=m")
16583 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16585 (clobber (match_scratch:XF 2 "=&1f"))]
16586 "TARGET_USE_FANCY_MATH_387
16587 && flag_unsafe_math_optimizations"
16588 "* return output_fix_trunc (insn, operands, 0);"
16589 [(set_attr "type" "fpspc")
16590 (set_attr "mode" "DI")])
16592 (define_insn "fistdi2_with_temp"
16593 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16594 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16596 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16597 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16598 "TARGET_USE_FANCY_MATH_387
16599 && flag_unsafe_math_optimizations"
16601 [(set_attr "type" "fpspc")
16602 (set_attr "mode" "DI")])
16605 [(set (match_operand:DI 0 "register_operand" "")
16606 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16608 (clobber (match_operand:DI 2 "memory_operand" ""))
16609 (clobber (match_scratch 3 ""))]
16611 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16612 (clobber (match_dup 3))])
16613 (set (match_dup 0) (match_dup 2))]
16617 [(set (match_operand:DI 0 "memory_operand" "")
16618 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16620 (clobber (match_operand:DI 2 "memory_operand" ""))
16621 (clobber (match_scratch 3 ""))]
16623 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16624 (clobber (match_dup 3))])]
16627 (define_insn_and_split "*fist<mode>2_1"
16628 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16629 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16631 "TARGET_USE_FANCY_MATH_387
16632 && flag_unsafe_math_optimizations
16633 && !(reload_completed || reload_in_progress)"
16638 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16639 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16643 [(set_attr "type" "fpspc")
16644 (set_attr "mode" "<MODE>")])
16646 (define_insn "fist<mode>2"
16647 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16648 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16650 "TARGET_USE_FANCY_MATH_387
16651 && flag_unsafe_math_optimizations"
16652 "* return output_fix_trunc (insn, operands, 0);"
16653 [(set_attr "type" "fpspc")
16654 (set_attr "mode" "<MODE>")])
16656 (define_insn "fist<mode>2_with_temp"
16657 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16658 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16660 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16661 "TARGET_USE_FANCY_MATH_387
16662 && flag_unsafe_math_optimizations"
16664 [(set_attr "type" "fpspc")
16665 (set_attr "mode" "<MODE>")])
16668 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16669 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16671 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16673 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16675 (set (match_dup 0) (match_dup 2))]
16679 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16680 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16682 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16684 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16688 (define_expand "lrint<mode>2"
16689 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16690 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16692 "TARGET_USE_FANCY_MATH_387
16693 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16694 && flag_unsafe_math_optimizations"
16697 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16698 (define_insn_and_split "frndintxf2_floor"
16699 [(set (match_operand:XF 0 "register_operand" "=f")
16700 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16701 UNSPEC_FRNDINT_FLOOR))
16702 (clobber (reg:CC FLAGS_REG))]
16703 "TARGET_USE_FANCY_MATH_387
16704 && flag_unsafe_math_optimizations
16705 && !(reload_completed || reload_in_progress)"
16710 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16712 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16713 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16715 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16716 operands[2], operands[3]));
16719 [(set_attr "type" "frndint")
16720 (set_attr "i387_cw" "floor")
16721 (set_attr "mode" "XF")])
16723 (define_insn "frndintxf2_floor_i387"
16724 [(set (match_operand:XF 0 "register_operand" "=f")
16725 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16726 UNSPEC_FRNDINT_FLOOR))
16727 (use (match_operand:HI 2 "memory_operand" "m"))
16728 (use (match_operand:HI 3 "memory_operand" "m"))]
16729 "TARGET_USE_FANCY_MATH_387
16730 && flag_unsafe_math_optimizations"
16731 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16732 [(set_attr "type" "frndint")
16733 (set_attr "i387_cw" "floor")
16734 (set_attr "mode" "XF")])
16736 (define_expand "floorxf2"
16737 [(use (match_operand:XF 0 "register_operand" ""))
16738 (use (match_operand:XF 1 "register_operand" ""))]
16739 "TARGET_USE_FANCY_MATH_387
16740 && flag_unsafe_math_optimizations"
16742 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16746 (define_expand "floordf2"
16747 [(use (match_operand:DF 0 "register_operand" ""))
16748 (use (match_operand:DF 1 "register_operand" ""))]
16749 "TARGET_USE_FANCY_MATH_387
16750 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16751 && flag_unsafe_math_optimizations"
16753 rtx op0 = gen_reg_rtx (XFmode);
16754 rtx op1 = gen_reg_rtx (XFmode);
16756 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16757 emit_insn (gen_frndintxf2_floor (op0, op1));
16759 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16763 (define_expand "floorsf2"
16764 [(use (match_operand:SF 0 "register_operand" ""))
16765 (use (match_operand:SF 1 "register_operand" ""))]
16766 "TARGET_USE_FANCY_MATH_387
16767 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16768 && flag_unsafe_math_optimizations"
16770 rtx op0 = gen_reg_rtx (XFmode);
16771 rtx op1 = gen_reg_rtx (XFmode);
16773 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16774 emit_insn (gen_frndintxf2_floor (op0, op1));
16776 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16780 (define_insn_and_split "*fist<mode>2_floor_1"
16781 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16782 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16783 UNSPEC_FIST_FLOOR))
16784 (clobber (reg:CC FLAGS_REG))]
16785 "TARGET_USE_FANCY_MATH_387
16786 && flag_unsafe_math_optimizations
16787 && !(reload_completed || reload_in_progress)"
16792 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16794 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16795 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16796 if (memory_operand (operands[0], VOIDmode))
16797 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16798 operands[2], operands[3]));
16801 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16802 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16803 operands[2], operands[3],
16808 [(set_attr "type" "fistp")
16809 (set_attr "i387_cw" "floor")
16810 (set_attr "mode" "<MODE>")])
16812 (define_insn "fistdi2_floor"
16813 [(set (match_operand:DI 0 "memory_operand" "=m")
16814 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16815 UNSPEC_FIST_FLOOR))
16816 (use (match_operand:HI 2 "memory_operand" "m"))
16817 (use (match_operand:HI 3 "memory_operand" "m"))
16818 (clobber (match_scratch:XF 4 "=&1f"))]
16819 "TARGET_USE_FANCY_MATH_387
16820 && flag_unsafe_math_optimizations"
16821 "* return output_fix_trunc (insn, operands, 0);"
16822 [(set_attr "type" "fistp")
16823 (set_attr "i387_cw" "floor")
16824 (set_attr "mode" "DI")])
16826 (define_insn "fistdi2_floor_with_temp"
16827 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16828 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16829 UNSPEC_FIST_FLOOR))
16830 (use (match_operand:HI 2 "memory_operand" "m,m"))
16831 (use (match_operand:HI 3 "memory_operand" "m,m"))
16832 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16833 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16834 "TARGET_USE_FANCY_MATH_387
16835 && flag_unsafe_math_optimizations"
16837 [(set_attr "type" "fistp")
16838 (set_attr "i387_cw" "floor")
16839 (set_attr "mode" "DI")])
16842 [(set (match_operand:DI 0 "register_operand" "")
16843 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16844 UNSPEC_FIST_FLOOR))
16845 (use (match_operand:HI 2 "memory_operand" ""))
16846 (use (match_operand:HI 3 "memory_operand" ""))
16847 (clobber (match_operand:DI 4 "memory_operand" ""))
16848 (clobber (match_scratch 5 ""))]
16850 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16851 (use (match_dup 2))
16852 (use (match_dup 3))
16853 (clobber (match_dup 5))])
16854 (set (match_dup 0) (match_dup 4))]
16858 [(set (match_operand:DI 0 "memory_operand" "")
16859 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16860 UNSPEC_FIST_FLOOR))
16861 (use (match_operand:HI 2 "memory_operand" ""))
16862 (use (match_operand:HI 3 "memory_operand" ""))
16863 (clobber (match_operand:DI 4 "memory_operand" ""))
16864 (clobber (match_scratch 5 ""))]
16866 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16867 (use (match_dup 2))
16868 (use (match_dup 3))
16869 (clobber (match_dup 5))])]
16872 (define_insn "fist<mode>2_floor"
16873 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16874 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16875 UNSPEC_FIST_FLOOR))
16876 (use (match_operand:HI 2 "memory_operand" "m"))
16877 (use (match_operand:HI 3 "memory_operand" "m"))]
16878 "TARGET_USE_FANCY_MATH_387
16879 && flag_unsafe_math_optimizations"
16880 "* return output_fix_trunc (insn, operands, 0);"
16881 [(set_attr "type" "fistp")
16882 (set_attr "i387_cw" "floor")
16883 (set_attr "mode" "<MODE>")])
16885 (define_insn "fist<mode>2_floor_with_temp"
16886 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16887 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16888 UNSPEC_FIST_FLOOR))
16889 (use (match_operand:HI 2 "memory_operand" "m,m"))
16890 (use (match_operand:HI 3 "memory_operand" "m,m"))
16891 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16892 "TARGET_USE_FANCY_MATH_387
16893 && flag_unsafe_math_optimizations"
16895 [(set_attr "type" "fistp")
16896 (set_attr "i387_cw" "floor")
16897 (set_attr "mode" "<MODE>")])
16900 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16901 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16902 UNSPEC_FIST_FLOOR))
16903 (use (match_operand:HI 2 "memory_operand" ""))
16904 (use (match_operand:HI 3 "memory_operand" ""))
16905 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16907 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16908 UNSPEC_FIST_FLOOR))
16909 (use (match_dup 2))
16910 (use (match_dup 3))])
16911 (set (match_dup 0) (match_dup 4))]
16915 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16916 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16917 UNSPEC_FIST_FLOOR))
16918 (use (match_operand:HI 2 "memory_operand" ""))
16919 (use (match_operand:HI 3 "memory_operand" ""))
16920 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16922 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16923 UNSPEC_FIST_FLOOR))
16924 (use (match_dup 2))
16925 (use (match_dup 3))])]
16928 (define_expand "lfloor<mode>2"
16929 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16930 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16931 UNSPEC_FIST_FLOOR))
16932 (clobber (reg:CC FLAGS_REG))])]
16933 "TARGET_USE_FANCY_MATH_387
16934 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16935 && flag_unsafe_math_optimizations"
16938 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16939 (define_insn_and_split "frndintxf2_ceil"
16940 [(set (match_operand:XF 0 "register_operand" "=f")
16941 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16942 UNSPEC_FRNDINT_CEIL))
16943 (clobber (reg:CC FLAGS_REG))]
16944 "TARGET_USE_FANCY_MATH_387
16945 && flag_unsafe_math_optimizations
16946 && !(reload_completed || reload_in_progress)"
16951 ix86_optimize_mode_switching[I387_CEIL] = 1;
16953 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16954 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16956 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16957 operands[2], operands[3]));
16960 [(set_attr "type" "frndint")
16961 (set_attr "i387_cw" "ceil")
16962 (set_attr "mode" "XF")])
16964 (define_insn "frndintxf2_ceil_i387"
16965 [(set (match_operand:XF 0 "register_operand" "=f")
16966 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16967 UNSPEC_FRNDINT_CEIL))
16968 (use (match_operand:HI 2 "memory_operand" "m"))
16969 (use (match_operand:HI 3 "memory_operand" "m"))]
16970 "TARGET_USE_FANCY_MATH_387
16971 && flag_unsafe_math_optimizations"
16972 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16973 [(set_attr "type" "frndint")
16974 (set_attr "i387_cw" "ceil")
16975 (set_attr "mode" "XF")])
16977 (define_expand "ceilxf2"
16978 [(use (match_operand:XF 0 "register_operand" ""))
16979 (use (match_operand:XF 1 "register_operand" ""))]
16980 "TARGET_USE_FANCY_MATH_387
16981 && flag_unsafe_math_optimizations"
16983 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16987 (define_expand "ceildf2"
16988 [(use (match_operand:DF 0 "register_operand" ""))
16989 (use (match_operand:DF 1 "register_operand" ""))]
16990 "TARGET_USE_FANCY_MATH_387
16991 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16992 && flag_unsafe_math_optimizations"
16994 rtx op0 = gen_reg_rtx (XFmode);
16995 rtx op1 = gen_reg_rtx (XFmode);
16997 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16998 emit_insn (gen_frndintxf2_ceil (op0, op1));
17000 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17004 (define_expand "ceilsf2"
17005 [(use (match_operand:SF 0 "register_operand" ""))
17006 (use (match_operand:SF 1 "register_operand" ""))]
17007 "TARGET_USE_FANCY_MATH_387
17008 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17009 && flag_unsafe_math_optimizations"
17011 rtx op0 = gen_reg_rtx (XFmode);
17012 rtx op1 = gen_reg_rtx (XFmode);
17014 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17015 emit_insn (gen_frndintxf2_ceil (op0, op1));
17017 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17021 (define_insn_and_split "*fist<mode>2_ceil_1"
17022 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17023 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17025 (clobber (reg:CC FLAGS_REG))]
17026 "TARGET_USE_FANCY_MATH_387
17027 && flag_unsafe_math_optimizations
17028 && !(reload_completed || reload_in_progress)"
17033 ix86_optimize_mode_switching[I387_CEIL] = 1;
17035 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17036 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17037 if (memory_operand (operands[0], VOIDmode))
17038 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17039 operands[2], operands[3]));
17042 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17043 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17044 operands[2], operands[3],
17049 [(set_attr "type" "fistp")
17050 (set_attr "i387_cw" "ceil")
17051 (set_attr "mode" "<MODE>")])
17053 (define_insn "fistdi2_ceil"
17054 [(set (match_operand:DI 0 "memory_operand" "=m")
17055 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17057 (use (match_operand:HI 2 "memory_operand" "m"))
17058 (use (match_operand:HI 3 "memory_operand" "m"))
17059 (clobber (match_scratch:XF 4 "=&1f"))]
17060 "TARGET_USE_FANCY_MATH_387
17061 && flag_unsafe_math_optimizations"
17062 "* return output_fix_trunc (insn, operands, 0);"
17063 [(set_attr "type" "fistp")
17064 (set_attr "i387_cw" "ceil")
17065 (set_attr "mode" "DI")])
17067 (define_insn "fistdi2_ceil_with_temp"
17068 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17069 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17071 (use (match_operand:HI 2 "memory_operand" "m,m"))
17072 (use (match_operand:HI 3 "memory_operand" "m,m"))
17073 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17074 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17075 "TARGET_USE_FANCY_MATH_387
17076 && flag_unsafe_math_optimizations"
17078 [(set_attr "type" "fistp")
17079 (set_attr "i387_cw" "ceil")
17080 (set_attr "mode" "DI")])
17083 [(set (match_operand:DI 0 "register_operand" "")
17084 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17086 (use (match_operand:HI 2 "memory_operand" ""))
17087 (use (match_operand:HI 3 "memory_operand" ""))
17088 (clobber (match_operand:DI 4 "memory_operand" ""))
17089 (clobber (match_scratch 5 ""))]
17091 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17092 (use (match_dup 2))
17093 (use (match_dup 3))
17094 (clobber (match_dup 5))])
17095 (set (match_dup 0) (match_dup 4))]
17099 [(set (match_operand:DI 0 "memory_operand" "")
17100 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17102 (use (match_operand:HI 2 "memory_operand" ""))
17103 (use (match_operand:HI 3 "memory_operand" ""))
17104 (clobber (match_operand:DI 4 "memory_operand" ""))
17105 (clobber (match_scratch 5 ""))]
17107 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17108 (use (match_dup 2))
17109 (use (match_dup 3))
17110 (clobber (match_dup 5))])]
17113 (define_insn "fist<mode>2_ceil"
17114 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17115 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17117 (use (match_operand:HI 2 "memory_operand" "m"))
17118 (use (match_operand:HI 3 "memory_operand" "m"))]
17119 "TARGET_USE_FANCY_MATH_387
17120 && flag_unsafe_math_optimizations"
17121 "* return output_fix_trunc (insn, operands, 0);"
17122 [(set_attr "type" "fistp")
17123 (set_attr "i387_cw" "ceil")
17124 (set_attr "mode" "<MODE>")])
17126 (define_insn "fist<mode>2_ceil_with_temp"
17127 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17128 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17130 (use (match_operand:HI 2 "memory_operand" "m,m"))
17131 (use (match_operand:HI 3 "memory_operand" "m,m"))
17132 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17133 "TARGET_USE_FANCY_MATH_387
17134 && flag_unsafe_math_optimizations"
17136 [(set_attr "type" "fistp")
17137 (set_attr "i387_cw" "ceil")
17138 (set_attr "mode" "<MODE>")])
17141 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17142 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17144 (use (match_operand:HI 2 "memory_operand" ""))
17145 (use (match_operand:HI 3 "memory_operand" ""))
17146 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17148 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17150 (use (match_dup 2))
17151 (use (match_dup 3))])
17152 (set (match_dup 0) (match_dup 4))]
17156 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17157 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17159 (use (match_operand:HI 2 "memory_operand" ""))
17160 (use (match_operand:HI 3 "memory_operand" ""))
17161 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17163 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17165 (use (match_dup 2))
17166 (use (match_dup 3))])]
17169 (define_expand "lceil<mode>2"
17170 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17171 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17173 (clobber (reg:CC FLAGS_REG))])]
17174 "TARGET_USE_FANCY_MATH_387
17175 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17176 && flag_unsafe_math_optimizations"
17179 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17180 (define_insn_and_split "frndintxf2_trunc"
17181 [(set (match_operand:XF 0 "register_operand" "=f")
17182 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17183 UNSPEC_FRNDINT_TRUNC))
17184 (clobber (reg:CC FLAGS_REG))]
17185 "TARGET_USE_FANCY_MATH_387
17186 && flag_unsafe_math_optimizations
17187 && !(reload_completed || reload_in_progress)"
17192 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17194 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17195 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17197 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17198 operands[2], operands[3]));
17201 [(set_attr "type" "frndint")
17202 (set_attr "i387_cw" "trunc")
17203 (set_attr "mode" "XF")])
17205 (define_insn "frndintxf2_trunc_i387"
17206 [(set (match_operand:XF 0 "register_operand" "=f")
17207 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17208 UNSPEC_FRNDINT_TRUNC))
17209 (use (match_operand:HI 2 "memory_operand" "m"))
17210 (use (match_operand:HI 3 "memory_operand" "m"))]
17211 "TARGET_USE_FANCY_MATH_387
17212 && flag_unsafe_math_optimizations"
17213 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17214 [(set_attr "type" "frndint")
17215 (set_attr "i387_cw" "trunc")
17216 (set_attr "mode" "XF")])
17218 (define_expand "btruncxf2"
17219 [(use (match_operand:XF 0 "register_operand" ""))
17220 (use (match_operand:XF 1 "register_operand" ""))]
17221 "TARGET_USE_FANCY_MATH_387
17222 && flag_unsafe_math_optimizations"
17224 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17228 (define_expand "btruncdf2"
17229 [(use (match_operand:DF 0 "register_operand" ""))
17230 (use (match_operand:DF 1 "register_operand" ""))]
17231 "TARGET_USE_FANCY_MATH_387
17232 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17233 && flag_unsafe_math_optimizations"
17235 rtx op0 = gen_reg_rtx (XFmode);
17236 rtx op1 = gen_reg_rtx (XFmode);
17238 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17239 emit_insn (gen_frndintxf2_trunc (op0, op1));
17241 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17245 (define_expand "btruncsf2"
17246 [(use (match_operand:SF 0 "register_operand" ""))
17247 (use (match_operand:SF 1 "register_operand" ""))]
17248 "TARGET_USE_FANCY_MATH_387
17249 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17250 && flag_unsafe_math_optimizations"
17252 rtx op0 = gen_reg_rtx (XFmode);
17253 rtx op1 = gen_reg_rtx (XFmode);
17255 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17256 emit_insn (gen_frndintxf2_trunc (op0, op1));
17258 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17262 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17263 (define_insn_and_split "frndintxf2_mask_pm"
17264 [(set (match_operand:XF 0 "register_operand" "=f")
17265 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17266 UNSPEC_FRNDINT_MASK_PM))
17267 (clobber (reg:CC FLAGS_REG))]
17268 "TARGET_USE_FANCY_MATH_387
17269 && flag_unsafe_math_optimizations
17270 && !(reload_completed || reload_in_progress)"
17275 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17277 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17278 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17280 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17281 operands[2], operands[3]));
17284 [(set_attr "type" "frndint")
17285 (set_attr "i387_cw" "mask_pm")
17286 (set_attr "mode" "XF")])
17288 (define_insn "frndintxf2_mask_pm_i387"
17289 [(set (match_operand:XF 0 "register_operand" "=f")
17290 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17291 UNSPEC_FRNDINT_MASK_PM))
17292 (use (match_operand:HI 2 "memory_operand" "m"))
17293 (use (match_operand:HI 3 "memory_operand" "m"))]
17294 "TARGET_USE_FANCY_MATH_387
17295 && flag_unsafe_math_optimizations"
17296 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17297 [(set_attr "type" "frndint")
17298 (set_attr "i387_cw" "mask_pm")
17299 (set_attr "mode" "XF")])
17301 (define_expand "nearbyintxf2"
17302 [(use (match_operand:XF 0 "register_operand" ""))
17303 (use (match_operand:XF 1 "register_operand" ""))]
17304 "TARGET_USE_FANCY_MATH_387
17305 && flag_unsafe_math_optimizations"
17307 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17312 (define_expand "nearbyintdf2"
17313 [(use (match_operand:DF 0 "register_operand" ""))
17314 (use (match_operand:DF 1 "register_operand" ""))]
17315 "TARGET_USE_FANCY_MATH_387
17316 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17317 && flag_unsafe_math_optimizations"
17319 rtx op0 = gen_reg_rtx (XFmode);
17320 rtx op1 = gen_reg_rtx (XFmode);
17322 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17323 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17325 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17329 (define_expand "nearbyintsf2"
17330 [(use (match_operand:SF 0 "register_operand" ""))
17331 (use (match_operand:SF 1 "register_operand" ""))]
17332 "TARGET_USE_FANCY_MATH_387
17333 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17334 && flag_unsafe_math_optimizations"
17336 rtx op0 = gen_reg_rtx (XFmode);
17337 rtx op1 = gen_reg_rtx (XFmode);
17339 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17340 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17342 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17347 ;; Block operation instructions
17350 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17353 [(set_attr "type" "cld")])
17355 (define_expand "movmemsi"
17356 [(use (match_operand:BLK 0 "memory_operand" ""))
17357 (use (match_operand:BLK 1 "memory_operand" ""))
17358 (use (match_operand:SI 2 "nonmemory_operand" ""))
17359 (use (match_operand:SI 3 "const_int_operand" ""))]
17360 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17362 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17368 (define_expand "movmemdi"
17369 [(use (match_operand:BLK 0 "memory_operand" ""))
17370 (use (match_operand:BLK 1 "memory_operand" ""))
17371 (use (match_operand:DI 2 "nonmemory_operand" ""))
17372 (use (match_operand:DI 3 "const_int_operand" ""))]
17375 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17381 ;; Most CPUs don't like single string operations
17382 ;; Handle this case here to simplify previous expander.
17384 (define_expand "strmov"
17385 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17386 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17387 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17388 (clobber (reg:CC FLAGS_REG))])
17389 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17390 (clobber (reg:CC FLAGS_REG))])]
17393 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17395 /* If .md ever supports :P for Pmode, these can be directly
17396 in the pattern above. */
17397 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17398 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17400 if (TARGET_SINGLE_STRINGOP || optimize_size)
17402 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17403 operands[2], operands[3],
17404 operands[5], operands[6]));
17408 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17411 (define_expand "strmov_singleop"
17412 [(parallel [(set (match_operand 1 "memory_operand" "")
17413 (match_operand 3 "memory_operand" ""))
17414 (set (match_operand 0 "register_operand" "")
17415 (match_operand 4 "" ""))
17416 (set (match_operand 2 "register_operand" "")
17417 (match_operand 5 "" ""))
17418 (use (reg:SI DIRFLAG_REG))])]
17419 "TARGET_SINGLE_STRINGOP || optimize_size"
17422 (define_insn "*strmovdi_rex_1"
17423 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17424 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17425 (set (match_operand:DI 0 "register_operand" "=D")
17426 (plus:DI (match_dup 2)
17428 (set (match_operand:DI 1 "register_operand" "=S")
17429 (plus:DI (match_dup 3)
17431 (use (reg:SI DIRFLAG_REG))]
17432 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17434 [(set_attr "type" "str")
17435 (set_attr "mode" "DI")
17436 (set_attr "memory" "both")])
17438 (define_insn "*strmovsi_1"
17439 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17440 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17441 (set (match_operand:SI 0 "register_operand" "=D")
17442 (plus:SI (match_dup 2)
17444 (set (match_operand:SI 1 "register_operand" "=S")
17445 (plus:SI (match_dup 3)
17447 (use (reg:SI DIRFLAG_REG))]
17448 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17450 [(set_attr "type" "str")
17451 (set_attr "mode" "SI")
17452 (set_attr "memory" "both")])
17454 (define_insn "*strmovsi_rex_1"
17455 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17456 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17457 (set (match_operand:DI 0 "register_operand" "=D")
17458 (plus:DI (match_dup 2)
17460 (set (match_operand:DI 1 "register_operand" "=S")
17461 (plus:DI (match_dup 3)
17463 (use (reg:SI DIRFLAG_REG))]
17464 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17466 [(set_attr "type" "str")
17467 (set_attr "mode" "SI")
17468 (set_attr "memory" "both")])
17470 (define_insn "*strmovhi_1"
17471 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17472 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17473 (set (match_operand:SI 0 "register_operand" "=D")
17474 (plus:SI (match_dup 2)
17476 (set (match_operand:SI 1 "register_operand" "=S")
17477 (plus:SI (match_dup 3)
17479 (use (reg:SI DIRFLAG_REG))]
17480 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17482 [(set_attr "type" "str")
17483 (set_attr "memory" "both")
17484 (set_attr "mode" "HI")])
17486 (define_insn "*strmovhi_rex_1"
17487 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17488 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17489 (set (match_operand:DI 0 "register_operand" "=D")
17490 (plus:DI (match_dup 2)
17492 (set (match_operand:DI 1 "register_operand" "=S")
17493 (plus:DI (match_dup 3)
17495 (use (reg:SI DIRFLAG_REG))]
17496 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17498 [(set_attr "type" "str")
17499 (set_attr "memory" "both")
17500 (set_attr "mode" "HI")])
17502 (define_insn "*strmovqi_1"
17503 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17504 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17505 (set (match_operand:SI 0 "register_operand" "=D")
17506 (plus:SI (match_dup 2)
17508 (set (match_operand:SI 1 "register_operand" "=S")
17509 (plus:SI (match_dup 3)
17511 (use (reg:SI DIRFLAG_REG))]
17512 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17514 [(set_attr "type" "str")
17515 (set_attr "memory" "both")
17516 (set_attr "mode" "QI")])
17518 (define_insn "*strmovqi_rex_1"
17519 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17520 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17521 (set (match_operand:DI 0 "register_operand" "=D")
17522 (plus:DI (match_dup 2)
17524 (set (match_operand:DI 1 "register_operand" "=S")
17525 (plus:DI (match_dup 3)
17527 (use (reg:SI DIRFLAG_REG))]
17528 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17530 [(set_attr "type" "str")
17531 (set_attr "memory" "both")
17532 (set_attr "mode" "QI")])
17534 (define_expand "rep_mov"
17535 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17536 (set (match_operand 0 "register_operand" "")
17537 (match_operand 5 "" ""))
17538 (set (match_operand 2 "register_operand" "")
17539 (match_operand 6 "" ""))
17540 (set (match_operand 1 "memory_operand" "")
17541 (match_operand 3 "memory_operand" ""))
17542 (use (match_dup 4))
17543 (use (reg:SI DIRFLAG_REG))])]
17547 (define_insn "*rep_movdi_rex64"
17548 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17549 (set (match_operand:DI 0 "register_operand" "=D")
17550 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17552 (match_operand:DI 3 "register_operand" "0")))
17553 (set (match_operand:DI 1 "register_operand" "=S")
17554 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17555 (match_operand:DI 4 "register_operand" "1")))
17556 (set (mem:BLK (match_dup 3))
17557 (mem:BLK (match_dup 4)))
17558 (use (match_dup 5))
17559 (use (reg:SI DIRFLAG_REG))]
17561 "{rep\;movsq|rep movsq}"
17562 [(set_attr "type" "str")
17563 (set_attr "prefix_rep" "1")
17564 (set_attr "memory" "both")
17565 (set_attr "mode" "DI")])
17567 (define_insn "*rep_movsi"
17568 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17569 (set (match_operand:SI 0 "register_operand" "=D")
17570 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17572 (match_operand:SI 3 "register_operand" "0")))
17573 (set (match_operand:SI 1 "register_operand" "=S")
17574 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17575 (match_operand:SI 4 "register_operand" "1")))
17576 (set (mem:BLK (match_dup 3))
17577 (mem:BLK (match_dup 4)))
17578 (use (match_dup 5))
17579 (use (reg:SI DIRFLAG_REG))]
17581 "{rep\;movsl|rep movsd}"
17582 [(set_attr "type" "str")
17583 (set_attr "prefix_rep" "1")
17584 (set_attr "memory" "both")
17585 (set_attr "mode" "SI")])
17587 (define_insn "*rep_movsi_rex64"
17588 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17589 (set (match_operand:DI 0 "register_operand" "=D")
17590 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17592 (match_operand:DI 3 "register_operand" "0")))
17593 (set (match_operand:DI 1 "register_operand" "=S")
17594 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17595 (match_operand:DI 4 "register_operand" "1")))
17596 (set (mem:BLK (match_dup 3))
17597 (mem:BLK (match_dup 4)))
17598 (use (match_dup 5))
17599 (use (reg:SI DIRFLAG_REG))]
17601 "{rep\;movsl|rep movsd}"
17602 [(set_attr "type" "str")
17603 (set_attr "prefix_rep" "1")
17604 (set_attr "memory" "both")
17605 (set_attr "mode" "SI")])
17607 (define_insn "*rep_movqi"
17608 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17609 (set (match_operand:SI 0 "register_operand" "=D")
17610 (plus:SI (match_operand:SI 3 "register_operand" "0")
17611 (match_operand:SI 5 "register_operand" "2")))
17612 (set (match_operand:SI 1 "register_operand" "=S")
17613 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17614 (set (mem:BLK (match_dup 3))
17615 (mem:BLK (match_dup 4)))
17616 (use (match_dup 5))
17617 (use (reg:SI DIRFLAG_REG))]
17619 "{rep\;movsb|rep movsb}"
17620 [(set_attr "type" "str")
17621 (set_attr "prefix_rep" "1")
17622 (set_attr "memory" "both")
17623 (set_attr "mode" "SI")])
17625 (define_insn "*rep_movqi_rex64"
17626 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17627 (set (match_operand:DI 0 "register_operand" "=D")
17628 (plus:DI (match_operand:DI 3 "register_operand" "0")
17629 (match_operand:DI 5 "register_operand" "2")))
17630 (set (match_operand:DI 1 "register_operand" "=S")
17631 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17632 (set (mem:BLK (match_dup 3))
17633 (mem:BLK (match_dup 4)))
17634 (use (match_dup 5))
17635 (use (reg:SI DIRFLAG_REG))]
17637 "{rep\;movsb|rep movsb}"
17638 [(set_attr "type" "str")
17639 (set_attr "prefix_rep" "1")
17640 (set_attr "memory" "both")
17641 (set_attr "mode" "SI")])
17643 (define_expand "setmemsi"
17644 [(use (match_operand:BLK 0 "memory_operand" ""))
17645 (use (match_operand:SI 1 "nonmemory_operand" ""))
17646 (use (match_operand 2 "const_int_operand" ""))
17647 (use (match_operand 3 "const_int_operand" ""))]
17650 /* If value to set is not zero, use the library routine. */
17651 if (operands[2] != const0_rtx)
17654 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17660 (define_expand "setmemdi"
17661 [(use (match_operand:BLK 0 "memory_operand" ""))
17662 (use (match_operand:DI 1 "nonmemory_operand" ""))
17663 (use (match_operand 2 "const_int_operand" ""))
17664 (use (match_operand 3 "const_int_operand" ""))]
17667 /* If value to set is not zero, use the library routine. */
17668 if (operands[2] != const0_rtx)
17671 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17677 ;; Most CPUs don't like single string operations
17678 ;; Handle this case here to simplify previous expander.
17680 (define_expand "strset"
17681 [(set (match_operand 1 "memory_operand" "")
17682 (match_operand 2 "register_operand" ""))
17683 (parallel [(set (match_operand 0 "register_operand" "")
17685 (clobber (reg:CC FLAGS_REG))])]
17688 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17689 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17691 /* If .md ever supports :P for Pmode, this can be directly
17692 in the pattern above. */
17693 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17694 GEN_INT (GET_MODE_SIZE (GET_MODE
17696 if (TARGET_SINGLE_STRINGOP || optimize_size)
17698 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17704 (define_expand "strset_singleop"
17705 [(parallel [(set (match_operand 1 "memory_operand" "")
17706 (match_operand 2 "register_operand" ""))
17707 (set (match_operand 0 "register_operand" "")
17708 (match_operand 3 "" ""))
17709 (use (reg:SI DIRFLAG_REG))])]
17710 "TARGET_SINGLE_STRINGOP || optimize_size"
17713 (define_insn "*strsetdi_rex_1"
17714 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17715 (match_operand:DI 2 "register_operand" "a"))
17716 (set (match_operand:DI 0 "register_operand" "=D")
17717 (plus:DI (match_dup 1)
17719 (use (reg:SI DIRFLAG_REG))]
17720 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17722 [(set_attr "type" "str")
17723 (set_attr "memory" "store")
17724 (set_attr "mode" "DI")])
17726 (define_insn "*strsetsi_1"
17727 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17728 (match_operand:SI 2 "register_operand" "a"))
17729 (set (match_operand:SI 0 "register_operand" "=D")
17730 (plus:SI (match_dup 1)
17732 (use (reg:SI DIRFLAG_REG))]
17733 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17735 [(set_attr "type" "str")
17736 (set_attr "memory" "store")
17737 (set_attr "mode" "SI")])
17739 (define_insn "*strsetsi_rex_1"
17740 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17741 (match_operand:SI 2 "register_operand" "a"))
17742 (set (match_operand:DI 0 "register_operand" "=D")
17743 (plus:DI (match_dup 1)
17745 (use (reg:SI DIRFLAG_REG))]
17746 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17748 [(set_attr "type" "str")
17749 (set_attr "memory" "store")
17750 (set_attr "mode" "SI")])
17752 (define_insn "*strsethi_1"
17753 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17754 (match_operand:HI 2 "register_operand" "a"))
17755 (set (match_operand:SI 0 "register_operand" "=D")
17756 (plus:SI (match_dup 1)
17758 (use (reg:SI DIRFLAG_REG))]
17759 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17761 [(set_attr "type" "str")
17762 (set_attr "memory" "store")
17763 (set_attr "mode" "HI")])
17765 (define_insn "*strsethi_rex_1"
17766 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17767 (match_operand:HI 2 "register_operand" "a"))
17768 (set (match_operand:DI 0 "register_operand" "=D")
17769 (plus:DI (match_dup 1)
17771 (use (reg:SI DIRFLAG_REG))]
17772 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17774 [(set_attr "type" "str")
17775 (set_attr "memory" "store")
17776 (set_attr "mode" "HI")])
17778 (define_insn "*strsetqi_1"
17779 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17780 (match_operand:QI 2 "register_operand" "a"))
17781 (set (match_operand:SI 0 "register_operand" "=D")
17782 (plus:SI (match_dup 1)
17784 (use (reg:SI DIRFLAG_REG))]
17785 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17787 [(set_attr "type" "str")
17788 (set_attr "memory" "store")
17789 (set_attr "mode" "QI")])
17791 (define_insn "*strsetqi_rex_1"
17792 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17793 (match_operand:QI 2 "register_operand" "a"))
17794 (set (match_operand:DI 0 "register_operand" "=D")
17795 (plus:DI (match_dup 1)
17797 (use (reg:SI DIRFLAG_REG))]
17798 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17800 [(set_attr "type" "str")
17801 (set_attr "memory" "store")
17802 (set_attr "mode" "QI")])
17804 (define_expand "rep_stos"
17805 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17806 (set (match_operand 0 "register_operand" "")
17807 (match_operand 4 "" ""))
17808 (set (match_operand 2 "memory_operand" "") (const_int 0))
17809 (use (match_operand 3 "register_operand" ""))
17810 (use (match_dup 1))
17811 (use (reg:SI DIRFLAG_REG))])]
17815 (define_insn "*rep_stosdi_rex64"
17816 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17817 (set (match_operand:DI 0 "register_operand" "=D")
17818 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17820 (match_operand:DI 3 "register_operand" "0")))
17821 (set (mem:BLK (match_dup 3))
17823 (use (match_operand:DI 2 "register_operand" "a"))
17824 (use (match_dup 4))
17825 (use (reg:SI DIRFLAG_REG))]
17827 "{rep\;stosq|rep stosq}"
17828 [(set_attr "type" "str")
17829 (set_attr "prefix_rep" "1")
17830 (set_attr "memory" "store")
17831 (set_attr "mode" "DI")])
17833 (define_insn "*rep_stossi"
17834 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17835 (set (match_operand:SI 0 "register_operand" "=D")
17836 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17838 (match_operand:SI 3 "register_operand" "0")))
17839 (set (mem:BLK (match_dup 3))
17841 (use (match_operand:SI 2 "register_operand" "a"))
17842 (use (match_dup 4))
17843 (use (reg:SI DIRFLAG_REG))]
17845 "{rep\;stosl|rep stosd}"
17846 [(set_attr "type" "str")
17847 (set_attr "prefix_rep" "1")
17848 (set_attr "memory" "store")
17849 (set_attr "mode" "SI")])
17851 (define_insn "*rep_stossi_rex64"
17852 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17853 (set (match_operand:DI 0 "register_operand" "=D")
17854 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17856 (match_operand:DI 3 "register_operand" "0")))
17857 (set (mem:BLK (match_dup 3))
17859 (use (match_operand:SI 2 "register_operand" "a"))
17860 (use (match_dup 4))
17861 (use (reg:SI DIRFLAG_REG))]
17863 "{rep\;stosl|rep stosd}"
17864 [(set_attr "type" "str")
17865 (set_attr "prefix_rep" "1")
17866 (set_attr "memory" "store")
17867 (set_attr "mode" "SI")])
17869 (define_insn "*rep_stosqi"
17870 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17871 (set (match_operand:SI 0 "register_operand" "=D")
17872 (plus:SI (match_operand:SI 3 "register_operand" "0")
17873 (match_operand:SI 4 "register_operand" "1")))
17874 (set (mem:BLK (match_dup 3))
17876 (use (match_operand:QI 2 "register_operand" "a"))
17877 (use (match_dup 4))
17878 (use (reg:SI DIRFLAG_REG))]
17880 "{rep\;stosb|rep stosb}"
17881 [(set_attr "type" "str")
17882 (set_attr "prefix_rep" "1")
17883 (set_attr "memory" "store")
17884 (set_attr "mode" "QI")])
17886 (define_insn "*rep_stosqi_rex64"
17887 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17888 (set (match_operand:DI 0 "register_operand" "=D")
17889 (plus:DI (match_operand:DI 3 "register_operand" "0")
17890 (match_operand:DI 4 "register_operand" "1")))
17891 (set (mem:BLK (match_dup 3))
17893 (use (match_operand:QI 2 "register_operand" "a"))
17894 (use (match_dup 4))
17895 (use (reg:SI DIRFLAG_REG))]
17897 "{rep\;stosb|rep stosb}"
17898 [(set_attr "type" "str")
17899 (set_attr "prefix_rep" "1")
17900 (set_attr "memory" "store")
17901 (set_attr "mode" "QI")])
17903 (define_expand "cmpstrnsi"
17904 [(set (match_operand:SI 0 "register_operand" "")
17905 (compare:SI (match_operand:BLK 1 "general_operand" "")
17906 (match_operand:BLK 2 "general_operand" "")))
17907 (use (match_operand 3 "general_operand" ""))
17908 (use (match_operand 4 "immediate_operand" ""))]
17909 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17911 rtx addr1, addr2, out, outlow, count, countreg, align;
17913 /* Can't use this if the user has appropriated esi or edi. */
17914 if (global_regs[4] || global_regs[5])
17918 if (GET_CODE (out) != REG)
17919 out = gen_reg_rtx (SImode);
17921 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17922 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17923 if (addr1 != XEXP (operands[1], 0))
17924 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17925 if (addr2 != XEXP (operands[2], 0))
17926 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17928 count = operands[3];
17929 countreg = ix86_zero_extend_to_Pmode (count);
17931 /* %%% Iff we are testing strict equality, we can use known alignment
17932 to good advantage. This may be possible with combine, particularly
17933 once cc0 is dead. */
17934 align = operands[4];
17936 emit_insn (gen_cld ());
17937 if (GET_CODE (count) == CONST_INT)
17939 if (INTVAL (count) == 0)
17941 emit_move_insn (operands[0], const0_rtx);
17944 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17945 operands[1], operands[2]));
17950 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17952 emit_insn (gen_cmpsi_1 (countreg, countreg));
17953 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17954 operands[1], operands[2]));
17957 outlow = gen_lowpart (QImode, out);
17958 emit_insn (gen_cmpintqi (outlow));
17959 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17961 if (operands[0] != out)
17962 emit_move_insn (operands[0], out);
17967 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17969 (define_expand "cmpintqi"
17970 [(set (match_dup 1)
17971 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17973 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17974 (parallel [(set (match_operand:QI 0 "register_operand" "")
17975 (minus:QI (match_dup 1)
17977 (clobber (reg:CC FLAGS_REG))])]
17979 "operands[1] = gen_reg_rtx (QImode);
17980 operands[2] = gen_reg_rtx (QImode);")
17982 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17983 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17985 (define_expand "cmpstrnqi_nz_1"
17986 [(parallel [(set (reg:CC FLAGS_REG)
17987 (compare:CC (match_operand 4 "memory_operand" "")
17988 (match_operand 5 "memory_operand" "")))
17989 (use (match_operand 2 "register_operand" ""))
17990 (use (match_operand:SI 3 "immediate_operand" ""))
17991 (use (reg:SI DIRFLAG_REG))
17992 (clobber (match_operand 0 "register_operand" ""))
17993 (clobber (match_operand 1 "register_operand" ""))
17994 (clobber (match_dup 2))])]
17998 (define_insn "*cmpstrnqi_nz_1"
17999 [(set (reg:CC FLAGS_REG)
18000 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18001 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18002 (use (match_operand:SI 6 "register_operand" "2"))
18003 (use (match_operand:SI 3 "immediate_operand" "i"))
18004 (use (reg:SI DIRFLAG_REG))
18005 (clobber (match_operand:SI 0 "register_operand" "=S"))
18006 (clobber (match_operand:SI 1 "register_operand" "=D"))
18007 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18010 [(set_attr "type" "str")
18011 (set_attr "mode" "QI")
18012 (set_attr "prefix_rep" "1")])
18014 (define_insn "*cmpstrnqi_nz_rex_1"
18015 [(set (reg:CC FLAGS_REG)
18016 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18017 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18018 (use (match_operand:DI 6 "register_operand" "2"))
18019 (use (match_operand:SI 3 "immediate_operand" "i"))
18020 (use (reg:SI DIRFLAG_REG))
18021 (clobber (match_operand:DI 0 "register_operand" "=S"))
18022 (clobber (match_operand:DI 1 "register_operand" "=D"))
18023 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18026 [(set_attr "type" "str")
18027 (set_attr "mode" "QI")
18028 (set_attr "prefix_rep" "1")])
18030 ;; The same, but the count is not known to not be zero.
18032 (define_expand "cmpstrnqi_1"
18033 [(parallel [(set (reg:CC FLAGS_REG)
18034 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18036 (compare:CC (match_operand 4 "memory_operand" "")
18037 (match_operand 5 "memory_operand" ""))
18039 (use (match_operand:SI 3 "immediate_operand" ""))
18040 (use (reg:CC FLAGS_REG))
18041 (use (reg:SI DIRFLAG_REG))
18042 (clobber (match_operand 0 "register_operand" ""))
18043 (clobber (match_operand 1 "register_operand" ""))
18044 (clobber (match_dup 2))])]
18048 (define_insn "*cmpstrnqi_1"
18049 [(set (reg:CC FLAGS_REG)
18050 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18052 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18053 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18055 (use (match_operand:SI 3 "immediate_operand" "i"))
18056 (use (reg:CC FLAGS_REG))
18057 (use (reg:SI DIRFLAG_REG))
18058 (clobber (match_operand:SI 0 "register_operand" "=S"))
18059 (clobber (match_operand:SI 1 "register_operand" "=D"))
18060 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18063 [(set_attr "type" "str")
18064 (set_attr "mode" "QI")
18065 (set_attr "prefix_rep" "1")])
18067 (define_insn "*cmpstrnqi_rex_1"
18068 [(set (reg:CC FLAGS_REG)
18069 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18071 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18072 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18074 (use (match_operand:SI 3 "immediate_operand" "i"))
18075 (use (reg:CC FLAGS_REG))
18076 (use (reg:SI DIRFLAG_REG))
18077 (clobber (match_operand:DI 0 "register_operand" "=S"))
18078 (clobber (match_operand:DI 1 "register_operand" "=D"))
18079 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18082 [(set_attr "type" "str")
18083 (set_attr "mode" "QI")
18084 (set_attr "prefix_rep" "1")])
18086 (define_expand "strlensi"
18087 [(set (match_operand:SI 0 "register_operand" "")
18088 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18089 (match_operand:QI 2 "immediate_operand" "")
18090 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18093 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18099 (define_expand "strlendi"
18100 [(set (match_operand:DI 0 "register_operand" "")
18101 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18102 (match_operand:QI 2 "immediate_operand" "")
18103 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18106 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18112 (define_expand "strlenqi_1"
18113 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18114 (use (reg:SI DIRFLAG_REG))
18115 (clobber (match_operand 1 "register_operand" ""))
18116 (clobber (reg:CC FLAGS_REG))])]
18120 (define_insn "*strlenqi_1"
18121 [(set (match_operand:SI 0 "register_operand" "=&c")
18122 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18123 (match_operand:QI 2 "register_operand" "a")
18124 (match_operand:SI 3 "immediate_operand" "i")
18125 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18126 (use (reg:SI DIRFLAG_REG))
18127 (clobber (match_operand:SI 1 "register_operand" "=D"))
18128 (clobber (reg:CC FLAGS_REG))]
18131 [(set_attr "type" "str")
18132 (set_attr "mode" "QI")
18133 (set_attr "prefix_rep" "1")])
18135 (define_insn "*strlenqi_rex_1"
18136 [(set (match_operand:DI 0 "register_operand" "=&c")
18137 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18138 (match_operand:QI 2 "register_operand" "a")
18139 (match_operand:DI 3 "immediate_operand" "i")
18140 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18141 (use (reg:SI DIRFLAG_REG))
18142 (clobber (match_operand:DI 1 "register_operand" "=D"))
18143 (clobber (reg:CC FLAGS_REG))]
18146 [(set_attr "type" "str")
18147 (set_attr "mode" "QI")
18148 (set_attr "prefix_rep" "1")])
18150 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18151 ;; handled in combine, but it is not currently up to the task.
18152 ;; When used for their truth value, the cmpstrn* expanders generate
18161 ;; The intermediate three instructions are unnecessary.
18163 ;; This one handles cmpstrn*_nz_1...
18166 (set (reg:CC FLAGS_REG)
18167 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18168 (mem:BLK (match_operand 5 "register_operand" ""))))
18169 (use (match_operand 6 "register_operand" ""))
18170 (use (match_operand:SI 3 "immediate_operand" ""))
18171 (use (reg:SI DIRFLAG_REG))
18172 (clobber (match_operand 0 "register_operand" ""))
18173 (clobber (match_operand 1 "register_operand" ""))
18174 (clobber (match_operand 2 "register_operand" ""))])
18175 (set (match_operand:QI 7 "register_operand" "")
18176 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18177 (set (match_operand:QI 8 "register_operand" "")
18178 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18179 (set (reg FLAGS_REG)
18180 (compare (match_dup 7) (match_dup 8)))
18182 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18184 (set (reg:CC FLAGS_REG)
18185 (compare:CC (mem:BLK (match_dup 4))
18186 (mem:BLK (match_dup 5))))
18187 (use (match_dup 6))
18188 (use (match_dup 3))
18189 (use (reg:SI DIRFLAG_REG))
18190 (clobber (match_dup 0))
18191 (clobber (match_dup 1))
18192 (clobber (match_dup 2))])]
18195 ;; ...and this one handles cmpstrn*_1.
18198 (set (reg:CC FLAGS_REG)
18199 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18201 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18202 (mem:BLK (match_operand 5 "register_operand" "")))
18204 (use (match_operand:SI 3 "immediate_operand" ""))
18205 (use (reg:CC FLAGS_REG))
18206 (use (reg:SI DIRFLAG_REG))
18207 (clobber (match_operand 0 "register_operand" ""))
18208 (clobber (match_operand 1 "register_operand" ""))
18209 (clobber (match_operand 2 "register_operand" ""))])
18210 (set (match_operand:QI 7 "register_operand" "")
18211 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18212 (set (match_operand:QI 8 "register_operand" "")
18213 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18214 (set (reg FLAGS_REG)
18215 (compare (match_dup 7) (match_dup 8)))
18217 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18219 (set (reg:CC FLAGS_REG)
18220 (if_then_else:CC (ne (match_dup 6)
18222 (compare:CC (mem:BLK (match_dup 4))
18223 (mem:BLK (match_dup 5)))
18225 (use (match_dup 3))
18226 (use (reg:CC FLAGS_REG))
18227 (use (reg:SI DIRFLAG_REG))
18228 (clobber (match_dup 0))
18229 (clobber (match_dup 1))
18230 (clobber (match_dup 2))])]
18235 ;; Conditional move instructions.
18237 (define_expand "movdicc"
18238 [(set (match_operand:DI 0 "register_operand" "")
18239 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18240 (match_operand:DI 2 "general_operand" "")
18241 (match_operand:DI 3 "general_operand" "")))]
18243 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18245 (define_insn "x86_movdicc_0_m1_rex64"
18246 [(set (match_operand:DI 0 "register_operand" "=r")
18247 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18250 (clobber (reg:CC FLAGS_REG))]
18253 ; Since we don't have the proper number of operands for an alu insn,
18254 ; fill in all the blanks.
18255 [(set_attr "type" "alu")
18256 (set_attr "pent_pair" "pu")
18257 (set_attr "memory" "none")
18258 (set_attr "imm_disp" "false")
18259 (set_attr "mode" "DI")
18260 (set_attr "length_immediate" "0")])
18262 (define_insn "*movdicc_c_rex64"
18263 [(set (match_operand:DI 0 "register_operand" "=r,r")
18264 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18265 [(reg FLAGS_REG) (const_int 0)])
18266 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18267 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18268 "TARGET_64BIT && TARGET_CMOVE
18269 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18271 cmov%O2%C1\t{%2, %0|%0, %2}
18272 cmov%O2%c1\t{%3, %0|%0, %3}"
18273 [(set_attr "type" "icmov")
18274 (set_attr "mode" "DI")])
18276 (define_expand "movsicc"
18277 [(set (match_operand:SI 0 "register_operand" "")
18278 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18279 (match_operand:SI 2 "general_operand" "")
18280 (match_operand:SI 3 "general_operand" "")))]
18282 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18284 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18285 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18286 ;; So just document what we're doing explicitly.
18288 (define_insn "x86_movsicc_0_m1"
18289 [(set (match_operand:SI 0 "register_operand" "=r")
18290 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18293 (clobber (reg:CC FLAGS_REG))]
18296 ; Since we don't have the proper number of operands for an alu insn,
18297 ; fill in all the blanks.
18298 [(set_attr "type" "alu")
18299 (set_attr "pent_pair" "pu")
18300 (set_attr "memory" "none")
18301 (set_attr "imm_disp" "false")
18302 (set_attr "mode" "SI")
18303 (set_attr "length_immediate" "0")])
18305 (define_insn "*movsicc_noc"
18306 [(set (match_operand:SI 0 "register_operand" "=r,r")
18307 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18308 [(reg FLAGS_REG) (const_int 0)])
18309 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18310 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18312 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18314 cmov%O2%C1\t{%2, %0|%0, %2}
18315 cmov%O2%c1\t{%3, %0|%0, %3}"
18316 [(set_attr "type" "icmov")
18317 (set_attr "mode" "SI")])
18319 (define_expand "movhicc"
18320 [(set (match_operand:HI 0 "register_operand" "")
18321 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18322 (match_operand:HI 2 "general_operand" "")
18323 (match_operand:HI 3 "general_operand" "")))]
18324 "TARGET_HIMODE_MATH"
18325 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18327 (define_insn "*movhicc_noc"
18328 [(set (match_operand:HI 0 "register_operand" "=r,r")
18329 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18330 [(reg FLAGS_REG) (const_int 0)])
18331 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18332 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18334 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18336 cmov%O2%C1\t{%2, %0|%0, %2}
18337 cmov%O2%c1\t{%3, %0|%0, %3}"
18338 [(set_attr "type" "icmov")
18339 (set_attr "mode" "HI")])
18341 (define_expand "movqicc"
18342 [(set (match_operand:QI 0 "register_operand" "")
18343 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18344 (match_operand:QI 2 "general_operand" "")
18345 (match_operand:QI 3 "general_operand" "")))]
18346 "TARGET_QIMODE_MATH"
18347 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18349 (define_insn_and_split "*movqicc_noc"
18350 [(set (match_operand:QI 0 "register_operand" "=r,r")
18351 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18352 [(match_operand 4 "flags_reg_operand" "")
18354 (match_operand:QI 2 "register_operand" "r,0")
18355 (match_operand:QI 3 "register_operand" "0,r")))]
18356 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18358 "&& reload_completed"
18359 [(set (match_dup 0)
18360 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18363 "operands[0] = gen_lowpart (SImode, operands[0]);
18364 operands[2] = gen_lowpart (SImode, operands[2]);
18365 operands[3] = gen_lowpart (SImode, operands[3]);"
18366 [(set_attr "type" "icmov")
18367 (set_attr "mode" "SI")])
18369 (define_expand "movsfcc"
18370 [(set (match_operand:SF 0 "register_operand" "")
18371 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18372 (match_operand:SF 2 "register_operand" "")
18373 (match_operand:SF 3 "register_operand" "")))]
18374 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18375 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18377 (define_insn "*movsfcc_1_387"
18378 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18379 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18380 [(reg FLAGS_REG) (const_int 0)])
18381 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18382 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18383 "TARGET_80387 && TARGET_CMOVE
18384 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18386 fcmov%F1\t{%2, %0|%0, %2}
18387 fcmov%f1\t{%3, %0|%0, %3}
18388 cmov%O2%C1\t{%2, %0|%0, %2}
18389 cmov%O2%c1\t{%3, %0|%0, %3}"
18390 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18391 (set_attr "mode" "SF,SF,SI,SI")])
18393 (define_expand "movdfcc"
18394 [(set (match_operand:DF 0 "register_operand" "")
18395 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18396 (match_operand:DF 2 "register_operand" "")
18397 (match_operand:DF 3 "register_operand" "")))]
18398 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18399 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18401 (define_insn "*movdfcc_1"
18402 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18403 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18404 [(reg FLAGS_REG) (const_int 0)])
18405 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18406 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18407 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18408 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18410 fcmov%F1\t{%2, %0|%0, %2}
18411 fcmov%f1\t{%3, %0|%0, %3}
18414 [(set_attr "type" "fcmov,fcmov,multi,multi")
18415 (set_attr "mode" "DF")])
18417 (define_insn "*movdfcc_1_rex64"
18418 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18419 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18420 [(reg FLAGS_REG) (const_int 0)])
18421 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18422 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18423 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18424 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18426 fcmov%F1\t{%2, %0|%0, %2}
18427 fcmov%f1\t{%3, %0|%0, %3}
18428 cmov%O2%C1\t{%2, %0|%0, %2}
18429 cmov%O2%c1\t{%3, %0|%0, %3}"
18430 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18431 (set_attr "mode" "DF")])
18434 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18435 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18436 [(match_operand 4 "flags_reg_operand" "")
18438 (match_operand:DF 2 "nonimmediate_operand" "")
18439 (match_operand:DF 3 "nonimmediate_operand" "")))]
18440 "!TARGET_64BIT && reload_completed"
18441 [(set (match_dup 2)
18442 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18446 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18449 "split_di (operands+2, 1, operands+5, operands+6);
18450 split_di (operands+3, 1, operands+7, operands+8);
18451 split_di (operands, 1, operands+2, operands+3);")
18453 (define_expand "movxfcc"
18454 [(set (match_operand:XF 0 "register_operand" "")
18455 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18456 (match_operand:XF 2 "register_operand" "")
18457 (match_operand:XF 3 "register_operand" "")))]
18458 "TARGET_80387 && TARGET_CMOVE"
18459 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18461 (define_insn "*movxfcc_1"
18462 [(set (match_operand:XF 0 "register_operand" "=f,f")
18463 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18464 [(reg FLAGS_REG) (const_int 0)])
18465 (match_operand:XF 2 "register_operand" "f,0")
18466 (match_operand:XF 3 "register_operand" "0,f")))]
18467 "TARGET_80387 && TARGET_CMOVE"
18469 fcmov%F1\t{%2, %0|%0, %2}
18470 fcmov%f1\t{%3, %0|%0, %3}"
18471 [(set_attr "type" "fcmov")
18472 (set_attr "mode" "XF")])
18474 ;; These versions of the min/max patterns are intentionally ignorant of
18475 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18476 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18477 ;; are undefined in this condition, we're certain this is correct.
18479 (define_insn "sminsf3"
18480 [(set (match_operand:SF 0 "register_operand" "=x")
18481 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18482 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18484 "minss\t{%2, %0|%0, %2}"
18485 [(set_attr "type" "sseadd")
18486 (set_attr "mode" "SF")])
18488 (define_insn "smaxsf3"
18489 [(set (match_operand:SF 0 "register_operand" "=x")
18490 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18491 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18493 "maxss\t{%2, %0|%0, %2}"
18494 [(set_attr "type" "sseadd")
18495 (set_attr "mode" "SF")])
18497 (define_insn "smindf3"
18498 [(set (match_operand:DF 0 "register_operand" "=x")
18499 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18500 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18501 "TARGET_SSE2 && TARGET_SSE_MATH"
18502 "minsd\t{%2, %0|%0, %2}"
18503 [(set_attr "type" "sseadd")
18504 (set_attr "mode" "DF")])
18506 (define_insn "smaxdf3"
18507 [(set (match_operand:DF 0 "register_operand" "=x")
18508 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18509 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18510 "TARGET_SSE2 && TARGET_SSE_MATH"
18511 "maxsd\t{%2, %0|%0, %2}"
18512 [(set_attr "type" "sseadd")
18513 (set_attr "mode" "DF")])
18515 ;; These versions of the min/max patterns implement exactly the operations
18516 ;; min = (op1 < op2 ? op1 : op2)
18517 ;; max = (!(op1 < op2) ? op1 : op2)
18518 ;; Their operands are not commutative, and thus they may be used in the
18519 ;; presence of -0.0 and NaN.
18521 (define_insn "*ieee_sminsf3"
18522 [(set (match_operand:SF 0 "register_operand" "=x")
18523 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18524 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18527 "minss\t{%2, %0|%0, %2}"
18528 [(set_attr "type" "sseadd")
18529 (set_attr "mode" "SF")])
18531 (define_insn "*ieee_smaxsf3"
18532 [(set (match_operand:SF 0 "register_operand" "=x")
18533 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18534 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18537 "maxss\t{%2, %0|%0, %2}"
18538 [(set_attr "type" "sseadd")
18539 (set_attr "mode" "SF")])
18541 (define_insn "*ieee_smindf3"
18542 [(set (match_operand:DF 0 "register_operand" "=x")
18543 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18544 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18546 "TARGET_SSE2 && TARGET_SSE_MATH"
18547 "minsd\t{%2, %0|%0, %2}"
18548 [(set_attr "type" "sseadd")
18549 (set_attr "mode" "DF")])
18551 (define_insn "*ieee_smaxdf3"
18552 [(set (match_operand:DF 0 "register_operand" "=x")
18553 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18554 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18556 "TARGET_SSE2 && TARGET_SSE_MATH"
18557 "maxsd\t{%2, %0|%0, %2}"
18558 [(set_attr "type" "sseadd")
18559 (set_attr "mode" "DF")])
18561 ;; Conditional addition patterns
18562 (define_expand "addqicc"
18563 [(match_operand:QI 0 "register_operand" "")
18564 (match_operand 1 "comparison_operator" "")
18565 (match_operand:QI 2 "register_operand" "")
18566 (match_operand:QI 3 "const_int_operand" "")]
18568 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18570 (define_expand "addhicc"
18571 [(match_operand:HI 0 "register_operand" "")
18572 (match_operand 1 "comparison_operator" "")
18573 (match_operand:HI 2 "register_operand" "")
18574 (match_operand:HI 3 "const_int_operand" "")]
18576 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18578 (define_expand "addsicc"
18579 [(match_operand:SI 0 "register_operand" "")
18580 (match_operand 1 "comparison_operator" "")
18581 (match_operand:SI 2 "register_operand" "")
18582 (match_operand:SI 3 "const_int_operand" "")]
18584 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18586 (define_expand "adddicc"
18587 [(match_operand:DI 0 "register_operand" "")
18588 (match_operand 1 "comparison_operator" "")
18589 (match_operand:DI 2 "register_operand" "")
18590 (match_operand:DI 3 "const_int_operand" "")]
18592 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18595 ;; Misc patterns (?)
18597 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18598 ;; Otherwise there will be nothing to keep
18600 ;; [(set (reg ebp) (reg esp))]
18601 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18602 ;; (clobber (eflags)]
18603 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18605 ;; in proper program order.
18606 (define_insn "pro_epilogue_adjust_stack_1"
18607 [(set (match_operand:SI 0 "register_operand" "=r,r")
18608 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18609 (match_operand:SI 2 "immediate_operand" "i,i")))
18610 (clobber (reg:CC FLAGS_REG))
18611 (clobber (mem:BLK (scratch)))]
18614 switch (get_attr_type (insn))
18617 return "mov{l}\t{%1, %0|%0, %1}";
18620 if (GET_CODE (operands[2]) == CONST_INT
18621 && (INTVAL (operands[2]) == 128
18622 || (INTVAL (operands[2]) < 0
18623 && INTVAL (operands[2]) != -128)))
18625 operands[2] = GEN_INT (-INTVAL (operands[2]));
18626 return "sub{l}\t{%2, %0|%0, %2}";
18628 return "add{l}\t{%2, %0|%0, %2}";
18631 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18632 return "lea{l}\t{%a2, %0|%0, %a2}";
18635 gcc_unreachable ();
18638 [(set (attr "type")
18639 (cond [(eq_attr "alternative" "0")
18640 (const_string "alu")
18641 (match_operand:SI 2 "const0_operand" "")
18642 (const_string "imov")
18644 (const_string "lea")))
18645 (set_attr "mode" "SI")])
18647 (define_insn "pro_epilogue_adjust_stack_rex64"
18648 [(set (match_operand:DI 0 "register_operand" "=r,r")
18649 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18650 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18651 (clobber (reg:CC FLAGS_REG))
18652 (clobber (mem:BLK (scratch)))]
18655 switch (get_attr_type (insn))
18658 return "mov{q}\t{%1, %0|%0, %1}";
18661 if (GET_CODE (operands[2]) == CONST_INT
18662 /* Avoid overflows. */
18663 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18664 && (INTVAL (operands[2]) == 128
18665 || (INTVAL (operands[2]) < 0
18666 && INTVAL (operands[2]) != -128)))
18668 operands[2] = GEN_INT (-INTVAL (operands[2]));
18669 return "sub{q}\t{%2, %0|%0, %2}";
18671 return "add{q}\t{%2, %0|%0, %2}";
18674 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18675 return "lea{q}\t{%a2, %0|%0, %a2}";
18678 gcc_unreachable ();
18681 [(set (attr "type")
18682 (cond [(eq_attr "alternative" "0")
18683 (const_string "alu")
18684 (match_operand:DI 2 "const0_operand" "")
18685 (const_string "imov")
18687 (const_string "lea")))
18688 (set_attr "mode" "DI")])
18690 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18691 [(set (match_operand:DI 0 "register_operand" "=r,r")
18692 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18693 (match_operand:DI 3 "immediate_operand" "i,i")))
18694 (use (match_operand:DI 2 "register_operand" "r,r"))
18695 (clobber (reg:CC FLAGS_REG))
18696 (clobber (mem:BLK (scratch)))]
18699 switch (get_attr_type (insn))
18702 return "add{q}\t{%2, %0|%0, %2}";
18705 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18706 return "lea{q}\t{%a2, %0|%0, %a2}";
18709 gcc_unreachable ();
18712 [(set_attr "type" "alu,lea")
18713 (set_attr "mode" "DI")])
18715 (define_expand "allocate_stack_worker"
18716 [(match_operand:SI 0 "register_operand" "")]
18717 "TARGET_STACK_PROBE"
18719 if (reload_completed)
18722 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18724 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18729 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18731 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18736 (define_insn "allocate_stack_worker_1"
18737 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18738 UNSPECV_STACK_PROBE)
18739 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18740 (clobber (match_scratch:SI 1 "=0"))
18741 (clobber (reg:CC FLAGS_REG))]
18742 "!TARGET_64BIT && TARGET_STACK_PROBE"
18744 [(set_attr "type" "multi")
18745 (set_attr "length" "5")])
18747 (define_expand "allocate_stack_worker_postreload"
18748 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18749 UNSPECV_STACK_PROBE)
18750 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18751 (clobber (match_dup 0))
18752 (clobber (reg:CC FLAGS_REG))])]
18756 (define_insn "allocate_stack_worker_rex64"
18757 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18758 UNSPECV_STACK_PROBE)
18759 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18760 (clobber (match_scratch:DI 1 "=0"))
18761 (clobber (reg:CC FLAGS_REG))]
18762 "TARGET_64BIT && TARGET_STACK_PROBE"
18764 [(set_attr "type" "multi")
18765 (set_attr "length" "5")])
18767 (define_expand "allocate_stack_worker_rex64_postreload"
18768 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18769 UNSPECV_STACK_PROBE)
18770 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18771 (clobber (match_dup 0))
18772 (clobber (reg:CC FLAGS_REG))])]
18776 (define_expand "allocate_stack"
18777 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18778 (minus:SI (reg:SI SP_REG)
18779 (match_operand:SI 1 "general_operand" "")))
18780 (clobber (reg:CC FLAGS_REG))])
18781 (parallel [(set (reg:SI SP_REG)
18782 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18783 (clobber (reg:CC FLAGS_REG))])]
18784 "TARGET_STACK_PROBE"
18786 #ifdef CHECK_STACK_LIMIT
18787 if (GET_CODE (operands[1]) == CONST_INT
18788 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18789 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18793 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18796 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18800 (define_expand "builtin_setjmp_receiver"
18801 [(label_ref (match_operand 0 "" ""))]
18802 "!TARGET_64BIT && flag_pic"
18804 emit_insn (gen_set_got (pic_offset_table_rtx));
18808 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18811 [(set (match_operand 0 "register_operand" "")
18812 (match_operator 3 "promotable_binary_operator"
18813 [(match_operand 1 "register_operand" "")
18814 (match_operand 2 "aligned_operand" "")]))
18815 (clobber (reg:CC FLAGS_REG))]
18816 "! TARGET_PARTIAL_REG_STALL && reload_completed
18817 && ((GET_MODE (operands[0]) == HImode
18818 && ((!optimize_size && !TARGET_FAST_PREFIX)
18819 || GET_CODE (operands[2]) != CONST_INT
18820 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18821 || (GET_MODE (operands[0]) == QImode
18822 && (TARGET_PROMOTE_QImode || optimize_size)))"
18823 [(parallel [(set (match_dup 0)
18824 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18825 (clobber (reg:CC FLAGS_REG))])]
18826 "operands[0] = gen_lowpart (SImode, operands[0]);
18827 operands[1] = gen_lowpart (SImode, operands[1]);
18828 if (GET_CODE (operands[3]) != ASHIFT)
18829 operands[2] = gen_lowpart (SImode, operands[2]);
18830 PUT_MODE (operands[3], SImode);")
18832 ; Promote the QImode tests, as i386 has encoding of the AND
18833 ; instruction with 32-bit sign-extended immediate and thus the
18834 ; instruction size is unchanged, except in the %eax case for
18835 ; which it is increased by one byte, hence the ! optimize_size.
18837 [(set (match_operand 0 "flags_reg_operand" "")
18838 (match_operator 2 "compare_operator"
18839 [(and (match_operand 3 "aligned_operand" "")
18840 (match_operand 4 "const_int_operand" ""))
18842 (set (match_operand 1 "register_operand" "")
18843 (and (match_dup 3) (match_dup 4)))]
18844 "! TARGET_PARTIAL_REG_STALL && reload_completed
18845 /* Ensure that the operand will remain sign-extended immediate. */
18846 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18848 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18849 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18850 [(parallel [(set (match_dup 0)
18851 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18854 (and:SI (match_dup 3) (match_dup 4)))])]
18857 = gen_int_mode (INTVAL (operands[4])
18858 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18859 operands[1] = gen_lowpart (SImode, operands[1]);
18860 operands[3] = gen_lowpart (SImode, operands[3]);
18863 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18864 ; the TEST instruction with 32-bit sign-extended immediate and thus
18865 ; the instruction size would at least double, which is not what we
18866 ; want even with ! optimize_size.
18868 [(set (match_operand 0 "flags_reg_operand" "")
18869 (match_operator 1 "compare_operator"
18870 [(and (match_operand:HI 2 "aligned_operand" "")
18871 (match_operand:HI 3 "const_int_operand" ""))
18873 "! TARGET_PARTIAL_REG_STALL && reload_completed
18874 /* Ensure that the operand will remain sign-extended immediate. */
18875 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18876 && ! TARGET_FAST_PREFIX
18877 && ! optimize_size"
18878 [(set (match_dup 0)
18879 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18883 = gen_int_mode (INTVAL (operands[3])
18884 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18885 operands[2] = gen_lowpart (SImode, operands[2]);
18889 [(set (match_operand 0 "register_operand" "")
18890 (neg (match_operand 1 "register_operand" "")))
18891 (clobber (reg:CC FLAGS_REG))]
18892 "! TARGET_PARTIAL_REG_STALL && reload_completed
18893 && (GET_MODE (operands[0]) == HImode
18894 || (GET_MODE (operands[0]) == QImode
18895 && (TARGET_PROMOTE_QImode || optimize_size)))"
18896 [(parallel [(set (match_dup 0)
18897 (neg:SI (match_dup 1)))
18898 (clobber (reg:CC FLAGS_REG))])]
18899 "operands[0] = gen_lowpart (SImode, operands[0]);
18900 operands[1] = gen_lowpart (SImode, operands[1]);")
18903 [(set (match_operand 0 "register_operand" "")
18904 (not (match_operand 1 "register_operand" "")))]
18905 "! TARGET_PARTIAL_REG_STALL && reload_completed
18906 && (GET_MODE (operands[0]) == HImode
18907 || (GET_MODE (operands[0]) == QImode
18908 && (TARGET_PROMOTE_QImode || optimize_size)))"
18909 [(set (match_dup 0)
18910 (not:SI (match_dup 1)))]
18911 "operands[0] = gen_lowpart (SImode, operands[0]);
18912 operands[1] = gen_lowpart (SImode, operands[1]);")
18915 [(set (match_operand 0 "register_operand" "")
18916 (if_then_else (match_operator 1 "comparison_operator"
18917 [(reg FLAGS_REG) (const_int 0)])
18918 (match_operand 2 "register_operand" "")
18919 (match_operand 3 "register_operand" "")))]
18920 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18921 && (GET_MODE (operands[0]) == HImode
18922 || (GET_MODE (operands[0]) == QImode
18923 && (TARGET_PROMOTE_QImode || optimize_size)))"
18924 [(set (match_dup 0)
18925 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18926 "operands[0] = gen_lowpart (SImode, operands[0]);
18927 operands[2] = gen_lowpart (SImode, operands[2]);
18928 operands[3] = gen_lowpart (SImode, operands[3]);")
18931 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18932 ;; transform a complex memory operation into two memory to register operations.
18934 ;; Don't push memory operands
18936 [(set (match_operand:SI 0 "push_operand" "")
18937 (match_operand:SI 1 "memory_operand" ""))
18938 (match_scratch:SI 2 "r")]
18939 "!optimize_size && !TARGET_PUSH_MEMORY
18940 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18941 [(set (match_dup 2) (match_dup 1))
18942 (set (match_dup 0) (match_dup 2))]
18946 [(set (match_operand:DI 0 "push_operand" "")
18947 (match_operand:DI 1 "memory_operand" ""))
18948 (match_scratch:DI 2 "r")]
18949 "!optimize_size && !TARGET_PUSH_MEMORY
18950 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18951 [(set (match_dup 2) (match_dup 1))
18952 (set (match_dup 0) (match_dup 2))]
18955 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18958 [(set (match_operand:SF 0 "push_operand" "")
18959 (match_operand:SF 1 "memory_operand" ""))
18960 (match_scratch:SF 2 "r")]
18961 "!optimize_size && !TARGET_PUSH_MEMORY
18962 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18963 [(set (match_dup 2) (match_dup 1))
18964 (set (match_dup 0) (match_dup 2))]
18968 [(set (match_operand:HI 0 "push_operand" "")
18969 (match_operand:HI 1 "memory_operand" ""))
18970 (match_scratch:HI 2 "r")]
18971 "!optimize_size && !TARGET_PUSH_MEMORY
18972 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18973 [(set (match_dup 2) (match_dup 1))
18974 (set (match_dup 0) (match_dup 2))]
18978 [(set (match_operand:QI 0 "push_operand" "")
18979 (match_operand:QI 1 "memory_operand" ""))
18980 (match_scratch:QI 2 "q")]
18981 "!optimize_size && !TARGET_PUSH_MEMORY
18982 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18983 [(set (match_dup 2) (match_dup 1))
18984 (set (match_dup 0) (match_dup 2))]
18987 ;; Don't move an immediate directly to memory when the instruction
18990 [(match_scratch:SI 1 "r")
18991 (set (match_operand:SI 0 "memory_operand" "")
18994 && ! TARGET_USE_MOV0
18995 && TARGET_SPLIT_LONG_MOVES
18996 && get_attr_length (insn) >= ix86_cost->large_insn
18997 && peep2_regno_dead_p (0, FLAGS_REG)"
18998 [(parallel [(set (match_dup 1) (const_int 0))
18999 (clobber (reg:CC FLAGS_REG))])
19000 (set (match_dup 0) (match_dup 1))]
19004 [(match_scratch:HI 1 "r")
19005 (set (match_operand:HI 0 "memory_operand" "")
19008 && ! TARGET_USE_MOV0
19009 && TARGET_SPLIT_LONG_MOVES
19010 && get_attr_length (insn) >= ix86_cost->large_insn
19011 && peep2_regno_dead_p (0, FLAGS_REG)"
19012 [(parallel [(set (match_dup 2) (const_int 0))
19013 (clobber (reg:CC FLAGS_REG))])
19014 (set (match_dup 0) (match_dup 1))]
19015 "operands[2] = gen_lowpart (SImode, operands[1]);")
19018 [(match_scratch:QI 1 "q")
19019 (set (match_operand:QI 0 "memory_operand" "")
19022 && ! TARGET_USE_MOV0
19023 && TARGET_SPLIT_LONG_MOVES
19024 && get_attr_length (insn) >= ix86_cost->large_insn
19025 && peep2_regno_dead_p (0, FLAGS_REG)"
19026 [(parallel [(set (match_dup 2) (const_int 0))
19027 (clobber (reg:CC FLAGS_REG))])
19028 (set (match_dup 0) (match_dup 1))]
19029 "operands[2] = gen_lowpart (SImode, operands[1]);")
19032 [(match_scratch:SI 2 "r")
19033 (set (match_operand:SI 0 "memory_operand" "")
19034 (match_operand:SI 1 "immediate_operand" ""))]
19036 && get_attr_length (insn) >= ix86_cost->large_insn
19037 && TARGET_SPLIT_LONG_MOVES"
19038 [(set (match_dup 2) (match_dup 1))
19039 (set (match_dup 0) (match_dup 2))]
19043 [(match_scratch:HI 2 "r")
19044 (set (match_operand:HI 0 "memory_operand" "")
19045 (match_operand:HI 1 "immediate_operand" ""))]
19046 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19047 && TARGET_SPLIT_LONG_MOVES"
19048 [(set (match_dup 2) (match_dup 1))
19049 (set (match_dup 0) (match_dup 2))]
19053 [(match_scratch:QI 2 "q")
19054 (set (match_operand:QI 0 "memory_operand" "")
19055 (match_operand:QI 1 "immediate_operand" ""))]
19056 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19057 && TARGET_SPLIT_LONG_MOVES"
19058 [(set (match_dup 2) (match_dup 1))
19059 (set (match_dup 0) (match_dup 2))]
19062 ;; Don't compare memory with zero, load and use a test instead.
19064 [(set (match_operand 0 "flags_reg_operand" "")
19065 (match_operator 1 "compare_operator"
19066 [(match_operand:SI 2 "memory_operand" "")
19068 (match_scratch:SI 3 "r")]
19069 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19070 [(set (match_dup 3) (match_dup 2))
19071 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19074 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19075 ;; Don't split NOTs with a displacement operand, because resulting XOR
19076 ;; will not be pairable anyway.
19078 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19079 ;; represented using a modRM byte. The XOR replacement is long decoded,
19080 ;; so this split helps here as well.
19082 ;; Note: Can't do this as a regular split because we can't get proper
19083 ;; lifetime information then.
19086 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19087 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19089 && peep2_regno_dead_p (0, FLAGS_REG)
19090 && ((TARGET_PENTIUM
19091 && (GET_CODE (operands[0]) != MEM
19092 || !memory_displacement_operand (operands[0], SImode)))
19093 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19094 [(parallel [(set (match_dup 0)
19095 (xor:SI (match_dup 1) (const_int -1)))
19096 (clobber (reg:CC FLAGS_REG))])]
19100 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19101 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19103 && peep2_regno_dead_p (0, FLAGS_REG)
19104 && ((TARGET_PENTIUM
19105 && (GET_CODE (operands[0]) != MEM
19106 || !memory_displacement_operand (operands[0], HImode)))
19107 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19108 [(parallel [(set (match_dup 0)
19109 (xor:HI (match_dup 1) (const_int -1)))
19110 (clobber (reg:CC FLAGS_REG))])]
19114 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19115 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19117 && peep2_regno_dead_p (0, FLAGS_REG)
19118 && ((TARGET_PENTIUM
19119 && (GET_CODE (operands[0]) != MEM
19120 || !memory_displacement_operand (operands[0], QImode)))
19121 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19122 [(parallel [(set (match_dup 0)
19123 (xor:QI (match_dup 1) (const_int -1)))
19124 (clobber (reg:CC FLAGS_REG))])]
19127 ;; Non pairable "test imm, reg" instructions can be translated to
19128 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19129 ;; byte opcode instead of two, have a short form for byte operands),
19130 ;; so do it for other CPUs as well. Given that the value was dead,
19131 ;; this should not create any new dependencies. Pass on the sub-word
19132 ;; versions if we're concerned about partial register stalls.
19135 [(set (match_operand 0 "flags_reg_operand" "")
19136 (match_operator 1 "compare_operator"
19137 [(and:SI (match_operand:SI 2 "register_operand" "")
19138 (match_operand:SI 3 "immediate_operand" ""))
19140 "ix86_match_ccmode (insn, CCNOmode)
19141 && (true_regnum (operands[2]) != 0
19142 || (GET_CODE (operands[3]) == CONST_INT
19143 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19144 && peep2_reg_dead_p (1, operands[2])"
19146 [(set (match_dup 0)
19147 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19150 (and:SI (match_dup 2) (match_dup 3)))])]
19153 ;; We don't need to handle HImode case, because it will be promoted to SImode
19154 ;; on ! TARGET_PARTIAL_REG_STALL
19157 [(set (match_operand 0 "flags_reg_operand" "")
19158 (match_operator 1 "compare_operator"
19159 [(and:QI (match_operand:QI 2 "register_operand" "")
19160 (match_operand:QI 3 "immediate_operand" ""))
19162 "! TARGET_PARTIAL_REG_STALL
19163 && ix86_match_ccmode (insn, CCNOmode)
19164 && true_regnum (operands[2]) != 0
19165 && peep2_reg_dead_p (1, operands[2])"
19167 [(set (match_dup 0)
19168 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19171 (and:QI (match_dup 2) (match_dup 3)))])]
19175 [(set (match_operand 0 "flags_reg_operand" "")
19176 (match_operator 1 "compare_operator"
19179 (match_operand 2 "ext_register_operand" "")
19182 (match_operand 3 "const_int_operand" ""))
19184 "! TARGET_PARTIAL_REG_STALL
19185 && ix86_match_ccmode (insn, CCNOmode)
19186 && true_regnum (operands[2]) != 0
19187 && peep2_reg_dead_p (1, operands[2])"
19188 [(parallel [(set (match_dup 0)
19197 (set (zero_extract:SI (match_dup 2)
19208 ;; Don't do logical operations with memory inputs.
19210 [(match_scratch:SI 2 "r")
19211 (parallel [(set (match_operand:SI 0 "register_operand" "")
19212 (match_operator:SI 3 "arith_or_logical_operator"
19214 (match_operand:SI 1 "memory_operand" "")]))
19215 (clobber (reg:CC FLAGS_REG))])]
19216 "! optimize_size && ! TARGET_READ_MODIFY"
19217 [(set (match_dup 2) (match_dup 1))
19218 (parallel [(set (match_dup 0)
19219 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19220 (clobber (reg:CC FLAGS_REG))])]
19224 [(match_scratch:SI 2 "r")
19225 (parallel [(set (match_operand:SI 0 "register_operand" "")
19226 (match_operator:SI 3 "arith_or_logical_operator"
19227 [(match_operand:SI 1 "memory_operand" "")
19229 (clobber (reg:CC FLAGS_REG))])]
19230 "! optimize_size && ! TARGET_READ_MODIFY"
19231 [(set (match_dup 2) (match_dup 1))
19232 (parallel [(set (match_dup 0)
19233 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19234 (clobber (reg:CC FLAGS_REG))])]
19237 ; Don't do logical operations with memory outputs
19239 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19240 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19241 ; the same decoder scheduling characteristics as the original.
19244 [(match_scratch:SI 2 "r")
19245 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19246 (match_operator:SI 3 "arith_or_logical_operator"
19248 (match_operand:SI 1 "nonmemory_operand" "")]))
19249 (clobber (reg:CC FLAGS_REG))])]
19250 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19251 [(set (match_dup 2) (match_dup 0))
19252 (parallel [(set (match_dup 2)
19253 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19254 (clobber (reg:CC FLAGS_REG))])
19255 (set (match_dup 0) (match_dup 2))]
19259 [(match_scratch:SI 2 "r")
19260 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19261 (match_operator:SI 3 "arith_or_logical_operator"
19262 [(match_operand:SI 1 "nonmemory_operand" "")
19264 (clobber (reg:CC FLAGS_REG))])]
19265 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19266 [(set (match_dup 2) (match_dup 0))
19267 (parallel [(set (match_dup 2)
19268 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19269 (clobber (reg:CC FLAGS_REG))])
19270 (set (match_dup 0) (match_dup 2))]
19273 ;; Attempt to always use XOR for zeroing registers.
19275 [(set (match_operand 0 "register_operand" "")
19276 (match_operand 1 "const0_operand" ""))]
19277 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19278 && (! TARGET_USE_MOV0 || optimize_size)
19279 && GENERAL_REG_P (operands[0])
19280 && peep2_regno_dead_p (0, FLAGS_REG)"
19281 [(parallel [(set (match_dup 0) (const_int 0))
19282 (clobber (reg:CC FLAGS_REG))])]
19284 operands[0] = gen_lowpart (word_mode, operands[0]);
19288 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19290 "(GET_MODE (operands[0]) == QImode
19291 || GET_MODE (operands[0]) == HImode)
19292 && (! TARGET_USE_MOV0 || optimize_size)
19293 && peep2_regno_dead_p (0, FLAGS_REG)"
19294 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19295 (clobber (reg:CC FLAGS_REG))])])
19297 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19299 [(set (match_operand 0 "register_operand" "")
19301 "(GET_MODE (operands[0]) == HImode
19302 || GET_MODE (operands[0]) == SImode
19303 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19304 && (optimize_size || TARGET_PENTIUM)
19305 && peep2_regno_dead_p (0, FLAGS_REG)"
19306 [(parallel [(set (match_dup 0) (const_int -1))
19307 (clobber (reg:CC FLAGS_REG))])]
19308 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19311 ;; Attempt to convert simple leas to adds. These can be created by
19314 [(set (match_operand:SI 0 "register_operand" "")
19315 (plus:SI (match_dup 0)
19316 (match_operand:SI 1 "nonmemory_operand" "")))]
19317 "peep2_regno_dead_p (0, FLAGS_REG)"
19318 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19319 (clobber (reg:CC FLAGS_REG))])]
19323 [(set (match_operand:SI 0 "register_operand" "")
19324 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19325 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19326 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19327 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19328 (clobber (reg:CC FLAGS_REG))])]
19329 "operands[2] = gen_lowpart (SImode, operands[2]);")
19332 [(set (match_operand:DI 0 "register_operand" "")
19333 (plus:DI (match_dup 0)
19334 (match_operand:DI 1 "x86_64_general_operand" "")))]
19335 "peep2_regno_dead_p (0, FLAGS_REG)"
19336 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19337 (clobber (reg:CC FLAGS_REG))])]
19341 [(set (match_operand:SI 0 "register_operand" "")
19342 (mult:SI (match_dup 0)
19343 (match_operand:SI 1 "const_int_operand" "")))]
19344 "exact_log2 (INTVAL (operands[1])) >= 0
19345 && peep2_regno_dead_p (0, FLAGS_REG)"
19346 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19347 (clobber (reg:CC FLAGS_REG))])]
19348 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19351 [(set (match_operand:DI 0 "register_operand" "")
19352 (mult:DI (match_dup 0)
19353 (match_operand:DI 1 "const_int_operand" "")))]
19354 "exact_log2 (INTVAL (operands[1])) >= 0
19355 && peep2_regno_dead_p (0, FLAGS_REG)"
19356 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19357 (clobber (reg:CC FLAGS_REG))])]
19358 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19361 [(set (match_operand:SI 0 "register_operand" "")
19362 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19363 (match_operand:DI 2 "const_int_operand" "")) 0))]
19364 "exact_log2 (INTVAL (operands[2])) >= 0
19365 && REGNO (operands[0]) == REGNO (operands[1])
19366 && peep2_regno_dead_p (0, FLAGS_REG)"
19367 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19368 (clobber (reg:CC FLAGS_REG))])]
19369 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19371 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19372 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19373 ;; many CPUs it is also faster, since special hardware to avoid esp
19374 ;; dependencies is present.
19376 ;; While some of these conversions may be done using splitters, we use peepholes
19377 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19379 ;; Convert prologue esp subtractions to push.
19380 ;; We need register to push. In order to keep verify_flow_info happy we have
19382 ;; - use scratch and clobber it in order to avoid dependencies
19383 ;; - use already live register
19384 ;; We can't use the second way right now, since there is no reliable way how to
19385 ;; verify that given register is live. First choice will also most likely in
19386 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19387 ;; call clobbered registers are dead. We may want to use base pointer as an
19388 ;; alternative when no register is available later.
19391 [(match_scratch:SI 0 "r")
19392 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19393 (clobber (reg:CC FLAGS_REG))
19394 (clobber (mem:BLK (scratch)))])]
19395 "optimize_size || !TARGET_SUB_ESP_4"
19396 [(clobber (match_dup 0))
19397 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19398 (clobber (mem:BLK (scratch)))])])
19401 [(match_scratch:SI 0 "r")
19402 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19403 (clobber (reg:CC FLAGS_REG))
19404 (clobber (mem:BLK (scratch)))])]
19405 "optimize_size || !TARGET_SUB_ESP_8"
19406 [(clobber (match_dup 0))
19407 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19408 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19409 (clobber (mem:BLK (scratch)))])])
19411 ;; Convert esp subtractions to push.
19413 [(match_scratch:SI 0 "r")
19414 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19415 (clobber (reg:CC FLAGS_REG))])]
19416 "optimize_size || !TARGET_SUB_ESP_4"
19417 [(clobber (match_dup 0))
19418 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19421 [(match_scratch:SI 0 "r")
19422 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19423 (clobber (reg:CC FLAGS_REG))])]
19424 "optimize_size || !TARGET_SUB_ESP_8"
19425 [(clobber (match_dup 0))
19426 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19427 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19429 ;; Convert epilogue deallocator to pop.
19431 [(match_scratch:SI 0 "r")
19432 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19433 (clobber (reg:CC FLAGS_REG))
19434 (clobber (mem:BLK (scratch)))])]
19435 "optimize_size || !TARGET_ADD_ESP_4"
19436 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19437 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19438 (clobber (mem:BLK (scratch)))])]
19441 ;; Two pops case is tricky, since pop causes dependency on destination register.
19442 ;; We use two registers if available.
19444 [(match_scratch:SI 0 "r")
19445 (match_scratch:SI 1 "r")
19446 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19447 (clobber (reg:CC FLAGS_REG))
19448 (clobber (mem:BLK (scratch)))])]
19449 "optimize_size || !TARGET_ADD_ESP_8"
19450 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19451 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19452 (clobber (mem:BLK (scratch)))])
19453 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19454 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19458 [(match_scratch:SI 0 "r")
19459 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19460 (clobber (reg:CC FLAGS_REG))
19461 (clobber (mem:BLK (scratch)))])]
19463 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19464 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19465 (clobber (mem:BLK (scratch)))])
19466 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19467 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19470 ;; Convert esp additions to pop.
19472 [(match_scratch:SI 0 "r")
19473 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19474 (clobber (reg:CC FLAGS_REG))])]
19476 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19477 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19480 ;; Two pops case is tricky, since pop causes dependency on destination register.
19481 ;; We use two registers if available.
19483 [(match_scratch:SI 0 "r")
19484 (match_scratch:SI 1 "r")
19485 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19486 (clobber (reg:CC FLAGS_REG))])]
19488 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19489 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19490 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19491 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19495 [(match_scratch:SI 0 "r")
19496 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19497 (clobber (reg:CC FLAGS_REG))])]
19499 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19500 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19501 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19502 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19505 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19506 ;; required and register dies. Similarly for 128 to plus -128.
19508 [(set (match_operand 0 "flags_reg_operand" "")
19509 (match_operator 1 "compare_operator"
19510 [(match_operand 2 "register_operand" "")
19511 (match_operand 3 "const_int_operand" "")]))]
19512 "(INTVAL (operands[3]) == -1
19513 || INTVAL (operands[3]) == 1
19514 || INTVAL (operands[3]) == 128)
19515 && ix86_match_ccmode (insn, CCGCmode)
19516 && peep2_reg_dead_p (1, operands[2])"
19517 [(parallel [(set (match_dup 0)
19518 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19519 (clobber (match_dup 2))])]
19523 [(match_scratch:DI 0 "r")
19524 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19525 (clobber (reg:CC FLAGS_REG))
19526 (clobber (mem:BLK (scratch)))])]
19527 "optimize_size || !TARGET_SUB_ESP_4"
19528 [(clobber (match_dup 0))
19529 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19530 (clobber (mem:BLK (scratch)))])])
19533 [(match_scratch:DI 0 "r")
19534 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19535 (clobber (reg:CC FLAGS_REG))
19536 (clobber (mem:BLK (scratch)))])]
19537 "optimize_size || !TARGET_SUB_ESP_8"
19538 [(clobber (match_dup 0))
19539 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19540 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19541 (clobber (mem:BLK (scratch)))])])
19543 ;; Convert esp subtractions to push.
19545 [(match_scratch:DI 0 "r")
19546 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19547 (clobber (reg:CC FLAGS_REG))])]
19548 "optimize_size || !TARGET_SUB_ESP_4"
19549 [(clobber (match_dup 0))
19550 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19553 [(match_scratch:DI 0 "r")
19554 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19555 (clobber (reg:CC FLAGS_REG))])]
19556 "optimize_size || !TARGET_SUB_ESP_8"
19557 [(clobber (match_dup 0))
19558 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19559 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19561 ;; Convert epilogue deallocator to pop.
19563 [(match_scratch:DI 0 "r")
19564 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19565 (clobber (reg:CC FLAGS_REG))
19566 (clobber (mem:BLK (scratch)))])]
19567 "optimize_size || !TARGET_ADD_ESP_4"
19568 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19569 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19570 (clobber (mem:BLK (scratch)))])]
19573 ;; Two pops case is tricky, since pop causes dependency on destination register.
19574 ;; We use two registers if available.
19576 [(match_scratch:DI 0 "r")
19577 (match_scratch:DI 1 "r")
19578 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19579 (clobber (reg:CC FLAGS_REG))
19580 (clobber (mem:BLK (scratch)))])]
19581 "optimize_size || !TARGET_ADD_ESP_8"
19582 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19583 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19584 (clobber (mem:BLK (scratch)))])
19585 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19586 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19590 [(match_scratch:DI 0 "r")
19591 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19592 (clobber (reg:CC FLAGS_REG))
19593 (clobber (mem:BLK (scratch)))])]
19595 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19596 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19597 (clobber (mem:BLK (scratch)))])
19598 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19599 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19602 ;; Convert esp additions to pop.
19604 [(match_scratch:DI 0 "r")
19605 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19606 (clobber (reg:CC FLAGS_REG))])]
19608 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19609 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19612 ;; Two pops case is tricky, since pop causes dependency on destination register.
19613 ;; We use two registers if available.
19615 [(match_scratch:DI 0 "r")
19616 (match_scratch:DI 1 "r")
19617 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19618 (clobber (reg:CC FLAGS_REG))])]
19620 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19621 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19622 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19623 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19627 [(match_scratch:DI 0 "r")
19628 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19629 (clobber (reg:CC FLAGS_REG))])]
19631 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19632 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19633 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19634 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19637 ;; Convert imul by three, five and nine into lea
19640 [(set (match_operand:SI 0 "register_operand" "")
19641 (mult:SI (match_operand:SI 1 "register_operand" "")
19642 (match_operand:SI 2 "const_int_operand" "")))
19643 (clobber (reg:CC FLAGS_REG))])]
19644 "INTVAL (operands[2]) == 3
19645 || INTVAL (operands[2]) == 5
19646 || INTVAL (operands[2]) == 9"
19647 [(set (match_dup 0)
19648 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19650 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19654 [(set (match_operand:SI 0 "register_operand" "")
19655 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19656 (match_operand:SI 2 "const_int_operand" "")))
19657 (clobber (reg:CC FLAGS_REG))])]
19659 && (INTVAL (operands[2]) == 3
19660 || INTVAL (operands[2]) == 5
19661 || INTVAL (operands[2]) == 9)"
19662 [(set (match_dup 0) (match_dup 1))
19664 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19666 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19670 [(set (match_operand:DI 0 "register_operand" "")
19671 (mult:DI (match_operand:DI 1 "register_operand" "")
19672 (match_operand:DI 2 "const_int_operand" "")))
19673 (clobber (reg:CC FLAGS_REG))])]
19675 && (INTVAL (operands[2]) == 3
19676 || INTVAL (operands[2]) == 5
19677 || INTVAL (operands[2]) == 9)"
19678 [(set (match_dup 0)
19679 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19681 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19685 [(set (match_operand:DI 0 "register_operand" "")
19686 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19687 (match_operand:DI 2 "const_int_operand" "")))
19688 (clobber (reg:CC FLAGS_REG))])]
19691 && (INTVAL (operands[2]) == 3
19692 || INTVAL (operands[2]) == 5
19693 || INTVAL (operands[2]) == 9)"
19694 [(set (match_dup 0) (match_dup 1))
19696 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19698 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19700 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19701 ;; imul $32bit_imm, reg, reg is direct decoded.
19703 [(match_scratch:DI 3 "r")
19704 (parallel [(set (match_operand:DI 0 "register_operand" "")
19705 (mult:DI (match_operand:DI 1 "memory_operand" "")
19706 (match_operand:DI 2 "immediate_operand" "")))
19707 (clobber (reg:CC FLAGS_REG))])]
19708 "TARGET_K8 && !optimize_size
19709 && (GET_CODE (operands[2]) != CONST_INT
19710 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19711 [(set (match_dup 3) (match_dup 1))
19712 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19713 (clobber (reg:CC FLAGS_REG))])]
19717 [(match_scratch:SI 3 "r")
19718 (parallel [(set (match_operand:SI 0 "register_operand" "")
19719 (mult:SI (match_operand:SI 1 "memory_operand" "")
19720 (match_operand:SI 2 "immediate_operand" "")))
19721 (clobber (reg:CC FLAGS_REG))])]
19722 "TARGET_K8 && !optimize_size
19723 && (GET_CODE (operands[2]) != CONST_INT
19724 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19725 [(set (match_dup 3) (match_dup 1))
19726 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19727 (clobber (reg:CC FLAGS_REG))])]
19731 [(match_scratch:SI 3 "r")
19732 (parallel [(set (match_operand:DI 0 "register_operand" "")
19734 (mult:SI (match_operand:SI 1 "memory_operand" "")
19735 (match_operand:SI 2 "immediate_operand" ""))))
19736 (clobber (reg:CC FLAGS_REG))])]
19737 "TARGET_K8 && !optimize_size
19738 && (GET_CODE (operands[2]) != CONST_INT
19739 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19740 [(set (match_dup 3) (match_dup 1))
19741 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19742 (clobber (reg:CC FLAGS_REG))])]
19745 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19746 ;; Convert it into imul reg, reg
19747 ;; It would be better to force assembler to encode instruction using long
19748 ;; immediate, but there is apparently no way to do so.
19750 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19751 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19752 (match_operand:DI 2 "const_int_operand" "")))
19753 (clobber (reg:CC FLAGS_REG))])
19754 (match_scratch:DI 3 "r")]
19755 "TARGET_K8 && !optimize_size
19756 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19757 [(set (match_dup 3) (match_dup 2))
19758 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19759 (clobber (reg:CC FLAGS_REG))])]
19761 if (!rtx_equal_p (operands[0], operands[1]))
19762 emit_move_insn (operands[0], operands[1]);
19766 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19767 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19768 (match_operand:SI 2 "const_int_operand" "")))
19769 (clobber (reg:CC FLAGS_REG))])
19770 (match_scratch:SI 3 "r")]
19771 "TARGET_K8 && !optimize_size
19772 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19773 [(set (match_dup 3) (match_dup 2))
19774 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19775 (clobber (reg:CC FLAGS_REG))])]
19777 if (!rtx_equal_p (operands[0], operands[1]))
19778 emit_move_insn (operands[0], operands[1]);
19782 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19783 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19784 (match_operand:HI 2 "immediate_operand" "")))
19785 (clobber (reg:CC FLAGS_REG))])
19786 (match_scratch:HI 3 "r")]
19787 "TARGET_K8 && !optimize_size"
19788 [(set (match_dup 3) (match_dup 2))
19789 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19790 (clobber (reg:CC FLAGS_REG))])]
19792 if (!rtx_equal_p (operands[0], operands[1]))
19793 emit_move_insn (operands[0], operands[1]);
19796 ;; After splitting up read-modify operations, array accesses with memory
19797 ;; operands might end up in form:
19799 ;; movl 4(%esp), %edx
19801 ;; instead of pre-splitting:
19803 ;; addl 4(%esp), %eax
19805 ;; movl 4(%esp), %edx
19806 ;; leal (%edx,%eax,4), %eax
19809 [(parallel [(set (match_operand 0 "register_operand" "")
19810 (ashift (match_operand 1 "register_operand" "")
19811 (match_operand 2 "const_int_operand" "")))
19812 (clobber (reg:CC FLAGS_REG))])
19813 (set (match_operand 3 "register_operand")
19814 (match_operand 4 "x86_64_general_operand" ""))
19815 (parallel [(set (match_operand 5 "register_operand" "")
19816 (plus (match_operand 6 "register_operand" "")
19817 (match_operand 7 "register_operand" "")))
19818 (clobber (reg:CC FLAGS_REG))])]
19819 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19820 /* Validate MODE for lea. */
19821 && ((!TARGET_PARTIAL_REG_STALL
19822 && (GET_MODE (operands[0]) == QImode
19823 || GET_MODE (operands[0]) == HImode))
19824 || GET_MODE (operands[0]) == SImode
19825 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19826 /* We reorder load and the shift. */
19827 && !rtx_equal_p (operands[1], operands[3])
19828 && !reg_overlap_mentioned_p (operands[0], operands[4])
19829 /* Last PLUS must consist of operand 0 and 3. */
19830 && !rtx_equal_p (operands[0], operands[3])
19831 && (rtx_equal_p (operands[3], operands[6])
19832 || rtx_equal_p (operands[3], operands[7]))
19833 && (rtx_equal_p (operands[0], operands[6])
19834 || rtx_equal_p (operands[0], operands[7]))
19835 /* The intermediate operand 0 must die or be same as output. */
19836 && (rtx_equal_p (operands[0], operands[5])
19837 || peep2_reg_dead_p (3, operands[0]))"
19838 [(set (match_dup 3) (match_dup 4))
19839 (set (match_dup 0) (match_dup 1))]
19841 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19842 int scale = 1 << INTVAL (operands[2]);
19843 rtx index = gen_lowpart (Pmode, operands[1]);
19844 rtx base = gen_lowpart (Pmode, operands[3]);
19845 rtx dest = gen_lowpart (mode, operands[5]);
19847 operands[1] = gen_rtx_PLUS (Pmode, base,
19848 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19850 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19851 operands[0] = dest;
19854 ;; Call-value patterns last so that the wildcard operand does not
19855 ;; disrupt insn-recog's switch tables.
19857 (define_insn "*call_value_pop_0"
19858 [(set (match_operand 0 "" "")
19859 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19860 (match_operand:SI 2 "" "")))
19861 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19862 (match_operand:SI 3 "immediate_operand" "")))]
19865 if (SIBLING_CALL_P (insn))
19868 return "call\t%P1";
19870 [(set_attr "type" "callv")])
19872 (define_insn "*call_value_pop_1"
19873 [(set (match_operand 0 "" "")
19874 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19875 (match_operand:SI 2 "" "")))
19876 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19877 (match_operand:SI 3 "immediate_operand" "i")))]
19880 if (constant_call_address_operand (operands[1], Pmode))
19882 if (SIBLING_CALL_P (insn))
19885 return "call\t%P1";
19887 if (SIBLING_CALL_P (insn))
19890 return "call\t%A1";
19892 [(set_attr "type" "callv")])
19894 (define_insn "*call_value_0"
19895 [(set (match_operand 0 "" "")
19896 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19897 (match_operand:SI 2 "" "")))]
19900 if (SIBLING_CALL_P (insn))
19903 return "call\t%P1";
19905 [(set_attr "type" "callv")])
19907 (define_insn "*call_value_0_rex64"
19908 [(set (match_operand 0 "" "")
19909 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19910 (match_operand:DI 2 "const_int_operand" "")))]
19913 if (SIBLING_CALL_P (insn))
19916 return "call\t%P1";
19918 [(set_attr "type" "callv")])
19920 (define_insn "*call_value_1"
19921 [(set (match_operand 0 "" "")
19922 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19923 (match_operand:SI 2 "" "")))]
19924 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19926 if (constant_call_address_operand (operands[1], Pmode))
19927 return "call\t%P1";
19928 return "call\t%A1";
19930 [(set_attr "type" "callv")])
19932 (define_insn "*sibcall_value_1"
19933 [(set (match_operand 0 "" "")
19934 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19935 (match_operand:SI 2 "" "")))]
19936 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19938 if (constant_call_address_operand (operands[1], Pmode))
19942 [(set_attr "type" "callv")])
19944 (define_insn "*call_value_1_rex64"
19945 [(set (match_operand 0 "" "")
19946 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19947 (match_operand:DI 2 "" "")))]
19948 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19950 if (constant_call_address_operand (operands[1], Pmode))
19951 return "call\t%P1";
19952 return "call\t%A1";
19954 [(set_attr "type" "callv")])
19956 (define_insn "*sibcall_value_1_rex64"
19957 [(set (match_operand 0 "" "")
19958 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19959 (match_operand:DI 2 "" "")))]
19960 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19962 [(set_attr "type" "callv")])
19964 (define_insn "*sibcall_value_1_rex64_v"
19965 [(set (match_operand 0 "" "")
19966 (call (mem:QI (reg:DI 40))
19967 (match_operand:DI 1 "" "")))]
19968 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19970 [(set_attr "type" "callv")])
19972 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19973 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19974 ;; caught for use by garbage collectors and the like. Using an insn that
19975 ;; maps to SIGILL makes it more likely the program will rightfully die.
19976 ;; Keeping with tradition, "6" is in honor of #UD.
19977 (define_insn "trap"
19978 [(trap_if (const_int 1) (const_int 6))]
19981 [(set_attr "length" "2")])
19983 (define_expand "sse_prologue_save"
19984 [(parallel [(set (match_operand:BLK 0 "" "")
19985 (unspec:BLK [(reg:DI 21)
19992 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19993 (use (match_operand:DI 1 "register_operand" ""))
19994 (use (match_operand:DI 2 "immediate_operand" ""))
19995 (use (label_ref:DI (match_operand 3 "" "")))])]
19999 (define_insn "*sse_prologue_save_insn"
20000 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20001 (match_operand:DI 4 "const_int_operand" "n")))
20002 (unspec:BLK [(reg:DI 21)
20009 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20010 (use (match_operand:DI 1 "register_operand" "r"))
20011 (use (match_operand:DI 2 "const_int_operand" "i"))
20012 (use (label_ref:DI (match_operand 3 "" "X")))]
20014 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20015 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20019 operands[0] = gen_rtx_MEM (Pmode,
20020 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20021 output_asm_insn (\"jmp\\t%A1\", operands);
20022 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20024 operands[4] = adjust_address (operands[0], DImode, i*16);
20025 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20026 PUT_MODE (operands[4], TImode);
20027 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20028 output_asm_insn (\"rex\", operands);
20029 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20031 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20032 CODE_LABEL_NUMBER (operands[3]));
20036 [(set_attr "type" "other")
20037 (set_attr "length_immediate" "0")
20038 (set_attr "length_address" "0")
20039 (set_attr "length" "135")
20040 (set_attr "memory" "store")
20041 (set_attr "modrm" "0")
20042 (set_attr "mode" "DI")])
20044 (define_expand "prefetch"
20045 [(prefetch (match_operand 0 "address_operand" "")
20046 (match_operand:SI 1 "const_int_operand" "")
20047 (match_operand:SI 2 "const_int_operand" ""))]
20048 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20050 int rw = INTVAL (operands[1]);
20051 int locality = INTVAL (operands[2]);
20053 gcc_assert (rw == 0 || rw == 1);
20054 gcc_assert (locality >= 0 && locality <= 3);
20055 gcc_assert (GET_MODE (operands[0]) == Pmode
20056 || GET_MODE (operands[0]) == VOIDmode);
20058 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20059 supported by SSE counterpart or the SSE prefetch is not available
20060 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20062 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20063 operands[2] = GEN_INT (3);
20065 operands[1] = const0_rtx;
20068 (define_insn "*prefetch_sse"
20069 [(prefetch (match_operand:SI 0 "address_operand" "p")
20071 (match_operand:SI 1 "const_int_operand" ""))]
20072 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20074 static const char * const patterns[4] = {
20075 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20078 int locality = INTVAL (operands[1]);
20079 gcc_assert (locality >= 0 && locality <= 3);
20081 return patterns[locality];
20083 [(set_attr "type" "sse")
20084 (set_attr "memory" "none")])
20086 (define_insn "*prefetch_sse_rex"
20087 [(prefetch (match_operand:DI 0 "address_operand" "p")
20089 (match_operand:SI 1 "const_int_operand" ""))]
20090 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20092 static const char * const patterns[4] = {
20093 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20096 int locality = INTVAL (operands[1]);
20097 gcc_assert (locality >= 0 && locality <= 3);
20099 return patterns[locality];
20101 [(set_attr "type" "sse")
20102 (set_attr "memory" "none")])
20104 (define_insn "*prefetch_3dnow"
20105 [(prefetch (match_operand:SI 0 "address_operand" "p")
20106 (match_operand:SI 1 "const_int_operand" "n")
20108 "TARGET_3DNOW && !TARGET_64BIT"
20110 if (INTVAL (operands[1]) == 0)
20111 return "prefetch\t%a0";
20113 return "prefetchw\t%a0";
20115 [(set_attr "type" "mmx")
20116 (set_attr "memory" "none")])
20118 (define_insn "*prefetch_3dnow_rex"
20119 [(prefetch (match_operand:DI 0 "address_operand" "p")
20120 (match_operand:SI 1 "const_int_operand" "n")
20122 "TARGET_3DNOW && TARGET_64BIT"
20124 if (INTVAL (operands[1]) == 0)
20125 return "prefetch\t%a0";
20127 return "prefetchw\t%a0";
20129 [(set_attr "type" "mmx")
20130 (set_attr "memory" "none")])
20132 (define_expand "stack_protect_set"
20133 [(match_operand 0 "memory_operand" "")
20134 (match_operand 1 "memory_operand" "")]
20137 #ifdef TARGET_THREAD_SSP_OFFSET
20139 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20140 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20142 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20143 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20146 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20148 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20153 (define_insn "stack_protect_set_si"
20154 [(set (match_operand:SI 0 "memory_operand" "=m")
20155 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20156 (set (match_scratch:SI 2 "=&r") (const_int 0))
20157 (clobber (reg:CC FLAGS_REG))]
20159 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20160 [(set_attr "type" "multi")])
20162 (define_insn "stack_protect_set_di"
20163 [(set (match_operand:DI 0 "memory_operand" "=m")
20164 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20165 (set (match_scratch:DI 2 "=&r") (const_int 0))
20166 (clobber (reg:CC FLAGS_REG))]
20168 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20169 [(set_attr "type" "multi")])
20171 (define_insn "stack_tls_protect_set_si"
20172 [(set (match_operand:SI 0 "memory_operand" "=m")
20173 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20174 (set (match_scratch:SI 2 "=&r") (const_int 0))
20175 (clobber (reg:CC FLAGS_REG))]
20177 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20178 [(set_attr "type" "multi")])
20180 (define_insn "stack_tls_protect_set_di"
20181 [(set (match_operand:DI 0 "memory_operand" "=m")
20182 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20183 (set (match_scratch:DI 2 "=&r") (const_int 0))
20184 (clobber (reg:CC FLAGS_REG))]
20186 "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20187 [(set_attr "type" "multi")])
20189 (define_expand "stack_protect_test"
20190 [(match_operand 0 "memory_operand" "")
20191 (match_operand 1 "memory_operand" "")
20192 (match_operand 2 "" "")]
20195 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20196 ix86_compare_op0 = operands[0];
20197 ix86_compare_op1 = operands[1];
20198 ix86_compare_emitted = flags;
20200 #ifdef TARGET_THREAD_SSP_OFFSET
20202 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20203 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20205 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20206 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20209 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20211 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20213 emit_jump_insn (gen_beq (operands[2]));
20217 (define_insn "stack_protect_test_si"
20218 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20219 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20220 (match_operand:SI 2 "memory_operand" "m")]
20222 (clobber (match_scratch:SI 3 "=&r"))]
20224 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20225 [(set_attr "type" "multi")])
20227 (define_insn "stack_protect_test_di"
20228 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20229 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20230 (match_operand:DI 2 "memory_operand" "m")]
20232 (clobber (match_scratch:DI 3 "=&r"))]
20234 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20235 [(set_attr "type" "multi")])
20237 (define_insn "stack_tls_protect_test_si"
20238 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20239 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20240 (match_operand:SI 2 "const_int_operand" "i")]
20241 UNSPEC_SP_TLS_TEST))
20242 (clobber (match_scratch:SI 3 "=r"))]
20244 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20245 [(set_attr "type" "multi")])
20247 (define_insn "stack_tls_protect_test_di"
20248 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20249 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20250 (match_operand:DI 2 "const_int_operand" "i")]
20251 UNSPEC_SP_TLS_TEST))
20252 (clobber (match_scratch:DI 3 "=r"))]
20254 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20255 [(set_attr "type" "multi")])
20259 (include "sync.md")