1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 30)
98 (UNSPEC_NOP 38) ; prevents combiner cleverness
109 ; Generic math support
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
125 (UNSPEC_FRNDINT_FLOOR 70)
126 (UNSPEC_FRNDINT_CEIL 71)
127 (UNSPEC_FRNDINT_TRUNC 72)
128 (UNSPEC_FRNDINT_MASK_PM 73)
129 (UNSPEC_FIST_FLOOR 74)
130 (UNSPEC_FIST_CEIL 75)
132 ; x87 Double output FP
133 (UNSPEC_SINCOS_COS 80)
134 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
149 (UNSPEC_SP_TLS_SET 102)
150 (UNSPEC_SP_TLS_TEST 103)
160 (UNSPEC_INSERTQI 132)
165 [(UNSPECV_BLOCKAGE 0)
166 (UNSPECV_STACK_PROBE 1)
175 (UNSPECV_CMPXCHG_1 10)
176 (UNSPECV_CMPXCHG_2 11)
181 ;; Registers by name.
190 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
193 ;; In C guard expressions, put expressions which may be compile-time
194 ;; constants first. This allows for better optimization. For
195 ;; example, write "TARGET_64BIT && reload_completed", not
196 ;; "reload_completed && TARGET_64BIT".
199 ;; Processor type. This attribute must exactly match the processor_type
200 ;; enumeration in i386.h.
201 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
202 nocona,core2,generic32,generic64,amdfam10"
203 (const (symbol_ref "ix86_tune")))
205 ;; A basic instruction type. Refinements due to arguments to be
206 ;; provided in other attributes.
209 alu,alu1,negnot,imov,imovx,lea,
210 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
211 icmp,test,ibr,setcc,icmov,
212 push,pop,call,callv,leave,
214 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
215 sselog,sselog1,sseiadd,sseishft,sseimul,
216 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
217 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
218 (const_string "other"))
220 ;; Main data type used by the insn
222 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
223 (const_string "unknown"))
225 ;; The CPU unit operations uses.
226 (define_attr "unit" "integer,i387,sse,mmx,unknown"
227 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
228 (const_string "i387")
229 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
230 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
232 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
234 (eq_attr "type" "other")
235 (const_string "unknown")]
236 (const_string "integer")))
238 ;; The (bounding maximum) length of an instruction immediate.
239 (define_attr "length_immediate" ""
240 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave,
243 (eq_attr "unit" "i387,sse,mmx")
245 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
247 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
248 (eq_attr "type" "imov,test")
249 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
250 (eq_attr "type" "call")
251 (if_then_else (match_operand 0 "constant_call_address_operand" "")
254 (eq_attr "type" "callv")
255 (if_then_else (match_operand 1 "constant_call_address_operand" "")
258 ;; We don't know the size before shorten_branches. Expect
259 ;; the instruction to fit for better scheduling.
260 (eq_attr "type" "ibr")
263 (symbol_ref "/* Update immediate_length and other attributes! */
264 gcc_unreachable (),1")))
266 ;; The (bounding maximum) length of an instruction address.
267 (define_attr "length_address" ""
268 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
270 (and (eq_attr "type" "call")
271 (match_operand 0 "constant_call_address_operand" ""))
273 (and (eq_attr "type" "callv")
274 (match_operand 1 "constant_call_address_operand" ""))
277 (symbol_ref "ix86_attr_length_address_default (insn)")))
279 ;; Set when length prefix is used.
280 (define_attr "prefix_data16" ""
281 (if_then_else (ior (eq_attr "mode" "HI")
282 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
286 ;; Set when string REP prefix is used.
287 (define_attr "prefix_rep" ""
288 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
292 ;; Set when 0f opcode prefix is used.
293 (define_attr "prefix_0f" ""
295 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
296 (eq_attr "unit" "sse,mmx"))
300 ;; Set when REX opcode prefix is used.
301 (define_attr "prefix_rex" ""
302 (cond [(and (eq_attr "mode" "DI")
303 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
305 (and (eq_attr "mode" "QI")
306 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
309 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
315 ;; Set when modrm byte is used.
316 (define_attr "modrm" ""
317 (cond [(eq_attr "type" "str,cld,leave")
319 (eq_attr "unit" "i387")
321 (and (eq_attr "type" "incdec")
322 (ior (match_operand:SI 1 "register_operand" "")
323 (match_operand:HI 1 "register_operand" "")))
325 (and (eq_attr "type" "push")
326 (not (match_operand 1 "memory_operand" "")))
328 (and (eq_attr "type" "pop")
329 (not (match_operand 0 "memory_operand" "")))
331 (and (eq_attr "type" "imov")
332 (ior (and (match_operand 0 "register_operand" "")
333 (match_operand 1 "immediate_operand" ""))
334 (ior (and (match_operand 0 "ax_reg_operand" "")
335 (match_operand 1 "memory_displacement_only_operand" ""))
336 (and (match_operand 0 "memory_displacement_only_operand" "")
337 (match_operand 1 "ax_reg_operand" "")))))
339 (and (eq_attr "type" "call")
340 (match_operand 0 "constant_call_address_operand" ""))
342 (and (eq_attr "type" "callv")
343 (match_operand 1 "constant_call_address_operand" ""))
348 ;; The (bounding maximum) length of an instruction in bytes.
349 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
350 ;; Later we may want to split them and compute proper length as for
352 (define_attr "length" ""
353 (cond [(eq_attr "type" "other,multi,fistp,frndint")
355 (eq_attr "type" "fcmp")
357 (eq_attr "unit" "i387")
359 (plus (attr "prefix_data16")
360 (attr "length_address")))]
361 (plus (plus (attr "modrm")
362 (plus (attr "prefix_0f")
363 (plus (attr "prefix_rex")
365 (plus (attr "prefix_rep")
366 (plus (attr "prefix_data16")
367 (plus (attr "length_immediate")
368 (attr "length_address")))))))
370 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
371 ;; `store' if there is a simple memory reference therein, or `unknown'
372 ;; if the instruction is complex.
374 (define_attr "memory" "none,load,store,both,unknown"
375 (cond [(eq_attr "type" "other,multi,str")
376 (const_string "unknown")
377 (eq_attr "type" "lea,fcmov,fpspc,cld")
378 (const_string "none")
379 (eq_attr "type" "fistp,leave")
380 (const_string "both")
381 (eq_attr "type" "frndint")
382 (const_string "load")
383 (eq_attr "type" "push")
384 (if_then_else (match_operand 1 "memory_operand" "")
385 (const_string "both")
386 (const_string "store"))
387 (eq_attr "type" "pop")
388 (if_then_else (match_operand 0 "memory_operand" "")
389 (const_string "both")
390 (const_string "load"))
391 (eq_attr "type" "setcc")
392 (if_then_else (match_operand 0 "memory_operand" "")
393 (const_string "store")
394 (const_string "none"))
395 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
396 (if_then_else (ior (match_operand 0 "memory_operand" "")
397 (match_operand 1 "memory_operand" ""))
398 (const_string "load")
399 (const_string "none"))
400 (eq_attr "type" "ibr")
401 (if_then_else (match_operand 0 "memory_operand" "")
402 (const_string "load")
403 (const_string "none"))
404 (eq_attr "type" "call")
405 (if_then_else (match_operand 0 "constant_call_address_operand" "")
406 (const_string "none")
407 (const_string "load"))
408 (eq_attr "type" "callv")
409 (if_then_else (match_operand 1 "constant_call_address_operand" "")
410 (const_string "none")
411 (const_string "load"))
412 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
413 (match_operand 1 "memory_operand" ""))
414 (const_string "both")
415 (and (match_operand 0 "memory_operand" "")
416 (match_operand 1 "memory_operand" ""))
417 (const_string "both")
418 (match_operand 0 "memory_operand" "")
419 (const_string "store")
420 (match_operand 1 "memory_operand" "")
421 (const_string "load")
423 "!alu1,negnot,ishift1,
424 imov,imovx,icmp,test,bitmanip,
426 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
427 mmx,mmxmov,mmxcmp,mmxcvt")
428 (match_operand 2 "memory_operand" ""))
429 (const_string "load")
430 (and (eq_attr "type" "icmov")
431 (match_operand 3 "memory_operand" ""))
432 (const_string "load")
434 (const_string "none")))
436 ;; Indicates if an instruction has both an immediate and a displacement.
438 (define_attr "imm_disp" "false,true,unknown"
439 (cond [(eq_attr "type" "other,multi")
440 (const_string "unknown")
441 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
442 (and (match_operand 0 "memory_displacement_operand" "")
443 (match_operand 1 "immediate_operand" "")))
444 (const_string "true")
445 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
446 (and (match_operand 0 "memory_displacement_operand" "")
447 (match_operand 2 "immediate_operand" "")))
448 (const_string "true")
450 (const_string "false")))
452 ;; Indicates if an FP operation has an integer source.
454 (define_attr "fp_int_src" "false,true"
455 (const_string "false"))
457 ;; Defines rounding mode of an FP operation.
459 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
460 (const_string "any"))
462 ;; Describe a user's asm statement.
463 (define_asm_attributes
464 [(set_attr "length" "128")
465 (set_attr "type" "multi")])
467 ;; All x87 floating point modes
468 (define_mode_macro X87MODEF [SF DF XF])
470 ;; All integer modes handled by x87 fisttp operator.
471 (define_mode_macro X87MODEI [HI SI DI])
473 ;; All integer modes handled by integer x87 operators.
474 (define_mode_macro X87MODEI12 [HI SI])
476 ;; All SSE floating point modes
477 (define_mode_macro SSEMODEF [SF DF])
479 ;; All integer modes handled by SSE cvtts?2si* operators.
480 (define_mode_macro SSEMODEI24 [SI DI])
483 ;; Scheduling descriptions
485 (include "pentium.md")
488 (include "athlon.md")
492 ;; Operand and operator predicates and constraints
494 (include "predicates.md")
495 (include "constraints.md")
498 ;; Compare instructions.
500 ;; All compare insns have expanders that save the operands away without
501 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
502 ;; after the cmp) will actually emit the cmpM.
504 (define_expand "cmpti"
505 [(set (reg:CC FLAGS_REG)
506 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
507 (match_operand:TI 1 "x86_64_general_operand" "")))]
510 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
511 operands[0] = force_reg (TImode, operands[0]);
512 ix86_compare_op0 = operands[0];
513 ix86_compare_op1 = operands[1];
517 (define_expand "cmpdi"
518 [(set (reg:CC FLAGS_REG)
519 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
520 (match_operand:DI 1 "x86_64_general_operand" "")))]
523 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
524 operands[0] = force_reg (DImode, operands[0]);
525 ix86_compare_op0 = operands[0];
526 ix86_compare_op1 = operands[1];
530 (define_expand "cmpsi"
531 [(set (reg:CC FLAGS_REG)
532 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
533 (match_operand:SI 1 "general_operand" "")))]
536 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
537 operands[0] = force_reg (SImode, operands[0]);
538 ix86_compare_op0 = operands[0];
539 ix86_compare_op1 = operands[1];
543 (define_expand "cmphi"
544 [(set (reg:CC FLAGS_REG)
545 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
546 (match_operand:HI 1 "general_operand" "")))]
549 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
550 operands[0] = force_reg (HImode, operands[0]);
551 ix86_compare_op0 = operands[0];
552 ix86_compare_op1 = operands[1];
556 (define_expand "cmpqi"
557 [(set (reg:CC FLAGS_REG)
558 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
559 (match_operand:QI 1 "general_operand" "")))]
562 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
563 operands[0] = force_reg (QImode, operands[0]);
564 ix86_compare_op0 = operands[0];
565 ix86_compare_op1 = operands[1];
569 (define_insn "cmpdi_ccno_1_rex64"
570 [(set (reg FLAGS_REG)
571 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
572 (match_operand:DI 1 "const0_operand" "n,n")))]
573 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
575 test{q}\t{%0, %0|%0, %0}
576 cmp{q}\t{%1, %0|%0, %1}"
577 [(set_attr "type" "test,icmp")
578 (set_attr "length_immediate" "0,1")
579 (set_attr "mode" "DI")])
581 (define_insn "*cmpdi_minus_1_rex64"
582 [(set (reg FLAGS_REG)
583 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
584 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
586 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
587 "cmp{q}\t{%1, %0|%0, %1}"
588 [(set_attr "type" "icmp")
589 (set_attr "mode" "DI")])
591 (define_expand "cmpdi_1_rex64"
592 [(set (reg:CC FLAGS_REG)
593 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
594 (match_operand:DI 1 "general_operand" "")))]
598 (define_insn "cmpdi_1_insn_rex64"
599 [(set (reg FLAGS_REG)
600 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
601 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
602 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
603 "cmp{q}\t{%1, %0|%0, %1}"
604 [(set_attr "type" "icmp")
605 (set_attr "mode" "DI")])
608 (define_insn "*cmpsi_ccno_1"
609 [(set (reg FLAGS_REG)
610 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
611 (match_operand:SI 1 "const0_operand" "n,n")))]
612 "ix86_match_ccmode (insn, CCNOmode)"
614 test{l}\t{%0, %0|%0, %0}
615 cmp{l}\t{%1, %0|%0, %1}"
616 [(set_attr "type" "test,icmp")
617 (set_attr "length_immediate" "0,1")
618 (set_attr "mode" "SI")])
620 (define_insn "*cmpsi_minus_1"
621 [(set (reg FLAGS_REG)
622 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623 (match_operand:SI 1 "general_operand" "ri,mr"))
625 "ix86_match_ccmode (insn, CCGOCmode)"
626 "cmp{l}\t{%1, %0|%0, %1}"
627 [(set_attr "type" "icmp")
628 (set_attr "mode" "SI")])
630 (define_expand "cmpsi_1"
631 [(set (reg:CC FLAGS_REG)
632 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
633 (match_operand:SI 1 "general_operand" "ri,mr")))]
637 (define_insn "*cmpsi_1_insn"
638 [(set (reg FLAGS_REG)
639 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
640 (match_operand:SI 1 "general_operand" "ri,mr")))]
641 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
642 && ix86_match_ccmode (insn, CCmode)"
643 "cmp{l}\t{%1, %0|%0, %1}"
644 [(set_attr "type" "icmp")
645 (set_attr "mode" "SI")])
647 (define_insn "*cmphi_ccno_1"
648 [(set (reg FLAGS_REG)
649 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
650 (match_operand:HI 1 "const0_operand" "n,n")))]
651 "ix86_match_ccmode (insn, CCNOmode)"
653 test{w}\t{%0, %0|%0, %0}
654 cmp{w}\t{%1, %0|%0, %1}"
655 [(set_attr "type" "test,icmp")
656 (set_attr "length_immediate" "0,1")
657 (set_attr "mode" "HI")])
659 (define_insn "*cmphi_minus_1"
660 [(set (reg FLAGS_REG)
661 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
662 (match_operand:HI 1 "general_operand" "ri,mr"))
664 "ix86_match_ccmode (insn, CCGOCmode)"
665 "cmp{w}\t{%1, %0|%0, %1}"
666 [(set_attr "type" "icmp")
667 (set_attr "mode" "HI")])
669 (define_insn "*cmphi_1"
670 [(set (reg FLAGS_REG)
671 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
672 (match_operand:HI 1 "general_operand" "ri,mr")))]
673 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
674 && ix86_match_ccmode (insn, CCmode)"
675 "cmp{w}\t{%1, %0|%0, %1}"
676 [(set_attr "type" "icmp")
677 (set_attr "mode" "HI")])
679 (define_insn "*cmpqi_ccno_1"
680 [(set (reg FLAGS_REG)
681 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
682 (match_operand:QI 1 "const0_operand" "n,n")))]
683 "ix86_match_ccmode (insn, CCNOmode)"
685 test{b}\t{%0, %0|%0, %0}
686 cmp{b}\t{$0, %0|%0, 0}"
687 [(set_attr "type" "test,icmp")
688 (set_attr "length_immediate" "0,1")
689 (set_attr "mode" "QI")])
691 (define_insn "*cmpqi_1"
692 [(set (reg FLAGS_REG)
693 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
694 (match_operand:QI 1 "general_operand" "qi,mq")))]
695 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
696 && ix86_match_ccmode (insn, CCmode)"
697 "cmp{b}\t{%1, %0|%0, %1}"
698 [(set_attr "type" "icmp")
699 (set_attr "mode" "QI")])
701 (define_insn "*cmpqi_minus_1"
702 [(set (reg FLAGS_REG)
703 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
704 (match_operand:QI 1 "general_operand" "qi,mq"))
706 "ix86_match_ccmode (insn, CCGOCmode)"
707 "cmp{b}\t{%1, %0|%0, %1}"
708 [(set_attr "type" "icmp")
709 (set_attr "mode" "QI")])
711 (define_insn "*cmpqi_ext_1"
712 [(set (reg FLAGS_REG)
714 (match_operand:QI 0 "general_operand" "Qm")
717 (match_operand 1 "ext_register_operand" "Q")
720 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721 "cmp{b}\t{%h1, %0|%0, %h1}"
722 [(set_attr "type" "icmp")
723 (set_attr "mode" "QI")])
725 (define_insn "*cmpqi_ext_1_rex64"
726 [(set (reg FLAGS_REG)
728 (match_operand:QI 0 "register_operand" "Q")
731 (match_operand 1 "ext_register_operand" "Q")
734 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735 "cmp{b}\t{%h1, %0|%0, %h1}"
736 [(set_attr "type" "icmp")
737 (set_attr "mode" "QI")])
739 (define_insn "*cmpqi_ext_2"
740 [(set (reg FLAGS_REG)
744 (match_operand 0 "ext_register_operand" "Q")
747 (match_operand:QI 1 "const0_operand" "n")))]
748 "ix86_match_ccmode (insn, CCNOmode)"
750 [(set_attr "type" "test")
751 (set_attr "length_immediate" "0")
752 (set_attr "mode" "QI")])
754 (define_expand "cmpqi_ext_3"
755 [(set (reg:CC FLAGS_REG)
759 (match_operand 0 "ext_register_operand" "")
762 (match_operand:QI 1 "general_operand" "")))]
766 (define_insn "cmpqi_ext_3_insn"
767 [(set (reg FLAGS_REG)
771 (match_operand 0 "ext_register_operand" "Q")
774 (match_operand:QI 1 "general_operand" "Qmn")))]
775 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776 "cmp{b}\t{%1, %h0|%h0, %1}"
777 [(set_attr "type" "icmp")
778 (set_attr "mode" "QI")])
780 (define_insn "cmpqi_ext_3_insn_rex64"
781 [(set (reg FLAGS_REG)
785 (match_operand 0 "ext_register_operand" "Q")
788 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
789 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
790 "cmp{b}\t{%1, %h0|%h0, %1}"
791 [(set_attr "type" "icmp")
792 (set_attr "mode" "QI")])
794 (define_insn "*cmpqi_ext_4"
795 [(set (reg FLAGS_REG)
799 (match_operand 0 "ext_register_operand" "Q")
804 (match_operand 1 "ext_register_operand" "Q")
807 "ix86_match_ccmode (insn, CCmode)"
808 "cmp{b}\t{%h1, %h0|%h0, %h1}"
809 [(set_attr "type" "icmp")
810 (set_attr "mode" "QI")])
812 ;; These implement float point compares.
813 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
814 ;; which would allow mix and match FP modes on the compares. Which is what
815 ;; the old patterns did, but with many more of them.
817 (define_expand "cmpxf"
818 [(set (reg:CC FLAGS_REG)
819 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
820 (match_operand:XF 1 "nonmemory_operand" "")))]
823 ix86_compare_op0 = operands[0];
824 ix86_compare_op1 = operands[1];
828 (define_expand "cmpdf"
829 [(set (reg:CC FLAGS_REG)
830 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
831 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
832 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
834 ix86_compare_op0 = operands[0];
835 ix86_compare_op1 = operands[1];
839 (define_expand "cmpsf"
840 [(set (reg:CC FLAGS_REG)
841 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
842 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
843 "TARGET_80387 || TARGET_SSE_MATH"
845 ix86_compare_op0 = operands[0];
846 ix86_compare_op1 = operands[1];
850 ;; FP compares, step 1:
851 ;; Set the FP condition codes.
853 ;; CCFPmode compare with exceptions
854 ;; CCFPUmode compare with no exceptions
856 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
857 ;; used to manage the reg stack popping would not be preserved.
859 (define_insn "*cmpfp_0"
860 [(set (match_operand:HI 0 "register_operand" "=a")
863 (match_operand 1 "register_operand" "f")
864 (match_operand 2 "const0_operand" "X"))]
867 && FLOAT_MODE_P (GET_MODE (operands[1]))
868 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
869 "* return output_fp_compare (insn, operands, 0, 0);"
870 [(set_attr "type" "multi")
871 (set_attr "unit" "i387")
873 (cond [(match_operand:SF 1 "" "")
875 (match_operand:DF 1 "" "")
878 (const_string "XF")))])
880 (define_insn "*cmpfp_sf"
881 [(set (match_operand:HI 0 "register_operand" "=a")
884 (match_operand:SF 1 "register_operand" "f")
885 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
888 "* return output_fp_compare (insn, operands, 0, 0);"
889 [(set_attr "type" "multi")
890 (set_attr "unit" "i387")
891 (set_attr "mode" "SF")])
893 (define_insn "*cmpfp_df"
894 [(set (match_operand:HI 0 "register_operand" "=a")
897 (match_operand:DF 1 "register_operand" "f")
898 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
901 "* return output_fp_compare (insn, operands, 0, 0);"
902 [(set_attr "type" "multi")
903 (set_attr "unit" "i387")
904 (set_attr "mode" "DF")])
906 (define_insn "*cmpfp_xf"
907 [(set (match_operand:HI 0 "register_operand" "=a")
910 (match_operand:XF 1 "register_operand" "f")
911 (match_operand:XF 2 "register_operand" "f"))]
914 "* return output_fp_compare (insn, operands, 0, 0);"
915 [(set_attr "type" "multi")
916 (set_attr "unit" "i387")
917 (set_attr "mode" "XF")])
919 (define_insn "*cmpfp_u"
920 [(set (match_operand:HI 0 "register_operand" "=a")
923 (match_operand 1 "register_operand" "f")
924 (match_operand 2 "register_operand" "f"))]
927 && FLOAT_MODE_P (GET_MODE (operands[1]))
928 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
929 "* return output_fp_compare (insn, operands, 0, 1);"
930 [(set_attr "type" "multi")
931 (set_attr "unit" "i387")
933 (cond [(match_operand:SF 1 "" "")
935 (match_operand:DF 1 "" "")
938 (const_string "XF")))])
940 (define_insn "*cmpfp_<mode>"
941 [(set (match_operand:HI 0 "register_operand" "=a")
944 (match_operand 1 "register_operand" "f")
945 (match_operator 3 "float_operator"
946 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
948 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
949 && FLOAT_MODE_P (GET_MODE (operands[1]))
950 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
951 "* return output_fp_compare (insn, operands, 0, 0);"
952 [(set_attr "type" "multi")
953 (set_attr "unit" "i387")
954 (set_attr "fp_int_src" "true")
955 (set_attr "mode" "<MODE>")])
957 ;; FP compares, step 2
958 ;; Move the fpsw to ax.
960 (define_insn "x86_fnstsw_1"
961 [(set (match_operand:HI 0 "register_operand" "=a")
962 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
965 [(set_attr "length" "2")
966 (set_attr "mode" "SI")
967 (set_attr "unit" "i387")])
969 ;; FP compares, step 3
970 ;; Get ax into flags, general case.
972 (define_insn "x86_sahf_1"
973 [(set (reg:CC FLAGS_REG)
974 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
977 [(set_attr "length" "1")
978 (set_attr "athlon_decode" "vector")
979 (set_attr "amdfam10_decode" "direct")
980 (set_attr "mode" "SI")])
982 ;; Pentium Pro can do steps 1 through 3 in one go.
983 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
984 (define_insn "*cmpfp_i_mixed"
985 [(set (reg:CCFP FLAGS_REG)
986 (compare:CCFP (match_operand 0 "register_operand" "f,x")
987 (match_operand 1 "nonimmediate_operand" "f,xm")))]
989 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991 "* return output_fp_compare (insn, operands, 1, 0);"
992 [(set_attr "type" "fcmp,ssecomi")
994 (if_then_else (match_operand:SF 1 "" "")
996 (const_string "DF")))
997 (set_attr "athlon_decode" "vector")
998 (set_attr "amdfam10_decode" "direct")])
1000 (define_insn "*cmpfp_i_sse"
1001 [(set (reg:CCFP FLAGS_REG)
1002 (compare:CCFP (match_operand 0 "register_operand" "x")
1003 (match_operand 1 "nonimmediate_operand" "xm")))]
1005 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1006 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007 "* return output_fp_compare (insn, operands, 1, 0);"
1008 [(set_attr "type" "ssecomi")
1010 (if_then_else (match_operand:SF 1 "" "")
1012 (const_string "DF")))
1013 (set_attr "athlon_decode" "vector")
1014 (set_attr "amdfam10_decode" "direct")])
1016 (define_insn "*cmpfp_i_i387"
1017 [(set (reg:CCFP FLAGS_REG)
1018 (compare:CCFP (match_operand 0 "register_operand" "f")
1019 (match_operand 1 "register_operand" "f")))]
1020 "TARGET_80387 && TARGET_CMOVE
1021 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1022 && FLOAT_MODE_P (GET_MODE (operands[0]))
1023 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1024 "* return output_fp_compare (insn, operands, 1, 0);"
1025 [(set_attr "type" "fcmp")
1027 (cond [(match_operand:SF 1 "" "")
1029 (match_operand:DF 1 "" "")
1032 (const_string "XF")))
1033 (set_attr "athlon_decode" "vector")
1034 (set_attr "amdfam10_decode" "direct")])
1036 (define_insn "*cmpfp_iu_mixed"
1037 [(set (reg:CCFPU FLAGS_REG)
1038 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1039 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1040 "TARGET_MIX_SSE_I387
1041 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1042 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1043 "* return output_fp_compare (insn, operands, 1, 1);"
1044 [(set_attr "type" "fcmp,ssecomi")
1046 (if_then_else (match_operand:SF 1 "" "")
1048 (const_string "DF")))
1049 (set_attr "athlon_decode" "vector")
1050 (set_attr "amdfam10_decode" "direct")])
1052 (define_insn "*cmpfp_iu_sse"
1053 [(set (reg:CCFPU FLAGS_REG)
1054 (compare:CCFPU (match_operand 0 "register_operand" "x")
1055 (match_operand 1 "nonimmediate_operand" "xm")))]
1057 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1058 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1059 "* return output_fp_compare (insn, operands, 1, 1);"
1060 [(set_attr "type" "ssecomi")
1062 (if_then_else (match_operand:SF 1 "" "")
1064 (const_string "DF")))
1065 (set_attr "athlon_decode" "vector")
1066 (set_attr "amdfam10_decode" "direct")])
1068 (define_insn "*cmpfp_iu_387"
1069 [(set (reg:CCFPU FLAGS_REG)
1070 (compare:CCFPU (match_operand 0 "register_operand" "f")
1071 (match_operand 1 "register_operand" "f")))]
1072 "TARGET_80387 && TARGET_CMOVE
1073 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1074 && FLOAT_MODE_P (GET_MODE (operands[0]))
1075 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1076 "* return output_fp_compare (insn, operands, 1, 1);"
1077 [(set_attr "type" "fcmp")
1079 (cond [(match_operand:SF 1 "" "")
1081 (match_operand:DF 1 "" "")
1084 (const_string "XF")))
1085 (set_attr "athlon_decode" "vector")
1086 (set_attr "amdfam10_decode" "direct")])
1088 ;; Move instructions.
1090 ;; General case of fullword move.
1092 (define_expand "movsi"
1093 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1094 (match_operand:SI 1 "general_operand" ""))]
1096 "ix86_expand_move (SImode, operands); DONE;")
1098 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1101 ;; %%% We don't use a post-inc memory reference because x86 is not a
1102 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1103 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1104 ;; targets without our curiosities, and it is just as easy to represent
1105 ;; this differently.
1107 (define_insn "*pushsi2"
1108 [(set (match_operand:SI 0 "push_operand" "=<")
1109 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1112 [(set_attr "type" "push")
1113 (set_attr "mode" "SI")])
1115 ;; For 64BIT abi we always round up to 8 bytes.
1116 (define_insn "*pushsi2_rex64"
1117 [(set (match_operand:SI 0 "push_operand" "=X")
1118 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1121 [(set_attr "type" "push")
1122 (set_attr "mode" "SI")])
1124 (define_insn "*pushsi2_prologue"
1125 [(set (match_operand:SI 0 "push_operand" "=<")
1126 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1127 (clobber (mem:BLK (scratch)))]
1130 [(set_attr "type" "push")
1131 (set_attr "mode" "SI")])
1133 (define_insn "*popsi1_epilogue"
1134 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1135 (mem:SI (reg:SI SP_REG)))
1136 (set (reg:SI SP_REG)
1137 (plus:SI (reg:SI SP_REG) (const_int 4)))
1138 (clobber (mem:BLK (scratch)))]
1141 [(set_attr "type" "pop")
1142 (set_attr "mode" "SI")])
1144 (define_insn "popsi1"
1145 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1146 (mem:SI (reg:SI SP_REG)))
1147 (set (reg:SI SP_REG)
1148 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1151 [(set_attr "type" "pop")
1152 (set_attr "mode" "SI")])
1154 (define_insn "*movsi_xor"
1155 [(set (match_operand:SI 0 "register_operand" "=r")
1156 (match_operand:SI 1 "const0_operand" "i"))
1157 (clobber (reg:CC FLAGS_REG))]
1158 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1159 "xor{l}\t{%0, %0|%0, %0}"
1160 [(set_attr "type" "alu1")
1161 (set_attr "mode" "SI")
1162 (set_attr "length_immediate" "0")])
1164 (define_insn "*movsi_or"
1165 [(set (match_operand:SI 0 "register_operand" "=r")
1166 (match_operand:SI 1 "immediate_operand" "i"))
1167 (clobber (reg:CC FLAGS_REG))]
1169 && operands[1] == constm1_rtx
1170 && (TARGET_PENTIUM || optimize_size)"
1172 operands[1] = constm1_rtx;
1173 return "or{l}\t{%1, %0|%0, %1}";
1175 [(set_attr "type" "alu1")
1176 (set_attr "mode" "SI")
1177 (set_attr "length_immediate" "1")])
1179 (define_insn "*movsi_1"
1180 [(set (match_operand:SI 0 "nonimmediate_operand"
1181 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1182 (match_operand:SI 1 "general_operand"
1183 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1184 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1186 switch (get_attr_type (insn))
1189 if (get_attr_mode (insn) == MODE_TI)
1190 return "pxor\t%0, %0";
1191 return "xorps\t%0, %0";
1194 switch (get_attr_mode (insn))
1197 return "movdqa\t{%1, %0|%0, %1}";
1199 return "movaps\t{%1, %0|%0, %1}";
1201 return "movd\t{%1, %0|%0, %1}";
1203 return "movss\t{%1, %0|%0, %1}";
1209 return "pxor\t%0, %0";
1212 if (get_attr_mode (insn) == MODE_DI)
1213 return "movq\t{%1, %0|%0, %1}";
1214 return "movd\t{%1, %0|%0, %1}";
1217 return "lea{l}\t{%1, %0|%0, %1}";
1220 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1221 return "mov{l}\t{%1, %0|%0, %1}";
1225 (cond [(eq_attr "alternative" "2")
1226 (const_string "mmxadd")
1227 (eq_attr "alternative" "3,4,5")
1228 (const_string "mmxmov")
1229 (eq_attr "alternative" "6")
1230 (const_string "sselog1")
1231 (eq_attr "alternative" "7,8,9,10,11")
1232 (const_string "ssemov")
1233 (match_operand:DI 1 "pic_32bit_operand" "")
1234 (const_string "lea")
1236 (const_string "imov")))
1238 (cond [(eq_attr "alternative" "2,3")
1240 (eq_attr "alternative" "6,7")
1242 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1243 (const_string "V4SF")
1244 (const_string "TI"))
1245 (and (eq_attr "alternative" "8,9,10,11")
1246 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1249 (const_string "SI")))])
1251 ;; Stores and loads of ax to arbitrary constant address.
1252 ;; We fake an second form of instruction to force reload to load address
1253 ;; into register when rax is not available
1254 (define_insn "*movabssi_1_rex64"
1255 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1256 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1257 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1259 movabs{l}\t{%1, %P0|%P0, %1}
1260 mov{l}\t{%1, %a0|%a0, %1}"
1261 [(set_attr "type" "imov")
1262 (set_attr "modrm" "0,*")
1263 (set_attr "length_address" "8,0")
1264 (set_attr "length_immediate" "0,*")
1265 (set_attr "memory" "store")
1266 (set_attr "mode" "SI")])
1268 (define_insn "*movabssi_2_rex64"
1269 [(set (match_operand:SI 0 "register_operand" "=a,r")
1270 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1271 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1273 movabs{l}\t{%P1, %0|%0, %P1}
1274 mov{l}\t{%a1, %0|%0, %a1}"
1275 [(set_attr "type" "imov")
1276 (set_attr "modrm" "0,*")
1277 (set_attr "length_address" "8,0")
1278 (set_attr "length_immediate" "0")
1279 (set_attr "memory" "load")
1280 (set_attr "mode" "SI")])
1282 (define_insn "*swapsi"
1283 [(set (match_operand:SI 0 "register_operand" "+r")
1284 (match_operand:SI 1 "register_operand" "+r"))
1289 [(set_attr "type" "imov")
1290 (set_attr "mode" "SI")
1291 (set_attr "pent_pair" "np")
1292 (set_attr "athlon_decode" "vector")
1293 (set_attr "amdfam10_decode" "double")])
1295 (define_expand "movhi"
1296 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1297 (match_operand:HI 1 "general_operand" ""))]
1299 "ix86_expand_move (HImode, operands); DONE;")
1301 (define_insn "*pushhi2"
1302 [(set (match_operand:HI 0 "push_operand" "=X")
1303 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1306 [(set_attr "type" "push")
1307 (set_attr "mode" "SI")])
1309 ;; For 64BIT abi we always round up to 8 bytes.
1310 (define_insn "*pushhi2_rex64"
1311 [(set (match_operand:HI 0 "push_operand" "=X")
1312 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1315 [(set_attr "type" "push")
1316 (set_attr "mode" "DI")])
1318 (define_insn "*movhi_1"
1319 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1320 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1321 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1323 switch (get_attr_type (insn))
1326 /* movzwl is faster than movw on p2 due to partial word stalls,
1327 though not as fast as an aligned movl. */
1328 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1330 if (get_attr_mode (insn) == MODE_SI)
1331 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1333 return "mov{w}\t{%1, %0|%0, %1}";
1337 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1338 (const_string "imov")
1339 (and (eq_attr "alternative" "0")
1340 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1342 (eq (symbol_ref "TARGET_HIMODE_MATH")
1344 (const_string "imov")
1345 (and (eq_attr "alternative" "1,2")
1346 (match_operand:HI 1 "aligned_operand" ""))
1347 (const_string "imov")
1348 (and (ne (symbol_ref "TARGET_MOVX")
1350 (eq_attr "alternative" "0,2"))
1351 (const_string "imovx")
1353 (const_string "imov")))
1355 (cond [(eq_attr "type" "imovx")
1357 (and (eq_attr "alternative" "1,2")
1358 (match_operand:HI 1 "aligned_operand" ""))
1360 (and (eq_attr "alternative" "0")
1361 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1363 (eq (symbol_ref "TARGET_HIMODE_MATH")
1367 (const_string "HI")))])
1369 ;; Stores and loads of ax to arbitrary constant address.
1370 ;; We fake an second form of instruction to force reload to load address
1371 ;; into register when rax is not available
1372 (define_insn "*movabshi_1_rex64"
1373 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1374 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1375 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1377 movabs{w}\t{%1, %P0|%P0, %1}
1378 mov{w}\t{%1, %a0|%a0, %1}"
1379 [(set_attr "type" "imov")
1380 (set_attr "modrm" "0,*")
1381 (set_attr "length_address" "8,0")
1382 (set_attr "length_immediate" "0,*")
1383 (set_attr "memory" "store")
1384 (set_attr "mode" "HI")])
1386 (define_insn "*movabshi_2_rex64"
1387 [(set (match_operand:HI 0 "register_operand" "=a,r")
1388 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1389 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1391 movabs{w}\t{%P1, %0|%0, %P1}
1392 mov{w}\t{%a1, %0|%0, %a1}"
1393 [(set_attr "type" "imov")
1394 (set_attr "modrm" "0,*")
1395 (set_attr "length_address" "8,0")
1396 (set_attr "length_immediate" "0")
1397 (set_attr "memory" "load")
1398 (set_attr "mode" "HI")])
1400 (define_insn "*swaphi_1"
1401 [(set (match_operand:HI 0 "register_operand" "+r")
1402 (match_operand:HI 1 "register_operand" "+r"))
1405 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1407 [(set_attr "type" "imov")
1408 (set_attr "mode" "SI")
1409 (set_attr "pent_pair" "np")
1410 (set_attr "athlon_decode" "vector")
1411 (set_attr "amdfam10_decode" "double")])
1413 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1414 (define_insn "*swaphi_2"
1415 [(set (match_operand:HI 0 "register_operand" "+r")
1416 (match_operand:HI 1 "register_operand" "+r"))
1419 "TARGET_PARTIAL_REG_STALL"
1421 [(set_attr "type" "imov")
1422 (set_attr "mode" "HI")
1423 (set_attr "pent_pair" "np")
1424 (set_attr "athlon_decode" "vector")])
1426 (define_expand "movstricthi"
1427 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1428 (match_operand:HI 1 "general_operand" ""))]
1429 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1431 /* Don't generate memory->memory moves, go through a register */
1432 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1433 operands[1] = force_reg (HImode, operands[1]);
1436 (define_insn "*movstricthi_1"
1437 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1438 (match_operand:HI 1 "general_operand" "rn,m"))]
1439 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1440 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1441 "mov{w}\t{%1, %0|%0, %1}"
1442 [(set_attr "type" "imov")
1443 (set_attr "mode" "HI")])
1445 (define_insn "*movstricthi_xor"
1446 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1447 (match_operand:HI 1 "const0_operand" "i"))
1448 (clobber (reg:CC FLAGS_REG))]
1450 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1451 "xor{w}\t{%0, %0|%0, %0}"
1452 [(set_attr "type" "alu1")
1453 (set_attr "mode" "HI")
1454 (set_attr "length_immediate" "0")])
1456 (define_expand "movqi"
1457 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1458 (match_operand:QI 1 "general_operand" ""))]
1460 "ix86_expand_move (QImode, operands); DONE;")
1462 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1463 ;; "push a byte". But actually we use pushl, which has the effect
1464 ;; of rounding the amount pushed up to a word.
1466 (define_insn "*pushqi2"
1467 [(set (match_operand:QI 0 "push_operand" "=X")
1468 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1471 [(set_attr "type" "push")
1472 (set_attr "mode" "SI")])
1474 ;; For 64BIT abi we always round up to 8 bytes.
1475 (define_insn "*pushqi2_rex64"
1476 [(set (match_operand:QI 0 "push_operand" "=X")
1477 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1480 [(set_attr "type" "push")
1481 (set_attr "mode" "DI")])
1483 ;; Situation is quite tricky about when to choose full sized (SImode) move
1484 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1485 ;; partial register dependency machines (such as AMD Athlon), where QImode
1486 ;; moves issue extra dependency and for partial register stalls machines
1487 ;; that don't use QImode patterns (and QImode move cause stall on the next
1490 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1491 ;; register stall machines with, where we use QImode instructions, since
1492 ;; partial register stall can be caused there. Then we use movzx.
1493 (define_insn "*movqi_1"
1494 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1495 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1496 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1498 switch (get_attr_type (insn))
1501 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1502 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1504 if (get_attr_mode (insn) == MODE_SI)
1505 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1507 return "mov{b}\t{%1, %0|%0, %1}";
1511 (cond [(and (eq_attr "alternative" "5")
1512 (not (match_operand:QI 1 "aligned_operand" "")))
1513 (const_string "imovx")
1514 (ne (symbol_ref "optimize_size") (const_int 0))
1515 (const_string "imov")
1516 (and (eq_attr "alternative" "3")
1517 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1519 (eq (symbol_ref "TARGET_QIMODE_MATH")
1521 (const_string "imov")
1522 (eq_attr "alternative" "3,5")
1523 (const_string "imovx")
1524 (and (ne (symbol_ref "TARGET_MOVX")
1526 (eq_attr "alternative" "2"))
1527 (const_string "imovx")
1529 (const_string "imov")))
1531 (cond [(eq_attr "alternative" "3,4,5")
1533 (eq_attr "alternative" "6")
1535 (eq_attr "type" "imovx")
1537 (and (eq_attr "type" "imov")
1538 (and (eq_attr "alternative" "0,1")
1539 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1541 (and (eq (symbol_ref "optimize_size")
1543 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1546 ;; Avoid partial register stalls when not using QImode arithmetic
1547 (and (eq_attr "type" "imov")
1548 (and (eq_attr "alternative" "0,1")
1549 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1551 (eq (symbol_ref "TARGET_QIMODE_MATH")
1555 (const_string "QI")))])
1557 (define_expand "reload_outqi"
1558 [(parallel [(match_operand:QI 0 "" "=m")
1559 (match_operand:QI 1 "register_operand" "r")
1560 (match_operand:QI 2 "register_operand" "=&q")])]
1564 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1566 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1567 if (! q_regs_operand (op1, QImode))
1569 emit_insn (gen_movqi (op2, op1));
1572 emit_insn (gen_movqi (op0, op1));
1576 (define_insn "*swapqi_1"
1577 [(set (match_operand:QI 0 "register_operand" "+r")
1578 (match_operand:QI 1 "register_operand" "+r"))
1581 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1583 [(set_attr "type" "imov")
1584 (set_attr "mode" "SI")
1585 (set_attr "pent_pair" "np")
1586 (set_attr "athlon_decode" "vector")
1587 (set_attr "amdfam10_decode" "vector")])
1589 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1590 (define_insn "*swapqi_2"
1591 [(set (match_operand:QI 0 "register_operand" "+q")
1592 (match_operand:QI 1 "register_operand" "+q"))
1595 "TARGET_PARTIAL_REG_STALL"
1597 [(set_attr "type" "imov")
1598 (set_attr "mode" "QI")
1599 (set_attr "pent_pair" "np")
1600 (set_attr "athlon_decode" "vector")])
1602 (define_expand "movstrictqi"
1603 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1604 (match_operand:QI 1 "general_operand" ""))]
1605 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1607 /* Don't generate memory->memory moves, go through a register. */
1608 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1609 operands[1] = force_reg (QImode, operands[1]);
1612 (define_insn "*movstrictqi_1"
1613 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1614 (match_operand:QI 1 "general_operand" "*qn,m"))]
1615 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1616 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1617 "mov{b}\t{%1, %0|%0, %1}"
1618 [(set_attr "type" "imov")
1619 (set_attr "mode" "QI")])
1621 (define_insn "*movstrictqi_xor"
1622 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1623 (match_operand:QI 1 "const0_operand" "i"))
1624 (clobber (reg:CC FLAGS_REG))]
1625 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1626 "xor{b}\t{%0, %0|%0, %0}"
1627 [(set_attr "type" "alu1")
1628 (set_attr "mode" "QI")
1629 (set_attr "length_immediate" "0")])
1631 (define_insn "*movsi_extv_1"
1632 [(set (match_operand:SI 0 "register_operand" "=R")
1633 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1637 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1638 [(set_attr "type" "imovx")
1639 (set_attr "mode" "SI")])
1641 (define_insn "*movhi_extv_1"
1642 [(set (match_operand:HI 0 "register_operand" "=R")
1643 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1647 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1648 [(set_attr "type" "imovx")
1649 (set_attr "mode" "SI")])
1651 (define_insn "*movqi_extv_1"
1652 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1653 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1658 switch (get_attr_type (insn))
1661 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1663 return "mov{b}\t{%h1, %0|%0, %h1}";
1667 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1668 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1669 (ne (symbol_ref "TARGET_MOVX")
1671 (const_string "imovx")
1672 (const_string "imov")))
1674 (if_then_else (eq_attr "type" "imovx")
1676 (const_string "QI")))])
1678 (define_insn "*movqi_extv_1_rex64"
1679 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1680 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1685 switch (get_attr_type (insn))
1688 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1690 return "mov{b}\t{%h1, %0|%0, %h1}";
1694 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1695 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1696 (ne (symbol_ref "TARGET_MOVX")
1698 (const_string "imovx")
1699 (const_string "imov")))
1701 (if_then_else (eq_attr "type" "imovx")
1703 (const_string "QI")))])
1705 ;; Stores and loads of ax to arbitrary constant address.
1706 ;; We fake an second form of instruction to force reload to load address
1707 ;; into register when rax is not available
1708 (define_insn "*movabsqi_1_rex64"
1709 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1710 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1711 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1713 movabs{b}\t{%1, %P0|%P0, %1}
1714 mov{b}\t{%1, %a0|%a0, %1}"
1715 [(set_attr "type" "imov")
1716 (set_attr "modrm" "0,*")
1717 (set_attr "length_address" "8,0")
1718 (set_attr "length_immediate" "0,*")
1719 (set_attr "memory" "store")
1720 (set_attr "mode" "QI")])
1722 (define_insn "*movabsqi_2_rex64"
1723 [(set (match_operand:QI 0 "register_operand" "=a,r")
1724 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1725 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1727 movabs{b}\t{%P1, %0|%0, %P1}
1728 mov{b}\t{%a1, %0|%0, %a1}"
1729 [(set_attr "type" "imov")
1730 (set_attr "modrm" "0,*")
1731 (set_attr "length_address" "8,0")
1732 (set_attr "length_immediate" "0")
1733 (set_attr "memory" "load")
1734 (set_attr "mode" "QI")])
1736 (define_insn "*movdi_extzv_1"
1737 [(set (match_operand:DI 0 "register_operand" "=R")
1738 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1742 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1743 [(set_attr "type" "imovx")
1744 (set_attr "mode" "DI")])
1746 (define_insn "*movsi_extzv_1"
1747 [(set (match_operand:SI 0 "register_operand" "=R")
1748 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1752 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1753 [(set_attr "type" "imovx")
1754 (set_attr "mode" "SI")])
1756 (define_insn "*movqi_extzv_2"
1757 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1758 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1763 switch (get_attr_type (insn))
1766 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1768 return "mov{b}\t{%h1, %0|%0, %h1}";
1772 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1773 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774 (ne (symbol_ref "TARGET_MOVX")
1776 (const_string "imovx")
1777 (const_string "imov")))
1779 (if_then_else (eq_attr "type" "imovx")
1781 (const_string "QI")))])
1783 (define_insn "*movqi_extzv_2_rex64"
1784 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1785 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1790 switch (get_attr_type (insn))
1793 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1795 return "mov{b}\t{%h1, %0|%0, %h1}";
1799 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1800 (ne (symbol_ref "TARGET_MOVX")
1802 (const_string "imovx")
1803 (const_string "imov")))
1805 (if_then_else (eq_attr "type" "imovx")
1807 (const_string "QI")))])
1809 (define_insn "movsi_insv_1"
1810 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1813 (match_operand:SI 1 "general_operand" "Qmn"))]
1815 "mov{b}\t{%b1, %h0|%h0, %b1}"
1816 [(set_attr "type" "imov")
1817 (set_attr "mode" "QI")])
1819 (define_insn "movdi_insv_1_rex64"
1820 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1823 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1825 "mov{b}\t{%b1, %h0|%h0, %b1}"
1826 [(set_attr "type" "imov")
1827 (set_attr "mode" "QI")])
1829 (define_insn "*movqi_insv_2"
1830 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1833 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1836 "mov{b}\t{%h1, %h0|%h0, %h1}"
1837 [(set_attr "type" "imov")
1838 (set_attr "mode" "QI")])
1840 (define_expand "movdi"
1841 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1842 (match_operand:DI 1 "general_operand" ""))]
1844 "ix86_expand_move (DImode, operands); DONE;")
1846 (define_insn "*pushdi"
1847 [(set (match_operand:DI 0 "push_operand" "=<")
1848 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1852 (define_insn "*pushdi2_rex64"
1853 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1854 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1859 [(set_attr "type" "push,multi")
1860 (set_attr "mode" "DI")])
1862 ;; Convert impossible pushes of immediate to existing instructions.
1863 ;; First try to get scratch register and go through it. In case this
1864 ;; fails, push sign extended lower part first and then overwrite
1865 ;; upper part by 32bit move.
1867 [(match_scratch:DI 2 "r")
1868 (set (match_operand:DI 0 "push_operand" "")
1869 (match_operand:DI 1 "immediate_operand" ""))]
1870 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1871 && !x86_64_immediate_operand (operands[1], DImode)"
1872 [(set (match_dup 2) (match_dup 1))
1873 (set (match_dup 0) (match_dup 2))]
1876 ;; We need to define this as both peepholer and splitter for case
1877 ;; peephole2 pass is not run.
1878 ;; "&& 1" is needed to keep it from matching the previous pattern.
1880 [(set (match_operand:DI 0 "push_operand" "")
1881 (match_operand:DI 1 "immediate_operand" ""))]
1882 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1883 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1884 [(set (match_dup 0) (match_dup 1))
1885 (set (match_dup 2) (match_dup 3))]
1886 "split_di (operands + 1, 1, operands + 2, operands + 3);
1887 operands[1] = gen_lowpart (DImode, operands[2]);
1888 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1893 [(set (match_operand:DI 0 "push_operand" "")
1894 (match_operand:DI 1 "immediate_operand" ""))]
1895 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1896 ? flow2_completed : reload_completed)
1897 && !symbolic_operand (operands[1], DImode)
1898 && !x86_64_immediate_operand (operands[1], DImode)"
1899 [(set (match_dup 0) (match_dup 1))
1900 (set (match_dup 2) (match_dup 3))]
1901 "split_di (operands + 1, 1, operands + 2, operands + 3);
1902 operands[1] = gen_lowpart (DImode, operands[2]);
1903 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1907 (define_insn "*pushdi2_prologue_rex64"
1908 [(set (match_operand:DI 0 "push_operand" "=<")
1909 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1910 (clobber (mem:BLK (scratch)))]
1913 [(set_attr "type" "push")
1914 (set_attr "mode" "DI")])
1916 (define_insn "*popdi1_epilogue_rex64"
1917 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1918 (mem:DI (reg:DI SP_REG)))
1919 (set (reg:DI SP_REG)
1920 (plus:DI (reg:DI SP_REG) (const_int 8)))
1921 (clobber (mem:BLK (scratch)))]
1924 [(set_attr "type" "pop")
1925 (set_attr "mode" "DI")])
1927 (define_insn "popdi1"
1928 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1929 (mem:DI (reg:DI SP_REG)))
1930 (set (reg:DI SP_REG)
1931 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1934 [(set_attr "type" "pop")
1935 (set_attr "mode" "DI")])
1937 (define_insn "*movdi_xor_rex64"
1938 [(set (match_operand:DI 0 "register_operand" "=r")
1939 (match_operand:DI 1 "const0_operand" "i"))
1940 (clobber (reg:CC FLAGS_REG))]
1941 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1942 && reload_completed"
1943 "xor{l}\t{%k0, %k0|%k0, %k0}"
1944 [(set_attr "type" "alu1")
1945 (set_attr "mode" "SI")
1946 (set_attr "length_immediate" "0")])
1948 (define_insn "*movdi_or_rex64"
1949 [(set (match_operand:DI 0 "register_operand" "=r")
1950 (match_operand:DI 1 "const_int_operand" "i"))
1951 (clobber (reg:CC FLAGS_REG))]
1952 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1954 && operands[1] == constm1_rtx"
1956 operands[1] = constm1_rtx;
1957 return "or{q}\t{%1, %0|%0, %1}";
1959 [(set_attr "type" "alu1")
1960 (set_attr "mode" "DI")
1961 (set_attr "length_immediate" "1")])
1963 (define_insn "*movdi_2"
1964 [(set (match_operand:DI 0 "nonimmediate_operand"
1965 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1966 (match_operand:DI 1 "general_operand"
1967 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1968 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1973 movq\t{%1, %0|%0, %1}
1974 movq\t{%1, %0|%0, %1}
1976 movq\t{%1, %0|%0, %1}
1977 movdqa\t{%1, %0|%0, %1}
1978 movq\t{%1, %0|%0, %1}
1980 movlps\t{%1, %0|%0, %1}
1981 movaps\t{%1, %0|%0, %1}
1982 movlps\t{%1, %0|%0, %1}"
1983 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1984 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1987 [(set (match_operand:DI 0 "push_operand" "")
1988 (match_operand:DI 1 "general_operand" ""))]
1989 "!TARGET_64BIT && reload_completed
1990 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1992 "ix86_split_long_move (operands); DONE;")
1994 ;; %%% This multiword shite has got to go.
1996 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1997 (match_operand:DI 1 "general_operand" ""))]
1998 "!TARGET_64BIT && reload_completed
1999 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2000 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2002 "ix86_split_long_move (operands); DONE;")
2004 (define_insn "*movdi_1_rex64"
2005 [(set (match_operand:DI 0 "nonimmediate_operand"
2006 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2007 (match_operand:DI 1 "general_operand"
2008 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2009 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2011 switch (get_attr_type (insn))
2014 if (which_alternative == 13)
2015 return "movq2dq\t{%1, %0|%0, %1}";
2017 return "movdq2q\t{%1, %0|%0, %1}";
2019 if (get_attr_mode (insn) == MODE_TI)
2020 return "movdqa\t{%1, %0|%0, %1}";
2023 /* Moves from and into integer register is done using movd opcode with
2025 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2026 return "movd\t{%1, %0|%0, %1}";
2027 return "movq\t{%1, %0|%0, %1}";
2030 return "pxor\t%0, %0";
2034 return "lea{q}\t{%a1, %0|%0, %a1}";
2036 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2037 if (get_attr_mode (insn) == MODE_SI)
2038 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2039 else if (which_alternative == 2)
2040 return "movabs{q}\t{%1, %0|%0, %1}";
2042 return "mov{q}\t{%1, %0|%0, %1}";
2046 (cond [(eq_attr "alternative" "5")
2047 (const_string "mmxadd")
2048 (eq_attr "alternative" "6,7,8")
2049 (const_string "mmxmov")
2050 (eq_attr "alternative" "9")
2051 (const_string "sselog1")
2052 (eq_attr "alternative" "10,11,12")
2053 (const_string "ssemov")
2054 (eq_attr "alternative" "13,14")
2055 (const_string "ssecvt")
2056 (eq_attr "alternative" "4")
2057 (const_string "multi")
2058 (match_operand:DI 1 "pic_32bit_operand" "")
2059 (const_string "lea")
2061 (const_string "imov")))
2062 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2063 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2064 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2066 ;; Stores and loads of ax to arbitrary constant address.
2067 ;; We fake an second form of instruction to force reload to load address
2068 ;; into register when rax is not available
2069 (define_insn "*movabsdi_1_rex64"
2070 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2071 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2072 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2074 movabs{q}\t{%1, %P0|%P0, %1}
2075 mov{q}\t{%1, %a0|%a0, %1}"
2076 [(set_attr "type" "imov")
2077 (set_attr "modrm" "0,*")
2078 (set_attr "length_address" "8,0")
2079 (set_attr "length_immediate" "0,*")
2080 (set_attr "memory" "store")
2081 (set_attr "mode" "DI")])
2083 (define_insn "*movabsdi_2_rex64"
2084 [(set (match_operand:DI 0 "register_operand" "=a,r")
2085 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2086 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2088 movabs{q}\t{%P1, %0|%0, %P1}
2089 mov{q}\t{%a1, %0|%0, %a1}"
2090 [(set_attr "type" "imov")
2091 (set_attr "modrm" "0,*")
2092 (set_attr "length_address" "8,0")
2093 (set_attr "length_immediate" "0")
2094 (set_attr "memory" "load")
2095 (set_attr "mode" "DI")])
2097 ;; Convert impossible stores of immediate to existing instructions.
2098 ;; First try to get scratch register and go through it. In case this
2099 ;; fails, move by 32bit parts.
2101 [(match_scratch:DI 2 "r")
2102 (set (match_operand:DI 0 "memory_operand" "")
2103 (match_operand:DI 1 "immediate_operand" ""))]
2104 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2105 && !x86_64_immediate_operand (operands[1], DImode)"
2106 [(set (match_dup 2) (match_dup 1))
2107 (set (match_dup 0) (match_dup 2))]
2110 ;; We need to define this as both peepholer and splitter for case
2111 ;; peephole2 pass is not run.
2112 ;; "&& 1" is needed to keep it from matching the previous pattern.
2114 [(set (match_operand:DI 0 "memory_operand" "")
2115 (match_operand:DI 1 "immediate_operand" ""))]
2116 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2117 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2118 [(set (match_dup 2) (match_dup 3))
2119 (set (match_dup 4) (match_dup 5))]
2120 "split_di (operands, 2, operands + 2, operands + 4);")
2123 [(set (match_operand:DI 0 "memory_operand" "")
2124 (match_operand:DI 1 "immediate_operand" ""))]
2125 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2126 ? flow2_completed : reload_completed)
2127 && !symbolic_operand (operands[1], DImode)
2128 && !x86_64_immediate_operand (operands[1], DImode)"
2129 [(set (match_dup 2) (match_dup 3))
2130 (set (match_dup 4) (match_dup 5))]
2131 "split_di (operands, 2, operands + 2, operands + 4);")
2133 (define_insn "*swapdi_rex64"
2134 [(set (match_operand:DI 0 "register_operand" "+r")
2135 (match_operand:DI 1 "register_operand" "+r"))
2140 [(set_attr "type" "imov")
2141 (set_attr "mode" "DI")
2142 (set_attr "pent_pair" "np")
2143 (set_attr "athlon_decode" "vector")
2144 (set_attr "amdfam10_decode" "double")])
2146 (define_expand "movti"
2147 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2148 (match_operand:TI 1 "nonimmediate_operand" ""))]
2149 "TARGET_SSE || TARGET_64BIT"
2152 ix86_expand_move (TImode, operands);
2154 ix86_expand_vector_move (TImode, operands);
2158 (define_insn "*movti_internal"
2159 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2160 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2161 "TARGET_SSE && !TARGET_64BIT
2162 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2164 switch (which_alternative)
2167 if (get_attr_mode (insn) == MODE_V4SF)
2168 return "xorps\t%0, %0";
2170 return "pxor\t%0, %0";
2173 if (get_attr_mode (insn) == MODE_V4SF)
2174 return "movaps\t{%1, %0|%0, %1}";
2176 return "movdqa\t{%1, %0|%0, %1}";
2181 [(set_attr "type" "sselog1,ssemov,ssemov")
2183 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2184 (ne (symbol_ref "optimize_size") (const_int 0)))
2185 (const_string "V4SF")
2186 (and (eq_attr "alternative" "2")
2187 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2189 (const_string "V4SF")]
2190 (const_string "TI")))])
2192 (define_insn "*movti_rex64"
2193 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2194 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2196 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2198 switch (which_alternative)
2204 if (get_attr_mode (insn) == MODE_V4SF)
2205 return "xorps\t%0, %0";
2207 return "pxor\t%0, %0";
2210 if (get_attr_mode (insn) == MODE_V4SF)
2211 return "movaps\t{%1, %0|%0, %1}";
2213 return "movdqa\t{%1, %0|%0, %1}";
2218 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2220 (cond [(eq_attr "alternative" "2,3")
2222 (ne (symbol_ref "optimize_size")
2224 (const_string "V4SF")
2225 (const_string "TI"))
2226 (eq_attr "alternative" "4")
2228 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2230 (ne (symbol_ref "optimize_size")
2232 (const_string "V4SF")
2233 (const_string "TI"))]
2234 (const_string "DI")))])
2237 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2238 (match_operand:TI 1 "general_operand" ""))]
2239 "reload_completed && !SSE_REG_P (operands[0])
2240 && !SSE_REG_P (operands[1])"
2242 "ix86_split_long_move (operands); DONE;")
2244 (define_expand "movsf"
2245 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2246 (match_operand:SF 1 "general_operand" ""))]
2248 "ix86_expand_move (SFmode, operands); DONE;")
2250 (define_insn "*pushsf"
2251 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2252 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2255 /* Anything else should be already split before reg-stack. */
2256 gcc_assert (which_alternative == 1);
2257 return "push{l}\t%1";
2259 [(set_attr "type" "multi,push,multi")
2260 (set_attr "unit" "i387,*,*")
2261 (set_attr "mode" "SF,SI,SF")])
2263 (define_insn "*pushsf_rex64"
2264 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2265 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2268 /* Anything else should be already split before reg-stack. */
2269 gcc_assert (which_alternative == 1);
2270 return "push{q}\t%q1";
2272 [(set_attr "type" "multi,push,multi")
2273 (set_attr "unit" "i387,*,*")
2274 (set_attr "mode" "SF,DI,SF")])
2277 [(set (match_operand:SF 0 "push_operand" "")
2278 (match_operand:SF 1 "memory_operand" ""))]
2280 && GET_CODE (operands[1]) == MEM
2281 && constant_pool_reference_p (operands[1])"
2284 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2287 ;; %%% Kill this when call knows how to work this out.
2289 [(set (match_operand:SF 0 "push_operand" "")
2290 (match_operand:SF 1 "any_fp_register_operand" ""))]
2292 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2293 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2296 [(set (match_operand:SF 0 "push_operand" "")
2297 (match_operand:SF 1 "any_fp_register_operand" ""))]
2299 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2300 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2302 (define_insn "*movsf_1"
2303 [(set (match_operand:SF 0 "nonimmediate_operand"
2304 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2305 (match_operand:SF 1 "general_operand"
2306 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2307 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2308 && (reload_in_progress || reload_completed
2309 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2310 || GET_CODE (operands[1]) != CONST_DOUBLE
2311 || memory_operand (operands[0], SFmode))"
2313 switch (which_alternative)
2316 return output_387_reg_move (insn, operands);
2319 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2320 return "fstp%z0\t%y0";
2322 return "fst%z0\t%y0";
2325 return standard_80387_constant_opcode (operands[1]);
2329 return "mov{l}\t{%1, %0|%0, %1}";
2331 if (get_attr_mode (insn) == MODE_TI)
2332 return "pxor\t%0, %0";
2334 return "xorps\t%0, %0";
2336 if (get_attr_mode (insn) == MODE_V4SF)
2337 return "movaps\t{%1, %0|%0, %1}";
2339 return "movss\t{%1, %0|%0, %1}";
2342 return "movss\t{%1, %0|%0, %1}";
2346 return "movd\t{%1, %0|%0, %1}";
2349 return "movq\t{%1, %0|%0, %1}";
2355 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2357 (cond [(eq_attr "alternative" "3,4,9,10")
2359 (eq_attr "alternative" "5")
2361 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2363 (ne (symbol_ref "TARGET_SSE2")
2365 (eq (symbol_ref "optimize_size")
2368 (const_string "V4SF"))
2369 /* For architectures resolving dependencies on
2370 whole SSE registers use APS move to break dependency
2371 chains, otherwise use short move to avoid extra work.
2373 Do the same for architectures resolving dependencies on
2374 the parts. While in DF mode it is better to always handle
2375 just register parts, the SF mode is different due to lack
2376 of instructions to load just part of the register. It is
2377 better to maintain the whole registers in single format
2378 to avoid problems on using packed logical operations. */
2379 (eq_attr "alternative" "6")
2381 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2383 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2385 (const_string "V4SF")
2386 (const_string "SF"))
2387 (eq_attr "alternative" "11")
2388 (const_string "DI")]
2389 (const_string "SF")))])
2391 (define_insn "*swapsf"
2392 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2393 (match_operand:SF 1 "fp_register_operand" "+f"))
2396 "reload_completed || TARGET_80387"
2398 if (STACK_TOP_P (operands[0]))
2403 [(set_attr "type" "fxch")
2404 (set_attr "mode" "SF")])
2406 (define_expand "movdf"
2407 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2408 (match_operand:DF 1 "general_operand" ""))]
2410 "ix86_expand_move (DFmode, operands); DONE;")
2412 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2413 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2414 ;; On the average, pushdf using integers can be still shorter. Allow this
2415 ;; pattern for optimize_size too.
2417 (define_insn "*pushdf_nointeger"
2418 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2419 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2420 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2422 /* This insn should be already split before reg-stack. */
2425 [(set_attr "type" "multi")
2426 (set_attr "unit" "i387,*,*,*")
2427 (set_attr "mode" "DF,SI,SI,DF")])
2429 (define_insn "*pushdf_integer"
2430 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2431 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2432 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2434 /* This insn should be already split before reg-stack. */
2437 [(set_attr "type" "multi")
2438 (set_attr "unit" "i387,*,*")
2439 (set_attr "mode" "DF,SI,DF")])
2441 ;; %%% Kill this when call knows how to work this out.
2443 [(set (match_operand:DF 0 "push_operand" "")
2444 (match_operand:DF 1 "any_fp_register_operand" ""))]
2445 "!TARGET_64BIT && reload_completed"
2446 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2447 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2451 [(set (match_operand:DF 0 "push_operand" "")
2452 (match_operand:DF 1 "any_fp_register_operand" ""))]
2453 "TARGET_64BIT && reload_completed"
2454 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2455 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2459 [(set (match_operand:DF 0 "push_operand" "")
2460 (match_operand:DF 1 "general_operand" ""))]
2463 "ix86_split_long_move (operands); DONE;")
2465 ;; Moving is usually shorter when only FP registers are used. This separate
2466 ;; movdf pattern avoids the use of integer registers for FP operations
2467 ;; when optimizing for size.
2469 (define_insn "*movdf_nointeger"
2470 [(set (match_operand:DF 0 "nonimmediate_operand"
2471 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2472 (match_operand:DF 1 "general_operand"
2473 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2474 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2475 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2476 && (reload_in_progress || reload_completed
2477 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2478 || GET_CODE (operands[1]) != CONST_DOUBLE
2479 || memory_operand (operands[0], DFmode))"
2481 switch (which_alternative)
2484 return output_387_reg_move (insn, operands);
2487 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2488 return "fstp%z0\t%y0";
2490 return "fst%z0\t%y0";
2493 return standard_80387_constant_opcode (operands[1]);
2499 switch (get_attr_mode (insn))
2502 return "xorps\t%0, %0";
2504 return "xorpd\t%0, %0";
2506 return "pxor\t%0, %0";
2513 switch (get_attr_mode (insn))
2516 return "movaps\t{%1, %0|%0, %1}";
2518 return "movapd\t{%1, %0|%0, %1}";
2520 return "movdqa\t{%1, %0|%0, %1}";
2522 return "movq\t{%1, %0|%0, %1}";
2524 return "movsd\t{%1, %0|%0, %1}";
2526 return "movlpd\t{%1, %0|%0, %1}";
2528 return "movlps\t{%1, %0|%0, %1}";
2537 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2539 (cond [(eq_attr "alternative" "0,1,2")
2541 (eq_attr "alternative" "3,4")
2544 /* For SSE1, we have many fewer alternatives. */
2545 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2546 (cond [(eq_attr "alternative" "5,6")
2547 (const_string "V4SF")
2549 (const_string "V2SF"))
2551 /* xorps is one byte shorter. */
2552 (eq_attr "alternative" "5")
2553 (cond [(ne (symbol_ref "optimize_size")
2555 (const_string "V4SF")
2556 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2560 (const_string "V2DF"))
2562 /* For architectures resolving dependencies on
2563 whole SSE registers use APD move to break dependency
2564 chains, otherwise use short move to avoid extra work.
2566 movaps encodes one byte shorter. */
2567 (eq_attr "alternative" "6")
2569 [(ne (symbol_ref "optimize_size")
2571 (const_string "V4SF")
2572 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2574 (const_string "V2DF")
2576 (const_string "DF"))
2577 /* For architectures resolving dependencies on register
2578 parts we may avoid extra work to zero out upper part
2580 (eq_attr "alternative" "7")
2582 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2584 (const_string "V1DF")
2585 (const_string "DF"))
2587 (const_string "DF")))])
2589 (define_insn "*movdf_integer"
2590 [(set (match_operand:DF 0 "nonimmediate_operand"
2591 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2592 (match_operand:DF 1 "general_operand"
2593 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2594 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2595 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2596 && (reload_in_progress || reload_completed
2597 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2598 || GET_CODE (operands[1]) != CONST_DOUBLE
2599 || memory_operand (operands[0], DFmode))"
2601 switch (which_alternative)
2604 return output_387_reg_move (insn, operands);
2607 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2608 return "fstp%z0\t%y0";
2610 return "fst%z0\t%y0";
2613 return standard_80387_constant_opcode (operands[1]);
2620 switch (get_attr_mode (insn))
2623 return "xorps\t%0, %0";
2625 return "xorpd\t%0, %0";
2627 return "pxor\t%0, %0";
2634 switch (get_attr_mode (insn))
2637 return "movaps\t{%1, %0|%0, %1}";
2639 return "movapd\t{%1, %0|%0, %1}";
2641 return "movdqa\t{%1, %0|%0, %1}";
2643 return "movq\t{%1, %0|%0, %1}";
2645 return "movsd\t{%1, %0|%0, %1}";
2647 return "movlpd\t{%1, %0|%0, %1}";
2649 return "movlps\t{%1, %0|%0, %1}";
2658 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2660 (cond [(eq_attr "alternative" "0,1,2")
2662 (eq_attr "alternative" "3,4")
2665 /* For SSE1, we have many fewer alternatives. */
2666 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2667 (cond [(eq_attr "alternative" "5,6")
2668 (const_string "V4SF")
2670 (const_string "V2SF"))
2672 /* xorps is one byte shorter. */
2673 (eq_attr "alternative" "5")
2674 (cond [(ne (symbol_ref "optimize_size")
2676 (const_string "V4SF")
2677 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2681 (const_string "V2DF"))
2683 /* For architectures resolving dependencies on
2684 whole SSE registers use APD move to break dependency
2685 chains, otherwise use short move to avoid extra work.
2687 movaps encodes one byte shorter. */
2688 (eq_attr "alternative" "6")
2690 [(ne (symbol_ref "optimize_size")
2692 (const_string "V4SF")
2693 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2695 (const_string "V2DF")
2697 (const_string "DF"))
2698 /* For architectures resolving dependencies on register
2699 parts we may avoid extra work to zero out upper part
2701 (eq_attr "alternative" "7")
2703 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2705 (const_string "V1DF")
2706 (const_string "DF"))
2708 (const_string "DF")))])
2711 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2712 (match_operand:DF 1 "general_operand" ""))]
2714 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2715 && ! (ANY_FP_REG_P (operands[0]) ||
2716 (GET_CODE (operands[0]) == SUBREG
2717 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2718 && ! (ANY_FP_REG_P (operands[1]) ||
2719 (GET_CODE (operands[1]) == SUBREG
2720 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2722 "ix86_split_long_move (operands); DONE;")
2724 (define_insn "*swapdf"
2725 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2726 (match_operand:DF 1 "fp_register_operand" "+f"))
2729 "reload_completed || TARGET_80387"
2731 if (STACK_TOP_P (operands[0]))
2736 [(set_attr "type" "fxch")
2737 (set_attr "mode" "DF")])
2739 (define_expand "movxf"
2740 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2741 (match_operand:XF 1 "general_operand" ""))]
2743 "ix86_expand_move (XFmode, operands); DONE;")
2745 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2746 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2747 ;; Pushing using integer instructions is longer except for constants
2748 ;; and direct memory references.
2749 ;; (assuming that any given constant is pushed only once, but this ought to be
2750 ;; handled elsewhere).
2752 (define_insn "*pushxf_nointeger"
2753 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2754 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2757 /* This insn should be already split before reg-stack. */
2760 [(set_attr "type" "multi")
2761 (set_attr "unit" "i387,*,*")
2762 (set_attr "mode" "XF,SI,SI")])
2764 (define_insn "*pushxf_integer"
2765 [(set (match_operand:XF 0 "push_operand" "=<,<")
2766 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2769 /* This insn should be already split before reg-stack. */
2772 [(set_attr "type" "multi")
2773 (set_attr "unit" "i387,*")
2774 (set_attr "mode" "XF,SI")])
2777 [(set (match_operand 0 "push_operand" "")
2778 (match_operand 1 "general_operand" ""))]
2780 && (GET_MODE (operands[0]) == XFmode
2781 || GET_MODE (operands[0]) == DFmode)
2782 && !ANY_FP_REG_P (operands[1])"
2784 "ix86_split_long_move (operands); DONE;")
2787 [(set (match_operand:XF 0 "push_operand" "")
2788 (match_operand:XF 1 "any_fp_register_operand" ""))]
2790 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2791 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2792 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2795 [(set (match_operand:XF 0 "push_operand" "")
2796 (match_operand:XF 1 "any_fp_register_operand" ""))]
2798 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2799 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2800 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2802 ;; Do not use integer registers when optimizing for size
2803 (define_insn "*movxf_nointeger"
2804 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2805 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2807 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2808 && (reload_in_progress || reload_completed
2809 || GET_CODE (operands[1]) != CONST_DOUBLE
2810 || memory_operand (operands[0], XFmode))"
2812 switch (which_alternative)
2815 return output_387_reg_move (insn, operands);
2818 /* There is no non-popping store to memory for XFmode. So if
2819 we need one, follow the store with a load. */
2820 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2821 return "fstp%z0\t%y0\;fld%z0\t%y0";
2823 return "fstp%z0\t%y0";
2826 return standard_80387_constant_opcode (operands[1]);
2834 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2835 (set_attr "mode" "XF,XF,XF,SI,SI")])
2837 (define_insn "*movxf_integer"
2838 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2839 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2841 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2842 && (reload_in_progress || reload_completed
2843 || GET_CODE (operands[1]) != CONST_DOUBLE
2844 || memory_operand (operands[0], XFmode))"
2846 switch (which_alternative)
2849 return output_387_reg_move (insn, operands);
2852 /* There is no non-popping store to memory for XFmode. So if
2853 we need one, follow the store with a load. */
2854 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2855 return "fstp%z0\t%y0\;fld%z0\t%y0";
2857 return "fstp%z0\t%y0";
2860 return standard_80387_constant_opcode (operands[1]);
2869 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2870 (set_attr "mode" "XF,XF,XF,SI,SI")])
2873 [(set (match_operand 0 "nonimmediate_operand" "")
2874 (match_operand 1 "general_operand" ""))]
2876 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2877 && GET_MODE (operands[0]) == XFmode
2878 && ! (ANY_FP_REG_P (operands[0]) ||
2879 (GET_CODE (operands[0]) == SUBREG
2880 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2881 && ! (ANY_FP_REG_P (operands[1]) ||
2882 (GET_CODE (operands[1]) == SUBREG
2883 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2885 "ix86_split_long_move (operands); DONE;")
2888 [(set (match_operand 0 "register_operand" "")
2889 (match_operand 1 "memory_operand" ""))]
2891 && GET_CODE (operands[1]) == MEM
2892 && (GET_MODE (operands[0]) == XFmode
2893 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2894 && constant_pool_reference_p (operands[1])"
2895 [(set (match_dup 0) (match_dup 1))]
2897 rtx c = avoid_constant_pool_reference (operands[1]);
2898 rtx r = operands[0];
2900 if (GET_CODE (r) == SUBREG)
2905 if (!standard_sse_constant_p (c))
2908 else if (FP_REG_P (r))
2910 if (!standard_80387_constant_p (c))
2913 else if (MMX_REG_P (r))
2919 (define_insn "swapxf"
2920 [(set (match_operand:XF 0 "register_operand" "+f")
2921 (match_operand:XF 1 "register_operand" "+f"))
2926 if (STACK_TOP_P (operands[0]))
2931 [(set_attr "type" "fxch")
2932 (set_attr "mode" "XF")])
2934 (define_expand "movtf"
2935 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2936 (match_operand:TF 1 "nonimmediate_operand" ""))]
2939 ix86_expand_move (TFmode, operands);
2943 (define_insn "*movtf_internal"
2944 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2945 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2947 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2949 switch (which_alternative)
2955 if (get_attr_mode (insn) == MODE_V4SF)
2956 return "xorps\t%0, %0";
2958 return "pxor\t%0, %0";
2961 if (get_attr_mode (insn) == MODE_V4SF)
2962 return "movaps\t{%1, %0|%0, %1}";
2964 return "movdqa\t{%1, %0|%0, %1}";
2969 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2971 (cond [(eq_attr "alternative" "2,3")
2973 (ne (symbol_ref "optimize_size")
2975 (const_string "V4SF")
2976 (const_string "TI"))
2977 (eq_attr "alternative" "4")
2979 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2981 (ne (symbol_ref "optimize_size")
2983 (const_string "V4SF")
2984 (const_string "TI"))]
2985 (const_string "DI")))])
2988 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2989 (match_operand:TF 1 "general_operand" ""))]
2990 "reload_completed && !SSE_REG_P (operands[0])
2991 && !SSE_REG_P (operands[1])"
2993 "ix86_split_long_move (operands); DONE;")
2995 ;; Zero extension instructions
2997 (define_expand "zero_extendhisi2"
2998 [(set (match_operand:SI 0 "register_operand" "")
2999 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3002 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3004 operands[1] = force_reg (HImode, operands[1]);
3005 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3010 (define_insn "zero_extendhisi2_and"
3011 [(set (match_operand:SI 0 "register_operand" "=r")
3012 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3013 (clobber (reg:CC FLAGS_REG))]
3014 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3016 [(set_attr "type" "alu1")
3017 (set_attr "mode" "SI")])
3020 [(set (match_operand:SI 0 "register_operand" "")
3021 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3022 (clobber (reg:CC FLAGS_REG))]
3023 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3024 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3025 (clobber (reg:CC FLAGS_REG))])]
3028 (define_insn "*zero_extendhisi2_movzwl"
3029 [(set (match_operand:SI 0 "register_operand" "=r")
3030 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3031 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3032 "movz{wl|x}\t{%1, %0|%0, %1}"
3033 [(set_attr "type" "imovx")
3034 (set_attr "mode" "SI")])
3036 (define_expand "zero_extendqihi2"
3038 [(set (match_operand:HI 0 "register_operand" "")
3039 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3040 (clobber (reg:CC FLAGS_REG))])]
3044 (define_insn "*zero_extendqihi2_and"
3045 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3046 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3047 (clobber (reg:CC FLAGS_REG))]
3048 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3050 [(set_attr "type" "alu1")
3051 (set_attr "mode" "HI")])
3053 (define_insn "*zero_extendqihi2_movzbw_and"
3054 [(set (match_operand:HI 0 "register_operand" "=r,r")
3055 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3056 (clobber (reg:CC FLAGS_REG))]
3057 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3059 [(set_attr "type" "imovx,alu1")
3060 (set_attr "mode" "HI")])
3062 ; zero extend to SImode here to avoid partial register stalls
3063 (define_insn "*zero_extendqihi2_movzbl"
3064 [(set (match_operand:HI 0 "register_operand" "=r")
3065 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3066 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3067 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3068 [(set_attr "type" "imovx")
3069 (set_attr "mode" "SI")])
3071 ;; For the movzbw case strip only the clobber
3073 [(set (match_operand:HI 0 "register_operand" "")
3074 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3075 (clobber (reg:CC FLAGS_REG))]
3077 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3078 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3079 [(set (match_operand:HI 0 "register_operand" "")
3080 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3082 ;; When source and destination does not overlap, clear destination
3083 ;; first and then do the movb
3085 [(set (match_operand:HI 0 "register_operand" "")
3086 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3087 (clobber (reg:CC FLAGS_REG))]
3089 && ANY_QI_REG_P (operands[0])
3090 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3091 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3092 [(set (match_dup 0) (const_int 0))
3093 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3094 "operands[2] = gen_lowpart (QImode, operands[0]);")
3096 ;; Rest is handled by single and.
3098 [(set (match_operand:HI 0 "register_operand" "")
3099 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3100 (clobber (reg:CC FLAGS_REG))]
3102 && true_regnum (operands[0]) == true_regnum (operands[1])"
3103 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3104 (clobber (reg:CC FLAGS_REG))])]
3107 (define_expand "zero_extendqisi2"
3109 [(set (match_operand:SI 0 "register_operand" "")
3110 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3111 (clobber (reg:CC FLAGS_REG))])]
3115 (define_insn "*zero_extendqisi2_and"
3116 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3117 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3118 (clobber (reg:CC FLAGS_REG))]
3119 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3121 [(set_attr "type" "alu1")
3122 (set_attr "mode" "SI")])
3124 (define_insn "*zero_extendqisi2_movzbw_and"
3125 [(set (match_operand:SI 0 "register_operand" "=r,r")
3126 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3127 (clobber (reg:CC FLAGS_REG))]
3128 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3130 [(set_attr "type" "imovx,alu1")
3131 (set_attr "mode" "SI")])
3133 (define_insn "*zero_extendqisi2_movzbw"
3134 [(set (match_operand:SI 0 "register_operand" "=r")
3135 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3136 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3137 "movz{bl|x}\t{%1, %0|%0, %1}"
3138 [(set_attr "type" "imovx")
3139 (set_attr "mode" "SI")])
3141 ;; For the movzbl case strip only the clobber
3143 [(set (match_operand:SI 0 "register_operand" "")
3144 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3145 (clobber (reg:CC FLAGS_REG))]
3147 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3148 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3150 (zero_extend:SI (match_dup 1)))])
3152 ;; When source and destination does not overlap, clear destination
3153 ;; first and then do the movb
3155 [(set (match_operand:SI 0 "register_operand" "")
3156 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3157 (clobber (reg:CC FLAGS_REG))]
3159 && ANY_QI_REG_P (operands[0])
3160 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3161 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3162 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3163 [(set (match_dup 0) (const_int 0))
3164 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3165 "operands[2] = gen_lowpart (QImode, operands[0]);")
3167 ;; Rest is handled by single and.
3169 [(set (match_operand:SI 0 "register_operand" "")
3170 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3171 (clobber (reg:CC FLAGS_REG))]
3173 && true_regnum (operands[0]) == true_regnum (operands[1])"
3174 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3175 (clobber (reg:CC FLAGS_REG))])]
3178 ;; %%% Kill me once multi-word ops are sane.
3179 (define_expand "zero_extendsidi2"
3180 [(set (match_operand:DI 0 "register_operand" "=r")
3181 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3185 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3190 (define_insn "zero_extendsidi2_32"
3191 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3192 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3193 (clobber (reg:CC FLAGS_REG))]
3199 movd\t{%1, %0|%0, %1}
3200 movd\t{%1, %0|%0, %1}"
3201 [(set_attr "mode" "SI,SI,SI,DI,TI")
3202 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3204 (define_insn "zero_extendsidi2_rex64"
3205 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3206 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3209 mov\t{%k1, %k0|%k0, %k1}
3211 movd\t{%1, %0|%0, %1}
3212 movd\t{%1, %0|%0, %1}"
3213 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3214 (set_attr "mode" "SI,DI,SI,SI")])
3217 [(set (match_operand:DI 0 "memory_operand" "")
3218 (zero_extend:DI (match_dup 0)))]
3220 [(set (match_dup 4) (const_int 0))]
3221 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3224 [(set (match_operand:DI 0 "register_operand" "")
3225 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3226 (clobber (reg:CC FLAGS_REG))]
3227 "!TARGET_64BIT && reload_completed
3228 && true_regnum (operands[0]) == true_regnum (operands[1])"
3229 [(set (match_dup 4) (const_int 0))]
3230 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3233 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3234 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3235 (clobber (reg:CC FLAGS_REG))]
3236 "!TARGET_64BIT && reload_completed
3237 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3238 [(set (match_dup 3) (match_dup 1))
3239 (set (match_dup 4) (const_int 0))]
3240 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3242 (define_insn "zero_extendhidi2"
3243 [(set (match_operand:DI 0 "register_operand" "=r")
3244 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3246 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3247 [(set_attr "type" "imovx")
3248 (set_attr "mode" "DI")])
3250 (define_insn "zero_extendqidi2"
3251 [(set (match_operand:DI 0 "register_operand" "=r")
3252 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3254 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3255 [(set_attr "type" "imovx")
3256 (set_attr "mode" "DI")])
3258 ;; Sign extension instructions
3260 (define_expand "extendsidi2"
3261 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3262 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3263 (clobber (reg:CC FLAGS_REG))
3264 (clobber (match_scratch:SI 2 ""))])]
3269 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3274 (define_insn "*extendsidi2_1"
3275 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3276 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3277 (clobber (reg:CC FLAGS_REG))
3278 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3282 (define_insn "extendsidi2_rex64"
3283 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3284 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3288 movs{lq|x}\t{%1,%0|%0, %1}"
3289 [(set_attr "type" "imovx")
3290 (set_attr "mode" "DI")
3291 (set_attr "prefix_0f" "0")
3292 (set_attr "modrm" "0,1")])
3294 (define_insn "extendhidi2"
3295 [(set (match_operand:DI 0 "register_operand" "=r")
3296 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3298 "movs{wq|x}\t{%1,%0|%0, %1}"
3299 [(set_attr "type" "imovx")
3300 (set_attr "mode" "DI")])
3302 (define_insn "extendqidi2"
3303 [(set (match_operand:DI 0 "register_operand" "=r")
3304 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3306 "movs{bq|x}\t{%1,%0|%0, %1}"
3307 [(set_attr "type" "imovx")
3308 (set_attr "mode" "DI")])
3310 ;; Extend to memory case when source register does die.
3312 [(set (match_operand:DI 0 "memory_operand" "")
3313 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3314 (clobber (reg:CC FLAGS_REG))
3315 (clobber (match_operand:SI 2 "register_operand" ""))]
3317 && dead_or_set_p (insn, operands[1])
3318 && !reg_mentioned_p (operands[1], operands[0]))"
3319 [(set (match_dup 3) (match_dup 1))
3320 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3321 (clobber (reg:CC FLAGS_REG))])
3322 (set (match_dup 4) (match_dup 1))]
3323 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3325 ;; Extend to memory case when source register does not die.
3327 [(set (match_operand:DI 0 "memory_operand" "")
3328 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3329 (clobber (reg:CC FLAGS_REG))
3330 (clobber (match_operand:SI 2 "register_operand" ""))]
3334 split_di (&operands[0], 1, &operands[3], &operands[4]);
3336 emit_move_insn (operands[3], operands[1]);
3338 /* Generate a cltd if possible and doing so it profitable. */
3339 if (true_regnum (operands[1]) == 0
3340 && true_regnum (operands[2]) == 1
3341 && (optimize_size || TARGET_USE_CLTD))
3343 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3347 emit_move_insn (operands[2], operands[1]);
3348 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3350 emit_move_insn (operands[4], operands[2]);
3354 ;; Extend to register case. Optimize case where source and destination
3355 ;; registers match and cases where we can use cltd.
3357 [(set (match_operand:DI 0 "register_operand" "")
3358 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3359 (clobber (reg:CC FLAGS_REG))
3360 (clobber (match_scratch:SI 2 ""))]
3364 split_di (&operands[0], 1, &operands[3], &operands[4]);
3366 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3367 emit_move_insn (operands[3], operands[1]);
3369 /* Generate a cltd if possible and doing so it profitable. */
3370 if (true_regnum (operands[3]) == 0
3371 && (optimize_size || TARGET_USE_CLTD))
3373 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3377 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3378 emit_move_insn (operands[4], operands[1]);
3380 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3384 (define_insn "extendhisi2"
3385 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3386 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3389 switch (get_attr_prefix_0f (insn))
3392 return "{cwtl|cwde}";
3394 return "movs{wl|x}\t{%1,%0|%0, %1}";
3397 [(set_attr "type" "imovx")
3398 (set_attr "mode" "SI")
3399 (set (attr "prefix_0f")
3400 ;; movsx is short decodable while cwtl is vector decoded.
3401 (if_then_else (and (eq_attr "cpu" "!k6")
3402 (eq_attr "alternative" "0"))
3404 (const_string "1")))
3406 (if_then_else (eq_attr "prefix_0f" "0")
3408 (const_string "1")))])
3410 (define_insn "*extendhisi2_zext"
3411 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3413 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3416 switch (get_attr_prefix_0f (insn))
3419 return "{cwtl|cwde}";
3421 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3424 [(set_attr "type" "imovx")
3425 (set_attr "mode" "SI")
3426 (set (attr "prefix_0f")
3427 ;; movsx is short decodable while cwtl is vector decoded.
3428 (if_then_else (and (eq_attr "cpu" "!k6")
3429 (eq_attr "alternative" "0"))
3431 (const_string "1")))
3433 (if_then_else (eq_attr "prefix_0f" "0")
3435 (const_string "1")))])
3437 (define_insn "extendqihi2"
3438 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3439 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3442 switch (get_attr_prefix_0f (insn))
3445 return "{cbtw|cbw}";
3447 return "movs{bw|x}\t{%1,%0|%0, %1}";
3450 [(set_attr "type" "imovx")
3451 (set_attr "mode" "HI")
3452 (set (attr "prefix_0f")
3453 ;; movsx is short decodable while cwtl is vector decoded.
3454 (if_then_else (and (eq_attr "cpu" "!k6")
3455 (eq_attr "alternative" "0"))
3457 (const_string "1")))
3459 (if_then_else (eq_attr "prefix_0f" "0")
3461 (const_string "1")))])
3463 (define_insn "extendqisi2"
3464 [(set (match_operand:SI 0 "register_operand" "=r")
3465 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3467 "movs{bl|x}\t{%1,%0|%0, %1}"
3468 [(set_attr "type" "imovx")
3469 (set_attr "mode" "SI")])
3471 (define_insn "*extendqisi2_zext"
3472 [(set (match_operand:DI 0 "register_operand" "=r")
3474 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3476 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3477 [(set_attr "type" "imovx")
3478 (set_attr "mode" "SI")])
3480 ;; Conversions between float and double.
3482 ;; These are all no-ops in the model used for the 80387. So just
3485 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3486 (define_insn "*dummy_extendsfdf2"
3487 [(set (match_operand:DF 0 "push_operand" "=<")
3488 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3493 [(set (match_operand:DF 0 "push_operand" "")
3494 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3496 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3497 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3500 [(set (match_operand:DF 0 "push_operand" "")
3501 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3503 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3504 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3506 (define_insn "*dummy_extendsfxf2"
3507 [(set (match_operand:XF 0 "push_operand" "=<")
3508 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3513 [(set (match_operand:XF 0 "push_operand" "")
3514 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3516 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3517 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3518 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3521 [(set (match_operand:XF 0 "push_operand" "")
3522 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3524 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3525 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3526 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3529 [(set (match_operand:XF 0 "push_operand" "")
3530 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3532 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3533 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3534 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3537 [(set (match_operand:XF 0 "push_operand" "")
3538 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3540 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3541 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3542 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3544 (define_expand "extendsfdf2"
3545 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3546 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3547 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3549 /* ??? Needed for compress_float_constant since all fp constants
3550 are LEGITIMATE_CONSTANT_P. */
3551 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3553 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3554 && standard_80387_constant_p (operands[1]) > 0)
3556 operands[1] = simplify_const_unary_operation
3557 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3558 emit_move_insn_1 (operands[0], operands[1]);
3561 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3563 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3564 operands[1] = force_reg (SFmode, operands[1]);
3567 (define_insn "*extendsfdf2_mixed"
3568 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3569 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3570 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3571 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3573 switch (which_alternative)
3576 return output_387_reg_move (insn, operands);
3579 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3580 return "fstp%z0\t%y0";
3582 return "fst%z0\t%y0";
3585 return "cvtss2sd\t{%1, %0|%0, %1}";
3591 [(set_attr "type" "fmov,fmov,ssecvt")
3592 (set_attr "mode" "SF,XF,DF")])
3594 (define_insn "*extendsfdf2_sse"
3595 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3596 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3597 "TARGET_SSE2 && TARGET_SSE_MATH
3598 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3599 "cvtss2sd\t{%1, %0|%0, %1}"
3600 [(set_attr "type" "ssecvt")
3601 (set_attr "mode" "DF")])
3603 (define_insn "*extendsfdf2_i387"
3604 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3605 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3607 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3609 switch (which_alternative)
3612 return output_387_reg_move (insn, operands);
3615 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3616 return "fstp%z0\t%y0";
3618 return "fst%z0\t%y0";
3624 [(set_attr "type" "fmov")
3625 (set_attr "mode" "SF,XF")])
3627 (define_expand "extendsfxf2"
3628 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3629 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3632 /* ??? Needed for compress_float_constant since all fp constants
3633 are LEGITIMATE_CONSTANT_P. */
3634 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3636 if (standard_80387_constant_p (operands[1]) > 0)
3638 operands[1] = simplify_const_unary_operation
3639 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3640 emit_move_insn_1 (operands[0], operands[1]);
3643 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3645 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3646 operands[1] = force_reg (SFmode, operands[1]);
3649 (define_insn "*extendsfxf2_i387"
3650 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3651 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3653 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3655 switch (which_alternative)
3658 return output_387_reg_move (insn, operands);
3661 /* There is no non-popping store to memory for XFmode. So if
3662 we need one, follow the store with a load. */
3663 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3664 return "fstp%z0\t%y0";
3666 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3672 [(set_attr "type" "fmov")
3673 (set_attr "mode" "SF,XF")])
3675 (define_expand "extenddfxf2"
3676 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3677 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3680 /* ??? Needed for compress_float_constant since all fp constants
3681 are LEGITIMATE_CONSTANT_P. */
3682 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3684 if (standard_80387_constant_p (operands[1]) > 0)
3686 operands[1] = simplify_const_unary_operation
3687 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3688 emit_move_insn_1 (operands[0], operands[1]);
3691 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3693 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3694 operands[1] = force_reg (DFmode, operands[1]);
3697 (define_insn "*extenddfxf2_i387"
3698 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3699 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3701 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3703 switch (which_alternative)
3706 return output_387_reg_move (insn, operands);
3709 /* There is no non-popping store to memory for XFmode. So if
3710 we need one, follow the store with a load. */
3711 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3714 return "fstp%z0\t%y0";
3720 [(set_attr "type" "fmov")
3721 (set_attr "mode" "DF,XF")])
3723 ;; %%% This seems bad bad news.
3724 ;; This cannot output into an f-reg because there is no way to be sure
3725 ;; of truncating in that case. Otherwise this is just like a simple move
3726 ;; insn. So we pretend we can output to a reg in order to get better
3727 ;; register preferencing, but we really use a stack slot.
3729 ;; Conversion from DFmode to SFmode.
3731 (define_expand "truncdfsf2"
3732 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3734 (match_operand:DF 1 "nonimmediate_operand" "")))]
3735 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3737 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3738 operands[1] = force_reg (DFmode, operands[1]);
3740 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3742 else if (flag_unsafe_math_optimizations)
3746 rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3747 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3752 (define_expand "truncdfsf2_with_temp"
3753 [(parallel [(set (match_operand:SF 0 "" "")
3754 (float_truncate:SF (match_operand:DF 1 "" "")))
3755 (clobber (match_operand:SF 2 "" ""))])]
3758 (define_insn "*truncdfsf_fast_mixed"
3759 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3761 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3762 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3764 switch (which_alternative)
3767 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3768 return "fstp%z0\t%y0";
3770 return "fst%z0\t%y0";
3772 return output_387_reg_move (insn, operands);
3774 return "cvtsd2ss\t{%1, %0|%0, %1}";
3779 [(set_attr "type" "fmov,fmov,ssecvt")
3780 (set_attr "mode" "SF")])
3782 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3783 ;; because nothing we do here is unsafe.
3784 (define_insn "*truncdfsf_fast_sse"
3785 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3787 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3788 "TARGET_SSE2 && TARGET_SSE_MATH"
3789 "cvtsd2ss\t{%1, %0|%0, %1}"
3790 [(set_attr "type" "ssecvt")
3791 (set_attr "mode" "SF")])
3793 (define_insn "*truncdfsf_fast_i387"
3794 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3796 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3797 "TARGET_80387 && flag_unsafe_math_optimizations"
3798 "* return output_387_reg_move (insn, operands);"
3799 [(set_attr "type" "fmov")
3800 (set_attr "mode" "SF")])
3802 (define_insn "*truncdfsf_mixed"
3803 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3805 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3806 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3807 "TARGET_MIX_SSE_I387"
3809 switch (which_alternative)
3812 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3813 return "fstp%z0\t%y0";
3815 return "fst%z0\t%y0";
3819 return "cvtsd2ss\t{%1, %0|%0, %1}";
3824 [(set_attr "type" "fmov,multi,ssecvt")
3825 (set_attr "unit" "*,i387,*")
3826 (set_attr "mode" "SF")])
3828 (define_insn "*truncdfsf_i387"
3829 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3831 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3832 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3835 switch (which_alternative)
3838 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3839 return "fstp%z0\t%y0";
3841 return "fst%z0\t%y0";
3848 [(set_attr "type" "fmov,multi")
3849 (set_attr "unit" "*,i387")
3850 (set_attr "mode" "SF")])
3852 (define_insn "*truncdfsf2_i387_1"
3853 [(set (match_operand:SF 0 "memory_operand" "=m")
3855 (match_operand:DF 1 "register_operand" "f")))]
3857 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3858 && !TARGET_MIX_SSE_I387"
3860 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3861 return "fstp%z0\t%y0";
3863 return "fst%z0\t%y0";
3865 [(set_attr "type" "fmov")
3866 (set_attr "mode" "SF")])
3869 [(set (match_operand:SF 0 "register_operand" "")
3871 (match_operand:DF 1 "fp_register_operand" "")))
3872 (clobber (match_operand 2 "" ""))]
3874 [(set (match_dup 2) (match_dup 1))
3875 (set (match_dup 0) (match_dup 2))]
3877 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3880 ;; Conversion from XFmode to SFmode.
3882 (define_expand "truncxfsf2"
3883 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3885 (match_operand:XF 1 "register_operand" "")))
3886 (clobber (match_dup 2))])]
3889 if (flag_unsafe_math_optimizations)
3891 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3892 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3893 if (reg != operands[0])
3894 emit_move_insn (operands[0], reg);
3898 operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3901 (define_insn "*truncxfsf2_mixed"
3902 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3904 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3905 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3906 "TARGET_MIX_SSE_I387"
3908 gcc_assert (!which_alternative);
3909 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910 return "fstp%z0\t%y0";
3912 return "fst%z0\t%y0";
3914 [(set_attr "type" "fmov,multi,multi,multi")
3915 (set_attr "unit" "*,i387,i387,i387")
3916 (set_attr "mode" "SF")])
3918 (define_insn "truncxfsf2_i387_noop"
3919 [(set (match_operand:SF 0 "register_operand" "=f")
3920 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3921 "TARGET_80387 && flag_unsafe_math_optimizations"
3923 return output_387_reg_move (insn, operands);
3925 [(set_attr "type" "fmov")
3926 (set_attr "mode" "SF")])
3928 (define_insn "*truncxfsf2_i387"
3929 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3931 (match_operand:XF 1 "register_operand" "f,f,f")))
3932 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3935 gcc_assert (!which_alternative);
3936 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3937 return "fstp%z0\t%y0";
3939 return "fst%z0\t%y0";
3941 [(set_attr "type" "fmov,multi,multi")
3942 (set_attr "unit" "*,i387,i387")
3943 (set_attr "mode" "SF")])
3945 (define_insn "*truncxfsf2_i387_1"
3946 [(set (match_operand:SF 0 "memory_operand" "=m")
3948 (match_operand:XF 1 "register_operand" "f")))]
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")
3957 (set_attr "mode" "SF")])
3960 [(set (match_operand:SF 0 "register_operand" "")
3962 (match_operand:XF 1 "register_operand" "")))
3963 (clobber (match_operand:SF 2 "memory_operand" ""))]
3964 "TARGET_80387 && reload_completed"
3965 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3966 (set (match_dup 0) (match_dup 2))]
3970 [(set (match_operand:SF 0 "memory_operand" "")
3972 (match_operand:XF 1 "register_operand" "")))
3973 (clobber (match_operand:SF 2 "memory_operand" ""))]
3975 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3978 ;; Conversion from XFmode to DFmode.
3980 (define_expand "truncxfdf2"
3981 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3983 (match_operand:XF 1 "register_operand" "")))
3984 (clobber (match_dup 2))])]
3987 if (flag_unsafe_math_optimizations)
3989 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3990 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3991 if (reg != operands[0])
3992 emit_move_insn (operands[0], reg);
3996 operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3999 (define_insn "*truncxfdf2_mixed"
4000 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4002 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4003 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4004 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4006 gcc_assert (!which_alternative);
4007 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4008 return "fstp%z0\t%y0";
4010 return "fst%z0\t%y0";
4012 [(set_attr "type" "fmov,multi,multi,multi")
4013 (set_attr "unit" "*,i387,i387,i387")
4014 (set_attr "mode" "DF")])
4016 (define_insn "truncxfdf2_i387_noop"
4017 [(set (match_operand:DF 0 "register_operand" "=f")
4018 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4019 "TARGET_80387 && flag_unsafe_math_optimizations"
4021 return output_387_reg_move (insn, operands);
4023 [(set_attr "type" "fmov")
4024 (set_attr "mode" "DF")])
4026 (define_insn "*truncxfdf2_i387"
4027 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4029 (match_operand:XF 1 "register_operand" "f,f,f")))
4030 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4033 gcc_assert (!which_alternative);
4034 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4035 return "fstp%z0\t%y0";
4037 return "fst%z0\t%y0";
4039 [(set_attr "type" "fmov,multi,multi")
4040 (set_attr "unit" "*,i387,i387")
4041 (set_attr "mode" "DF")])
4043 (define_insn "*truncxfdf2_i387_1"
4044 [(set (match_operand:DF 0 "memory_operand" "=m")
4046 (match_operand:XF 1 "register_operand" "f")))]
4049 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4050 return "fstp%z0\t%y0";
4052 return "fst%z0\t%y0";
4054 [(set_attr "type" "fmov")
4055 (set_attr "mode" "DF")])
4058 [(set (match_operand:DF 0 "register_operand" "")
4060 (match_operand:XF 1 "register_operand" "")))
4061 (clobber (match_operand:DF 2 "memory_operand" ""))]
4062 "TARGET_80387 && reload_completed"
4063 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4064 (set (match_dup 0) (match_dup 2))]
4068 [(set (match_operand:DF 0 "memory_operand" "")
4070 (match_operand:XF 1 "register_operand" "")))
4071 (clobber (match_operand:DF 2 "memory_operand" ""))]
4073 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4076 ;; Signed conversion to DImode.
4078 (define_expand "fix_truncxfdi2"
4079 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4080 (fix:DI (match_operand:XF 1 "register_operand" "")))
4081 (clobber (reg:CC FLAGS_REG))])]
4086 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4091 (define_expand "fix_trunc<mode>di2"
4092 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4093 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4094 (clobber (reg:CC FLAGS_REG))])]
4095 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4098 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4100 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4103 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4105 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4106 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4107 if (out != operands[0])
4108 emit_move_insn (operands[0], out);
4113 ;; Signed conversion to SImode.
4115 (define_expand "fix_truncxfsi2"
4116 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4117 (fix:SI (match_operand:XF 1 "register_operand" "")))
4118 (clobber (reg:CC FLAGS_REG))])]
4123 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4128 (define_expand "fix_trunc<mode>si2"
4129 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4130 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4131 (clobber (reg:CC FLAGS_REG))])]
4132 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4135 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4137 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4140 if (SSE_FLOAT_MODE_P (<MODE>mode))
4142 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4143 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4144 if (out != operands[0])
4145 emit_move_insn (operands[0], out);
4150 ;; Signed conversion to HImode.
4152 (define_expand "fix_trunc<mode>hi2"
4153 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4154 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4155 (clobber (reg:CC FLAGS_REG))])]
4157 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4161 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4166 ;; When SSE is available, it is always faster to use it!
4167 (define_insn "fix_truncsfdi_sse"
4168 [(set (match_operand:DI 0 "register_operand" "=r,r")
4169 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4170 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4171 "cvttss2si{q}\t{%1, %0|%0, %1}"
4172 [(set_attr "type" "sseicvt")
4173 (set_attr "mode" "SF")
4174 (set_attr "athlon_decode" "double,vector")
4175 (set_attr "amdfam10_decode" "double,double")])
4177 (define_insn "fix_truncdfdi_sse"
4178 [(set (match_operand:DI 0 "register_operand" "=r,r")
4179 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4180 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4181 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4182 [(set_attr "type" "sseicvt")
4183 (set_attr "mode" "DF")
4184 (set_attr "athlon_decode" "double,vector")
4185 (set_attr "amdfam10_decode" "double,double")])
4187 (define_insn "fix_truncsfsi_sse"
4188 [(set (match_operand:SI 0 "register_operand" "=r,r")
4189 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4190 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4191 "cvttss2si\t{%1, %0|%0, %1}"
4192 [(set_attr "type" "sseicvt")
4193 (set_attr "mode" "DF")
4194 (set_attr "athlon_decode" "double,vector")
4195 (set_attr "amdfam10_decode" "double,double")])
4197 (define_insn "fix_truncdfsi_sse"
4198 [(set (match_operand:SI 0 "register_operand" "=r,r")
4199 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4200 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4201 "cvttsd2si\t{%1, %0|%0, %1}"
4202 [(set_attr "type" "sseicvt")
4203 (set_attr "mode" "DF")
4204 (set_attr "athlon_decode" "double,vector")
4205 (set_attr "amdfam10_decode" "double,double")])
4207 ;; Avoid vector decoded forms of the instruction.
4209 [(match_scratch:DF 2 "Y")
4210 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4211 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4212 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4213 [(set (match_dup 2) (match_dup 1))
4214 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4218 [(match_scratch:SF 2 "x")
4219 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4220 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4221 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4222 [(set (match_dup 2) (match_dup 1))
4223 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4226 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4227 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4228 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4230 && FLOAT_MODE_P (GET_MODE (operands[1]))
4231 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4232 && (TARGET_64BIT || <MODE>mode != DImode))
4234 && !(reload_completed || reload_in_progress)"
4239 if (memory_operand (operands[0], VOIDmode))
4240 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4243 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4244 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4250 [(set_attr "type" "fisttp")
4251 (set_attr "mode" "<MODE>")])
4253 (define_insn "fix_trunc<mode>_i387_fisttp"
4254 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4255 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4256 (clobber (match_scratch:XF 2 "=&1f"))]
4258 && FLOAT_MODE_P (GET_MODE (operands[1]))
4259 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4260 && (TARGET_64BIT || <MODE>mode != DImode))
4261 && TARGET_SSE_MATH)"
4262 "* return output_fix_trunc (insn, operands, 1);"
4263 [(set_attr "type" "fisttp")
4264 (set_attr "mode" "<MODE>")])
4266 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4267 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4268 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4269 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4270 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4272 && FLOAT_MODE_P (GET_MODE (operands[1]))
4273 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4274 && (TARGET_64BIT || <MODE>mode != DImode))
4275 && TARGET_SSE_MATH)"
4277 [(set_attr "type" "fisttp")
4278 (set_attr "mode" "<MODE>")])
4281 [(set (match_operand:X87MODEI 0 "register_operand" "")
4282 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4283 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4284 (clobber (match_scratch 3 ""))]
4286 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4287 (clobber (match_dup 3))])
4288 (set (match_dup 0) (match_dup 2))]
4292 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4293 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4294 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4295 (clobber (match_scratch 3 ""))]
4297 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4298 (clobber (match_dup 3))])]
4301 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4302 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4303 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4304 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4305 ;; function in i386.c.
4306 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4307 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4308 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4309 (clobber (reg:CC FLAGS_REG))]
4310 "TARGET_80387 && !TARGET_FISTTP
4311 && FLOAT_MODE_P (GET_MODE (operands[1]))
4312 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4313 && (TARGET_64BIT || <MODE>mode != DImode))
4314 && !(reload_completed || reload_in_progress)"
4319 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4321 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4322 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4323 if (memory_operand (operands[0], VOIDmode))
4324 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4325 operands[2], operands[3]));
4328 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4329 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4330 operands[2], operands[3],
4335 [(set_attr "type" "fistp")
4336 (set_attr "i387_cw" "trunc")
4337 (set_attr "mode" "<MODE>")])
4339 (define_insn "fix_truncdi_i387"
4340 [(set (match_operand:DI 0 "memory_operand" "=m")
4341 (fix:DI (match_operand 1 "register_operand" "f")))
4342 (use (match_operand:HI 2 "memory_operand" "m"))
4343 (use (match_operand:HI 3 "memory_operand" "m"))
4344 (clobber (match_scratch:XF 4 "=&1f"))]
4345 "TARGET_80387 && !TARGET_FISTTP
4346 && FLOAT_MODE_P (GET_MODE (operands[1]))
4347 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4348 "* return output_fix_trunc (insn, operands, 0);"
4349 [(set_attr "type" "fistp")
4350 (set_attr "i387_cw" "trunc")
4351 (set_attr "mode" "DI")])
4353 (define_insn "fix_truncdi_i387_with_temp"
4354 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4355 (fix:DI (match_operand 1 "register_operand" "f,f")))
4356 (use (match_operand:HI 2 "memory_operand" "m,m"))
4357 (use (match_operand:HI 3 "memory_operand" "m,m"))
4358 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4359 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4360 "TARGET_80387 && !TARGET_FISTTP
4361 && FLOAT_MODE_P (GET_MODE (operands[1]))
4362 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4364 [(set_attr "type" "fistp")
4365 (set_attr "i387_cw" "trunc")
4366 (set_attr "mode" "DI")])
4369 [(set (match_operand:DI 0 "register_operand" "")
4370 (fix:DI (match_operand 1 "register_operand" "")))
4371 (use (match_operand:HI 2 "memory_operand" ""))
4372 (use (match_operand:HI 3 "memory_operand" ""))
4373 (clobber (match_operand:DI 4 "memory_operand" ""))
4374 (clobber (match_scratch 5 ""))]
4376 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4379 (clobber (match_dup 5))])
4380 (set (match_dup 0) (match_dup 4))]
4384 [(set (match_operand:DI 0 "memory_operand" "")
4385 (fix:DI (match_operand 1 "register_operand" "")))
4386 (use (match_operand:HI 2 "memory_operand" ""))
4387 (use (match_operand:HI 3 "memory_operand" ""))
4388 (clobber (match_operand:DI 4 "memory_operand" ""))
4389 (clobber (match_scratch 5 ""))]
4391 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4394 (clobber (match_dup 5))])]
4397 (define_insn "fix_trunc<mode>_i387"
4398 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4399 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4400 (use (match_operand:HI 2 "memory_operand" "m"))
4401 (use (match_operand:HI 3 "memory_operand" "m"))]
4402 "TARGET_80387 && !TARGET_FISTTP
4403 && FLOAT_MODE_P (GET_MODE (operands[1]))
4404 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4405 "* return output_fix_trunc (insn, operands, 0);"
4406 [(set_attr "type" "fistp")
4407 (set_attr "i387_cw" "trunc")
4408 (set_attr "mode" "<MODE>")])
4410 (define_insn "fix_trunc<mode>_i387_with_temp"
4411 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4412 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4413 (use (match_operand:HI 2 "memory_operand" "m,m"))
4414 (use (match_operand:HI 3 "memory_operand" "m,m"))
4415 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4416 "TARGET_80387 && !TARGET_FISTTP
4417 && FLOAT_MODE_P (GET_MODE (operands[1]))
4418 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4420 [(set_attr "type" "fistp")
4421 (set_attr "i387_cw" "trunc")
4422 (set_attr "mode" "<MODE>")])
4425 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4426 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4427 (use (match_operand:HI 2 "memory_operand" ""))
4428 (use (match_operand:HI 3 "memory_operand" ""))
4429 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4431 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4433 (use (match_dup 3))])
4434 (set (match_dup 0) (match_dup 4))]
4438 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4439 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4440 (use (match_operand:HI 2 "memory_operand" ""))
4441 (use (match_operand:HI 3 "memory_operand" ""))
4442 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4444 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4446 (use (match_dup 3))])]
4449 (define_insn "x86_fnstcw_1"
4450 [(set (match_operand:HI 0 "memory_operand" "=m")
4451 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4454 [(set_attr "length" "2")
4455 (set_attr "mode" "HI")
4456 (set_attr "unit" "i387")])
4458 (define_insn "x86_fldcw_1"
4459 [(set (reg:HI FPSR_REG)
4460 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4463 [(set_attr "length" "2")
4464 (set_attr "mode" "HI")
4465 (set_attr "unit" "i387")
4466 (set_attr "athlon_decode" "vector")
4467 (set_attr "amdfam10_decode" "vector")])
4469 ;; Conversion between fixed point and floating point.
4471 ;; Even though we only accept memory inputs, the backend _really_
4472 ;; wants to be able to do this between registers.
4474 (define_expand "floathisf2"
4475 [(set (match_operand:SF 0 "register_operand" "")
4476 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4477 "TARGET_80387 || TARGET_SSE_MATH"
4479 if (TARGET_SSE_MATH)
4481 emit_insn (gen_floatsisf2 (operands[0],
4482 convert_to_mode (SImode, operands[1], 0)));
4487 (define_insn "*floathisf2_i387"
4488 [(set (match_operand:SF 0 "register_operand" "=f,f")
4489 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4490 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4494 [(set_attr "type" "fmov,multi")
4495 (set_attr "mode" "SF")
4496 (set_attr "unit" "*,i387")
4497 (set_attr "fp_int_src" "true")])
4499 (define_expand "floatsisf2"
4500 [(set (match_operand:SF 0 "register_operand" "")
4501 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4502 "TARGET_80387 || TARGET_SSE_MATH"
4505 (define_insn "*floatsisf2_mixed"
4506 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4507 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4508 "TARGET_MIX_SSE_I387"
4512 cvtsi2ss\t{%1, %0|%0, %1}
4513 cvtsi2ss\t{%1, %0|%0, %1}"
4514 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4515 (set_attr "mode" "SF")
4516 (set_attr "unit" "*,i387,*,*")
4517 (set_attr "athlon_decode" "*,*,vector,double")
4518 (set_attr "amdfam10_decode" "*,*,vector,double")
4519 (set_attr "fp_int_src" "true")])
4521 (define_insn "*floatsisf2_sse"
4522 [(set (match_operand:SF 0 "register_operand" "=x,x")
4523 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4525 "cvtsi2ss\t{%1, %0|%0, %1}"
4526 [(set_attr "type" "sseicvt")
4527 (set_attr "mode" "SF")
4528 (set_attr "athlon_decode" "vector,double")
4529 (set_attr "amdfam10_decode" "vector,double")
4530 (set_attr "fp_int_src" "true")])
4532 (define_insn "*floatsisf2_i387"
4533 [(set (match_operand:SF 0 "register_operand" "=f,f")
4534 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4539 [(set_attr "type" "fmov,multi")
4540 (set_attr "mode" "SF")
4541 (set_attr "unit" "*,i387")
4542 (set_attr "fp_int_src" "true")])
4544 (define_expand "floatdisf2"
4545 [(set (match_operand:SF 0 "register_operand" "")
4546 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4547 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4550 (define_insn "*floatdisf2_mixed"
4551 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4552 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4553 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4557 cvtsi2ss{q}\t{%1, %0|%0, %1}
4558 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4559 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4560 (set_attr "mode" "SF")
4561 (set_attr "unit" "*,i387,*,*")
4562 (set_attr "athlon_decode" "*,*,vector,double")
4563 (set_attr "amdfam10_decode" "*,*,vector,double")
4564 (set_attr "fp_int_src" "true")])
4566 (define_insn "*floatdisf2_sse"
4567 [(set (match_operand:SF 0 "register_operand" "=x,x")
4568 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4569 "TARGET_64BIT && TARGET_SSE_MATH"
4570 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4571 [(set_attr "type" "sseicvt")
4572 (set_attr "mode" "SF")
4573 (set_attr "athlon_decode" "vector,double")
4574 (set_attr "amdfam10_decode" "vector,double")
4575 (set_attr "fp_int_src" "true")])
4577 (define_insn "*floatdisf2_i387"
4578 [(set (match_operand:SF 0 "register_operand" "=f,f")
4579 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4584 [(set_attr "type" "fmov,multi")
4585 (set_attr "mode" "SF")
4586 (set_attr "unit" "*,i387")
4587 (set_attr "fp_int_src" "true")])
4589 (define_expand "floathidf2"
4590 [(set (match_operand:DF 0 "register_operand" "")
4591 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4592 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4594 if (TARGET_SSE2 && TARGET_SSE_MATH)
4596 emit_insn (gen_floatsidf2 (operands[0],
4597 convert_to_mode (SImode, operands[1], 0)));
4602 (define_insn "*floathidf2_i387"
4603 [(set (match_operand:DF 0 "register_operand" "=f,f")
4604 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4605 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4609 [(set_attr "type" "fmov,multi")
4610 (set_attr "mode" "DF")
4611 (set_attr "unit" "*,i387")
4612 (set_attr "fp_int_src" "true")])
4614 (define_expand "floatsidf2"
4615 [(set (match_operand:DF 0 "register_operand" "")
4616 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4617 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4620 (define_insn "*floatsidf2_mixed"
4621 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4622 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4623 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4627 cvtsi2sd\t{%1, %0|%0, %1}
4628 cvtsi2sd\t{%1, %0|%0, %1}"
4629 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4630 (set_attr "mode" "DF")
4631 (set_attr "unit" "*,i387,*,*")
4632 (set_attr "athlon_decode" "*,*,double,direct")
4633 (set_attr "amdfam10_decode" "*,*,vector,double")
4634 (set_attr "fp_int_src" "true")])
4636 (define_insn "*floatsidf2_sse"
4637 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4638 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4639 "TARGET_SSE2 && TARGET_SSE_MATH"
4640 "cvtsi2sd\t{%1, %0|%0, %1}"
4641 [(set_attr "type" "sseicvt")
4642 (set_attr "mode" "DF")
4643 (set_attr "athlon_decode" "double,direct")
4644 (set_attr "amdfam10_decode" "vector,double")
4645 (set_attr "fp_int_src" "true")])
4647 (define_insn "*floatsidf2_i387"
4648 [(set (match_operand:DF 0 "register_operand" "=f,f")
4649 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4654 [(set_attr "type" "fmov,multi")
4655 (set_attr "mode" "DF")
4656 (set_attr "unit" "*,i387")
4657 (set_attr "fp_int_src" "true")])
4659 (define_expand "floatdidf2"
4660 [(set (match_operand:DF 0 "register_operand" "")
4661 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4662 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4665 (define_insn "*floatdidf2_mixed"
4666 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4667 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4668 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4672 cvtsi2sd{q}\t{%1, %0|%0, %1}
4673 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4674 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4675 (set_attr "mode" "DF")
4676 (set_attr "unit" "*,i387,*,*")
4677 (set_attr "athlon_decode" "*,*,double,direct")
4678 (set_attr "amdfam10_decode" "*,*,vector,double")
4679 (set_attr "fp_int_src" "true")])
4681 (define_insn "*floatdidf2_sse"
4682 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4683 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4684 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4685 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4686 [(set_attr "type" "sseicvt")
4687 (set_attr "mode" "DF")
4688 (set_attr "athlon_decode" "double,direct")
4689 (set_attr "amdfam10_decode" "vector,double")
4690 (set_attr "fp_int_src" "true")])
4692 (define_insn "*floatdidf2_i387"
4693 [(set (match_operand:DF 0 "register_operand" "=f,f")
4694 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4699 [(set_attr "type" "fmov,multi")
4700 (set_attr "mode" "DF")
4701 (set_attr "unit" "*,i387")
4702 (set_attr "fp_int_src" "true")])
4704 (define_insn "floathixf2"
4705 [(set (match_operand:XF 0 "register_operand" "=f,f")
4706 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4711 [(set_attr "type" "fmov,multi")
4712 (set_attr "mode" "XF")
4713 (set_attr "unit" "*,i387")
4714 (set_attr "fp_int_src" "true")])
4716 (define_insn "floatsixf2"
4717 [(set (match_operand:XF 0 "register_operand" "=f,f")
4718 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4723 [(set_attr "type" "fmov,multi")
4724 (set_attr "mode" "XF")
4725 (set_attr "unit" "*,i387")
4726 (set_attr "fp_int_src" "true")])
4728 (define_insn "floatdixf2"
4729 [(set (match_operand:XF 0 "register_operand" "=f,f")
4730 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4735 [(set_attr "type" "fmov,multi")
4736 (set_attr "mode" "XF")
4737 (set_attr "unit" "*,i387")
4738 (set_attr "fp_int_src" "true")])
4740 ;; %%% Kill these when reload knows how to do it.
4742 [(set (match_operand 0 "fp_register_operand" "")
4743 (float (match_operand 1 "register_operand" "")))]
4746 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4749 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4750 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4751 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4752 ix86_free_from_memory (GET_MODE (operands[1]));
4756 (define_expand "floatunssisf2"
4757 [(use (match_operand:SF 0 "register_operand" ""))
4758 (use (match_operand:SI 1 "register_operand" ""))]
4759 "!TARGET_64BIT && TARGET_SSE_MATH"
4760 "x86_emit_floatuns (operands); DONE;")
4762 (define_expand "floatunsdisf2"
4763 [(use (match_operand:SF 0 "register_operand" ""))
4764 (use (match_operand:DI 1 "register_operand" ""))]
4765 "TARGET_64BIT && TARGET_SSE_MATH"
4766 "x86_emit_floatuns (operands); DONE;")
4768 (define_expand "floatunsdidf2"
4769 [(use (match_operand:DF 0 "register_operand" ""))
4770 (use (match_operand:DI 1 "register_operand" ""))]
4771 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4772 "x86_emit_floatuns (operands); DONE;")
4774 ;; SSE extract/set expanders
4779 ;; %%% splits for addditi3
4781 (define_expand "addti3"
4782 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4783 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4784 (match_operand:TI 2 "x86_64_general_operand" "")))
4785 (clobber (reg:CC FLAGS_REG))]
4787 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4789 (define_insn "*addti3_1"
4790 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4791 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4792 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4793 (clobber (reg:CC FLAGS_REG))]
4794 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4798 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4799 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4800 (match_operand:TI 2 "x86_64_general_operand" "")))
4801 (clobber (reg:CC FLAGS_REG))]
4802 "TARGET_64BIT && reload_completed"
4803 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4805 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4806 (parallel [(set (match_dup 3)
4807 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4810 (clobber (reg:CC FLAGS_REG))])]
4811 "split_ti (operands+0, 1, operands+0, operands+3);
4812 split_ti (operands+1, 1, operands+1, operands+4);
4813 split_ti (operands+2, 1, operands+2, operands+5);")
4815 ;; %%% splits for addsidi3
4816 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4817 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4818 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4820 (define_expand "adddi3"
4821 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4822 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4823 (match_operand:DI 2 "x86_64_general_operand" "")))
4824 (clobber (reg:CC FLAGS_REG))]
4826 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4828 (define_insn "*adddi3_1"
4829 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4830 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4831 (match_operand:DI 2 "general_operand" "roiF,riF")))
4832 (clobber (reg:CC FLAGS_REG))]
4833 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4837 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4838 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4839 (match_operand:DI 2 "general_operand" "")))
4840 (clobber (reg:CC FLAGS_REG))]
4841 "!TARGET_64BIT && reload_completed"
4842 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4844 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4845 (parallel [(set (match_dup 3)
4846 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4849 (clobber (reg:CC FLAGS_REG))])]
4850 "split_di (operands+0, 1, operands+0, operands+3);
4851 split_di (operands+1, 1, operands+1, operands+4);
4852 split_di (operands+2, 1, operands+2, operands+5);")
4854 (define_insn "adddi3_carry_rex64"
4855 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4856 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4857 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4858 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4859 (clobber (reg:CC FLAGS_REG))]
4860 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4861 "adc{q}\t{%2, %0|%0, %2}"
4862 [(set_attr "type" "alu")
4863 (set_attr "pent_pair" "pu")
4864 (set_attr "mode" "DI")])
4866 (define_insn "*adddi3_cc_rex64"
4867 [(set (reg:CC FLAGS_REG)
4868 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4869 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4871 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4872 (plus:DI (match_dup 1) (match_dup 2)))]
4873 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4874 "add{q}\t{%2, %0|%0, %2}"
4875 [(set_attr "type" "alu")
4876 (set_attr "mode" "DI")])
4878 (define_insn "addqi3_carry"
4879 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4880 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4881 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4882 (match_operand:QI 2 "general_operand" "qi,qm")))
4883 (clobber (reg:CC FLAGS_REG))]
4884 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4885 "adc{b}\t{%2, %0|%0, %2}"
4886 [(set_attr "type" "alu")
4887 (set_attr "pent_pair" "pu")
4888 (set_attr "mode" "QI")])
4890 (define_insn "addhi3_carry"
4891 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4892 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4893 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4894 (match_operand:HI 2 "general_operand" "ri,rm")))
4895 (clobber (reg:CC FLAGS_REG))]
4896 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4897 "adc{w}\t{%2, %0|%0, %2}"
4898 [(set_attr "type" "alu")
4899 (set_attr "pent_pair" "pu")
4900 (set_attr "mode" "HI")])
4902 (define_insn "addsi3_carry"
4903 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4904 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4905 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4906 (match_operand:SI 2 "general_operand" "ri,rm")))
4907 (clobber (reg:CC FLAGS_REG))]
4908 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4909 "adc{l}\t{%2, %0|%0, %2}"
4910 [(set_attr "type" "alu")
4911 (set_attr "pent_pair" "pu")
4912 (set_attr "mode" "SI")])
4914 (define_insn "*addsi3_carry_zext"
4915 [(set (match_operand:DI 0 "register_operand" "=r")
4917 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4918 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4919 (match_operand:SI 2 "general_operand" "rim"))))
4920 (clobber (reg:CC FLAGS_REG))]
4921 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4922 "adc{l}\t{%2, %k0|%k0, %2}"
4923 [(set_attr "type" "alu")
4924 (set_attr "pent_pair" "pu")
4925 (set_attr "mode" "SI")])
4927 (define_insn "*addsi3_cc"
4928 [(set (reg:CC FLAGS_REG)
4929 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4930 (match_operand:SI 2 "general_operand" "ri,rm")]
4932 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4933 (plus:SI (match_dup 1) (match_dup 2)))]
4934 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4935 "add{l}\t{%2, %0|%0, %2}"
4936 [(set_attr "type" "alu")
4937 (set_attr "mode" "SI")])
4939 (define_insn "addqi3_cc"
4940 [(set (reg:CC FLAGS_REG)
4941 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4942 (match_operand:QI 2 "general_operand" "qi,qm")]
4944 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4945 (plus:QI (match_dup 1) (match_dup 2)))]
4946 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4947 "add{b}\t{%2, %0|%0, %2}"
4948 [(set_attr "type" "alu")
4949 (set_attr "mode" "QI")])
4951 (define_expand "addsi3"
4952 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4953 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4954 (match_operand:SI 2 "general_operand" "")))
4955 (clobber (reg:CC FLAGS_REG))])]
4957 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4959 (define_insn "*lea_1"
4960 [(set (match_operand:SI 0 "register_operand" "=r")
4961 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4963 "lea{l}\t{%a1, %0|%0, %a1}"
4964 [(set_attr "type" "lea")
4965 (set_attr "mode" "SI")])
4967 (define_insn "*lea_1_rex64"
4968 [(set (match_operand:SI 0 "register_operand" "=r")
4969 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4971 "lea{l}\t{%a1, %0|%0, %a1}"
4972 [(set_attr "type" "lea")
4973 (set_attr "mode" "SI")])
4975 (define_insn "*lea_1_zext"
4976 [(set (match_operand:DI 0 "register_operand" "=r")
4978 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4980 "lea{l}\t{%a1, %k0|%k0, %a1}"
4981 [(set_attr "type" "lea")
4982 (set_attr "mode" "SI")])
4984 (define_insn "*lea_2_rex64"
4985 [(set (match_operand:DI 0 "register_operand" "=r")
4986 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4988 "lea{q}\t{%a1, %0|%0, %a1}"
4989 [(set_attr "type" "lea")
4990 (set_attr "mode" "DI")])
4992 ;; The lea patterns for non-Pmodes needs to be matched by several
4993 ;; insns converted to real lea by splitters.
4995 (define_insn_and_split "*lea_general_1"
4996 [(set (match_operand 0 "register_operand" "=r")
4997 (plus (plus (match_operand 1 "index_register_operand" "l")
4998 (match_operand 2 "register_operand" "r"))
4999 (match_operand 3 "immediate_operand" "i")))]
5000 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5001 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5002 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5003 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5004 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5005 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5006 || GET_MODE (operands[3]) == VOIDmode)"
5008 "&& reload_completed"
5012 operands[0] = gen_lowpart (SImode, operands[0]);
5013 operands[1] = gen_lowpart (Pmode, operands[1]);
5014 operands[2] = gen_lowpart (Pmode, operands[2]);
5015 operands[3] = gen_lowpart (Pmode, operands[3]);
5016 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5018 if (Pmode != SImode)
5019 pat = gen_rtx_SUBREG (SImode, pat, 0);
5020 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5023 [(set_attr "type" "lea")
5024 (set_attr "mode" "SI")])
5026 (define_insn_and_split "*lea_general_1_zext"
5027 [(set (match_operand:DI 0 "register_operand" "=r")
5029 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5030 (match_operand:SI 2 "register_operand" "r"))
5031 (match_operand:SI 3 "immediate_operand" "i"))))]
5034 "&& reload_completed"
5036 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5038 (match_dup 3)) 0)))]
5040 operands[1] = gen_lowpart (Pmode, operands[1]);
5041 operands[2] = gen_lowpart (Pmode, operands[2]);
5042 operands[3] = gen_lowpart (Pmode, operands[3]);
5044 [(set_attr "type" "lea")
5045 (set_attr "mode" "SI")])
5047 (define_insn_and_split "*lea_general_2"
5048 [(set (match_operand 0 "register_operand" "=r")
5049 (plus (mult (match_operand 1 "index_register_operand" "l")
5050 (match_operand 2 "const248_operand" "i"))
5051 (match_operand 3 "nonmemory_operand" "ri")))]
5052 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5053 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5054 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5055 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5056 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5057 || GET_MODE (operands[3]) == VOIDmode)"
5059 "&& reload_completed"
5063 operands[0] = gen_lowpart (SImode, operands[0]);
5064 operands[1] = gen_lowpart (Pmode, operands[1]);
5065 operands[3] = gen_lowpart (Pmode, operands[3]);
5066 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5068 if (Pmode != SImode)
5069 pat = gen_rtx_SUBREG (SImode, pat, 0);
5070 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5073 [(set_attr "type" "lea")
5074 (set_attr "mode" "SI")])
5076 (define_insn_and_split "*lea_general_2_zext"
5077 [(set (match_operand:DI 0 "register_operand" "=r")
5079 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5080 (match_operand:SI 2 "const248_operand" "n"))
5081 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5084 "&& reload_completed"
5086 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5088 (match_dup 3)) 0)))]
5090 operands[1] = gen_lowpart (Pmode, operands[1]);
5091 operands[3] = gen_lowpart (Pmode, operands[3]);
5093 [(set_attr "type" "lea")
5094 (set_attr "mode" "SI")])
5096 (define_insn_and_split "*lea_general_3"
5097 [(set (match_operand 0 "register_operand" "=r")
5098 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5099 (match_operand 2 "const248_operand" "i"))
5100 (match_operand 3 "register_operand" "r"))
5101 (match_operand 4 "immediate_operand" "i")))]
5102 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5103 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5104 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5105 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5106 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5108 "&& reload_completed"
5112 operands[0] = gen_lowpart (SImode, operands[0]);
5113 operands[1] = gen_lowpart (Pmode, operands[1]);
5114 operands[3] = gen_lowpart (Pmode, operands[3]);
5115 operands[4] = gen_lowpart (Pmode, operands[4]);
5116 pat = gen_rtx_PLUS (Pmode,
5117 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5121 if (Pmode != SImode)
5122 pat = gen_rtx_SUBREG (SImode, pat, 0);
5123 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5126 [(set_attr "type" "lea")
5127 (set_attr "mode" "SI")])
5129 (define_insn_and_split "*lea_general_3_zext"
5130 [(set (match_operand:DI 0 "register_operand" "=r")
5132 (plus:SI (plus:SI (mult:SI
5133 (match_operand:SI 1 "index_register_operand" "l")
5134 (match_operand:SI 2 "const248_operand" "n"))
5135 (match_operand:SI 3 "register_operand" "r"))
5136 (match_operand:SI 4 "immediate_operand" "i"))))]
5139 "&& reload_completed"
5141 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5144 (match_dup 4)) 0)))]
5146 operands[1] = gen_lowpart (Pmode, operands[1]);
5147 operands[3] = gen_lowpart (Pmode, operands[3]);
5148 operands[4] = gen_lowpart (Pmode, operands[4]);
5150 [(set_attr "type" "lea")
5151 (set_attr "mode" "SI")])
5153 (define_insn "*adddi_1_rex64"
5154 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5155 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5156 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5157 (clobber (reg:CC FLAGS_REG))]
5158 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5160 switch (get_attr_type (insn))
5163 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5164 return "lea{q}\t{%a2, %0|%0, %a2}";
5167 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5168 if (operands[2] == const1_rtx)
5169 return "inc{q}\t%0";
5172 gcc_assert (operands[2] == constm1_rtx);
5173 return "dec{q}\t%0";
5177 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5179 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5180 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5181 if (GET_CODE (operands[2]) == CONST_INT
5182 /* Avoid overflows. */
5183 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5184 && (INTVAL (operands[2]) == 128
5185 || (INTVAL (operands[2]) < 0
5186 && INTVAL (operands[2]) != -128)))
5188 operands[2] = GEN_INT (-INTVAL (operands[2]));
5189 return "sub{q}\t{%2, %0|%0, %2}";
5191 return "add{q}\t{%2, %0|%0, %2}";
5195 (cond [(eq_attr "alternative" "2")
5196 (const_string "lea")
5197 ; Current assemblers are broken and do not allow @GOTOFF in
5198 ; ought but a memory context.
5199 (match_operand:DI 2 "pic_symbolic_operand" "")
5200 (const_string "lea")
5201 (match_operand:DI 2 "incdec_operand" "")
5202 (const_string "incdec")
5204 (const_string "alu")))
5205 (set_attr "mode" "DI")])
5207 ;; Convert lea to the lea pattern to avoid flags dependency.
5209 [(set (match_operand:DI 0 "register_operand" "")
5210 (plus:DI (match_operand:DI 1 "register_operand" "")
5211 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5212 (clobber (reg:CC FLAGS_REG))]
5213 "TARGET_64BIT && reload_completed
5214 && true_regnum (operands[0]) != true_regnum (operands[1])"
5216 (plus:DI (match_dup 1)
5220 (define_insn "*adddi_2_rex64"
5221 [(set (reg FLAGS_REG)
5223 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5224 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5226 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5227 (plus:DI (match_dup 1) (match_dup 2)))]
5228 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5229 && ix86_binary_operator_ok (PLUS, DImode, operands)
5230 /* Current assemblers are broken and do not allow @GOTOFF in
5231 ought but a memory context. */
5232 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5234 switch (get_attr_type (insn))
5237 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5238 if (operands[2] == const1_rtx)
5239 return "inc{q}\t%0";
5242 gcc_assert (operands[2] == constm1_rtx);
5243 return "dec{q}\t%0";
5247 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5248 /* ???? We ought to handle there the 32bit case too
5249 - do we need new constraint? */
5250 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5251 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5252 if (GET_CODE (operands[2]) == CONST_INT
5253 /* Avoid overflows. */
5254 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5255 && (INTVAL (operands[2]) == 128
5256 || (INTVAL (operands[2]) < 0
5257 && INTVAL (operands[2]) != -128)))
5259 operands[2] = GEN_INT (-INTVAL (operands[2]));
5260 return "sub{q}\t{%2, %0|%0, %2}";
5262 return "add{q}\t{%2, %0|%0, %2}";
5266 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5267 (const_string "incdec")
5268 (const_string "alu")))
5269 (set_attr "mode" "DI")])
5271 (define_insn "*adddi_3_rex64"
5272 [(set (reg FLAGS_REG)
5273 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5274 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5275 (clobber (match_scratch:DI 0 "=r"))]
5277 && ix86_match_ccmode (insn, CCZmode)
5278 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5279 /* Current assemblers are broken and do not allow @GOTOFF in
5280 ought but a memory context. */
5281 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5283 switch (get_attr_type (insn))
5286 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5287 if (operands[2] == const1_rtx)
5288 return "inc{q}\t%0";
5291 gcc_assert (operands[2] == constm1_rtx);
5292 return "dec{q}\t%0";
5296 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5297 /* ???? We ought to handle there the 32bit case too
5298 - do we need new constraint? */
5299 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5300 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5301 if (GET_CODE (operands[2]) == CONST_INT
5302 /* Avoid overflows. */
5303 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5304 && (INTVAL (operands[2]) == 128
5305 || (INTVAL (operands[2]) < 0
5306 && INTVAL (operands[2]) != -128)))
5308 operands[2] = GEN_INT (-INTVAL (operands[2]));
5309 return "sub{q}\t{%2, %0|%0, %2}";
5311 return "add{q}\t{%2, %0|%0, %2}";
5315 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5316 (const_string "incdec")
5317 (const_string "alu")))
5318 (set_attr "mode" "DI")])
5320 ; For comparisons against 1, -1 and 128, we may generate better code
5321 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5322 ; is matched then. We can't accept general immediate, because for
5323 ; case of overflows, the result is messed up.
5324 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5326 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5327 ; only for comparisons not depending on it.
5328 (define_insn "*adddi_4_rex64"
5329 [(set (reg FLAGS_REG)
5330 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5331 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5332 (clobber (match_scratch:DI 0 "=rm"))]
5334 && ix86_match_ccmode (insn, CCGCmode)"
5336 switch (get_attr_type (insn))
5339 if (operands[2] == constm1_rtx)
5340 return "inc{q}\t%0";
5343 gcc_assert (operands[2] == const1_rtx);
5344 return "dec{q}\t%0";
5348 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5349 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5350 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5351 if ((INTVAL (operands[2]) == -128
5352 || (INTVAL (operands[2]) > 0
5353 && INTVAL (operands[2]) != 128))
5354 /* Avoid overflows. */
5355 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5356 return "sub{q}\t{%2, %0|%0, %2}";
5357 operands[2] = GEN_INT (-INTVAL (operands[2]));
5358 return "add{q}\t{%2, %0|%0, %2}";
5362 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5363 (const_string "incdec")
5364 (const_string "alu")))
5365 (set_attr "mode" "DI")])
5367 (define_insn "*adddi_5_rex64"
5368 [(set (reg FLAGS_REG)
5370 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5371 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5373 (clobber (match_scratch:DI 0 "=r"))]
5375 && ix86_match_ccmode (insn, CCGOCmode)
5376 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5377 /* Current assemblers are broken and do not allow @GOTOFF in
5378 ought but a memory context. */
5379 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5381 switch (get_attr_type (insn))
5384 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5385 if (operands[2] == const1_rtx)
5386 return "inc{q}\t%0";
5389 gcc_assert (operands[2] == constm1_rtx);
5390 return "dec{q}\t%0";
5394 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5395 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5396 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5397 if (GET_CODE (operands[2]) == CONST_INT
5398 /* Avoid overflows. */
5399 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5400 && (INTVAL (operands[2]) == 128
5401 || (INTVAL (operands[2]) < 0
5402 && INTVAL (operands[2]) != -128)))
5404 operands[2] = GEN_INT (-INTVAL (operands[2]));
5405 return "sub{q}\t{%2, %0|%0, %2}";
5407 return "add{q}\t{%2, %0|%0, %2}";
5411 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5412 (const_string "incdec")
5413 (const_string "alu")))
5414 (set_attr "mode" "DI")])
5417 (define_insn "*addsi_1"
5418 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5419 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5420 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5421 (clobber (reg:CC FLAGS_REG))]
5422 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5424 switch (get_attr_type (insn))
5427 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5428 return "lea{l}\t{%a2, %0|%0, %a2}";
5431 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5432 if (operands[2] == const1_rtx)
5433 return "inc{l}\t%0";
5436 gcc_assert (operands[2] == constm1_rtx);
5437 return "dec{l}\t%0";
5441 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5443 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5444 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5445 if (GET_CODE (operands[2]) == CONST_INT
5446 && (INTVAL (operands[2]) == 128
5447 || (INTVAL (operands[2]) < 0
5448 && INTVAL (operands[2]) != -128)))
5450 operands[2] = GEN_INT (-INTVAL (operands[2]));
5451 return "sub{l}\t{%2, %0|%0, %2}";
5453 return "add{l}\t{%2, %0|%0, %2}";
5457 (cond [(eq_attr "alternative" "2")
5458 (const_string "lea")
5459 ; Current assemblers are broken and do not allow @GOTOFF in
5460 ; ought but a memory context.
5461 (match_operand:SI 2 "pic_symbolic_operand" "")
5462 (const_string "lea")
5463 (match_operand:SI 2 "incdec_operand" "")
5464 (const_string "incdec")
5466 (const_string "alu")))
5467 (set_attr "mode" "SI")])
5469 ;; Convert lea to the lea pattern to avoid flags dependency.
5471 [(set (match_operand 0 "register_operand" "")
5472 (plus (match_operand 1 "register_operand" "")
5473 (match_operand 2 "nonmemory_operand" "")))
5474 (clobber (reg:CC FLAGS_REG))]
5476 && true_regnum (operands[0]) != true_regnum (operands[1])"
5480 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5481 may confuse gen_lowpart. */
5482 if (GET_MODE (operands[0]) != Pmode)
5484 operands[1] = gen_lowpart (Pmode, operands[1]);
5485 operands[2] = gen_lowpart (Pmode, operands[2]);
5487 operands[0] = gen_lowpart (SImode, operands[0]);
5488 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5489 if (Pmode != SImode)
5490 pat = gen_rtx_SUBREG (SImode, pat, 0);
5491 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5495 ;; It may seem that nonimmediate operand is proper one for operand 1.
5496 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5497 ;; we take care in ix86_binary_operator_ok to not allow two memory
5498 ;; operands so proper swapping will be done in reload. This allow
5499 ;; patterns constructed from addsi_1 to match.
5500 (define_insn "addsi_1_zext"
5501 [(set (match_operand:DI 0 "register_operand" "=r,r")
5503 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5504 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5505 (clobber (reg:CC FLAGS_REG))]
5506 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5508 switch (get_attr_type (insn))
5511 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5512 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5515 if (operands[2] == const1_rtx)
5516 return "inc{l}\t%k0";
5519 gcc_assert (operands[2] == constm1_rtx);
5520 return "dec{l}\t%k0";
5524 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5525 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5526 if (GET_CODE (operands[2]) == CONST_INT
5527 && (INTVAL (operands[2]) == 128
5528 || (INTVAL (operands[2]) < 0
5529 && INTVAL (operands[2]) != -128)))
5531 operands[2] = GEN_INT (-INTVAL (operands[2]));
5532 return "sub{l}\t{%2, %k0|%k0, %2}";
5534 return "add{l}\t{%2, %k0|%k0, %2}";
5538 (cond [(eq_attr "alternative" "1")
5539 (const_string "lea")
5540 ; Current assemblers are broken and do not allow @GOTOFF in
5541 ; ought but a memory context.
5542 (match_operand:SI 2 "pic_symbolic_operand" "")
5543 (const_string "lea")
5544 (match_operand:SI 2 "incdec_operand" "")
5545 (const_string "incdec")
5547 (const_string "alu")))
5548 (set_attr "mode" "SI")])
5550 ;; Convert lea to the lea pattern to avoid flags dependency.
5552 [(set (match_operand:DI 0 "register_operand" "")
5554 (plus:SI (match_operand:SI 1 "register_operand" "")
5555 (match_operand:SI 2 "nonmemory_operand" ""))))
5556 (clobber (reg:CC FLAGS_REG))]
5557 "TARGET_64BIT && reload_completed
5558 && true_regnum (operands[0]) != true_regnum (operands[1])"
5560 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5562 operands[1] = gen_lowpart (Pmode, operands[1]);
5563 operands[2] = gen_lowpart (Pmode, operands[2]);
5566 (define_insn "*addsi_2"
5567 [(set (reg FLAGS_REG)
5569 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5570 (match_operand:SI 2 "general_operand" "rmni,rni"))
5572 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5573 (plus:SI (match_dup 1) (match_dup 2)))]
5574 "ix86_match_ccmode (insn, CCGOCmode)
5575 && ix86_binary_operator_ok (PLUS, SImode, operands)
5576 /* Current assemblers are broken and do not allow @GOTOFF in
5577 ought but a memory context. */
5578 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5580 switch (get_attr_type (insn))
5583 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5584 if (operands[2] == const1_rtx)
5585 return "inc{l}\t%0";
5588 gcc_assert (operands[2] == constm1_rtx);
5589 return "dec{l}\t%0";
5593 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5594 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5595 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5596 if (GET_CODE (operands[2]) == CONST_INT
5597 && (INTVAL (operands[2]) == 128
5598 || (INTVAL (operands[2]) < 0
5599 && INTVAL (operands[2]) != -128)))
5601 operands[2] = GEN_INT (-INTVAL (operands[2]));
5602 return "sub{l}\t{%2, %0|%0, %2}";
5604 return "add{l}\t{%2, %0|%0, %2}";
5608 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5609 (const_string "incdec")
5610 (const_string "alu")))
5611 (set_attr "mode" "SI")])
5613 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5614 (define_insn "*addsi_2_zext"
5615 [(set (reg FLAGS_REG)
5617 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5618 (match_operand:SI 2 "general_operand" "rmni"))
5620 (set (match_operand:DI 0 "register_operand" "=r")
5621 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5622 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5623 && ix86_binary_operator_ok (PLUS, SImode, operands)
5624 /* Current assemblers are broken and do not allow @GOTOFF in
5625 ought but a memory context. */
5626 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5628 switch (get_attr_type (insn))
5631 if (operands[2] == const1_rtx)
5632 return "inc{l}\t%k0";
5635 gcc_assert (operands[2] == constm1_rtx);
5636 return "dec{l}\t%k0";
5640 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5641 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5642 if (GET_CODE (operands[2]) == CONST_INT
5643 && (INTVAL (operands[2]) == 128
5644 || (INTVAL (operands[2]) < 0
5645 && INTVAL (operands[2]) != -128)))
5647 operands[2] = GEN_INT (-INTVAL (operands[2]));
5648 return "sub{l}\t{%2, %k0|%k0, %2}";
5650 return "add{l}\t{%2, %k0|%k0, %2}";
5654 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5655 (const_string "incdec")
5656 (const_string "alu")))
5657 (set_attr "mode" "SI")])
5659 (define_insn "*addsi_3"
5660 [(set (reg FLAGS_REG)
5661 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5662 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5663 (clobber (match_scratch:SI 0 "=r"))]
5664 "ix86_match_ccmode (insn, CCZmode)
5665 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5666 /* Current assemblers are broken and do not allow @GOTOFF in
5667 ought but a memory context. */
5668 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5670 switch (get_attr_type (insn))
5673 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5674 if (operands[2] == const1_rtx)
5675 return "inc{l}\t%0";
5678 gcc_assert (operands[2] == constm1_rtx);
5679 return "dec{l}\t%0";
5683 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5684 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5685 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5686 if (GET_CODE (operands[2]) == CONST_INT
5687 && (INTVAL (operands[2]) == 128
5688 || (INTVAL (operands[2]) < 0
5689 && INTVAL (operands[2]) != -128)))
5691 operands[2] = GEN_INT (-INTVAL (operands[2]));
5692 return "sub{l}\t{%2, %0|%0, %2}";
5694 return "add{l}\t{%2, %0|%0, %2}";
5698 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5699 (const_string "incdec")
5700 (const_string "alu")))
5701 (set_attr "mode" "SI")])
5703 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5704 (define_insn "*addsi_3_zext"
5705 [(set (reg FLAGS_REG)
5706 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5707 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5708 (set (match_operand:DI 0 "register_operand" "=r")
5709 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5710 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5711 && ix86_binary_operator_ok (PLUS, SImode, operands)
5712 /* Current assemblers are broken and do not allow @GOTOFF in
5713 ought but a memory context. */
5714 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5716 switch (get_attr_type (insn))
5719 if (operands[2] == const1_rtx)
5720 return "inc{l}\t%k0";
5723 gcc_assert (operands[2] == constm1_rtx);
5724 return "dec{l}\t%k0";
5728 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5729 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5730 if (GET_CODE (operands[2]) == CONST_INT
5731 && (INTVAL (operands[2]) == 128
5732 || (INTVAL (operands[2]) < 0
5733 && INTVAL (operands[2]) != -128)))
5735 operands[2] = GEN_INT (-INTVAL (operands[2]));
5736 return "sub{l}\t{%2, %k0|%k0, %2}";
5738 return "add{l}\t{%2, %k0|%k0, %2}";
5742 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5743 (const_string "incdec")
5744 (const_string "alu")))
5745 (set_attr "mode" "SI")])
5747 ; For comparisons against 1, -1 and 128, we may generate better code
5748 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5749 ; is matched then. We can't accept general immediate, because for
5750 ; case of overflows, the result is messed up.
5751 ; This pattern also don't hold of 0x80000000, since the value overflows
5753 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5754 ; only for comparisons not depending on it.
5755 (define_insn "*addsi_4"
5756 [(set (reg FLAGS_REG)
5757 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5758 (match_operand:SI 2 "const_int_operand" "n")))
5759 (clobber (match_scratch:SI 0 "=rm"))]
5760 "ix86_match_ccmode (insn, CCGCmode)
5761 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5763 switch (get_attr_type (insn))
5766 if (operands[2] == constm1_rtx)
5767 return "inc{l}\t%0";
5770 gcc_assert (operands[2] == const1_rtx);
5771 return "dec{l}\t%0";
5775 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5776 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5777 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5778 if ((INTVAL (operands[2]) == -128
5779 || (INTVAL (operands[2]) > 0
5780 && INTVAL (operands[2]) != 128)))
5781 return "sub{l}\t{%2, %0|%0, %2}";
5782 operands[2] = GEN_INT (-INTVAL (operands[2]));
5783 return "add{l}\t{%2, %0|%0, %2}";
5787 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5788 (const_string "incdec")
5789 (const_string "alu")))
5790 (set_attr "mode" "SI")])
5792 (define_insn "*addsi_5"
5793 [(set (reg FLAGS_REG)
5795 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5796 (match_operand:SI 2 "general_operand" "rmni"))
5798 (clobber (match_scratch:SI 0 "=r"))]
5799 "ix86_match_ccmode (insn, CCGOCmode)
5800 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5801 /* Current assemblers are broken and do not allow @GOTOFF in
5802 ought but a memory context. */
5803 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5805 switch (get_attr_type (insn))
5808 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809 if (operands[2] == const1_rtx)
5810 return "inc{l}\t%0";
5813 gcc_assert (operands[2] == constm1_rtx);
5814 return "dec{l}\t%0";
5818 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5819 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5820 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5821 if (GET_CODE (operands[2]) == CONST_INT
5822 && (INTVAL (operands[2]) == 128
5823 || (INTVAL (operands[2]) < 0
5824 && INTVAL (operands[2]) != -128)))
5826 operands[2] = GEN_INT (-INTVAL (operands[2]));
5827 return "sub{l}\t{%2, %0|%0, %2}";
5829 return "add{l}\t{%2, %0|%0, %2}";
5833 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5834 (const_string "incdec")
5835 (const_string "alu")))
5836 (set_attr "mode" "SI")])
5838 (define_expand "addhi3"
5839 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5840 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5841 (match_operand:HI 2 "general_operand" "")))
5842 (clobber (reg:CC FLAGS_REG))])]
5843 "TARGET_HIMODE_MATH"
5844 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5846 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5847 ;; type optimizations enabled by define-splits. This is not important
5848 ;; for PII, and in fact harmful because of partial register stalls.
5850 (define_insn "*addhi_1_lea"
5851 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5852 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5853 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5854 (clobber (reg:CC FLAGS_REG))]
5855 "!TARGET_PARTIAL_REG_STALL
5856 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5858 switch (get_attr_type (insn))
5863 if (operands[2] == const1_rtx)
5864 return "inc{w}\t%0";
5867 gcc_assert (operands[2] == constm1_rtx);
5868 return "dec{w}\t%0";
5872 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5873 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5874 if (GET_CODE (operands[2]) == CONST_INT
5875 && (INTVAL (operands[2]) == 128
5876 || (INTVAL (operands[2]) < 0
5877 && INTVAL (operands[2]) != -128)))
5879 operands[2] = GEN_INT (-INTVAL (operands[2]));
5880 return "sub{w}\t{%2, %0|%0, %2}";
5882 return "add{w}\t{%2, %0|%0, %2}";
5886 (if_then_else (eq_attr "alternative" "2")
5887 (const_string "lea")
5888 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5889 (const_string "incdec")
5890 (const_string "alu"))))
5891 (set_attr "mode" "HI,HI,SI")])
5893 (define_insn "*addhi_1"
5894 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5895 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5896 (match_operand:HI 2 "general_operand" "ri,rm")))
5897 (clobber (reg:CC FLAGS_REG))]
5898 "TARGET_PARTIAL_REG_STALL
5899 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5901 switch (get_attr_type (insn))
5904 if (operands[2] == const1_rtx)
5905 return "inc{w}\t%0";
5908 gcc_assert (operands[2] == constm1_rtx);
5909 return "dec{w}\t%0";
5913 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5914 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5915 if (GET_CODE (operands[2]) == CONST_INT
5916 && (INTVAL (operands[2]) == 128
5917 || (INTVAL (operands[2]) < 0
5918 && INTVAL (operands[2]) != -128)))
5920 operands[2] = GEN_INT (-INTVAL (operands[2]));
5921 return "sub{w}\t{%2, %0|%0, %2}";
5923 return "add{w}\t{%2, %0|%0, %2}";
5927 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5928 (const_string "incdec")
5929 (const_string "alu")))
5930 (set_attr "mode" "HI")])
5932 (define_insn "*addhi_2"
5933 [(set (reg FLAGS_REG)
5935 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5936 (match_operand:HI 2 "general_operand" "rmni,rni"))
5938 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5939 (plus:HI (match_dup 1) (match_dup 2)))]
5940 "ix86_match_ccmode (insn, CCGOCmode)
5941 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5943 switch (get_attr_type (insn))
5946 if (operands[2] == const1_rtx)
5947 return "inc{w}\t%0";
5950 gcc_assert (operands[2] == constm1_rtx);
5951 return "dec{w}\t%0";
5955 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5956 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5957 if (GET_CODE (operands[2]) == CONST_INT
5958 && (INTVAL (operands[2]) == 128
5959 || (INTVAL (operands[2]) < 0
5960 && INTVAL (operands[2]) != -128)))
5962 operands[2] = GEN_INT (-INTVAL (operands[2]));
5963 return "sub{w}\t{%2, %0|%0, %2}";
5965 return "add{w}\t{%2, %0|%0, %2}";
5969 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5970 (const_string "incdec")
5971 (const_string "alu")))
5972 (set_attr "mode" "HI")])
5974 (define_insn "*addhi_3"
5975 [(set (reg FLAGS_REG)
5976 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5977 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5978 (clobber (match_scratch:HI 0 "=r"))]
5979 "ix86_match_ccmode (insn, CCZmode)
5980 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5982 switch (get_attr_type (insn))
5985 if (operands[2] == const1_rtx)
5986 return "inc{w}\t%0";
5989 gcc_assert (operands[2] == constm1_rtx);
5990 return "dec{w}\t%0";
5994 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5995 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5996 if (GET_CODE (operands[2]) == CONST_INT
5997 && (INTVAL (operands[2]) == 128
5998 || (INTVAL (operands[2]) < 0
5999 && INTVAL (operands[2]) != -128)))
6001 operands[2] = GEN_INT (-INTVAL (operands[2]));
6002 return "sub{w}\t{%2, %0|%0, %2}";
6004 return "add{w}\t{%2, %0|%0, %2}";
6008 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6009 (const_string "incdec")
6010 (const_string "alu")))
6011 (set_attr "mode" "HI")])
6013 ; See comments above addsi_4 for details.
6014 (define_insn "*addhi_4"
6015 [(set (reg FLAGS_REG)
6016 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6017 (match_operand:HI 2 "const_int_operand" "n")))
6018 (clobber (match_scratch:HI 0 "=rm"))]
6019 "ix86_match_ccmode (insn, CCGCmode)
6020 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6022 switch (get_attr_type (insn))
6025 if (operands[2] == constm1_rtx)
6026 return "inc{w}\t%0";
6029 gcc_assert (operands[2] == const1_rtx);
6030 return "dec{w}\t%0";
6034 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6035 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6036 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6037 if ((INTVAL (operands[2]) == -128
6038 || (INTVAL (operands[2]) > 0
6039 && INTVAL (operands[2]) != 128)))
6040 return "sub{w}\t{%2, %0|%0, %2}";
6041 operands[2] = GEN_INT (-INTVAL (operands[2]));
6042 return "add{w}\t{%2, %0|%0, %2}";
6046 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6047 (const_string "incdec")
6048 (const_string "alu")))
6049 (set_attr "mode" "SI")])
6052 (define_insn "*addhi_5"
6053 [(set (reg FLAGS_REG)
6055 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6056 (match_operand:HI 2 "general_operand" "rmni"))
6058 (clobber (match_scratch:HI 0 "=r"))]
6059 "ix86_match_ccmode (insn, CCGOCmode)
6060 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6062 switch (get_attr_type (insn))
6065 if (operands[2] == const1_rtx)
6066 return "inc{w}\t%0";
6069 gcc_assert (operands[2] == constm1_rtx);
6070 return "dec{w}\t%0";
6074 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6075 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6076 if (GET_CODE (operands[2]) == CONST_INT
6077 && (INTVAL (operands[2]) == 128
6078 || (INTVAL (operands[2]) < 0
6079 && INTVAL (operands[2]) != -128)))
6081 operands[2] = GEN_INT (-INTVAL (operands[2]));
6082 return "sub{w}\t{%2, %0|%0, %2}";
6084 return "add{w}\t{%2, %0|%0, %2}";
6088 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6089 (const_string "incdec")
6090 (const_string "alu")))
6091 (set_attr "mode" "HI")])
6093 (define_expand "addqi3"
6094 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6095 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6096 (match_operand:QI 2 "general_operand" "")))
6097 (clobber (reg:CC FLAGS_REG))])]
6098 "TARGET_QIMODE_MATH"
6099 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6101 ;; %%% Potential partial reg stall on alternative 2. What to do?
6102 (define_insn "*addqi_1_lea"
6103 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6104 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6105 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6106 (clobber (reg:CC FLAGS_REG))]
6107 "!TARGET_PARTIAL_REG_STALL
6108 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6110 int widen = (which_alternative == 2);
6111 switch (get_attr_type (insn))
6116 if (operands[2] == const1_rtx)
6117 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6120 gcc_assert (operands[2] == constm1_rtx);
6121 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6125 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6126 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6127 if (GET_CODE (operands[2]) == CONST_INT
6128 && (INTVAL (operands[2]) == 128
6129 || (INTVAL (operands[2]) < 0
6130 && INTVAL (operands[2]) != -128)))
6132 operands[2] = GEN_INT (-INTVAL (operands[2]));
6134 return "sub{l}\t{%2, %k0|%k0, %2}";
6136 return "sub{b}\t{%2, %0|%0, %2}";
6139 return "add{l}\t{%k2, %k0|%k0, %k2}";
6141 return "add{b}\t{%2, %0|%0, %2}";
6145 (if_then_else (eq_attr "alternative" "3")
6146 (const_string "lea")
6147 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6148 (const_string "incdec")
6149 (const_string "alu"))))
6150 (set_attr "mode" "QI,QI,SI,SI")])
6152 (define_insn "*addqi_1"
6153 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6154 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6155 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6156 (clobber (reg:CC FLAGS_REG))]
6157 "TARGET_PARTIAL_REG_STALL
6158 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6160 int widen = (which_alternative == 2);
6161 switch (get_attr_type (insn))
6164 if (operands[2] == const1_rtx)
6165 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6168 gcc_assert (operands[2] == constm1_rtx);
6169 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6173 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6174 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6175 if (GET_CODE (operands[2]) == CONST_INT
6176 && (INTVAL (operands[2]) == 128
6177 || (INTVAL (operands[2]) < 0
6178 && INTVAL (operands[2]) != -128)))
6180 operands[2] = GEN_INT (-INTVAL (operands[2]));
6182 return "sub{l}\t{%2, %k0|%k0, %2}";
6184 return "sub{b}\t{%2, %0|%0, %2}";
6187 return "add{l}\t{%k2, %k0|%k0, %k2}";
6189 return "add{b}\t{%2, %0|%0, %2}";
6193 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6194 (const_string "incdec")
6195 (const_string "alu")))
6196 (set_attr "mode" "QI,QI,SI")])
6198 (define_insn "*addqi_1_slp"
6199 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6200 (plus:QI (match_dup 0)
6201 (match_operand:QI 1 "general_operand" "qn,qnm")))
6202 (clobber (reg:CC FLAGS_REG))]
6203 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6204 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6206 switch (get_attr_type (insn))
6209 if (operands[1] == const1_rtx)
6210 return "inc{b}\t%0";
6213 gcc_assert (operands[1] == constm1_rtx);
6214 return "dec{b}\t%0";
6218 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6219 if (GET_CODE (operands[1]) == CONST_INT
6220 && INTVAL (operands[1]) < 0)
6222 operands[1] = GEN_INT (-INTVAL (operands[1]));
6223 return "sub{b}\t{%1, %0|%0, %1}";
6225 return "add{b}\t{%1, %0|%0, %1}";
6229 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6230 (const_string "incdec")
6231 (const_string "alu1")))
6232 (set (attr "memory")
6233 (if_then_else (match_operand 1 "memory_operand" "")
6234 (const_string "load")
6235 (const_string "none")))
6236 (set_attr "mode" "QI")])
6238 (define_insn "*addqi_2"
6239 [(set (reg FLAGS_REG)
6241 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6242 (match_operand:QI 2 "general_operand" "qmni,qni"))
6244 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6245 (plus:QI (match_dup 1) (match_dup 2)))]
6246 "ix86_match_ccmode (insn, CCGOCmode)
6247 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6249 switch (get_attr_type (insn))
6252 if (operands[2] == const1_rtx)
6253 return "inc{b}\t%0";
6256 gcc_assert (operands[2] == constm1_rtx
6257 || (GET_CODE (operands[2]) == CONST_INT
6258 && INTVAL (operands[2]) == 255));
6259 return "dec{b}\t%0";
6263 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6264 if (GET_CODE (operands[2]) == CONST_INT
6265 && INTVAL (operands[2]) < 0)
6267 operands[2] = GEN_INT (-INTVAL (operands[2]));
6268 return "sub{b}\t{%2, %0|%0, %2}";
6270 return "add{b}\t{%2, %0|%0, %2}";
6274 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6275 (const_string "incdec")
6276 (const_string "alu")))
6277 (set_attr "mode" "QI")])
6279 (define_insn "*addqi_3"
6280 [(set (reg FLAGS_REG)
6281 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6282 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6283 (clobber (match_scratch:QI 0 "=q"))]
6284 "ix86_match_ccmode (insn, CCZmode)
6285 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6287 switch (get_attr_type (insn))
6290 if (operands[2] == const1_rtx)
6291 return "inc{b}\t%0";
6294 gcc_assert (operands[2] == constm1_rtx
6295 || (GET_CODE (operands[2]) == CONST_INT
6296 && INTVAL (operands[2]) == 255));
6297 return "dec{b}\t%0";
6301 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6302 if (GET_CODE (operands[2]) == CONST_INT
6303 && INTVAL (operands[2]) < 0)
6305 operands[2] = GEN_INT (-INTVAL (operands[2]));
6306 return "sub{b}\t{%2, %0|%0, %2}";
6308 return "add{b}\t{%2, %0|%0, %2}";
6312 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6313 (const_string "incdec")
6314 (const_string "alu")))
6315 (set_attr "mode" "QI")])
6317 ; See comments above addsi_4 for details.
6318 (define_insn "*addqi_4"
6319 [(set (reg FLAGS_REG)
6320 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6321 (match_operand:QI 2 "const_int_operand" "n")))
6322 (clobber (match_scratch:QI 0 "=qm"))]
6323 "ix86_match_ccmode (insn, CCGCmode)
6324 && (INTVAL (operands[2]) & 0xff) != 0x80"
6326 switch (get_attr_type (insn))
6329 if (operands[2] == constm1_rtx
6330 || (GET_CODE (operands[2]) == CONST_INT
6331 && INTVAL (operands[2]) == 255))
6332 return "inc{b}\t%0";
6335 gcc_assert (operands[2] == const1_rtx);
6336 return "dec{b}\t%0";
6340 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6341 if (INTVAL (operands[2]) < 0)
6343 operands[2] = GEN_INT (-INTVAL (operands[2]));
6344 return "add{b}\t{%2, %0|%0, %2}";
6346 return "sub{b}\t{%2, %0|%0, %2}";
6350 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6351 (const_string "incdec")
6352 (const_string "alu")))
6353 (set_attr "mode" "QI")])
6356 (define_insn "*addqi_5"
6357 [(set (reg FLAGS_REG)
6359 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6360 (match_operand:QI 2 "general_operand" "qmni"))
6362 (clobber (match_scratch:QI 0 "=q"))]
6363 "ix86_match_ccmode (insn, CCGOCmode)
6364 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6366 switch (get_attr_type (insn))
6369 if (operands[2] == const1_rtx)
6370 return "inc{b}\t%0";
6373 gcc_assert (operands[2] == constm1_rtx
6374 || (GET_CODE (operands[2]) == CONST_INT
6375 && INTVAL (operands[2]) == 255));
6376 return "dec{b}\t%0";
6380 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6381 if (GET_CODE (operands[2]) == CONST_INT
6382 && INTVAL (operands[2]) < 0)
6384 operands[2] = GEN_INT (-INTVAL (operands[2]));
6385 return "sub{b}\t{%2, %0|%0, %2}";
6387 return "add{b}\t{%2, %0|%0, %2}";
6391 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6392 (const_string "incdec")
6393 (const_string "alu")))
6394 (set_attr "mode" "QI")])
6397 (define_insn "addqi_ext_1"
6398 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6403 (match_operand 1 "ext_register_operand" "0")
6406 (match_operand:QI 2 "general_operand" "Qmn")))
6407 (clobber (reg:CC FLAGS_REG))]
6410 switch (get_attr_type (insn))
6413 if (operands[2] == const1_rtx)
6414 return "inc{b}\t%h0";
6417 gcc_assert (operands[2] == constm1_rtx
6418 || (GET_CODE (operands[2]) == CONST_INT
6419 && INTVAL (operands[2]) == 255));
6420 return "dec{b}\t%h0";
6424 return "add{b}\t{%2, %h0|%h0, %2}";
6428 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6429 (const_string "incdec")
6430 (const_string "alu")))
6431 (set_attr "mode" "QI")])
6433 (define_insn "*addqi_ext_1_rex64"
6434 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6439 (match_operand 1 "ext_register_operand" "0")
6442 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6443 (clobber (reg:CC FLAGS_REG))]
6446 switch (get_attr_type (insn))
6449 if (operands[2] == const1_rtx)
6450 return "inc{b}\t%h0";
6453 gcc_assert (operands[2] == constm1_rtx
6454 || (GET_CODE (operands[2]) == CONST_INT
6455 && INTVAL (operands[2]) == 255));
6456 return "dec{b}\t%h0";
6460 return "add{b}\t{%2, %h0|%h0, %2}";
6464 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6465 (const_string "incdec")
6466 (const_string "alu")))
6467 (set_attr "mode" "QI")])
6469 (define_insn "*addqi_ext_2"
6470 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6475 (match_operand 1 "ext_register_operand" "%0")
6479 (match_operand 2 "ext_register_operand" "Q")
6482 (clobber (reg:CC FLAGS_REG))]
6484 "add{b}\t{%h2, %h0|%h0, %h2}"
6485 [(set_attr "type" "alu")
6486 (set_attr "mode" "QI")])
6488 ;; The patterns that match these are at the end of this file.
6490 (define_expand "addxf3"
6491 [(set (match_operand:XF 0 "register_operand" "")
6492 (plus:XF (match_operand:XF 1 "register_operand" "")
6493 (match_operand:XF 2 "register_operand" "")))]
6497 (define_expand "adddf3"
6498 [(set (match_operand:DF 0 "register_operand" "")
6499 (plus:DF (match_operand:DF 1 "register_operand" "")
6500 (match_operand:DF 2 "nonimmediate_operand" "")))]
6501 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6504 (define_expand "addsf3"
6505 [(set (match_operand:SF 0 "register_operand" "")
6506 (plus:SF (match_operand:SF 1 "register_operand" "")
6507 (match_operand:SF 2 "nonimmediate_operand" "")))]
6508 "TARGET_80387 || TARGET_SSE_MATH"
6511 ;; Subtract instructions
6513 ;; %%% splits for subditi3
6515 (define_expand "subti3"
6516 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6517 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6518 (match_operand:TI 2 "x86_64_general_operand" "")))
6519 (clobber (reg:CC FLAGS_REG))])]
6521 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6523 (define_insn "*subti3_1"
6524 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6525 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6526 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6527 (clobber (reg:CC FLAGS_REG))]
6528 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6532 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6533 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6534 (match_operand:TI 2 "x86_64_general_operand" "")))
6535 (clobber (reg:CC FLAGS_REG))]
6536 "TARGET_64BIT && reload_completed"
6537 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6538 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6539 (parallel [(set (match_dup 3)
6540 (minus:DI (match_dup 4)
6541 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6543 (clobber (reg:CC FLAGS_REG))])]
6544 "split_ti (operands+0, 1, operands+0, operands+3);
6545 split_ti (operands+1, 1, operands+1, operands+4);
6546 split_ti (operands+2, 1, operands+2, operands+5);")
6548 ;; %%% splits for subsidi3
6550 (define_expand "subdi3"
6551 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6552 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6553 (match_operand:DI 2 "x86_64_general_operand" "")))
6554 (clobber (reg:CC FLAGS_REG))])]
6556 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6558 (define_insn "*subdi3_1"
6559 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6560 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6561 (match_operand:DI 2 "general_operand" "roiF,riF")))
6562 (clobber (reg:CC FLAGS_REG))]
6563 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6567 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6568 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6569 (match_operand:DI 2 "general_operand" "")))
6570 (clobber (reg:CC FLAGS_REG))]
6571 "!TARGET_64BIT && reload_completed"
6572 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6573 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6574 (parallel [(set (match_dup 3)
6575 (minus:SI (match_dup 4)
6576 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6578 (clobber (reg:CC FLAGS_REG))])]
6579 "split_di (operands+0, 1, operands+0, operands+3);
6580 split_di (operands+1, 1, operands+1, operands+4);
6581 split_di (operands+2, 1, operands+2, operands+5);")
6583 (define_insn "subdi3_carry_rex64"
6584 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6585 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6586 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6587 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6588 (clobber (reg:CC FLAGS_REG))]
6589 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6590 "sbb{q}\t{%2, %0|%0, %2}"
6591 [(set_attr "type" "alu")
6592 (set_attr "pent_pair" "pu")
6593 (set_attr "mode" "DI")])
6595 (define_insn "*subdi_1_rex64"
6596 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6597 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6598 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6599 (clobber (reg:CC FLAGS_REG))]
6600 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6601 "sub{q}\t{%2, %0|%0, %2}"
6602 [(set_attr "type" "alu")
6603 (set_attr "mode" "DI")])
6605 (define_insn "*subdi_2_rex64"
6606 [(set (reg FLAGS_REG)
6608 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6609 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6611 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6612 (minus:DI (match_dup 1) (match_dup 2)))]
6613 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6614 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6615 "sub{q}\t{%2, %0|%0, %2}"
6616 [(set_attr "type" "alu")
6617 (set_attr "mode" "DI")])
6619 (define_insn "*subdi_3_rex63"
6620 [(set (reg FLAGS_REG)
6621 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6622 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6623 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6624 (minus:DI (match_dup 1) (match_dup 2)))]
6625 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6626 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6627 "sub{q}\t{%2, %0|%0, %2}"
6628 [(set_attr "type" "alu")
6629 (set_attr "mode" "DI")])
6631 (define_insn "subqi3_carry"
6632 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6633 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6634 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6635 (match_operand:QI 2 "general_operand" "qi,qm"))))
6636 (clobber (reg:CC FLAGS_REG))]
6637 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6638 "sbb{b}\t{%2, %0|%0, %2}"
6639 [(set_attr "type" "alu")
6640 (set_attr "pent_pair" "pu")
6641 (set_attr "mode" "QI")])
6643 (define_insn "subhi3_carry"
6644 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6645 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6646 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6647 (match_operand:HI 2 "general_operand" "ri,rm"))))
6648 (clobber (reg:CC FLAGS_REG))]
6649 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6650 "sbb{w}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "pent_pair" "pu")
6653 (set_attr "mode" "HI")])
6655 (define_insn "subsi3_carry"
6656 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6657 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6658 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6659 (match_operand:SI 2 "general_operand" "ri,rm"))))
6660 (clobber (reg:CC FLAGS_REG))]
6661 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6662 "sbb{l}\t{%2, %0|%0, %2}"
6663 [(set_attr "type" "alu")
6664 (set_attr "pent_pair" "pu")
6665 (set_attr "mode" "SI")])
6667 (define_insn "subsi3_carry_zext"
6668 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6670 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6671 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6672 (match_operand:SI 2 "general_operand" "ri,rm")))))
6673 (clobber (reg:CC FLAGS_REG))]
6674 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6675 "sbb{l}\t{%2, %k0|%k0, %2}"
6676 [(set_attr "type" "alu")
6677 (set_attr "pent_pair" "pu")
6678 (set_attr "mode" "SI")])
6680 (define_expand "subsi3"
6681 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6682 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6683 (match_operand:SI 2 "general_operand" "")))
6684 (clobber (reg:CC FLAGS_REG))])]
6686 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6688 (define_insn "*subsi_1"
6689 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6690 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6691 (match_operand:SI 2 "general_operand" "ri,rm")))
6692 (clobber (reg:CC FLAGS_REG))]
6693 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6694 "sub{l}\t{%2, %0|%0, %2}"
6695 [(set_attr "type" "alu")
6696 (set_attr "mode" "SI")])
6698 (define_insn "*subsi_1_zext"
6699 [(set (match_operand:DI 0 "register_operand" "=r")
6701 (minus:SI (match_operand:SI 1 "register_operand" "0")
6702 (match_operand:SI 2 "general_operand" "rim"))))
6703 (clobber (reg:CC FLAGS_REG))]
6704 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6705 "sub{l}\t{%2, %k0|%k0, %2}"
6706 [(set_attr "type" "alu")
6707 (set_attr "mode" "SI")])
6709 (define_insn "*subsi_2"
6710 [(set (reg FLAGS_REG)
6712 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6713 (match_operand:SI 2 "general_operand" "ri,rm"))
6715 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6716 (minus:SI (match_dup 1) (match_dup 2)))]
6717 "ix86_match_ccmode (insn, CCGOCmode)
6718 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6719 "sub{l}\t{%2, %0|%0, %2}"
6720 [(set_attr "type" "alu")
6721 (set_attr "mode" "SI")])
6723 (define_insn "*subsi_2_zext"
6724 [(set (reg FLAGS_REG)
6726 (minus:SI (match_operand:SI 1 "register_operand" "0")
6727 (match_operand:SI 2 "general_operand" "rim"))
6729 (set (match_operand:DI 0 "register_operand" "=r")
6731 (minus:SI (match_dup 1)
6733 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6734 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735 "sub{l}\t{%2, %k0|%k0, %2}"
6736 [(set_attr "type" "alu")
6737 (set_attr "mode" "SI")])
6739 (define_insn "*subsi_3"
6740 [(set (reg FLAGS_REG)
6741 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6742 (match_operand:SI 2 "general_operand" "ri,rm")))
6743 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6744 (minus:SI (match_dup 1) (match_dup 2)))]
6745 "ix86_match_ccmode (insn, CCmode)
6746 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6747 "sub{l}\t{%2, %0|%0, %2}"
6748 [(set_attr "type" "alu")
6749 (set_attr "mode" "SI")])
6751 (define_insn "*subsi_3_zext"
6752 [(set (reg FLAGS_REG)
6753 (compare (match_operand:SI 1 "register_operand" "0")
6754 (match_operand:SI 2 "general_operand" "rim")))
6755 (set (match_operand:DI 0 "register_operand" "=r")
6757 (minus:SI (match_dup 1)
6759 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6760 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6761 "sub{l}\t{%2, %1|%1, %2}"
6762 [(set_attr "type" "alu")
6763 (set_attr "mode" "DI")])
6765 (define_expand "subhi3"
6766 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6767 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6768 (match_operand:HI 2 "general_operand" "")))
6769 (clobber (reg:CC FLAGS_REG))])]
6770 "TARGET_HIMODE_MATH"
6771 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6773 (define_insn "*subhi_1"
6774 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6775 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6776 (match_operand:HI 2 "general_operand" "ri,rm")))
6777 (clobber (reg:CC FLAGS_REG))]
6778 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6779 "sub{w}\t{%2, %0|%0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "HI")])
6783 (define_insn "*subhi_2"
6784 [(set (reg FLAGS_REG)
6786 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6787 (match_operand:HI 2 "general_operand" "ri,rm"))
6789 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6790 (minus:HI (match_dup 1) (match_dup 2)))]
6791 "ix86_match_ccmode (insn, CCGOCmode)
6792 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6793 "sub{w}\t{%2, %0|%0, %2}"
6794 [(set_attr "type" "alu")
6795 (set_attr "mode" "HI")])
6797 (define_insn "*subhi_3"
6798 [(set (reg FLAGS_REG)
6799 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6800 (match_operand:HI 2 "general_operand" "ri,rm")))
6801 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6802 (minus:HI (match_dup 1) (match_dup 2)))]
6803 "ix86_match_ccmode (insn, CCmode)
6804 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6805 "sub{w}\t{%2, %0|%0, %2}"
6806 [(set_attr "type" "alu")
6807 (set_attr "mode" "HI")])
6809 (define_expand "subqi3"
6810 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6811 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6812 (match_operand:QI 2 "general_operand" "")))
6813 (clobber (reg:CC FLAGS_REG))])]
6814 "TARGET_QIMODE_MATH"
6815 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6817 (define_insn "*subqi_1"
6818 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6819 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6820 (match_operand:QI 2 "general_operand" "qn,qmn")))
6821 (clobber (reg:CC FLAGS_REG))]
6822 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6823 "sub{b}\t{%2, %0|%0, %2}"
6824 [(set_attr "type" "alu")
6825 (set_attr "mode" "QI")])
6827 (define_insn "*subqi_1_slp"
6828 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6829 (minus:QI (match_dup 0)
6830 (match_operand:QI 1 "general_operand" "qn,qmn")))
6831 (clobber (reg:CC FLAGS_REG))]
6832 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6833 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6834 "sub{b}\t{%1, %0|%0, %1}"
6835 [(set_attr "type" "alu1")
6836 (set_attr "mode" "QI")])
6838 (define_insn "*subqi_2"
6839 [(set (reg FLAGS_REG)
6841 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6842 (match_operand:QI 2 "general_operand" "qi,qm"))
6844 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6845 (minus:HI (match_dup 1) (match_dup 2)))]
6846 "ix86_match_ccmode (insn, CCGOCmode)
6847 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6848 "sub{b}\t{%2, %0|%0, %2}"
6849 [(set_attr "type" "alu")
6850 (set_attr "mode" "QI")])
6852 (define_insn "*subqi_3"
6853 [(set (reg FLAGS_REG)
6854 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6855 (match_operand:QI 2 "general_operand" "qi,qm")))
6856 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6857 (minus:HI (match_dup 1) (match_dup 2)))]
6858 "ix86_match_ccmode (insn, CCmode)
6859 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6860 "sub{b}\t{%2, %0|%0, %2}"
6861 [(set_attr "type" "alu")
6862 (set_attr "mode" "QI")])
6864 ;; The patterns that match these are at the end of this file.
6866 (define_expand "subxf3"
6867 [(set (match_operand:XF 0 "register_operand" "")
6868 (minus:XF (match_operand:XF 1 "register_operand" "")
6869 (match_operand:XF 2 "register_operand" "")))]
6873 (define_expand "subdf3"
6874 [(set (match_operand:DF 0 "register_operand" "")
6875 (minus:DF (match_operand:DF 1 "register_operand" "")
6876 (match_operand:DF 2 "nonimmediate_operand" "")))]
6877 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6880 (define_expand "subsf3"
6881 [(set (match_operand:SF 0 "register_operand" "")
6882 (minus:SF (match_operand:SF 1 "register_operand" "")
6883 (match_operand:SF 2 "nonimmediate_operand" "")))]
6884 "TARGET_80387 || TARGET_SSE_MATH"
6887 ;; Multiply instructions
6889 (define_expand "muldi3"
6890 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6891 (mult:DI (match_operand:DI 1 "register_operand" "")
6892 (match_operand:DI 2 "x86_64_general_operand" "")))
6893 (clobber (reg:CC FLAGS_REG))])]
6898 ;; IMUL reg64, reg64, imm8 Direct
6899 ;; IMUL reg64, mem64, imm8 VectorPath
6900 ;; IMUL reg64, reg64, imm32 Direct
6901 ;; IMUL reg64, mem64, imm32 VectorPath
6902 ;; IMUL reg64, reg64 Direct
6903 ;; IMUL reg64, mem64 Direct
6905 (define_insn "*muldi3_1_rex64"
6906 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6907 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6908 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6909 (clobber (reg:CC FLAGS_REG))]
6911 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6913 imul{q}\t{%2, %1, %0|%0, %1, %2}
6914 imul{q}\t{%2, %1, %0|%0, %1, %2}
6915 imul{q}\t{%2, %0|%0, %2}"
6916 [(set_attr "type" "imul")
6917 (set_attr "prefix_0f" "0,0,1")
6918 (set (attr "athlon_decode")
6919 (cond [(eq_attr "cpu" "athlon")
6920 (const_string "vector")
6921 (eq_attr "alternative" "1")
6922 (const_string "vector")
6923 (and (eq_attr "alternative" "2")
6924 (match_operand 1 "memory_operand" ""))
6925 (const_string "vector")]
6926 (const_string "direct")))
6927 (set (attr "amdfam10_decode")
6928 (cond [(and (eq_attr "alternative" "0,1")
6929 (match_operand 1 "memory_operand" ""))
6930 (const_string "vector")]
6931 (const_string "direct")))
6932 (set_attr "mode" "DI")])
6934 (define_expand "mulsi3"
6935 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6936 (mult:SI (match_operand:SI 1 "register_operand" "")
6937 (match_operand:SI 2 "general_operand" "")))
6938 (clobber (reg:CC FLAGS_REG))])]
6943 ;; IMUL reg32, reg32, imm8 Direct
6944 ;; IMUL reg32, mem32, imm8 VectorPath
6945 ;; IMUL reg32, reg32, imm32 Direct
6946 ;; IMUL reg32, mem32, imm32 VectorPath
6947 ;; IMUL reg32, reg32 Direct
6948 ;; IMUL reg32, mem32 Direct
6950 (define_insn "*mulsi3_1"
6951 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6952 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6953 (match_operand:SI 2 "general_operand" "K,i,mr")))
6954 (clobber (reg:CC FLAGS_REG))]
6955 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6957 imul{l}\t{%2, %1, %0|%0, %1, %2}
6958 imul{l}\t{%2, %1, %0|%0, %1, %2}
6959 imul{l}\t{%2, %0|%0, %2}"
6960 [(set_attr "type" "imul")
6961 (set_attr "prefix_0f" "0,0,1")
6962 (set (attr "athlon_decode")
6963 (cond [(eq_attr "cpu" "athlon")
6964 (const_string "vector")
6965 (eq_attr "alternative" "1")
6966 (const_string "vector")
6967 (and (eq_attr "alternative" "2")
6968 (match_operand 1 "memory_operand" ""))
6969 (const_string "vector")]
6970 (const_string "direct")))
6971 (set (attr "amdfam10_decode")
6972 (cond [(and (eq_attr "alternative" "0,1")
6973 (match_operand 1 "memory_operand" ""))
6974 (const_string "vector")]
6975 (const_string "direct")))
6976 (set_attr "mode" "SI")])
6978 (define_insn "*mulsi3_1_zext"
6979 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6981 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6982 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6983 (clobber (reg:CC FLAGS_REG))]
6985 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6987 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6988 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6989 imul{l}\t{%2, %k0|%k0, %2}"
6990 [(set_attr "type" "imul")
6991 (set_attr "prefix_0f" "0,0,1")
6992 (set (attr "athlon_decode")
6993 (cond [(eq_attr "cpu" "athlon")
6994 (const_string "vector")
6995 (eq_attr "alternative" "1")
6996 (const_string "vector")
6997 (and (eq_attr "alternative" "2")
6998 (match_operand 1 "memory_operand" ""))
6999 (const_string "vector")]
7000 (const_string "direct")))
7001 (set (attr "amdfam10_decode")
7002 (cond [(and (eq_attr "alternative" "0,1")
7003 (match_operand 1 "memory_operand" ""))
7004 (const_string "vector")]
7005 (const_string "direct")))
7006 (set_attr "mode" "SI")])
7008 (define_expand "mulhi3"
7009 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7010 (mult:HI (match_operand:HI 1 "register_operand" "")
7011 (match_operand:HI 2 "general_operand" "")))
7012 (clobber (reg:CC FLAGS_REG))])]
7013 "TARGET_HIMODE_MATH"
7017 ;; IMUL reg16, reg16, imm8 VectorPath
7018 ;; IMUL reg16, mem16, imm8 VectorPath
7019 ;; IMUL reg16, reg16, imm16 VectorPath
7020 ;; IMUL reg16, mem16, imm16 VectorPath
7021 ;; IMUL reg16, reg16 Direct
7022 ;; IMUL reg16, mem16 Direct
7023 (define_insn "*mulhi3_1"
7024 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7025 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7026 (match_operand:HI 2 "general_operand" "K,i,mr")))
7027 (clobber (reg:CC FLAGS_REG))]
7028 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7030 imul{w}\t{%2, %1, %0|%0, %1, %2}
7031 imul{w}\t{%2, %1, %0|%0, %1, %2}
7032 imul{w}\t{%2, %0|%0, %2}"
7033 [(set_attr "type" "imul")
7034 (set_attr "prefix_0f" "0,0,1")
7035 (set (attr "athlon_decode")
7036 (cond [(eq_attr "cpu" "athlon")
7037 (const_string "vector")
7038 (eq_attr "alternative" "1,2")
7039 (const_string "vector")]
7040 (const_string "direct")))
7041 (set (attr "amdfam10_decode")
7042 (cond [(eq_attr "alternative" "0,1")
7043 (const_string "vector")]
7044 (const_string "direct")))
7045 (set_attr "mode" "HI")])
7047 (define_expand "mulqi3"
7048 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7049 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7050 (match_operand:QI 2 "register_operand" "")))
7051 (clobber (reg:CC FLAGS_REG))])]
7052 "TARGET_QIMODE_MATH"
7059 (define_insn "*mulqi3_1"
7060 [(set (match_operand:QI 0 "register_operand" "=a")
7061 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7062 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7063 (clobber (reg:CC FLAGS_REG))]
7065 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7067 [(set_attr "type" "imul")
7068 (set_attr "length_immediate" "0")
7069 (set (attr "athlon_decode")
7070 (if_then_else (eq_attr "cpu" "athlon")
7071 (const_string "vector")
7072 (const_string "direct")))
7073 (set_attr "amdfam10_decode" "direct")
7074 (set_attr "mode" "QI")])
7076 (define_expand "umulqihi3"
7077 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7078 (mult:HI (zero_extend:HI
7079 (match_operand:QI 1 "nonimmediate_operand" ""))
7081 (match_operand:QI 2 "register_operand" ""))))
7082 (clobber (reg:CC FLAGS_REG))])]
7083 "TARGET_QIMODE_MATH"
7086 (define_insn "*umulqihi3_1"
7087 [(set (match_operand:HI 0 "register_operand" "=a")
7088 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7089 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7090 (clobber (reg:CC FLAGS_REG))]
7092 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7094 [(set_attr "type" "imul")
7095 (set_attr "length_immediate" "0")
7096 (set (attr "athlon_decode")
7097 (if_then_else (eq_attr "cpu" "athlon")
7098 (const_string "vector")
7099 (const_string "direct")))
7100 (set_attr "amdfam10_decode" "direct")
7101 (set_attr "mode" "QI")])
7103 (define_expand "mulqihi3"
7104 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7105 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7106 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7107 (clobber (reg:CC FLAGS_REG))])]
7108 "TARGET_QIMODE_MATH"
7111 (define_insn "*mulqihi3_insn"
7112 [(set (match_operand:HI 0 "register_operand" "=a")
7113 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7114 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7115 (clobber (reg:CC FLAGS_REG))]
7117 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7119 [(set_attr "type" "imul")
7120 (set_attr "length_immediate" "0")
7121 (set (attr "athlon_decode")
7122 (if_then_else (eq_attr "cpu" "athlon")
7123 (const_string "vector")
7124 (const_string "direct")))
7125 (set_attr "amdfam10_decode" "direct")
7126 (set_attr "mode" "QI")])
7128 (define_expand "umulditi3"
7129 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7130 (mult:TI (zero_extend:TI
7131 (match_operand:DI 1 "nonimmediate_operand" ""))
7133 (match_operand:DI 2 "register_operand" ""))))
7134 (clobber (reg:CC FLAGS_REG))])]
7138 (define_insn "*umulditi3_insn"
7139 [(set (match_operand:TI 0 "register_operand" "=A")
7140 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7141 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7142 (clobber (reg:CC FLAGS_REG))]
7144 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7146 [(set_attr "type" "imul")
7147 (set_attr "length_immediate" "0")
7148 (set (attr "athlon_decode")
7149 (if_then_else (eq_attr "cpu" "athlon")
7150 (const_string "vector")
7151 (const_string "double")))
7152 (set_attr "amdfam10_decode" "double")
7153 (set_attr "mode" "DI")])
7155 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7156 (define_expand "umulsidi3"
7157 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7158 (mult:DI (zero_extend:DI
7159 (match_operand:SI 1 "nonimmediate_operand" ""))
7161 (match_operand:SI 2 "register_operand" ""))))
7162 (clobber (reg:CC FLAGS_REG))])]
7166 (define_insn "*umulsidi3_insn"
7167 [(set (match_operand:DI 0 "register_operand" "=A")
7168 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7169 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7170 (clobber (reg:CC FLAGS_REG))]
7172 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7174 [(set_attr "type" "imul")
7175 (set_attr "length_immediate" "0")
7176 (set (attr "athlon_decode")
7177 (if_then_else (eq_attr "cpu" "athlon")
7178 (const_string "vector")
7179 (const_string "double")))
7180 (set_attr "amdfam10_decode" "double")
7181 (set_attr "mode" "SI")])
7183 (define_expand "mulditi3"
7184 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7185 (mult:TI (sign_extend:TI
7186 (match_operand:DI 1 "nonimmediate_operand" ""))
7188 (match_operand:DI 2 "register_operand" ""))))
7189 (clobber (reg:CC FLAGS_REG))])]
7193 (define_insn "*mulditi3_insn"
7194 [(set (match_operand:TI 0 "register_operand" "=A")
7195 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7196 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7197 (clobber (reg:CC FLAGS_REG))]
7199 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7201 [(set_attr "type" "imul")
7202 (set_attr "length_immediate" "0")
7203 (set (attr "athlon_decode")
7204 (if_then_else (eq_attr "cpu" "athlon")
7205 (const_string "vector")
7206 (const_string "double")))
7207 (set_attr "amdfam10_decode" "double")
7208 (set_attr "mode" "DI")])
7210 (define_expand "mulsidi3"
7211 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7212 (mult:DI (sign_extend:DI
7213 (match_operand:SI 1 "nonimmediate_operand" ""))
7215 (match_operand:SI 2 "register_operand" ""))))
7216 (clobber (reg:CC FLAGS_REG))])]
7220 (define_insn "*mulsidi3_insn"
7221 [(set (match_operand:DI 0 "register_operand" "=A")
7222 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7223 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7224 (clobber (reg:CC FLAGS_REG))]
7226 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7228 [(set_attr "type" "imul")
7229 (set_attr "length_immediate" "0")
7230 (set (attr "athlon_decode")
7231 (if_then_else (eq_attr "cpu" "athlon")
7232 (const_string "vector")
7233 (const_string "double")))
7234 (set_attr "amdfam10_decode" "double")
7235 (set_attr "mode" "SI")])
7237 (define_expand "umuldi3_highpart"
7238 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7241 (mult:TI (zero_extend:TI
7242 (match_operand:DI 1 "nonimmediate_operand" ""))
7244 (match_operand:DI 2 "register_operand" "")))
7246 (clobber (match_scratch:DI 3 ""))
7247 (clobber (reg:CC FLAGS_REG))])]
7251 (define_insn "*umuldi3_highpart_rex64"
7252 [(set (match_operand:DI 0 "register_operand" "=d")
7255 (mult:TI (zero_extend:TI
7256 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7258 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7260 (clobber (match_scratch:DI 3 "=1"))
7261 (clobber (reg:CC FLAGS_REG))]
7263 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7265 [(set_attr "type" "imul")
7266 (set_attr "length_immediate" "0")
7267 (set (attr "athlon_decode")
7268 (if_then_else (eq_attr "cpu" "athlon")
7269 (const_string "vector")
7270 (const_string "double")))
7271 (set_attr "amdfam10_decode" "double")
7272 (set_attr "mode" "DI")])
7274 (define_expand "umulsi3_highpart"
7275 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7278 (mult:DI (zero_extend:DI
7279 (match_operand:SI 1 "nonimmediate_operand" ""))
7281 (match_operand:SI 2 "register_operand" "")))
7283 (clobber (match_scratch:SI 3 ""))
7284 (clobber (reg:CC FLAGS_REG))])]
7288 (define_insn "*umulsi3_highpart_insn"
7289 [(set (match_operand:SI 0 "register_operand" "=d")
7292 (mult:DI (zero_extend:DI
7293 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7295 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7297 (clobber (match_scratch:SI 3 "=1"))
7298 (clobber (reg:CC FLAGS_REG))]
7299 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7301 [(set_attr "type" "imul")
7302 (set_attr "length_immediate" "0")
7303 (set (attr "athlon_decode")
7304 (if_then_else (eq_attr "cpu" "athlon")
7305 (const_string "vector")
7306 (const_string "double")))
7307 (set_attr "amdfam10_decode" "double")
7308 (set_attr "mode" "SI")])
7310 (define_insn "*umulsi3_highpart_zext"
7311 [(set (match_operand:DI 0 "register_operand" "=d")
7312 (zero_extend:DI (truncate:SI
7314 (mult:DI (zero_extend:DI
7315 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7317 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7319 (clobber (match_scratch:SI 3 "=1"))
7320 (clobber (reg:CC FLAGS_REG))]
7322 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7324 [(set_attr "type" "imul")
7325 (set_attr "length_immediate" "0")
7326 (set (attr "athlon_decode")
7327 (if_then_else (eq_attr "cpu" "athlon")
7328 (const_string "vector")
7329 (const_string "double")))
7330 (set_attr "amdfam10_decode" "double")
7331 (set_attr "mode" "SI")])
7333 (define_expand "smuldi3_highpart"
7334 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7337 (mult:TI (sign_extend:TI
7338 (match_operand:DI 1 "nonimmediate_operand" ""))
7340 (match_operand:DI 2 "register_operand" "")))
7342 (clobber (match_scratch:DI 3 ""))
7343 (clobber (reg:CC FLAGS_REG))])]
7347 (define_insn "*smuldi3_highpart_rex64"
7348 [(set (match_operand:DI 0 "register_operand" "=d")
7351 (mult:TI (sign_extend:TI
7352 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7354 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7356 (clobber (match_scratch:DI 3 "=1"))
7357 (clobber (reg:CC FLAGS_REG))]
7359 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7361 [(set_attr "type" "imul")
7362 (set (attr "athlon_decode")
7363 (if_then_else (eq_attr "cpu" "athlon")
7364 (const_string "vector")
7365 (const_string "double")))
7366 (set_attr "amdfam10_decode" "double")
7367 (set_attr "mode" "DI")])
7369 (define_expand "smulsi3_highpart"
7370 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7373 (mult:DI (sign_extend:DI
7374 (match_operand:SI 1 "nonimmediate_operand" ""))
7376 (match_operand:SI 2 "register_operand" "")))
7378 (clobber (match_scratch:SI 3 ""))
7379 (clobber (reg:CC FLAGS_REG))])]
7383 (define_insn "*smulsi3_highpart_insn"
7384 [(set (match_operand:SI 0 "register_operand" "=d")
7387 (mult:DI (sign_extend:DI
7388 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7390 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7392 (clobber (match_scratch:SI 3 "=1"))
7393 (clobber (reg:CC FLAGS_REG))]
7394 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7396 [(set_attr "type" "imul")
7397 (set (attr "athlon_decode")
7398 (if_then_else (eq_attr "cpu" "athlon")
7399 (const_string "vector")
7400 (const_string "double")))
7401 (set_attr "amdfam10_decode" "double")
7402 (set_attr "mode" "SI")])
7404 (define_insn "*smulsi3_highpart_zext"
7405 [(set (match_operand:DI 0 "register_operand" "=d")
7406 (zero_extend:DI (truncate:SI
7408 (mult:DI (sign_extend:DI
7409 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7411 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7413 (clobber (match_scratch:SI 3 "=1"))
7414 (clobber (reg:CC FLAGS_REG))]
7416 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7418 [(set_attr "type" "imul")
7419 (set (attr "athlon_decode")
7420 (if_then_else (eq_attr "cpu" "athlon")
7421 (const_string "vector")
7422 (const_string "double")))
7423 (set_attr "amdfam10_decode" "double")
7424 (set_attr "mode" "SI")])
7426 ;; The patterns that match these are at the end of this file.
7428 (define_expand "mulxf3"
7429 [(set (match_operand:XF 0 "register_operand" "")
7430 (mult:XF (match_operand:XF 1 "register_operand" "")
7431 (match_operand:XF 2 "register_operand" "")))]
7435 (define_expand "muldf3"
7436 [(set (match_operand:DF 0 "register_operand" "")
7437 (mult:DF (match_operand:DF 1 "register_operand" "")
7438 (match_operand:DF 2 "nonimmediate_operand" "")))]
7439 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7442 (define_expand "mulsf3"
7443 [(set (match_operand:SF 0 "register_operand" "")
7444 (mult:SF (match_operand:SF 1 "register_operand" "")
7445 (match_operand:SF 2 "nonimmediate_operand" "")))]
7446 "TARGET_80387 || TARGET_SSE_MATH"
7449 ;; Divide instructions
7451 (define_insn "divqi3"
7452 [(set (match_operand:QI 0 "register_operand" "=a")
7453 (div:QI (match_operand:HI 1 "register_operand" "0")
7454 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7455 (clobber (reg:CC FLAGS_REG))]
7456 "TARGET_QIMODE_MATH"
7458 [(set_attr "type" "idiv")
7459 (set_attr "mode" "QI")])
7461 (define_insn "udivqi3"
7462 [(set (match_operand:QI 0 "register_operand" "=a")
7463 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7464 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7465 (clobber (reg:CC FLAGS_REG))]
7466 "TARGET_QIMODE_MATH"
7468 [(set_attr "type" "idiv")
7469 (set_attr "mode" "QI")])
7471 ;; The patterns that match these are at the end of this file.
7473 (define_expand "divxf3"
7474 [(set (match_operand:XF 0 "register_operand" "")
7475 (div:XF (match_operand:XF 1 "register_operand" "")
7476 (match_operand:XF 2 "register_operand" "")))]
7480 (define_expand "divdf3"
7481 [(set (match_operand:DF 0 "register_operand" "")
7482 (div:DF (match_operand:DF 1 "register_operand" "")
7483 (match_operand:DF 2 "nonimmediate_operand" "")))]
7484 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7487 (define_expand "divsf3"
7488 [(set (match_operand:SF 0 "register_operand" "")
7489 (div:SF (match_operand:SF 1 "register_operand" "")
7490 (match_operand:SF 2 "nonimmediate_operand" "")))]
7491 "TARGET_80387 || TARGET_SSE_MATH"
7494 ;; Remainder instructions.
7496 (define_expand "divmoddi4"
7497 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7498 (div:DI (match_operand:DI 1 "register_operand" "")
7499 (match_operand:DI 2 "nonimmediate_operand" "")))
7500 (set (match_operand:DI 3 "register_operand" "")
7501 (mod:DI (match_dup 1) (match_dup 2)))
7502 (clobber (reg:CC FLAGS_REG))])]
7506 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7507 ;; Penalize eax case slightly because it results in worse scheduling
7509 (define_insn "*divmoddi4_nocltd_rex64"
7510 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7511 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7512 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7513 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7514 (mod:DI (match_dup 2) (match_dup 3)))
7515 (clobber (reg:CC FLAGS_REG))]
7516 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7518 [(set_attr "type" "multi")])
7520 (define_insn "*divmoddi4_cltd_rex64"
7521 [(set (match_operand:DI 0 "register_operand" "=a")
7522 (div:DI (match_operand:DI 2 "register_operand" "a")
7523 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7524 (set (match_operand:DI 1 "register_operand" "=&d")
7525 (mod:DI (match_dup 2) (match_dup 3)))
7526 (clobber (reg:CC FLAGS_REG))]
7527 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7529 [(set_attr "type" "multi")])
7531 (define_insn "*divmoddi_noext_rex64"
7532 [(set (match_operand:DI 0 "register_operand" "=a")
7533 (div:DI (match_operand:DI 1 "register_operand" "0")
7534 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7535 (set (match_operand:DI 3 "register_operand" "=d")
7536 (mod:DI (match_dup 1) (match_dup 2)))
7537 (use (match_operand:DI 4 "register_operand" "3"))
7538 (clobber (reg:CC FLAGS_REG))]
7541 [(set_attr "type" "idiv")
7542 (set_attr "mode" "DI")])
7545 [(set (match_operand:DI 0 "register_operand" "")
7546 (div:DI (match_operand:DI 1 "register_operand" "")
7547 (match_operand:DI 2 "nonimmediate_operand" "")))
7548 (set (match_operand:DI 3 "register_operand" "")
7549 (mod:DI (match_dup 1) (match_dup 2)))
7550 (clobber (reg:CC FLAGS_REG))]
7551 "TARGET_64BIT && reload_completed"
7552 [(parallel [(set (match_dup 3)
7553 (ashiftrt:DI (match_dup 4) (const_int 63)))
7554 (clobber (reg:CC FLAGS_REG))])
7555 (parallel [(set (match_dup 0)
7556 (div:DI (reg:DI 0) (match_dup 2)))
7558 (mod:DI (reg:DI 0) (match_dup 2)))
7560 (clobber (reg:CC FLAGS_REG))])]
7562 /* Avoid use of cltd in favor of a mov+shift. */
7563 if (!TARGET_USE_CLTD && !optimize_size)
7565 if (true_regnum (operands[1]))
7566 emit_move_insn (operands[0], operands[1]);
7568 emit_move_insn (operands[3], operands[1]);
7569 operands[4] = operands[3];
7573 gcc_assert (!true_regnum (operands[1]));
7574 operands[4] = operands[1];
7579 (define_expand "divmodsi4"
7580 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7581 (div:SI (match_operand:SI 1 "register_operand" "")
7582 (match_operand:SI 2 "nonimmediate_operand" "")))
7583 (set (match_operand:SI 3 "register_operand" "")
7584 (mod:SI (match_dup 1) (match_dup 2)))
7585 (clobber (reg:CC FLAGS_REG))])]
7589 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7590 ;; Penalize eax case slightly because it results in worse scheduling
7592 (define_insn "*divmodsi4_nocltd"
7593 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7594 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7595 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7596 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7597 (mod:SI (match_dup 2) (match_dup 3)))
7598 (clobber (reg:CC FLAGS_REG))]
7599 "!optimize_size && !TARGET_USE_CLTD"
7601 [(set_attr "type" "multi")])
7603 (define_insn "*divmodsi4_cltd"
7604 [(set (match_operand:SI 0 "register_operand" "=a")
7605 (div:SI (match_operand:SI 2 "register_operand" "a")
7606 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7607 (set (match_operand:SI 1 "register_operand" "=&d")
7608 (mod:SI (match_dup 2) (match_dup 3)))
7609 (clobber (reg:CC FLAGS_REG))]
7610 "optimize_size || TARGET_USE_CLTD"
7612 [(set_attr "type" "multi")])
7614 (define_insn "*divmodsi_noext"
7615 [(set (match_operand:SI 0 "register_operand" "=a")
7616 (div:SI (match_operand:SI 1 "register_operand" "0")
7617 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7618 (set (match_operand:SI 3 "register_operand" "=d")
7619 (mod:SI (match_dup 1) (match_dup 2)))
7620 (use (match_operand:SI 4 "register_operand" "3"))
7621 (clobber (reg:CC FLAGS_REG))]
7624 [(set_attr "type" "idiv")
7625 (set_attr "mode" "SI")])
7628 [(set (match_operand:SI 0 "register_operand" "")
7629 (div:SI (match_operand:SI 1 "register_operand" "")
7630 (match_operand:SI 2 "nonimmediate_operand" "")))
7631 (set (match_operand:SI 3 "register_operand" "")
7632 (mod:SI (match_dup 1) (match_dup 2)))
7633 (clobber (reg:CC FLAGS_REG))]
7635 [(parallel [(set (match_dup 3)
7636 (ashiftrt:SI (match_dup 4) (const_int 31)))
7637 (clobber (reg:CC FLAGS_REG))])
7638 (parallel [(set (match_dup 0)
7639 (div:SI (reg:SI 0) (match_dup 2)))
7641 (mod:SI (reg:SI 0) (match_dup 2)))
7643 (clobber (reg:CC FLAGS_REG))])]
7645 /* Avoid use of cltd in favor of a mov+shift. */
7646 if (!TARGET_USE_CLTD && !optimize_size)
7648 if (true_regnum (operands[1]))
7649 emit_move_insn (operands[0], operands[1]);
7651 emit_move_insn (operands[3], operands[1]);
7652 operands[4] = operands[3];
7656 gcc_assert (!true_regnum (operands[1]));
7657 operands[4] = operands[1];
7661 (define_insn "divmodhi4"
7662 [(set (match_operand:HI 0 "register_operand" "=a")
7663 (div:HI (match_operand:HI 1 "register_operand" "0")
7664 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7665 (set (match_operand:HI 3 "register_operand" "=&d")
7666 (mod:HI (match_dup 1) (match_dup 2)))
7667 (clobber (reg:CC FLAGS_REG))]
7668 "TARGET_HIMODE_MATH"
7670 [(set_attr "type" "multi")
7671 (set_attr "length_immediate" "0")
7672 (set_attr "mode" "SI")])
7674 (define_insn "udivmoddi4"
7675 [(set (match_operand:DI 0 "register_operand" "=a")
7676 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7677 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7678 (set (match_operand:DI 3 "register_operand" "=&d")
7679 (umod:DI (match_dup 1) (match_dup 2)))
7680 (clobber (reg:CC FLAGS_REG))]
7682 "xor{q}\t%3, %3\;div{q}\t%2"
7683 [(set_attr "type" "multi")
7684 (set_attr "length_immediate" "0")
7685 (set_attr "mode" "DI")])
7687 (define_insn "*udivmoddi4_noext"
7688 [(set (match_operand:DI 0 "register_operand" "=a")
7689 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7690 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7691 (set (match_operand:DI 3 "register_operand" "=d")
7692 (umod:DI (match_dup 1) (match_dup 2)))
7694 (clobber (reg:CC FLAGS_REG))]
7697 [(set_attr "type" "idiv")
7698 (set_attr "mode" "DI")])
7701 [(set (match_operand:DI 0 "register_operand" "")
7702 (udiv:DI (match_operand:DI 1 "register_operand" "")
7703 (match_operand:DI 2 "nonimmediate_operand" "")))
7704 (set (match_operand:DI 3 "register_operand" "")
7705 (umod:DI (match_dup 1) (match_dup 2)))
7706 (clobber (reg:CC FLAGS_REG))]
7707 "TARGET_64BIT && reload_completed"
7708 [(set (match_dup 3) (const_int 0))
7709 (parallel [(set (match_dup 0)
7710 (udiv:DI (match_dup 1) (match_dup 2)))
7712 (umod:DI (match_dup 1) (match_dup 2)))
7714 (clobber (reg:CC FLAGS_REG))])]
7717 (define_insn "udivmodsi4"
7718 [(set (match_operand:SI 0 "register_operand" "=a")
7719 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7720 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7721 (set (match_operand:SI 3 "register_operand" "=&d")
7722 (umod:SI (match_dup 1) (match_dup 2)))
7723 (clobber (reg:CC FLAGS_REG))]
7725 "xor{l}\t%3, %3\;div{l}\t%2"
7726 [(set_attr "type" "multi")
7727 (set_attr "length_immediate" "0")
7728 (set_attr "mode" "SI")])
7730 (define_insn "*udivmodsi4_noext"
7731 [(set (match_operand:SI 0 "register_operand" "=a")
7732 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7733 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7734 (set (match_operand:SI 3 "register_operand" "=d")
7735 (umod:SI (match_dup 1) (match_dup 2)))
7737 (clobber (reg:CC FLAGS_REG))]
7740 [(set_attr "type" "idiv")
7741 (set_attr "mode" "SI")])
7744 [(set (match_operand:SI 0 "register_operand" "")
7745 (udiv:SI (match_operand:SI 1 "register_operand" "")
7746 (match_operand:SI 2 "nonimmediate_operand" "")))
7747 (set (match_operand:SI 3 "register_operand" "")
7748 (umod:SI (match_dup 1) (match_dup 2)))
7749 (clobber (reg:CC FLAGS_REG))]
7751 [(set (match_dup 3) (const_int 0))
7752 (parallel [(set (match_dup 0)
7753 (udiv:SI (match_dup 1) (match_dup 2)))
7755 (umod:SI (match_dup 1) (match_dup 2)))
7757 (clobber (reg:CC FLAGS_REG))])]
7760 (define_expand "udivmodhi4"
7761 [(set (match_dup 4) (const_int 0))
7762 (parallel [(set (match_operand:HI 0 "register_operand" "")
7763 (udiv:HI (match_operand:HI 1 "register_operand" "")
7764 (match_operand:HI 2 "nonimmediate_operand" "")))
7765 (set (match_operand:HI 3 "register_operand" "")
7766 (umod:HI (match_dup 1) (match_dup 2)))
7768 (clobber (reg:CC FLAGS_REG))])]
7769 "TARGET_HIMODE_MATH"
7770 "operands[4] = gen_reg_rtx (HImode);")
7772 (define_insn "*udivmodhi_noext"
7773 [(set (match_operand:HI 0 "register_operand" "=a")
7774 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7775 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7776 (set (match_operand:HI 3 "register_operand" "=d")
7777 (umod:HI (match_dup 1) (match_dup 2)))
7778 (use (match_operand:HI 4 "register_operand" "3"))
7779 (clobber (reg:CC FLAGS_REG))]
7782 [(set_attr "type" "idiv")
7783 (set_attr "mode" "HI")])
7785 ;; We cannot use div/idiv for double division, because it causes
7786 ;; "division by zero" on the overflow and that's not what we expect
7787 ;; from truncate. Because true (non truncating) double division is
7788 ;; never generated, we can't create this insn anyway.
7791 ; [(set (match_operand:SI 0 "register_operand" "=a")
7793 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7795 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7796 ; (set (match_operand:SI 3 "register_operand" "=d")
7798 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7799 ; (clobber (reg:CC FLAGS_REG))]
7801 ; "div{l}\t{%2, %0|%0, %2}"
7802 ; [(set_attr "type" "idiv")])
7804 ;;- Logical AND instructions
7806 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7807 ;; Note that this excludes ah.
7809 (define_insn "*testdi_1_rex64"
7810 [(set (reg FLAGS_REG)
7812 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7813 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7815 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7816 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7818 test{l}\t{%k1, %k0|%k0, %k1}
7819 test{l}\t{%k1, %k0|%k0, %k1}
7820 test{q}\t{%1, %0|%0, %1}
7821 test{q}\t{%1, %0|%0, %1}
7822 test{q}\t{%1, %0|%0, %1}"
7823 [(set_attr "type" "test")
7824 (set_attr "modrm" "0,1,0,1,1")
7825 (set_attr "mode" "SI,SI,DI,DI,DI")
7826 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7828 (define_insn "testsi_1"
7829 [(set (reg FLAGS_REG)
7831 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7832 (match_operand:SI 1 "general_operand" "in,in,rin"))
7834 "ix86_match_ccmode (insn, CCNOmode)
7835 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7836 "test{l}\t{%1, %0|%0, %1}"
7837 [(set_attr "type" "test")
7838 (set_attr "modrm" "0,1,1")
7839 (set_attr "mode" "SI")
7840 (set_attr "pent_pair" "uv,np,uv")])
7842 (define_expand "testsi_ccno_1"
7843 [(set (reg:CCNO FLAGS_REG)
7845 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7846 (match_operand:SI 1 "nonmemory_operand" ""))
7851 (define_insn "*testhi_1"
7852 [(set (reg FLAGS_REG)
7853 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7854 (match_operand:HI 1 "general_operand" "n,n,rn"))
7856 "ix86_match_ccmode (insn, CCNOmode)
7857 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7858 "test{w}\t{%1, %0|%0, %1}"
7859 [(set_attr "type" "test")
7860 (set_attr "modrm" "0,1,1")
7861 (set_attr "mode" "HI")
7862 (set_attr "pent_pair" "uv,np,uv")])
7864 (define_expand "testqi_ccz_1"
7865 [(set (reg:CCZ FLAGS_REG)
7866 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7867 (match_operand:QI 1 "nonmemory_operand" ""))
7872 (define_insn "*testqi_1_maybe_si"
7873 [(set (reg FLAGS_REG)
7876 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7877 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7879 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7880 && ix86_match_ccmode (insn,
7881 GET_CODE (operands[1]) == CONST_INT
7882 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7884 if (which_alternative == 3)
7886 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7887 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7888 return "test{l}\t{%1, %k0|%k0, %1}";
7890 return "test{b}\t{%1, %0|%0, %1}";
7892 [(set_attr "type" "test")
7893 (set_attr "modrm" "0,1,1,1")
7894 (set_attr "mode" "QI,QI,QI,SI")
7895 (set_attr "pent_pair" "uv,np,uv,np")])
7897 (define_insn "*testqi_1"
7898 [(set (reg FLAGS_REG)
7901 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7902 (match_operand:QI 1 "general_operand" "n,n,qn"))
7904 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7905 && ix86_match_ccmode (insn, CCNOmode)"
7906 "test{b}\t{%1, %0|%0, %1}"
7907 [(set_attr "type" "test")
7908 (set_attr "modrm" "0,1,1")
7909 (set_attr "mode" "QI")
7910 (set_attr "pent_pair" "uv,np,uv")])
7912 (define_expand "testqi_ext_ccno_0"
7913 [(set (reg:CCNO FLAGS_REG)
7917 (match_operand 0 "ext_register_operand" "")
7920 (match_operand 1 "const_int_operand" ""))
7925 (define_insn "*testqi_ext_0"
7926 [(set (reg FLAGS_REG)
7930 (match_operand 0 "ext_register_operand" "Q")
7933 (match_operand 1 "const_int_operand" "n"))
7935 "ix86_match_ccmode (insn, CCNOmode)"
7936 "test{b}\t{%1, %h0|%h0, %1}"
7937 [(set_attr "type" "test")
7938 (set_attr "mode" "QI")
7939 (set_attr "length_immediate" "1")
7940 (set_attr "pent_pair" "np")])
7942 (define_insn "*testqi_ext_1"
7943 [(set (reg FLAGS_REG)
7947 (match_operand 0 "ext_register_operand" "Q")
7951 (match_operand:QI 1 "general_operand" "Qm")))
7953 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7954 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7955 "test{b}\t{%1, %h0|%h0, %1}"
7956 [(set_attr "type" "test")
7957 (set_attr "mode" "QI")])
7959 (define_insn "*testqi_ext_1_rex64"
7960 [(set (reg FLAGS_REG)
7964 (match_operand 0 "ext_register_operand" "Q")
7968 (match_operand:QI 1 "register_operand" "Q")))
7970 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7971 "test{b}\t{%1, %h0|%h0, %1}"
7972 [(set_attr "type" "test")
7973 (set_attr "mode" "QI")])
7975 (define_insn "*testqi_ext_2"
7976 [(set (reg FLAGS_REG)
7980 (match_operand 0 "ext_register_operand" "Q")
7984 (match_operand 1 "ext_register_operand" "Q")
7988 "ix86_match_ccmode (insn, CCNOmode)"
7989 "test{b}\t{%h1, %h0|%h0, %h1}"
7990 [(set_attr "type" "test")
7991 (set_attr "mode" "QI")])
7993 ;; Combine likes to form bit extractions for some tests. Humor it.
7994 (define_insn "*testqi_ext_3"
7995 [(set (reg FLAGS_REG)
7996 (compare (zero_extract:SI
7997 (match_operand 0 "nonimmediate_operand" "rm")
7998 (match_operand:SI 1 "const_int_operand" "")
7999 (match_operand:SI 2 "const_int_operand" ""))
8001 "ix86_match_ccmode (insn, CCNOmode)
8002 && INTVAL (operands[1]) > 0
8003 && INTVAL (operands[2]) >= 0
8004 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8005 && (GET_MODE (operands[0]) == SImode
8006 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8007 || GET_MODE (operands[0]) == HImode
8008 || GET_MODE (operands[0]) == QImode)"
8011 (define_insn "*testqi_ext_3_rex64"
8012 [(set (reg FLAGS_REG)
8013 (compare (zero_extract:DI
8014 (match_operand 0 "nonimmediate_operand" "rm")
8015 (match_operand:DI 1 "const_int_operand" "")
8016 (match_operand:DI 2 "const_int_operand" ""))
8019 && ix86_match_ccmode (insn, CCNOmode)
8020 && INTVAL (operands[1]) > 0
8021 && INTVAL (operands[2]) >= 0
8022 /* Ensure that resulting mask is zero or sign extended operand. */
8023 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8024 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8025 && INTVAL (operands[1]) > 32))
8026 && (GET_MODE (operands[0]) == SImode
8027 || GET_MODE (operands[0]) == DImode
8028 || GET_MODE (operands[0]) == HImode
8029 || GET_MODE (operands[0]) == QImode)"
8033 [(set (match_operand 0 "flags_reg_operand" "")
8034 (match_operator 1 "compare_operator"
8036 (match_operand 2 "nonimmediate_operand" "")
8037 (match_operand 3 "const_int_operand" "")
8038 (match_operand 4 "const_int_operand" ""))
8040 "ix86_match_ccmode (insn, CCNOmode)"
8041 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8043 rtx val = operands[2];
8044 HOST_WIDE_INT len = INTVAL (operands[3]);
8045 HOST_WIDE_INT pos = INTVAL (operands[4]);
8047 enum machine_mode mode, submode;
8049 mode = GET_MODE (val);
8050 if (GET_CODE (val) == MEM)
8052 /* ??? Combine likes to put non-volatile mem extractions in QImode
8053 no matter the size of the test. So find a mode that works. */
8054 if (! MEM_VOLATILE_P (val))
8056 mode = smallest_mode_for_size (pos + len, MODE_INT);
8057 val = adjust_address (val, mode, 0);
8060 else if (GET_CODE (val) == SUBREG
8061 && (submode = GET_MODE (SUBREG_REG (val)),
8062 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8063 && pos + len <= GET_MODE_BITSIZE (submode))
8065 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8067 val = SUBREG_REG (val);
8069 else if (mode == HImode && pos + len <= 8)
8071 /* Small HImode tests can be converted to QImode. */
8073 val = gen_lowpart (QImode, val);
8076 if (len == HOST_BITS_PER_WIDE_INT)
8079 mask = ((HOST_WIDE_INT)1 << len) - 1;
8082 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8085 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8086 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8087 ;; this is relatively important trick.
8088 ;; Do the conversion only post-reload to avoid limiting of the register class
8091 [(set (match_operand 0 "flags_reg_operand" "")
8092 (match_operator 1 "compare_operator"
8093 [(and (match_operand 2 "register_operand" "")
8094 (match_operand 3 "const_int_operand" ""))
8097 && QI_REG_P (operands[2])
8098 && GET_MODE (operands[2]) != QImode
8099 && ((ix86_match_ccmode (insn, CCZmode)
8100 && !(INTVAL (operands[3]) & ~(255 << 8)))
8101 || (ix86_match_ccmode (insn, CCNOmode)
8102 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8105 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8108 "operands[2] = gen_lowpart (SImode, operands[2]);
8109 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8112 [(set (match_operand 0 "flags_reg_operand" "")
8113 (match_operator 1 "compare_operator"
8114 [(and (match_operand 2 "nonimmediate_operand" "")
8115 (match_operand 3 "const_int_operand" ""))
8118 && GET_MODE (operands[2]) != QImode
8119 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8120 && ((ix86_match_ccmode (insn, CCZmode)
8121 && !(INTVAL (operands[3]) & ~255))
8122 || (ix86_match_ccmode (insn, CCNOmode)
8123 && !(INTVAL (operands[3]) & ~127)))"
8125 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8127 "operands[2] = gen_lowpart (QImode, operands[2]);
8128 operands[3] = gen_lowpart (QImode, operands[3]);")
8131 ;; %%% This used to optimize known byte-wide and operations to memory,
8132 ;; and sometimes to QImode registers. If this is considered useful,
8133 ;; it should be done with splitters.
8135 (define_expand "anddi3"
8136 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8137 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8138 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8139 (clobber (reg:CC FLAGS_REG))]
8141 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8143 (define_insn "*anddi_1_rex64"
8144 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8145 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8146 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8147 (clobber (reg:CC FLAGS_REG))]
8148 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8150 switch (get_attr_type (insn))
8154 enum machine_mode mode;
8156 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8157 if (INTVAL (operands[2]) == 0xff)
8161 gcc_assert (INTVAL (operands[2]) == 0xffff);
8165 operands[1] = gen_lowpart (mode, operands[1]);
8167 return "movz{bq|x}\t{%1,%0|%0, %1}";
8169 return "movz{wq|x}\t{%1,%0|%0, %1}";
8173 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8174 if (get_attr_mode (insn) == MODE_SI)
8175 return "and{l}\t{%k2, %k0|%k0, %k2}";
8177 return "and{q}\t{%2, %0|%0, %2}";
8180 [(set_attr "type" "alu,alu,alu,imovx")
8181 (set_attr "length_immediate" "*,*,*,0")
8182 (set_attr "mode" "SI,DI,DI,DI")])
8184 (define_insn "*anddi_2"
8185 [(set (reg FLAGS_REG)
8186 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8187 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8189 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8190 (and:DI (match_dup 1) (match_dup 2)))]
8191 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8192 && ix86_binary_operator_ok (AND, DImode, operands)"
8194 and{l}\t{%k2, %k0|%k0, %k2}
8195 and{q}\t{%2, %0|%0, %2}
8196 and{q}\t{%2, %0|%0, %2}"
8197 [(set_attr "type" "alu")
8198 (set_attr "mode" "SI,DI,DI")])
8200 (define_expand "andsi3"
8201 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8202 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8203 (match_operand:SI 2 "general_operand" "")))
8204 (clobber (reg:CC FLAGS_REG))]
8206 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8208 (define_insn "*andsi_1"
8209 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8210 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8211 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8212 (clobber (reg:CC FLAGS_REG))]
8213 "ix86_binary_operator_ok (AND, SImode, operands)"
8215 switch (get_attr_type (insn))
8219 enum machine_mode mode;
8221 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8222 if (INTVAL (operands[2]) == 0xff)
8226 gcc_assert (INTVAL (operands[2]) == 0xffff);
8230 operands[1] = gen_lowpart (mode, operands[1]);
8232 return "movz{bl|x}\t{%1,%0|%0, %1}";
8234 return "movz{wl|x}\t{%1,%0|%0, %1}";
8238 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8239 return "and{l}\t{%2, %0|%0, %2}";
8242 [(set_attr "type" "alu,alu,imovx")
8243 (set_attr "length_immediate" "*,*,0")
8244 (set_attr "mode" "SI")])
8247 [(set (match_operand 0 "register_operand" "")
8249 (const_int -65536)))
8250 (clobber (reg:CC FLAGS_REG))]
8251 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8252 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8253 "operands[1] = gen_lowpart (HImode, operands[0]);")
8256 [(set (match_operand 0 "ext_register_operand" "")
8259 (clobber (reg:CC FLAGS_REG))]
8260 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8261 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8262 "operands[1] = gen_lowpart (QImode, operands[0]);")
8265 [(set (match_operand 0 "ext_register_operand" "")
8267 (const_int -65281)))
8268 (clobber (reg:CC FLAGS_REG))]
8269 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8270 [(parallel [(set (zero_extract:SI (match_dup 0)
8274 (zero_extract:SI (match_dup 0)
8277 (zero_extract:SI (match_dup 0)
8280 (clobber (reg:CC FLAGS_REG))])]
8281 "operands[0] = gen_lowpart (SImode, operands[0]);")
8283 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8284 (define_insn "*andsi_1_zext"
8285 [(set (match_operand:DI 0 "register_operand" "=r")
8287 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8288 (match_operand:SI 2 "general_operand" "rim"))))
8289 (clobber (reg:CC FLAGS_REG))]
8290 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8291 "and{l}\t{%2, %k0|%k0, %2}"
8292 [(set_attr "type" "alu")
8293 (set_attr "mode" "SI")])
8295 (define_insn "*andsi_2"
8296 [(set (reg FLAGS_REG)
8297 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8298 (match_operand:SI 2 "general_operand" "rim,ri"))
8300 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8301 (and:SI (match_dup 1) (match_dup 2)))]
8302 "ix86_match_ccmode (insn, CCNOmode)
8303 && ix86_binary_operator_ok (AND, SImode, operands)"
8304 "and{l}\t{%2, %0|%0, %2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "mode" "SI")])
8308 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8309 (define_insn "*andsi_2_zext"
8310 [(set (reg FLAGS_REG)
8311 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8312 (match_operand:SI 2 "general_operand" "rim"))
8314 (set (match_operand:DI 0 "register_operand" "=r")
8315 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8316 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8317 && ix86_binary_operator_ok (AND, SImode, operands)"
8318 "and{l}\t{%2, %k0|%k0, %2}"
8319 [(set_attr "type" "alu")
8320 (set_attr "mode" "SI")])
8322 (define_expand "andhi3"
8323 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8324 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8325 (match_operand:HI 2 "general_operand" "")))
8326 (clobber (reg:CC FLAGS_REG))]
8327 "TARGET_HIMODE_MATH"
8328 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8330 (define_insn "*andhi_1"
8331 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8332 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8333 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8334 (clobber (reg:CC FLAGS_REG))]
8335 "ix86_binary_operator_ok (AND, HImode, operands)"
8337 switch (get_attr_type (insn))
8340 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8341 gcc_assert (INTVAL (operands[2]) == 0xff);
8342 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8345 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8347 return "and{w}\t{%2, %0|%0, %2}";
8350 [(set_attr "type" "alu,alu,imovx")
8351 (set_attr "length_immediate" "*,*,0")
8352 (set_attr "mode" "HI,HI,SI")])
8354 (define_insn "*andhi_2"
8355 [(set (reg FLAGS_REG)
8356 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8357 (match_operand:HI 2 "general_operand" "rim,ri"))
8359 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8360 (and:HI (match_dup 1) (match_dup 2)))]
8361 "ix86_match_ccmode (insn, CCNOmode)
8362 && ix86_binary_operator_ok (AND, HImode, operands)"
8363 "and{w}\t{%2, %0|%0, %2}"
8364 [(set_attr "type" "alu")
8365 (set_attr "mode" "HI")])
8367 (define_expand "andqi3"
8368 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8369 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8370 (match_operand:QI 2 "general_operand" "")))
8371 (clobber (reg:CC FLAGS_REG))]
8372 "TARGET_QIMODE_MATH"
8373 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8375 ;; %%% Potential partial reg stall on alternative 2. What to do?
8376 (define_insn "*andqi_1"
8377 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8378 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8379 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8380 (clobber (reg:CC FLAGS_REG))]
8381 "ix86_binary_operator_ok (AND, QImode, operands)"
8383 and{b}\t{%2, %0|%0, %2}
8384 and{b}\t{%2, %0|%0, %2}
8385 and{l}\t{%k2, %k0|%k0, %k2}"
8386 [(set_attr "type" "alu")
8387 (set_attr "mode" "QI,QI,SI")])
8389 (define_insn "*andqi_1_slp"
8390 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8391 (and:QI (match_dup 0)
8392 (match_operand:QI 1 "general_operand" "qi,qmi")))
8393 (clobber (reg:CC FLAGS_REG))]
8394 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8395 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8396 "and{b}\t{%1, %0|%0, %1}"
8397 [(set_attr "type" "alu1")
8398 (set_attr "mode" "QI")])
8400 (define_insn "*andqi_2_maybe_si"
8401 [(set (reg FLAGS_REG)
8403 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8404 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8406 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8407 (and:QI (match_dup 1) (match_dup 2)))]
8408 "ix86_binary_operator_ok (AND, QImode, operands)
8409 && ix86_match_ccmode (insn,
8410 GET_CODE (operands[2]) == CONST_INT
8411 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8413 if (which_alternative == 2)
8415 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8416 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8417 return "and{l}\t{%2, %k0|%k0, %2}";
8419 return "and{b}\t{%2, %0|%0, %2}";
8421 [(set_attr "type" "alu")
8422 (set_attr "mode" "QI,QI,SI")])
8424 (define_insn "*andqi_2"
8425 [(set (reg FLAGS_REG)
8427 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8428 (match_operand:QI 2 "general_operand" "qim,qi"))
8430 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8431 (and:QI (match_dup 1) (match_dup 2)))]
8432 "ix86_match_ccmode (insn, CCNOmode)
8433 && ix86_binary_operator_ok (AND, QImode, operands)"
8434 "and{b}\t{%2, %0|%0, %2}"
8435 [(set_attr "type" "alu")
8436 (set_attr "mode" "QI")])
8438 (define_insn "*andqi_2_slp"
8439 [(set (reg FLAGS_REG)
8441 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8442 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8444 (set (strict_low_part (match_dup 0))
8445 (and:QI (match_dup 0) (match_dup 1)))]
8446 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8447 && ix86_match_ccmode (insn, CCNOmode)
8448 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8449 "and{b}\t{%1, %0|%0, %1}"
8450 [(set_attr "type" "alu1")
8451 (set_attr "mode" "QI")])
8453 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8454 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8455 ;; for a QImode operand, which of course failed.
8457 (define_insn "andqi_ext_0"
8458 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8463 (match_operand 1 "ext_register_operand" "0")
8466 (match_operand 2 "const_int_operand" "n")))
8467 (clobber (reg:CC FLAGS_REG))]
8469 "and{b}\t{%2, %h0|%h0, %2}"
8470 [(set_attr "type" "alu")
8471 (set_attr "length_immediate" "1")
8472 (set_attr "mode" "QI")])
8474 ;; Generated by peephole translating test to and. This shows up
8475 ;; often in fp comparisons.
8477 (define_insn "*andqi_ext_0_cc"
8478 [(set (reg FLAGS_REG)
8482 (match_operand 1 "ext_register_operand" "0")
8485 (match_operand 2 "const_int_operand" "n"))
8487 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8496 "ix86_match_ccmode (insn, CCNOmode)"
8497 "and{b}\t{%2, %h0|%h0, %2}"
8498 [(set_attr "type" "alu")
8499 (set_attr "length_immediate" "1")
8500 (set_attr "mode" "QI")])
8502 (define_insn "*andqi_ext_1"
8503 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8508 (match_operand 1 "ext_register_operand" "0")
8512 (match_operand:QI 2 "general_operand" "Qm"))))
8513 (clobber (reg:CC FLAGS_REG))]
8515 "and{b}\t{%2, %h0|%h0, %2}"
8516 [(set_attr "type" "alu")
8517 (set_attr "length_immediate" "0")
8518 (set_attr "mode" "QI")])
8520 (define_insn "*andqi_ext_1_rex64"
8521 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8526 (match_operand 1 "ext_register_operand" "0")
8530 (match_operand 2 "ext_register_operand" "Q"))))
8531 (clobber (reg:CC FLAGS_REG))]
8533 "and{b}\t{%2, %h0|%h0, %2}"
8534 [(set_attr "type" "alu")
8535 (set_attr "length_immediate" "0")
8536 (set_attr "mode" "QI")])
8538 (define_insn "*andqi_ext_2"
8539 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8544 (match_operand 1 "ext_register_operand" "%0")
8548 (match_operand 2 "ext_register_operand" "Q")
8551 (clobber (reg:CC FLAGS_REG))]
8553 "and{b}\t{%h2, %h0|%h0, %h2}"
8554 [(set_attr "type" "alu")
8555 (set_attr "length_immediate" "0")
8556 (set_attr "mode" "QI")])
8558 ;; Convert wide AND instructions with immediate operand to shorter QImode
8559 ;; equivalents when possible.
8560 ;; Don't do the splitting with memory operands, since it introduces risk
8561 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8562 ;; for size, but that can (should?) be handled by generic code instead.
8564 [(set (match_operand 0 "register_operand" "")
8565 (and (match_operand 1 "register_operand" "")
8566 (match_operand 2 "const_int_operand" "")))
8567 (clobber (reg:CC FLAGS_REG))]
8569 && QI_REG_P (operands[0])
8570 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8571 && !(~INTVAL (operands[2]) & ~(255 << 8))
8572 && GET_MODE (operands[0]) != QImode"
8573 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8574 (and:SI (zero_extract:SI (match_dup 1)
8575 (const_int 8) (const_int 8))
8577 (clobber (reg:CC FLAGS_REG))])]
8578 "operands[0] = gen_lowpart (SImode, operands[0]);
8579 operands[1] = gen_lowpart (SImode, operands[1]);
8580 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8582 ;; Since AND can be encoded with sign extended immediate, this is only
8583 ;; profitable when 7th bit is not set.
8585 [(set (match_operand 0 "register_operand" "")
8586 (and (match_operand 1 "general_operand" "")
8587 (match_operand 2 "const_int_operand" "")))
8588 (clobber (reg:CC FLAGS_REG))]
8590 && ANY_QI_REG_P (operands[0])
8591 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8592 && !(~INTVAL (operands[2]) & ~255)
8593 && !(INTVAL (operands[2]) & 128)
8594 && GET_MODE (operands[0]) != QImode"
8595 [(parallel [(set (strict_low_part (match_dup 0))
8596 (and:QI (match_dup 1)
8598 (clobber (reg:CC FLAGS_REG))])]
8599 "operands[0] = gen_lowpart (QImode, operands[0]);
8600 operands[1] = gen_lowpart (QImode, operands[1]);
8601 operands[2] = gen_lowpart (QImode, operands[2]);")
8603 ;; Logical inclusive OR instructions
8605 ;; %%% This used to optimize known byte-wide and operations to memory.
8606 ;; If this is considered useful, it should be done with splitters.
8608 (define_expand "iordi3"
8609 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8610 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8611 (match_operand:DI 2 "x86_64_general_operand" "")))
8612 (clobber (reg:CC FLAGS_REG))]
8614 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8616 (define_insn "*iordi_1_rex64"
8617 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8618 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8619 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8620 (clobber (reg:CC FLAGS_REG))]
8622 && ix86_binary_operator_ok (IOR, DImode, operands)"
8623 "or{q}\t{%2, %0|%0, %2}"
8624 [(set_attr "type" "alu")
8625 (set_attr "mode" "DI")])
8627 (define_insn "*iordi_2_rex64"
8628 [(set (reg FLAGS_REG)
8629 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8630 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8632 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8633 (ior:DI (match_dup 1) (match_dup 2)))]
8635 && ix86_match_ccmode (insn, CCNOmode)
8636 && ix86_binary_operator_ok (IOR, DImode, operands)"
8637 "or{q}\t{%2, %0|%0, %2}"
8638 [(set_attr "type" "alu")
8639 (set_attr "mode" "DI")])
8641 (define_insn "*iordi_3_rex64"
8642 [(set (reg FLAGS_REG)
8643 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8644 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8646 (clobber (match_scratch:DI 0 "=r"))]
8648 && ix86_match_ccmode (insn, CCNOmode)
8649 && ix86_binary_operator_ok (IOR, DImode, operands)"
8650 "or{q}\t{%2, %0|%0, %2}"
8651 [(set_attr "type" "alu")
8652 (set_attr "mode" "DI")])
8655 (define_expand "iorsi3"
8656 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8657 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8658 (match_operand:SI 2 "general_operand" "")))
8659 (clobber (reg:CC FLAGS_REG))]
8661 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8663 (define_insn "*iorsi_1"
8664 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8665 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8666 (match_operand:SI 2 "general_operand" "ri,rmi")))
8667 (clobber (reg:CC FLAGS_REG))]
8668 "ix86_binary_operator_ok (IOR, SImode, operands)"
8669 "or{l}\t{%2, %0|%0, %2}"
8670 [(set_attr "type" "alu")
8671 (set_attr "mode" "SI")])
8673 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8674 (define_insn "*iorsi_1_zext"
8675 [(set (match_operand:DI 0 "register_operand" "=rm")
8677 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8678 (match_operand:SI 2 "general_operand" "rim"))))
8679 (clobber (reg:CC FLAGS_REG))]
8680 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8681 "or{l}\t{%2, %k0|%k0, %2}"
8682 [(set_attr "type" "alu")
8683 (set_attr "mode" "SI")])
8685 (define_insn "*iorsi_1_zext_imm"
8686 [(set (match_operand:DI 0 "register_operand" "=rm")
8687 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8688 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8689 (clobber (reg:CC FLAGS_REG))]
8691 "or{l}\t{%2, %k0|%k0, %2}"
8692 [(set_attr "type" "alu")
8693 (set_attr "mode" "SI")])
8695 (define_insn "*iorsi_2"
8696 [(set (reg FLAGS_REG)
8697 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8698 (match_operand:SI 2 "general_operand" "rim,ri"))
8700 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8701 (ior:SI (match_dup 1) (match_dup 2)))]
8702 "ix86_match_ccmode (insn, CCNOmode)
8703 && ix86_binary_operator_ok (IOR, SImode, operands)"
8704 "or{l}\t{%2, %0|%0, %2}"
8705 [(set_attr "type" "alu")
8706 (set_attr "mode" "SI")])
8708 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8709 ;; ??? Special case for immediate operand is missing - it is tricky.
8710 (define_insn "*iorsi_2_zext"
8711 [(set (reg FLAGS_REG)
8712 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8713 (match_operand:SI 2 "general_operand" "rim"))
8715 (set (match_operand:DI 0 "register_operand" "=r")
8716 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8717 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8718 && ix86_binary_operator_ok (IOR, SImode, operands)"
8719 "or{l}\t{%2, %k0|%k0, %2}"
8720 [(set_attr "type" "alu")
8721 (set_attr "mode" "SI")])
8723 (define_insn "*iorsi_2_zext_imm"
8724 [(set (reg FLAGS_REG)
8725 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8726 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8728 (set (match_operand:DI 0 "register_operand" "=r")
8729 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8730 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8731 && ix86_binary_operator_ok (IOR, SImode, operands)"
8732 "or{l}\t{%2, %k0|%k0, %2}"
8733 [(set_attr "type" "alu")
8734 (set_attr "mode" "SI")])
8736 (define_insn "*iorsi_3"
8737 [(set (reg FLAGS_REG)
8738 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8739 (match_operand:SI 2 "general_operand" "rim"))
8741 (clobber (match_scratch:SI 0 "=r"))]
8742 "ix86_match_ccmode (insn, CCNOmode)
8743 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8744 "or{l}\t{%2, %0|%0, %2}"
8745 [(set_attr "type" "alu")
8746 (set_attr "mode" "SI")])
8748 (define_expand "iorhi3"
8749 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8750 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8751 (match_operand:HI 2 "general_operand" "")))
8752 (clobber (reg:CC FLAGS_REG))]
8753 "TARGET_HIMODE_MATH"
8754 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8756 (define_insn "*iorhi_1"
8757 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8758 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8759 (match_operand:HI 2 "general_operand" "rmi,ri")))
8760 (clobber (reg:CC FLAGS_REG))]
8761 "ix86_binary_operator_ok (IOR, HImode, operands)"
8762 "or{w}\t{%2, %0|%0, %2}"
8763 [(set_attr "type" "alu")
8764 (set_attr "mode" "HI")])
8766 (define_insn "*iorhi_2"
8767 [(set (reg FLAGS_REG)
8768 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8769 (match_operand:HI 2 "general_operand" "rim,ri"))
8771 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8772 (ior:HI (match_dup 1) (match_dup 2)))]
8773 "ix86_match_ccmode (insn, CCNOmode)
8774 && ix86_binary_operator_ok (IOR, HImode, operands)"
8775 "or{w}\t{%2, %0|%0, %2}"
8776 [(set_attr "type" "alu")
8777 (set_attr "mode" "HI")])
8779 (define_insn "*iorhi_3"
8780 [(set (reg FLAGS_REG)
8781 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8782 (match_operand:HI 2 "general_operand" "rim"))
8784 (clobber (match_scratch:HI 0 "=r"))]
8785 "ix86_match_ccmode (insn, CCNOmode)
8786 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8787 "or{w}\t{%2, %0|%0, %2}"
8788 [(set_attr "type" "alu")
8789 (set_attr "mode" "HI")])
8791 (define_expand "iorqi3"
8792 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8793 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8794 (match_operand:QI 2 "general_operand" "")))
8795 (clobber (reg:CC FLAGS_REG))]
8796 "TARGET_QIMODE_MATH"
8797 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8799 ;; %%% Potential partial reg stall on alternative 2. What to do?
8800 (define_insn "*iorqi_1"
8801 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8802 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8803 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8804 (clobber (reg:CC FLAGS_REG))]
8805 "ix86_binary_operator_ok (IOR, QImode, operands)"
8807 or{b}\t{%2, %0|%0, %2}
8808 or{b}\t{%2, %0|%0, %2}
8809 or{l}\t{%k2, %k0|%k0, %k2}"
8810 [(set_attr "type" "alu")
8811 (set_attr "mode" "QI,QI,SI")])
8813 (define_insn "*iorqi_1_slp"
8814 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8815 (ior:QI (match_dup 0)
8816 (match_operand:QI 1 "general_operand" "qmi,qi")))
8817 (clobber (reg:CC FLAGS_REG))]
8818 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8819 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8820 "or{b}\t{%1, %0|%0, %1}"
8821 [(set_attr "type" "alu1")
8822 (set_attr "mode" "QI")])
8824 (define_insn "*iorqi_2"
8825 [(set (reg FLAGS_REG)
8826 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8827 (match_operand:QI 2 "general_operand" "qim,qi"))
8829 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8830 (ior:QI (match_dup 1) (match_dup 2)))]
8831 "ix86_match_ccmode (insn, CCNOmode)
8832 && ix86_binary_operator_ok (IOR, QImode, operands)"
8833 "or{b}\t{%2, %0|%0, %2}"
8834 [(set_attr "type" "alu")
8835 (set_attr "mode" "QI")])
8837 (define_insn "*iorqi_2_slp"
8838 [(set (reg FLAGS_REG)
8839 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8840 (match_operand:QI 1 "general_operand" "qim,qi"))
8842 (set (strict_low_part (match_dup 0))
8843 (ior:QI (match_dup 0) (match_dup 1)))]
8844 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8845 && ix86_match_ccmode (insn, CCNOmode)
8846 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8847 "or{b}\t{%1, %0|%0, %1}"
8848 [(set_attr "type" "alu1")
8849 (set_attr "mode" "QI")])
8851 (define_insn "*iorqi_3"
8852 [(set (reg FLAGS_REG)
8853 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8854 (match_operand:QI 2 "general_operand" "qim"))
8856 (clobber (match_scratch:QI 0 "=q"))]
8857 "ix86_match_ccmode (insn, CCNOmode)
8858 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8859 "or{b}\t{%2, %0|%0, %2}"
8860 [(set_attr "type" "alu")
8861 (set_attr "mode" "QI")])
8863 (define_insn "iorqi_ext_0"
8864 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8869 (match_operand 1 "ext_register_operand" "0")
8872 (match_operand 2 "const_int_operand" "n")))
8873 (clobber (reg:CC FLAGS_REG))]
8874 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8875 "or{b}\t{%2, %h0|%h0, %2}"
8876 [(set_attr "type" "alu")
8877 (set_attr "length_immediate" "1")
8878 (set_attr "mode" "QI")])
8880 (define_insn "*iorqi_ext_1"
8881 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8886 (match_operand 1 "ext_register_operand" "0")
8890 (match_operand:QI 2 "general_operand" "Qm"))))
8891 (clobber (reg:CC FLAGS_REG))]
8893 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8894 "or{b}\t{%2, %h0|%h0, %2}"
8895 [(set_attr "type" "alu")
8896 (set_attr "length_immediate" "0")
8897 (set_attr "mode" "QI")])
8899 (define_insn "*iorqi_ext_1_rex64"
8900 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8905 (match_operand 1 "ext_register_operand" "0")
8909 (match_operand 2 "ext_register_operand" "Q"))))
8910 (clobber (reg:CC FLAGS_REG))]
8912 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8913 "or{b}\t{%2, %h0|%h0, %2}"
8914 [(set_attr "type" "alu")
8915 (set_attr "length_immediate" "0")
8916 (set_attr "mode" "QI")])
8918 (define_insn "*iorqi_ext_2"
8919 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8923 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8926 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8929 (clobber (reg:CC FLAGS_REG))]
8930 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8931 "ior{b}\t{%h2, %h0|%h0, %h2}"
8932 [(set_attr "type" "alu")
8933 (set_attr "length_immediate" "0")
8934 (set_attr "mode" "QI")])
8937 [(set (match_operand 0 "register_operand" "")
8938 (ior (match_operand 1 "register_operand" "")
8939 (match_operand 2 "const_int_operand" "")))
8940 (clobber (reg:CC FLAGS_REG))]
8942 && QI_REG_P (operands[0])
8943 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8944 && !(INTVAL (operands[2]) & ~(255 << 8))
8945 && GET_MODE (operands[0]) != QImode"
8946 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8947 (ior:SI (zero_extract:SI (match_dup 1)
8948 (const_int 8) (const_int 8))
8950 (clobber (reg:CC FLAGS_REG))])]
8951 "operands[0] = gen_lowpart (SImode, operands[0]);
8952 operands[1] = gen_lowpart (SImode, operands[1]);
8953 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8955 ;; Since OR can be encoded with sign extended immediate, this is only
8956 ;; profitable when 7th bit is set.
8958 [(set (match_operand 0 "register_operand" "")
8959 (ior (match_operand 1 "general_operand" "")
8960 (match_operand 2 "const_int_operand" "")))
8961 (clobber (reg:CC FLAGS_REG))]
8963 && ANY_QI_REG_P (operands[0])
8964 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8965 && !(INTVAL (operands[2]) & ~255)
8966 && (INTVAL (operands[2]) & 128)
8967 && GET_MODE (operands[0]) != QImode"
8968 [(parallel [(set (strict_low_part (match_dup 0))
8969 (ior:QI (match_dup 1)
8971 (clobber (reg:CC FLAGS_REG))])]
8972 "operands[0] = gen_lowpart (QImode, operands[0]);
8973 operands[1] = gen_lowpart (QImode, operands[1]);
8974 operands[2] = gen_lowpart (QImode, operands[2]);")
8976 ;; Logical XOR instructions
8978 ;; %%% This used to optimize known byte-wide and operations to memory.
8979 ;; If this is considered useful, it should be done with splitters.
8981 (define_expand "xordi3"
8982 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8983 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8984 (match_operand:DI 2 "x86_64_general_operand" "")))
8985 (clobber (reg:CC FLAGS_REG))]
8987 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8989 (define_insn "*xordi_1_rex64"
8990 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8991 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8992 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8993 (clobber (reg:CC FLAGS_REG))]
8995 && ix86_binary_operator_ok (XOR, DImode, operands)"
8997 xor{q}\t{%2, %0|%0, %2}
8998 xor{q}\t{%2, %0|%0, %2}"
8999 [(set_attr "type" "alu")
9000 (set_attr "mode" "DI,DI")])
9002 (define_insn "*xordi_2_rex64"
9003 [(set (reg FLAGS_REG)
9004 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9005 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9007 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9008 (xor:DI (match_dup 1) (match_dup 2)))]
9010 && ix86_match_ccmode (insn, CCNOmode)
9011 && ix86_binary_operator_ok (XOR, DImode, operands)"
9013 xor{q}\t{%2, %0|%0, %2}
9014 xor{q}\t{%2, %0|%0, %2}"
9015 [(set_attr "type" "alu")
9016 (set_attr "mode" "DI,DI")])
9018 (define_insn "*xordi_3_rex64"
9019 [(set (reg FLAGS_REG)
9020 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9021 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9023 (clobber (match_scratch:DI 0 "=r"))]
9025 && ix86_match_ccmode (insn, CCNOmode)
9026 && ix86_binary_operator_ok (XOR, DImode, operands)"
9027 "xor{q}\t{%2, %0|%0, %2}"
9028 [(set_attr "type" "alu")
9029 (set_attr "mode" "DI")])
9031 (define_expand "xorsi3"
9032 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9033 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9034 (match_operand:SI 2 "general_operand" "")))
9035 (clobber (reg:CC FLAGS_REG))]
9037 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9039 (define_insn "*xorsi_1"
9040 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9041 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9042 (match_operand:SI 2 "general_operand" "ri,rm")))
9043 (clobber (reg:CC FLAGS_REG))]
9044 "ix86_binary_operator_ok (XOR, SImode, operands)"
9045 "xor{l}\t{%2, %0|%0, %2}"
9046 [(set_attr "type" "alu")
9047 (set_attr "mode" "SI")])
9049 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9050 ;; Add speccase for immediates
9051 (define_insn "*xorsi_1_zext"
9052 [(set (match_operand:DI 0 "register_operand" "=r")
9054 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9055 (match_operand:SI 2 "general_operand" "rim"))))
9056 (clobber (reg:CC FLAGS_REG))]
9057 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9058 "xor{l}\t{%2, %k0|%k0, %2}"
9059 [(set_attr "type" "alu")
9060 (set_attr "mode" "SI")])
9062 (define_insn "*xorsi_1_zext_imm"
9063 [(set (match_operand:DI 0 "register_operand" "=r")
9064 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9065 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9066 (clobber (reg:CC FLAGS_REG))]
9067 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9068 "xor{l}\t{%2, %k0|%k0, %2}"
9069 [(set_attr "type" "alu")
9070 (set_attr "mode" "SI")])
9072 (define_insn "*xorsi_2"
9073 [(set (reg FLAGS_REG)
9074 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9075 (match_operand:SI 2 "general_operand" "rim,ri"))
9077 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9078 (xor:SI (match_dup 1) (match_dup 2)))]
9079 "ix86_match_ccmode (insn, CCNOmode)
9080 && ix86_binary_operator_ok (XOR, SImode, operands)"
9081 "xor{l}\t{%2, %0|%0, %2}"
9082 [(set_attr "type" "alu")
9083 (set_attr "mode" "SI")])
9085 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9086 ;; ??? Special case for immediate operand is missing - it is tricky.
9087 (define_insn "*xorsi_2_zext"
9088 [(set (reg FLAGS_REG)
9089 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9090 (match_operand:SI 2 "general_operand" "rim"))
9092 (set (match_operand:DI 0 "register_operand" "=r")
9093 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9094 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9095 && ix86_binary_operator_ok (XOR, SImode, operands)"
9096 "xor{l}\t{%2, %k0|%k0, %2}"
9097 [(set_attr "type" "alu")
9098 (set_attr "mode" "SI")])
9100 (define_insn "*xorsi_2_zext_imm"
9101 [(set (reg FLAGS_REG)
9102 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9103 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9105 (set (match_operand:DI 0 "register_operand" "=r")
9106 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9107 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9108 && ix86_binary_operator_ok (XOR, SImode, operands)"
9109 "xor{l}\t{%2, %k0|%k0, %2}"
9110 [(set_attr "type" "alu")
9111 (set_attr "mode" "SI")])
9113 (define_insn "*xorsi_3"
9114 [(set (reg FLAGS_REG)
9115 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9116 (match_operand:SI 2 "general_operand" "rim"))
9118 (clobber (match_scratch:SI 0 "=r"))]
9119 "ix86_match_ccmode (insn, CCNOmode)
9120 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9121 "xor{l}\t{%2, %0|%0, %2}"
9122 [(set_attr "type" "alu")
9123 (set_attr "mode" "SI")])
9125 (define_expand "xorhi3"
9126 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9127 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9128 (match_operand:HI 2 "general_operand" "")))
9129 (clobber (reg:CC FLAGS_REG))]
9130 "TARGET_HIMODE_MATH"
9131 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9133 (define_insn "*xorhi_1"
9134 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9135 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9136 (match_operand:HI 2 "general_operand" "rmi,ri")))
9137 (clobber (reg:CC FLAGS_REG))]
9138 "ix86_binary_operator_ok (XOR, HImode, operands)"
9139 "xor{w}\t{%2, %0|%0, %2}"
9140 [(set_attr "type" "alu")
9141 (set_attr "mode" "HI")])
9143 (define_insn "*xorhi_2"
9144 [(set (reg FLAGS_REG)
9145 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9146 (match_operand:HI 2 "general_operand" "rim,ri"))
9148 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9149 (xor:HI (match_dup 1) (match_dup 2)))]
9150 "ix86_match_ccmode (insn, CCNOmode)
9151 && ix86_binary_operator_ok (XOR, HImode, operands)"
9152 "xor{w}\t{%2, %0|%0, %2}"
9153 [(set_attr "type" "alu")
9154 (set_attr "mode" "HI")])
9156 (define_insn "*xorhi_3"
9157 [(set (reg FLAGS_REG)
9158 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9159 (match_operand:HI 2 "general_operand" "rim"))
9161 (clobber (match_scratch:HI 0 "=r"))]
9162 "ix86_match_ccmode (insn, CCNOmode)
9163 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9164 "xor{w}\t{%2, %0|%0, %2}"
9165 [(set_attr "type" "alu")
9166 (set_attr "mode" "HI")])
9168 (define_expand "xorqi3"
9169 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9170 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9171 (match_operand:QI 2 "general_operand" "")))
9172 (clobber (reg:CC FLAGS_REG))]
9173 "TARGET_QIMODE_MATH"
9174 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9176 ;; %%% Potential partial reg stall on alternative 2. What to do?
9177 (define_insn "*xorqi_1"
9178 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9179 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9180 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9181 (clobber (reg:CC FLAGS_REG))]
9182 "ix86_binary_operator_ok (XOR, QImode, operands)"
9184 xor{b}\t{%2, %0|%0, %2}
9185 xor{b}\t{%2, %0|%0, %2}
9186 xor{l}\t{%k2, %k0|%k0, %k2}"
9187 [(set_attr "type" "alu")
9188 (set_attr "mode" "QI,QI,SI")])
9190 (define_insn "*xorqi_1_slp"
9191 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9192 (xor:QI (match_dup 0)
9193 (match_operand:QI 1 "general_operand" "qi,qmi")))
9194 (clobber (reg:CC FLAGS_REG))]
9195 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9196 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9197 "xor{b}\t{%1, %0|%0, %1}"
9198 [(set_attr "type" "alu1")
9199 (set_attr "mode" "QI")])
9201 (define_insn "xorqi_ext_0"
9202 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9207 (match_operand 1 "ext_register_operand" "0")
9210 (match_operand 2 "const_int_operand" "n")))
9211 (clobber (reg:CC FLAGS_REG))]
9212 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9213 "xor{b}\t{%2, %h0|%h0, %2}"
9214 [(set_attr "type" "alu")
9215 (set_attr "length_immediate" "1")
9216 (set_attr "mode" "QI")])
9218 (define_insn "*xorqi_ext_1"
9219 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9224 (match_operand 1 "ext_register_operand" "0")
9228 (match_operand:QI 2 "general_operand" "Qm"))))
9229 (clobber (reg:CC FLAGS_REG))]
9231 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9232 "xor{b}\t{%2, %h0|%h0, %2}"
9233 [(set_attr "type" "alu")
9234 (set_attr "length_immediate" "0")
9235 (set_attr "mode" "QI")])
9237 (define_insn "*xorqi_ext_1_rex64"
9238 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9243 (match_operand 1 "ext_register_operand" "0")
9247 (match_operand 2 "ext_register_operand" "Q"))))
9248 (clobber (reg:CC FLAGS_REG))]
9250 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9251 "xor{b}\t{%2, %h0|%h0, %2}"
9252 [(set_attr "type" "alu")
9253 (set_attr "length_immediate" "0")
9254 (set_attr "mode" "QI")])
9256 (define_insn "*xorqi_ext_2"
9257 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9261 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9264 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9267 (clobber (reg:CC FLAGS_REG))]
9268 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9269 "xor{b}\t{%h2, %h0|%h0, %h2}"
9270 [(set_attr "type" "alu")
9271 (set_attr "length_immediate" "0")
9272 (set_attr "mode" "QI")])
9274 (define_insn "*xorqi_cc_1"
9275 [(set (reg FLAGS_REG)
9277 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9278 (match_operand:QI 2 "general_operand" "qim,qi"))
9280 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9281 (xor:QI (match_dup 1) (match_dup 2)))]
9282 "ix86_match_ccmode (insn, CCNOmode)
9283 && ix86_binary_operator_ok (XOR, QImode, operands)"
9284 "xor{b}\t{%2, %0|%0, %2}"
9285 [(set_attr "type" "alu")
9286 (set_attr "mode" "QI")])
9288 (define_insn "*xorqi_2_slp"
9289 [(set (reg FLAGS_REG)
9290 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9291 (match_operand:QI 1 "general_operand" "qim,qi"))
9293 (set (strict_low_part (match_dup 0))
9294 (xor:QI (match_dup 0) (match_dup 1)))]
9295 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9296 && ix86_match_ccmode (insn, CCNOmode)
9297 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9298 "xor{b}\t{%1, %0|%0, %1}"
9299 [(set_attr "type" "alu1")
9300 (set_attr "mode" "QI")])
9302 (define_insn "*xorqi_cc_2"
9303 [(set (reg FLAGS_REG)
9305 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9306 (match_operand:QI 2 "general_operand" "qim"))
9308 (clobber (match_scratch:QI 0 "=q"))]
9309 "ix86_match_ccmode (insn, CCNOmode)
9310 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9311 "xor{b}\t{%2, %0|%0, %2}"
9312 [(set_attr "type" "alu")
9313 (set_attr "mode" "QI")])
9315 (define_insn "*xorqi_cc_ext_1"
9316 [(set (reg FLAGS_REG)
9320 (match_operand 1 "ext_register_operand" "0")
9323 (match_operand:QI 2 "general_operand" "qmn"))
9325 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9329 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9331 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9332 "xor{b}\t{%2, %h0|%h0, %2}"
9333 [(set_attr "type" "alu")
9334 (set_attr "mode" "QI")])
9336 (define_insn "*xorqi_cc_ext_1_rex64"
9337 [(set (reg FLAGS_REG)
9341 (match_operand 1 "ext_register_operand" "0")
9344 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9346 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9350 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9352 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9353 "xor{b}\t{%2, %h0|%h0, %2}"
9354 [(set_attr "type" "alu")
9355 (set_attr "mode" "QI")])
9357 (define_expand "xorqi_cc_ext_1"
9359 (set (reg:CCNO FLAGS_REG)
9363 (match_operand 1 "ext_register_operand" "")
9366 (match_operand:QI 2 "general_operand" ""))
9368 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9372 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9378 [(set (match_operand 0 "register_operand" "")
9379 (xor (match_operand 1 "register_operand" "")
9380 (match_operand 2 "const_int_operand" "")))
9381 (clobber (reg:CC FLAGS_REG))]
9383 && QI_REG_P (operands[0])
9384 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9385 && !(INTVAL (operands[2]) & ~(255 << 8))
9386 && GET_MODE (operands[0]) != QImode"
9387 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9388 (xor:SI (zero_extract:SI (match_dup 1)
9389 (const_int 8) (const_int 8))
9391 (clobber (reg:CC FLAGS_REG))])]
9392 "operands[0] = gen_lowpart (SImode, operands[0]);
9393 operands[1] = gen_lowpart (SImode, operands[1]);
9394 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9396 ;; Since XOR can be encoded with sign extended immediate, this is only
9397 ;; profitable when 7th bit is set.
9399 [(set (match_operand 0 "register_operand" "")
9400 (xor (match_operand 1 "general_operand" "")
9401 (match_operand 2 "const_int_operand" "")))
9402 (clobber (reg:CC FLAGS_REG))]
9404 && ANY_QI_REG_P (operands[0])
9405 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9406 && !(INTVAL (operands[2]) & ~255)
9407 && (INTVAL (operands[2]) & 128)
9408 && GET_MODE (operands[0]) != QImode"
9409 [(parallel [(set (strict_low_part (match_dup 0))
9410 (xor:QI (match_dup 1)
9412 (clobber (reg:CC FLAGS_REG))])]
9413 "operands[0] = gen_lowpart (QImode, operands[0]);
9414 operands[1] = gen_lowpart (QImode, operands[1]);
9415 operands[2] = gen_lowpart (QImode, operands[2]);")
9417 ;; Negation instructions
9419 (define_expand "negti2"
9420 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9421 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9422 (clobber (reg:CC FLAGS_REG))])]
9424 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9426 (define_insn "*negti2_1"
9427 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9428 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9429 (clobber (reg:CC FLAGS_REG))]
9431 && ix86_unary_operator_ok (NEG, TImode, operands)"
9435 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9436 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9437 (clobber (reg:CC FLAGS_REG))]
9438 "TARGET_64BIT && reload_completed"
9440 [(set (reg:CCZ FLAGS_REG)
9441 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9442 (set (match_dup 0) (neg:DI (match_dup 2)))])
9445 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9448 (clobber (reg:CC FLAGS_REG))])
9451 (neg:DI (match_dup 1)))
9452 (clobber (reg:CC FLAGS_REG))])]
9453 "split_ti (operands+1, 1, operands+2, operands+3);
9454 split_ti (operands+0, 1, operands+0, operands+1);")
9456 (define_expand "negdi2"
9457 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9458 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9459 (clobber (reg:CC FLAGS_REG))])]
9461 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9463 (define_insn "*negdi2_1"
9464 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9465 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9466 (clobber (reg:CC FLAGS_REG))]
9468 && ix86_unary_operator_ok (NEG, DImode, operands)"
9472 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9473 (neg:DI (match_operand:DI 1 "general_operand" "")))
9474 (clobber (reg:CC FLAGS_REG))]
9475 "!TARGET_64BIT && reload_completed"
9477 [(set (reg:CCZ FLAGS_REG)
9478 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9479 (set (match_dup 0) (neg:SI (match_dup 2)))])
9482 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9485 (clobber (reg:CC FLAGS_REG))])
9488 (neg:SI (match_dup 1)))
9489 (clobber (reg:CC FLAGS_REG))])]
9490 "split_di (operands+1, 1, operands+2, operands+3);
9491 split_di (operands+0, 1, operands+0, operands+1);")
9493 (define_insn "*negdi2_1_rex64"
9494 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9495 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9496 (clobber (reg:CC FLAGS_REG))]
9497 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9499 [(set_attr "type" "negnot")
9500 (set_attr "mode" "DI")])
9502 ;; The problem with neg is that it does not perform (compare x 0),
9503 ;; it really performs (compare 0 x), which leaves us with the zero
9504 ;; flag being the only useful item.
9506 (define_insn "*negdi2_cmpz_rex64"
9507 [(set (reg:CCZ FLAGS_REG)
9508 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9510 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9511 (neg:DI (match_dup 1)))]
9512 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9514 [(set_attr "type" "negnot")
9515 (set_attr "mode" "DI")])
9518 (define_expand "negsi2"
9519 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9520 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9521 (clobber (reg:CC FLAGS_REG))])]
9523 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9525 (define_insn "*negsi2_1"
9526 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9527 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9528 (clobber (reg:CC FLAGS_REG))]
9529 "ix86_unary_operator_ok (NEG, SImode, operands)"
9531 [(set_attr "type" "negnot")
9532 (set_attr "mode" "SI")])
9534 ;; Combine is quite creative about this pattern.
9535 (define_insn "*negsi2_1_zext"
9536 [(set (match_operand:DI 0 "register_operand" "=r")
9537 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9540 (clobber (reg:CC FLAGS_REG))]
9541 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9543 [(set_attr "type" "negnot")
9544 (set_attr "mode" "SI")])
9546 ;; The problem with neg is that it does not perform (compare x 0),
9547 ;; it really performs (compare 0 x), which leaves us with the zero
9548 ;; flag being the only useful item.
9550 (define_insn "*negsi2_cmpz"
9551 [(set (reg:CCZ FLAGS_REG)
9552 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9554 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9555 (neg:SI (match_dup 1)))]
9556 "ix86_unary_operator_ok (NEG, SImode, operands)"
9558 [(set_attr "type" "negnot")
9559 (set_attr "mode" "SI")])
9561 (define_insn "*negsi2_cmpz_zext"
9562 [(set (reg:CCZ FLAGS_REG)
9563 (compare:CCZ (lshiftrt:DI
9565 (match_operand:DI 1 "register_operand" "0")
9569 (set (match_operand:DI 0 "register_operand" "=r")
9570 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9573 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9575 [(set_attr "type" "negnot")
9576 (set_attr "mode" "SI")])
9578 (define_expand "neghi2"
9579 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9580 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9581 (clobber (reg:CC FLAGS_REG))])]
9582 "TARGET_HIMODE_MATH"
9583 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9585 (define_insn "*neghi2_1"
9586 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9587 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9588 (clobber (reg:CC FLAGS_REG))]
9589 "ix86_unary_operator_ok (NEG, HImode, operands)"
9591 [(set_attr "type" "negnot")
9592 (set_attr "mode" "HI")])
9594 (define_insn "*neghi2_cmpz"
9595 [(set (reg:CCZ FLAGS_REG)
9596 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9598 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9599 (neg:HI (match_dup 1)))]
9600 "ix86_unary_operator_ok (NEG, HImode, operands)"
9602 [(set_attr "type" "negnot")
9603 (set_attr "mode" "HI")])
9605 (define_expand "negqi2"
9606 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9607 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9608 (clobber (reg:CC FLAGS_REG))])]
9609 "TARGET_QIMODE_MATH"
9610 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9612 (define_insn "*negqi2_1"
9613 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9614 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9615 (clobber (reg:CC FLAGS_REG))]
9616 "ix86_unary_operator_ok (NEG, QImode, operands)"
9618 [(set_attr "type" "negnot")
9619 (set_attr "mode" "QI")])
9621 (define_insn "*negqi2_cmpz"
9622 [(set (reg:CCZ FLAGS_REG)
9623 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9625 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9626 (neg:QI (match_dup 1)))]
9627 "ix86_unary_operator_ok (NEG, QImode, operands)"
9629 [(set_attr "type" "negnot")
9630 (set_attr "mode" "QI")])
9632 ;; Changing of sign for FP values is doable using integer unit too.
9634 (define_expand "negsf2"
9635 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9636 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9637 "TARGET_80387 || TARGET_SSE_MATH"
9638 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9640 (define_expand "abssf2"
9641 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9642 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9643 "TARGET_80387 || TARGET_SSE_MATH"
9644 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9646 (define_insn "*absnegsf2_mixed"
9647 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9648 (match_operator:SF 3 "absneg_operator"
9649 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9650 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9651 (clobber (reg:CC FLAGS_REG))]
9652 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9653 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9656 (define_insn "*absnegsf2_sse"
9657 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9658 (match_operator:SF 3 "absneg_operator"
9659 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9660 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9661 (clobber (reg:CC FLAGS_REG))]
9663 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9666 (define_insn "*absnegsf2_i387"
9667 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9668 (match_operator:SF 3 "absneg_operator"
9669 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9670 (use (match_operand 2 "" ""))
9671 (clobber (reg:CC FLAGS_REG))]
9672 "TARGET_80387 && !TARGET_SSE_MATH
9673 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9676 (define_expand "copysignsf3"
9677 [(match_operand:SF 0 "register_operand" "")
9678 (match_operand:SF 1 "nonmemory_operand" "")
9679 (match_operand:SF 2 "register_operand" "")]
9682 ix86_expand_copysign (operands);
9686 (define_insn_and_split "copysignsf3_const"
9687 [(set (match_operand:SF 0 "register_operand" "=x")
9689 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9690 (match_operand:SF 2 "register_operand" "0")
9691 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9695 "&& reload_completed"
9698 ix86_split_copysign_const (operands);
9702 (define_insn "copysignsf3_var"
9703 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9705 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9706 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9707 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9708 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9710 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9715 [(set (match_operand:SF 0 "register_operand" "")
9717 [(match_operand:SF 2 "register_operand" "")
9718 (match_operand:SF 3 "register_operand" "")
9719 (match_operand:V4SF 4 "" "")
9720 (match_operand:V4SF 5 "" "")]
9722 (clobber (match_scratch:V4SF 1 ""))]
9723 "TARGET_SSE_MATH && reload_completed"
9726 ix86_split_copysign_var (operands);
9730 (define_expand "negdf2"
9731 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9732 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9733 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9734 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9736 (define_expand "absdf2"
9737 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9738 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9739 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9740 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9742 (define_insn "*absnegdf2_mixed"
9743 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9744 (match_operator:DF 3 "absneg_operator"
9745 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9746 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9747 (clobber (reg:CC FLAGS_REG))]
9748 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9749 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9752 (define_insn "*absnegdf2_sse"
9753 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9754 (match_operator:DF 3 "absneg_operator"
9755 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9756 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9757 (clobber (reg:CC FLAGS_REG))]
9758 "TARGET_SSE2 && TARGET_SSE_MATH
9759 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9762 (define_insn "*absnegdf2_i387"
9763 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9764 (match_operator:DF 3 "absneg_operator"
9765 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9766 (use (match_operand 2 "" ""))
9767 (clobber (reg:CC FLAGS_REG))]
9768 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9769 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9772 (define_expand "copysigndf3"
9773 [(match_operand:DF 0 "register_operand" "")
9774 (match_operand:DF 1 "nonmemory_operand" "")
9775 (match_operand:DF 2 "register_operand" "")]
9776 "TARGET_SSE2 && TARGET_SSE_MATH"
9778 ix86_expand_copysign (operands);
9782 (define_insn_and_split "copysigndf3_const"
9783 [(set (match_operand:DF 0 "register_operand" "=x")
9785 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9786 (match_operand:DF 2 "register_operand" "0")
9787 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9789 "TARGET_SSE2 && TARGET_SSE_MATH"
9791 "&& reload_completed"
9794 ix86_split_copysign_const (operands);
9798 (define_insn "copysigndf3_var"
9799 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9801 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9802 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9803 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9804 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9806 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9807 "TARGET_SSE2 && TARGET_SSE_MATH"
9811 [(set (match_operand:DF 0 "register_operand" "")
9813 [(match_operand:DF 2 "register_operand" "")
9814 (match_operand:DF 3 "register_operand" "")
9815 (match_operand:V2DF 4 "" "")
9816 (match_operand:V2DF 5 "" "")]
9818 (clobber (match_scratch:V2DF 1 ""))]
9819 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9822 ix86_split_copysign_var (operands);
9826 (define_expand "negxf2"
9827 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9828 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9830 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9832 (define_expand "absxf2"
9833 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9834 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9836 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9838 (define_insn "*absnegxf2_i387"
9839 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9840 (match_operator:XF 3 "absneg_operator"
9841 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9842 (use (match_operand 2 "" ""))
9843 (clobber (reg:CC FLAGS_REG))]
9845 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9848 ;; Splitters for fp abs and neg.
9851 [(set (match_operand 0 "fp_register_operand" "")
9852 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9853 (use (match_operand 2 "" ""))
9854 (clobber (reg:CC FLAGS_REG))]
9856 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9859 [(set (match_operand 0 "register_operand" "")
9860 (match_operator 3 "absneg_operator"
9861 [(match_operand 1 "register_operand" "")]))
9862 (use (match_operand 2 "nonimmediate_operand" ""))
9863 (clobber (reg:CC FLAGS_REG))]
9864 "reload_completed && SSE_REG_P (operands[0])"
9865 [(set (match_dup 0) (match_dup 3))]
9867 enum machine_mode mode = GET_MODE (operands[0]);
9868 enum machine_mode vmode = GET_MODE (operands[2]);
9871 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9872 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9873 if (operands_match_p (operands[0], operands[2]))
9876 operands[1] = operands[2];
9879 if (GET_CODE (operands[3]) == ABS)
9880 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9882 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9887 [(set (match_operand:SF 0 "register_operand" "")
9888 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9889 (use (match_operand:V4SF 2 "" ""))
9890 (clobber (reg:CC FLAGS_REG))]
9892 [(parallel [(set (match_dup 0) (match_dup 1))
9893 (clobber (reg:CC FLAGS_REG))])]
9896 operands[0] = gen_lowpart (SImode, operands[0]);
9897 if (GET_CODE (operands[1]) == ABS)
9899 tmp = gen_int_mode (0x7fffffff, SImode);
9900 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9904 tmp = gen_int_mode (0x80000000, SImode);
9905 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9911 [(set (match_operand:DF 0 "register_operand" "")
9912 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9913 (use (match_operand 2 "" ""))
9914 (clobber (reg:CC FLAGS_REG))]
9916 [(parallel [(set (match_dup 0) (match_dup 1))
9917 (clobber (reg:CC FLAGS_REG))])]
9922 tmp = gen_lowpart (DImode, operands[0]);
9923 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9926 if (GET_CODE (operands[1]) == ABS)
9929 tmp = gen_rtx_NOT (DImode, tmp);
9933 operands[0] = gen_highpart (SImode, operands[0]);
9934 if (GET_CODE (operands[1]) == ABS)
9936 tmp = gen_int_mode (0x7fffffff, SImode);
9937 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9941 tmp = gen_int_mode (0x80000000, SImode);
9942 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9949 [(set (match_operand:XF 0 "register_operand" "")
9950 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9951 (use (match_operand 2 "" ""))
9952 (clobber (reg:CC FLAGS_REG))]
9954 [(parallel [(set (match_dup 0) (match_dup 1))
9955 (clobber (reg:CC FLAGS_REG))])]
9958 operands[0] = gen_rtx_REG (SImode,
9959 true_regnum (operands[0])
9960 + (TARGET_64BIT ? 1 : 2));
9961 if (GET_CODE (operands[1]) == ABS)
9963 tmp = GEN_INT (0x7fff);
9964 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9968 tmp = GEN_INT (0x8000);
9969 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9975 [(set (match_operand 0 "memory_operand" "")
9976 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9977 (use (match_operand 2 "" ""))
9978 (clobber (reg:CC FLAGS_REG))]
9980 [(parallel [(set (match_dup 0) (match_dup 1))
9981 (clobber (reg:CC FLAGS_REG))])]
9983 enum machine_mode mode = GET_MODE (operands[0]);
9984 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9987 operands[0] = adjust_address (operands[0], QImode, size - 1);
9988 if (GET_CODE (operands[1]) == ABS)
9990 tmp = gen_int_mode (0x7f, QImode);
9991 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9995 tmp = gen_int_mode (0x80, QImode);
9996 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10001 ;; Conditionalize these after reload. If they match before reload, we
10002 ;; lose the clobber and ability to use integer instructions.
10004 (define_insn "*negsf2_1"
10005 [(set (match_operand:SF 0 "register_operand" "=f")
10006 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10007 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10009 [(set_attr "type" "fsgn")
10010 (set_attr "mode" "SF")])
10012 (define_insn "*negdf2_1"
10013 [(set (match_operand:DF 0 "register_operand" "=f")
10014 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10015 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10017 [(set_attr "type" "fsgn")
10018 (set_attr "mode" "DF")])
10020 (define_insn "*negxf2_1"
10021 [(set (match_operand:XF 0 "register_operand" "=f")
10022 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10025 [(set_attr "type" "fsgn")
10026 (set_attr "mode" "XF")])
10028 (define_insn "*abssf2_1"
10029 [(set (match_operand:SF 0 "register_operand" "=f")
10030 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10031 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10033 [(set_attr "type" "fsgn")
10034 (set_attr "mode" "SF")])
10036 (define_insn "*absdf2_1"
10037 [(set (match_operand:DF 0 "register_operand" "=f")
10038 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10039 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10041 [(set_attr "type" "fsgn")
10042 (set_attr "mode" "DF")])
10044 (define_insn "*absxf2_1"
10045 [(set (match_operand:XF 0 "register_operand" "=f")
10046 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10049 [(set_attr "type" "fsgn")
10050 (set_attr "mode" "DF")])
10052 (define_insn "*negextendsfdf2"
10053 [(set (match_operand:DF 0 "register_operand" "=f")
10054 (neg:DF (float_extend:DF
10055 (match_operand:SF 1 "register_operand" "0"))))]
10056 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10058 [(set_attr "type" "fsgn")
10059 (set_attr "mode" "DF")])
10061 (define_insn "*negextenddfxf2"
10062 [(set (match_operand:XF 0 "register_operand" "=f")
10063 (neg:XF (float_extend:XF
10064 (match_operand:DF 1 "register_operand" "0"))))]
10067 [(set_attr "type" "fsgn")
10068 (set_attr "mode" "XF")])
10070 (define_insn "*negextendsfxf2"
10071 [(set (match_operand:XF 0 "register_operand" "=f")
10072 (neg:XF (float_extend:XF
10073 (match_operand:SF 1 "register_operand" "0"))))]
10076 [(set_attr "type" "fsgn")
10077 (set_attr "mode" "XF")])
10079 (define_insn "*absextendsfdf2"
10080 [(set (match_operand:DF 0 "register_operand" "=f")
10081 (abs:DF (float_extend:DF
10082 (match_operand:SF 1 "register_operand" "0"))))]
10083 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10085 [(set_attr "type" "fsgn")
10086 (set_attr "mode" "DF")])
10088 (define_insn "*absextenddfxf2"
10089 [(set (match_operand:XF 0 "register_operand" "=f")
10090 (abs:XF (float_extend:XF
10091 (match_operand:DF 1 "register_operand" "0"))))]
10094 [(set_attr "type" "fsgn")
10095 (set_attr "mode" "XF")])
10097 (define_insn "*absextendsfxf2"
10098 [(set (match_operand:XF 0 "register_operand" "=f")
10099 (abs:XF (float_extend:XF
10100 (match_operand:SF 1 "register_operand" "0"))))]
10103 [(set_attr "type" "fsgn")
10104 (set_attr "mode" "XF")])
10106 ;; One complement instructions
10108 (define_expand "one_cmpldi2"
10109 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10110 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10112 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10114 (define_insn "*one_cmpldi2_1_rex64"
10115 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10116 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10117 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10119 [(set_attr "type" "negnot")
10120 (set_attr "mode" "DI")])
10122 (define_insn "*one_cmpldi2_2_rex64"
10123 [(set (reg FLAGS_REG)
10124 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10126 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10127 (not:DI (match_dup 1)))]
10128 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10129 && ix86_unary_operator_ok (NOT, DImode, operands)"
10131 [(set_attr "type" "alu1")
10132 (set_attr "mode" "DI")])
10135 [(set (match_operand 0 "flags_reg_operand" "")
10136 (match_operator 2 "compare_operator"
10137 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10139 (set (match_operand:DI 1 "nonimmediate_operand" "")
10140 (not:DI (match_dup 3)))]
10141 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10142 [(parallel [(set (match_dup 0)
10144 [(xor:DI (match_dup 3) (const_int -1))
10147 (xor:DI (match_dup 3) (const_int -1)))])]
10150 (define_expand "one_cmplsi2"
10151 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10152 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10154 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10156 (define_insn "*one_cmplsi2_1"
10157 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10158 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10159 "ix86_unary_operator_ok (NOT, SImode, operands)"
10161 [(set_attr "type" "negnot")
10162 (set_attr "mode" "SI")])
10164 ;; ??? Currently never generated - xor is used instead.
10165 (define_insn "*one_cmplsi2_1_zext"
10166 [(set (match_operand:DI 0 "register_operand" "=r")
10167 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10168 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10170 [(set_attr "type" "negnot")
10171 (set_attr "mode" "SI")])
10173 (define_insn "*one_cmplsi2_2"
10174 [(set (reg FLAGS_REG)
10175 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10177 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10178 (not:SI (match_dup 1)))]
10179 "ix86_match_ccmode (insn, CCNOmode)
10180 && ix86_unary_operator_ok (NOT, SImode, operands)"
10182 [(set_attr "type" "alu1")
10183 (set_attr "mode" "SI")])
10186 [(set (match_operand 0 "flags_reg_operand" "")
10187 (match_operator 2 "compare_operator"
10188 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10190 (set (match_operand:SI 1 "nonimmediate_operand" "")
10191 (not:SI (match_dup 3)))]
10192 "ix86_match_ccmode (insn, CCNOmode)"
10193 [(parallel [(set (match_dup 0)
10194 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10197 (xor:SI (match_dup 3) (const_int -1)))])]
10200 ;; ??? Currently never generated - xor is used instead.
10201 (define_insn "*one_cmplsi2_2_zext"
10202 [(set (reg FLAGS_REG)
10203 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10205 (set (match_operand:DI 0 "register_operand" "=r")
10206 (zero_extend:DI (not:SI (match_dup 1))))]
10207 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10208 && ix86_unary_operator_ok (NOT, SImode, operands)"
10210 [(set_attr "type" "alu1")
10211 (set_attr "mode" "SI")])
10214 [(set (match_operand 0 "flags_reg_operand" "")
10215 (match_operator 2 "compare_operator"
10216 [(not:SI (match_operand:SI 3 "register_operand" ""))
10218 (set (match_operand:DI 1 "register_operand" "")
10219 (zero_extend:DI (not:SI (match_dup 3))))]
10220 "ix86_match_ccmode (insn, CCNOmode)"
10221 [(parallel [(set (match_dup 0)
10222 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10225 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10228 (define_expand "one_cmplhi2"
10229 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10230 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10231 "TARGET_HIMODE_MATH"
10232 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10234 (define_insn "*one_cmplhi2_1"
10235 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10236 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10237 "ix86_unary_operator_ok (NOT, HImode, operands)"
10239 [(set_attr "type" "negnot")
10240 (set_attr "mode" "HI")])
10242 (define_insn "*one_cmplhi2_2"
10243 [(set (reg FLAGS_REG)
10244 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10246 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10247 (not:HI (match_dup 1)))]
10248 "ix86_match_ccmode (insn, CCNOmode)
10249 && ix86_unary_operator_ok (NEG, HImode, operands)"
10251 [(set_attr "type" "alu1")
10252 (set_attr "mode" "HI")])
10255 [(set (match_operand 0 "flags_reg_operand" "")
10256 (match_operator 2 "compare_operator"
10257 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10259 (set (match_operand:HI 1 "nonimmediate_operand" "")
10260 (not:HI (match_dup 3)))]
10261 "ix86_match_ccmode (insn, CCNOmode)"
10262 [(parallel [(set (match_dup 0)
10263 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10266 (xor:HI (match_dup 3) (const_int -1)))])]
10269 ;; %%% Potential partial reg stall on alternative 1. What to do?
10270 (define_expand "one_cmplqi2"
10271 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10272 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10273 "TARGET_QIMODE_MATH"
10274 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10276 (define_insn "*one_cmplqi2_1"
10277 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10278 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10279 "ix86_unary_operator_ok (NOT, QImode, operands)"
10283 [(set_attr "type" "negnot")
10284 (set_attr "mode" "QI,SI")])
10286 (define_insn "*one_cmplqi2_2"
10287 [(set (reg FLAGS_REG)
10288 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10290 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10291 (not:QI (match_dup 1)))]
10292 "ix86_match_ccmode (insn, CCNOmode)
10293 && ix86_unary_operator_ok (NOT, QImode, operands)"
10295 [(set_attr "type" "alu1")
10296 (set_attr "mode" "QI")])
10299 [(set (match_operand 0 "flags_reg_operand" "")
10300 (match_operator 2 "compare_operator"
10301 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10303 (set (match_operand:QI 1 "nonimmediate_operand" "")
10304 (not:QI (match_dup 3)))]
10305 "ix86_match_ccmode (insn, CCNOmode)"
10306 [(parallel [(set (match_dup 0)
10307 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10310 (xor:QI (match_dup 3) (const_int -1)))])]
10313 ;; Arithmetic shift instructions
10315 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10316 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10317 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10318 ;; from the assembler input.
10320 ;; This instruction shifts the target reg/mem as usual, but instead of
10321 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10322 ;; is a left shift double, bits are taken from the high order bits of
10323 ;; reg, else if the insn is a shift right double, bits are taken from the
10324 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10325 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10327 ;; Since sh[lr]d does not change the `reg' operand, that is done
10328 ;; separately, making all shifts emit pairs of shift double and normal
10329 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10330 ;; support a 63 bit shift, each shift where the count is in a reg expands
10331 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10333 ;; If the shift count is a constant, we need never emit more than one
10334 ;; shift pair, instead using moves and sign extension for counts greater
10337 (define_expand "ashlti3"
10338 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10339 (ashift:TI (match_operand:TI 1 "register_operand" "")
10340 (match_operand:QI 2 "nonmemory_operand" "")))
10341 (clobber (reg:CC FLAGS_REG))])]
10344 if (! immediate_operand (operands[2], QImode))
10346 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10349 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10353 (define_insn "ashlti3_1"
10354 [(set (match_operand:TI 0 "register_operand" "=r")
10355 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10356 (match_operand:QI 2 "register_operand" "c")))
10357 (clobber (match_scratch:DI 3 "=&r"))
10358 (clobber (reg:CC FLAGS_REG))]
10361 [(set_attr "type" "multi")])
10363 (define_insn "*ashlti3_2"
10364 [(set (match_operand:TI 0 "register_operand" "=r")
10365 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10366 (match_operand:QI 2 "immediate_operand" "O")))
10367 (clobber (reg:CC FLAGS_REG))]
10370 [(set_attr "type" "multi")])
10373 [(set (match_operand:TI 0 "register_operand" "")
10374 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10375 (match_operand:QI 2 "register_operand" "")))
10376 (clobber (match_scratch:DI 3 ""))
10377 (clobber (reg:CC FLAGS_REG))]
10378 "TARGET_64BIT && reload_completed"
10380 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10383 [(set (match_operand:TI 0 "register_operand" "")
10384 (ashift:TI (match_operand:TI 1 "register_operand" "")
10385 (match_operand:QI 2 "immediate_operand" "")))
10386 (clobber (reg:CC FLAGS_REG))]
10387 "TARGET_64BIT && reload_completed"
10389 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10391 (define_insn "x86_64_shld"
10392 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10393 (ior:DI (ashift:DI (match_dup 0)
10394 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10395 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10396 (minus:QI (const_int 64) (match_dup 2)))))
10397 (clobber (reg:CC FLAGS_REG))]
10400 shld{q}\t{%2, %1, %0|%0, %1, %2}
10401 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10402 [(set_attr "type" "ishift")
10403 (set_attr "prefix_0f" "1")
10404 (set_attr "mode" "DI")
10405 (set_attr "athlon_decode" "vector")
10406 (set_attr "amdfam10_decode" "vector")])
10408 (define_expand "x86_64_shift_adj"
10409 [(set (reg:CCZ FLAGS_REG)
10410 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10413 (set (match_operand:DI 0 "register_operand" "")
10414 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10415 (match_operand:DI 1 "register_operand" "")
10418 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10419 (match_operand:DI 3 "register_operand" "r")
10424 (define_expand "ashldi3"
10425 [(set (match_operand:DI 0 "shiftdi_operand" "")
10426 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10427 (match_operand:QI 2 "nonmemory_operand" "")))]
10429 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10431 (define_insn "*ashldi3_1_rex64"
10432 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10433 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10434 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10435 (clobber (reg:CC FLAGS_REG))]
10436 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10438 switch (get_attr_type (insn))
10441 gcc_assert (operands[2] == const1_rtx);
10442 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10443 return "add{q}\t{%0, %0|%0, %0}";
10446 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10447 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10448 operands[1] = gen_rtx_MULT (DImode, operands[1],
10449 GEN_INT (1 << INTVAL (operands[2])));
10450 return "lea{q}\t{%a1, %0|%0, %a1}";
10453 if (REG_P (operands[2]))
10454 return "sal{q}\t{%b2, %0|%0, %b2}";
10455 else if (operands[2] == const1_rtx
10456 && (TARGET_SHIFT1 || optimize_size))
10457 return "sal{q}\t%0";
10459 return "sal{q}\t{%2, %0|%0, %2}";
10462 [(set (attr "type")
10463 (cond [(eq_attr "alternative" "1")
10464 (const_string "lea")
10465 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10467 (match_operand 0 "register_operand" ""))
10468 (match_operand 2 "const1_operand" ""))
10469 (const_string "alu")
10471 (const_string "ishift")))
10472 (set_attr "mode" "DI")])
10474 ;; Convert lea to the lea pattern to avoid flags dependency.
10476 [(set (match_operand:DI 0 "register_operand" "")
10477 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10478 (match_operand:QI 2 "immediate_operand" "")))
10479 (clobber (reg:CC FLAGS_REG))]
10480 "TARGET_64BIT && reload_completed
10481 && true_regnum (operands[0]) != true_regnum (operands[1])"
10482 [(set (match_dup 0)
10483 (mult:DI (match_dup 1)
10485 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10487 ;; This pattern can't accept a variable shift count, since shifts by
10488 ;; zero don't affect the flags. We assume that shifts by constant
10489 ;; zero are optimized away.
10490 (define_insn "*ashldi3_cmp_rex64"
10491 [(set (reg FLAGS_REG)
10493 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10494 (match_operand:QI 2 "immediate_operand" "e"))
10496 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10497 (ashift:DI (match_dup 1) (match_dup 2)))]
10498 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10499 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10501 || !TARGET_PARTIAL_FLAG_REG_STALL
10502 || (operands[2] == const1_rtx
10504 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10506 switch (get_attr_type (insn))
10509 gcc_assert (operands[2] == const1_rtx);
10510 return "add{q}\t{%0, %0|%0, %0}";
10513 if (REG_P (operands[2]))
10514 return "sal{q}\t{%b2, %0|%0, %b2}";
10515 else if (operands[2] == const1_rtx
10516 && (TARGET_SHIFT1 || optimize_size))
10517 return "sal{q}\t%0";
10519 return "sal{q}\t{%2, %0|%0, %2}";
10522 [(set (attr "type")
10523 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10525 (match_operand 0 "register_operand" ""))
10526 (match_operand 2 "const1_operand" ""))
10527 (const_string "alu")
10529 (const_string "ishift")))
10530 (set_attr "mode" "DI")])
10532 (define_insn "*ashldi3_cconly_rex64"
10533 [(set (reg FLAGS_REG)
10535 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10536 (match_operand:QI 2 "immediate_operand" "e"))
10538 (clobber (match_scratch:DI 0 "=r"))]
10539 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10540 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10542 || !TARGET_PARTIAL_FLAG_REG_STALL
10543 || (operands[2] == const1_rtx
10545 || TARGET_DOUBLE_WITH_ADD)))"
10547 switch (get_attr_type (insn))
10550 gcc_assert (operands[2] == const1_rtx);
10551 return "add{q}\t{%0, %0|%0, %0}";
10554 if (REG_P (operands[2]))
10555 return "sal{q}\t{%b2, %0|%0, %b2}";
10556 else if (operands[2] == const1_rtx
10557 && (TARGET_SHIFT1 || optimize_size))
10558 return "sal{q}\t%0";
10560 return "sal{q}\t{%2, %0|%0, %2}";
10563 [(set (attr "type")
10564 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10566 (match_operand 0 "register_operand" ""))
10567 (match_operand 2 "const1_operand" ""))
10568 (const_string "alu")
10570 (const_string "ishift")))
10571 (set_attr "mode" "DI")])
10573 (define_insn "*ashldi3_1"
10574 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10575 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10576 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10577 (clobber (reg:CC FLAGS_REG))]
10580 [(set_attr "type" "multi")])
10582 ;; By default we don't ask for a scratch register, because when DImode
10583 ;; values are manipulated, registers are already at a premium. But if
10584 ;; we have one handy, we won't turn it away.
10586 [(match_scratch:SI 3 "r")
10587 (parallel [(set (match_operand:DI 0 "register_operand" "")
10588 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10589 (match_operand:QI 2 "nonmemory_operand" "")))
10590 (clobber (reg:CC FLAGS_REG))])
10592 "!TARGET_64BIT && TARGET_CMOVE"
10594 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10597 [(set (match_operand:DI 0 "register_operand" "")
10598 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10599 (match_operand:QI 2 "nonmemory_operand" "")))
10600 (clobber (reg:CC FLAGS_REG))]
10601 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10602 ? flow2_completed : reload_completed)"
10604 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10606 (define_insn "x86_shld_1"
10607 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10608 (ior:SI (ashift:SI (match_dup 0)
10609 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10610 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10611 (minus:QI (const_int 32) (match_dup 2)))))
10612 (clobber (reg:CC FLAGS_REG))]
10615 shld{l}\t{%2, %1, %0|%0, %1, %2}
10616 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10617 [(set_attr "type" "ishift")
10618 (set_attr "prefix_0f" "1")
10619 (set_attr "mode" "SI")
10620 (set_attr "pent_pair" "np")
10621 (set_attr "athlon_decode" "vector")
10622 (set_attr "amdfam10_decode" "vector")])
10624 (define_expand "x86_shift_adj_1"
10625 [(set (reg:CCZ FLAGS_REG)
10626 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10629 (set (match_operand:SI 0 "register_operand" "")
10630 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10631 (match_operand:SI 1 "register_operand" "")
10634 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10635 (match_operand:SI 3 "register_operand" "r")
10640 (define_expand "x86_shift_adj_2"
10641 [(use (match_operand:SI 0 "register_operand" ""))
10642 (use (match_operand:SI 1 "register_operand" ""))
10643 (use (match_operand:QI 2 "register_operand" ""))]
10646 rtx label = gen_label_rtx ();
10649 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10651 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10652 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10653 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10654 gen_rtx_LABEL_REF (VOIDmode, label),
10656 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10657 JUMP_LABEL (tmp) = label;
10659 emit_move_insn (operands[0], operands[1]);
10660 ix86_expand_clear (operands[1]);
10662 emit_label (label);
10663 LABEL_NUSES (label) = 1;
10668 (define_expand "ashlsi3"
10669 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10670 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10671 (match_operand:QI 2 "nonmemory_operand" "")))
10672 (clobber (reg:CC FLAGS_REG))]
10674 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10676 (define_insn "*ashlsi3_1"
10677 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10678 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10679 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10680 (clobber (reg:CC FLAGS_REG))]
10681 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10683 switch (get_attr_type (insn))
10686 gcc_assert (operands[2] == const1_rtx);
10687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10688 return "add{l}\t{%0, %0|%0, %0}";
10694 if (REG_P (operands[2]))
10695 return "sal{l}\t{%b2, %0|%0, %b2}";
10696 else if (operands[2] == const1_rtx
10697 && (TARGET_SHIFT1 || optimize_size))
10698 return "sal{l}\t%0";
10700 return "sal{l}\t{%2, %0|%0, %2}";
10703 [(set (attr "type")
10704 (cond [(eq_attr "alternative" "1")
10705 (const_string "lea")
10706 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10708 (match_operand 0 "register_operand" ""))
10709 (match_operand 2 "const1_operand" ""))
10710 (const_string "alu")
10712 (const_string "ishift")))
10713 (set_attr "mode" "SI")])
10715 ;; Convert lea to the lea pattern to avoid flags dependency.
10717 [(set (match_operand 0 "register_operand" "")
10718 (ashift (match_operand 1 "index_register_operand" "")
10719 (match_operand:QI 2 "const_int_operand" "")))
10720 (clobber (reg:CC FLAGS_REG))]
10722 && true_regnum (operands[0]) != true_regnum (operands[1])
10723 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10727 enum machine_mode mode = GET_MODE (operands[0]);
10729 if (GET_MODE_SIZE (mode) < 4)
10730 operands[0] = gen_lowpart (SImode, operands[0]);
10732 operands[1] = gen_lowpart (Pmode, operands[1]);
10733 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10735 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10736 if (Pmode != SImode)
10737 pat = gen_rtx_SUBREG (SImode, pat, 0);
10738 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10742 ;; Rare case of shifting RSP is handled by generating move and shift
10744 [(set (match_operand 0 "register_operand" "")
10745 (ashift (match_operand 1 "register_operand" "")
10746 (match_operand:QI 2 "const_int_operand" "")))
10747 (clobber (reg:CC FLAGS_REG))]
10749 && true_regnum (operands[0]) != true_regnum (operands[1])"
10753 emit_move_insn (operands[0], operands[1]);
10754 pat = gen_rtx_SET (VOIDmode, operands[0],
10755 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10756 operands[0], operands[2]));
10757 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10758 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10762 (define_insn "*ashlsi3_1_zext"
10763 [(set (match_operand:DI 0 "register_operand" "=r,r")
10764 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10765 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10766 (clobber (reg:CC FLAGS_REG))]
10767 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10769 switch (get_attr_type (insn))
10772 gcc_assert (operands[2] == const1_rtx);
10773 return "add{l}\t{%k0, %k0|%k0, %k0}";
10779 if (REG_P (operands[2]))
10780 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10781 else if (operands[2] == const1_rtx
10782 && (TARGET_SHIFT1 || optimize_size))
10783 return "sal{l}\t%k0";
10785 return "sal{l}\t{%2, %k0|%k0, %2}";
10788 [(set (attr "type")
10789 (cond [(eq_attr "alternative" "1")
10790 (const_string "lea")
10791 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10793 (match_operand 2 "const1_operand" ""))
10794 (const_string "alu")
10796 (const_string "ishift")))
10797 (set_attr "mode" "SI")])
10799 ;; Convert lea to the lea pattern to avoid flags dependency.
10801 [(set (match_operand:DI 0 "register_operand" "")
10802 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10803 (match_operand:QI 2 "const_int_operand" ""))))
10804 (clobber (reg:CC FLAGS_REG))]
10805 "TARGET_64BIT && reload_completed
10806 && true_regnum (operands[0]) != true_regnum (operands[1])"
10807 [(set (match_dup 0) (zero_extend:DI
10808 (subreg:SI (mult:SI (match_dup 1)
10809 (match_dup 2)) 0)))]
10811 operands[1] = gen_lowpart (Pmode, operands[1]);
10812 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10815 ;; This pattern can't accept a variable shift count, since shifts by
10816 ;; zero don't affect the flags. We assume that shifts by constant
10817 ;; zero are optimized away.
10818 (define_insn "*ashlsi3_cmp"
10819 [(set (reg FLAGS_REG)
10821 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10822 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10824 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10825 (ashift:SI (match_dup 1) (match_dup 2)))]
10826 "ix86_match_ccmode (insn, CCGOCmode)
10827 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10829 || !TARGET_PARTIAL_FLAG_REG_STALL
10830 || (operands[2] == const1_rtx
10832 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10834 switch (get_attr_type (insn))
10837 gcc_assert (operands[2] == const1_rtx);
10838 return "add{l}\t{%0, %0|%0, %0}";
10841 if (REG_P (operands[2]))
10842 return "sal{l}\t{%b2, %0|%0, %b2}";
10843 else if (operands[2] == const1_rtx
10844 && (TARGET_SHIFT1 || optimize_size))
10845 return "sal{l}\t%0";
10847 return "sal{l}\t{%2, %0|%0, %2}";
10850 [(set (attr "type")
10851 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10853 (match_operand 0 "register_operand" ""))
10854 (match_operand 2 "const1_operand" ""))
10855 (const_string "alu")
10857 (const_string "ishift")))
10858 (set_attr "mode" "SI")])
10860 (define_insn "*ashlsi3_cconly"
10861 [(set (reg FLAGS_REG)
10863 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10864 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10866 (clobber (match_scratch:SI 0 "=r"))]
10867 "ix86_match_ccmode (insn, CCGOCmode)
10868 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10870 || !TARGET_PARTIAL_FLAG_REG_STALL
10871 || (operands[2] == const1_rtx
10873 || TARGET_DOUBLE_WITH_ADD)))"
10875 switch (get_attr_type (insn))
10878 gcc_assert (operands[2] == const1_rtx);
10879 return "add{l}\t{%0, %0|%0, %0}";
10882 if (REG_P (operands[2]))
10883 return "sal{l}\t{%b2, %0|%0, %b2}";
10884 else if (operands[2] == const1_rtx
10885 && (TARGET_SHIFT1 || optimize_size))
10886 return "sal{l}\t%0";
10888 return "sal{l}\t{%2, %0|%0, %2}";
10891 [(set (attr "type")
10892 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10894 (match_operand 0 "register_operand" ""))
10895 (match_operand 2 "const1_operand" ""))
10896 (const_string "alu")
10898 (const_string "ishift")))
10899 (set_attr "mode" "SI")])
10901 (define_insn "*ashlsi3_cmp_zext"
10902 [(set (reg FLAGS_REG)
10904 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10905 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10907 (set (match_operand:DI 0 "register_operand" "=r")
10908 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10909 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10910 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10912 || !TARGET_PARTIAL_FLAG_REG_STALL
10913 || (operands[2] == const1_rtx
10915 || TARGET_DOUBLE_WITH_ADD)))"
10917 switch (get_attr_type (insn))
10920 gcc_assert (operands[2] == const1_rtx);
10921 return "add{l}\t{%k0, %k0|%k0, %k0}";
10924 if (REG_P (operands[2]))
10925 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10926 else if (operands[2] == const1_rtx
10927 && (TARGET_SHIFT1 || optimize_size))
10928 return "sal{l}\t%k0";
10930 return "sal{l}\t{%2, %k0|%k0, %2}";
10933 [(set (attr "type")
10934 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10936 (match_operand 2 "const1_operand" ""))
10937 (const_string "alu")
10939 (const_string "ishift")))
10940 (set_attr "mode" "SI")])
10942 (define_expand "ashlhi3"
10943 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10944 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10945 (match_operand:QI 2 "nonmemory_operand" "")))
10946 (clobber (reg:CC FLAGS_REG))]
10947 "TARGET_HIMODE_MATH"
10948 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10950 (define_insn "*ashlhi3_1_lea"
10951 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10952 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10953 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10954 (clobber (reg:CC FLAGS_REG))]
10955 "!TARGET_PARTIAL_REG_STALL
10956 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10958 switch (get_attr_type (insn))
10963 gcc_assert (operands[2] == const1_rtx);
10964 return "add{w}\t{%0, %0|%0, %0}";
10967 if (REG_P (operands[2]))
10968 return "sal{w}\t{%b2, %0|%0, %b2}";
10969 else if (operands[2] == const1_rtx
10970 && (TARGET_SHIFT1 || optimize_size))
10971 return "sal{w}\t%0";
10973 return "sal{w}\t{%2, %0|%0, %2}";
10976 [(set (attr "type")
10977 (cond [(eq_attr "alternative" "1")
10978 (const_string "lea")
10979 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10981 (match_operand 0 "register_operand" ""))
10982 (match_operand 2 "const1_operand" ""))
10983 (const_string "alu")
10985 (const_string "ishift")))
10986 (set_attr "mode" "HI,SI")])
10988 (define_insn "*ashlhi3_1"
10989 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10990 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10991 (match_operand:QI 2 "nonmemory_operand" "cI")))
10992 (clobber (reg:CC FLAGS_REG))]
10993 "TARGET_PARTIAL_REG_STALL
10994 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10996 switch (get_attr_type (insn))
10999 gcc_assert (operands[2] == const1_rtx);
11000 return "add{w}\t{%0, %0|%0, %0}";
11003 if (REG_P (operands[2]))
11004 return "sal{w}\t{%b2, %0|%0, %b2}";
11005 else if (operands[2] == const1_rtx
11006 && (TARGET_SHIFT1 || optimize_size))
11007 return "sal{w}\t%0";
11009 return "sal{w}\t{%2, %0|%0, %2}";
11012 [(set (attr "type")
11013 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11015 (match_operand 0 "register_operand" ""))
11016 (match_operand 2 "const1_operand" ""))
11017 (const_string "alu")
11019 (const_string "ishift")))
11020 (set_attr "mode" "HI")])
11022 ;; This pattern can't accept a variable shift count, since shifts by
11023 ;; zero don't affect the flags. We assume that shifts by constant
11024 ;; zero are optimized away.
11025 (define_insn "*ashlhi3_cmp"
11026 [(set (reg FLAGS_REG)
11028 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11029 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11031 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11032 (ashift:HI (match_dup 1) (match_dup 2)))]
11033 "ix86_match_ccmode (insn, CCGOCmode)
11034 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11036 || !TARGET_PARTIAL_FLAG_REG_STALL
11037 || (operands[2] == const1_rtx
11039 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11041 switch (get_attr_type (insn))
11044 gcc_assert (operands[2] == const1_rtx);
11045 return "add{w}\t{%0, %0|%0, %0}";
11048 if (REG_P (operands[2]))
11049 return "sal{w}\t{%b2, %0|%0, %b2}";
11050 else if (operands[2] == const1_rtx
11051 && (TARGET_SHIFT1 || optimize_size))
11052 return "sal{w}\t%0";
11054 return "sal{w}\t{%2, %0|%0, %2}";
11057 [(set (attr "type")
11058 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11060 (match_operand 0 "register_operand" ""))
11061 (match_operand 2 "const1_operand" ""))
11062 (const_string "alu")
11064 (const_string "ishift")))
11065 (set_attr "mode" "HI")])
11067 (define_insn "*ashlhi3_cconly"
11068 [(set (reg FLAGS_REG)
11070 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11071 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11073 (clobber (match_scratch:HI 0 "=r"))]
11074 "ix86_match_ccmode (insn, CCGOCmode)
11075 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11077 || !TARGET_PARTIAL_FLAG_REG_STALL
11078 || (operands[2] == const1_rtx
11080 || TARGET_DOUBLE_WITH_ADD)))"
11082 switch (get_attr_type (insn))
11085 gcc_assert (operands[2] == const1_rtx);
11086 return "add{w}\t{%0, %0|%0, %0}";
11089 if (REG_P (operands[2]))
11090 return "sal{w}\t{%b2, %0|%0, %b2}";
11091 else if (operands[2] == const1_rtx
11092 && (TARGET_SHIFT1 || optimize_size))
11093 return "sal{w}\t%0";
11095 return "sal{w}\t{%2, %0|%0, %2}";
11098 [(set (attr "type")
11099 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11101 (match_operand 0 "register_operand" ""))
11102 (match_operand 2 "const1_operand" ""))
11103 (const_string "alu")
11105 (const_string "ishift")))
11106 (set_attr "mode" "HI")])
11108 (define_expand "ashlqi3"
11109 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11110 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11111 (match_operand:QI 2 "nonmemory_operand" "")))
11112 (clobber (reg:CC FLAGS_REG))]
11113 "TARGET_QIMODE_MATH"
11114 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11116 ;; %%% Potential partial reg stall on alternative 2. What to do?
11118 (define_insn "*ashlqi3_1_lea"
11119 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11120 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11121 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11122 (clobber (reg:CC FLAGS_REG))]
11123 "!TARGET_PARTIAL_REG_STALL
11124 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11126 switch (get_attr_type (insn))
11131 gcc_assert (operands[2] == const1_rtx);
11132 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11133 return "add{l}\t{%k0, %k0|%k0, %k0}";
11135 return "add{b}\t{%0, %0|%0, %0}";
11138 if (REG_P (operands[2]))
11140 if (get_attr_mode (insn) == MODE_SI)
11141 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11143 return "sal{b}\t{%b2, %0|%0, %b2}";
11145 else if (operands[2] == const1_rtx
11146 && (TARGET_SHIFT1 || optimize_size))
11148 if (get_attr_mode (insn) == MODE_SI)
11149 return "sal{l}\t%0";
11151 return "sal{b}\t%0";
11155 if (get_attr_mode (insn) == MODE_SI)
11156 return "sal{l}\t{%2, %k0|%k0, %2}";
11158 return "sal{b}\t{%2, %0|%0, %2}";
11162 [(set (attr "type")
11163 (cond [(eq_attr "alternative" "2")
11164 (const_string "lea")
11165 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11167 (match_operand 0 "register_operand" ""))
11168 (match_operand 2 "const1_operand" ""))
11169 (const_string "alu")
11171 (const_string "ishift")))
11172 (set_attr "mode" "QI,SI,SI")])
11174 (define_insn "*ashlqi3_1"
11175 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11176 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11177 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11178 (clobber (reg:CC FLAGS_REG))]
11179 "TARGET_PARTIAL_REG_STALL
11180 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11182 switch (get_attr_type (insn))
11185 gcc_assert (operands[2] == const1_rtx);
11186 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11187 return "add{l}\t{%k0, %k0|%k0, %k0}";
11189 return "add{b}\t{%0, %0|%0, %0}";
11192 if (REG_P (operands[2]))
11194 if (get_attr_mode (insn) == MODE_SI)
11195 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11197 return "sal{b}\t{%b2, %0|%0, %b2}";
11199 else if (operands[2] == const1_rtx
11200 && (TARGET_SHIFT1 || optimize_size))
11202 if (get_attr_mode (insn) == MODE_SI)
11203 return "sal{l}\t%0";
11205 return "sal{b}\t%0";
11209 if (get_attr_mode (insn) == MODE_SI)
11210 return "sal{l}\t{%2, %k0|%k0, %2}";
11212 return "sal{b}\t{%2, %0|%0, %2}";
11216 [(set (attr "type")
11217 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11219 (match_operand 0 "register_operand" ""))
11220 (match_operand 2 "const1_operand" ""))
11221 (const_string "alu")
11223 (const_string "ishift")))
11224 (set_attr "mode" "QI,SI")])
11226 ;; This pattern can't accept a variable shift count, since shifts by
11227 ;; zero don't affect the flags. We assume that shifts by constant
11228 ;; zero are optimized away.
11229 (define_insn "*ashlqi3_cmp"
11230 [(set (reg FLAGS_REG)
11232 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11233 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11235 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11236 (ashift:QI (match_dup 1) (match_dup 2)))]
11237 "ix86_match_ccmode (insn, CCGOCmode)
11238 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11240 || !TARGET_PARTIAL_FLAG_REG_STALL
11241 || (operands[2] == const1_rtx
11243 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11245 switch (get_attr_type (insn))
11248 gcc_assert (operands[2] == const1_rtx);
11249 return "add{b}\t{%0, %0|%0, %0}";
11252 if (REG_P (operands[2]))
11253 return "sal{b}\t{%b2, %0|%0, %b2}";
11254 else if (operands[2] == const1_rtx
11255 && (TARGET_SHIFT1 || optimize_size))
11256 return "sal{b}\t%0";
11258 return "sal{b}\t{%2, %0|%0, %2}";
11261 [(set (attr "type")
11262 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11264 (match_operand 0 "register_operand" ""))
11265 (match_operand 2 "const1_operand" ""))
11266 (const_string "alu")
11268 (const_string "ishift")))
11269 (set_attr "mode" "QI")])
11271 (define_insn "*ashlqi3_cconly"
11272 [(set (reg FLAGS_REG)
11274 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11275 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11277 (clobber (match_scratch:QI 0 "=q"))]
11278 "ix86_match_ccmode (insn, CCGOCmode)
11279 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11281 || !TARGET_PARTIAL_FLAG_REG_STALL
11282 || (operands[2] == const1_rtx
11284 || TARGET_DOUBLE_WITH_ADD)))"
11286 switch (get_attr_type (insn))
11289 gcc_assert (operands[2] == const1_rtx);
11290 return "add{b}\t{%0, %0|%0, %0}";
11293 if (REG_P (operands[2]))
11294 return "sal{b}\t{%b2, %0|%0, %b2}";
11295 else if (operands[2] == const1_rtx
11296 && (TARGET_SHIFT1 || optimize_size))
11297 return "sal{b}\t%0";
11299 return "sal{b}\t{%2, %0|%0, %2}";
11302 [(set (attr "type")
11303 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11305 (match_operand 0 "register_operand" ""))
11306 (match_operand 2 "const1_operand" ""))
11307 (const_string "alu")
11309 (const_string "ishift")))
11310 (set_attr "mode" "QI")])
11312 ;; See comment above `ashldi3' about how this works.
11314 (define_expand "ashrti3"
11315 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11316 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11317 (match_operand:QI 2 "nonmemory_operand" "")))
11318 (clobber (reg:CC FLAGS_REG))])]
11321 if (! immediate_operand (operands[2], QImode))
11323 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11326 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11330 (define_insn "ashrti3_1"
11331 [(set (match_operand:TI 0 "register_operand" "=r")
11332 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11333 (match_operand:QI 2 "register_operand" "c")))
11334 (clobber (match_scratch:DI 3 "=&r"))
11335 (clobber (reg:CC FLAGS_REG))]
11338 [(set_attr "type" "multi")])
11340 (define_insn "*ashrti3_2"
11341 [(set (match_operand:TI 0 "register_operand" "=r")
11342 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11343 (match_operand:QI 2 "immediate_operand" "O")))
11344 (clobber (reg:CC FLAGS_REG))]
11347 [(set_attr "type" "multi")])
11350 [(set (match_operand:TI 0 "register_operand" "")
11351 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11352 (match_operand:QI 2 "register_operand" "")))
11353 (clobber (match_scratch:DI 3 ""))
11354 (clobber (reg:CC FLAGS_REG))]
11355 "TARGET_64BIT && reload_completed"
11357 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11360 [(set (match_operand:TI 0 "register_operand" "")
11361 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11362 (match_operand:QI 2 "immediate_operand" "")))
11363 (clobber (reg:CC FLAGS_REG))]
11364 "TARGET_64BIT && reload_completed"
11366 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11368 (define_insn "x86_64_shrd"
11369 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11370 (ior:DI (ashiftrt:DI (match_dup 0)
11371 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11372 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11373 (minus:QI (const_int 64) (match_dup 2)))))
11374 (clobber (reg:CC FLAGS_REG))]
11377 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11378 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11379 [(set_attr "type" "ishift")
11380 (set_attr "prefix_0f" "1")
11381 (set_attr "mode" "DI")
11382 (set_attr "athlon_decode" "vector")
11383 (set_attr "amdfam10_decode" "vector")])
11385 (define_expand "ashrdi3"
11386 [(set (match_operand:DI 0 "shiftdi_operand" "")
11387 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11388 (match_operand:QI 2 "nonmemory_operand" "")))]
11390 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11392 (define_insn "*ashrdi3_63_rex64"
11393 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11394 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11395 (match_operand:DI 2 "const_int_operand" "i,i")))
11396 (clobber (reg:CC FLAGS_REG))]
11397 "TARGET_64BIT && INTVAL (operands[2]) == 63
11398 && (TARGET_USE_CLTD || optimize_size)
11399 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11402 sar{q}\t{%2, %0|%0, %2}"
11403 [(set_attr "type" "imovx,ishift")
11404 (set_attr "prefix_0f" "0,*")
11405 (set_attr "length_immediate" "0,*")
11406 (set_attr "modrm" "0,1")
11407 (set_attr "mode" "DI")])
11409 (define_insn "*ashrdi3_1_one_bit_rex64"
11410 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11411 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11412 (match_operand:QI 2 "const1_operand" "")))
11413 (clobber (reg:CC FLAGS_REG))]
11414 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11415 && (TARGET_SHIFT1 || optimize_size)"
11417 [(set_attr "type" "ishift")
11418 (set (attr "length")
11419 (if_then_else (match_operand:DI 0 "register_operand" "")
11421 (const_string "*")))])
11423 (define_insn "*ashrdi3_1_rex64"
11424 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11425 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11426 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11427 (clobber (reg:CC FLAGS_REG))]
11428 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11430 sar{q}\t{%2, %0|%0, %2}
11431 sar{q}\t{%b2, %0|%0, %b2}"
11432 [(set_attr "type" "ishift")
11433 (set_attr "mode" "DI")])
11435 ;; This pattern can't accept a variable shift count, since shifts by
11436 ;; zero don't affect the flags. We assume that shifts by constant
11437 ;; zero are optimized away.
11438 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11439 [(set (reg FLAGS_REG)
11441 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11442 (match_operand:QI 2 "const1_operand" ""))
11444 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11445 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11446 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11447 && (TARGET_SHIFT1 || optimize_size)
11448 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11450 [(set_attr "type" "ishift")
11451 (set (attr "length")
11452 (if_then_else (match_operand:DI 0 "register_operand" "")
11454 (const_string "*")))])
11456 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11457 [(set (reg FLAGS_REG)
11459 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11460 (match_operand:QI 2 "const1_operand" ""))
11462 (clobber (match_scratch:DI 0 "=r"))]
11463 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11464 && (TARGET_SHIFT1 || optimize_size)
11465 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11467 [(set_attr "type" "ishift")
11468 (set_attr "length" "2")])
11470 ;; This pattern can't accept a variable shift count, since shifts by
11471 ;; zero don't affect the flags. We assume that shifts by constant
11472 ;; zero are optimized away.
11473 (define_insn "*ashrdi3_cmp_rex64"
11474 [(set (reg FLAGS_REG)
11476 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11477 (match_operand:QI 2 "const_int_operand" "n"))
11479 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11480 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11481 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11482 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11484 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11485 "sar{q}\t{%2, %0|%0, %2}"
11486 [(set_attr "type" "ishift")
11487 (set_attr "mode" "DI")])
11489 (define_insn "*ashrdi3_cconly_rex64"
11490 [(set (reg FLAGS_REG)
11492 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11493 (match_operand:QI 2 "const_int_operand" "n"))
11495 (clobber (match_scratch:DI 0 "=r"))]
11496 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11497 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11499 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11500 "sar{q}\t{%2, %0|%0, %2}"
11501 [(set_attr "type" "ishift")
11502 (set_attr "mode" "DI")])
11504 (define_insn "*ashrdi3_1"
11505 [(set (match_operand:DI 0 "register_operand" "=r")
11506 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11507 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11508 (clobber (reg:CC FLAGS_REG))]
11511 [(set_attr "type" "multi")])
11513 ;; By default we don't ask for a scratch register, because when DImode
11514 ;; values are manipulated, registers are already at a premium. But if
11515 ;; we have one handy, we won't turn it away.
11517 [(match_scratch:SI 3 "r")
11518 (parallel [(set (match_operand:DI 0 "register_operand" "")
11519 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11520 (match_operand:QI 2 "nonmemory_operand" "")))
11521 (clobber (reg:CC FLAGS_REG))])
11523 "!TARGET_64BIT && TARGET_CMOVE"
11525 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11528 [(set (match_operand:DI 0 "register_operand" "")
11529 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11530 (match_operand:QI 2 "nonmemory_operand" "")))
11531 (clobber (reg:CC FLAGS_REG))]
11532 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11533 ? flow2_completed : reload_completed)"
11535 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11537 (define_insn "x86_shrd_1"
11538 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11539 (ior:SI (ashiftrt:SI (match_dup 0)
11540 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11541 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11542 (minus:QI (const_int 32) (match_dup 2)))))
11543 (clobber (reg:CC FLAGS_REG))]
11546 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11547 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11548 [(set_attr "type" "ishift")
11549 (set_attr "prefix_0f" "1")
11550 (set_attr "pent_pair" "np")
11551 (set_attr "mode" "SI")])
11553 (define_expand "x86_shift_adj_3"
11554 [(use (match_operand:SI 0 "register_operand" ""))
11555 (use (match_operand:SI 1 "register_operand" ""))
11556 (use (match_operand:QI 2 "register_operand" ""))]
11559 rtx label = gen_label_rtx ();
11562 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11564 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11565 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11566 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11567 gen_rtx_LABEL_REF (VOIDmode, label),
11569 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11570 JUMP_LABEL (tmp) = label;
11572 emit_move_insn (operands[0], operands[1]);
11573 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11575 emit_label (label);
11576 LABEL_NUSES (label) = 1;
11581 (define_insn "ashrsi3_31"
11582 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11583 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11584 (match_operand:SI 2 "const_int_operand" "i,i")))
11585 (clobber (reg:CC FLAGS_REG))]
11586 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11587 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11590 sar{l}\t{%2, %0|%0, %2}"
11591 [(set_attr "type" "imovx,ishift")
11592 (set_attr "prefix_0f" "0,*")
11593 (set_attr "length_immediate" "0,*")
11594 (set_attr "modrm" "0,1")
11595 (set_attr "mode" "SI")])
11597 (define_insn "*ashrsi3_31_zext"
11598 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11599 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11600 (match_operand:SI 2 "const_int_operand" "i,i"))))
11601 (clobber (reg:CC FLAGS_REG))]
11602 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11603 && INTVAL (operands[2]) == 31
11604 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11607 sar{l}\t{%2, %k0|%k0, %2}"
11608 [(set_attr "type" "imovx,ishift")
11609 (set_attr "prefix_0f" "0,*")
11610 (set_attr "length_immediate" "0,*")
11611 (set_attr "modrm" "0,1")
11612 (set_attr "mode" "SI")])
11614 (define_expand "ashrsi3"
11615 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11616 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11617 (match_operand:QI 2 "nonmemory_operand" "")))
11618 (clobber (reg:CC FLAGS_REG))]
11620 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11622 (define_insn "*ashrsi3_1_one_bit"
11623 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11624 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11625 (match_operand:QI 2 "const1_operand" "")))
11626 (clobber (reg:CC FLAGS_REG))]
11627 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11628 && (TARGET_SHIFT1 || optimize_size)"
11630 [(set_attr "type" "ishift")
11631 (set (attr "length")
11632 (if_then_else (match_operand:SI 0 "register_operand" "")
11634 (const_string "*")))])
11636 (define_insn "*ashrsi3_1_one_bit_zext"
11637 [(set (match_operand:DI 0 "register_operand" "=r")
11638 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11639 (match_operand:QI 2 "const1_operand" ""))))
11640 (clobber (reg:CC FLAGS_REG))]
11641 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11642 && (TARGET_SHIFT1 || optimize_size)"
11644 [(set_attr "type" "ishift")
11645 (set_attr "length" "2")])
11647 (define_insn "*ashrsi3_1"
11648 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11649 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11650 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11651 (clobber (reg:CC FLAGS_REG))]
11652 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11654 sar{l}\t{%2, %0|%0, %2}
11655 sar{l}\t{%b2, %0|%0, %b2}"
11656 [(set_attr "type" "ishift")
11657 (set_attr "mode" "SI")])
11659 (define_insn "*ashrsi3_1_zext"
11660 [(set (match_operand:DI 0 "register_operand" "=r,r")
11661 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11662 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11663 (clobber (reg:CC FLAGS_REG))]
11664 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11666 sar{l}\t{%2, %k0|%k0, %2}
11667 sar{l}\t{%b2, %k0|%k0, %b2}"
11668 [(set_attr "type" "ishift")
11669 (set_attr "mode" "SI")])
11671 ;; This pattern can't accept a variable shift count, since shifts by
11672 ;; zero don't affect the flags. We assume that shifts by constant
11673 ;; zero are optimized away.
11674 (define_insn "*ashrsi3_one_bit_cmp"
11675 [(set (reg FLAGS_REG)
11677 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11678 (match_operand:QI 2 "const1_operand" ""))
11680 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11681 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11682 "ix86_match_ccmode (insn, CCGOCmode)
11683 && (TARGET_SHIFT1 || optimize_size)
11684 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11686 [(set_attr "type" "ishift")
11687 (set (attr "length")
11688 (if_then_else (match_operand:SI 0 "register_operand" "")
11690 (const_string "*")))])
11692 (define_insn "*ashrsi3_one_bit_cconly"
11693 [(set (reg FLAGS_REG)
11695 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11696 (match_operand:QI 2 "const1_operand" ""))
11698 (clobber (match_scratch:SI 0 "=r"))]
11699 "ix86_match_ccmode (insn, CCGOCmode)
11700 && (TARGET_SHIFT1 || optimize_size)
11701 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11703 [(set_attr "type" "ishift")
11704 (set_attr "length" "2")])
11706 (define_insn "*ashrsi3_one_bit_cmp_zext"
11707 [(set (reg FLAGS_REG)
11709 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11710 (match_operand:QI 2 "const1_operand" ""))
11712 (set (match_operand:DI 0 "register_operand" "=r")
11713 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11714 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11715 && (TARGET_SHIFT1 || optimize_size)
11716 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11718 [(set_attr "type" "ishift")
11719 (set_attr "length" "2")])
11721 ;; This pattern can't accept a variable shift count, since shifts by
11722 ;; zero don't affect the flags. We assume that shifts by constant
11723 ;; zero are optimized away.
11724 (define_insn "*ashrsi3_cmp"
11725 [(set (reg FLAGS_REG)
11727 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11728 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11730 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11731 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11732 "ix86_match_ccmode (insn, CCGOCmode)
11733 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11735 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11736 "sar{l}\t{%2, %0|%0, %2}"
11737 [(set_attr "type" "ishift")
11738 (set_attr "mode" "SI")])
11740 (define_insn "*ashrsi3_cconly"
11741 [(set (reg FLAGS_REG)
11743 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11744 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11746 (clobber (match_scratch:SI 0 "=r"))]
11747 "ix86_match_ccmode (insn, CCGOCmode)
11748 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11750 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11751 "sar{l}\t{%2, %0|%0, %2}"
11752 [(set_attr "type" "ishift")
11753 (set_attr "mode" "SI")])
11755 (define_insn "*ashrsi3_cmp_zext"
11756 [(set (reg FLAGS_REG)
11758 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11759 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11761 (set (match_operand:DI 0 "register_operand" "=r")
11762 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11763 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11764 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11766 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11767 "sar{l}\t{%2, %k0|%k0, %2}"
11768 [(set_attr "type" "ishift")
11769 (set_attr "mode" "SI")])
11771 (define_expand "ashrhi3"
11772 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11773 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11774 (match_operand:QI 2 "nonmemory_operand" "")))
11775 (clobber (reg:CC FLAGS_REG))]
11776 "TARGET_HIMODE_MATH"
11777 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11779 (define_insn "*ashrhi3_1_one_bit"
11780 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11781 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11782 (match_operand:QI 2 "const1_operand" "")))
11783 (clobber (reg:CC FLAGS_REG))]
11784 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11785 && (TARGET_SHIFT1 || optimize_size)"
11787 [(set_attr "type" "ishift")
11788 (set (attr "length")
11789 (if_then_else (match_operand 0 "register_operand" "")
11791 (const_string "*")))])
11793 (define_insn "*ashrhi3_1"
11794 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11795 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11796 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11797 (clobber (reg:CC FLAGS_REG))]
11798 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11800 sar{w}\t{%2, %0|%0, %2}
11801 sar{w}\t{%b2, %0|%0, %b2}"
11802 [(set_attr "type" "ishift")
11803 (set_attr "mode" "HI")])
11805 ;; This pattern can't accept a variable shift count, since shifts by
11806 ;; zero don't affect the flags. We assume that shifts by constant
11807 ;; zero are optimized away.
11808 (define_insn "*ashrhi3_one_bit_cmp"
11809 [(set (reg FLAGS_REG)
11811 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11812 (match_operand:QI 2 "const1_operand" ""))
11814 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11815 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11816 "ix86_match_ccmode (insn, CCGOCmode)
11817 && (TARGET_SHIFT1 || optimize_size)
11818 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11820 [(set_attr "type" "ishift")
11821 (set (attr "length")
11822 (if_then_else (match_operand 0 "register_operand" "")
11824 (const_string "*")))])
11826 (define_insn "*ashrhi3_one_bit_cconly"
11827 [(set (reg FLAGS_REG)
11829 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11830 (match_operand:QI 2 "const1_operand" ""))
11832 (clobber (match_scratch:HI 0 "=r"))]
11833 "ix86_match_ccmode (insn, CCGOCmode)
11834 && (TARGET_SHIFT1 || optimize_size)
11835 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11837 [(set_attr "type" "ishift")
11838 (set_attr "length" "2")])
11840 ;; This pattern can't accept a variable shift count, since shifts by
11841 ;; zero don't affect the flags. We assume that shifts by constant
11842 ;; zero are optimized away.
11843 (define_insn "*ashrhi3_cmp"
11844 [(set (reg FLAGS_REG)
11846 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11847 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11849 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11850 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11851 "ix86_match_ccmode (insn, CCGOCmode)
11852 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11854 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11855 "sar{w}\t{%2, %0|%0, %2}"
11856 [(set_attr "type" "ishift")
11857 (set_attr "mode" "HI")])
11859 (define_insn "*ashrhi3_cconly"
11860 [(set (reg FLAGS_REG)
11862 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11863 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11865 (clobber (match_scratch:HI 0 "=r"))]
11866 "ix86_match_ccmode (insn, CCGOCmode)
11867 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11869 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11870 "sar{w}\t{%2, %0|%0, %2}"
11871 [(set_attr "type" "ishift")
11872 (set_attr "mode" "HI")])
11874 (define_expand "ashrqi3"
11875 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11876 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11877 (match_operand:QI 2 "nonmemory_operand" "")))
11878 (clobber (reg:CC FLAGS_REG))]
11879 "TARGET_QIMODE_MATH"
11880 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11882 (define_insn "*ashrqi3_1_one_bit"
11883 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11884 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11885 (match_operand:QI 2 "const1_operand" "")))
11886 (clobber (reg:CC FLAGS_REG))]
11887 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11888 && (TARGET_SHIFT1 || optimize_size)"
11890 [(set_attr "type" "ishift")
11891 (set (attr "length")
11892 (if_then_else (match_operand 0 "register_operand" "")
11894 (const_string "*")))])
11896 (define_insn "*ashrqi3_1_one_bit_slp"
11897 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11898 (ashiftrt:QI (match_dup 0)
11899 (match_operand:QI 1 "const1_operand" "")))
11900 (clobber (reg:CC FLAGS_REG))]
11901 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11902 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11903 && (TARGET_SHIFT1 || optimize_size)"
11905 [(set_attr "type" "ishift1")
11906 (set (attr "length")
11907 (if_then_else (match_operand 0 "register_operand" "")
11909 (const_string "*")))])
11911 (define_insn "*ashrqi3_1"
11912 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11913 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11914 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11915 (clobber (reg:CC FLAGS_REG))]
11916 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11918 sar{b}\t{%2, %0|%0, %2}
11919 sar{b}\t{%b2, %0|%0, %b2}"
11920 [(set_attr "type" "ishift")
11921 (set_attr "mode" "QI")])
11923 (define_insn "*ashrqi3_1_slp"
11924 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11925 (ashiftrt:QI (match_dup 0)
11926 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11927 (clobber (reg:CC FLAGS_REG))]
11928 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11929 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11931 sar{b}\t{%1, %0|%0, %1}
11932 sar{b}\t{%b1, %0|%0, %b1}"
11933 [(set_attr "type" "ishift1")
11934 (set_attr "mode" "QI")])
11936 ;; This pattern can't accept a variable shift count, since shifts by
11937 ;; zero don't affect the flags. We assume that shifts by constant
11938 ;; zero are optimized away.
11939 (define_insn "*ashrqi3_one_bit_cmp"
11940 [(set (reg FLAGS_REG)
11942 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11943 (match_operand:QI 2 "const1_operand" "I"))
11945 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11946 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11947 "ix86_match_ccmode (insn, CCGOCmode)
11948 && (TARGET_SHIFT1 || optimize_size)
11949 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11951 [(set_attr "type" "ishift")
11952 (set (attr "length")
11953 (if_then_else (match_operand 0 "register_operand" "")
11955 (const_string "*")))])
11957 (define_insn "*ashrqi3_one_bit_cconly"
11958 [(set (reg FLAGS_REG)
11960 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11961 (match_operand:QI 2 "const1_operand" "I"))
11963 (clobber (match_scratch:QI 0 "=q"))]
11964 "ix86_match_ccmode (insn, CCGOCmode)
11965 && (TARGET_SHIFT1 || optimize_size)
11966 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11968 [(set_attr "type" "ishift")
11969 (set_attr "length" "2")])
11971 ;; This pattern can't accept a variable shift count, since shifts by
11972 ;; zero don't affect the flags. We assume that shifts by constant
11973 ;; zero are optimized away.
11974 (define_insn "*ashrqi3_cmp"
11975 [(set (reg FLAGS_REG)
11977 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11978 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11980 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11981 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11982 "ix86_match_ccmode (insn, CCGOCmode)
11983 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11985 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11986 "sar{b}\t{%2, %0|%0, %2}"
11987 [(set_attr "type" "ishift")
11988 (set_attr "mode" "QI")])
11990 (define_insn "*ashrqi3_cconly"
11991 [(set (reg FLAGS_REG)
11993 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11994 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11996 (clobber (match_scratch:QI 0 "=q"))]
11997 "ix86_match_ccmode (insn, CCGOCmode)
11998 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12000 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12001 "sar{b}\t{%2, %0|%0, %2}"
12002 [(set_attr "type" "ishift")
12003 (set_attr "mode" "QI")])
12006 ;; Logical shift instructions
12008 ;; See comment above `ashldi3' about how this works.
12010 (define_expand "lshrti3"
12011 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12012 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12013 (match_operand:QI 2 "nonmemory_operand" "")))
12014 (clobber (reg:CC FLAGS_REG))])]
12017 if (! immediate_operand (operands[2], QImode))
12019 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12022 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12026 (define_insn "lshrti3_1"
12027 [(set (match_operand:TI 0 "register_operand" "=r")
12028 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12029 (match_operand:QI 2 "register_operand" "c")))
12030 (clobber (match_scratch:DI 3 "=&r"))
12031 (clobber (reg:CC FLAGS_REG))]
12034 [(set_attr "type" "multi")])
12036 (define_insn "*lshrti3_2"
12037 [(set (match_operand:TI 0 "register_operand" "=r")
12038 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12039 (match_operand:QI 2 "immediate_operand" "O")))
12040 (clobber (reg:CC FLAGS_REG))]
12043 [(set_attr "type" "multi")])
12046 [(set (match_operand:TI 0 "register_operand" "")
12047 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12048 (match_operand:QI 2 "register_operand" "")))
12049 (clobber (match_scratch:DI 3 ""))
12050 (clobber (reg:CC FLAGS_REG))]
12051 "TARGET_64BIT && reload_completed"
12053 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12056 [(set (match_operand:TI 0 "register_operand" "")
12057 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12058 (match_operand:QI 2 "immediate_operand" "")))
12059 (clobber (reg:CC FLAGS_REG))]
12060 "TARGET_64BIT && reload_completed"
12062 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12064 (define_expand "lshrdi3"
12065 [(set (match_operand:DI 0 "shiftdi_operand" "")
12066 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12067 (match_operand:QI 2 "nonmemory_operand" "")))]
12069 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12071 (define_insn "*lshrdi3_1_one_bit_rex64"
12072 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12073 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12074 (match_operand:QI 2 "const1_operand" "")))
12075 (clobber (reg:CC FLAGS_REG))]
12076 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12077 && (TARGET_SHIFT1 || optimize_size)"
12079 [(set_attr "type" "ishift")
12080 (set (attr "length")
12081 (if_then_else (match_operand:DI 0 "register_operand" "")
12083 (const_string "*")))])
12085 (define_insn "*lshrdi3_1_rex64"
12086 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12087 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12088 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12089 (clobber (reg:CC FLAGS_REG))]
12090 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12092 shr{q}\t{%2, %0|%0, %2}
12093 shr{q}\t{%b2, %0|%0, %b2}"
12094 [(set_attr "type" "ishift")
12095 (set_attr "mode" "DI")])
12097 ;; This pattern can't accept a variable shift count, since shifts by
12098 ;; zero don't affect the flags. We assume that shifts by constant
12099 ;; zero are optimized away.
12100 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12101 [(set (reg FLAGS_REG)
12103 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12104 (match_operand:QI 2 "const1_operand" ""))
12106 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12107 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12108 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12109 && (TARGET_SHIFT1 || optimize_size)
12110 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12112 [(set_attr "type" "ishift")
12113 (set (attr "length")
12114 (if_then_else (match_operand:DI 0 "register_operand" "")
12116 (const_string "*")))])
12118 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12119 [(set (reg FLAGS_REG)
12121 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12122 (match_operand:QI 2 "const1_operand" ""))
12124 (clobber (match_scratch:DI 0 "=r"))]
12125 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12126 && (TARGET_SHIFT1 || optimize_size)
12127 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12129 [(set_attr "type" "ishift")
12130 (set_attr "length" "2")])
12132 ;; This pattern can't accept a variable shift count, since shifts by
12133 ;; zero don't affect the flags. We assume that shifts by constant
12134 ;; zero are optimized away.
12135 (define_insn "*lshrdi3_cmp_rex64"
12136 [(set (reg FLAGS_REG)
12138 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12139 (match_operand:QI 2 "const_int_operand" "e"))
12141 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12142 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12143 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12144 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12146 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12147 "shr{q}\t{%2, %0|%0, %2}"
12148 [(set_attr "type" "ishift")
12149 (set_attr "mode" "DI")])
12151 (define_insn "*lshrdi3_cconly_rex64"
12152 [(set (reg FLAGS_REG)
12154 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12155 (match_operand:QI 2 "const_int_operand" "e"))
12157 (clobber (match_scratch:DI 0 "=r"))]
12158 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12159 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12161 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12162 "shr{q}\t{%2, %0|%0, %2}"
12163 [(set_attr "type" "ishift")
12164 (set_attr "mode" "DI")])
12166 (define_insn "*lshrdi3_1"
12167 [(set (match_operand:DI 0 "register_operand" "=r")
12168 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12169 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12170 (clobber (reg:CC FLAGS_REG))]
12173 [(set_attr "type" "multi")])
12175 ;; By default we don't ask for a scratch register, because when DImode
12176 ;; values are manipulated, registers are already at a premium. But if
12177 ;; we have one handy, we won't turn it away.
12179 [(match_scratch:SI 3 "r")
12180 (parallel [(set (match_operand:DI 0 "register_operand" "")
12181 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12182 (match_operand:QI 2 "nonmemory_operand" "")))
12183 (clobber (reg:CC FLAGS_REG))])
12185 "!TARGET_64BIT && TARGET_CMOVE"
12187 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12190 [(set (match_operand:DI 0 "register_operand" "")
12191 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12192 (match_operand:QI 2 "nonmemory_operand" "")))
12193 (clobber (reg:CC FLAGS_REG))]
12194 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12195 ? flow2_completed : reload_completed)"
12197 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12199 (define_expand "lshrsi3"
12200 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12201 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12202 (match_operand:QI 2 "nonmemory_operand" "")))
12203 (clobber (reg:CC FLAGS_REG))]
12205 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12207 (define_insn "*lshrsi3_1_one_bit"
12208 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12209 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12210 (match_operand:QI 2 "const1_operand" "")))
12211 (clobber (reg:CC FLAGS_REG))]
12212 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12213 && (TARGET_SHIFT1 || optimize_size)"
12215 [(set_attr "type" "ishift")
12216 (set (attr "length")
12217 (if_then_else (match_operand:SI 0 "register_operand" "")
12219 (const_string "*")))])
12221 (define_insn "*lshrsi3_1_one_bit_zext"
12222 [(set (match_operand:DI 0 "register_operand" "=r")
12223 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12224 (match_operand:QI 2 "const1_operand" "")))
12225 (clobber (reg:CC FLAGS_REG))]
12226 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12227 && (TARGET_SHIFT1 || optimize_size)"
12229 [(set_attr "type" "ishift")
12230 (set_attr "length" "2")])
12232 (define_insn "*lshrsi3_1"
12233 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12234 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12235 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12236 (clobber (reg:CC FLAGS_REG))]
12237 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12239 shr{l}\t{%2, %0|%0, %2}
12240 shr{l}\t{%b2, %0|%0, %b2}"
12241 [(set_attr "type" "ishift")
12242 (set_attr "mode" "SI")])
12244 (define_insn "*lshrsi3_1_zext"
12245 [(set (match_operand:DI 0 "register_operand" "=r,r")
12247 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12248 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12249 (clobber (reg:CC FLAGS_REG))]
12250 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12252 shr{l}\t{%2, %k0|%k0, %2}
12253 shr{l}\t{%b2, %k0|%k0, %b2}"
12254 [(set_attr "type" "ishift")
12255 (set_attr "mode" "SI")])
12257 ;; This pattern can't accept a variable shift count, since shifts by
12258 ;; zero don't affect the flags. We assume that shifts by constant
12259 ;; zero are optimized away.
12260 (define_insn "*lshrsi3_one_bit_cmp"
12261 [(set (reg FLAGS_REG)
12263 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12264 (match_operand:QI 2 "const1_operand" ""))
12266 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12267 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12268 "ix86_match_ccmode (insn, CCGOCmode)
12269 && (TARGET_SHIFT1 || optimize_size)
12270 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12272 [(set_attr "type" "ishift")
12273 (set (attr "length")
12274 (if_then_else (match_operand:SI 0 "register_operand" "")
12276 (const_string "*")))])
12278 (define_insn "*lshrsi3_one_bit_cconly"
12279 [(set (reg FLAGS_REG)
12281 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12282 (match_operand:QI 2 "const1_operand" ""))
12284 (clobber (match_scratch:SI 0 "=r"))]
12285 "ix86_match_ccmode (insn, CCGOCmode)
12286 && (TARGET_SHIFT1 || optimize_size)
12287 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12289 [(set_attr "type" "ishift")
12290 (set_attr "length" "2")])
12292 (define_insn "*lshrsi3_cmp_one_bit_zext"
12293 [(set (reg FLAGS_REG)
12295 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12296 (match_operand:QI 2 "const1_operand" ""))
12298 (set (match_operand:DI 0 "register_operand" "=r")
12299 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12300 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12301 && (TARGET_SHIFT1 || optimize_size)
12302 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12304 [(set_attr "type" "ishift")
12305 (set_attr "length" "2")])
12307 ;; This pattern can't accept a variable shift count, since shifts by
12308 ;; zero don't affect the flags. We assume that shifts by constant
12309 ;; zero are optimized away.
12310 (define_insn "*lshrsi3_cmp"
12311 [(set (reg FLAGS_REG)
12313 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12314 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12316 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12317 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12318 "ix86_match_ccmode (insn, CCGOCmode)
12319 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12321 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12322 "shr{l}\t{%2, %0|%0, %2}"
12323 [(set_attr "type" "ishift")
12324 (set_attr "mode" "SI")])
12326 (define_insn "*lshrsi3_cconly"
12327 [(set (reg FLAGS_REG)
12329 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12330 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12332 (clobber (match_scratch:SI 0 "=r"))]
12333 "ix86_match_ccmode (insn, CCGOCmode)
12334 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12336 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12337 "shr{l}\t{%2, %0|%0, %2}"
12338 [(set_attr "type" "ishift")
12339 (set_attr "mode" "SI")])
12341 (define_insn "*lshrsi3_cmp_zext"
12342 [(set (reg FLAGS_REG)
12344 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12345 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12347 (set (match_operand:DI 0 "register_operand" "=r")
12348 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12349 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12350 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12352 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12353 "shr{l}\t{%2, %k0|%k0, %2}"
12354 [(set_attr "type" "ishift")
12355 (set_attr "mode" "SI")])
12357 (define_expand "lshrhi3"
12358 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12359 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12360 (match_operand:QI 2 "nonmemory_operand" "")))
12361 (clobber (reg:CC FLAGS_REG))]
12362 "TARGET_HIMODE_MATH"
12363 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12365 (define_insn "*lshrhi3_1_one_bit"
12366 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12367 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "const1_operand" "")))
12369 (clobber (reg:CC FLAGS_REG))]
12370 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12371 && (TARGET_SHIFT1 || optimize_size)"
12373 [(set_attr "type" "ishift")
12374 (set (attr "length")
12375 (if_then_else (match_operand 0 "register_operand" "")
12377 (const_string "*")))])
12379 (define_insn "*lshrhi3_1"
12380 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12381 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12382 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12383 (clobber (reg:CC FLAGS_REG))]
12384 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12386 shr{w}\t{%2, %0|%0, %2}
12387 shr{w}\t{%b2, %0|%0, %b2}"
12388 [(set_attr "type" "ishift")
12389 (set_attr "mode" "HI")])
12391 ;; This pattern can't accept a variable shift count, since shifts by
12392 ;; zero don't affect the flags. We assume that shifts by constant
12393 ;; zero are optimized away.
12394 (define_insn "*lshrhi3_one_bit_cmp"
12395 [(set (reg FLAGS_REG)
12397 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12398 (match_operand:QI 2 "const1_operand" ""))
12400 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12401 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12402 "ix86_match_ccmode (insn, CCGOCmode)
12403 && (TARGET_SHIFT1 || optimize_size)
12404 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12406 [(set_attr "type" "ishift")
12407 (set (attr "length")
12408 (if_then_else (match_operand:SI 0 "register_operand" "")
12410 (const_string "*")))])
12412 (define_insn "*lshrhi3_one_bit_cconly"
12413 [(set (reg FLAGS_REG)
12415 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12416 (match_operand:QI 2 "const1_operand" ""))
12418 (clobber (match_scratch:HI 0 "=r"))]
12419 "ix86_match_ccmode (insn, CCGOCmode)
12420 && (TARGET_SHIFT1 || optimize_size)
12421 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12423 [(set_attr "type" "ishift")
12424 (set_attr "length" "2")])
12426 ;; This pattern can't accept a variable shift count, since shifts by
12427 ;; zero don't affect the flags. We assume that shifts by constant
12428 ;; zero are optimized away.
12429 (define_insn "*lshrhi3_cmp"
12430 [(set (reg FLAGS_REG)
12432 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12433 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12435 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12436 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12437 "ix86_match_ccmode (insn, CCGOCmode)
12438 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12440 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12441 "shr{w}\t{%2, %0|%0, %2}"
12442 [(set_attr "type" "ishift")
12443 (set_attr "mode" "HI")])
12445 (define_insn "*lshrhi3_cconly"
12446 [(set (reg FLAGS_REG)
12448 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12449 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12451 (clobber (match_scratch:HI 0 "=r"))]
12452 "ix86_match_ccmode (insn, CCGOCmode)
12453 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12455 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12456 "shr{w}\t{%2, %0|%0, %2}"
12457 [(set_attr "type" "ishift")
12458 (set_attr "mode" "HI")])
12460 (define_expand "lshrqi3"
12461 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12462 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12463 (match_operand:QI 2 "nonmemory_operand" "")))
12464 (clobber (reg:CC FLAGS_REG))]
12465 "TARGET_QIMODE_MATH"
12466 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12468 (define_insn "*lshrqi3_1_one_bit"
12469 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12470 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12471 (match_operand:QI 2 "const1_operand" "")))
12472 (clobber (reg:CC FLAGS_REG))]
12473 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12474 && (TARGET_SHIFT1 || optimize_size)"
12476 [(set_attr "type" "ishift")
12477 (set (attr "length")
12478 (if_then_else (match_operand 0 "register_operand" "")
12480 (const_string "*")))])
12482 (define_insn "*lshrqi3_1_one_bit_slp"
12483 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12484 (lshiftrt:QI (match_dup 0)
12485 (match_operand:QI 1 "const1_operand" "")))
12486 (clobber (reg:CC FLAGS_REG))]
12487 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12488 && (TARGET_SHIFT1 || optimize_size)"
12490 [(set_attr "type" "ishift1")
12491 (set (attr "length")
12492 (if_then_else (match_operand 0 "register_operand" "")
12494 (const_string "*")))])
12496 (define_insn "*lshrqi3_1"
12497 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12498 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12499 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12500 (clobber (reg:CC FLAGS_REG))]
12501 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12503 shr{b}\t{%2, %0|%0, %2}
12504 shr{b}\t{%b2, %0|%0, %b2}"
12505 [(set_attr "type" "ishift")
12506 (set_attr "mode" "QI")])
12508 (define_insn "*lshrqi3_1_slp"
12509 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12510 (lshiftrt:QI (match_dup 0)
12511 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12512 (clobber (reg:CC FLAGS_REG))]
12513 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12514 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12516 shr{b}\t{%1, %0|%0, %1}
12517 shr{b}\t{%b1, %0|%0, %b1}"
12518 [(set_attr "type" "ishift1")
12519 (set_attr "mode" "QI")])
12521 ;; This pattern can't accept a variable shift count, since shifts by
12522 ;; zero don't affect the flags. We assume that shifts by constant
12523 ;; zero are optimized away.
12524 (define_insn "*lshrqi2_one_bit_cmp"
12525 [(set (reg FLAGS_REG)
12527 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12528 (match_operand:QI 2 "const1_operand" ""))
12530 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12531 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12532 "ix86_match_ccmode (insn, CCGOCmode)
12533 && (TARGET_SHIFT1 || optimize_size)
12534 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12536 [(set_attr "type" "ishift")
12537 (set (attr "length")
12538 (if_then_else (match_operand:SI 0 "register_operand" "")
12540 (const_string "*")))])
12542 (define_insn "*lshrqi2_one_bit_cconly"
12543 [(set (reg FLAGS_REG)
12545 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12546 (match_operand:QI 2 "const1_operand" ""))
12548 (clobber (match_scratch:QI 0 "=q"))]
12549 "ix86_match_ccmode (insn, CCGOCmode)
12550 && (TARGET_SHIFT1 || optimize_size)
12551 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12553 [(set_attr "type" "ishift")
12554 (set_attr "length" "2")])
12556 ;; This pattern can't accept a variable shift count, since shifts by
12557 ;; zero don't affect the flags. We assume that shifts by constant
12558 ;; zero are optimized away.
12559 (define_insn "*lshrqi2_cmp"
12560 [(set (reg FLAGS_REG)
12562 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12563 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12565 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12566 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12567 "ix86_match_ccmode (insn, CCGOCmode)
12568 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12570 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12571 "shr{b}\t{%2, %0|%0, %2}"
12572 [(set_attr "type" "ishift")
12573 (set_attr "mode" "QI")])
12575 (define_insn "*lshrqi2_cconly"
12576 [(set (reg FLAGS_REG)
12578 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12579 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12581 (clobber (match_scratch:QI 0 "=q"))]
12582 "ix86_match_ccmode (insn, CCGOCmode)
12583 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12585 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12586 "shr{b}\t{%2, %0|%0, %2}"
12587 [(set_attr "type" "ishift")
12588 (set_attr "mode" "QI")])
12590 ;; Rotate instructions
12592 (define_expand "rotldi3"
12593 [(set (match_operand:DI 0 "shiftdi_operand" "")
12594 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12595 (match_operand:QI 2 "nonmemory_operand" "")))
12596 (clobber (reg:CC FLAGS_REG))]
12601 ix86_expand_binary_operator (ROTATE, DImode, operands);
12604 if (!const_1_to_31_operand (operands[2], VOIDmode))
12606 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12610 ;; Implement rotation using two double-precision shift instructions
12611 ;; and a scratch register.
12612 (define_insn_and_split "ix86_rotldi3"
12613 [(set (match_operand:DI 0 "register_operand" "=r")
12614 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12615 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12616 (clobber (reg:CC FLAGS_REG))
12617 (clobber (match_scratch:SI 3 "=&r"))]
12620 "&& reload_completed"
12621 [(set (match_dup 3) (match_dup 4))
12623 [(set (match_dup 4)
12624 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12625 (lshiftrt:SI (match_dup 5)
12626 (minus:QI (const_int 32) (match_dup 2)))))
12627 (clobber (reg:CC FLAGS_REG))])
12629 [(set (match_dup 5)
12630 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12631 (lshiftrt:SI (match_dup 3)
12632 (minus:QI (const_int 32) (match_dup 2)))))
12633 (clobber (reg:CC FLAGS_REG))])]
12634 "split_di (operands, 1, operands + 4, operands + 5);")
12636 (define_insn "*rotlsi3_1_one_bit_rex64"
12637 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12638 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12639 (match_operand:QI 2 "const1_operand" "")))
12640 (clobber (reg:CC FLAGS_REG))]
12641 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12642 && (TARGET_SHIFT1 || optimize_size)"
12644 [(set_attr "type" "rotate")
12645 (set (attr "length")
12646 (if_then_else (match_operand:DI 0 "register_operand" "")
12648 (const_string "*")))])
12650 (define_insn "*rotldi3_1_rex64"
12651 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12652 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12653 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12654 (clobber (reg:CC FLAGS_REG))]
12655 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12657 rol{q}\t{%2, %0|%0, %2}
12658 rol{q}\t{%b2, %0|%0, %b2}"
12659 [(set_attr "type" "rotate")
12660 (set_attr "mode" "DI")])
12662 (define_expand "rotlsi3"
12663 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12664 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12665 (match_operand:QI 2 "nonmemory_operand" "")))
12666 (clobber (reg:CC FLAGS_REG))]
12668 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12670 (define_insn "*rotlsi3_1_one_bit"
12671 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12672 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12673 (match_operand:QI 2 "const1_operand" "")))
12674 (clobber (reg:CC FLAGS_REG))]
12675 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12676 && (TARGET_SHIFT1 || optimize_size)"
12678 [(set_attr "type" "rotate")
12679 (set (attr "length")
12680 (if_then_else (match_operand:SI 0 "register_operand" "")
12682 (const_string "*")))])
12684 (define_insn "*rotlsi3_1_one_bit_zext"
12685 [(set (match_operand:DI 0 "register_operand" "=r")
12687 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12688 (match_operand:QI 2 "const1_operand" ""))))
12689 (clobber (reg:CC FLAGS_REG))]
12690 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12691 && (TARGET_SHIFT1 || optimize_size)"
12693 [(set_attr "type" "rotate")
12694 (set_attr "length" "2")])
12696 (define_insn "*rotlsi3_1"
12697 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12698 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12699 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12700 (clobber (reg:CC FLAGS_REG))]
12701 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12703 rol{l}\t{%2, %0|%0, %2}
12704 rol{l}\t{%b2, %0|%0, %b2}"
12705 [(set_attr "type" "rotate")
12706 (set_attr "mode" "SI")])
12708 (define_insn "*rotlsi3_1_zext"
12709 [(set (match_operand:DI 0 "register_operand" "=r,r")
12711 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12712 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12713 (clobber (reg:CC FLAGS_REG))]
12714 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12716 rol{l}\t{%2, %k0|%k0, %2}
12717 rol{l}\t{%b2, %k0|%k0, %b2}"
12718 [(set_attr "type" "rotate")
12719 (set_attr "mode" "SI")])
12721 (define_expand "rotlhi3"
12722 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12723 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12724 (match_operand:QI 2 "nonmemory_operand" "")))
12725 (clobber (reg:CC FLAGS_REG))]
12726 "TARGET_HIMODE_MATH"
12727 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12729 (define_insn "*rotlhi3_1_one_bit"
12730 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12731 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12732 (match_operand:QI 2 "const1_operand" "")))
12733 (clobber (reg:CC FLAGS_REG))]
12734 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12735 && (TARGET_SHIFT1 || optimize_size)"
12737 [(set_attr "type" "rotate")
12738 (set (attr "length")
12739 (if_then_else (match_operand 0 "register_operand" "")
12741 (const_string "*")))])
12743 (define_insn "*rotlhi3_1"
12744 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12745 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12746 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12747 (clobber (reg:CC FLAGS_REG))]
12748 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12750 rol{w}\t{%2, %0|%0, %2}
12751 rol{w}\t{%b2, %0|%0, %b2}"
12752 [(set_attr "type" "rotate")
12753 (set_attr "mode" "HI")])
12755 (define_expand "rotlqi3"
12756 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12757 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12758 (match_operand:QI 2 "nonmemory_operand" "")))
12759 (clobber (reg:CC FLAGS_REG))]
12760 "TARGET_QIMODE_MATH"
12761 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12763 (define_insn "*rotlqi3_1_one_bit_slp"
12764 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12765 (rotate:QI (match_dup 0)
12766 (match_operand:QI 1 "const1_operand" "")))
12767 (clobber (reg:CC FLAGS_REG))]
12768 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12769 && (TARGET_SHIFT1 || optimize_size)"
12771 [(set_attr "type" "rotate1")
12772 (set (attr "length")
12773 (if_then_else (match_operand 0 "register_operand" "")
12775 (const_string "*")))])
12777 (define_insn "*rotlqi3_1_one_bit"
12778 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12779 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12780 (match_operand:QI 2 "const1_operand" "")))
12781 (clobber (reg:CC FLAGS_REG))]
12782 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12783 && (TARGET_SHIFT1 || optimize_size)"
12785 [(set_attr "type" "rotate")
12786 (set (attr "length")
12787 (if_then_else (match_operand 0 "register_operand" "")
12789 (const_string "*")))])
12791 (define_insn "*rotlqi3_1_slp"
12792 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12793 (rotate:QI (match_dup 0)
12794 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12795 (clobber (reg:CC FLAGS_REG))]
12796 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12797 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12799 rol{b}\t{%1, %0|%0, %1}
12800 rol{b}\t{%b1, %0|%0, %b1}"
12801 [(set_attr "type" "rotate1")
12802 (set_attr "mode" "QI")])
12804 (define_insn "*rotlqi3_1"
12805 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12806 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12807 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12808 (clobber (reg:CC FLAGS_REG))]
12809 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12811 rol{b}\t{%2, %0|%0, %2}
12812 rol{b}\t{%b2, %0|%0, %b2}"
12813 [(set_attr "type" "rotate")
12814 (set_attr "mode" "QI")])
12816 (define_expand "rotrdi3"
12817 [(set (match_operand:DI 0 "shiftdi_operand" "")
12818 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12819 (match_operand:QI 2 "nonmemory_operand" "")))
12820 (clobber (reg:CC FLAGS_REG))]
12825 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12828 if (!const_1_to_31_operand (operands[2], VOIDmode))
12830 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12834 ;; Implement rotation using two double-precision shift instructions
12835 ;; and a scratch register.
12836 (define_insn_and_split "ix86_rotrdi3"
12837 [(set (match_operand:DI 0 "register_operand" "=r")
12838 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12839 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12840 (clobber (reg:CC FLAGS_REG))
12841 (clobber (match_scratch:SI 3 "=&r"))]
12844 "&& reload_completed"
12845 [(set (match_dup 3) (match_dup 4))
12847 [(set (match_dup 4)
12848 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12849 (ashift:SI (match_dup 5)
12850 (minus:QI (const_int 32) (match_dup 2)))))
12851 (clobber (reg:CC FLAGS_REG))])
12853 [(set (match_dup 5)
12854 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12855 (ashift:SI (match_dup 3)
12856 (minus:QI (const_int 32) (match_dup 2)))))
12857 (clobber (reg:CC FLAGS_REG))])]
12858 "split_di (operands, 1, operands + 4, operands + 5);")
12860 (define_insn "*rotrdi3_1_one_bit_rex64"
12861 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12862 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12863 (match_operand:QI 2 "const1_operand" "")))
12864 (clobber (reg:CC FLAGS_REG))]
12865 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12866 && (TARGET_SHIFT1 || optimize_size)"
12868 [(set_attr "type" "rotate")
12869 (set (attr "length")
12870 (if_then_else (match_operand:DI 0 "register_operand" "")
12872 (const_string "*")))])
12874 (define_insn "*rotrdi3_1_rex64"
12875 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12876 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12877 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12878 (clobber (reg:CC FLAGS_REG))]
12879 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12881 ror{q}\t{%2, %0|%0, %2}
12882 ror{q}\t{%b2, %0|%0, %b2}"
12883 [(set_attr "type" "rotate")
12884 (set_attr "mode" "DI")])
12886 (define_expand "rotrsi3"
12887 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12888 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12889 (match_operand:QI 2 "nonmemory_operand" "")))
12890 (clobber (reg:CC FLAGS_REG))]
12892 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12894 (define_insn "*rotrsi3_1_one_bit"
12895 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12896 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12897 (match_operand:QI 2 "const1_operand" "")))
12898 (clobber (reg:CC FLAGS_REG))]
12899 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12900 && (TARGET_SHIFT1 || optimize_size)"
12902 [(set_attr "type" "rotate")
12903 (set (attr "length")
12904 (if_then_else (match_operand:SI 0 "register_operand" "")
12906 (const_string "*")))])
12908 (define_insn "*rotrsi3_1_one_bit_zext"
12909 [(set (match_operand:DI 0 "register_operand" "=r")
12911 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12912 (match_operand:QI 2 "const1_operand" ""))))
12913 (clobber (reg:CC FLAGS_REG))]
12914 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12915 && (TARGET_SHIFT1 || optimize_size)"
12917 [(set_attr "type" "rotate")
12918 (set (attr "length")
12919 (if_then_else (match_operand:SI 0 "register_operand" "")
12921 (const_string "*")))])
12923 (define_insn "*rotrsi3_1"
12924 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12925 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12926 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12927 (clobber (reg:CC FLAGS_REG))]
12928 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12930 ror{l}\t{%2, %0|%0, %2}
12931 ror{l}\t{%b2, %0|%0, %b2}"
12932 [(set_attr "type" "rotate")
12933 (set_attr "mode" "SI")])
12935 (define_insn "*rotrsi3_1_zext"
12936 [(set (match_operand:DI 0 "register_operand" "=r,r")
12938 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12939 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12940 (clobber (reg:CC FLAGS_REG))]
12941 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12943 ror{l}\t{%2, %k0|%k0, %2}
12944 ror{l}\t{%b2, %k0|%k0, %b2}"
12945 [(set_attr "type" "rotate")
12946 (set_attr "mode" "SI")])
12948 (define_expand "rotrhi3"
12949 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12950 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12951 (match_operand:QI 2 "nonmemory_operand" "")))
12952 (clobber (reg:CC FLAGS_REG))]
12953 "TARGET_HIMODE_MATH"
12954 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12956 (define_insn "*rotrhi3_one_bit"
12957 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12958 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12959 (match_operand:QI 2 "const1_operand" "")))
12960 (clobber (reg:CC FLAGS_REG))]
12961 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12962 && (TARGET_SHIFT1 || optimize_size)"
12964 [(set_attr "type" "rotate")
12965 (set (attr "length")
12966 (if_then_else (match_operand 0 "register_operand" "")
12968 (const_string "*")))])
12970 (define_insn "*rotrhi3"
12971 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12972 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12973 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12974 (clobber (reg:CC FLAGS_REG))]
12975 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12977 ror{w}\t{%2, %0|%0, %2}
12978 ror{w}\t{%b2, %0|%0, %b2}"
12979 [(set_attr "type" "rotate")
12980 (set_attr "mode" "HI")])
12982 (define_expand "rotrqi3"
12983 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12984 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12985 (match_operand:QI 2 "nonmemory_operand" "")))
12986 (clobber (reg:CC FLAGS_REG))]
12987 "TARGET_QIMODE_MATH"
12988 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12990 (define_insn "*rotrqi3_1_one_bit"
12991 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12992 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12993 (match_operand:QI 2 "const1_operand" "")))
12994 (clobber (reg:CC FLAGS_REG))]
12995 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12996 && (TARGET_SHIFT1 || optimize_size)"
12998 [(set_attr "type" "rotate")
12999 (set (attr "length")
13000 (if_then_else (match_operand 0 "register_operand" "")
13002 (const_string "*")))])
13004 (define_insn "*rotrqi3_1_one_bit_slp"
13005 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13006 (rotatert:QI (match_dup 0)
13007 (match_operand:QI 1 "const1_operand" "")))
13008 (clobber (reg:CC FLAGS_REG))]
13009 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13010 && (TARGET_SHIFT1 || optimize_size)"
13012 [(set_attr "type" "rotate1")
13013 (set (attr "length")
13014 (if_then_else (match_operand 0 "register_operand" "")
13016 (const_string "*")))])
13018 (define_insn "*rotrqi3_1"
13019 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13020 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13021 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13022 (clobber (reg:CC FLAGS_REG))]
13023 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13025 ror{b}\t{%2, %0|%0, %2}
13026 ror{b}\t{%b2, %0|%0, %b2}"
13027 [(set_attr "type" "rotate")
13028 (set_attr "mode" "QI")])
13030 (define_insn "*rotrqi3_1_slp"
13031 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13032 (rotatert:QI (match_dup 0)
13033 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13034 (clobber (reg:CC FLAGS_REG))]
13035 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13036 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13038 ror{b}\t{%1, %0|%0, %1}
13039 ror{b}\t{%b1, %0|%0, %b1}"
13040 [(set_attr "type" "rotate1")
13041 (set_attr "mode" "QI")])
13043 ;; Bit set / bit test instructions
13045 (define_expand "extv"
13046 [(set (match_operand:SI 0 "register_operand" "")
13047 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13048 (match_operand:SI 2 "const8_operand" "")
13049 (match_operand:SI 3 "const8_operand" "")))]
13052 /* Handle extractions from %ah et al. */
13053 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13056 /* From mips.md: extract_bit_field doesn't verify that our source
13057 matches the predicate, so check it again here. */
13058 if (! ext_register_operand (operands[1], VOIDmode))
13062 (define_expand "extzv"
13063 [(set (match_operand:SI 0 "register_operand" "")
13064 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13065 (match_operand:SI 2 "const8_operand" "")
13066 (match_operand:SI 3 "const8_operand" "")))]
13069 /* Handle extractions from %ah et al. */
13070 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13073 /* From mips.md: extract_bit_field doesn't verify that our source
13074 matches the predicate, so check it again here. */
13075 if (! ext_register_operand (operands[1], VOIDmode))
13079 (define_expand "insv"
13080 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13081 (match_operand 1 "const8_operand" "")
13082 (match_operand 2 "const8_operand" ""))
13083 (match_operand 3 "register_operand" ""))]
13086 /* Handle insertions to %ah et al. */
13087 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13090 /* From mips.md: insert_bit_field doesn't verify that our source
13091 matches the predicate, so check it again here. */
13092 if (! ext_register_operand (operands[0], VOIDmode))
13096 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13098 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13103 ;; %%% bts, btr, btc, bt.
13104 ;; In general these instructions are *slow* when applied to memory,
13105 ;; since they enforce atomic operation. When applied to registers,
13106 ;; it depends on the cpu implementation. They're never faster than
13107 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13108 ;; no point. But in 64-bit, we can't hold the relevant immediates
13109 ;; within the instruction itself, so operating on bits in the high
13110 ;; 32-bits of a register becomes easier.
13112 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13113 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13114 ;; negdf respectively, so they can never be disabled entirely.
13116 (define_insn "*btsq"
13117 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13119 (match_operand:DI 1 "const_0_to_63_operand" ""))
13121 (clobber (reg:CC FLAGS_REG))]
13122 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13124 [(set_attr "type" "alu1")])
13126 (define_insn "*btrq"
13127 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13129 (match_operand:DI 1 "const_0_to_63_operand" ""))
13131 (clobber (reg:CC FLAGS_REG))]
13132 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13134 [(set_attr "type" "alu1")])
13136 (define_insn "*btcq"
13137 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13139 (match_operand:DI 1 "const_0_to_63_operand" ""))
13140 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13141 (clobber (reg:CC FLAGS_REG))]
13142 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13144 [(set_attr "type" "alu1")])
13146 ;; Allow Nocona to avoid these instructions if a register is available.
13149 [(match_scratch:DI 2 "r")
13150 (parallel [(set (zero_extract:DI
13151 (match_operand:DI 0 "register_operand" "")
13153 (match_operand:DI 1 "const_0_to_63_operand" ""))
13155 (clobber (reg:CC FLAGS_REG))])]
13156 "TARGET_64BIT && !TARGET_USE_BT"
13159 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13162 if (HOST_BITS_PER_WIDE_INT >= 64)
13163 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13164 else if (i < HOST_BITS_PER_WIDE_INT)
13165 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13167 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13169 op1 = immed_double_const (lo, hi, DImode);
13172 emit_move_insn (operands[2], op1);
13176 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13181 [(match_scratch:DI 2 "r")
13182 (parallel [(set (zero_extract:DI
13183 (match_operand:DI 0 "register_operand" "")
13185 (match_operand:DI 1 "const_0_to_63_operand" ""))
13187 (clobber (reg:CC FLAGS_REG))])]
13188 "TARGET_64BIT && !TARGET_USE_BT"
13191 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13194 if (HOST_BITS_PER_WIDE_INT >= 64)
13195 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13196 else if (i < HOST_BITS_PER_WIDE_INT)
13197 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13199 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13201 op1 = immed_double_const (~lo, ~hi, DImode);
13204 emit_move_insn (operands[2], op1);
13208 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13213 [(match_scratch:DI 2 "r")
13214 (parallel [(set (zero_extract:DI
13215 (match_operand:DI 0 "register_operand" "")
13217 (match_operand:DI 1 "const_0_to_63_operand" ""))
13218 (not:DI (zero_extract:DI
13219 (match_dup 0) (const_int 1) (match_dup 1))))
13220 (clobber (reg:CC FLAGS_REG))])]
13221 "TARGET_64BIT && !TARGET_USE_BT"
13224 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13227 if (HOST_BITS_PER_WIDE_INT >= 64)
13228 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13229 else if (i < HOST_BITS_PER_WIDE_INT)
13230 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13232 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13234 op1 = immed_double_const (lo, hi, DImode);
13237 emit_move_insn (operands[2], op1);
13241 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13245 ;; Store-flag instructions.
13247 ;; For all sCOND expanders, also expand the compare or test insn that
13248 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13250 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13251 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13252 ;; way, which can later delete the movzx if only QImode is needed.
13254 (define_expand "seq"
13255 [(set (match_operand:QI 0 "register_operand" "")
13256 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13258 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13260 (define_expand "sne"
13261 [(set (match_operand:QI 0 "register_operand" "")
13262 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13264 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13266 (define_expand "sgt"
13267 [(set (match_operand:QI 0 "register_operand" "")
13268 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13270 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13272 (define_expand "sgtu"
13273 [(set (match_operand:QI 0 "register_operand" "")
13274 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13276 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13278 (define_expand "slt"
13279 [(set (match_operand:QI 0 "register_operand" "")
13280 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13282 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13284 (define_expand "sltu"
13285 [(set (match_operand:QI 0 "register_operand" "")
13286 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13288 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13290 (define_expand "sge"
13291 [(set (match_operand:QI 0 "register_operand" "")
13292 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13294 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13296 (define_expand "sgeu"
13297 [(set (match_operand:QI 0 "register_operand" "")
13298 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13300 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13302 (define_expand "sle"
13303 [(set (match_operand:QI 0 "register_operand" "")
13304 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13306 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13308 (define_expand "sleu"
13309 [(set (match_operand:QI 0 "register_operand" "")
13310 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13312 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13314 (define_expand "sunordered"
13315 [(set (match_operand:QI 0 "register_operand" "")
13316 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13317 "TARGET_80387 || TARGET_SSE"
13318 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13320 (define_expand "sordered"
13321 [(set (match_operand:QI 0 "register_operand" "")
13322 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13324 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13326 (define_expand "suneq"
13327 [(set (match_operand:QI 0 "register_operand" "")
13328 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13329 "TARGET_80387 || TARGET_SSE"
13330 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13332 (define_expand "sunge"
13333 [(set (match_operand:QI 0 "register_operand" "")
13334 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13335 "TARGET_80387 || TARGET_SSE"
13336 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13338 (define_expand "sungt"
13339 [(set (match_operand:QI 0 "register_operand" "")
13340 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13341 "TARGET_80387 || TARGET_SSE"
13342 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13344 (define_expand "sunle"
13345 [(set (match_operand:QI 0 "register_operand" "")
13346 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13347 "TARGET_80387 || TARGET_SSE"
13348 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13350 (define_expand "sunlt"
13351 [(set (match_operand:QI 0 "register_operand" "")
13352 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13353 "TARGET_80387 || TARGET_SSE"
13354 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13356 (define_expand "sltgt"
13357 [(set (match_operand:QI 0 "register_operand" "")
13358 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13359 "TARGET_80387 || TARGET_SSE"
13360 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13362 (define_insn "*setcc_1"
13363 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13364 (match_operator:QI 1 "ix86_comparison_operator"
13365 [(reg FLAGS_REG) (const_int 0)]))]
13368 [(set_attr "type" "setcc")
13369 (set_attr "mode" "QI")])
13371 (define_insn "*setcc_2"
13372 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13373 (match_operator:QI 1 "ix86_comparison_operator"
13374 [(reg FLAGS_REG) (const_int 0)]))]
13377 [(set_attr "type" "setcc")
13378 (set_attr "mode" "QI")])
13380 ;; In general it is not safe to assume too much about CCmode registers,
13381 ;; so simplify-rtx stops when it sees a second one. Under certain
13382 ;; conditions this is safe on x86, so help combine not create
13389 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13390 (ne:QI (match_operator 1 "ix86_comparison_operator"
13391 [(reg FLAGS_REG) (const_int 0)])
13394 [(set (match_dup 0) (match_dup 1))]
13396 PUT_MODE (operands[1], QImode);
13400 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13401 (ne:QI (match_operator 1 "ix86_comparison_operator"
13402 [(reg FLAGS_REG) (const_int 0)])
13405 [(set (match_dup 0) (match_dup 1))]
13407 PUT_MODE (operands[1], QImode);
13411 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13412 (eq:QI (match_operator 1 "ix86_comparison_operator"
13413 [(reg FLAGS_REG) (const_int 0)])
13416 [(set (match_dup 0) (match_dup 1))]
13418 rtx new_op1 = copy_rtx (operands[1]);
13419 operands[1] = new_op1;
13420 PUT_MODE (new_op1, QImode);
13421 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13422 GET_MODE (XEXP (new_op1, 0))));
13424 /* Make sure that (a) the CCmode we have for the flags is strong
13425 enough for the reversed compare or (b) we have a valid FP compare. */
13426 if (! ix86_comparison_operator (new_op1, VOIDmode))
13431 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13432 (eq:QI (match_operator 1 "ix86_comparison_operator"
13433 [(reg FLAGS_REG) (const_int 0)])
13436 [(set (match_dup 0) (match_dup 1))]
13438 rtx new_op1 = copy_rtx (operands[1]);
13439 operands[1] = new_op1;
13440 PUT_MODE (new_op1, QImode);
13441 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13442 GET_MODE (XEXP (new_op1, 0))));
13444 /* Make sure that (a) the CCmode we have for the flags is strong
13445 enough for the reversed compare or (b) we have a valid FP compare. */
13446 if (! ix86_comparison_operator (new_op1, VOIDmode))
13450 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13451 ;; subsequent logical operations are used to imitate conditional moves.
13452 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13455 (define_insn "*sse_setccsf"
13456 [(set (match_operand:SF 0 "register_operand" "=x")
13457 (match_operator:SF 1 "sse_comparison_operator"
13458 [(match_operand:SF 2 "register_operand" "0")
13459 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13461 "cmp%D1ss\t{%3, %0|%0, %3}"
13462 [(set_attr "type" "ssecmp")
13463 (set_attr "mode" "SF")])
13465 (define_insn "*sse_setccdf"
13466 [(set (match_operand:DF 0 "register_operand" "=Y")
13467 (match_operator:DF 1 "sse_comparison_operator"
13468 [(match_operand:DF 2 "register_operand" "0")
13469 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13471 "cmp%D1sd\t{%3, %0|%0, %3}"
13472 [(set_attr "type" "ssecmp")
13473 (set_attr "mode" "DF")])
13475 ;; Basic conditional jump instructions.
13476 ;; We ignore the overflow flag for signed branch instructions.
13478 ;; For all bCOND expanders, also expand the compare or test insn that
13479 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13481 (define_expand "beq"
13483 (if_then_else (match_dup 1)
13484 (label_ref (match_operand 0 "" ""))
13487 "ix86_expand_branch (EQ, operands[0]); DONE;")
13489 (define_expand "bne"
13491 (if_then_else (match_dup 1)
13492 (label_ref (match_operand 0 "" ""))
13495 "ix86_expand_branch (NE, operands[0]); DONE;")
13497 (define_expand "bgt"
13499 (if_then_else (match_dup 1)
13500 (label_ref (match_operand 0 "" ""))
13503 "ix86_expand_branch (GT, operands[0]); DONE;")
13505 (define_expand "bgtu"
13507 (if_then_else (match_dup 1)
13508 (label_ref (match_operand 0 "" ""))
13511 "ix86_expand_branch (GTU, operands[0]); DONE;")
13513 (define_expand "blt"
13515 (if_then_else (match_dup 1)
13516 (label_ref (match_operand 0 "" ""))
13519 "ix86_expand_branch (LT, operands[0]); DONE;")
13521 (define_expand "bltu"
13523 (if_then_else (match_dup 1)
13524 (label_ref (match_operand 0 "" ""))
13527 "ix86_expand_branch (LTU, operands[0]); DONE;")
13529 (define_expand "bge"
13531 (if_then_else (match_dup 1)
13532 (label_ref (match_operand 0 "" ""))
13535 "ix86_expand_branch (GE, operands[0]); DONE;")
13537 (define_expand "bgeu"
13539 (if_then_else (match_dup 1)
13540 (label_ref (match_operand 0 "" ""))
13543 "ix86_expand_branch (GEU, operands[0]); DONE;")
13545 (define_expand "ble"
13547 (if_then_else (match_dup 1)
13548 (label_ref (match_operand 0 "" ""))
13551 "ix86_expand_branch (LE, operands[0]); DONE;")
13553 (define_expand "bleu"
13555 (if_then_else (match_dup 1)
13556 (label_ref (match_operand 0 "" ""))
13559 "ix86_expand_branch (LEU, operands[0]); DONE;")
13561 (define_expand "bunordered"
13563 (if_then_else (match_dup 1)
13564 (label_ref (match_operand 0 "" ""))
13566 "TARGET_80387 || TARGET_SSE_MATH"
13567 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13569 (define_expand "bordered"
13571 (if_then_else (match_dup 1)
13572 (label_ref (match_operand 0 "" ""))
13574 "TARGET_80387 || TARGET_SSE_MATH"
13575 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13577 (define_expand "buneq"
13579 (if_then_else (match_dup 1)
13580 (label_ref (match_operand 0 "" ""))
13582 "TARGET_80387 || TARGET_SSE_MATH"
13583 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13585 (define_expand "bunge"
13587 (if_then_else (match_dup 1)
13588 (label_ref (match_operand 0 "" ""))
13590 "TARGET_80387 || TARGET_SSE_MATH"
13591 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13593 (define_expand "bungt"
13595 (if_then_else (match_dup 1)
13596 (label_ref (match_operand 0 "" ""))
13598 "TARGET_80387 || TARGET_SSE_MATH"
13599 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13601 (define_expand "bunle"
13603 (if_then_else (match_dup 1)
13604 (label_ref (match_operand 0 "" ""))
13606 "TARGET_80387 || TARGET_SSE_MATH"
13607 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13609 (define_expand "bunlt"
13611 (if_then_else (match_dup 1)
13612 (label_ref (match_operand 0 "" ""))
13614 "TARGET_80387 || TARGET_SSE_MATH"
13615 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13617 (define_expand "bltgt"
13619 (if_then_else (match_dup 1)
13620 (label_ref (match_operand 0 "" ""))
13622 "TARGET_80387 || TARGET_SSE_MATH"
13623 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13625 (define_insn "*jcc_1"
13627 (if_then_else (match_operator 1 "ix86_comparison_operator"
13628 [(reg FLAGS_REG) (const_int 0)])
13629 (label_ref (match_operand 0 "" ""))
13633 [(set_attr "type" "ibr")
13634 (set_attr "modrm" "0")
13635 (set (attr "length")
13636 (if_then_else (and (ge (minus (match_dup 0) (pc))
13638 (lt (minus (match_dup 0) (pc))
13643 (define_insn "*jcc_2"
13645 (if_then_else (match_operator 1 "ix86_comparison_operator"
13646 [(reg FLAGS_REG) (const_int 0)])
13648 (label_ref (match_operand 0 "" ""))))]
13651 [(set_attr "type" "ibr")
13652 (set_attr "modrm" "0")
13653 (set (attr "length")
13654 (if_then_else (and (ge (minus (match_dup 0) (pc))
13656 (lt (minus (match_dup 0) (pc))
13661 ;; In general it is not safe to assume too much about CCmode registers,
13662 ;; so simplify-rtx stops when it sees a second one. Under certain
13663 ;; conditions this is safe on x86, so help combine not create
13671 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13672 [(reg FLAGS_REG) (const_int 0)])
13674 (label_ref (match_operand 1 "" ""))
13678 (if_then_else (match_dup 0)
13679 (label_ref (match_dup 1))
13682 PUT_MODE (operands[0], VOIDmode);
13687 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13688 [(reg FLAGS_REG) (const_int 0)])
13690 (label_ref (match_operand 1 "" ""))
13694 (if_then_else (match_dup 0)
13695 (label_ref (match_dup 1))
13698 rtx new_op0 = copy_rtx (operands[0]);
13699 operands[0] = new_op0;
13700 PUT_MODE (new_op0, VOIDmode);
13701 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13702 GET_MODE (XEXP (new_op0, 0))));
13704 /* Make sure that (a) the CCmode we have for the flags is strong
13705 enough for the reversed compare or (b) we have a valid FP compare. */
13706 if (! ix86_comparison_operator (new_op0, VOIDmode))
13710 ;; Define combination compare-and-branch fp compare instructions to use
13711 ;; during early optimization. Splitting the operation apart early makes
13712 ;; for bad code when we want to reverse the operation.
13714 (define_insn "*fp_jcc_1_mixed"
13716 (if_then_else (match_operator 0 "comparison_operator"
13717 [(match_operand 1 "register_operand" "f,x")
13718 (match_operand 2 "nonimmediate_operand" "f,xm")])
13719 (label_ref (match_operand 3 "" ""))
13721 (clobber (reg:CCFP FPSR_REG))
13722 (clobber (reg:CCFP FLAGS_REG))]
13723 "TARGET_MIX_SSE_I387
13724 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13725 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13726 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13729 (define_insn "*fp_jcc_1_sse"
13731 (if_then_else (match_operator 0 "comparison_operator"
13732 [(match_operand 1 "register_operand" "x")
13733 (match_operand 2 "nonimmediate_operand" "xm")])
13734 (label_ref (match_operand 3 "" ""))
13736 (clobber (reg:CCFP FPSR_REG))
13737 (clobber (reg:CCFP FLAGS_REG))]
13739 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13740 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13741 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13744 (define_insn "*fp_jcc_1_387"
13746 (if_then_else (match_operator 0 "comparison_operator"
13747 [(match_operand 1 "register_operand" "f")
13748 (match_operand 2 "register_operand" "f")])
13749 (label_ref (match_operand 3 "" ""))
13751 (clobber (reg:CCFP FPSR_REG))
13752 (clobber (reg:CCFP FLAGS_REG))]
13753 "TARGET_CMOVE && TARGET_80387
13754 && FLOAT_MODE_P (GET_MODE (operands[1]))
13755 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13756 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13759 (define_insn "*fp_jcc_2_mixed"
13761 (if_then_else (match_operator 0 "comparison_operator"
13762 [(match_operand 1 "register_operand" "f,x")
13763 (match_operand 2 "nonimmediate_operand" "f,xm")])
13765 (label_ref (match_operand 3 "" ""))))
13766 (clobber (reg:CCFP FPSR_REG))
13767 (clobber (reg:CCFP FLAGS_REG))]
13768 "TARGET_MIX_SSE_I387
13769 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13770 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13771 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13774 (define_insn "*fp_jcc_2_sse"
13776 (if_then_else (match_operator 0 "comparison_operator"
13777 [(match_operand 1 "register_operand" "x")
13778 (match_operand 2 "nonimmediate_operand" "xm")])
13780 (label_ref (match_operand 3 "" ""))))
13781 (clobber (reg:CCFP FPSR_REG))
13782 (clobber (reg:CCFP FLAGS_REG))]
13784 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13785 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13786 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13789 (define_insn "*fp_jcc_2_387"
13791 (if_then_else (match_operator 0 "comparison_operator"
13792 [(match_operand 1 "register_operand" "f")
13793 (match_operand 2 "register_operand" "f")])
13795 (label_ref (match_operand 3 "" ""))))
13796 (clobber (reg:CCFP FPSR_REG))
13797 (clobber (reg:CCFP FLAGS_REG))]
13798 "TARGET_CMOVE && TARGET_80387
13799 && FLOAT_MODE_P (GET_MODE (operands[1]))
13800 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13801 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13804 (define_insn "*fp_jcc_3_387"
13806 (if_then_else (match_operator 0 "comparison_operator"
13807 [(match_operand 1 "register_operand" "f")
13808 (match_operand 2 "nonimmediate_operand" "fm")])
13809 (label_ref (match_operand 3 "" ""))
13811 (clobber (reg:CCFP FPSR_REG))
13812 (clobber (reg:CCFP FLAGS_REG))
13813 (clobber (match_scratch:HI 4 "=a"))]
13815 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13816 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13817 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13818 && SELECT_CC_MODE (GET_CODE (operands[0]),
13819 operands[1], operands[2]) == CCFPmode
13820 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13823 (define_insn "*fp_jcc_4_387"
13825 (if_then_else (match_operator 0 "comparison_operator"
13826 [(match_operand 1 "register_operand" "f")
13827 (match_operand 2 "nonimmediate_operand" "fm")])
13829 (label_ref (match_operand 3 "" ""))))
13830 (clobber (reg:CCFP FPSR_REG))
13831 (clobber (reg:CCFP FLAGS_REG))
13832 (clobber (match_scratch:HI 4 "=a"))]
13834 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13835 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13836 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13837 && SELECT_CC_MODE (GET_CODE (operands[0]),
13838 operands[1], operands[2]) == CCFPmode
13839 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13842 (define_insn "*fp_jcc_5_387"
13844 (if_then_else (match_operator 0 "comparison_operator"
13845 [(match_operand 1 "register_operand" "f")
13846 (match_operand 2 "register_operand" "f")])
13847 (label_ref (match_operand 3 "" ""))
13849 (clobber (reg:CCFP FPSR_REG))
13850 (clobber (reg:CCFP FLAGS_REG))
13851 (clobber (match_scratch:HI 4 "=a"))]
13853 && FLOAT_MODE_P (GET_MODE (operands[1]))
13854 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13855 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13858 (define_insn "*fp_jcc_6_387"
13860 (if_then_else (match_operator 0 "comparison_operator"
13861 [(match_operand 1 "register_operand" "f")
13862 (match_operand 2 "register_operand" "f")])
13864 (label_ref (match_operand 3 "" ""))))
13865 (clobber (reg:CCFP FPSR_REG))
13866 (clobber (reg:CCFP FLAGS_REG))
13867 (clobber (match_scratch:HI 4 "=a"))]
13869 && FLOAT_MODE_P (GET_MODE (operands[1]))
13870 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13871 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13874 (define_insn "*fp_jcc_7_387"
13876 (if_then_else (match_operator 0 "comparison_operator"
13877 [(match_operand 1 "register_operand" "f")
13878 (match_operand 2 "const0_operand" "X")])
13879 (label_ref (match_operand 3 "" ""))
13881 (clobber (reg:CCFP FPSR_REG))
13882 (clobber (reg:CCFP FLAGS_REG))
13883 (clobber (match_scratch:HI 4 "=a"))]
13885 && FLOAT_MODE_P (GET_MODE (operands[1]))
13886 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13887 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13888 && SELECT_CC_MODE (GET_CODE (operands[0]),
13889 operands[1], operands[2]) == CCFPmode
13890 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13893 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13894 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13895 ;; with a precedence over other operators and is always put in the first
13896 ;; place. Swap condition and operands to match ficom instruction.
13898 (define_insn "*fp_jcc_8<mode>_387"
13900 (if_then_else (match_operator 0 "comparison_operator"
13901 [(match_operator 1 "float_operator"
13902 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13903 (match_operand 3 "register_operand" "f,f")])
13904 (label_ref (match_operand 4 "" ""))
13906 (clobber (reg:CCFP FPSR_REG))
13907 (clobber (reg:CCFP FLAGS_REG))
13908 (clobber (match_scratch:HI 5 "=a,a"))]
13909 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13910 && FLOAT_MODE_P (GET_MODE (operands[3]))
13911 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13912 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13913 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13914 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13919 (if_then_else (match_operator 0 "comparison_operator"
13920 [(match_operand 1 "register_operand" "")
13921 (match_operand 2 "nonimmediate_operand" "")])
13922 (match_operand 3 "" "")
13923 (match_operand 4 "" "")))
13924 (clobber (reg:CCFP FPSR_REG))
13925 (clobber (reg:CCFP FLAGS_REG))]
13929 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13930 operands[3], operands[4], NULL_RTX, NULL_RTX);
13936 (if_then_else (match_operator 0 "comparison_operator"
13937 [(match_operand 1 "register_operand" "")
13938 (match_operand 2 "general_operand" "")])
13939 (match_operand 3 "" "")
13940 (match_operand 4 "" "")))
13941 (clobber (reg:CCFP FPSR_REG))
13942 (clobber (reg:CCFP FLAGS_REG))
13943 (clobber (match_scratch:HI 5 "=a"))]
13947 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13948 operands[3], operands[4], operands[5], NULL_RTX);
13954 (if_then_else (match_operator 0 "comparison_operator"
13955 [(match_operator 1 "float_operator"
13956 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13957 (match_operand 3 "register_operand" "")])
13958 (match_operand 4 "" "")
13959 (match_operand 5 "" "")))
13960 (clobber (reg:CCFP FPSR_REG))
13961 (clobber (reg:CCFP FLAGS_REG))
13962 (clobber (match_scratch:HI 6 "=a"))]
13966 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13967 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13968 operands[3], operands[7],
13969 operands[4], operands[5], operands[6], NULL_RTX);
13973 ;; %%% Kill this when reload knows how to do it.
13976 (if_then_else (match_operator 0 "comparison_operator"
13977 [(match_operator 1 "float_operator"
13978 [(match_operand:X87MODEI12 2 "register_operand" "")])
13979 (match_operand 3 "register_operand" "")])
13980 (match_operand 4 "" "")
13981 (match_operand 5 "" "")))
13982 (clobber (reg:CCFP FPSR_REG))
13983 (clobber (reg:CCFP FLAGS_REG))
13984 (clobber (match_scratch:HI 6 "=a"))]
13988 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13989 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13990 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13991 operands[3], operands[7],
13992 operands[4], operands[5], operands[6], operands[2]);
13996 ;; Unconditional and other jump instructions
13998 (define_insn "jump"
14000 (label_ref (match_operand 0 "" "")))]
14003 [(set_attr "type" "ibr")
14004 (set (attr "length")
14005 (if_then_else (and (ge (minus (match_dup 0) (pc))
14007 (lt (minus (match_dup 0) (pc))
14011 (set_attr "modrm" "0")])
14013 (define_expand "indirect_jump"
14014 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14018 (define_insn "*indirect_jump"
14019 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14022 [(set_attr "type" "ibr")
14023 (set_attr "length_immediate" "0")])
14025 (define_insn "*indirect_jump_rtx64"
14026 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14029 [(set_attr "type" "ibr")
14030 (set_attr "length_immediate" "0")])
14032 (define_expand "tablejump"
14033 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14034 (use (label_ref (match_operand 1 "" "")))])]
14037 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14038 relative. Convert the relative address to an absolute address. */
14042 enum rtx_code code;
14048 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14050 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14054 op1 = pic_offset_table_rtx;
14059 op0 = pic_offset_table_rtx;
14063 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14068 (define_insn "*tablejump_1"
14069 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14070 (use (label_ref (match_operand 1 "" "")))]
14073 [(set_attr "type" "ibr")
14074 (set_attr "length_immediate" "0")])
14076 (define_insn "*tablejump_1_rtx64"
14077 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14078 (use (label_ref (match_operand 1 "" "")))]
14081 [(set_attr "type" "ibr")
14082 (set_attr "length_immediate" "0")])
14084 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14087 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14088 (set (match_operand:QI 1 "register_operand" "")
14089 (match_operator:QI 2 "ix86_comparison_operator"
14090 [(reg FLAGS_REG) (const_int 0)]))
14091 (set (match_operand 3 "q_regs_operand" "")
14092 (zero_extend (match_dup 1)))]
14093 "(peep2_reg_dead_p (3, operands[1])
14094 || operands_match_p (operands[1], operands[3]))
14095 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14096 [(set (match_dup 4) (match_dup 0))
14097 (set (strict_low_part (match_dup 5))
14100 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14101 operands[5] = gen_lowpart (QImode, operands[3]);
14102 ix86_expand_clear (operands[3]);
14105 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14108 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14109 (set (match_operand:QI 1 "register_operand" "")
14110 (match_operator:QI 2 "ix86_comparison_operator"
14111 [(reg FLAGS_REG) (const_int 0)]))
14112 (parallel [(set (match_operand 3 "q_regs_operand" "")
14113 (zero_extend (match_dup 1)))
14114 (clobber (reg:CC FLAGS_REG))])]
14115 "(peep2_reg_dead_p (3, operands[1])
14116 || operands_match_p (operands[1], operands[3]))
14117 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14118 [(set (match_dup 4) (match_dup 0))
14119 (set (strict_low_part (match_dup 5))
14122 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14123 operands[5] = gen_lowpart (QImode, operands[3]);
14124 ix86_expand_clear (operands[3]);
14127 ;; Call instructions.
14129 ;; The predicates normally associated with named expanders are not properly
14130 ;; checked for calls. This is a bug in the generic code, but it isn't that
14131 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14133 ;; Call subroutine returning no value.
14135 (define_expand "call_pop"
14136 [(parallel [(call (match_operand:QI 0 "" "")
14137 (match_operand:SI 1 "" ""))
14138 (set (reg:SI SP_REG)
14139 (plus:SI (reg:SI SP_REG)
14140 (match_operand:SI 3 "" "")))])]
14143 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14147 (define_insn "*call_pop_0"
14148 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14149 (match_operand:SI 1 "" ""))
14150 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14151 (match_operand:SI 2 "immediate_operand" "")))]
14154 if (SIBLING_CALL_P (insn))
14157 return "call\t%P0";
14159 [(set_attr "type" "call")])
14161 (define_insn "*call_pop_1"
14162 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14163 (match_operand:SI 1 "" ""))
14164 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14165 (match_operand:SI 2 "immediate_operand" "i")))]
14168 if (constant_call_address_operand (operands[0], Pmode))
14170 if (SIBLING_CALL_P (insn))
14173 return "call\t%P0";
14175 if (SIBLING_CALL_P (insn))
14178 return "call\t%A0";
14180 [(set_attr "type" "call")])
14182 (define_expand "call"
14183 [(call (match_operand:QI 0 "" "")
14184 (match_operand 1 "" ""))
14185 (use (match_operand 2 "" ""))]
14188 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14192 (define_expand "sibcall"
14193 [(call (match_operand:QI 0 "" "")
14194 (match_operand 1 "" ""))
14195 (use (match_operand 2 "" ""))]
14198 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14202 (define_insn "*call_0"
14203 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14204 (match_operand 1 "" ""))]
14207 if (SIBLING_CALL_P (insn))
14210 return "call\t%P0";
14212 [(set_attr "type" "call")])
14214 (define_insn "*call_1"
14215 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14216 (match_operand 1 "" ""))]
14217 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14219 if (constant_call_address_operand (operands[0], Pmode))
14220 return "call\t%P0";
14221 return "call\t%A0";
14223 [(set_attr "type" "call")])
14225 (define_insn "*sibcall_1"
14226 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14227 (match_operand 1 "" ""))]
14228 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14230 if (constant_call_address_operand (operands[0], Pmode))
14234 [(set_attr "type" "call")])
14236 (define_insn "*call_1_rex64"
14237 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14238 (match_operand 1 "" ""))]
14239 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14241 if (constant_call_address_operand (operands[0], Pmode))
14242 return "call\t%P0";
14243 return "call\t%A0";
14245 [(set_attr "type" "call")])
14247 (define_insn "*sibcall_1_rex64"
14248 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14249 (match_operand 1 "" ""))]
14250 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14252 [(set_attr "type" "call")])
14254 (define_insn "*sibcall_1_rex64_v"
14255 [(call (mem:QI (reg:DI 40))
14256 (match_operand 0 "" ""))]
14257 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14259 [(set_attr "type" "call")])
14262 ;; Call subroutine, returning value in operand 0
14264 (define_expand "call_value_pop"
14265 [(parallel [(set (match_operand 0 "" "")
14266 (call (match_operand:QI 1 "" "")
14267 (match_operand:SI 2 "" "")))
14268 (set (reg:SI SP_REG)
14269 (plus:SI (reg:SI SP_REG)
14270 (match_operand:SI 4 "" "")))])]
14273 ix86_expand_call (operands[0], operands[1], operands[2],
14274 operands[3], operands[4], 0);
14278 (define_expand "call_value"
14279 [(set (match_operand 0 "" "")
14280 (call (match_operand:QI 1 "" "")
14281 (match_operand:SI 2 "" "")))
14282 (use (match_operand:SI 3 "" ""))]
14283 ;; Operand 2 not used on the i386.
14286 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14290 (define_expand "sibcall_value"
14291 [(set (match_operand 0 "" "")
14292 (call (match_operand:QI 1 "" "")
14293 (match_operand:SI 2 "" "")))
14294 (use (match_operand:SI 3 "" ""))]
14295 ;; Operand 2 not used on the i386.
14298 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14302 ;; Call subroutine returning any type.
14304 (define_expand "untyped_call"
14305 [(parallel [(call (match_operand 0 "" "")
14307 (match_operand 1 "" "")
14308 (match_operand 2 "" "")])]
14313 /* In order to give reg-stack an easier job in validating two
14314 coprocessor registers as containing a possible return value,
14315 simply pretend the untyped call returns a complex long double
14318 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14319 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14320 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14323 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14325 rtx set = XVECEXP (operands[2], 0, i);
14326 emit_move_insn (SET_DEST (set), SET_SRC (set));
14329 /* The optimizer does not know that the call sets the function value
14330 registers we stored in the result block. We avoid problems by
14331 claiming that all hard registers are used and clobbered at this
14333 emit_insn (gen_blockage (const0_rtx));
14338 ;; Prologue and epilogue instructions
14340 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14341 ;; all of memory. This blocks insns from being moved across this point.
14343 (define_insn "blockage"
14344 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14347 [(set_attr "length" "0")])
14349 ;; Insn emitted into the body of a function to return from a function.
14350 ;; This is only done if the function's epilogue is known to be simple.
14351 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14353 (define_expand "return"
14355 "ix86_can_use_return_insn_p ()"
14357 if (current_function_pops_args)
14359 rtx popc = GEN_INT (current_function_pops_args);
14360 emit_jump_insn (gen_return_pop_internal (popc));
14365 (define_insn "return_internal"
14369 [(set_attr "length" "1")
14370 (set_attr "length_immediate" "0")
14371 (set_attr "modrm" "0")])
14373 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14374 ;; instruction Athlon and K8 have.
14376 (define_insn "return_internal_long"
14378 (unspec [(const_int 0)] UNSPEC_REP)]
14381 [(set_attr "length" "1")
14382 (set_attr "length_immediate" "0")
14383 (set_attr "prefix_rep" "1")
14384 (set_attr "modrm" "0")])
14386 (define_insn "return_pop_internal"
14388 (use (match_operand:SI 0 "const_int_operand" ""))]
14391 [(set_attr "length" "3")
14392 (set_attr "length_immediate" "2")
14393 (set_attr "modrm" "0")])
14395 (define_insn "return_indirect_internal"
14397 (use (match_operand:SI 0 "register_operand" "r"))]
14400 [(set_attr "type" "ibr")
14401 (set_attr "length_immediate" "0")])
14407 [(set_attr "length" "1")
14408 (set_attr "length_immediate" "0")
14409 (set_attr "modrm" "0")])
14411 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14412 ;; branch prediction penalty for the third jump in a 16-byte
14415 (define_insn "align"
14416 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14419 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14420 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14422 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14423 The align insn is used to avoid 3 jump instructions in the row to improve
14424 branch prediction and the benefits hardly outweigh the cost of extra 8
14425 nops on the average inserted by full alignment pseudo operation. */
14429 [(set_attr "length" "16")])
14431 (define_expand "prologue"
14434 "ix86_expand_prologue (); DONE;")
14436 (define_insn "set_got"
14437 [(set (match_operand:SI 0 "register_operand" "=r")
14438 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14439 (clobber (reg:CC FLAGS_REG))]
14441 { return output_set_got (operands[0], NULL_RTX); }
14442 [(set_attr "type" "multi")
14443 (set_attr "length" "12")])
14445 (define_insn "set_got_labelled"
14446 [(set (match_operand:SI 0 "register_operand" "=r")
14447 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14449 (clobber (reg:CC FLAGS_REG))]
14451 { return output_set_got (operands[0], operands[1]); }
14452 [(set_attr "type" "multi")
14453 (set_attr "length" "12")])
14455 (define_insn "set_got_rex64"
14456 [(set (match_operand:DI 0 "register_operand" "=r")
14457 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14459 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14460 [(set_attr "type" "lea")
14461 (set_attr "length" "6")])
14463 (define_expand "epilogue"
14466 "ix86_expand_epilogue (1); DONE;")
14468 (define_expand "sibcall_epilogue"
14471 "ix86_expand_epilogue (0); DONE;")
14473 (define_expand "eh_return"
14474 [(use (match_operand 0 "register_operand" ""))]
14477 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14479 /* Tricky bit: we write the address of the handler to which we will
14480 be returning into someone else's stack frame, one word below the
14481 stack address we wish to restore. */
14482 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14483 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14484 tmp = gen_rtx_MEM (Pmode, tmp);
14485 emit_move_insn (tmp, ra);
14487 if (Pmode == SImode)
14488 emit_jump_insn (gen_eh_return_si (sa));
14490 emit_jump_insn (gen_eh_return_di (sa));
14495 (define_insn_and_split "eh_return_si"
14497 (unspec [(match_operand:SI 0 "register_operand" "c")]
14498 UNSPEC_EH_RETURN))]
14503 "ix86_expand_epilogue (2); DONE;")
14505 (define_insn_and_split "eh_return_di"
14507 (unspec [(match_operand:DI 0 "register_operand" "c")]
14508 UNSPEC_EH_RETURN))]
14513 "ix86_expand_epilogue (2); DONE;")
14515 (define_insn "leave"
14516 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14517 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14518 (clobber (mem:BLK (scratch)))]
14521 [(set_attr "type" "leave")])
14523 (define_insn "leave_rex64"
14524 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14525 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14526 (clobber (mem:BLK (scratch)))]
14529 [(set_attr "type" "leave")])
14531 (define_expand "ffssi2"
14533 [(set (match_operand:SI 0 "register_operand" "")
14534 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14535 (clobber (match_scratch:SI 2 ""))
14536 (clobber (reg:CC FLAGS_REG))])]
14540 (define_insn_and_split "*ffs_cmove"
14541 [(set (match_operand:SI 0 "register_operand" "=r")
14542 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14543 (clobber (match_scratch:SI 2 "=&r"))
14544 (clobber (reg:CC FLAGS_REG))]
14547 "&& reload_completed"
14548 [(set (match_dup 2) (const_int -1))
14549 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14550 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14551 (set (match_dup 0) (if_then_else:SI
14552 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14555 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14556 (clobber (reg:CC FLAGS_REG))])]
14559 (define_insn_and_split "*ffs_no_cmove"
14560 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14561 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14562 (clobber (match_scratch:SI 2 "=&q"))
14563 (clobber (reg:CC FLAGS_REG))]
14567 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14568 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14569 (set (strict_low_part (match_dup 3))
14570 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14571 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14572 (clobber (reg:CC FLAGS_REG))])
14573 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14574 (clobber (reg:CC FLAGS_REG))])
14575 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14576 (clobber (reg:CC FLAGS_REG))])]
14578 operands[3] = gen_lowpart (QImode, operands[2]);
14579 ix86_expand_clear (operands[2]);
14582 (define_insn "*ffssi_1"
14583 [(set (reg:CCZ FLAGS_REG)
14584 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14586 (set (match_operand:SI 0 "register_operand" "=r")
14587 (ctz:SI (match_dup 1)))]
14589 "bsf{l}\t{%1, %0|%0, %1}"
14590 [(set_attr "prefix_0f" "1")])
14592 (define_expand "ffsdi2"
14594 [(set (match_operand:DI 0 "register_operand" "")
14595 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14596 (clobber (match_scratch:DI 2 ""))
14597 (clobber (reg:CC FLAGS_REG))])]
14598 "TARGET_64BIT && TARGET_CMOVE"
14601 (define_insn_and_split "*ffs_rex64"
14602 [(set (match_operand:DI 0 "register_operand" "=r")
14603 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14604 (clobber (match_scratch:DI 2 "=&r"))
14605 (clobber (reg:CC FLAGS_REG))]
14606 "TARGET_64BIT && TARGET_CMOVE"
14608 "&& reload_completed"
14609 [(set (match_dup 2) (const_int -1))
14610 (parallel [(set (reg:CCZ FLAGS_REG)
14611 (compare:CCZ (match_dup 1) (const_int 0)))
14612 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14613 (set (match_dup 0) (if_then_else:DI
14614 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14617 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14618 (clobber (reg:CC FLAGS_REG))])]
14621 (define_insn "*ffsdi_1"
14622 [(set (reg:CCZ FLAGS_REG)
14623 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14625 (set (match_operand:DI 0 "register_operand" "=r")
14626 (ctz:DI (match_dup 1)))]
14628 "bsf{q}\t{%1, %0|%0, %1}"
14629 [(set_attr "prefix_0f" "1")])
14631 (define_insn "ctzsi2"
14632 [(set (match_operand:SI 0 "register_operand" "=r")
14633 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14634 (clobber (reg:CC FLAGS_REG))]
14636 "bsf{l}\t{%1, %0|%0, %1}"
14637 [(set_attr "prefix_0f" "1")])
14639 (define_insn "ctzdi2"
14640 [(set (match_operand:DI 0 "register_operand" "=r")
14641 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14642 (clobber (reg:CC FLAGS_REG))]
14644 "bsf{q}\t{%1, %0|%0, %1}"
14645 [(set_attr "prefix_0f" "1")])
14647 (define_expand "clzsi2"
14649 [(set (match_operand:SI 0 "register_operand" "")
14650 (minus:SI (const_int 31)
14651 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14652 (clobber (reg:CC FLAGS_REG))])
14654 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14655 (clobber (reg:CC FLAGS_REG))])]
14660 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14665 (define_insn "clzsi2_abm"
14666 [(set (match_operand:SI 0 "register_operand" "=r")
14667 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14668 (clobber (reg:CC FLAGS_REG))]
14670 "lzcnt{l}\t{%1, %0|%0, %1}"
14671 [(set_attr "prefix_rep" "1")
14672 (set_attr "type" "bitmanip")
14673 (set_attr "mode" "SI")])
14675 (define_insn "*bsr"
14676 [(set (match_operand:SI 0 "register_operand" "=r")
14677 (minus:SI (const_int 31)
14678 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14679 (clobber (reg:CC FLAGS_REG))]
14681 "bsr{l}\t{%1, %0|%0, %1}"
14682 [(set_attr "prefix_0f" "1")
14683 (set_attr "mode" "SI")])
14685 (define_insn "popcountsi2"
14686 [(set (match_operand:SI 0 "register_operand" "=r")
14687 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14688 (clobber (reg:CC FLAGS_REG))]
14690 "popcnt{l}\t{%1, %0|%0, %1}"
14691 [(set_attr "prefix_rep" "1")
14692 (set_attr "type" "bitmanip")
14693 (set_attr "mode" "SI")])
14695 (define_insn "*popcountsi2_cmp"
14696 [(set (reg FLAGS_REG)
14698 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14700 (set (match_operand:SI 0 "register_operand" "=r")
14701 (popcount:SI (match_dup 1)))]
14702 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14703 "popcnt{l}\t{%1, %0|%0, %1}"
14704 [(set_attr "prefix_rep" "1")
14705 (set_attr "type" "bitmanip")
14706 (set_attr "mode" "SI")])
14708 (define_insn "*popcountsi2_cmp_zext"
14709 [(set (reg FLAGS_REG)
14711 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14713 (set (match_operand:DI 0 "register_operand" "=r")
14714 (zero_extend:DI(popcount:SI (match_dup 1))))]
14715 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14716 "popcnt{l}\t{%1, %0|%0, %1}"
14717 [(set_attr "prefix_rep" "1")
14718 (set_attr "type" "bitmanip")
14719 (set_attr "mode" "SI")])
14721 (define_expand "clzdi2"
14723 [(set (match_operand:DI 0 "register_operand" "")
14724 (minus:DI (const_int 63)
14725 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14726 (clobber (reg:CC FLAGS_REG))])
14728 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14729 (clobber (reg:CC FLAGS_REG))])]
14734 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14739 (define_insn "clzdi2_abm"
14740 [(set (match_operand:DI 0 "register_operand" "=r")
14741 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14742 (clobber (reg:CC FLAGS_REG))]
14743 "TARGET_64BIT && TARGET_ABM"
14744 "lzcnt{q}\t{%1, %0|%0, %1}"
14745 [(set_attr "prefix_rep" "1")
14746 (set_attr "type" "bitmanip")
14747 (set_attr "mode" "DI")])
14749 (define_insn "*bsr_rex64"
14750 [(set (match_operand:DI 0 "register_operand" "=r")
14751 (minus:DI (const_int 63)
14752 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14753 (clobber (reg:CC FLAGS_REG))]
14755 "bsr{q}\t{%1, %0|%0, %1}"
14756 [(set_attr "prefix_0f" "1")
14757 (set_attr "mode" "DI")])
14759 (define_insn "popcountdi2"
14760 [(set (match_operand:DI 0 "register_operand" "=r")
14761 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14762 (clobber (reg:CC FLAGS_REG))]
14763 "TARGET_64BIT && TARGET_POPCNT"
14764 "popcnt{q}\t{%1, %0|%0, %1}"
14765 [(set_attr "prefix_rep" "1")
14766 (set_attr "type" "bitmanip")
14767 (set_attr "mode" "DI")])
14769 (define_insn "*popcountdi2_cmp"
14770 [(set (reg FLAGS_REG)
14772 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14774 (set (match_operand:DI 0 "register_operand" "=r")
14775 (popcount:DI (match_dup 1)))]
14776 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14777 "popcnt{q}\t{%1, %0|%0, %1}"
14778 [(set_attr "prefix_rep" "1")
14779 (set_attr "type" "bitmanip")
14780 (set_attr "mode" "DI")])
14782 (define_expand "clzhi2"
14784 [(set (match_operand:HI 0 "register_operand" "")
14785 (minus:HI (const_int 15)
14786 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14787 (clobber (reg:CC FLAGS_REG))])
14789 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14790 (clobber (reg:CC FLAGS_REG))])]
14795 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14800 (define_insn "clzhi2_abm"
14801 [(set (match_operand:HI 0 "register_operand" "=r")
14802 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14803 (clobber (reg:CC FLAGS_REG))]
14805 "lzcnt{w}\t{%1, %0|%0, %1}"
14806 [(set_attr "prefix_rep" "1")
14807 (set_attr "type" "bitmanip")
14808 (set_attr "mode" "HI")])
14810 (define_insn "*bsrhi"
14811 [(set (match_operand:HI 0 "register_operand" "=r")
14812 (minus:HI (const_int 15)
14813 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14814 (clobber (reg:CC FLAGS_REG))]
14816 "bsr{w}\t{%1, %0|%0, %1}"
14817 [(set_attr "prefix_0f" "1")
14818 (set_attr "mode" "HI")])
14820 (define_insn "popcounthi2"
14821 [(set (match_operand:HI 0 "register_operand" "=r")
14822 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14823 (clobber (reg:CC FLAGS_REG))]
14825 "popcnt{w}\t{%1, %0|%0, %1}"
14826 [(set_attr "prefix_rep" "1")
14827 (set_attr "type" "bitmanip")
14828 (set_attr "mode" "HI")])
14830 (define_insn "*popcounthi2_cmp"
14831 [(set (reg FLAGS_REG)
14833 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14835 (set (match_operand:HI 0 "register_operand" "=r")
14836 (popcount:HI (match_dup 1)))]
14837 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14838 "popcnt{w}\t{%1, %0|%0, %1}"
14839 [(set_attr "prefix_rep" "1")
14840 (set_attr "type" "bitmanip")
14841 (set_attr "mode" "HI")])
14843 ;; Thread-local storage patterns for ELF.
14845 ;; Note that these code sequences must appear exactly as shown
14846 ;; in order to allow linker relaxation.
14848 (define_insn "*tls_global_dynamic_32_gnu"
14849 [(set (match_operand:SI 0 "register_operand" "=a")
14850 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14851 (match_operand:SI 2 "tls_symbolic_operand" "")
14852 (match_operand:SI 3 "call_insn_operand" "")]
14854 (clobber (match_scratch:SI 4 "=d"))
14855 (clobber (match_scratch:SI 5 "=c"))
14856 (clobber (reg:CC FLAGS_REG))]
14857 "!TARGET_64BIT && TARGET_GNU_TLS"
14858 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14859 [(set_attr "type" "multi")
14860 (set_attr "length" "12")])
14862 (define_insn "*tls_global_dynamic_32_sun"
14863 [(set (match_operand:SI 0 "register_operand" "=a")
14864 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14865 (match_operand:SI 2 "tls_symbolic_operand" "")
14866 (match_operand:SI 3 "call_insn_operand" "")]
14868 (clobber (match_scratch:SI 4 "=d"))
14869 (clobber (match_scratch:SI 5 "=c"))
14870 (clobber (reg:CC FLAGS_REG))]
14871 "!TARGET_64BIT && TARGET_SUN_TLS"
14872 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14873 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14874 [(set_attr "type" "multi")
14875 (set_attr "length" "14")])
14877 (define_expand "tls_global_dynamic_32"
14878 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14881 (match_operand:SI 1 "tls_symbolic_operand" "")
14884 (clobber (match_scratch:SI 4 ""))
14885 (clobber (match_scratch:SI 5 ""))
14886 (clobber (reg:CC FLAGS_REG))])]
14890 operands[2] = pic_offset_table_rtx;
14893 operands[2] = gen_reg_rtx (Pmode);
14894 emit_insn (gen_set_got (operands[2]));
14896 if (TARGET_GNU2_TLS)
14898 emit_insn (gen_tls_dynamic_gnu2_32
14899 (operands[0], operands[1], operands[2]));
14902 operands[3] = ix86_tls_get_addr ();
14905 (define_insn "*tls_global_dynamic_64"
14906 [(set (match_operand:DI 0 "register_operand" "=a")
14907 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14908 (match_operand:DI 3 "" "")))
14909 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14912 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14913 [(set_attr "type" "multi")
14914 (set_attr "length" "16")])
14916 (define_expand "tls_global_dynamic_64"
14917 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14918 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14919 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14923 if (TARGET_GNU2_TLS)
14925 emit_insn (gen_tls_dynamic_gnu2_64
14926 (operands[0], operands[1]));
14929 operands[2] = ix86_tls_get_addr ();
14932 (define_insn "*tls_local_dynamic_base_32_gnu"
14933 [(set (match_operand:SI 0 "register_operand" "=a")
14934 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14935 (match_operand:SI 2 "call_insn_operand" "")]
14936 UNSPEC_TLS_LD_BASE))
14937 (clobber (match_scratch:SI 3 "=d"))
14938 (clobber (match_scratch:SI 4 "=c"))
14939 (clobber (reg:CC FLAGS_REG))]
14940 "!TARGET_64BIT && TARGET_GNU_TLS"
14941 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14942 [(set_attr "type" "multi")
14943 (set_attr "length" "11")])
14945 (define_insn "*tls_local_dynamic_base_32_sun"
14946 [(set (match_operand:SI 0 "register_operand" "=a")
14947 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14948 (match_operand:SI 2 "call_insn_operand" "")]
14949 UNSPEC_TLS_LD_BASE))
14950 (clobber (match_scratch:SI 3 "=d"))
14951 (clobber (match_scratch:SI 4 "=c"))
14952 (clobber (reg:CC FLAGS_REG))]
14953 "!TARGET_64BIT && TARGET_SUN_TLS"
14954 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14955 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14956 [(set_attr "type" "multi")
14957 (set_attr "length" "13")])
14959 (define_expand "tls_local_dynamic_base_32"
14960 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14961 (unspec:SI [(match_dup 1) (match_dup 2)]
14962 UNSPEC_TLS_LD_BASE))
14963 (clobber (match_scratch:SI 3 ""))
14964 (clobber (match_scratch:SI 4 ""))
14965 (clobber (reg:CC FLAGS_REG))])]
14969 operands[1] = pic_offset_table_rtx;
14972 operands[1] = gen_reg_rtx (Pmode);
14973 emit_insn (gen_set_got (operands[1]));
14975 if (TARGET_GNU2_TLS)
14977 emit_insn (gen_tls_dynamic_gnu2_32
14978 (operands[0], ix86_tls_module_base (), operands[1]));
14981 operands[2] = ix86_tls_get_addr ();
14984 (define_insn "*tls_local_dynamic_base_64"
14985 [(set (match_operand:DI 0 "register_operand" "=a")
14986 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14987 (match_operand:DI 2 "" "")))
14988 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14990 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14991 [(set_attr "type" "multi")
14992 (set_attr "length" "12")])
14994 (define_expand "tls_local_dynamic_base_64"
14995 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14996 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14997 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15000 if (TARGET_GNU2_TLS)
15002 emit_insn (gen_tls_dynamic_gnu2_64
15003 (operands[0], ix86_tls_module_base ()));
15006 operands[1] = ix86_tls_get_addr ();
15009 ;; Local dynamic of a single variable is a lose. Show combine how
15010 ;; to convert that back to global dynamic.
15012 (define_insn_and_split "*tls_local_dynamic_32_once"
15013 [(set (match_operand:SI 0 "register_operand" "=a")
15014 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15015 (match_operand:SI 2 "call_insn_operand" "")]
15016 UNSPEC_TLS_LD_BASE)
15017 (const:SI (unspec:SI
15018 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15020 (clobber (match_scratch:SI 4 "=d"))
15021 (clobber (match_scratch:SI 5 "=c"))
15022 (clobber (reg:CC FLAGS_REG))]
15026 [(parallel [(set (match_dup 0)
15027 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15029 (clobber (match_dup 4))
15030 (clobber (match_dup 5))
15031 (clobber (reg:CC FLAGS_REG))])]
15034 ;; Load and add the thread base pointer from %gs:0.
15036 (define_insn "*load_tp_si"
15037 [(set (match_operand:SI 0 "register_operand" "=r")
15038 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15040 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15041 [(set_attr "type" "imov")
15042 (set_attr "modrm" "0")
15043 (set_attr "length" "7")
15044 (set_attr "memory" "load")
15045 (set_attr "imm_disp" "false")])
15047 (define_insn "*add_tp_si"
15048 [(set (match_operand:SI 0 "register_operand" "=r")
15049 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15050 (match_operand:SI 1 "register_operand" "0")))
15051 (clobber (reg:CC FLAGS_REG))]
15053 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15054 [(set_attr "type" "alu")
15055 (set_attr "modrm" "0")
15056 (set_attr "length" "7")
15057 (set_attr "memory" "load")
15058 (set_attr "imm_disp" "false")])
15060 (define_insn "*load_tp_di"
15061 [(set (match_operand:DI 0 "register_operand" "=r")
15062 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15064 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15065 [(set_attr "type" "imov")
15066 (set_attr "modrm" "0")
15067 (set_attr "length" "7")
15068 (set_attr "memory" "load")
15069 (set_attr "imm_disp" "false")])
15071 (define_insn "*add_tp_di"
15072 [(set (match_operand:DI 0 "register_operand" "=r")
15073 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15074 (match_operand:DI 1 "register_operand" "0")))
15075 (clobber (reg:CC FLAGS_REG))]
15077 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15078 [(set_attr "type" "alu")
15079 (set_attr "modrm" "0")
15080 (set_attr "length" "7")
15081 (set_attr "memory" "load")
15082 (set_attr "imm_disp" "false")])
15084 ;; GNU2 TLS patterns can be split.
15086 (define_expand "tls_dynamic_gnu2_32"
15087 [(set (match_dup 3)
15088 (plus:SI (match_operand:SI 2 "register_operand" "")
15090 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15093 [(set (match_operand:SI 0 "register_operand" "")
15094 (unspec:SI [(match_dup 1) (match_dup 3)
15095 (match_dup 2) (reg:SI SP_REG)]
15097 (clobber (reg:CC FLAGS_REG))])]
15098 "!TARGET_64BIT && TARGET_GNU2_TLS"
15100 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15101 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15104 (define_insn "*tls_dynamic_lea_32"
15105 [(set (match_operand:SI 0 "register_operand" "=r")
15106 (plus:SI (match_operand:SI 1 "register_operand" "b")
15108 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15109 UNSPEC_TLSDESC))))]
15110 "!TARGET_64BIT && TARGET_GNU2_TLS"
15111 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15112 [(set_attr "type" "lea")
15113 (set_attr "mode" "SI")
15114 (set_attr "length" "6")
15115 (set_attr "length_address" "4")])
15117 (define_insn "*tls_dynamic_call_32"
15118 [(set (match_operand:SI 0 "register_operand" "=a")
15119 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15120 (match_operand:SI 2 "register_operand" "0")
15121 ;; we have to make sure %ebx still points to the GOT
15122 (match_operand:SI 3 "register_operand" "b")
15125 (clobber (reg:CC FLAGS_REG))]
15126 "!TARGET_64BIT && TARGET_GNU2_TLS"
15127 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15128 [(set_attr "type" "call")
15129 (set_attr "length" "2")
15130 (set_attr "length_address" "0")])
15132 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15133 [(set (match_operand:SI 0 "register_operand" "=&a")
15135 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15136 (match_operand:SI 4 "" "")
15137 (match_operand:SI 2 "register_operand" "b")
15140 (const:SI (unspec:SI
15141 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15143 (clobber (reg:CC FLAGS_REG))]
15144 "!TARGET_64BIT && TARGET_GNU2_TLS"
15147 [(set (match_dup 0) (match_dup 5))]
15149 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15150 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15153 (define_expand "tls_dynamic_gnu2_64"
15154 [(set (match_dup 2)
15155 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15158 [(set (match_operand:DI 0 "register_operand" "")
15159 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15161 (clobber (reg:CC FLAGS_REG))])]
15162 "TARGET_64BIT && TARGET_GNU2_TLS"
15164 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15165 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15168 (define_insn "*tls_dynamic_lea_64"
15169 [(set (match_operand:DI 0 "register_operand" "=r")
15170 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15172 "TARGET_64BIT && TARGET_GNU2_TLS"
15173 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15174 [(set_attr "type" "lea")
15175 (set_attr "mode" "DI")
15176 (set_attr "length" "7")
15177 (set_attr "length_address" "4")])
15179 (define_insn "*tls_dynamic_call_64"
15180 [(set (match_operand:DI 0 "register_operand" "=a")
15181 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15182 (match_operand:DI 2 "register_operand" "0")
15185 (clobber (reg:CC FLAGS_REG))]
15186 "TARGET_64BIT && TARGET_GNU2_TLS"
15187 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15188 [(set_attr "type" "call")
15189 (set_attr "length" "2")
15190 (set_attr "length_address" "0")])
15192 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15193 [(set (match_operand:DI 0 "register_operand" "=&a")
15195 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15196 (match_operand:DI 3 "" "")
15199 (const:DI (unspec:DI
15200 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15202 (clobber (reg:CC FLAGS_REG))]
15203 "TARGET_64BIT && TARGET_GNU2_TLS"
15206 [(set (match_dup 0) (match_dup 4))]
15208 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15209 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15214 ;; These patterns match the binary 387 instructions for addM3, subM3,
15215 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15216 ;; SFmode. The first is the normal insn, the second the same insn but
15217 ;; with one operand a conversion, and the third the same insn but with
15218 ;; the other operand a conversion. The conversion may be SFmode or
15219 ;; SImode if the target mode DFmode, but only SImode if the target mode
15222 ;; Gcc is slightly more smart about handling normal two address instructions
15223 ;; so use special patterns for add and mull.
15225 (define_insn "*fop_sf_comm_mixed"
15226 [(set (match_operand:SF 0 "register_operand" "=f,x")
15227 (match_operator:SF 3 "binary_fp_operator"
15228 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15229 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15230 "TARGET_MIX_SSE_I387
15231 && COMMUTATIVE_ARITH_P (operands[3])
15232 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15233 "* return output_387_binary_op (insn, operands);"
15234 [(set (attr "type")
15235 (if_then_else (eq_attr "alternative" "1")
15236 (if_then_else (match_operand:SF 3 "mult_operator" "")
15237 (const_string "ssemul")
15238 (const_string "sseadd"))
15239 (if_then_else (match_operand:SF 3 "mult_operator" "")
15240 (const_string "fmul")
15241 (const_string "fop"))))
15242 (set_attr "mode" "SF")])
15244 (define_insn "*fop_sf_comm_sse"
15245 [(set (match_operand:SF 0 "register_operand" "=x")
15246 (match_operator:SF 3 "binary_fp_operator"
15247 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15248 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15250 && COMMUTATIVE_ARITH_P (operands[3])
15251 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15252 "* return output_387_binary_op (insn, operands);"
15253 [(set (attr "type")
15254 (if_then_else (match_operand:SF 3 "mult_operator" "")
15255 (const_string "ssemul")
15256 (const_string "sseadd")))
15257 (set_attr "mode" "SF")])
15259 (define_insn "*fop_sf_comm_i387"
15260 [(set (match_operand:SF 0 "register_operand" "=f")
15261 (match_operator:SF 3 "binary_fp_operator"
15262 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15263 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15265 && COMMUTATIVE_ARITH_P (operands[3])
15266 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15267 "* return output_387_binary_op (insn, operands);"
15268 [(set (attr "type")
15269 (if_then_else (match_operand:SF 3 "mult_operator" "")
15270 (const_string "fmul")
15271 (const_string "fop")))
15272 (set_attr "mode" "SF")])
15274 (define_insn "*fop_sf_1_mixed"
15275 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15276 (match_operator:SF 3 "binary_fp_operator"
15277 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15278 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15279 "TARGET_MIX_SSE_I387
15280 && !COMMUTATIVE_ARITH_P (operands[3])
15281 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15282 "* return output_387_binary_op (insn, operands);"
15283 [(set (attr "type")
15284 (cond [(and (eq_attr "alternative" "2")
15285 (match_operand:SF 3 "mult_operator" ""))
15286 (const_string "ssemul")
15287 (and (eq_attr "alternative" "2")
15288 (match_operand:SF 3 "div_operator" ""))
15289 (const_string "ssediv")
15290 (eq_attr "alternative" "2")
15291 (const_string "sseadd")
15292 (match_operand:SF 3 "mult_operator" "")
15293 (const_string "fmul")
15294 (match_operand:SF 3 "div_operator" "")
15295 (const_string "fdiv")
15297 (const_string "fop")))
15298 (set_attr "mode" "SF")])
15300 (define_insn "*fop_sf_1_sse"
15301 [(set (match_operand:SF 0 "register_operand" "=x")
15302 (match_operator:SF 3 "binary_fp_operator"
15303 [(match_operand:SF 1 "register_operand" "0")
15304 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15306 && !COMMUTATIVE_ARITH_P (operands[3])"
15307 "* return output_387_binary_op (insn, operands);"
15308 [(set (attr "type")
15309 (cond [(match_operand:SF 3 "mult_operator" "")
15310 (const_string "ssemul")
15311 (match_operand:SF 3 "div_operator" "")
15312 (const_string "ssediv")
15314 (const_string "sseadd")))
15315 (set_attr "mode" "SF")])
15317 ;; This pattern is not fully shadowed by the pattern above.
15318 (define_insn "*fop_sf_1_i387"
15319 [(set (match_operand:SF 0 "register_operand" "=f,f")
15320 (match_operator:SF 3 "binary_fp_operator"
15321 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15322 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15323 "TARGET_80387 && !TARGET_SSE_MATH
15324 && !COMMUTATIVE_ARITH_P (operands[3])
15325 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15326 "* return output_387_binary_op (insn, operands);"
15327 [(set (attr "type")
15328 (cond [(match_operand:SF 3 "mult_operator" "")
15329 (const_string "fmul")
15330 (match_operand:SF 3 "div_operator" "")
15331 (const_string "fdiv")
15333 (const_string "fop")))
15334 (set_attr "mode" "SF")])
15336 ;; ??? Add SSE splitters for these!
15337 (define_insn "*fop_sf_2<mode>_i387"
15338 [(set (match_operand:SF 0 "register_operand" "=f,f")
15339 (match_operator:SF 3 "binary_fp_operator"
15340 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15341 (match_operand:SF 2 "register_operand" "0,0")]))]
15342 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15343 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15344 [(set (attr "type")
15345 (cond [(match_operand:SF 3 "mult_operator" "")
15346 (const_string "fmul")
15347 (match_operand:SF 3 "div_operator" "")
15348 (const_string "fdiv")
15350 (const_string "fop")))
15351 (set_attr "fp_int_src" "true")
15352 (set_attr "mode" "<MODE>")])
15354 (define_insn "*fop_sf_3<mode>_i387"
15355 [(set (match_operand:SF 0 "register_operand" "=f,f")
15356 (match_operator:SF 3 "binary_fp_operator"
15357 [(match_operand:SF 1 "register_operand" "0,0")
15358 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15359 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15360 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15361 [(set (attr "type")
15362 (cond [(match_operand:SF 3 "mult_operator" "")
15363 (const_string "fmul")
15364 (match_operand:SF 3 "div_operator" "")
15365 (const_string "fdiv")
15367 (const_string "fop")))
15368 (set_attr "fp_int_src" "true")
15369 (set_attr "mode" "<MODE>")])
15371 (define_insn "*fop_df_comm_mixed"
15372 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15373 (match_operator:DF 3 "binary_fp_operator"
15374 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15375 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15376 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15377 && COMMUTATIVE_ARITH_P (operands[3])
15378 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15379 "* return output_387_binary_op (insn, operands);"
15380 [(set (attr "type")
15381 (if_then_else (eq_attr "alternative" "1")
15382 (if_then_else (match_operand:DF 3 "mult_operator" "")
15383 (const_string "ssemul")
15384 (const_string "sseadd"))
15385 (if_then_else (match_operand:DF 3 "mult_operator" "")
15386 (const_string "fmul")
15387 (const_string "fop"))))
15388 (set_attr "mode" "DF")])
15390 (define_insn "*fop_df_comm_sse"
15391 [(set (match_operand:DF 0 "register_operand" "=Y")
15392 (match_operator:DF 3 "binary_fp_operator"
15393 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15394 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15395 "TARGET_SSE2 && TARGET_SSE_MATH
15396 && COMMUTATIVE_ARITH_P (operands[3])
15397 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15398 "* return output_387_binary_op (insn, operands);"
15399 [(set (attr "type")
15400 (if_then_else (match_operand:DF 3 "mult_operator" "")
15401 (const_string "ssemul")
15402 (const_string "sseadd")))
15403 (set_attr "mode" "DF")])
15405 (define_insn "*fop_df_comm_i387"
15406 [(set (match_operand:DF 0 "register_operand" "=f")
15407 (match_operator:DF 3 "binary_fp_operator"
15408 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15409 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15411 && COMMUTATIVE_ARITH_P (operands[3])
15412 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15413 "* return output_387_binary_op (insn, operands);"
15414 [(set (attr "type")
15415 (if_then_else (match_operand:DF 3 "mult_operator" "")
15416 (const_string "fmul")
15417 (const_string "fop")))
15418 (set_attr "mode" "DF")])
15420 (define_insn "*fop_df_1_mixed"
15421 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15422 (match_operator:DF 3 "binary_fp_operator"
15423 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15424 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15425 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15426 && !COMMUTATIVE_ARITH_P (operands[3])
15427 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15428 "* return output_387_binary_op (insn, operands);"
15429 [(set (attr "type")
15430 (cond [(and (eq_attr "alternative" "2")
15431 (match_operand:DF 3 "mult_operator" ""))
15432 (const_string "ssemul")
15433 (and (eq_attr "alternative" "2")
15434 (match_operand:DF 3 "div_operator" ""))
15435 (const_string "ssediv")
15436 (eq_attr "alternative" "2")
15437 (const_string "sseadd")
15438 (match_operand:DF 3 "mult_operator" "")
15439 (const_string "fmul")
15440 (match_operand:DF 3 "div_operator" "")
15441 (const_string "fdiv")
15443 (const_string "fop")))
15444 (set_attr "mode" "DF")])
15446 (define_insn "*fop_df_1_sse"
15447 [(set (match_operand:DF 0 "register_operand" "=Y")
15448 (match_operator:DF 3 "binary_fp_operator"
15449 [(match_operand:DF 1 "register_operand" "0")
15450 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15451 "TARGET_SSE2 && TARGET_SSE_MATH
15452 && !COMMUTATIVE_ARITH_P (operands[3])"
15453 "* return output_387_binary_op (insn, operands);"
15454 [(set_attr "mode" "DF")
15456 (cond [(match_operand:DF 3 "mult_operator" "")
15457 (const_string "ssemul")
15458 (match_operand:DF 3 "div_operator" "")
15459 (const_string "ssediv")
15461 (const_string "sseadd")))])
15463 ;; This pattern is not fully shadowed by the pattern above.
15464 (define_insn "*fop_df_1_i387"
15465 [(set (match_operand:DF 0 "register_operand" "=f,f")
15466 (match_operator:DF 3 "binary_fp_operator"
15467 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15468 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15469 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15470 && !COMMUTATIVE_ARITH_P (operands[3])
15471 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15472 "* return output_387_binary_op (insn, operands);"
15473 [(set (attr "type")
15474 (cond [(match_operand:DF 3 "mult_operator" "")
15475 (const_string "fmul")
15476 (match_operand:DF 3 "div_operator" "")
15477 (const_string "fdiv")
15479 (const_string "fop")))
15480 (set_attr "mode" "DF")])
15482 ;; ??? Add SSE splitters for these!
15483 (define_insn "*fop_df_2<mode>_i387"
15484 [(set (match_operand:DF 0 "register_operand" "=f,f")
15485 (match_operator:DF 3 "binary_fp_operator"
15486 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15487 (match_operand:DF 2 "register_operand" "0,0")]))]
15488 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15489 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15490 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15491 [(set (attr "type")
15492 (cond [(match_operand:DF 3 "mult_operator" "")
15493 (const_string "fmul")
15494 (match_operand:DF 3 "div_operator" "")
15495 (const_string "fdiv")
15497 (const_string "fop")))
15498 (set_attr "fp_int_src" "true")
15499 (set_attr "mode" "<MODE>")])
15501 (define_insn "*fop_df_3<mode>_i387"
15502 [(set (match_operand:DF 0 "register_operand" "=f,f")
15503 (match_operator:DF 3 "binary_fp_operator"
15504 [(match_operand:DF 1 "register_operand" "0,0")
15505 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15506 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15507 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15508 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15509 [(set (attr "type")
15510 (cond [(match_operand:DF 3 "mult_operator" "")
15511 (const_string "fmul")
15512 (match_operand:DF 3 "div_operator" "")
15513 (const_string "fdiv")
15515 (const_string "fop")))
15516 (set_attr "fp_int_src" "true")
15517 (set_attr "mode" "<MODE>")])
15519 (define_insn "*fop_df_4_i387"
15520 [(set (match_operand:DF 0 "register_operand" "=f,f")
15521 (match_operator:DF 3 "binary_fp_operator"
15522 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15523 (match_operand:DF 2 "register_operand" "0,f")]))]
15524 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15525 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15526 "* return output_387_binary_op (insn, operands);"
15527 [(set (attr "type")
15528 (cond [(match_operand:DF 3 "mult_operator" "")
15529 (const_string "fmul")
15530 (match_operand:DF 3 "div_operator" "")
15531 (const_string "fdiv")
15533 (const_string "fop")))
15534 (set_attr "mode" "SF")])
15536 (define_insn "*fop_df_5_i387"
15537 [(set (match_operand:DF 0 "register_operand" "=f,f")
15538 (match_operator:DF 3 "binary_fp_operator"
15539 [(match_operand:DF 1 "register_operand" "0,f")
15541 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15542 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15543 "* return output_387_binary_op (insn, operands);"
15544 [(set (attr "type")
15545 (cond [(match_operand:DF 3 "mult_operator" "")
15546 (const_string "fmul")
15547 (match_operand:DF 3 "div_operator" "")
15548 (const_string "fdiv")
15550 (const_string "fop")))
15551 (set_attr "mode" "SF")])
15553 (define_insn "*fop_df_6_i387"
15554 [(set (match_operand:DF 0 "register_operand" "=f,f")
15555 (match_operator:DF 3 "binary_fp_operator"
15557 (match_operand:SF 1 "register_operand" "0,f"))
15559 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15560 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15561 "* return output_387_binary_op (insn, operands);"
15562 [(set (attr "type")
15563 (cond [(match_operand:DF 3 "mult_operator" "")
15564 (const_string "fmul")
15565 (match_operand:DF 3 "div_operator" "")
15566 (const_string "fdiv")
15568 (const_string "fop")))
15569 (set_attr "mode" "SF")])
15571 (define_insn "*fop_xf_comm_i387"
15572 [(set (match_operand:XF 0 "register_operand" "=f")
15573 (match_operator:XF 3 "binary_fp_operator"
15574 [(match_operand:XF 1 "register_operand" "%0")
15575 (match_operand:XF 2 "register_operand" "f")]))]
15577 && COMMUTATIVE_ARITH_P (operands[3])"
15578 "* return output_387_binary_op (insn, operands);"
15579 [(set (attr "type")
15580 (if_then_else (match_operand:XF 3 "mult_operator" "")
15581 (const_string "fmul")
15582 (const_string "fop")))
15583 (set_attr "mode" "XF")])
15585 (define_insn "*fop_xf_1_i387"
15586 [(set (match_operand:XF 0 "register_operand" "=f,f")
15587 (match_operator:XF 3 "binary_fp_operator"
15588 [(match_operand:XF 1 "register_operand" "0,f")
15589 (match_operand:XF 2 "register_operand" "f,0")]))]
15591 && !COMMUTATIVE_ARITH_P (operands[3])"
15592 "* return output_387_binary_op (insn, operands);"
15593 [(set (attr "type")
15594 (cond [(match_operand:XF 3 "mult_operator" "")
15595 (const_string "fmul")
15596 (match_operand:XF 3 "div_operator" "")
15597 (const_string "fdiv")
15599 (const_string "fop")))
15600 (set_attr "mode" "XF")])
15602 (define_insn "*fop_xf_2<mode>_i387"
15603 [(set (match_operand:XF 0 "register_operand" "=f,f")
15604 (match_operator:XF 3 "binary_fp_operator"
15605 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15606 (match_operand:XF 2 "register_operand" "0,0")]))]
15607 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15608 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15609 [(set (attr "type")
15610 (cond [(match_operand:XF 3 "mult_operator" "")
15611 (const_string "fmul")
15612 (match_operand:XF 3 "div_operator" "")
15613 (const_string "fdiv")
15615 (const_string "fop")))
15616 (set_attr "fp_int_src" "true")
15617 (set_attr "mode" "<MODE>")])
15619 (define_insn "*fop_xf_3<mode>_i387"
15620 [(set (match_operand:XF 0 "register_operand" "=f,f")
15621 (match_operator:XF 3 "binary_fp_operator"
15622 [(match_operand:XF 1 "register_operand" "0,0")
15623 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15624 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15625 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15626 [(set (attr "type")
15627 (cond [(match_operand:XF 3 "mult_operator" "")
15628 (const_string "fmul")
15629 (match_operand:XF 3 "div_operator" "")
15630 (const_string "fdiv")
15632 (const_string "fop")))
15633 (set_attr "fp_int_src" "true")
15634 (set_attr "mode" "<MODE>")])
15636 (define_insn "*fop_xf_4_i387"
15637 [(set (match_operand:XF 0 "register_operand" "=f,f")
15638 (match_operator:XF 3 "binary_fp_operator"
15639 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15640 (match_operand:XF 2 "register_operand" "0,f")]))]
15642 "* return output_387_binary_op (insn, operands);"
15643 [(set (attr "type")
15644 (cond [(match_operand:XF 3 "mult_operator" "")
15645 (const_string "fmul")
15646 (match_operand:XF 3 "div_operator" "")
15647 (const_string "fdiv")
15649 (const_string "fop")))
15650 (set_attr "mode" "SF")])
15652 (define_insn "*fop_xf_5_i387"
15653 [(set (match_operand:XF 0 "register_operand" "=f,f")
15654 (match_operator:XF 3 "binary_fp_operator"
15655 [(match_operand:XF 1 "register_operand" "0,f")
15657 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15659 "* return output_387_binary_op (insn, operands);"
15660 [(set (attr "type")
15661 (cond [(match_operand:XF 3 "mult_operator" "")
15662 (const_string "fmul")
15663 (match_operand:XF 3 "div_operator" "")
15664 (const_string "fdiv")
15666 (const_string "fop")))
15667 (set_attr "mode" "SF")])
15669 (define_insn "*fop_xf_6_i387"
15670 [(set (match_operand:XF 0 "register_operand" "=f,f")
15671 (match_operator:XF 3 "binary_fp_operator"
15673 (match_operand 1 "register_operand" "0,f"))
15675 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15677 "* return output_387_binary_op (insn, operands);"
15678 [(set (attr "type")
15679 (cond [(match_operand:XF 3 "mult_operator" "")
15680 (const_string "fmul")
15681 (match_operand:XF 3 "div_operator" "")
15682 (const_string "fdiv")
15684 (const_string "fop")))
15685 (set_attr "mode" "SF")])
15688 [(set (match_operand 0 "register_operand" "")
15689 (match_operator 3 "binary_fp_operator"
15690 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15691 (match_operand 2 "register_operand" "")]))]
15692 "TARGET_80387 && reload_completed
15693 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15696 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15697 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15698 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15699 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15700 GET_MODE (operands[3]),
15703 ix86_free_from_memory (GET_MODE (operands[1]));
15708 [(set (match_operand 0 "register_operand" "")
15709 (match_operator 3 "binary_fp_operator"
15710 [(match_operand 1 "register_operand" "")
15711 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15712 "TARGET_80387 && reload_completed
15713 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15716 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15717 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15718 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15719 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15720 GET_MODE (operands[3]),
15723 ix86_free_from_memory (GET_MODE (operands[2]));
15727 ;; FPU special functions.
15729 (define_expand "sqrtsf2"
15730 [(set (match_operand:SF 0 "register_operand" "")
15731 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15732 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15734 if (!TARGET_SSE_MATH)
15735 operands[1] = force_reg (SFmode, operands[1]);
15738 (define_insn "*sqrtsf2_mixed"
15739 [(set (match_operand:SF 0 "register_operand" "=f,x")
15740 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15741 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15744 sqrtss\t{%1, %0|%0, %1}"
15745 [(set_attr "type" "fpspc,sse")
15746 (set_attr "mode" "SF,SF")
15747 (set_attr "athlon_decode" "direct,*")
15748 (set_attr "amdfam10_decode" "direct,*")])
15750 (define_insn "*sqrtsf2_sse"
15751 [(set (match_operand:SF 0 "register_operand" "=x")
15752 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15754 "sqrtss\t{%1, %0|%0, %1}"
15755 [(set_attr "type" "sse")
15756 (set_attr "mode" "SF")
15757 (set_attr "athlon_decode" "*")
15758 (set_attr "amdfam10_decode" "*")])
15760 (define_insn "*sqrtsf2_i387"
15761 [(set (match_operand:SF 0 "register_operand" "=f")
15762 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15763 "TARGET_USE_FANCY_MATH_387"
15765 [(set_attr "type" "fpspc")
15766 (set_attr "mode" "SF")
15767 (set_attr "athlon_decode" "direct")
15768 (set_attr "amdfam10_decode" "direct")])
15770 (define_expand "sqrtdf2"
15771 [(set (match_operand:DF 0 "register_operand" "")
15772 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15773 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15775 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15776 operands[1] = force_reg (DFmode, operands[1]);
15779 (define_insn "*sqrtdf2_mixed"
15780 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15781 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15782 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15785 sqrtsd\t{%1, %0|%0, %1}"
15786 [(set_attr "type" "fpspc,sse")
15787 (set_attr "mode" "DF,DF")
15788 (set_attr "athlon_decode" "direct,*")
15789 (set_attr "amdfam10_decode" "direct,*")])
15791 (define_insn "*sqrtdf2_sse"
15792 [(set (match_operand:DF 0 "register_operand" "=Y")
15793 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15794 "TARGET_SSE2 && TARGET_SSE_MATH"
15795 "sqrtsd\t{%1, %0|%0, %1}"
15796 [(set_attr "type" "sse")
15797 (set_attr "mode" "DF")
15798 (set_attr "athlon_decode" "*")
15799 (set_attr "amdfam10_decode" "*")])
15801 (define_insn "*sqrtdf2_i387"
15802 [(set (match_operand:DF 0 "register_operand" "=f")
15803 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15804 "TARGET_USE_FANCY_MATH_387"
15806 [(set_attr "type" "fpspc")
15807 (set_attr "mode" "DF")
15808 (set_attr "athlon_decode" "direct")
15809 (set_attr "amdfam10_decode" "direct")])
15811 (define_insn "*sqrtextendsfdf2_i387"
15812 [(set (match_operand:DF 0 "register_operand" "=f")
15813 (sqrt:DF (float_extend:DF
15814 (match_operand:SF 1 "register_operand" "0"))))]
15815 "TARGET_USE_FANCY_MATH_387
15816 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15818 [(set_attr "type" "fpspc")
15819 (set_attr "mode" "DF")
15820 (set_attr "athlon_decode" "direct")
15821 (set_attr "amdfam10_decode" "direct")])
15823 (define_insn "sqrtxf2"
15824 [(set (match_operand:XF 0 "register_operand" "=f")
15825 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15826 "TARGET_USE_FANCY_MATH_387"
15828 [(set_attr "type" "fpspc")
15829 (set_attr "mode" "XF")
15830 (set_attr "athlon_decode" "direct")
15831 (set_attr "amdfam10_decode" "direct")])
15833 (define_insn "*sqrtextendsfxf2_i387"
15834 [(set (match_operand:XF 0 "register_operand" "=f")
15835 (sqrt:XF (float_extend:XF
15836 (match_operand:SF 1 "register_operand" "0"))))]
15837 "TARGET_USE_FANCY_MATH_387"
15839 [(set_attr "type" "fpspc")
15840 (set_attr "mode" "XF")
15841 (set_attr "athlon_decode" "direct")
15842 (set_attr "amdfam10_decode" "direct")])
15844 (define_insn "*sqrtextenddfxf2_i387"
15845 [(set (match_operand:XF 0 "register_operand" "=f")
15846 (sqrt:XF (float_extend:XF
15847 (match_operand:DF 1 "register_operand" "0"))))]
15848 "TARGET_USE_FANCY_MATH_387"
15850 [(set_attr "type" "fpspc")
15851 (set_attr "mode" "XF")
15852 (set_attr "athlon_decode" "direct")
15853 (set_attr "amdfam10_decode" "direct")])
15855 (define_insn "fpremxf4"
15856 [(set (match_operand:XF 0 "register_operand" "=f")
15857 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15858 (match_operand:XF 3 "register_operand" "1")]
15860 (set (match_operand:XF 1 "register_operand" "=u")
15861 (unspec:XF [(match_dup 2) (match_dup 3)]
15863 (set (reg:CCFP FPSR_REG)
15864 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15865 "TARGET_USE_FANCY_MATH_387
15866 && flag_unsafe_math_optimizations"
15868 [(set_attr "type" "fpspc")
15869 (set_attr "mode" "XF")])
15871 (define_expand "fmodsf3"
15872 [(use (match_operand:SF 0 "register_operand" ""))
15873 (use (match_operand:SF 1 "register_operand" ""))
15874 (use (match_operand:SF 2 "register_operand" ""))]
15875 "TARGET_USE_FANCY_MATH_387
15876 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15877 && flag_unsafe_math_optimizations"
15879 rtx label = gen_label_rtx ();
15881 rtx op1 = gen_reg_rtx (XFmode);
15882 rtx op2 = gen_reg_rtx (XFmode);
15884 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15885 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15887 emit_label (label);
15889 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15890 ix86_emit_fp_unordered_jump (label);
15892 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15896 (define_expand "fmoddf3"
15897 [(use (match_operand:DF 0 "register_operand" ""))
15898 (use (match_operand:DF 1 "register_operand" ""))
15899 (use (match_operand:DF 2 "register_operand" ""))]
15900 "TARGET_USE_FANCY_MATH_387
15901 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15902 && flag_unsafe_math_optimizations"
15904 rtx label = gen_label_rtx ();
15906 rtx op1 = gen_reg_rtx (XFmode);
15907 rtx op2 = gen_reg_rtx (XFmode);
15909 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15910 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15912 emit_label (label);
15914 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15915 ix86_emit_fp_unordered_jump (label);
15917 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15921 (define_expand "fmodxf3"
15922 [(use (match_operand:XF 0 "register_operand" ""))
15923 (use (match_operand:XF 1 "register_operand" ""))
15924 (use (match_operand:XF 2 "register_operand" ""))]
15925 "TARGET_USE_FANCY_MATH_387
15926 && flag_unsafe_math_optimizations"
15928 rtx label = gen_label_rtx ();
15930 emit_label (label);
15932 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15933 operands[1], operands[2]));
15934 ix86_emit_fp_unordered_jump (label);
15936 emit_move_insn (operands[0], operands[1]);
15940 (define_insn "fprem1xf4"
15941 [(set (match_operand:XF 0 "register_operand" "=f")
15942 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15943 (match_operand:XF 3 "register_operand" "1")]
15945 (set (match_operand:XF 1 "register_operand" "=u")
15946 (unspec:XF [(match_dup 2) (match_dup 3)]
15948 (set (reg:CCFP FPSR_REG)
15949 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15950 "TARGET_USE_FANCY_MATH_387
15951 && flag_unsafe_math_optimizations"
15953 [(set_attr "type" "fpspc")
15954 (set_attr "mode" "XF")])
15956 (define_expand "dremsf3"
15957 [(use (match_operand:SF 0 "register_operand" ""))
15958 (use (match_operand:SF 1 "register_operand" ""))
15959 (use (match_operand:SF 2 "register_operand" ""))]
15960 "TARGET_USE_FANCY_MATH_387
15961 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15962 && flag_unsafe_math_optimizations"
15964 rtx label = gen_label_rtx ();
15966 rtx op1 = gen_reg_rtx (XFmode);
15967 rtx op2 = gen_reg_rtx (XFmode);
15969 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15970 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15972 emit_label (label);
15974 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15975 ix86_emit_fp_unordered_jump (label);
15977 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15981 (define_expand "dremdf3"
15982 [(use (match_operand:DF 0 "register_operand" ""))
15983 (use (match_operand:DF 1 "register_operand" ""))
15984 (use (match_operand:DF 2 "register_operand" ""))]
15985 "TARGET_USE_FANCY_MATH_387
15986 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15987 && flag_unsafe_math_optimizations"
15989 rtx label = gen_label_rtx ();
15991 rtx op1 = gen_reg_rtx (XFmode);
15992 rtx op2 = gen_reg_rtx (XFmode);
15994 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15995 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15997 emit_label (label);
15999 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
16000 ix86_emit_fp_unordered_jump (label);
16002 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
16006 (define_expand "dremxf3"
16007 [(use (match_operand:XF 0 "register_operand" ""))
16008 (use (match_operand:XF 1 "register_operand" ""))
16009 (use (match_operand:XF 2 "register_operand" ""))]
16010 "TARGET_USE_FANCY_MATH_387
16011 && flag_unsafe_math_optimizations"
16013 rtx label = gen_label_rtx ();
16015 emit_label (label);
16017 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
16018 operands[1], operands[2]));
16019 ix86_emit_fp_unordered_jump (label);
16021 emit_move_insn (operands[0], operands[1]);
16025 (define_insn "*sindf2"
16026 [(set (match_operand:DF 0 "register_operand" "=f")
16027 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
16028 "TARGET_USE_FANCY_MATH_387
16029 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16030 && flag_unsafe_math_optimizations"
16032 [(set_attr "type" "fpspc")
16033 (set_attr "mode" "DF")])
16035 (define_insn "*sinsf2"
16036 [(set (match_operand:SF 0 "register_operand" "=f")
16037 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
16038 "TARGET_USE_FANCY_MATH_387
16039 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16040 && flag_unsafe_math_optimizations"
16042 [(set_attr "type" "fpspc")
16043 (set_attr "mode" "SF")])
16045 (define_insn "*sinextendsfdf2"
16046 [(set (match_operand:DF 0 "register_operand" "=f")
16047 (unspec:DF [(float_extend:DF
16048 (match_operand:SF 1 "register_operand" "0"))]
16050 "TARGET_USE_FANCY_MATH_387
16051 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16052 && flag_unsafe_math_optimizations"
16054 [(set_attr "type" "fpspc")
16055 (set_attr "mode" "DF")])
16057 (define_insn "*sinxf2"
16058 [(set (match_operand:XF 0 "register_operand" "=f")
16059 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16060 "TARGET_USE_FANCY_MATH_387
16061 && flag_unsafe_math_optimizations"
16063 [(set_attr "type" "fpspc")
16064 (set_attr "mode" "XF")])
16066 (define_insn "*cosdf2"
16067 [(set (match_operand:DF 0 "register_operand" "=f")
16068 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
16069 "TARGET_USE_FANCY_MATH_387
16070 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16071 && flag_unsafe_math_optimizations"
16073 [(set_attr "type" "fpspc")
16074 (set_attr "mode" "DF")])
16076 (define_insn "*cossf2"
16077 [(set (match_operand:SF 0 "register_operand" "=f")
16078 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
16079 "TARGET_USE_FANCY_MATH_387
16080 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16081 && flag_unsafe_math_optimizations"
16083 [(set_attr "type" "fpspc")
16084 (set_attr "mode" "SF")])
16086 (define_insn "*cosextendsfdf2"
16087 [(set (match_operand:DF 0 "register_operand" "=f")
16088 (unspec:DF [(float_extend:DF
16089 (match_operand:SF 1 "register_operand" "0"))]
16091 "TARGET_USE_FANCY_MATH_387
16092 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16093 && flag_unsafe_math_optimizations"
16095 [(set_attr "type" "fpspc")
16096 (set_attr "mode" "DF")])
16098 (define_insn "*cosxf2"
16099 [(set (match_operand:XF 0 "register_operand" "=f")
16100 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16101 "TARGET_USE_FANCY_MATH_387
16102 && flag_unsafe_math_optimizations"
16104 [(set_attr "type" "fpspc")
16105 (set_attr "mode" "XF")])
16107 ;; With sincos pattern defined, sin and cos builtin function will be
16108 ;; expanded to sincos pattern with one of its outputs left unused.
16109 ;; Cse pass will detected, if two sincos patterns can be combined,
16110 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16111 ;; depending on the unused output.
16113 (define_insn "sincosdf3"
16114 [(set (match_operand:DF 0 "register_operand" "=f")
16115 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16116 UNSPEC_SINCOS_COS))
16117 (set (match_operand:DF 1 "register_operand" "=u")
16118 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16119 "TARGET_USE_FANCY_MATH_387
16120 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16121 && flag_unsafe_math_optimizations"
16123 [(set_attr "type" "fpspc")
16124 (set_attr "mode" "DF")])
16127 [(set (match_operand:DF 0 "register_operand" "")
16128 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16129 UNSPEC_SINCOS_COS))
16130 (set (match_operand:DF 1 "register_operand" "")
16131 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16132 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16133 && !reload_completed && !reload_in_progress"
16134 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
16138 [(set (match_operand:DF 0 "register_operand" "")
16139 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16140 UNSPEC_SINCOS_COS))
16141 (set (match_operand:DF 1 "register_operand" "")
16142 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16143 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16144 && !reload_completed && !reload_in_progress"
16145 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
16148 (define_insn "sincossf3"
16149 [(set (match_operand:SF 0 "register_operand" "=f")
16150 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16151 UNSPEC_SINCOS_COS))
16152 (set (match_operand:SF 1 "register_operand" "=u")
16153 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16154 "TARGET_USE_FANCY_MATH_387
16155 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16156 && flag_unsafe_math_optimizations"
16158 [(set_attr "type" "fpspc")
16159 (set_attr "mode" "SF")])
16162 [(set (match_operand:SF 0 "register_operand" "")
16163 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16164 UNSPEC_SINCOS_COS))
16165 (set (match_operand:SF 1 "register_operand" "")
16166 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16167 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16168 && !reload_completed && !reload_in_progress"
16169 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
16173 [(set (match_operand:SF 0 "register_operand" "")
16174 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16175 UNSPEC_SINCOS_COS))
16176 (set (match_operand:SF 1 "register_operand" "")
16177 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16178 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16179 && !reload_completed && !reload_in_progress"
16180 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
16183 (define_insn "*sincosextendsfdf3"
16184 [(set (match_operand:DF 0 "register_operand" "=f")
16185 (unspec:DF [(float_extend:DF
16186 (match_operand:SF 2 "register_operand" "0"))]
16187 UNSPEC_SINCOS_COS))
16188 (set (match_operand:DF 1 "register_operand" "=u")
16189 (unspec:DF [(float_extend:DF
16190 (match_dup 2))] UNSPEC_SINCOS_SIN))]
16191 "TARGET_USE_FANCY_MATH_387
16192 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16193 && flag_unsafe_math_optimizations"
16195 [(set_attr "type" "fpspc")
16196 (set_attr "mode" "DF")])
16199 [(set (match_operand:DF 0 "register_operand" "")
16200 (unspec:DF [(float_extend:DF
16201 (match_operand:SF 2 "register_operand" ""))]
16202 UNSPEC_SINCOS_COS))
16203 (set (match_operand:DF 1 "register_operand" "")
16204 (unspec:DF [(float_extend:DF
16205 (match_dup 2))] UNSPEC_SINCOS_SIN))]
16206 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16207 && !reload_completed && !reload_in_progress"
16208 [(set (match_dup 1) (unspec:DF [(float_extend:DF
16209 (match_dup 2))] UNSPEC_SIN))]
16213 [(set (match_operand:DF 0 "register_operand" "")
16214 (unspec:DF [(float_extend:DF
16215 (match_operand:SF 2 "register_operand" ""))]
16216 UNSPEC_SINCOS_COS))
16217 (set (match_operand:DF 1 "register_operand" "")
16218 (unspec:DF [(float_extend:DF
16219 (match_dup 2))] UNSPEC_SINCOS_SIN))]
16220 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16221 && !reload_completed && !reload_in_progress"
16222 [(set (match_dup 0) (unspec:DF [(float_extend:DF
16223 (match_dup 2))] UNSPEC_COS))]
16226 (define_insn "sincosxf3"
16227 [(set (match_operand:XF 0 "register_operand" "=f")
16228 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16229 UNSPEC_SINCOS_COS))
16230 (set (match_operand:XF 1 "register_operand" "=u")
16231 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16232 "TARGET_USE_FANCY_MATH_387
16233 && flag_unsafe_math_optimizations"
16235 [(set_attr "type" "fpspc")
16236 (set_attr "mode" "XF")])
16239 [(set (match_operand:XF 0 "register_operand" "")
16240 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16241 UNSPEC_SINCOS_COS))
16242 (set (match_operand:XF 1 "register_operand" "")
16243 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16244 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16245 && !reload_completed && !reload_in_progress"
16246 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16250 [(set (match_operand:XF 0 "register_operand" "")
16251 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16252 UNSPEC_SINCOS_COS))
16253 (set (match_operand:XF 1 "register_operand" "")
16254 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16255 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16256 && !reload_completed && !reload_in_progress"
16257 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16260 (define_insn "*tandf3_1"
16261 [(set (match_operand:DF 0 "register_operand" "=f")
16262 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16264 (set (match_operand:DF 1 "register_operand" "=u")
16265 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16266 "TARGET_USE_FANCY_MATH_387
16267 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16268 && flag_unsafe_math_optimizations"
16270 [(set_attr "type" "fpspc")
16271 (set_attr "mode" "DF")])
16273 ;; optimize sequence: fptan
16276 ;; into fptan insn.
16279 [(parallel[(set (match_operand:DF 0 "register_operand" "")
16280 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16282 (set (match_operand:DF 1 "register_operand" "")
16283 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16285 (match_operand:DF 3 "immediate_operand" ""))]
16286 "standard_80387_constant_p (operands[3]) == 2"
16287 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16288 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16291 (define_expand "tandf2"
16292 [(parallel [(set (match_dup 2)
16293 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16295 (set (match_operand:DF 0 "register_operand" "")
16296 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16297 "TARGET_USE_FANCY_MATH_387
16298 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16299 && flag_unsafe_math_optimizations"
16301 operands[2] = gen_reg_rtx (DFmode);
16304 (define_insn "*tansf3_1"
16305 [(set (match_operand:SF 0 "register_operand" "=f")
16306 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16308 (set (match_operand:SF 1 "register_operand" "=u")
16309 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16310 "TARGET_USE_FANCY_MATH_387
16311 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16312 && flag_unsafe_math_optimizations"
16314 [(set_attr "type" "fpspc")
16315 (set_attr "mode" "SF")])
16317 ;; optimize sequence: fptan
16320 ;; into fptan insn.
16323 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16324 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16326 (set (match_operand:SF 1 "register_operand" "")
16327 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16329 (match_operand:SF 3 "immediate_operand" ""))]
16330 "standard_80387_constant_p (operands[3]) == 2"
16331 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16332 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16335 (define_expand "tansf2"
16336 [(parallel [(set (match_dup 2)
16337 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16339 (set (match_operand:SF 0 "register_operand" "")
16340 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16341 "TARGET_USE_FANCY_MATH_387
16342 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16343 && flag_unsafe_math_optimizations"
16345 operands[2] = gen_reg_rtx (SFmode);
16348 (define_insn "*tanxf3_1"
16349 [(set (match_operand:XF 0 "register_operand" "=f")
16350 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16352 (set (match_operand:XF 1 "register_operand" "=u")
16353 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16354 "TARGET_USE_FANCY_MATH_387
16355 && flag_unsafe_math_optimizations"
16357 [(set_attr "type" "fpspc")
16358 (set_attr "mode" "XF")])
16360 ;; optimize sequence: fptan
16363 ;; into fptan insn.
16366 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16367 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16369 (set (match_operand:XF 1 "register_operand" "")
16370 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16372 (match_operand:XF 3 "immediate_operand" ""))]
16373 "standard_80387_constant_p (operands[3]) == 2"
16374 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16375 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16378 (define_expand "tanxf2"
16379 [(parallel [(set (match_dup 2)
16380 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16382 (set (match_operand:XF 0 "register_operand" "")
16383 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16384 "TARGET_USE_FANCY_MATH_387
16385 && flag_unsafe_math_optimizations"
16387 operands[2] = gen_reg_rtx (XFmode);
16390 (define_insn "atan2df3_1"
16391 [(set (match_operand:DF 0 "register_operand" "=f")
16392 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16393 (match_operand:DF 1 "register_operand" "u")]
16395 (clobber (match_scratch:DF 3 "=1"))]
16396 "TARGET_USE_FANCY_MATH_387
16397 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16398 && flag_unsafe_math_optimizations"
16400 [(set_attr "type" "fpspc")
16401 (set_attr "mode" "DF")])
16403 (define_expand "atan2df3"
16404 [(use (match_operand:DF 0 "register_operand" ""))
16405 (use (match_operand:DF 2 "register_operand" ""))
16406 (use (match_operand:DF 1 "register_operand" ""))]
16407 "TARGET_USE_FANCY_MATH_387
16408 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16409 && flag_unsafe_math_optimizations"
16411 rtx copy = gen_reg_rtx (DFmode);
16412 emit_move_insn (copy, operands[1]);
16413 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16417 (define_expand "atandf2"
16418 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16419 (unspec:DF [(match_dup 2)
16420 (match_operand:DF 1 "register_operand" "")]
16422 (clobber (match_scratch:DF 3 ""))])]
16423 "TARGET_USE_FANCY_MATH_387
16424 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16425 && flag_unsafe_math_optimizations"
16427 operands[2] = gen_reg_rtx (DFmode);
16428 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16431 (define_insn "atan2sf3_1"
16432 [(set (match_operand:SF 0 "register_operand" "=f")
16433 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16434 (match_operand:SF 1 "register_operand" "u")]
16436 (clobber (match_scratch:SF 3 "=1"))]
16437 "TARGET_USE_FANCY_MATH_387
16438 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16439 && flag_unsafe_math_optimizations"
16441 [(set_attr "type" "fpspc")
16442 (set_attr "mode" "SF")])
16444 (define_expand "atan2sf3"
16445 [(use (match_operand:SF 0 "register_operand" ""))
16446 (use (match_operand:SF 2 "register_operand" ""))
16447 (use (match_operand:SF 1 "register_operand" ""))]
16448 "TARGET_USE_FANCY_MATH_387
16449 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16450 && flag_unsafe_math_optimizations"
16452 rtx copy = gen_reg_rtx (SFmode);
16453 emit_move_insn (copy, operands[1]);
16454 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16458 (define_expand "atansf2"
16459 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16460 (unspec:SF [(match_dup 2)
16461 (match_operand:SF 1 "register_operand" "")]
16463 (clobber (match_scratch:SF 3 ""))])]
16464 "TARGET_USE_FANCY_MATH_387
16465 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16466 && flag_unsafe_math_optimizations"
16468 operands[2] = gen_reg_rtx (SFmode);
16469 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16472 (define_insn "atan2xf3_1"
16473 [(set (match_operand:XF 0 "register_operand" "=f")
16474 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16475 (match_operand:XF 1 "register_operand" "u")]
16477 (clobber (match_scratch:XF 3 "=1"))]
16478 "TARGET_USE_FANCY_MATH_387
16479 && flag_unsafe_math_optimizations"
16481 [(set_attr "type" "fpspc")
16482 (set_attr "mode" "XF")])
16484 (define_expand "atan2xf3"
16485 [(use (match_operand:XF 0 "register_operand" ""))
16486 (use (match_operand:XF 2 "register_operand" ""))
16487 (use (match_operand:XF 1 "register_operand" ""))]
16488 "TARGET_USE_FANCY_MATH_387
16489 && flag_unsafe_math_optimizations"
16491 rtx copy = gen_reg_rtx (XFmode);
16492 emit_move_insn (copy, operands[1]);
16493 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16497 (define_expand "atanxf2"
16498 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16499 (unspec:XF [(match_dup 2)
16500 (match_operand:XF 1 "register_operand" "")]
16502 (clobber (match_scratch:XF 3 ""))])]
16503 "TARGET_USE_FANCY_MATH_387
16504 && flag_unsafe_math_optimizations"
16506 operands[2] = gen_reg_rtx (XFmode);
16507 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16510 (define_expand "asindf2"
16511 [(set (match_dup 2)
16512 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16513 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16514 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16515 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16516 (parallel [(set (match_dup 7)
16517 (unspec:XF [(match_dup 6) (match_dup 2)]
16519 (clobber (match_scratch:XF 8 ""))])
16520 (set (match_operand:DF 0 "register_operand" "")
16521 (float_truncate:DF (match_dup 7)))]
16522 "TARGET_USE_FANCY_MATH_387
16523 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16524 && flag_unsafe_math_optimizations"
16528 for (i=2; i<8; i++)
16529 operands[i] = gen_reg_rtx (XFmode);
16531 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16534 (define_expand "asinsf2"
16535 [(set (match_dup 2)
16536 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16537 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16538 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16539 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16540 (parallel [(set (match_dup 7)
16541 (unspec:XF [(match_dup 6) (match_dup 2)]
16543 (clobber (match_scratch:XF 8 ""))])
16544 (set (match_operand:SF 0 "register_operand" "")
16545 (float_truncate:SF (match_dup 7)))]
16546 "TARGET_USE_FANCY_MATH_387
16547 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16548 && flag_unsafe_math_optimizations"
16552 for (i=2; i<8; i++)
16553 operands[i] = gen_reg_rtx (XFmode);
16555 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16558 (define_expand "asinxf2"
16559 [(set (match_dup 2)
16560 (mult:XF (match_operand:XF 1 "register_operand" "")
16562 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16563 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16564 (parallel [(set (match_operand:XF 0 "register_operand" "")
16565 (unspec:XF [(match_dup 5) (match_dup 1)]
16567 (clobber (match_scratch:XF 6 ""))])]
16568 "TARGET_USE_FANCY_MATH_387
16569 && flag_unsafe_math_optimizations"
16573 for (i=2; i<6; i++)
16574 operands[i] = gen_reg_rtx (XFmode);
16576 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16579 (define_expand "acosdf2"
16580 [(set (match_dup 2)
16581 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16582 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16583 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16584 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16585 (parallel [(set (match_dup 7)
16586 (unspec:XF [(match_dup 2) (match_dup 6)]
16588 (clobber (match_scratch:XF 8 ""))])
16589 (set (match_operand:DF 0 "register_operand" "")
16590 (float_truncate:DF (match_dup 7)))]
16591 "TARGET_USE_FANCY_MATH_387
16592 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16593 && flag_unsafe_math_optimizations"
16597 for (i=2; i<8; i++)
16598 operands[i] = gen_reg_rtx (XFmode);
16600 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16603 (define_expand "acossf2"
16604 [(set (match_dup 2)
16605 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16606 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16607 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16608 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16609 (parallel [(set (match_dup 7)
16610 (unspec:XF [(match_dup 2) (match_dup 6)]
16612 (clobber (match_scratch:XF 8 ""))])
16613 (set (match_operand:SF 0 "register_operand" "")
16614 (float_truncate:SF (match_dup 7)))]
16615 "TARGET_USE_FANCY_MATH_387
16616 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16617 && flag_unsafe_math_optimizations"
16621 for (i=2; i<8; i++)
16622 operands[i] = gen_reg_rtx (XFmode);
16624 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16627 (define_expand "acosxf2"
16628 [(set (match_dup 2)
16629 (mult:XF (match_operand:XF 1 "register_operand" "")
16631 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16632 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16633 (parallel [(set (match_operand:XF 0 "register_operand" "")
16634 (unspec:XF [(match_dup 1) (match_dup 5)]
16636 (clobber (match_scratch:XF 6 ""))])]
16637 "TARGET_USE_FANCY_MATH_387
16638 && flag_unsafe_math_optimizations"
16642 for (i=2; i<6; i++)
16643 operands[i] = gen_reg_rtx (XFmode);
16645 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16648 (define_insn "fyl2x_xf3"
16649 [(set (match_operand:XF 0 "register_operand" "=f")
16650 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16651 (match_operand:XF 1 "register_operand" "u")]
16653 (clobber (match_scratch:XF 3 "=1"))]
16654 "TARGET_USE_FANCY_MATH_387
16655 && flag_unsafe_math_optimizations"
16657 [(set_attr "type" "fpspc")
16658 (set_attr "mode" "XF")])
16660 (define_expand "logsf2"
16661 [(set (match_dup 2)
16662 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16663 (parallel [(set (match_dup 4)
16664 (unspec:XF [(match_dup 2)
16665 (match_dup 3)] UNSPEC_FYL2X))
16666 (clobber (match_scratch:XF 5 ""))])
16667 (set (match_operand:SF 0 "register_operand" "")
16668 (float_truncate:SF (match_dup 4)))]
16669 "TARGET_USE_FANCY_MATH_387
16670 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16671 && flag_unsafe_math_optimizations"
16675 operands[2] = gen_reg_rtx (XFmode);
16676 operands[3] = gen_reg_rtx (XFmode);
16677 operands[4] = gen_reg_rtx (XFmode);
16679 temp = standard_80387_constant_rtx (4); /* fldln2 */
16680 emit_move_insn (operands[3], temp);
16683 (define_expand "logdf2"
16684 [(set (match_dup 2)
16685 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16686 (parallel [(set (match_dup 4)
16687 (unspec:XF [(match_dup 2)
16688 (match_dup 3)] UNSPEC_FYL2X))
16689 (clobber (match_scratch:XF 5 ""))])
16690 (set (match_operand:DF 0 "register_operand" "")
16691 (float_truncate:DF (match_dup 4)))]
16692 "TARGET_USE_FANCY_MATH_387
16693 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16694 && flag_unsafe_math_optimizations"
16698 operands[2] = gen_reg_rtx (XFmode);
16699 operands[3] = gen_reg_rtx (XFmode);
16700 operands[4] = gen_reg_rtx (XFmode);
16702 temp = standard_80387_constant_rtx (4); /* fldln2 */
16703 emit_move_insn (operands[3], temp);
16706 (define_expand "logxf2"
16707 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16708 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16709 (match_dup 2)] UNSPEC_FYL2X))
16710 (clobber (match_scratch:XF 3 ""))])]
16711 "TARGET_USE_FANCY_MATH_387
16712 && flag_unsafe_math_optimizations"
16716 operands[2] = gen_reg_rtx (XFmode);
16717 temp = standard_80387_constant_rtx (4); /* fldln2 */
16718 emit_move_insn (operands[2], temp);
16721 (define_expand "log10sf2"
16722 [(set (match_dup 2)
16723 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16724 (parallel [(set (match_dup 4)
16725 (unspec:XF [(match_dup 2)
16726 (match_dup 3)] UNSPEC_FYL2X))
16727 (clobber (match_scratch:XF 5 ""))])
16728 (set (match_operand:SF 0 "register_operand" "")
16729 (float_truncate:SF (match_dup 4)))]
16730 "TARGET_USE_FANCY_MATH_387
16731 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16732 && flag_unsafe_math_optimizations"
16736 operands[2] = gen_reg_rtx (XFmode);
16737 operands[3] = gen_reg_rtx (XFmode);
16738 operands[4] = gen_reg_rtx (XFmode);
16740 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16741 emit_move_insn (operands[3], temp);
16744 (define_expand "log10df2"
16745 [(set (match_dup 2)
16746 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16747 (parallel [(set (match_dup 4)
16748 (unspec:XF [(match_dup 2)
16749 (match_dup 3)] UNSPEC_FYL2X))
16750 (clobber (match_scratch:XF 5 ""))])
16751 (set (match_operand:DF 0 "register_operand" "")
16752 (float_truncate:DF (match_dup 4)))]
16753 "TARGET_USE_FANCY_MATH_387
16754 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16755 && flag_unsafe_math_optimizations"
16759 operands[2] = gen_reg_rtx (XFmode);
16760 operands[3] = gen_reg_rtx (XFmode);
16761 operands[4] = gen_reg_rtx (XFmode);
16763 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16764 emit_move_insn (operands[3], temp);
16767 (define_expand "log10xf2"
16768 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16769 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16770 (match_dup 2)] UNSPEC_FYL2X))
16771 (clobber (match_scratch:XF 3 ""))])]
16772 "TARGET_USE_FANCY_MATH_387
16773 && flag_unsafe_math_optimizations"
16777 operands[2] = gen_reg_rtx (XFmode);
16778 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16779 emit_move_insn (operands[2], temp);
16782 (define_expand "log2sf2"
16783 [(set (match_dup 2)
16784 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16785 (parallel [(set (match_dup 4)
16786 (unspec:XF [(match_dup 2)
16787 (match_dup 3)] UNSPEC_FYL2X))
16788 (clobber (match_scratch:XF 5 ""))])
16789 (set (match_operand:SF 0 "register_operand" "")
16790 (float_truncate:SF (match_dup 4)))]
16791 "TARGET_USE_FANCY_MATH_387
16792 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16793 && flag_unsafe_math_optimizations"
16795 operands[2] = gen_reg_rtx (XFmode);
16796 operands[3] = gen_reg_rtx (XFmode);
16797 operands[4] = gen_reg_rtx (XFmode);
16799 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16802 (define_expand "log2df2"
16803 [(set (match_dup 2)
16804 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16805 (parallel [(set (match_dup 4)
16806 (unspec:XF [(match_dup 2)
16807 (match_dup 3)] UNSPEC_FYL2X))
16808 (clobber (match_scratch:XF 5 ""))])
16809 (set (match_operand:DF 0 "register_operand" "")
16810 (float_truncate:DF (match_dup 4)))]
16811 "TARGET_USE_FANCY_MATH_387
16812 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16813 && flag_unsafe_math_optimizations"
16815 operands[2] = gen_reg_rtx (XFmode);
16816 operands[3] = gen_reg_rtx (XFmode);
16817 operands[4] = gen_reg_rtx (XFmode);
16819 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16822 (define_expand "log2xf2"
16823 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16824 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16825 (match_dup 2)] UNSPEC_FYL2X))
16826 (clobber (match_scratch:XF 3 ""))])]
16827 "TARGET_USE_FANCY_MATH_387
16828 && flag_unsafe_math_optimizations"
16830 operands[2] = gen_reg_rtx (XFmode);
16831 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16834 (define_insn "fyl2xp1_xf3"
16835 [(set (match_operand:XF 0 "register_operand" "=f")
16836 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16837 (match_operand:XF 1 "register_operand" "u")]
16839 (clobber (match_scratch:XF 3 "=1"))]
16840 "TARGET_USE_FANCY_MATH_387
16841 && flag_unsafe_math_optimizations"
16843 [(set_attr "type" "fpspc")
16844 (set_attr "mode" "XF")])
16846 (define_expand "log1psf2"
16847 [(use (match_operand:SF 0 "register_operand" ""))
16848 (use (match_operand:SF 1 "register_operand" ""))]
16849 "TARGET_USE_FANCY_MATH_387
16850 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16851 && flag_unsafe_math_optimizations"
16853 rtx op0 = gen_reg_rtx (XFmode);
16854 rtx op1 = gen_reg_rtx (XFmode);
16856 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16857 ix86_emit_i387_log1p (op0, op1);
16858 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16862 (define_expand "log1pdf2"
16863 [(use (match_operand:DF 0 "register_operand" ""))
16864 (use (match_operand:DF 1 "register_operand" ""))]
16865 "TARGET_USE_FANCY_MATH_387
16866 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16867 && flag_unsafe_math_optimizations"
16869 rtx op0 = gen_reg_rtx (XFmode);
16870 rtx op1 = gen_reg_rtx (XFmode);
16872 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16873 ix86_emit_i387_log1p (op0, op1);
16874 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16878 (define_expand "log1pxf2"
16879 [(use (match_operand:XF 0 "register_operand" ""))
16880 (use (match_operand:XF 1 "register_operand" ""))]
16881 "TARGET_USE_FANCY_MATH_387
16882 && flag_unsafe_math_optimizations"
16884 ix86_emit_i387_log1p (operands[0], operands[1]);
16888 (define_insn "*fxtractxf3"
16889 [(set (match_operand:XF 0 "register_operand" "=f")
16890 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16891 UNSPEC_XTRACT_FRACT))
16892 (set (match_operand:XF 1 "register_operand" "=u")
16893 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16894 "TARGET_USE_FANCY_MATH_387
16895 && flag_unsafe_math_optimizations"
16897 [(set_attr "type" "fpspc")
16898 (set_attr "mode" "XF")])
16900 (define_expand "logbsf2"
16901 [(set (match_dup 2)
16902 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16903 (parallel [(set (match_dup 3)
16904 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16906 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16907 (set (match_operand:SF 0 "register_operand" "")
16908 (float_truncate:SF (match_dup 4)))]
16909 "TARGET_USE_FANCY_MATH_387
16910 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16911 && flag_unsafe_math_optimizations"
16913 operands[2] = gen_reg_rtx (XFmode);
16914 operands[3] = gen_reg_rtx (XFmode);
16915 operands[4] = gen_reg_rtx (XFmode);
16918 (define_expand "logbdf2"
16919 [(set (match_dup 2)
16920 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16921 (parallel [(set (match_dup 3)
16922 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16924 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16925 (set (match_operand:DF 0 "register_operand" "")
16926 (float_truncate:DF (match_dup 4)))]
16927 "TARGET_USE_FANCY_MATH_387
16928 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16929 && flag_unsafe_math_optimizations"
16931 operands[2] = gen_reg_rtx (XFmode);
16932 operands[3] = gen_reg_rtx (XFmode);
16933 operands[4] = gen_reg_rtx (XFmode);
16936 (define_expand "logbxf2"
16937 [(parallel [(set (match_dup 2)
16938 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16939 UNSPEC_XTRACT_FRACT))
16940 (set (match_operand:XF 0 "register_operand" "")
16941 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16942 "TARGET_USE_FANCY_MATH_387
16943 && flag_unsafe_math_optimizations"
16945 operands[2] = gen_reg_rtx (XFmode);
16948 (define_expand "ilogbsi2"
16949 [(parallel [(set (match_dup 2)
16950 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16951 UNSPEC_XTRACT_FRACT))
16952 (set (match_operand:XF 3 "register_operand" "")
16953 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16954 (parallel [(set (match_operand:SI 0 "register_operand" "")
16955 (fix:SI (match_dup 3)))
16956 (clobber (reg:CC FLAGS_REG))])]
16957 "TARGET_USE_FANCY_MATH_387
16958 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16959 && flag_unsafe_math_optimizations"
16961 operands[2] = gen_reg_rtx (XFmode);
16962 operands[3] = gen_reg_rtx (XFmode);
16965 (define_insn "*f2xm1xf2"
16966 [(set (match_operand:XF 0 "register_operand" "=f")
16967 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16969 "TARGET_USE_FANCY_MATH_387
16970 && flag_unsafe_math_optimizations"
16972 [(set_attr "type" "fpspc")
16973 (set_attr "mode" "XF")])
16975 (define_insn "*fscalexf4"
16976 [(set (match_operand:XF 0 "register_operand" "=f")
16977 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16978 (match_operand:XF 3 "register_operand" "1")]
16979 UNSPEC_FSCALE_FRACT))
16980 (set (match_operand:XF 1 "register_operand" "=u")
16981 (unspec:XF [(match_dup 2) (match_dup 3)]
16982 UNSPEC_FSCALE_EXP))]
16983 "TARGET_USE_FANCY_MATH_387
16984 && flag_unsafe_math_optimizations"
16986 [(set_attr "type" "fpspc")
16987 (set_attr "mode" "XF")])
16989 (define_expand "expsf2"
16990 [(set (match_dup 2)
16991 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16992 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16993 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16994 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16995 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16996 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16997 (parallel [(set (match_dup 10)
16998 (unspec:XF [(match_dup 9) (match_dup 5)]
16999 UNSPEC_FSCALE_FRACT))
17000 (set (match_dup 11)
17001 (unspec:XF [(match_dup 9) (match_dup 5)]
17002 UNSPEC_FSCALE_EXP))])
17003 (set (match_operand:SF 0 "register_operand" "")
17004 (float_truncate:SF (match_dup 10)))]
17005 "TARGET_USE_FANCY_MATH_387
17006 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17007 && flag_unsafe_math_optimizations"
17012 for (i=2; i<12; i++)
17013 operands[i] = gen_reg_rtx (XFmode);
17014 temp = standard_80387_constant_rtx (5); /* fldl2e */
17015 emit_move_insn (operands[3], temp);
17016 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
17019 (define_expand "expdf2"
17020 [(set (match_dup 2)
17021 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17022 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17023 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17024 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17025 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17026 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17027 (parallel [(set (match_dup 10)
17028 (unspec:XF [(match_dup 9) (match_dup 5)]
17029 UNSPEC_FSCALE_FRACT))
17030 (set (match_dup 11)
17031 (unspec:XF [(match_dup 9) (match_dup 5)]
17032 UNSPEC_FSCALE_EXP))])
17033 (set (match_operand:DF 0 "register_operand" "")
17034 (float_truncate:DF (match_dup 10)))]
17035 "TARGET_USE_FANCY_MATH_387
17036 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17037 && flag_unsafe_math_optimizations"
17042 for (i=2; i<12; i++)
17043 operands[i] = gen_reg_rtx (XFmode);
17044 temp = standard_80387_constant_rtx (5); /* fldl2e */
17045 emit_move_insn (operands[3], temp);
17046 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
17049 (define_expand "expxf2"
17050 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17052 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17053 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17054 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17055 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17056 (parallel [(set (match_operand:XF 0 "register_operand" "")
17057 (unspec:XF [(match_dup 8) (match_dup 4)]
17058 UNSPEC_FSCALE_FRACT))
17060 (unspec:XF [(match_dup 8) (match_dup 4)]
17061 UNSPEC_FSCALE_EXP))])]
17062 "TARGET_USE_FANCY_MATH_387
17063 && flag_unsafe_math_optimizations"
17068 for (i=2; i<10; i++)
17069 operands[i] = gen_reg_rtx (XFmode);
17070 temp = standard_80387_constant_rtx (5); /* fldl2e */
17071 emit_move_insn (operands[2], temp);
17072 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17075 (define_expand "exp10sf2"
17076 [(set (match_dup 2)
17077 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17078 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17079 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17080 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17081 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17082 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17083 (parallel [(set (match_dup 10)
17084 (unspec:XF [(match_dup 9) (match_dup 5)]
17085 UNSPEC_FSCALE_FRACT))
17086 (set (match_dup 11)
17087 (unspec:XF [(match_dup 9) (match_dup 5)]
17088 UNSPEC_FSCALE_EXP))])
17089 (set (match_operand:SF 0 "register_operand" "")
17090 (float_truncate:SF (match_dup 10)))]
17091 "TARGET_USE_FANCY_MATH_387
17092 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17093 && flag_unsafe_math_optimizations"
17098 for (i=2; i<12; i++)
17099 operands[i] = gen_reg_rtx (XFmode);
17100 temp = standard_80387_constant_rtx (6); /* fldl2t */
17101 emit_move_insn (operands[3], temp);
17102 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
17105 (define_expand "exp10df2"
17106 [(set (match_dup 2)
17107 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17108 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17109 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17110 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17111 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17112 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17113 (parallel [(set (match_dup 10)
17114 (unspec:XF [(match_dup 9) (match_dup 5)]
17115 UNSPEC_FSCALE_FRACT))
17116 (set (match_dup 11)
17117 (unspec:XF [(match_dup 9) (match_dup 5)]
17118 UNSPEC_FSCALE_EXP))])
17119 (set (match_operand:DF 0 "register_operand" "")
17120 (float_truncate:DF (match_dup 10)))]
17121 "TARGET_USE_FANCY_MATH_387
17122 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17123 && flag_unsafe_math_optimizations"
17128 for (i=2; i<12; i++)
17129 operands[i] = gen_reg_rtx (XFmode);
17130 temp = standard_80387_constant_rtx (6); /* fldl2t */
17131 emit_move_insn (operands[3], temp);
17132 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
17135 (define_expand "exp10xf2"
17136 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17138 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17139 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17140 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17141 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17142 (parallel [(set (match_operand:XF 0 "register_operand" "")
17143 (unspec:XF [(match_dup 8) (match_dup 4)]
17144 UNSPEC_FSCALE_FRACT))
17146 (unspec:XF [(match_dup 8) (match_dup 4)]
17147 UNSPEC_FSCALE_EXP))])]
17148 "TARGET_USE_FANCY_MATH_387
17149 && flag_unsafe_math_optimizations"
17154 for (i=2; i<10; i++)
17155 operands[i] = gen_reg_rtx (XFmode);
17156 temp = standard_80387_constant_rtx (6); /* fldl2t */
17157 emit_move_insn (operands[2], temp);
17158 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17161 (define_expand "exp2sf2"
17162 [(set (match_dup 2)
17163 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17164 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17165 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17166 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17167 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17168 (parallel [(set (match_dup 8)
17169 (unspec:XF [(match_dup 7) (match_dup 3)]
17170 UNSPEC_FSCALE_FRACT))
17172 (unspec:XF [(match_dup 7) (match_dup 3)]
17173 UNSPEC_FSCALE_EXP))])
17174 (set (match_operand:SF 0 "register_operand" "")
17175 (float_truncate:SF (match_dup 8)))]
17176 "TARGET_USE_FANCY_MATH_387
17177 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17178 && flag_unsafe_math_optimizations"
17182 for (i=2; i<10; i++)
17183 operands[i] = gen_reg_rtx (XFmode);
17184 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
17187 (define_expand "exp2df2"
17188 [(set (match_dup 2)
17189 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17190 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17191 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17192 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17193 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17194 (parallel [(set (match_dup 8)
17195 (unspec:XF [(match_dup 7) (match_dup 3)]
17196 UNSPEC_FSCALE_FRACT))
17198 (unspec:XF [(match_dup 7) (match_dup 3)]
17199 UNSPEC_FSCALE_EXP))])
17200 (set (match_operand:DF 0 "register_operand" "")
17201 (float_truncate:DF (match_dup 8)))]
17202 "TARGET_USE_FANCY_MATH_387
17203 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17204 && flag_unsafe_math_optimizations"
17208 for (i=2; i<10; i++)
17209 operands[i] = gen_reg_rtx (XFmode);
17210 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
17213 (define_expand "exp2xf2"
17214 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
17215 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17216 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17217 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17218 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17219 (parallel [(set (match_operand:XF 0 "register_operand" "")
17220 (unspec:XF [(match_dup 7) (match_dup 3)]
17221 UNSPEC_FSCALE_FRACT))
17223 (unspec:XF [(match_dup 7) (match_dup 3)]
17224 UNSPEC_FSCALE_EXP))])]
17225 "TARGET_USE_FANCY_MATH_387
17226 && flag_unsafe_math_optimizations"
17230 for (i=2; i<9; i++)
17231 operands[i] = gen_reg_rtx (XFmode);
17232 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
17235 (define_expand "expm1df2"
17236 [(set (match_dup 2)
17237 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17238 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17239 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17240 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17241 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17242 (parallel [(set (match_dup 8)
17243 (unspec:XF [(match_dup 7) (match_dup 5)]
17244 UNSPEC_FSCALE_FRACT))
17246 (unspec:XF [(match_dup 7) (match_dup 5)]
17247 UNSPEC_FSCALE_EXP))])
17248 (parallel [(set (match_dup 11)
17249 (unspec:XF [(match_dup 10) (match_dup 9)]
17250 UNSPEC_FSCALE_FRACT))
17251 (set (match_dup 12)
17252 (unspec:XF [(match_dup 10) (match_dup 9)]
17253 UNSPEC_FSCALE_EXP))])
17254 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17255 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17256 (set (match_operand:DF 0 "register_operand" "")
17257 (float_truncate:DF (match_dup 14)))]
17258 "TARGET_USE_FANCY_MATH_387
17259 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17260 && flag_unsafe_math_optimizations"
17265 for (i=2; i<15; i++)
17266 operands[i] = gen_reg_rtx (XFmode);
17267 temp = standard_80387_constant_rtx (5); /* fldl2e */
17268 emit_move_insn (operands[3], temp);
17269 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17272 (define_expand "expm1sf2"
17273 [(set (match_dup 2)
17274 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17275 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17276 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17277 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17278 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17279 (parallel [(set (match_dup 8)
17280 (unspec:XF [(match_dup 7) (match_dup 5)]
17281 UNSPEC_FSCALE_FRACT))
17283 (unspec:XF [(match_dup 7) (match_dup 5)]
17284 UNSPEC_FSCALE_EXP))])
17285 (parallel [(set (match_dup 11)
17286 (unspec:XF [(match_dup 10) (match_dup 9)]
17287 UNSPEC_FSCALE_FRACT))
17288 (set (match_dup 12)
17289 (unspec:XF [(match_dup 10) (match_dup 9)]
17290 UNSPEC_FSCALE_EXP))])
17291 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17292 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17293 (set (match_operand:SF 0 "register_operand" "")
17294 (float_truncate:SF (match_dup 14)))]
17295 "TARGET_USE_FANCY_MATH_387
17296 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17297 && flag_unsafe_math_optimizations"
17302 for (i=2; i<15; i++)
17303 operands[i] = gen_reg_rtx (XFmode);
17304 temp = standard_80387_constant_rtx (5); /* fldl2e */
17305 emit_move_insn (operands[3], temp);
17306 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17309 (define_expand "expm1xf2"
17310 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17312 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17313 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17314 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17315 (parallel [(set (match_dup 7)
17316 (unspec:XF [(match_dup 6) (match_dup 4)]
17317 UNSPEC_FSCALE_FRACT))
17319 (unspec:XF [(match_dup 6) (match_dup 4)]
17320 UNSPEC_FSCALE_EXP))])
17321 (parallel [(set (match_dup 10)
17322 (unspec:XF [(match_dup 9) (match_dup 8)]
17323 UNSPEC_FSCALE_FRACT))
17324 (set (match_dup 11)
17325 (unspec:XF [(match_dup 9) (match_dup 8)]
17326 UNSPEC_FSCALE_EXP))])
17327 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17328 (set (match_operand:XF 0 "register_operand" "")
17329 (plus:XF (match_dup 12) (match_dup 7)))]
17330 "TARGET_USE_FANCY_MATH_387
17331 && flag_unsafe_math_optimizations"
17336 for (i=2; i<13; i++)
17337 operands[i] = gen_reg_rtx (XFmode);
17338 temp = standard_80387_constant_rtx (5); /* fldl2e */
17339 emit_move_insn (operands[2], temp);
17340 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17343 (define_expand "ldexpdf3"
17344 [(set (match_dup 3)
17345 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17347 (float:XF (match_operand:SI 2 "register_operand" "")))
17348 (parallel [(set (match_dup 5)
17349 (unspec:XF [(match_dup 3) (match_dup 4)]
17350 UNSPEC_FSCALE_FRACT))
17352 (unspec:XF [(match_dup 3) (match_dup 4)]
17353 UNSPEC_FSCALE_EXP))])
17354 (set (match_operand:DF 0 "register_operand" "")
17355 (float_truncate:DF (match_dup 5)))]
17356 "TARGET_USE_FANCY_MATH_387
17357 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17358 && flag_unsafe_math_optimizations"
17362 for (i=3; i<7; i++)
17363 operands[i] = gen_reg_rtx (XFmode);
17366 (define_expand "ldexpsf3"
17367 [(set (match_dup 3)
17368 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17370 (float:XF (match_operand:SI 2 "register_operand" "")))
17371 (parallel [(set (match_dup 5)
17372 (unspec:XF [(match_dup 3) (match_dup 4)]
17373 UNSPEC_FSCALE_FRACT))
17375 (unspec:XF [(match_dup 3) (match_dup 4)]
17376 UNSPEC_FSCALE_EXP))])
17377 (set (match_operand:SF 0 "register_operand" "")
17378 (float_truncate:SF (match_dup 5)))]
17379 "TARGET_USE_FANCY_MATH_387
17380 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17381 && flag_unsafe_math_optimizations"
17385 for (i=3; i<7; i++)
17386 operands[i] = gen_reg_rtx (XFmode);
17389 (define_expand "ldexpxf3"
17390 [(set (match_dup 3)
17391 (float:XF (match_operand:SI 2 "register_operand" "")))
17392 (parallel [(set (match_operand:XF 0 " register_operand" "")
17393 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17395 UNSPEC_FSCALE_FRACT))
17397 (unspec:XF [(match_dup 1) (match_dup 3)]
17398 UNSPEC_FSCALE_EXP))])]
17399 "TARGET_USE_FANCY_MATH_387
17400 && flag_unsafe_math_optimizations"
17404 for (i=3; i<5; i++)
17405 operands[i] = gen_reg_rtx (XFmode);
17409 (define_insn "frndintxf2"
17410 [(set (match_operand:XF 0 "register_operand" "=f")
17411 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17413 "TARGET_USE_FANCY_MATH_387
17414 && flag_unsafe_math_optimizations"
17416 [(set_attr "type" "fpspc")
17417 (set_attr "mode" "XF")])
17419 (define_expand "rintdf2"
17420 [(use (match_operand:DF 0 "register_operand" ""))
17421 (use (match_operand:DF 1 "register_operand" ""))]
17422 "TARGET_USE_FANCY_MATH_387
17423 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17424 && flag_unsafe_math_optimizations"
17426 rtx op0 = gen_reg_rtx (XFmode);
17427 rtx op1 = gen_reg_rtx (XFmode);
17429 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17430 emit_insn (gen_frndintxf2 (op0, op1));
17432 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17436 (define_expand "rintsf2"
17437 [(use (match_operand:SF 0 "register_operand" ""))
17438 (use (match_operand:SF 1 "register_operand" ""))]
17439 "TARGET_USE_FANCY_MATH_387
17440 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17441 && flag_unsafe_math_optimizations"
17443 rtx op0 = gen_reg_rtx (XFmode);
17444 rtx op1 = gen_reg_rtx (XFmode);
17446 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17447 emit_insn (gen_frndintxf2 (op0, op1));
17449 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17453 (define_expand "rintxf2"
17454 [(use (match_operand:XF 0 "register_operand" ""))
17455 (use (match_operand:XF 1 "register_operand" ""))]
17456 "TARGET_USE_FANCY_MATH_387
17457 && flag_unsafe_math_optimizations"
17459 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17463 (define_insn_and_split "*fistdi2_1"
17464 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17465 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17467 "TARGET_USE_FANCY_MATH_387
17468 && flag_unsafe_math_optimizations
17469 && !(reload_completed || reload_in_progress)"
17474 if (memory_operand (operands[0], VOIDmode))
17475 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17478 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17479 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17484 [(set_attr "type" "fpspc")
17485 (set_attr "mode" "DI")])
17487 (define_insn "fistdi2"
17488 [(set (match_operand:DI 0 "memory_operand" "=m")
17489 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17491 (clobber (match_scratch:XF 2 "=&1f"))]
17492 "TARGET_USE_FANCY_MATH_387
17493 && flag_unsafe_math_optimizations"
17494 "* return output_fix_trunc (insn, operands, 0);"
17495 [(set_attr "type" "fpspc")
17496 (set_attr "mode" "DI")])
17498 (define_insn "fistdi2_with_temp"
17499 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17500 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17502 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17503 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17504 "TARGET_USE_FANCY_MATH_387
17505 && flag_unsafe_math_optimizations"
17507 [(set_attr "type" "fpspc")
17508 (set_attr "mode" "DI")])
17511 [(set (match_operand:DI 0 "register_operand" "")
17512 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17514 (clobber (match_operand:DI 2 "memory_operand" ""))
17515 (clobber (match_scratch 3 ""))]
17517 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17518 (clobber (match_dup 3))])
17519 (set (match_dup 0) (match_dup 2))]
17523 [(set (match_operand:DI 0 "memory_operand" "")
17524 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17526 (clobber (match_operand:DI 2 "memory_operand" ""))
17527 (clobber (match_scratch 3 ""))]
17529 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17530 (clobber (match_dup 3))])]
17533 (define_insn_and_split "*fist<mode>2_1"
17534 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17535 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17537 "TARGET_USE_FANCY_MATH_387
17538 && flag_unsafe_math_optimizations
17539 && !(reload_completed || reload_in_progress)"
17544 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17545 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17549 [(set_attr "type" "fpspc")
17550 (set_attr "mode" "<MODE>")])
17552 (define_insn "fist<mode>2"
17553 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17554 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17556 "TARGET_USE_FANCY_MATH_387
17557 && flag_unsafe_math_optimizations"
17558 "* return output_fix_trunc (insn, operands, 0);"
17559 [(set_attr "type" "fpspc")
17560 (set_attr "mode" "<MODE>")])
17562 (define_insn "fist<mode>2_with_temp"
17563 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17564 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17566 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17567 "TARGET_USE_FANCY_MATH_387
17568 && flag_unsafe_math_optimizations"
17570 [(set_attr "type" "fpspc")
17571 (set_attr "mode" "<MODE>")])
17574 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17575 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17577 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17579 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17581 (set (match_dup 0) (match_dup 2))]
17585 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17586 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17588 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17590 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17594 (define_expand "lrint<mode>2"
17595 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17596 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17598 "TARGET_USE_FANCY_MATH_387
17599 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17600 && flag_unsafe_math_optimizations"
17603 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17604 (define_insn_and_split "frndintxf2_floor"
17605 [(set (match_operand:XF 0 "register_operand" "=f")
17606 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17607 UNSPEC_FRNDINT_FLOOR))
17608 (clobber (reg:CC FLAGS_REG))]
17609 "TARGET_USE_FANCY_MATH_387
17610 && flag_unsafe_math_optimizations
17611 && !(reload_completed || reload_in_progress)"
17616 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17618 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17619 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17621 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17622 operands[2], operands[3]));
17625 [(set_attr "type" "frndint")
17626 (set_attr "i387_cw" "floor")
17627 (set_attr "mode" "XF")])
17629 (define_insn "frndintxf2_floor_i387"
17630 [(set (match_operand:XF 0 "register_operand" "=f")
17631 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17632 UNSPEC_FRNDINT_FLOOR))
17633 (use (match_operand:HI 2 "memory_operand" "m"))
17634 (use (match_operand:HI 3 "memory_operand" "m"))]
17635 "TARGET_USE_FANCY_MATH_387
17636 && flag_unsafe_math_optimizations"
17637 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17638 [(set_attr "type" "frndint")
17639 (set_attr "i387_cw" "floor")
17640 (set_attr "mode" "XF")])
17642 (define_expand "floorxf2"
17643 [(use (match_operand:XF 0 "register_operand" ""))
17644 (use (match_operand:XF 1 "register_operand" ""))]
17645 "TARGET_USE_FANCY_MATH_387
17646 && flag_unsafe_math_optimizations"
17648 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17652 (define_expand "floordf2"
17653 [(use (match_operand:DF 0 "register_operand" ""))
17654 (use (match_operand:DF 1 "register_operand" ""))]
17655 "TARGET_USE_FANCY_MATH_387
17656 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17657 && flag_unsafe_math_optimizations"
17659 rtx op0 = gen_reg_rtx (XFmode);
17660 rtx op1 = gen_reg_rtx (XFmode);
17662 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17663 emit_insn (gen_frndintxf2_floor (op0, op1));
17665 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17669 (define_expand "floorsf2"
17670 [(use (match_operand:SF 0 "register_operand" ""))
17671 (use (match_operand:SF 1 "register_operand" ""))]
17672 "TARGET_USE_FANCY_MATH_387
17673 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17674 && flag_unsafe_math_optimizations"
17676 rtx op0 = gen_reg_rtx (XFmode);
17677 rtx op1 = gen_reg_rtx (XFmode);
17679 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17680 emit_insn (gen_frndintxf2_floor (op0, op1));
17682 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17686 (define_insn_and_split "*fist<mode>2_floor_1"
17687 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17688 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17689 UNSPEC_FIST_FLOOR))
17690 (clobber (reg:CC FLAGS_REG))]
17691 "TARGET_USE_FANCY_MATH_387
17692 && flag_unsafe_math_optimizations
17693 && !(reload_completed || reload_in_progress)"
17698 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17700 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17701 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17702 if (memory_operand (operands[0], VOIDmode))
17703 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17704 operands[2], operands[3]));
17707 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17708 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17709 operands[2], operands[3],
17714 [(set_attr "type" "fistp")
17715 (set_attr "i387_cw" "floor")
17716 (set_attr "mode" "<MODE>")])
17718 (define_insn "fistdi2_floor"
17719 [(set (match_operand:DI 0 "memory_operand" "=m")
17720 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17721 UNSPEC_FIST_FLOOR))
17722 (use (match_operand:HI 2 "memory_operand" "m"))
17723 (use (match_operand:HI 3 "memory_operand" "m"))
17724 (clobber (match_scratch:XF 4 "=&1f"))]
17725 "TARGET_USE_FANCY_MATH_387
17726 && flag_unsafe_math_optimizations"
17727 "* return output_fix_trunc (insn, operands, 0);"
17728 [(set_attr "type" "fistp")
17729 (set_attr "i387_cw" "floor")
17730 (set_attr "mode" "DI")])
17732 (define_insn "fistdi2_floor_with_temp"
17733 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17734 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17735 UNSPEC_FIST_FLOOR))
17736 (use (match_operand:HI 2 "memory_operand" "m,m"))
17737 (use (match_operand:HI 3 "memory_operand" "m,m"))
17738 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17739 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17740 "TARGET_USE_FANCY_MATH_387
17741 && flag_unsafe_math_optimizations"
17743 [(set_attr "type" "fistp")
17744 (set_attr "i387_cw" "floor")
17745 (set_attr "mode" "DI")])
17748 [(set (match_operand:DI 0 "register_operand" "")
17749 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17750 UNSPEC_FIST_FLOOR))
17751 (use (match_operand:HI 2 "memory_operand" ""))
17752 (use (match_operand:HI 3 "memory_operand" ""))
17753 (clobber (match_operand:DI 4 "memory_operand" ""))
17754 (clobber (match_scratch 5 ""))]
17756 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17757 (use (match_dup 2))
17758 (use (match_dup 3))
17759 (clobber (match_dup 5))])
17760 (set (match_dup 0) (match_dup 4))]
17764 [(set (match_operand:DI 0 "memory_operand" "")
17765 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17766 UNSPEC_FIST_FLOOR))
17767 (use (match_operand:HI 2 "memory_operand" ""))
17768 (use (match_operand:HI 3 "memory_operand" ""))
17769 (clobber (match_operand:DI 4 "memory_operand" ""))
17770 (clobber (match_scratch 5 ""))]
17772 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17773 (use (match_dup 2))
17774 (use (match_dup 3))
17775 (clobber (match_dup 5))])]
17778 (define_insn "fist<mode>2_floor"
17779 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17780 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17781 UNSPEC_FIST_FLOOR))
17782 (use (match_operand:HI 2 "memory_operand" "m"))
17783 (use (match_operand:HI 3 "memory_operand" "m"))]
17784 "TARGET_USE_FANCY_MATH_387
17785 && flag_unsafe_math_optimizations"
17786 "* return output_fix_trunc (insn, operands, 0);"
17787 [(set_attr "type" "fistp")
17788 (set_attr "i387_cw" "floor")
17789 (set_attr "mode" "<MODE>")])
17791 (define_insn "fist<mode>2_floor_with_temp"
17792 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17793 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17794 UNSPEC_FIST_FLOOR))
17795 (use (match_operand:HI 2 "memory_operand" "m,m"))
17796 (use (match_operand:HI 3 "memory_operand" "m,m"))
17797 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17798 "TARGET_USE_FANCY_MATH_387
17799 && flag_unsafe_math_optimizations"
17801 [(set_attr "type" "fistp")
17802 (set_attr "i387_cw" "floor")
17803 (set_attr "mode" "<MODE>")])
17806 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17807 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17808 UNSPEC_FIST_FLOOR))
17809 (use (match_operand:HI 2 "memory_operand" ""))
17810 (use (match_operand:HI 3 "memory_operand" ""))
17811 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17813 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17814 UNSPEC_FIST_FLOOR))
17815 (use (match_dup 2))
17816 (use (match_dup 3))])
17817 (set (match_dup 0) (match_dup 4))]
17821 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17822 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17823 UNSPEC_FIST_FLOOR))
17824 (use (match_operand:HI 2 "memory_operand" ""))
17825 (use (match_operand:HI 3 "memory_operand" ""))
17826 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17828 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17829 UNSPEC_FIST_FLOOR))
17830 (use (match_dup 2))
17831 (use (match_dup 3))])]
17834 (define_expand "lfloor<mode>2"
17835 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17836 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17837 UNSPEC_FIST_FLOOR))
17838 (clobber (reg:CC FLAGS_REG))])]
17839 "TARGET_USE_FANCY_MATH_387
17840 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17841 && flag_unsafe_math_optimizations"
17844 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17845 (define_insn_and_split "frndintxf2_ceil"
17846 [(set (match_operand:XF 0 "register_operand" "=f")
17847 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17848 UNSPEC_FRNDINT_CEIL))
17849 (clobber (reg:CC FLAGS_REG))]
17850 "TARGET_USE_FANCY_MATH_387
17851 && flag_unsafe_math_optimizations
17852 && !(reload_completed || reload_in_progress)"
17857 ix86_optimize_mode_switching[I387_CEIL] = 1;
17859 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17860 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17862 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17863 operands[2], operands[3]));
17866 [(set_attr "type" "frndint")
17867 (set_attr "i387_cw" "ceil")
17868 (set_attr "mode" "XF")])
17870 (define_insn "frndintxf2_ceil_i387"
17871 [(set (match_operand:XF 0 "register_operand" "=f")
17872 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17873 UNSPEC_FRNDINT_CEIL))
17874 (use (match_operand:HI 2 "memory_operand" "m"))
17875 (use (match_operand:HI 3 "memory_operand" "m"))]
17876 "TARGET_USE_FANCY_MATH_387
17877 && flag_unsafe_math_optimizations"
17878 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17879 [(set_attr "type" "frndint")
17880 (set_attr "i387_cw" "ceil")
17881 (set_attr "mode" "XF")])
17883 (define_expand "ceilxf2"
17884 [(use (match_operand:XF 0 "register_operand" ""))
17885 (use (match_operand:XF 1 "register_operand" ""))]
17886 "TARGET_USE_FANCY_MATH_387
17887 && flag_unsafe_math_optimizations"
17889 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17893 (define_expand "ceildf2"
17894 [(use (match_operand:DF 0 "register_operand" ""))
17895 (use (match_operand:DF 1 "register_operand" ""))]
17896 "TARGET_USE_FANCY_MATH_387
17897 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17898 && flag_unsafe_math_optimizations"
17900 rtx op0 = gen_reg_rtx (XFmode);
17901 rtx op1 = gen_reg_rtx (XFmode);
17903 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17904 emit_insn (gen_frndintxf2_ceil (op0, op1));
17906 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17910 (define_expand "ceilsf2"
17911 [(use (match_operand:SF 0 "register_operand" ""))
17912 (use (match_operand:SF 1 "register_operand" ""))]
17913 "TARGET_USE_FANCY_MATH_387
17914 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17915 && flag_unsafe_math_optimizations"
17917 rtx op0 = gen_reg_rtx (XFmode);
17918 rtx op1 = gen_reg_rtx (XFmode);
17920 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17921 emit_insn (gen_frndintxf2_ceil (op0, op1));
17923 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17927 (define_insn_and_split "*fist<mode>2_ceil_1"
17928 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17929 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17931 (clobber (reg:CC FLAGS_REG))]
17932 "TARGET_USE_FANCY_MATH_387
17933 && flag_unsafe_math_optimizations
17934 && !(reload_completed || reload_in_progress)"
17939 ix86_optimize_mode_switching[I387_CEIL] = 1;
17941 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17942 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17943 if (memory_operand (operands[0], VOIDmode))
17944 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17945 operands[2], operands[3]));
17948 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17949 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17950 operands[2], operands[3],
17955 [(set_attr "type" "fistp")
17956 (set_attr "i387_cw" "ceil")
17957 (set_attr "mode" "<MODE>")])
17959 (define_insn "fistdi2_ceil"
17960 [(set (match_operand:DI 0 "memory_operand" "=m")
17961 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17963 (use (match_operand:HI 2 "memory_operand" "m"))
17964 (use (match_operand:HI 3 "memory_operand" "m"))
17965 (clobber (match_scratch:XF 4 "=&1f"))]
17966 "TARGET_USE_FANCY_MATH_387
17967 && flag_unsafe_math_optimizations"
17968 "* return output_fix_trunc (insn, operands, 0);"
17969 [(set_attr "type" "fistp")
17970 (set_attr "i387_cw" "ceil")
17971 (set_attr "mode" "DI")])
17973 (define_insn "fistdi2_ceil_with_temp"
17974 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17975 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17977 (use (match_operand:HI 2 "memory_operand" "m,m"))
17978 (use (match_operand:HI 3 "memory_operand" "m,m"))
17979 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17980 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17981 "TARGET_USE_FANCY_MATH_387
17982 && flag_unsafe_math_optimizations"
17984 [(set_attr "type" "fistp")
17985 (set_attr "i387_cw" "ceil")
17986 (set_attr "mode" "DI")])
17989 [(set (match_operand:DI 0 "register_operand" "")
17990 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17992 (use (match_operand:HI 2 "memory_operand" ""))
17993 (use (match_operand:HI 3 "memory_operand" ""))
17994 (clobber (match_operand:DI 4 "memory_operand" ""))
17995 (clobber (match_scratch 5 ""))]
17997 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17998 (use (match_dup 2))
17999 (use (match_dup 3))
18000 (clobber (match_dup 5))])
18001 (set (match_dup 0) (match_dup 4))]
18005 [(set (match_operand:DI 0 "memory_operand" "")
18006 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18008 (use (match_operand:HI 2 "memory_operand" ""))
18009 (use (match_operand:HI 3 "memory_operand" ""))
18010 (clobber (match_operand:DI 4 "memory_operand" ""))
18011 (clobber (match_scratch 5 ""))]
18013 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18014 (use (match_dup 2))
18015 (use (match_dup 3))
18016 (clobber (match_dup 5))])]
18019 (define_insn "fist<mode>2_ceil"
18020 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18021 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18023 (use (match_operand:HI 2 "memory_operand" "m"))
18024 (use (match_operand:HI 3 "memory_operand" "m"))]
18025 "TARGET_USE_FANCY_MATH_387
18026 && flag_unsafe_math_optimizations"
18027 "* return output_fix_trunc (insn, operands, 0);"
18028 [(set_attr "type" "fistp")
18029 (set_attr "i387_cw" "ceil")
18030 (set_attr "mode" "<MODE>")])
18032 (define_insn "fist<mode>2_ceil_with_temp"
18033 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18034 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18036 (use (match_operand:HI 2 "memory_operand" "m,m"))
18037 (use (match_operand:HI 3 "memory_operand" "m,m"))
18038 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18039 "TARGET_USE_FANCY_MATH_387
18040 && flag_unsafe_math_optimizations"
18042 [(set_attr "type" "fistp")
18043 (set_attr "i387_cw" "ceil")
18044 (set_attr "mode" "<MODE>")])
18047 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18048 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18050 (use (match_operand:HI 2 "memory_operand" ""))
18051 (use (match_operand:HI 3 "memory_operand" ""))
18052 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18054 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18056 (use (match_dup 2))
18057 (use (match_dup 3))])
18058 (set (match_dup 0) (match_dup 4))]
18062 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18063 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18065 (use (match_operand:HI 2 "memory_operand" ""))
18066 (use (match_operand:HI 3 "memory_operand" ""))
18067 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18069 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18071 (use (match_dup 2))
18072 (use (match_dup 3))])]
18075 (define_expand "lceil<mode>2"
18076 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18077 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18079 (clobber (reg:CC FLAGS_REG))])]
18080 "TARGET_USE_FANCY_MATH_387
18081 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18082 && flag_unsafe_math_optimizations"
18085 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18086 (define_insn_and_split "frndintxf2_trunc"
18087 [(set (match_operand:XF 0 "register_operand" "=f")
18088 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18089 UNSPEC_FRNDINT_TRUNC))
18090 (clobber (reg:CC FLAGS_REG))]
18091 "TARGET_USE_FANCY_MATH_387
18092 && flag_unsafe_math_optimizations
18093 && !(reload_completed || reload_in_progress)"
18098 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18100 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18101 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18103 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18104 operands[2], operands[3]));
18107 [(set_attr "type" "frndint")
18108 (set_attr "i387_cw" "trunc")
18109 (set_attr "mode" "XF")])
18111 (define_insn "frndintxf2_trunc_i387"
18112 [(set (match_operand:XF 0 "register_operand" "=f")
18113 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18114 UNSPEC_FRNDINT_TRUNC))
18115 (use (match_operand:HI 2 "memory_operand" "m"))
18116 (use (match_operand:HI 3 "memory_operand" "m"))]
18117 "TARGET_USE_FANCY_MATH_387
18118 && flag_unsafe_math_optimizations"
18119 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18120 [(set_attr "type" "frndint")
18121 (set_attr "i387_cw" "trunc")
18122 (set_attr "mode" "XF")])
18124 (define_expand "btruncxf2"
18125 [(use (match_operand:XF 0 "register_operand" ""))
18126 (use (match_operand:XF 1 "register_operand" ""))]
18127 "TARGET_USE_FANCY_MATH_387
18128 && flag_unsafe_math_optimizations"
18130 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18134 (define_expand "btruncdf2"
18135 [(use (match_operand:DF 0 "register_operand" ""))
18136 (use (match_operand:DF 1 "register_operand" ""))]
18137 "TARGET_USE_FANCY_MATH_387
18138 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18139 && flag_unsafe_math_optimizations"
18141 rtx op0 = gen_reg_rtx (XFmode);
18142 rtx op1 = gen_reg_rtx (XFmode);
18144 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18145 emit_insn (gen_frndintxf2_trunc (op0, op1));
18147 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18151 (define_expand "btruncsf2"
18152 [(use (match_operand:SF 0 "register_operand" ""))
18153 (use (match_operand:SF 1 "register_operand" ""))]
18154 "TARGET_USE_FANCY_MATH_387
18155 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18156 && flag_unsafe_math_optimizations"
18158 rtx op0 = gen_reg_rtx (XFmode);
18159 rtx op1 = gen_reg_rtx (XFmode);
18161 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18162 emit_insn (gen_frndintxf2_trunc (op0, op1));
18164 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18168 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18169 (define_insn_and_split "frndintxf2_mask_pm"
18170 [(set (match_operand:XF 0 "register_operand" "=f")
18171 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18172 UNSPEC_FRNDINT_MASK_PM))
18173 (clobber (reg:CC FLAGS_REG))]
18174 "TARGET_USE_FANCY_MATH_387
18175 && flag_unsafe_math_optimizations
18176 && !(reload_completed || reload_in_progress)"
18181 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18183 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18184 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18186 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18187 operands[2], operands[3]));
18190 [(set_attr "type" "frndint")
18191 (set_attr "i387_cw" "mask_pm")
18192 (set_attr "mode" "XF")])
18194 (define_insn "frndintxf2_mask_pm_i387"
18195 [(set (match_operand:XF 0 "register_operand" "=f")
18196 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18197 UNSPEC_FRNDINT_MASK_PM))
18198 (use (match_operand:HI 2 "memory_operand" "m"))
18199 (use (match_operand:HI 3 "memory_operand" "m"))]
18200 "TARGET_USE_FANCY_MATH_387
18201 && flag_unsafe_math_optimizations"
18202 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18203 [(set_attr "type" "frndint")
18204 (set_attr "i387_cw" "mask_pm")
18205 (set_attr "mode" "XF")])
18207 (define_expand "nearbyintxf2"
18208 [(use (match_operand:XF 0 "register_operand" ""))
18209 (use (match_operand:XF 1 "register_operand" ""))]
18210 "TARGET_USE_FANCY_MATH_387
18211 && flag_unsafe_math_optimizations"
18213 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18218 (define_expand "nearbyintdf2"
18219 [(use (match_operand:DF 0 "register_operand" ""))
18220 (use (match_operand:DF 1 "register_operand" ""))]
18221 "TARGET_USE_FANCY_MATH_387
18222 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18223 && flag_unsafe_math_optimizations"
18225 rtx op0 = gen_reg_rtx (XFmode);
18226 rtx op1 = gen_reg_rtx (XFmode);
18228 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18229 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18231 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18235 (define_expand "nearbyintsf2"
18236 [(use (match_operand:SF 0 "register_operand" ""))
18237 (use (match_operand:SF 1 "register_operand" ""))]
18238 "TARGET_USE_FANCY_MATH_387
18239 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18240 && flag_unsafe_math_optimizations"
18242 rtx op0 = gen_reg_rtx (XFmode);
18243 rtx op1 = gen_reg_rtx (XFmode);
18245 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18246 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18248 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18253 ;; Block operation instructions
18256 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18259 [(set_attr "type" "cld")])
18261 (define_expand "movmemsi"
18262 [(use (match_operand:BLK 0 "memory_operand" ""))
18263 (use (match_operand:BLK 1 "memory_operand" ""))
18264 (use (match_operand:SI 2 "nonmemory_operand" ""))
18265 (use (match_operand:SI 3 "const_int_operand" ""))]
18266 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18268 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18274 (define_expand "movmemdi"
18275 [(use (match_operand:BLK 0 "memory_operand" ""))
18276 (use (match_operand:BLK 1 "memory_operand" ""))
18277 (use (match_operand:DI 2 "nonmemory_operand" ""))
18278 (use (match_operand:DI 3 "const_int_operand" ""))]
18281 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18287 ;; Most CPUs don't like single string operations
18288 ;; Handle this case here to simplify previous expander.
18290 (define_expand "strmov"
18291 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18292 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18293 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18294 (clobber (reg:CC FLAGS_REG))])
18295 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18296 (clobber (reg:CC FLAGS_REG))])]
18299 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18301 /* If .md ever supports :P for Pmode, these can be directly
18302 in the pattern above. */
18303 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18304 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18306 if (TARGET_SINGLE_STRINGOP || optimize_size)
18308 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18309 operands[2], operands[3],
18310 operands[5], operands[6]));
18314 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18317 (define_expand "strmov_singleop"
18318 [(parallel [(set (match_operand 1 "memory_operand" "")
18319 (match_operand 3 "memory_operand" ""))
18320 (set (match_operand 0 "register_operand" "")
18321 (match_operand 4 "" ""))
18322 (set (match_operand 2 "register_operand" "")
18323 (match_operand 5 "" ""))
18324 (use (reg:SI DIRFLAG_REG))])]
18325 "TARGET_SINGLE_STRINGOP || optimize_size"
18328 (define_insn "*strmovdi_rex_1"
18329 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18330 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18331 (set (match_operand:DI 0 "register_operand" "=D")
18332 (plus:DI (match_dup 2)
18334 (set (match_operand:DI 1 "register_operand" "=S")
18335 (plus:DI (match_dup 3)
18337 (use (reg:SI DIRFLAG_REG))]
18338 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18340 [(set_attr "type" "str")
18341 (set_attr "mode" "DI")
18342 (set_attr "memory" "both")])
18344 (define_insn "*strmovsi_1"
18345 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18346 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18347 (set (match_operand:SI 0 "register_operand" "=D")
18348 (plus:SI (match_dup 2)
18350 (set (match_operand:SI 1 "register_operand" "=S")
18351 (plus:SI (match_dup 3)
18353 (use (reg:SI DIRFLAG_REG))]
18354 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18356 [(set_attr "type" "str")
18357 (set_attr "mode" "SI")
18358 (set_attr "memory" "both")])
18360 (define_insn "*strmovsi_rex_1"
18361 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18362 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18363 (set (match_operand:DI 0 "register_operand" "=D")
18364 (plus:DI (match_dup 2)
18366 (set (match_operand:DI 1 "register_operand" "=S")
18367 (plus:DI (match_dup 3)
18369 (use (reg:SI DIRFLAG_REG))]
18370 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18372 [(set_attr "type" "str")
18373 (set_attr "mode" "SI")
18374 (set_attr "memory" "both")])
18376 (define_insn "*strmovhi_1"
18377 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18378 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18379 (set (match_operand:SI 0 "register_operand" "=D")
18380 (plus:SI (match_dup 2)
18382 (set (match_operand:SI 1 "register_operand" "=S")
18383 (plus:SI (match_dup 3)
18385 (use (reg:SI DIRFLAG_REG))]
18386 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18388 [(set_attr "type" "str")
18389 (set_attr "memory" "both")
18390 (set_attr "mode" "HI")])
18392 (define_insn "*strmovhi_rex_1"
18393 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18394 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18395 (set (match_operand:DI 0 "register_operand" "=D")
18396 (plus:DI (match_dup 2)
18398 (set (match_operand:DI 1 "register_operand" "=S")
18399 (plus:DI (match_dup 3)
18401 (use (reg:SI DIRFLAG_REG))]
18402 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18404 [(set_attr "type" "str")
18405 (set_attr "memory" "both")
18406 (set_attr "mode" "HI")])
18408 (define_insn "*strmovqi_1"
18409 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18410 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18411 (set (match_operand:SI 0 "register_operand" "=D")
18412 (plus:SI (match_dup 2)
18414 (set (match_operand:SI 1 "register_operand" "=S")
18415 (plus:SI (match_dup 3)
18417 (use (reg:SI DIRFLAG_REG))]
18418 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18420 [(set_attr "type" "str")
18421 (set_attr "memory" "both")
18422 (set_attr "mode" "QI")])
18424 (define_insn "*strmovqi_rex_1"
18425 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18426 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18427 (set (match_operand:DI 0 "register_operand" "=D")
18428 (plus:DI (match_dup 2)
18430 (set (match_operand:DI 1 "register_operand" "=S")
18431 (plus:DI (match_dup 3)
18433 (use (reg:SI DIRFLAG_REG))]
18434 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18436 [(set_attr "type" "str")
18437 (set_attr "memory" "both")
18438 (set_attr "mode" "QI")])
18440 (define_expand "rep_mov"
18441 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18442 (set (match_operand 0 "register_operand" "")
18443 (match_operand 5 "" ""))
18444 (set (match_operand 2 "register_operand" "")
18445 (match_operand 6 "" ""))
18446 (set (match_operand 1 "memory_operand" "")
18447 (match_operand 3 "memory_operand" ""))
18448 (use (match_dup 4))
18449 (use (reg:SI DIRFLAG_REG))])]
18453 (define_insn "*rep_movdi_rex64"
18454 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18455 (set (match_operand:DI 0 "register_operand" "=D")
18456 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18458 (match_operand:DI 3 "register_operand" "0")))
18459 (set (match_operand:DI 1 "register_operand" "=S")
18460 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18461 (match_operand:DI 4 "register_operand" "1")))
18462 (set (mem:BLK (match_dup 3))
18463 (mem:BLK (match_dup 4)))
18464 (use (match_dup 5))
18465 (use (reg:SI DIRFLAG_REG))]
18467 "{rep\;movsq|rep movsq}"
18468 [(set_attr "type" "str")
18469 (set_attr "prefix_rep" "1")
18470 (set_attr "memory" "both")
18471 (set_attr "mode" "DI")])
18473 (define_insn "*rep_movsi"
18474 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18475 (set (match_operand:SI 0 "register_operand" "=D")
18476 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18478 (match_operand:SI 3 "register_operand" "0")))
18479 (set (match_operand:SI 1 "register_operand" "=S")
18480 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18481 (match_operand:SI 4 "register_operand" "1")))
18482 (set (mem:BLK (match_dup 3))
18483 (mem:BLK (match_dup 4)))
18484 (use (match_dup 5))
18485 (use (reg:SI DIRFLAG_REG))]
18487 "{rep\;movsl|rep movsd}"
18488 [(set_attr "type" "str")
18489 (set_attr "prefix_rep" "1")
18490 (set_attr "memory" "both")
18491 (set_attr "mode" "SI")])
18493 (define_insn "*rep_movsi_rex64"
18494 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18495 (set (match_operand:DI 0 "register_operand" "=D")
18496 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18498 (match_operand:DI 3 "register_operand" "0")))
18499 (set (match_operand:DI 1 "register_operand" "=S")
18500 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18501 (match_operand:DI 4 "register_operand" "1")))
18502 (set (mem:BLK (match_dup 3))
18503 (mem:BLK (match_dup 4)))
18504 (use (match_dup 5))
18505 (use (reg:SI DIRFLAG_REG))]
18507 "{rep\;movsl|rep movsd}"
18508 [(set_attr "type" "str")
18509 (set_attr "prefix_rep" "1")
18510 (set_attr "memory" "both")
18511 (set_attr "mode" "SI")])
18513 (define_insn "*rep_movqi"
18514 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18515 (set (match_operand:SI 0 "register_operand" "=D")
18516 (plus:SI (match_operand:SI 3 "register_operand" "0")
18517 (match_operand:SI 5 "register_operand" "2")))
18518 (set (match_operand:SI 1 "register_operand" "=S")
18519 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18520 (set (mem:BLK (match_dup 3))
18521 (mem:BLK (match_dup 4)))
18522 (use (match_dup 5))
18523 (use (reg:SI DIRFLAG_REG))]
18525 "{rep\;movsb|rep movsb}"
18526 [(set_attr "type" "str")
18527 (set_attr "prefix_rep" "1")
18528 (set_attr "memory" "both")
18529 (set_attr "mode" "SI")])
18531 (define_insn "*rep_movqi_rex64"
18532 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18533 (set (match_operand:DI 0 "register_operand" "=D")
18534 (plus:DI (match_operand:DI 3 "register_operand" "0")
18535 (match_operand:DI 5 "register_operand" "2")))
18536 (set (match_operand:DI 1 "register_operand" "=S")
18537 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18538 (set (mem:BLK (match_dup 3))
18539 (mem:BLK (match_dup 4)))
18540 (use (match_dup 5))
18541 (use (reg:SI DIRFLAG_REG))]
18543 "{rep\;movsb|rep movsb}"
18544 [(set_attr "type" "str")
18545 (set_attr "prefix_rep" "1")
18546 (set_attr "memory" "both")
18547 (set_attr "mode" "SI")])
18549 (define_expand "setmemsi"
18550 [(use (match_operand:BLK 0 "memory_operand" ""))
18551 (use (match_operand:SI 1 "nonmemory_operand" ""))
18552 (use (match_operand 2 "const_int_operand" ""))
18553 (use (match_operand 3 "const_int_operand" ""))]
18556 /* If value to set is not zero, use the library routine. */
18557 if (operands[2] != const0_rtx)
18560 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18566 (define_expand "setmemdi"
18567 [(use (match_operand:BLK 0 "memory_operand" ""))
18568 (use (match_operand:DI 1 "nonmemory_operand" ""))
18569 (use (match_operand 2 "const_int_operand" ""))
18570 (use (match_operand 3 "const_int_operand" ""))]
18573 /* If value to set is not zero, use the library routine. */
18574 if (operands[2] != const0_rtx)
18577 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18583 ;; Most CPUs don't like single string operations
18584 ;; Handle this case here to simplify previous expander.
18586 (define_expand "strset"
18587 [(set (match_operand 1 "memory_operand" "")
18588 (match_operand 2 "register_operand" ""))
18589 (parallel [(set (match_operand 0 "register_operand" "")
18591 (clobber (reg:CC FLAGS_REG))])]
18594 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18595 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18597 /* If .md ever supports :P for Pmode, this can be directly
18598 in the pattern above. */
18599 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18600 GEN_INT (GET_MODE_SIZE (GET_MODE
18602 if (TARGET_SINGLE_STRINGOP || optimize_size)
18604 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18610 (define_expand "strset_singleop"
18611 [(parallel [(set (match_operand 1 "memory_operand" "")
18612 (match_operand 2 "register_operand" ""))
18613 (set (match_operand 0 "register_operand" "")
18614 (match_operand 3 "" ""))
18615 (use (reg:SI DIRFLAG_REG))])]
18616 "TARGET_SINGLE_STRINGOP || optimize_size"
18619 (define_insn "*strsetdi_rex_1"
18620 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18621 (match_operand:DI 2 "register_operand" "a"))
18622 (set (match_operand:DI 0 "register_operand" "=D")
18623 (plus:DI (match_dup 1)
18625 (use (reg:SI DIRFLAG_REG))]
18626 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18628 [(set_attr "type" "str")
18629 (set_attr "memory" "store")
18630 (set_attr "mode" "DI")])
18632 (define_insn "*strsetsi_1"
18633 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18634 (match_operand:SI 2 "register_operand" "a"))
18635 (set (match_operand:SI 0 "register_operand" "=D")
18636 (plus:SI (match_dup 1)
18638 (use (reg:SI DIRFLAG_REG))]
18639 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18641 [(set_attr "type" "str")
18642 (set_attr "memory" "store")
18643 (set_attr "mode" "SI")])
18645 (define_insn "*strsetsi_rex_1"
18646 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18647 (match_operand:SI 2 "register_operand" "a"))
18648 (set (match_operand:DI 0 "register_operand" "=D")
18649 (plus:DI (match_dup 1)
18651 (use (reg:SI DIRFLAG_REG))]
18652 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18654 [(set_attr "type" "str")
18655 (set_attr "memory" "store")
18656 (set_attr "mode" "SI")])
18658 (define_insn "*strsethi_1"
18659 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18660 (match_operand:HI 2 "register_operand" "a"))
18661 (set (match_operand:SI 0 "register_operand" "=D")
18662 (plus:SI (match_dup 1)
18664 (use (reg:SI DIRFLAG_REG))]
18665 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18667 [(set_attr "type" "str")
18668 (set_attr "memory" "store")
18669 (set_attr "mode" "HI")])
18671 (define_insn "*strsethi_rex_1"
18672 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18673 (match_operand:HI 2 "register_operand" "a"))
18674 (set (match_operand:DI 0 "register_operand" "=D")
18675 (plus:DI (match_dup 1)
18677 (use (reg:SI DIRFLAG_REG))]
18678 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18680 [(set_attr "type" "str")
18681 (set_attr "memory" "store")
18682 (set_attr "mode" "HI")])
18684 (define_insn "*strsetqi_1"
18685 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18686 (match_operand:QI 2 "register_operand" "a"))
18687 (set (match_operand:SI 0 "register_operand" "=D")
18688 (plus:SI (match_dup 1)
18690 (use (reg:SI DIRFLAG_REG))]
18691 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18693 [(set_attr "type" "str")
18694 (set_attr "memory" "store")
18695 (set_attr "mode" "QI")])
18697 (define_insn "*strsetqi_rex_1"
18698 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18699 (match_operand:QI 2 "register_operand" "a"))
18700 (set (match_operand:DI 0 "register_operand" "=D")
18701 (plus:DI (match_dup 1)
18703 (use (reg:SI DIRFLAG_REG))]
18704 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18706 [(set_attr "type" "str")
18707 (set_attr "memory" "store")
18708 (set_attr "mode" "QI")])
18710 (define_expand "rep_stos"
18711 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18712 (set (match_operand 0 "register_operand" "")
18713 (match_operand 4 "" ""))
18714 (set (match_operand 2 "memory_operand" "") (const_int 0))
18715 (use (match_operand 3 "register_operand" ""))
18716 (use (match_dup 1))
18717 (use (reg:SI DIRFLAG_REG))])]
18721 (define_insn "*rep_stosdi_rex64"
18722 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18723 (set (match_operand:DI 0 "register_operand" "=D")
18724 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18726 (match_operand:DI 3 "register_operand" "0")))
18727 (set (mem:BLK (match_dup 3))
18729 (use (match_operand:DI 2 "register_operand" "a"))
18730 (use (match_dup 4))
18731 (use (reg:SI DIRFLAG_REG))]
18733 "{rep\;stosq|rep stosq}"
18734 [(set_attr "type" "str")
18735 (set_attr "prefix_rep" "1")
18736 (set_attr "memory" "store")
18737 (set_attr "mode" "DI")])
18739 (define_insn "*rep_stossi"
18740 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18741 (set (match_operand:SI 0 "register_operand" "=D")
18742 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18744 (match_operand:SI 3 "register_operand" "0")))
18745 (set (mem:BLK (match_dup 3))
18747 (use (match_operand:SI 2 "register_operand" "a"))
18748 (use (match_dup 4))
18749 (use (reg:SI DIRFLAG_REG))]
18751 "{rep\;stosl|rep stosd}"
18752 [(set_attr "type" "str")
18753 (set_attr "prefix_rep" "1")
18754 (set_attr "memory" "store")
18755 (set_attr "mode" "SI")])
18757 (define_insn "*rep_stossi_rex64"
18758 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18759 (set (match_operand:DI 0 "register_operand" "=D")
18760 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18762 (match_operand:DI 3 "register_operand" "0")))
18763 (set (mem:BLK (match_dup 3))
18765 (use (match_operand:SI 2 "register_operand" "a"))
18766 (use (match_dup 4))
18767 (use (reg:SI DIRFLAG_REG))]
18769 "{rep\;stosl|rep stosd}"
18770 [(set_attr "type" "str")
18771 (set_attr "prefix_rep" "1")
18772 (set_attr "memory" "store")
18773 (set_attr "mode" "SI")])
18775 (define_insn "*rep_stosqi"
18776 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18777 (set (match_operand:SI 0 "register_operand" "=D")
18778 (plus:SI (match_operand:SI 3 "register_operand" "0")
18779 (match_operand:SI 4 "register_operand" "1")))
18780 (set (mem:BLK (match_dup 3))
18782 (use (match_operand:QI 2 "register_operand" "a"))
18783 (use (match_dup 4))
18784 (use (reg:SI DIRFLAG_REG))]
18786 "{rep\;stosb|rep stosb}"
18787 [(set_attr "type" "str")
18788 (set_attr "prefix_rep" "1")
18789 (set_attr "memory" "store")
18790 (set_attr "mode" "QI")])
18792 (define_insn "*rep_stosqi_rex64"
18793 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18794 (set (match_operand:DI 0 "register_operand" "=D")
18795 (plus:DI (match_operand:DI 3 "register_operand" "0")
18796 (match_operand:DI 4 "register_operand" "1")))
18797 (set (mem:BLK (match_dup 3))
18799 (use (match_operand:QI 2 "register_operand" "a"))
18800 (use (match_dup 4))
18801 (use (reg:SI DIRFLAG_REG))]
18803 "{rep\;stosb|rep stosb}"
18804 [(set_attr "type" "str")
18805 (set_attr "prefix_rep" "1")
18806 (set_attr "memory" "store")
18807 (set_attr "mode" "QI")])
18809 (define_expand "cmpstrnsi"
18810 [(set (match_operand:SI 0 "register_operand" "")
18811 (compare:SI (match_operand:BLK 1 "general_operand" "")
18812 (match_operand:BLK 2 "general_operand" "")))
18813 (use (match_operand 3 "general_operand" ""))
18814 (use (match_operand 4 "immediate_operand" ""))]
18815 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18817 rtx addr1, addr2, out, outlow, count, countreg, align;
18819 /* Can't use this if the user has appropriated esi or edi. */
18820 if (global_regs[4] || global_regs[5])
18824 if (GET_CODE (out) != REG)
18825 out = gen_reg_rtx (SImode);
18827 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18828 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18829 if (addr1 != XEXP (operands[1], 0))
18830 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18831 if (addr2 != XEXP (operands[2], 0))
18832 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18834 count = operands[3];
18835 countreg = ix86_zero_extend_to_Pmode (count);
18837 /* %%% Iff we are testing strict equality, we can use known alignment
18838 to good advantage. This may be possible with combine, particularly
18839 once cc0 is dead. */
18840 align = operands[4];
18842 emit_insn (gen_cld ());
18843 if (GET_CODE (count) == CONST_INT)
18845 if (INTVAL (count) == 0)
18847 emit_move_insn (operands[0], const0_rtx);
18850 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18851 operands[1], operands[2]));
18856 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18858 emit_insn (gen_cmpsi_1 (countreg, countreg));
18859 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18860 operands[1], operands[2]));
18863 outlow = gen_lowpart (QImode, out);
18864 emit_insn (gen_cmpintqi (outlow));
18865 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18867 if (operands[0] != out)
18868 emit_move_insn (operands[0], out);
18873 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18875 (define_expand "cmpintqi"
18876 [(set (match_dup 1)
18877 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18879 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18880 (parallel [(set (match_operand:QI 0 "register_operand" "")
18881 (minus:QI (match_dup 1)
18883 (clobber (reg:CC FLAGS_REG))])]
18885 "operands[1] = gen_reg_rtx (QImode);
18886 operands[2] = gen_reg_rtx (QImode);")
18888 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18889 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18891 (define_expand "cmpstrnqi_nz_1"
18892 [(parallel [(set (reg:CC FLAGS_REG)
18893 (compare:CC (match_operand 4 "memory_operand" "")
18894 (match_operand 5 "memory_operand" "")))
18895 (use (match_operand 2 "register_operand" ""))
18896 (use (match_operand:SI 3 "immediate_operand" ""))
18897 (use (reg:SI DIRFLAG_REG))
18898 (clobber (match_operand 0 "register_operand" ""))
18899 (clobber (match_operand 1 "register_operand" ""))
18900 (clobber (match_dup 2))])]
18904 (define_insn "*cmpstrnqi_nz_1"
18905 [(set (reg:CC FLAGS_REG)
18906 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18907 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18908 (use (match_operand:SI 6 "register_operand" "2"))
18909 (use (match_operand:SI 3 "immediate_operand" "i"))
18910 (use (reg:SI DIRFLAG_REG))
18911 (clobber (match_operand:SI 0 "register_operand" "=S"))
18912 (clobber (match_operand:SI 1 "register_operand" "=D"))
18913 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18916 [(set_attr "type" "str")
18917 (set_attr "mode" "QI")
18918 (set_attr "prefix_rep" "1")])
18920 (define_insn "*cmpstrnqi_nz_rex_1"
18921 [(set (reg:CC FLAGS_REG)
18922 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18923 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18924 (use (match_operand:DI 6 "register_operand" "2"))
18925 (use (match_operand:SI 3 "immediate_operand" "i"))
18926 (use (reg:SI DIRFLAG_REG))
18927 (clobber (match_operand:DI 0 "register_operand" "=S"))
18928 (clobber (match_operand:DI 1 "register_operand" "=D"))
18929 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18932 [(set_attr "type" "str")
18933 (set_attr "mode" "QI")
18934 (set_attr "prefix_rep" "1")])
18936 ;; The same, but the count is not known to not be zero.
18938 (define_expand "cmpstrnqi_1"
18939 [(parallel [(set (reg:CC FLAGS_REG)
18940 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18942 (compare:CC (match_operand 4 "memory_operand" "")
18943 (match_operand 5 "memory_operand" ""))
18945 (use (match_operand:SI 3 "immediate_operand" ""))
18946 (use (reg:CC FLAGS_REG))
18947 (use (reg:SI DIRFLAG_REG))
18948 (clobber (match_operand 0 "register_operand" ""))
18949 (clobber (match_operand 1 "register_operand" ""))
18950 (clobber (match_dup 2))])]
18954 (define_insn "*cmpstrnqi_1"
18955 [(set (reg:CC FLAGS_REG)
18956 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18958 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18959 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18961 (use (match_operand:SI 3 "immediate_operand" "i"))
18962 (use (reg:CC FLAGS_REG))
18963 (use (reg:SI DIRFLAG_REG))
18964 (clobber (match_operand:SI 0 "register_operand" "=S"))
18965 (clobber (match_operand:SI 1 "register_operand" "=D"))
18966 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18969 [(set_attr "type" "str")
18970 (set_attr "mode" "QI")
18971 (set_attr "prefix_rep" "1")])
18973 (define_insn "*cmpstrnqi_rex_1"
18974 [(set (reg:CC FLAGS_REG)
18975 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18977 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18978 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18980 (use (match_operand:SI 3 "immediate_operand" "i"))
18981 (use (reg:CC FLAGS_REG))
18982 (use (reg:SI DIRFLAG_REG))
18983 (clobber (match_operand:DI 0 "register_operand" "=S"))
18984 (clobber (match_operand:DI 1 "register_operand" "=D"))
18985 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18988 [(set_attr "type" "str")
18989 (set_attr "mode" "QI")
18990 (set_attr "prefix_rep" "1")])
18992 (define_expand "strlensi"
18993 [(set (match_operand:SI 0 "register_operand" "")
18994 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18995 (match_operand:QI 2 "immediate_operand" "")
18996 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18999 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19005 (define_expand "strlendi"
19006 [(set (match_operand:DI 0 "register_operand" "")
19007 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19008 (match_operand:QI 2 "immediate_operand" "")
19009 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19012 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19018 (define_expand "strlenqi_1"
19019 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19020 (use (reg:SI DIRFLAG_REG))
19021 (clobber (match_operand 1 "register_operand" ""))
19022 (clobber (reg:CC FLAGS_REG))])]
19026 (define_insn "*strlenqi_1"
19027 [(set (match_operand:SI 0 "register_operand" "=&c")
19028 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19029 (match_operand:QI 2 "register_operand" "a")
19030 (match_operand:SI 3 "immediate_operand" "i")
19031 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19032 (use (reg:SI DIRFLAG_REG))
19033 (clobber (match_operand:SI 1 "register_operand" "=D"))
19034 (clobber (reg:CC FLAGS_REG))]
19037 [(set_attr "type" "str")
19038 (set_attr "mode" "QI")
19039 (set_attr "prefix_rep" "1")])
19041 (define_insn "*strlenqi_rex_1"
19042 [(set (match_operand:DI 0 "register_operand" "=&c")
19043 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19044 (match_operand:QI 2 "register_operand" "a")
19045 (match_operand:DI 3 "immediate_operand" "i")
19046 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19047 (use (reg:SI DIRFLAG_REG))
19048 (clobber (match_operand:DI 1 "register_operand" "=D"))
19049 (clobber (reg:CC FLAGS_REG))]
19052 [(set_attr "type" "str")
19053 (set_attr "mode" "QI")
19054 (set_attr "prefix_rep" "1")])
19056 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19057 ;; handled in combine, but it is not currently up to the task.
19058 ;; When used for their truth value, the cmpstrn* expanders generate
19067 ;; The intermediate three instructions are unnecessary.
19069 ;; This one handles cmpstrn*_nz_1...
19072 (set (reg:CC FLAGS_REG)
19073 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19074 (mem:BLK (match_operand 5 "register_operand" ""))))
19075 (use (match_operand 6 "register_operand" ""))
19076 (use (match_operand:SI 3 "immediate_operand" ""))
19077 (use (reg:SI DIRFLAG_REG))
19078 (clobber (match_operand 0 "register_operand" ""))
19079 (clobber (match_operand 1 "register_operand" ""))
19080 (clobber (match_operand 2 "register_operand" ""))])
19081 (set (match_operand:QI 7 "register_operand" "")
19082 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19083 (set (match_operand:QI 8 "register_operand" "")
19084 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19085 (set (reg FLAGS_REG)
19086 (compare (match_dup 7) (match_dup 8)))
19088 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19090 (set (reg:CC FLAGS_REG)
19091 (compare:CC (mem:BLK (match_dup 4))
19092 (mem:BLK (match_dup 5))))
19093 (use (match_dup 6))
19094 (use (match_dup 3))
19095 (use (reg:SI DIRFLAG_REG))
19096 (clobber (match_dup 0))
19097 (clobber (match_dup 1))
19098 (clobber (match_dup 2))])]
19101 ;; ...and this one handles cmpstrn*_1.
19104 (set (reg:CC FLAGS_REG)
19105 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19107 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19108 (mem:BLK (match_operand 5 "register_operand" "")))
19110 (use (match_operand:SI 3 "immediate_operand" ""))
19111 (use (reg:CC FLAGS_REG))
19112 (use (reg:SI DIRFLAG_REG))
19113 (clobber (match_operand 0 "register_operand" ""))
19114 (clobber (match_operand 1 "register_operand" ""))
19115 (clobber (match_operand 2 "register_operand" ""))])
19116 (set (match_operand:QI 7 "register_operand" "")
19117 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19118 (set (match_operand:QI 8 "register_operand" "")
19119 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19120 (set (reg FLAGS_REG)
19121 (compare (match_dup 7) (match_dup 8)))
19123 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19125 (set (reg:CC FLAGS_REG)
19126 (if_then_else:CC (ne (match_dup 6)
19128 (compare:CC (mem:BLK (match_dup 4))
19129 (mem:BLK (match_dup 5)))
19131 (use (match_dup 3))
19132 (use (reg:CC FLAGS_REG))
19133 (use (reg:SI DIRFLAG_REG))
19134 (clobber (match_dup 0))
19135 (clobber (match_dup 1))
19136 (clobber (match_dup 2))])]
19141 ;; Conditional move instructions.
19143 (define_expand "movdicc"
19144 [(set (match_operand:DI 0 "register_operand" "")
19145 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19146 (match_operand:DI 2 "general_operand" "")
19147 (match_operand:DI 3 "general_operand" "")))]
19149 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19151 (define_insn "x86_movdicc_0_m1_rex64"
19152 [(set (match_operand:DI 0 "register_operand" "=r")
19153 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19156 (clobber (reg:CC FLAGS_REG))]
19159 ; Since we don't have the proper number of operands for an alu insn,
19160 ; fill in all the blanks.
19161 [(set_attr "type" "alu")
19162 (set_attr "pent_pair" "pu")
19163 (set_attr "memory" "none")
19164 (set_attr "imm_disp" "false")
19165 (set_attr "mode" "DI")
19166 (set_attr "length_immediate" "0")])
19168 (define_insn "*movdicc_c_rex64"
19169 [(set (match_operand:DI 0 "register_operand" "=r,r")
19170 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19171 [(reg FLAGS_REG) (const_int 0)])
19172 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19173 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19174 "TARGET_64BIT && TARGET_CMOVE
19175 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19177 cmov%O2%C1\t{%2, %0|%0, %2}
19178 cmov%O2%c1\t{%3, %0|%0, %3}"
19179 [(set_attr "type" "icmov")
19180 (set_attr "mode" "DI")])
19182 (define_expand "movsicc"
19183 [(set (match_operand:SI 0 "register_operand" "")
19184 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19185 (match_operand:SI 2 "general_operand" "")
19186 (match_operand:SI 3 "general_operand" "")))]
19188 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19190 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19191 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19192 ;; So just document what we're doing explicitly.
19194 (define_insn "x86_movsicc_0_m1"
19195 [(set (match_operand:SI 0 "register_operand" "=r")
19196 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19199 (clobber (reg:CC FLAGS_REG))]
19202 ; Since we don't have the proper number of operands for an alu insn,
19203 ; fill in all the blanks.
19204 [(set_attr "type" "alu")
19205 (set_attr "pent_pair" "pu")
19206 (set_attr "memory" "none")
19207 (set_attr "imm_disp" "false")
19208 (set_attr "mode" "SI")
19209 (set_attr "length_immediate" "0")])
19211 (define_insn "*movsicc_noc"
19212 [(set (match_operand:SI 0 "register_operand" "=r,r")
19213 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19214 [(reg FLAGS_REG) (const_int 0)])
19215 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19216 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19218 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19220 cmov%O2%C1\t{%2, %0|%0, %2}
19221 cmov%O2%c1\t{%3, %0|%0, %3}"
19222 [(set_attr "type" "icmov")
19223 (set_attr "mode" "SI")])
19225 (define_expand "movhicc"
19226 [(set (match_operand:HI 0 "register_operand" "")
19227 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19228 (match_operand:HI 2 "general_operand" "")
19229 (match_operand:HI 3 "general_operand" "")))]
19230 "TARGET_HIMODE_MATH"
19231 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19233 (define_insn "*movhicc_noc"
19234 [(set (match_operand:HI 0 "register_operand" "=r,r")
19235 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19236 [(reg FLAGS_REG) (const_int 0)])
19237 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19238 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19240 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19242 cmov%O2%C1\t{%2, %0|%0, %2}
19243 cmov%O2%c1\t{%3, %0|%0, %3}"
19244 [(set_attr "type" "icmov")
19245 (set_attr "mode" "HI")])
19247 (define_expand "movqicc"
19248 [(set (match_operand:QI 0 "register_operand" "")
19249 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19250 (match_operand:QI 2 "general_operand" "")
19251 (match_operand:QI 3 "general_operand" "")))]
19252 "TARGET_QIMODE_MATH"
19253 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19255 (define_insn_and_split "*movqicc_noc"
19256 [(set (match_operand:QI 0 "register_operand" "=r,r")
19257 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19258 [(match_operand 4 "flags_reg_operand" "")
19260 (match_operand:QI 2 "register_operand" "r,0")
19261 (match_operand:QI 3 "register_operand" "0,r")))]
19262 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19264 "&& reload_completed"
19265 [(set (match_dup 0)
19266 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19269 "operands[0] = gen_lowpart (SImode, operands[0]);
19270 operands[2] = gen_lowpart (SImode, operands[2]);
19271 operands[3] = gen_lowpart (SImode, operands[3]);"
19272 [(set_attr "type" "icmov")
19273 (set_attr "mode" "SI")])
19275 (define_expand "movsfcc"
19276 [(set (match_operand:SF 0 "register_operand" "")
19277 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19278 (match_operand:SF 2 "register_operand" "")
19279 (match_operand:SF 3 "register_operand" "")))]
19280 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19281 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19283 (define_insn "*movsfcc_1_387"
19284 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19285 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19286 [(reg FLAGS_REG) (const_int 0)])
19287 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19288 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19289 "TARGET_80387 && TARGET_CMOVE
19290 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19292 fcmov%F1\t{%2, %0|%0, %2}
19293 fcmov%f1\t{%3, %0|%0, %3}
19294 cmov%O2%C1\t{%2, %0|%0, %2}
19295 cmov%O2%c1\t{%3, %0|%0, %3}"
19296 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19297 (set_attr "mode" "SF,SF,SI,SI")])
19299 (define_expand "movdfcc"
19300 [(set (match_operand:DF 0 "register_operand" "")
19301 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19302 (match_operand:DF 2 "register_operand" "")
19303 (match_operand:DF 3 "register_operand" "")))]
19304 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19305 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19307 (define_insn "*movdfcc_1"
19308 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19309 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19310 [(reg FLAGS_REG) (const_int 0)])
19311 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19312 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19313 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19314 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19316 fcmov%F1\t{%2, %0|%0, %2}
19317 fcmov%f1\t{%3, %0|%0, %3}
19320 [(set_attr "type" "fcmov,fcmov,multi,multi")
19321 (set_attr "mode" "DF")])
19323 (define_insn "*movdfcc_1_rex64"
19324 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19325 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19326 [(reg FLAGS_REG) (const_int 0)])
19327 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19328 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19329 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19330 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19332 fcmov%F1\t{%2, %0|%0, %2}
19333 fcmov%f1\t{%3, %0|%0, %3}
19334 cmov%O2%C1\t{%2, %0|%0, %2}
19335 cmov%O2%c1\t{%3, %0|%0, %3}"
19336 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19337 (set_attr "mode" "DF")])
19340 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19341 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19342 [(match_operand 4 "flags_reg_operand" "")
19344 (match_operand:DF 2 "nonimmediate_operand" "")
19345 (match_operand:DF 3 "nonimmediate_operand" "")))]
19346 "!TARGET_64BIT && reload_completed"
19347 [(set (match_dup 2)
19348 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19352 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19355 "split_di (operands+2, 1, operands+5, operands+6);
19356 split_di (operands+3, 1, operands+7, operands+8);
19357 split_di (operands, 1, operands+2, operands+3);")
19359 (define_expand "movxfcc"
19360 [(set (match_operand:XF 0 "register_operand" "")
19361 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19362 (match_operand:XF 2 "register_operand" "")
19363 (match_operand:XF 3 "register_operand" "")))]
19364 "TARGET_80387 && TARGET_CMOVE"
19365 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19367 (define_insn "*movxfcc_1"
19368 [(set (match_operand:XF 0 "register_operand" "=f,f")
19369 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19370 [(reg FLAGS_REG) (const_int 0)])
19371 (match_operand:XF 2 "register_operand" "f,0")
19372 (match_operand:XF 3 "register_operand" "0,f")))]
19373 "TARGET_80387 && TARGET_CMOVE"
19375 fcmov%F1\t{%2, %0|%0, %2}
19376 fcmov%f1\t{%3, %0|%0, %3}"
19377 [(set_attr "type" "fcmov")
19378 (set_attr "mode" "XF")])
19380 ;; These versions of the min/max patterns are intentionally ignorant of
19381 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19382 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19383 ;; are undefined in this condition, we're certain this is correct.
19385 (define_insn "sminsf3"
19386 [(set (match_operand:SF 0 "register_operand" "=x")
19387 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19388 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19390 "minss\t{%2, %0|%0, %2}"
19391 [(set_attr "type" "sseadd")
19392 (set_attr "mode" "SF")])
19394 (define_insn "smaxsf3"
19395 [(set (match_operand:SF 0 "register_operand" "=x")
19396 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19397 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19399 "maxss\t{%2, %0|%0, %2}"
19400 [(set_attr "type" "sseadd")
19401 (set_attr "mode" "SF")])
19403 (define_insn "smindf3"
19404 [(set (match_operand:DF 0 "register_operand" "=x")
19405 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19406 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19407 "TARGET_SSE2 && TARGET_SSE_MATH"
19408 "minsd\t{%2, %0|%0, %2}"
19409 [(set_attr "type" "sseadd")
19410 (set_attr "mode" "DF")])
19412 (define_insn "smaxdf3"
19413 [(set (match_operand:DF 0 "register_operand" "=x")
19414 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19415 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19416 "TARGET_SSE2 && TARGET_SSE_MATH"
19417 "maxsd\t{%2, %0|%0, %2}"
19418 [(set_attr "type" "sseadd")
19419 (set_attr "mode" "DF")])
19421 ;; These versions of the min/max patterns implement exactly the operations
19422 ;; min = (op1 < op2 ? op1 : op2)
19423 ;; max = (!(op1 < op2) ? op1 : op2)
19424 ;; Their operands are not commutative, and thus they may be used in the
19425 ;; presence of -0.0 and NaN.
19427 (define_insn "*ieee_sminsf3"
19428 [(set (match_operand:SF 0 "register_operand" "=x")
19429 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19430 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19433 "minss\t{%2, %0|%0, %2}"
19434 [(set_attr "type" "sseadd")
19435 (set_attr "mode" "SF")])
19437 (define_insn "*ieee_smaxsf3"
19438 [(set (match_operand:SF 0 "register_operand" "=x")
19439 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19440 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19443 "maxss\t{%2, %0|%0, %2}"
19444 [(set_attr "type" "sseadd")
19445 (set_attr "mode" "SF")])
19447 (define_insn "*ieee_smindf3"
19448 [(set (match_operand:DF 0 "register_operand" "=x")
19449 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19450 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19452 "TARGET_SSE2 && TARGET_SSE_MATH"
19453 "minsd\t{%2, %0|%0, %2}"
19454 [(set_attr "type" "sseadd")
19455 (set_attr "mode" "DF")])
19457 (define_insn "*ieee_smaxdf3"
19458 [(set (match_operand:DF 0 "register_operand" "=x")
19459 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19460 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19462 "TARGET_SSE2 && TARGET_SSE_MATH"
19463 "maxsd\t{%2, %0|%0, %2}"
19464 [(set_attr "type" "sseadd")
19465 (set_attr "mode" "DF")])
19467 ;; Make two stack loads independent:
19469 ;; fld %st(0) -> fld bb
19470 ;; fmul bb fmul %st(1), %st
19472 ;; Actually we only match the last two instructions for simplicity.
19474 [(set (match_operand 0 "fp_register_operand" "")
19475 (match_operand 1 "fp_register_operand" ""))
19477 (match_operator 2 "binary_fp_operator"
19479 (match_operand 3 "memory_operand" "")]))]
19480 "REGNO (operands[0]) != REGNO (operands[1])"
19481 [(set (match_dup 0) (match_dup 3))
19482 (set (match_dup 0) (match_dup 4))]
19484 ;; The % modifier is not operational anymore in peephole2's, so we have to
19485 ;; swap the operands manually in the case of addition and multiplication.
19486 "if (COMMUTATIVE_ARITH_P (operands[2]))
19487 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19488 operands[0], operands[1]);
19490 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19491 operands[1], operands[0]);")
19493 ;; Conditional addition patterns
19494 (define_expand "addqicc"
19495 [(match_operand:QI 0 "register_operand" "")
19496 (match_operand 1 "comparison_operator" "")
19497 (match_operand:QI 2 "register_operand" "")
19498 (match_operand:QI 3 "const_int_operand" "")]
19500 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19502 (define_expand "addhicc"
19503 [(match_operand:HI 0 "register_operand" "")
19504 (match_operand 1 "comparison_operator" "")
19505 (match_operand:HI 2 "register_operand" "")
19506 (match_operand:HI 3 "const_int_operand" "")]
19508 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19510 (define_expand "addsicc"
19511 [(match_operand:SI 0 "register_operand" "")
19512 (match_operand 1 "comparison_operator" "")
19513 (match_operand:SI 2 "register_operand" "")
19514 (match_operand:SI 3 "const_int_operand" "")]
19516 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19518 (define_expand "adddicc"
19519 [(match_operand:DI 0 "register_operand" "")
19520 (match_operand 1 "comparison_operator" "")
19521 (match_operand:DI 2 "register_operand" "")
19522 (match_operand:DI 3 "const_int_operand" "")]
19524 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19527 ;; Misc patterns (?)
19529 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19530 ;; Otherwise there will be nothing to keep
19532 ;; [(set (reg ebp) (reg esp))]
19533 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19534 ;; (clobber (eflags)]
19535 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19537 ;; in proper program order.
19538 (define_insn "pro_epilogue_adjust_stack_1"
19539 [(set (match_operand:SI 0 "register_operand" "=r,r")
19540 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19541 (match_operand:SI 2 "immediate_operand" "i,i")))
19542 (clobber (reg:CC FLAGS_REG))
19543 (clobber (mem:BLK (scratch)))]
19546 switch (get_attr_type (insn))
19549 return "mov{l}\t{%1, %0|%0, %1}";
19552 if (GET_CODE (operands[2]) == CONST_INT
19553 && (INTVAL (operands[2]) == 128
19554 || (INTVAL (operands[2]) < 0
19555 && INTVAL (operands[2]) != -128)))
19557 operands[2] = GEN_INT (-INTVAL (operands[2]));
19558 return "sub{l}\t{%2, %0|%0, %2}";
19560 return "add{l}\t{%2, %0|%0, %2}";
19563 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19564 return "lea{l}\t{%a2, %0|%0, %a2}";
19567 gcc_unreachable ();
19570 [(set (attr "type")
19571 (cond [(eq_attr "alternative" "0")
19572 (const_string "alu")
19573 (match_operand:SI 2 "const0_operand" "")
19574 (const_string "imov")
19576 (const_string "lea")))
19577 (set_attr "mode" "SI")])
19579 (define_insn "pro_epilogue_adjust_stack_rex64"
19580 [(set (match_operand:DI 0 "register_operand" "=r,r")
19581 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19582 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19583 (clobber (reg:CC FLAGS_REG))
19584 (clobber (mem:BLK (scratch)))]
19587 switch (get_attr_type (insn))
19590 return "mov{q}\t{%1, %0|%0, %1}";
19593 if (GET_CODE (operands[2]) == CONST_INT
19594 /* Avoid overflows. */
19595 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19596 && (INTVAL (operands[2]) == 128
19597 || (INTVAL (operands[2]) < 0
19598 && INTVAL (operands[2]) != -128)))
19600 operands[2] = GEN_INT (-INTVAL (operands[2]));
19601 return "sub{q}\t{%2, %0|%0, %2}";
19603 return "add{q}\t{%2, %0|%0, %2}";
19606 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19607 return "lea{q}\t{%a2, %0|%0, %a2}";
19610 gcc_unreachable ();
19613 [(set (attr "type")
19614 (cond [(eq_attr "alternative" "0")
19615 (const_string "alu")
19616 (match_operand:DI 2 "const0_operand" "")
19617 (const_string "imov")
19619 (const_string "lea")))
19620 (set_attr "mode" "DI")])
19622 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19623 [(set (match_operand:DI 0 "register_operand" "=r,r")
19624 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19625 (match_operand:DI 3 "immediate_operand" "i,i")))
19626 (use (match_operand:DI 2 "register_operand" "r,r"))
19627 (clobber (reg:CC FLAGS_REG))
19628 (clobber (mem:BLK (scratch)))]
19631 switch (get_attr_type (insn))
19634 return "add{q}\t{%2, %0|%0, %2}";
19637 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19638 return "lea{q}\t{%a2, %0|%0, %a2}";
19641 gcc_unreachable ();
19644 [(set_attr "type" "alu,lea")
19645 (set_attr "mode" "DI")])
19647 (define_expand "allocate_stack_worker"
19648 [(match_operand:SI 0 "register_operand" "")]
19649 "TARGET_STACK_PROBE"
19651 if (reload_completed)
19654 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19656 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19661 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19663 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19668 (define_insn "allocate_stack_worker_1"
19669 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19670 UNSPECV_STACK_PROBE)
19671 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19672 (clobber (match_scratch:SI 1 "=0"))
19673 (clobber (reg:CC FLAGS_REG))]
19674 "!TARGET_64BIT && TARGET_STACK_PROBE"
19676 [(set_attr "type" "multi")
19677 (set_attr "length" "5")])
19679 (define_expand "allocate_stack_worker_postreload"
19680 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19681 UNSPECV_STACK_PROBE)
19682 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19683 (clobber (match_dup 0))
19684 (clobber (reg:CC FLAGS_REG))])]
19688 (define_insn "allocate_stack_worker_rex64"
19689 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19690 UNSPECV_STACK_PROBE)
19691 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19692 (clobber (match_scratch:DI 1 "=0"))
19693 (clobber (reg:CC FLAGS_REG))]
19694 "TARGET_64BIT && TARGET_STACK_PROBE"
19696 [(set_attr "type" "multi")
19697 (set_attr "length" "5")])
19699 (define_expand "allocate_stack_worker_rex64_postreload"
19700 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19701 UNSPECV_STACK_PROBE)
19702 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19703 (clobber (match_dup 0))
19704 (clobber (reg:CC FLAGS_REG))])]
19708 (define_expand "allocate_stack"
19709 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19710 (minus:SI (reg:SI SP_REG)
19711 (match_operand:SI 1 "general_operand" "")))
19712 (clobber (reg:CC FLAGS_REG))])
19713 (parallel [(set (reg:SI SP_REG)
19714 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19715 (clobber (reg:CC FLAGS_REG))])]
19716 "TARGET_STACK_PROBE"
19718 #ifdef CHECK_STACK_LIMIT
19719 if (GET_CODE (operands[1]) == CONST_INT
19720 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19721 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19725 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19728 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19732 (define_expand "builtin_setjmp_receiver"
19733 [(label_ref (match_operand 0 "" ""))]
19734 "!TARGET_64BIT && flag_pic"
19739 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19740 rtx label_rtx = gen_label_rtx ();
19741 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19742 xops[0] = xops[1] = picreg;
19743 xops[2] = gen_rtx_CONST (SImode,
19744 gen_rtx_MINUS (SImode,
19745 gen_rtx_LABEL_REF (SImode, label_rtx),
19746 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19747 ix86_expand_binary_operator (MINUS, SImode, xops);
19750 emit_insn (gen_set_got (pic_offset_table_rtx));
19754 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19757 [(set (match_operand 0 "register_operand" "")
19758 (match_operator 3 "promotable_binary_operator"
19759 [(match_operand 1 "register_operand" "")
19760 (match_operand 2 "aligned_operand" "")]))
19761 (clobber (reg:CC FLAGS_REG))]
19762 "! TARGET_PARTIAL_REG_STALL && reload_completed
19763 && ((GET_MODE (operands[0]) == HImode
19764 && ((!optimize_size && !TARGET_FAST_PREFIX)
19765 /* ??? next two lines just !satisfies_constraint_K (...) */
19766 || GET_CODE (operands[2]) != CONST_INT
19767 || satisfies_constraint_K (operands[2])))
19768 || (GET_MODE (operands[0]) == QImode
19769 && (TARGET_PROMOTE_QImode || optimize_size)))"
19770 [(parallel [(set (match_dup 0)
19771 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19772 (clobber (reg:CC FLAGS_REG))])]
19773 "operands[0] = gen_lowpart (SImode, operands[0]);
19774 operands[1] = gen_lowpart (SImode, operands[1]);
19775 if (GET_CODE (operands[3]) != ASHIFT)
19776 operands[2] = gen_lowpart (SImode, operands[2]);
19777 PUT_MODE (operands[3], SImode);")
19779 ; Promote the QImode tests, as i386 has encoding of the AND
19780 ; instruction with 32-bit sign-extended immediate and thus the
19781 ; instruction size is unchanged, except in the %eax case for
19782 ; which it is increased by one byte, hence the ! optimize_size.
19784 [(set (match_operand 0 "flags_reg_operand" "")
19785 (match_operator 2 "compare_operator"
19786 [(and (match_operand 3 "aligned_operand" "")
19787 (match_operand 4 "const_int_operand" ""))
19789 (set (match_operand 1 "register_operand" "")
19790 (and (match_dup 3) (match_dup 4)))]
19791 "! TARGET_PARTIAL_REG_STALL && reload_completed
19792 /* Ensure that the operand will remain sign-extended immediate. */
19793 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19795 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19796 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19797 [(parallel [(set (match_dup 0)
19798 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19801 (and:SI (match_dup 3) (match_dup 4)))])]
19804 = gen_int_mode (INTVAL (operands[4])
19805 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19806 operands[1] = gen_lowpart (SImode, operands[1]);
19807 operands[3] = gen_lowpart (SImode, operands[3]);
19810 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19811 ; the TEST instruction with 32-bit sign-extended immediate and thus
19812 ; the instruction size would at least double, which is not what we
19813 ; want even with ! optimize_size.
19815 [(set (match_operand 0 "flags_reg_operand" "")
19816 (match_operator 1 "compare_operator"
19817 [(and (match_operand:HI 2 "aligned_operand" "")
19818 (match_operand:HI 3 "const_int_operand" ""))
19820 "! TARGET_PARTIAL_REG_STALL && reload_completed
19821 /* Ensure that the operand will remain sign-extended immediate. */
19822 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19823 && ! TARGET_FAST_PREFIX
19824 && ! optimize_size"
19825 [(set (match_dup 0)
19826 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19830 = gen_int_mode (INTVAL (operands[3])
19831 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19832 operands[2] = gen_lowpart (SImode, operands[2]);
19836 [(set (match_operand 0 "register_operand" "")
19837 (neg (match_operand 1 "register_operand" "")))
19838 (clobber (reg:CC FLAGS_REG))]
19839 "! TARGET_PARTIAL_REG_STALL && reload_completed
19840 && (GET_MODE (operands[0]) == HImode
19841 || (GET_MODE (operands[0]) == QImode
19842 && (TARGET_PROMOTE_QImode || optimize_size)))"
19843 [(parallel [(set (match_dup 0)
19844 (neg:SI (match_dup 1)))
19845 (clobber (reg:CC FLAGS_REG))])]
19846 "operands[0] = gen_lowpart (SImode, operands[0]);
19847 operands[1] = gen_lowpart (SImode, operands[1]);")
19850 [(set (match_operand 0 "register_operand" "")
19851 (not (match_operand 1 "register_operand" "")))]
19852 "! TARGET_PARTIAL_REG_STALL && reload_completed
19853 && (GET_MODE (operands[0]) == HImode
19854 || (GET_MODE (operands[0]) == QImode
19855 && (TARGET_PROMOTE_QImode || optimize_size)))"
19856 [(set (match_dup 0)
19857 (not:SI (match_dup 1)))]
19858 "operands[0] = gen_lowpart (SImode, operands[0]);
19859 operands[1] = gen_lowpart (SImode, operands[1]);")
19862 [(set (match_operand 0 "register_operand" "")
19863 (if_then_else (match_operator 1 "comparison_operator"
19864 [(reg FLAGS_REG) (const_int 0)])
19865 (match_operand 2 "register_operand" "")
19866 (match_operand 3 "register_operand" "")))]
19867 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19868 && (GET_MODE (operands[0]) == HImode
19869 || (GET_MODE (operands[0]) == QImode
19870 && (TARGET_PROMOTE_QImode || optimize_size)))"
19871 [(set (match_dup 0)
19872 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19873 "operands[0] = gen_lowpart (SImode, operands[0]);
19874 operands[2] = gen_lowpart (SImode, operands[2]);
19875 operands[3] = gen_lowpart (SImode, operands[3]);")
19878 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19879 ;; transform a complex memory operation into two memory to register operations.
19881 ;; Don't push memory operands
19883 [(set (match_operand:SI 0 "push_operand" "")
19884 (match_operand:SI 1 "memory_operand" ""))
19885 (match_scratch:SI 2 "r")]
19886 "!optimize_size && !TARGET_PUSH_MEMORY
19887 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19888 [(set (match_dup 2) (match_dup 1))
19889 (set (match_dup 0) (match_dup 2))]
19893 [(set (match_operand:DI 0 "push_operand" "")
19894 (match_operand:DI 1 "memory_operand" ""))
19895 (match_scratch:DI 2 "r")]
19896 "!optimize_size && !TARGET_PUSH_MEMORY
19897 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19898 [(set (match_dup 2) (match_dup 1))
19899 (set (match_dup 0) (match_dup 2))]
19902 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19905 [(set (match_operand:SF 0 "push_operand" "")
19906 (match_operand:SF 1 "memory_operand" ""))
19907 (match_scratch:SF 2 "r")]
19908 "!optimize_size && !TARGET_PUSH_MEMORY
19909 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19910 [(set (match_dup 2) (match_dup 1))
19911 (set (match_dup 0) (match_dup 2))]
19915 [(set (match_operand:HI 0 "push_operand" "")
19916 (match_operand:HI 1 "memory_operand" ""))
19917 (match_scratch:HI 2 "r")]
19918 "!optimize_size && !TARGET_PUSH_MEMORY
19919 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19920 [(set (match_dup 2) (match_dup 1))
19921 (set (match_dup 0) (match_dup 2))]
19925 [(set (match_operand:QI 0 "push_operand" "")
19926 (match_operand:QI 1 "memory_operand" ""))
19927 (match_scratch:QI 2 "q")]
19928 "!optimize_size && !TARGET_PUSH_MEMORY
19929 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19930 [(set (match_dup 2) (match_dup 1))
19931 (set (match_dup 0) (match_dup 2))]
19934 ;; Don't move an immediate directly to memory when the instruction
19937 [(match_scratch:SI 1 "r")
19938 (set (match_operand:SI 0 "memory_operand" "")
19941 && ! TARGET_USE_MOV0
19942 && TARGET_SPLIT_LONG_MOVES
19943 && get_attr_length (insn) >= ix86_cost->large_insn
19944 && peep2_regno_dead_p (0, FLAGS_REG)"
19945 [(parallel [(set (match_dup 1) (const_int 0))
19946 (clobber (reg:CC FLAGS_REG))])
19947 (set (match_dup 0) (match_dup 1))]
19951 [(match_scratch:HI 1 "r")
19952 (set (match_operand:HI 0 "memory_operand" "")
19955 && ! TARGET_USE_MOV0
19956 && TARGET_SPLIT_LONG_MOVES
19957 && get_attr_length (insn) >= ix86_cost->large_insn
19958 && peep2_regno_dead_p (0, FLAGS_REG)"
19959 [(parallel [(set (match_dup 2) (const_int 0))
19960 (clobber (reg:CC FLAGS_REG))])
19961 (set (match_dup 0) (match_dup 1))]
19962 "operands[2] = gen_lowpart (SImode, operands[1]);")
19965 [(match_scratch:QI 1 "q")
19966 (set (match_operand:QI 0 "memory_operand" "")
19969 && ! TARGET_USE_MOV0
19970 && TARGET_SPLIT_LONG_MOVES
19971 && get_attr_length (insn) >= ix86_cost->large_insn
19972 && peep2_regno_dead_p (0, FLAGS_REG)"
19973 [(parallel [(set (match_dup 2) (const_int 0))
19974 (clobber (reg:CC FLAGS_REG))])
19975 (set (match_dup 0) (match_dup 1))]
19976 "operands[2] = gen_lowpart (SImode, operands[1]);")
19979 [(match_scratch:SI 2 "r")
19980 (set (match_operand:SI 0 "memory_operand" "")
19981 (match_operand:SI 1 "immediate_operand" ""))]
19983 && get_attr_length (insn) >= ix86_cost->large_insn
19984 && TARGET_SPLIT_LONG_MOVES"
19985 [(set (match_dup 2) (match_dup 1))
19986 (set (match_dup 0) (match_dup 2))]
19990 [(match_scratch:HI 2 "r")
19991 (set (match_operand:HI 0 "memory_operand" "")
19992 (match_operand:HI 1 "immediate_operand" ""))]
19993 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19994 && TARGET_SPLIT_LONG_MOVES"
19995 [(set (match_dup 2) (match_dup 1))
19996 (set (match_dup 0) (match_dup 2))]
20000 [(match_scratch:QI 2 "q")
20001 (set (match_operand:QI 0 "memory_operand" "")
20002 (match_operand:QI 1 "immediate_operand" ""))]
20003 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20004 && TARGET_SPLIT_LONG_MOVES"
20005 [(set (match_dup 2) (match_dup 1))
20006 (set (match_dup 0) (match_dup 2))]
20009 ;; Don't compare memory with zero, load and use a test instead.
20011 [(set (match_operand 0 "flags_reg_operand" "")
20012 (match_operator 1 "compare_operator"
20013 [(match_operand:SI 2 "memory_operand" "")
20015 (match_scratch:SI 3 "r")]
20016 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
20017 [(set (match_dup 3) (match_dup 2))
20018 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20021 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20022 ;; Don't split NOTs with a displacement operand, because resulting XOR
20023 ;; will not be pairable anyway.
20025 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20026 ;; represented using a modRM byte. The XOR replacement is long decoded,
20027 ;; so this split helps here as well.
20029 ;; Note: Can't do this as a regular split because we can't get proper
20030 ;; lifetime information then.
20033 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20034 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20036 && peep2_regno_dead_p (0, FLAGS_REG)
20037 && ((TARGET_PENTIUM
20038 && (GET_CODE (operands[0]) != MEM
20039 || !memory_displacement_operand (operands[0], SImode)))
20040 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20041 [(parallel [(set (match_dup 0)
20042 (xor:SI (match_dup 1) (const_int -1)))
20043 (clobber (reg:CC FLAGS_REG))])]
20047 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20048 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20050 && peep2_regno_dead_p (0, FLAGS_REG)
20051 && ((TARGET_PENTIUM
20052 && (GET_CODE (operands[0]) != MEM
20053 || !memory_displacement_operand (operands[0], HImode)))
20054 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20055 [(parallel [(set (match_dup 0)
20056 (xor:HI (match_dup 1) (const_int -1)))
20057 (clobber (reg:CC FLAGS_REG))])]
20061 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20062 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20064 && peep2_regno_dead_p (0, FLAGS_REG)
20065 && ((TARGET_PENTIUM
20066 && (GET_CODE (operands[0]) != MEM
20067 || !memory_displacement_operand (operands[0], QImode)))
20068 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20069 [(parallel [(set (match_dup 0)
20070 (xor:QI (match_dup 1) (const_int -1)))
20071 (clobber (reg:CC FLAGS_REG))])]
20074 ;; Non pairable "test imm, reg" instructions can be translated to
20075 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20076 ;; byte opcode instead of two, have a short form for byte operands),
20077 ;; so do it for other CPUs as well. Given that the value was dead,
20078 ;; this should not create any new dependencies. Pass on the sub-word
20079 ;; versions if we're concerned about partial register stalls.
20082 [(set (match_operand 0 "flags_reg_operand" "")
20083 (match_operator 1 "compare_operator"
20084 [(and:SI (match_operand:SI 2 "register_operand" "")
20085 (match_operand:SI 3 "immediate_operand" ""))
20087 "ix86_match_ccmode (insn, CCNOmode)
20088 && (true_regnum (operands[2]) != 0
20089 || satisfies_constraint_K (operands[3]))
20090 && peep2_reg_dead_p (1, operands[2])"
20092 [(set (match_dup 0)
20093 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20096 (and:SI (match_dup 2) (match_dup 3)))])]
20099 ;; We don't need to handle HImode case, because it will be promoted to SImode
20100 ;; on ! TARGET_PARTIAL_REG_STALL
20103 [(set (match_operand 0 "flags_reg_operand" "")
20104 (match_operator 1 "compare_operator"
20105 [(and:QI (match_operand:QI 2 "register_operand" "")
20106 (match_operand:QI 3 "immediate_operand" ""))
20108 "! TARGET_PARTIAL_REG_STALL
20109 && ix86_match_ccmode (insn, CCNOmode)
20110 && true_regnum (operands[2]) != 0
20111 && peep2_reg_dead_p (1, operands[2])"
20113 [(set (match_dup 0)
20114 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20117 (and:QI (match_dup 2) (match_dup 3)))])]
20121 [(set (match_operand 0 "flags_reg_operand" "")
20122 (match_operator 1 "compare_operator"
20125 (match_operand 2 "ext_register_operand" "")
20128 (match_operand 3 "const_int_operand" ""))
20130 "! TARGET_PARTIAL_REG_STALL
20131 && ix86_match_ccmode (insn, CCNOmode)
20132 && true_regnum (operands[2]) != 0
20133 && peep2_reg_dead_p (1, operands[2])"
20134 [(parallel [(set (match_dup 0)
20143 (set (zero_extract:SI (match_dup 2)
20154 ;; Don't do logical operations with memory inputs.
20156 [(match_scratch:SI 2 "r")
20157 (parallel [(set (match_operand:SI 0 "register_operand" "")
20158 (match_operator:SI 3 "arith_or_logical_operator"
20160 (match_operand:SI 1 "memory_operand" "")]))
20161 (clobber (reg:CC FLAGS_REG))])]
20162 "! optimize_size && ! TARGET_READ_MODIFY"
20163 [(set (match_dup 2) (match_dup 1))
20164 (parallel [(set (match_dup 0)
20165 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20166 (clobber (reg:CC FLAGS_REG))])]
20170 [(match_scratch:SI 2 "r")
20171 (parallel [(set (match_operand:SI 0 "register_operand" "")
20172 (match_operator:SI 3 "arith_or_logical_operator"
20173 [(match_operand:SI 1 "memory_operand" "")
20175 (clobber (reg:CC FLAGS_REG))])]
20176 "! optimize_size && ! TARGET_READ_MODIFY"
20177 [(set (match_dup 2) (match_dup 1))
20178 (parallel [(set (match_dup 0)
20179 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20180 (clobber (reg:CC FLAGS_REG))])]
20183 ; Don't do logical operations with memory outputs
20185 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20186 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20187 ; the same decoder scheduling characteristics as the original.
20190 [(match_scratch:SI 2 "r")
20191 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20192 (match_operator:SI 3 "arith_or_logical_operator"
20194 (match_operand:SI 1 "nonmemory_operand" "")]))
20195 (clobber (reg:CC FLAGS_REG))])]
20196 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20197 [(set (match_dup 2) (match_dup 0))
20198 (parallel [(set (match_dup 2)
20199 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20200 (clobber (reg:CC FLAGS_REG))])
20201 (set (match_dup 0) (match_dup 2))]
20205 [(match_scratch:SI 2 "r")
20206 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20207 (match_operator:SI 3 "arith_or_logical_operator"
20208 [(match_operand:SI 1 "nonmemory_operand" "")
20210 (clobber (reg:CC FLAGS_REG))])]
20211 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20212 [(set (match_dup 2) (match_dup 0))
20213 (parallel [(set (match_dup 2)
20214 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20215 (clobber (reg:CC FLAGS_REG))])
20216 (set (match_dup 0) (match_dup 2))]
20219 ;; Attempt to always use XOR for zeroing registers.
20221 [(set (match_operand 0 "register_operand" "")
20222 (match_operand 1 "const0_operand" ""))]
20223 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20224 && (! TARGET_USE_MOV0 || optimize_size)
20225 && GENERAL_REG_P (operands[0])
20226 && peep2_regno_dead_p (0, FLAGS_REG)"
20227 [(parallel [(set (match_dup 0) (const_int 0))
20228 (clobber (reg:CC FLAGS_REG))])]
20230 operands[0] = gen_lowpart (word_mode, operands[0]);
20234 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20236 "(GET_MODE (operands[0]) == QImode
20237 || GET_MODE (operands[0]) == HImode)
20238 && (! TARGET_USE_MOV0 || optimize_size)
20239 && peep2_regno_dead_p (0, FLAGS_REG)"
20240 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20241 (clobber (reg:CC FLAGS_REG))])])
20243 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20245 [(set (match_operand 0 "register_operand" "")
20247 "(GET_MODE (operands[0]) == HImode
20248 || GET_MODE (operands[0]) == SImode
20249 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20250 && (optimize_size || TARGET_PENTIUM)
20251 && peep2_regno_dead_p (0, FLAGS_REG)"
20252 [(parallel [(set (match_dup 0) (const_int -1))
20253 (clobber (reg:CC FLAGS_REG))])]
20254 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20257 ;; Attempt to convert simple leas to adds. These can be created by
20260 [(set (match_operand:SI 0 "register_operand" "")
20261 (plus:SI (match_dup 0)
20262 (match_operand:SI 1 "nonmemory_operand" "")))]
20263 "peep2_regno_dead_p (0, FLAGS_REG)"
20264 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20265 (clobber (reg:CC FLAGS_REG))])]
20269 [(set (match_operand:SI 0 "register_operand" "")
20270 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20271 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20272 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20273 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20274 (clobber (reg:CC FLAGS_REG))])]
20275 "operands[2] = gen_lowpart (SImode, operands[2]);")
20278 [(set (match_operand:DI 0 "register_operand" "")
20279 (plus:DI (match_dup 0)
20280 (match_operand:DI 1 "x86_64_general_operand" "")))]
20281 "peep2_regno_dead_p (0, FLAGS_REG)"
20282 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20283 (clobber (reg:CC FLAGS_REG))])]
20287 [(set (match_operand:SI 0 "register_operand" "")
20288 (mult:SI (match_dup 0)
20289 (match_operand:SI 1 "const_int_operand" "")))]
20290 "exact_log2 (INTVAL (operands[1])) >= 0
20291 && peep2_regno_dead_p (0, FLAGS_REG)"
20292 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20293 (clobber (reg:CC FLAGS_REG))])]
20294 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20297 [(set (match_operand:DI 0 "register_operand" "")
20298 (mult:DI (match_dup 0)
20299 (match_operand:DI 1 "const_int_operand" "")))]
20300 "exact_log2 (INTVAL (operands[1])) >= 0
20301 && peep2_regno_dead_p (0, FLAGS_REG)"
20302 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20303 (clobber (reg:CC FLAGS_REG))])]
20304 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20307 [(set (match_operand:SI 0 "register_operand" "")
20308 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20309 (match_operand:DI 2 "const_int_operand" "")) 0))]
20310 "exact_log2 (INTVAL (operands[2])) >= 0
20311 && REGNO (operands[0]) == REGNO (operands[1])
20312 && peep2_regno_dead_p (0, FLAGS_REG)"
20313 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20314 (clobber (reg:CC FLAGS_REG))])]
20315 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20317 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20318 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20319 ;; many CPUs it is also faster, since special hardware to avoid esp
20320 ;; dependencies is present.
20322 ;; While some of these conversions may be done using splitters, we use peepholes
20323 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20325 ;; Convert prologue esp subtractions to push.
20326 ;; We need register to push. In order to keep verify_flow_info happy we have
20328 ;; - use scratch and clobber it in order to avoid dependencies
20329 ;; - use already live register
20330 ;; We can't use the second way right now, since there is no reliable way how to
20331 ;; verify that given register is live. First choice will also most likely in
20332 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20333 ;; call clobbered registers are dead. We may want to use base pointer as an
20334 ;; alternative when no register is available later.
20337 [(match_scratch:SI 0 "r")
20338 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20339 (clobber (reg:CC FLAGS_REG))
20340 (clobber (mem:BLK (scratch)))])]
20341 "optimize_size || !TARGET_SUB_ESP_4"
20342 [(clobber (match_dup 0))
20343 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20344 (clobber (mem:BLK (scratch)))])])
20347 [(match_scratch:SI 0 "r")
20348 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20349 (clobber (reg:CC FLAGS_REG))
20350 (clobber (mem:BLK (scratch)))])]
20351 "optimize_size || !TARGET_SUB_ESP_8"
20352 [(clobber (match_dup 0))
20353 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20354 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20355 (clobber (mem:BLK (scratch)))])])
20357 ;; Convert esp subtractions to push.
20359 [(match_scratch:SI 0 "r")
20360 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20361 (clobber (reg:CC FLAGS_REG))])]
20362 "optimize_size || !TARGET_SUB_ESP_4"
20363 [(clobber (match_dup 0))
20364 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20367 [(match_scratch:SI 0 "r")
20368 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20369 (clobber (reg:CC FLAGS_REG))])]
20370 "optimize_size || !TARGET_SUB_ESP_8"
20371 [(clobber (match_dup 0))
20372 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20373 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20375 ;; Convert epilogue deallocator to pop.
20377 [(match_scratch:SI 0 "r")
20378 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20379 (clobber (reg:CC FLAGS_REG))
20380 (clobber (mem:BLK (scratch)))])]
20381 "optimize_size || !TARGET_ADD_ESP_4"
20382 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20383 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20384 (clobber (mem:BLK (scratch)))])]
20387 ;; Two pops case is tricky, since pop causes dependency on destination register.
20388 ;; We use two registers if available.
20390 [(match_scratch:SI 0 "r")
20391 (match_scratch:SI 1 "r")
20392 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20393 (clobber (reg:CC FLAGS_REG))
20394 (clobber (mem:BLK (scratch)))])]
20395 "optimize_size || !TARGET_ADD_ESP_8"
20396 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20397 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20398 (clobber (mem:BLK (scratch)))])
20399 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20400 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20404 [(match_scratch:SI 0 "r")
20405 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20406 (clobber (reg:CC FLAGS_REG))
20407 (clobber (mem:BLK (scratch)))])]
20409 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20410 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20411 (clobber (mem:BLK (scratch)))])
20412 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20413 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20416 ;; Convert esp additions to pop.
20418 [(match_scratch:SI 0 "r")
20419 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20420 (clobber (reg:CC FLAGS_REG))])]
20422 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20423 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20426 ;; Two pops case is tricky, since pop causes dependency on destination register.
20427 ;; We use two registers if available.
20429 [(match_scratch:SI 0 "r")
20430 (match_scratch:SI 1 "r")
20431 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20432 (clobber (reg:CC FLAGS_REG))])]
20434 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20435 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20436 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20437 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20441 [(match_scratch:SI 0 "r")
20442 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20443 (clobber (reg:CC FLAGS_REG))])]
20445 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20446 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20447 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20448 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20451 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20452 ;; required and register dies. Similarly for 128 to plus -128.
20454 [(set (match_operand 0 "flags_reg_operand" "")
20455 (match_operator 1 "compare_operator"
20456 [(match_operand 2 "register_operand" "")
20457 (match_operand 3 "const_int_operand" "")]))]
20458 "(INTVAL (operands[3]) == -1
20459 || INTVAL (operands[3]) == 1
20460 || INTVAL (operands[3]) == 128)
20461 && ix86_match_ccmode (insn, CCGCmode)
20462 && peep2_reg_dead_p (1, operands[2])"
20463 [(parallel [(set (match_dup 0)
20464 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20465 (clobber (match_dup 2))])]
20469 [(match_scratch:DI 0 "r")
20470 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20471 (clobber (reg:CC FLAGS_REG))
20472 (clobber (mem:BLK (scratch)))])]
20473 "optimize_size || !TARGET_SUB_ESP_4"
20474 [(clobber (match_dup 0))
20475 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20476 (clobber (mem:BLK (scratch)))])])
20479 [(match_scratch:DI 0 "r")
20480 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20481 (clobber (reg:CC FLAGS_REG))
20482 (clobber (mem:BLK (scratch)))])]
20483 "optimize_size || !TARGET_SUB_ESP_8"
20484 [(clobber (match_dup 0))
20485 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20486 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20487 (clobber (mem:BLK (scratch)))])])
20489 ;; Convert esp subtractions to push.
20491 [(match_scratch:DI 0 "r")
20492 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20493 (clobber (reg:CC FLAGS_REG))])]
20494 "optimize_size || !TARGET_SUB_ESP_4"
20495 [(clobber (match_dup 0))
20496 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20499 [(match_scratch:DI 0 "r")
20500 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20501 (clobber (reg:CC FLAGS_REG))])]
20502 "optimize_size || !TARGET_SUB_ESP_8"
20503 [(clobber (match_dup 0))
20504 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20505 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20507 ;; Convert epilogue deallocator to pop.
20509 [(match_scratch:DI 0 "r")
20510 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20511 (clobber (reg:CC FLAGS_REG))
20512 (clobber (mem:BLK (scratch)))])]
20513 "optimize_size || !TARGET_ADD_ESP_4"
20514 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20515 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20516 (clobber (mem:BLK (scratch)))])]
20519 ;; Two pops case is tricky, since pop causes dependency on destination register.
20520 ;; We use two registers if available.
20522 [(match_scratch:DI 0 "r")
20523 (match_scratch:DI 1 "r")
20524 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20525 (clobber (reg:CC FLAGS_REG))
20526 (clobber (mem:BLK (scratch)))])]
20527 "optimize_size || !TARGET_ADD_ESP_8"
20528 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20529 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20530 (clobber (mem:BLK (scratch)))])
20531 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20532 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20536 [(match_scratch:DI 0 "r")
20537 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20538 (clobber (reg:CC FLAGS_REG))
20539 (clobber (mem:BLK (scratch)))])]
20541 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20542 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20543 (clobber (mem:BLK (scratch)))])
20544 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20545 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20548 ;; Convert esp additions to pop.
20550 [(match_scratch:DI 0 "r")
20551 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20552 (clobber (reg:CC FLAGS_REG))])]
20554 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20555 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20558 ;; Two pops case is tricky, since pop causes dependency on destination register.
20559 ;; We use two registers if available.
20561 [(match_scratch:DI 0 "r")
20562 (match_scratch:DI 1 "r")
20563 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20564 (clobber (reg:CC FLAGS_REG))])]
20566 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20567 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20568 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20569 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20573 [(match_scratch:DI 0 "r")
20574 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20575 (clobber (reg:CC FLAGS_REG))])]
20577 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20578 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20579 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20580 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20583 ;; Convert imul by three, five and nine into lea
20586 [(set (match_operand:SI 0 "register_operand" "")
20587 (mult:SI (match_operand:SI 1 "register_operand" "")
20588 (match_operand:SI 2 "const_int_operand" "")))
20589 (clobber (reg:CC FLAGS_REG))])]
20590 "INTVAL (operands[2]) == 3
20591 || INTVAL (operands[2]) == 5
20592 || INTVAL (operands[2]) == 9"
20593 [(set (match_dup 0)
20594 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20596 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20600 [(set (match_operand:SI 0 "register_operand" "")
20601 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20602 (match_operand:SI 2 "const_int_operand" "")))
20603 (clobber (reg:CC FLAGS_REG))])]
20605 && (INTVAL (operands[2]) == 3
20606 || INTVAL (operands[2]) == 5
20607 || INTVAL (operands[2]) == 9)"
20608 [(set (match_dup 0) (match_dup 1))
20610 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20612 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20616 [(set (match_operand:DI 0 "register_operand" "")
20617 (mult:DI (match_operand:DI 1 "register_operand" "")
20618 (match_operand:DI 2 "const_int_operand" "")))
20619 (clobber (reg:CC FLAGS_REG))])]
20621 && (INTVAL (operands[2]) == 3
20622 || INTVAL (operands[2]) == 5
20623 || INTVAL (operands[2]) == 9)"
20624 [(set (match_dup 0)
20625 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20627 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20631 [(set (match_operand:DI 0 "register_operand" "")
20632 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20633 (match_operand:DI 2 "const_int_operand" "")))
20634 (clobber (reg:CC FLAGS_REG))])]
20637 && (INTVAL (operands[2]) == 3
20638 || INTVAL (operands[2]) == 5
20639 || INTVAL (operands[2]) == 9)"
20640 [(set (match_dup 0) (match_dup 1))
20642 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20644 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20646 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20647 ;; imul $32bit_imm, reg, reg is direct decoded.
20649 [(match_scratch:DI 3 "r")
20650 (parallel [(set (match_operand:DI 0 "register_operand" "")
20651 (mult:DI (match_operand:DI 1 "memory_operand" "")
20652 (match_operand:DI 2 "immediate_operand" "")))
20653 (clobber (reg:CC FLAGS_REG))])]
20654 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20655 && !satisfies_constraint_K (operands[2])"
20656 [(set (match_dup 3) (match_dup 1))
20657 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20658 (clobber (reg:CC FLAGS_REG))])]
20662 [(match_scratch:SI 3 "r")
20663 (parallel [(set (match_operand:SI 0 "register_operand" "")
20664 (mult:SI (match_operand:SI 1 "memory_operand" "")
20665 (match_operand:SI 2 "immediate_operand" "")))
20666 (clobber (reg:CC FLAGS_REG))])]
20667 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20668 && !satisfies_constraint_K (operands[2])"
20669 [(set (match_dup 3) (match_dup 1))
20670 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20671 (clobber (reg:CC FLAGS_REG))])]
20675 [(match_scratch:SI 3 "r")
20676 (parallel [(set (match_operand:DI 0 "register_operand" "")
20678 (mult:SI (match_operand:SI 1 "memory_operand" "")
20679 (match_operand:SI 2 "immediate_operand" ""))))
20680 (clobber (reg:CC FLAGS_REG))])]
20681 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20682 && !satisfies_constraint_K (operands[2])"
20683 [(set (match_dup 3) (match_dup 1))
20684 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20685 (clobber (reg:CC FLAGS_REG))])]
20688 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20689 ;; Convert it into imul reg, reg
20690 ;; It would be better to force assembler to encode instruction using long
20691 ;; immediate, but there is apparently no way to do so.
20693 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20694 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20695 (match_operand:DI 2 "const_int_operand" "")))
20696 (clobber (reg:CC FLAGS_REG))])
20697 (match_scratch:DI 3 "r")]
20698 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20699 && satisfies_constraint_K (operands[2])"
20700 [(set (match_dup 3) (match_dup 2))
20701 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20702 (clobber (reg:CC FLAGS_REG))])]
20704 if (!rtx_equal_p (operands[0], operands[1]))
20705 emit_move_insn (operands[0], operands[1]);
20709 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20710 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20711 (match_operand:SI 2 "const_int_operand" "")))
20712 (clobber (reg:CC FLAGS_REG))])
20713 (match_scratch:SI 3 "r")]
20714 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20715 && satisfies_constraint_K (operands[2])"
20716 [(set (match_dup 3) (match_dup 2))
20717 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20718 (clobber (reg:CC FLAGS_REG))])]
20720 if (!rtx_equal_p (operands[0], operands[1]))
20721 emit_move_insn (operands[0], operands[1]);
20725 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20726 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20727 (match_operand:HI 2 "immediate_operand" "")))
20728 (clobber (reg:CC FLAGS_REG))])
20729 (match_scratch:HI 3 "r")]
20730 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20731 [(set (match_dup 3) (match_dup 2))
20732 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20733 (clobber (reg:CC FLAGS_REG))])]
20735 if (!rtx_equal_p (operands[0], operands[1]))
20736 emit_move_insn (operands[0], operands[1]);
20739 ;; After splitting up read-modify operations, array accesses with memory
20740 ;; operands might end up in form:
20742 ;; movl 4(%esp), %edx
20744 ;; instead of pre-splitting:
20746 ;; addl 4(%esp), %eax
20748 ;; movl 4(%esp), %edx
20749 ;; leal (%edx,%eax,4), %eax
20752 [(parallel [(set (match_operand 0 "register_operand" "")
20753 (ashift (match_operand 1 "register_operand" "")
20754 (match_operand 2 "const_int_operand" "")))
20755 (clobber (reg:CC FLAGS_REG))])
20756 (set (match_operand 3 "register_operand")
20757 (match_operand 4 "x86_64_general_operand" ""))
20758 (parallel [(set (match_operand 5 "register_operand" "")
20759 (plus (match_operand 6 "register_operand" "")
20760 (match_operand 7 "register_operand" "")))
20761 (clobber (reg:CC FLAGS_REG))])]
20762 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20763 /* Validate MODE for lea. */
20764 && ((!TARGET_PARTIAL_REG_STALL
20765 && (GET_MODE (operands[0]) == QImode
20766 || GET_MODE (operands[0]) == HImode))
20767 || GET_MODE (operands[0]) == SImode
20768 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20769 /* We reorder load and the shift. */
20770 && !rtx_equal_p (operands[1], operands[3])
20771 && !reg_overlap_mentioned_p (operands[0], operands[4])
20772 /* Last PLUS must consist of operand 0 and 3. */
20773 && !rtx_equal_p (operands[0], operands[3])
20774 && (rtx_equal_p (operands[3], operands[6])
20775 || rtx_equal_p (operands[3], operands[7]))
20776 && (rtx_equal_p (operands[0], operands[6])
20777 || rtx_equal_p (operands[0], operands[7]))
20778 /* The intermediate operand 0 must die or be same as output. */
20779 && (rtx_equal_p (operands[0], operands[5])
20780 || peep2_reg_dead_p (3, operands[0]))"
20781 [(set (match_dup 3) (match_dup 4))
20782 (set (match_dup 0) (match_dup 1))]
20784 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20785 int scale = 1 << INTVAL (operands[2]);
20786 rtx index = gen_lowpart (Pmode, operands[1]);
20787 rtx base = gen_lowpart (Pmode, operands[3]);
20788 rtx dest = gen_lowpart (mode, operands[5]);
20790 operands[1] = gen_rtx_PLUS (Pmode, base,
20791 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20793 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20794 operands[0] = dest;
20797 ;; Call-value patterns last so that the wildcard operand does not
20798 ;; disrupt insn-recog's switch tables.
20800 (define_insn "*call_value_pop_0"
20801 [(set (match_operand 0 "" "")
20802 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20803 (match_operand:SI 2 "" "")))
20804 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20805 (match_operand:SI 3 "immediate_operand" "")))]
20808 if (SIBLING_CALL_P (insn))
20811 return "call\t%P1";
20813 [(set_attr "type" "callv")])
20815 (define_insn "*call_value_pop_1"
20816 [(set (match_operand 0 "" "")
20817 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20818 (match_operand:SI 2 "" "")))
20819 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20820 (match_operand:SI 3 "immediate_operand" "i")))]
20823 if (constant_call_address_operand (operands[1], Pmode))
20825 if (SIBLING_CALL_P (insn))
20828 return "call\t%P1";
20830 if (SIBLING_CALL_P (insn))
20833 return "call\t%A1";
20835 [(set_attr "type" "callv")])
20837 (define_insn "*call_value_0"
20838 [(set (match_operand 0 "" "")
20839 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20840 (match_operand:SI 2 "" "")))]
20843 if (SIBLING_CALL_P (insn))
20846 return "call\t%P1";
20848 [(set_attr "type" "callv")])
20850 (define_insn "*call_value_0_rex64"
20851 [(set (match_operand 0 "" "")
20852 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20853 (match_operand:DI 2 "const_int_operand" "")))]
20856 if (SIBLING_CALL_P (insn))
20859 return "call\t%P1";
20861 [(set_attr "type" "callv")])
20863 (define_insn "*call_value_1"
20864 [(set (match_operand 0 "" "")
20865 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20866 (match_operand:SI 2 "" "")))]
20867 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20869 if (constant_call_address_operand (operands[1], Pmode))
20870 return "call\t%P1";
20871 return "call\t%A1";
20873 [(set_attr "type" "callv")])
20875 (define_insn "*sibcall_value_1"
20876 [(set (match_operand 0 "" "")
20877 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20878 (match_operand:SI 2 "" "")))]
20879 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20881 if (constant_call_address_operand (operands[1], Pmode))
20885 [(set_attr "type" "callv")])
20887 (define_insn "*call_value_1_rex64"
20888 [(set (match_operand 0 "" "")
20889 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20890 (match_operand:DI 2 "" "")))]
20891 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20893 if (constant_call_address_operand (operands[1], Pmode))
20894 return "call\t%P1";
20895 return "call\t%A1";
20897 [(set_attr "type" "callv")])
20899 (define_insn "*sibcall_value_1_rex64"
20900 [(set (match_operand 0 "" "")
20901 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20902 (match_operand:DI 2 "" "")))]
20903 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20905 [(set_attr "type" "callv")])
20907 (define_insn "*sibcall_value_1_rex64_v"
20908 [(set (match_operand 0 "" "")
20909 (call (mem:QI (reg:DI 40))
20910 (match_operand:DI 1 "" "")))]
20911 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20913 [(set_attr "type" "callv")])
20915 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20916 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20917 ;; caught for use by garbage collectors and the like. Using an insn that
20918 ;; maps to SIGILL makes it more likely the program will rightfully die.
20919 ;; Keeping with tradition, "6" is in honor of #UD.
20920 (define_insn "trap"
20921 [(trap_if (const_int 1) (const_int 6))]
20923 { return ASM_SHORT "0x0b0f"; }
20924 [(set_attr "length" "2")])
20926 (define_expand "sse_prologue_save"
20927 [(parallel [(set (match_operand:BLK 0 "" "")
20928 (unspec:BLK [(reg:DI 21)
20935 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20936 (use (match_operand:DI 1 "register_operand" ""))
20937 (use (match_operand:DI 2 "immediate_operand" ""))
20938 (use (label_ref:DI (match_operand 3 "" "")))])]
20942 (define_insn "*sse_prologue_save_insn"
20943 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20944 (match_operand:DI 4 "const_int_operand" "n")))
20945 (unspec:BLK [(reg:DI 21)
20952 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20953 (use (match_operand:DI 1 "register_operand" "r"))
20954 (use (match_operand:DI 2 "const_int_operand" "i"))
20955 (use (label_ref:DI (match_operand 3 "" "X")))]
20957 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20958 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20962 operands[0] = gen_rtx_MEM (Pmode,
20963 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20964 output_asm_insn (\"jmp\\t%A1\", operands);
20965 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20967 operands[4] = adjust_address (operands[0], DImode, i*16);
20968 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20969 PUT_MODE (operands[4], TImode);
20970 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20971 output_asm_insn (\"rex\", operands);
20972 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20974 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20975 CODE_LABEL_NUMBER (operands[3]));
20979 [(set_attr "type" "other")
20980 (set_attr "length_immediate" "0")
20981 (set_attr "length_address" "0")
20982 (set_attr "length" "135")
20983 (set_attr "memory" "store")
20984 (set_attr "modrm" "0")
20985 (set_attr "mode" "DI")])
20987 (define_expand "prefetch"
20988 [(prefetch (match_operand 0 "address_operand" "")
20989 (match_operand:SI 1 "const_int_operand" "")
20990 (match_operand:SI 2 "const_int_operand" ""))]
20991 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20993 int rw = INTVAL (operands[1]);
20994 int locality = INTVAL (operands[2]);
20996 gcc_assert (rw == 0 || rw == 1);
20997 gcc_assert (locality >= 0 && locality <= 3);
20998 gcc_assert (GET_MODE (operands[0]) == Pmode
20999 || GET_MODE (operands[0]) == VOIDmode);
21001 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21002 supported by SSE counterpart or the SSE prefetch is not available
21003 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21005 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21006 operands[2] = GEN_INT (3);
21008 operands[1] = const0_rtx;
21011 (define_insn "*prefetch_sse"
21012 [(prefetch (match_operand:SI 0 "address_operand" "p")
21014 (match_operand:SI 1 "const_int_operand" ""))]
21015 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21017 static const char * const patterns[4] = {
21018 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21021 int locality = INTVAL (operands[1]);
21022 gcc_assert (locality >= 0 && locality <= 3);
21024 return patterns[locality];
21026 [(set_attr "type" "sse")
21027 (set_attr "memory" "none")])
21029 (define_insn "*prefetch_sse_rex"
21030 [(prefetch (match_operand:DI 0 "address_operand" "p")
21032 (match_operand:SI 1 "const_int_operand" ""))]
21033 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21035 static const char * const patterns[4] = {
21036 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21039 int locality = INTVAL (operands[1]);
21040 gcc_assert (locality >= 0 && locality <= 3);
21042 return patterns[locality];
21044 [(set_attr "type" "sse")
21045 (set_attr "memory" "none")])
21047 (define_insn "*prefetch_3dnow"
21048 [(prefetch (match_operand:SI 0 "address_operand" "p")
21049 (match_operand:SI 1 "const_int_operand" "n")
21051 "TARGET_3DNOW && !TARGET_64BIT"
21053 if (INTVAL (operands[1]) == 0)
21054 return "prefetch\t%a0";
21056 return "prefetchw\t%a0";
21058 [(set_attr "type" "mmx")
21059 (set_attr "memory" "none")])
21061 (define_insn "*prefetch_3dnow_rex"
21062 [(prefetch (match_operand:DI 0 "address_operand" "p")
21063 (match_operand:SI 1 "const_int_operand" "n")
21065 "TARGET_3DNOW && TARGET_64BIT"
21067 if (INTVAL (operands[1]) == 0)
21068 return "prefetch\t%a0";
21070 return "prefetchw\t%a0";
21072 [(set_attr "type" "mmx")
21073 (set_attr "memory" "none")])
21075 (define_expand "stack_protect_set"
21076 [(match_operand 0 "memory_operand" "")
21077 (match_operand 1 "memory_operand" "")]
21080 #ifdef TARGET_THREAD_SSP_OFFSET
21082 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21083 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21085 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21086 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21089 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21091 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21096 (define_insn "stack_protect_set_si"
21097 [(set (match_operand:SI 0 "memory_operand" "=m")
21098 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21099 (set (match_scratch:SI 2 "=&r") (const_int 0))
21100 (clobber (reg:CC FLAGS_REG))]
21102 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21103 [(set_attr "type" "multi")])
21105 (define_insn "stack_protect_set_di"
21106 [(set (match_operand:DI 0 "memory_operand" "=m")
21107 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21108 (set (match_scratch:DI 2 "=&r") (const_int 0))
21109 (clobber (reg:CC FLAGS_REG))]
21111 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21112 [(set_attr "type" "multi")])
21114 (define_insn "stack_tls_protect_set_si"
21115 [(set (match_operand:SI 0 "memory_operand" "=m")
21116 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21117 (set (match_scratch:SI 2 "=&r") (const_int 0))
21118 (clobber (reg:CC FLAGS_REG))]
21120 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21121 [(set_attr "type" "multi")])
21123 (define_insn "stack_tls_protect_set_di"
21124 [(set (match_operand:DI 0 "memory_operand" "=m")
21125 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21126 (set (match_scratch:DI 2 "=&r") (const_int 0))
21127 (clobber (reg:CC FLAGS_REG))]
21130 /* The kernel uses a different segment register for performance reasons; a
21131 system call would not have to trash the userspace segment register,
21132 which would be expensive */
21133 if (ix86_cmodel != CM_KERNEL)
21134 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21136 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21138 [(set_attr "type" "multi")])
21140 (define_expand "stack_protect_test"
21141 [(match_operand 0 "memory_operand" "")
21142 (match_operand 1 "memory_operand" "")
21143 (match_operand 2 "" "")]
21146 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21147 ix86_compare_op0 = operands[0];
21148 ix86_compare_op1 = operands[1];
21149 ix86_compare_emitted = flags;
21151 #ifdef TARGET_THREAD_SSP_OFFSET
21153 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21154 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21156 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21157 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21160 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21162 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21164 emit_jump_insn (gen_beq (operands[2]));
21168 (define_insn "stack_protect_test_si"
21169 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21170 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21171 (match_operand:SI 2 "memory_operand" "m")]
21173 (clobber (match_scratch:SI 3 "=&r"))]
21175 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21176 [(set_attr "type" "multi")])
21178 (define_insn "stack_protect_test_di"
21179 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21180 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21181 (match_operand:DI 2 "memory_operand" "m")]
21183 (clobber (match_scratch:DI 3 "=&r"))]
21185 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21186 [(set_attr "type" "multi")])
21188 (define_insn "stack_tls_protect_test_si"
21189 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21190 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21191 (match_operand:SI 2 "const_int_operand" "i")]
21192 UNSPEC_SP_TLS_TEST))
21193 (clobber (match_scratch:SI 3 "=r"))]
21195 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21196 [(set_attr "type" "multi")])
21198 (define_insn "stack_tls_protect_test_di"
21199 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21200 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21201 (match_operand:DI 2 "const_int_operand" "i")]
21202 UNSPEC_SP_TLS_TEST))
21203 (clobber (match_scratch:DI 3 "=r"))]
21206 /* The kernel uses a different segment register for performance reasons; a
21207 system call would not have to trash the userspace segment register,
21208 which would be expensive */
21209 if (ix86_cmodel != CM_KERNEL)
21210 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21212 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21214 [(set_attr "type" "multi")])
21218 (include "sync.md")