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_insn "bswapsi2"
14722 [(set (match_operand:SI 0 "register_operand" "=r")
14723 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14724 (clobber (reg:CC FLAGS_REG))]
14727 [(set_attr "prefix_0f" "1")
14728 (set_attr "length" "2")])
14730 (define_insn "bswapdi2"
14731 [(set (match_operand:DI 0 "register_operand" "=r")
14732 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14733 (clobber (reg:CC FLAGS_REG))]
14734 "TARGET_64BIT && TARGET_BSWAP"
14736 [(set_attr "prefix_0f" "1")
14737 (set_attr "length" "3")])
14739 (define_expand "clzdi2"
14741 [(set (match_operand:DI 0 "register_operand" "")
14742 (minus:DI (const_int 63)
14743 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14744 (clobber (reg:CC FLAGS_REG))])
14746 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14747 (clobber (reg:CC FLAGS_REG))])]
14752 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14757 (define_insn "clzdi2_abm"
14758 [(set (match_operand:DI 0 "register_operand" "=r")
14759 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14760 (clobber (reg:CC FLAGS_REG))]
14761 "TARGET_64BIT && TARGET_ABM"
14762 "lzcnt{q}\t{%1, %0|%0, %1}"
14763 [(set_attr "prefix_rep" "1")
14764 (set_attr "type" "bitmanip")
14765 (set_attr "mode" "DI")])
14767 (define_insn "*bsr_rex64"
14768 [(set (match_operand:DI 0 "register_operand" "=r")
14769 (minus:DI (const_int 63)
14770 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14771 (clobber (reg:CC FLAGS_REG))]
14773 "bsr{q}\t{%1, %0|%0, %1}"
14774 [(set_attr "prefix_0f" "1")
14775 (set_attr "mode" "DI")])
14777 (define_insn "popcountdi2"
14778 [(set (match_operand:DI 0 "register_operand" "=r")
14779 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14780 (clobber (reg:CC FLAGS_REG))]
14781 "TARGET_64BIT && TARGET_POPCNT"
14782 "popcnt{q}\t{%1, %0|%0, %1}"
14783 [(set_attr "prefix_rep" "1")
14784 (set_attr "type" "bitmanip")
14785 (set_attr "mode" "DI")])
14787 (define_insn "*popcountdi2_cmp"
14788 [(set (reg FLAGS_REG)
14790 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14792 (set (match_operand:DI 0 "register_operand" "=r")
14793 (popcount:DI (match_dup 1)))]
14794 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14795 "popcnt{q}\t{%1, %0|%0, %1}"
14796 [(set_attr "prefix_rep" "1")
14797 (set_attr "type" "bitmanip")
14798 (set_attr "mode" "DI")])
14800 (define_expand "clzhi2"
14802 [(set (match_operand:HI 0 "register_operand" "")
14803 (minus:HI (const_int 15)
14804 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14805 (clobber (reg:CC FLAGS_REG))])
14807 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14808 (clobber (reg:CC FLAGS_REG))])]
14813 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14818 (define_insn "clzhi2_abm"
14819 [(set (match_operand:HI 0 "register_operand" "=r")
14820 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14821 (clobber (reg:CC FLAGS_REG))]
14823 "lzcnt{w}\t{%1, %0|%0, %1}"
14824 [(set_attr "prefix_rep" "1")
14825 (set_attr "type" "bitmanip")
14826 (set_attr "mode" "HI")])
14828 (define_insn "*bsrhi"
14829 [(set (match_operand:HI 0 "register_operand" "=r")
14830 (minus:HI (const_int 15)
14831 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14832 (clobber (reg:CC FLAGS_REG))]
14834 "bsr{w}\t{%1, %0|%0, %1}"
14835 [(set_attr "prefix_0f" "1")
14836 (set_attr "mode" "HI")])
14838 (define_insn "popcounthi2"
14839 [(set (match_operand:HI 0 "register_operand" "=r")
14840 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14841 (clobber (reg:CC FLAGS_REG))]
14843 "popcnt{w}\t{%1, %0|%0, %1}"
14844 [(set_attr "prefix_rep" "1")
14845 (set_attr "type" "bitmanip")
14846 (set_attr "mode" "HI")])
14848 (define_insn "*popcounthi2_cmp"
14849 [(set (reg FLAGS_REG)
14851 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14853 (set (match_operand:HI 0 "register_operand" "=r")
14854 (popcount:HI (match_dup 1)))]
14855 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14856 "popcnt{w}\t{%1, %0|%0, %1}"
14857 [(set_attr "prefix_rep" "1")
14858 (set_attr "type" "bitmanip")
14859 (set_attr "mode" "HI")])
14861 ;; Thread-local storage patterns for ELF.
14863 ;; Note that these code sequences must appear exactly as shown
14864 ;; in order to allow linker relaxation.
14866 (define_insn "*tls_global_dynamic_32_gnu"
14867 [(set (match_operand:SI 0 "register_operand" "=a")
14868 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14869 (match_operand:SI 2 "tls_symbolic_operand" "")
14870 (match_operand:SI 3 "call_insn_operand" "")]
14872 (clobber (match_scratch:SI 4 "=d"))
14873 (clobber (match_scratch:SI 5 "=c"))
14874 (clobber (reg:CC FLAGS_REG))]
14875 "!TARGET_64BIT && TARGET_GNU_TLS"
14876 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14877 [(set_attr "type" "multi")
14878 (set_attr "length" "12")])
14880 (define_insn "*tls_global_dynamic_32_sun"
14881 [(set (match_operand:SI 0 "register_operand" "=a")
14882 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14883 (match_operand:SI 2 "tls_symbolic_operand" "")
14884 (match_operand:SI 3 "call_insn_operand" "")]
14886 (clobber (match_scratch:SI 4 "=d"))
14887 (clobber (match_scratch:SI 5 "=c"))
14888 (clobber (reg:CC FLAGS_REG))]
14889 "!TARGET_64BIT && TARGET_SUN_TLS"
14890 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14891 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14892 [(set_attr "type" "multi")
14893 (set_attr "length" "14")])
14895 (define_expand "tls_global_dynamic_32"
14896 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14899 (match_operand:SI 1 "tls_symbolic_operand" "")
14902 (clobber (match_scratch:SI 4 ""))
14903 (clobber (match_scratch:SI 5 ""))
14904 (clobber (reg:CC FLAGS_REG))])]
14908 operands[2] = pic_offset_table_rtx;
14911 operands[2] = gen_reg_rtx (Pmode);
14912 emit_insn (gen_set_got (operands[2]));
14914 if (TARGET_GNU2_TLS)
14916 emit_insn (gen_tls_dynamic_gnu2_32
14917 (operands[0], operands[1], operands[2]));
14920 operands[3] = ix86_tls_get_addr ();
14923 (define_insn "*tls_global_dynamic_64"
14924 [(set (match_operand:DI 0 "register_operand" "=a")
14925 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14926 (match_operand:DI 3 "" "")))
14927 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14930 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14931 [(set_attr "type" "multi")
14932 (set_attr "length" "16")])
14934 (define_expand "tls_global_dynamic_64"
14935 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14936 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14937 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14941 if (TARGET_GNU2_TLS)
14943 emit_insn (gen_tls_dynamic_gnu2_64
14944 (operands[0], operands[1]));
14947 operands[2] = ix86_tls_get_addr ();
14950 (define_insn "*tls_local_dynamic_base_32_gnu"
14951 [(set (match_operand:SI 0 "register_operand" "=a")
14952 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14953 (match_operand:SI 2 "call_insn_operand" "")]
14954 UNSPEC_TLS_LD_BASE))
14955 (clobber (match_scratch:SI 3 "=d"))
14956 (clobber (match_scratch:SI 4 "=c"))
14957 (clobber (reg:CC FLAGS_REG))]
14958 "!TARGET_64BIT && TARGET_GNU_TLS"
14959 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14960 [(set_attr "type" "multi")
14961 (set_attr "length" "11")])
14963 (define_insn "*tls_local_dynamic_base_32_sun"
14964 [(set (match_operand:SI 0 "register_operand" "=a")
14965 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14966 (match_operand:SI 2 "call_insn_operand" "")]
14967 UNSPEC_TLS_LD_BASE))
14968 (clobber (match_scratch:SI 3 "=d"))
14969 (clobber (match_scratch:SI 4 "=c"))
14970 (clobber (reg:CC FLAGS_REG))]
14971 "!TARGET_64BIT && TARGET_SUN_TLS"
14972 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14973 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14974 [(set_attr "type" "multi")
14975 (set_attr "length" "13")])
14977 (define_expand "tls_local_dynamic_base_32"
14978 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14979 (unspec:SI [(match_dup 1) (match_dup 2)]
14980 UNSPEC_TLS_LD_BASE))
14981 (clobber (match_scratch:SI 3 ""))
14982 (clobber (match_scratch:SI 4 ""))
14983 (clobber (reg:CC FLAGS_REG))])]
14987 operands[1] = pic_offset_table_rtx;
14990 operands[1] = gen_reg_rtx (Pmode);
14991 emit_insn (gen_set_got (operands[1]));
14993 if (TARGET_GNU2_TLS)
14995 emit_insn (gen_tls_dynamic_gnu2_32
14996 (operands[0], ix86_tls_module_base (), operands[1]));
14999 operands[2] = ix86_tls_get_addr ();
15002 (define_insn "*tls_local_dynamic_base_64"
15003 [(set (match_operand:DI 0 "register_operand" "=a")
15004 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15005 (match_operand:DI 2 "" "")))
15006 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15008 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15009 [(set_attr "type" "multi")
15010 (set_attr "length" "12")])
15012 (define_expand "tls_local_dynamic_base_64"
15013 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15014 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15015 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15018 if (TARGET_GNU2_TLS)
15020 emit_insn (gen_tls_dynamic_gnu2_64
15021 (operands[0], ix86_tls_module_base ()));
15024 operands[1] = ix86_tls_get_addr ();
15027 ;; Local dynamic of a single variable is a lose. Show combine how
15028 ;; to convert that back to global dynamic.
15030 (define_insn_and_split "*tls_local_dynamic_32_once"
15031 [(set (match_operand:SI 0 "register_operand" "=a")
15032 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15033 (match_operand:SI 2 "call_insn_operand" "")]
15034 UNSPEC_TLS_LD_BASE)
15035 (const:SI (unspec:SI
15036 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15038 (clobber (match_scratch:SI 4 "=d"))
15039 (clobber (match_scratch:SI 5 "=c"))
15040 (clobber (reg:CC FLAGS_REG))]
15044 [(parallel [(set (match_dup 0)
15045 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15047 (clobber (match_dup 4))
15048 (clobber (match_dup 5))
15049 (clobber (reg:CC FLAGS_REG))])]
15052 ;; Load and add the thread base pointer from %gs:0.
15054 (define_insn "*load_tp_si"
15055 [(set (match_operand:SI 0 "register_operand" "=r")
15056 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15058 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15059 [(set_attr "type" "imov")
15060 (set_attr "modrm" "0")
15061 (set_attr "length" "7")
15062 (set_attr "memory" "load")
15063 (set_attr "imm_disp" "false")])
15065 (define_insn "*add_tp_si"
15066 [(set (match_operand:SI 0 "register_operand" "=r")
15067 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15068 (match_operand:SI 1 "register_operand" "0")))
15069 (clobber (reg:CC FLAGS_REG))]
15071 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15072 [(set_attr "type" "alu")
15073 (set_attr "modrm" "0")
15074 (set_attr "length" "7")
15075 (set_attr "memory" "load")
15076 (set_attr "imm_disp" "false")])
15078 (define_insn "*load_tp_di"
15079 [(set (match_operand:DI 0 "register_operand" "=r")
15080 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15082 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15083 [(set_attr "type" "imov")
15084 (set_attr "modrm" "0")
15085 (set_attr "length" "7")
15086 (set_attr "memory" "load")
15087 (set_attr "imm_disp" "false")])
15089 (define_insn "*add_tp_di"
15090 [(set (match_operand:DI 0 "register_operand" "=r")
15091 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15092 (match_operand:DI 1 "register_operand" "0")))
15093 (clobber (reg:CC FLAGS_REG))]
15095 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15096 [(set_attr "type" "alu")
15097 (set_attr "modrm" "0")
15098 (set_attr "length" "7")
15099 (set_attr "memory" "load")
15100 (set_attr "imm_disp" "false")])
15102 ;; GNU2 TLS patterns can be split.
15104 (define_expand "tls_dynamic_gnu2_32"
15105 [(set (match_dup 3)
15106 (plus:SI (match_operand:SI 2 "register_operand" "")
15108 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15111 [(set (match_operand:SI 0 "register_operand" "")
15112 (unspec:SI [(match_dup 1) (match_dup 3)
15113 (match_dup 2) (reg:SI SP_REG)]
15115 (clobber (reg:CC FLAGS_REG))])]
15116 "!TARGET_64BIT && TARGET_GNU2_TLS"
15118 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15119 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15122 (define_insn "*tls_dynamic_lea_32"
15123 [(set (match_operand:SI 0 "register_operand" "=r")
15124 (plus:SI (match_operand:SI 1 "register_operand" "b")
15126 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15127 UNSPEC_TLSDESC))))]
15128 "!TARGET_64BIT && TARGET_GNU2_TLS"
15129 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15130 [(set_attr "type" "lea")
15131 (set_attr "mode" "SI")
15132 (set_attr "length" "6")
15133 (set_attr "length_address" "4")])
15135 (define_insn "*tls_dynamic_call_32"
15136 [(set (match_operand:SI 0 "register_operand" "=a")
15137 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15138 (match_operand:SI 2 "register_operand" "0")
15139 ;; we have to make sure %ebx still points to the GOT
15140 (match_operand:SI 3 "register_operand" "b")
15143 (clobber (reg:CC FLAGS_REG))]
15144 "!TARGET_64BIT && TARGET_GNU2_TLS"
15145 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15146 [(set_attr "type" "call")
15147 (set_attr "length" "2")
15148 (set_attr "length_address" "0")])
15150 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15151 [(set (match_operand:SI 0 "register_operand" "=&a")
15153 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15154 (match_operand:SI 4 "" "")
15155 (match_operand:SI 2 "register_operand" "b")
15158 (const:SI (unspec:SI
15159 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15161 (clobber (reg:CC FLAGS_REG))]
15162 "!TARGET_64BIT && TARGET_GNU2_TLS"
15165 [(set (match_dup 0) (match_dup 5))]
15167 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15168 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15171 (define_expand "tls_dynamic_gnu2_64"
15172 [(set (match_dup 2)
15173 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15176 [(set (match_operand:DI 0 "register_operand" "")
15177 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15179 (clobber (reg:CC FLAGS_REG))])]
15180 "TARGET_64BIT && TARGET_GNU2_TLS"
15182 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15183 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15186 (define_insn "*tls_dynamic_lea_64"
15187 [(set (match_operand:DI 0 "register_operand" "=r")
15188 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15190 "TARGET_64BIT && TARGET_GNU2_TLS"
15191 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15192 [(set_attr "type" "lea")
15193 (set_attr "mode" "DI")
15194 (set_attr "length" "7")
15195 (set_attr "length_address" "4")])
15197 (define_insn "*tls_dynamic_call_64"
15198 [(set (match_operand:DI 0 "register_operand" "=a")
15199 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15200 (match_operand:DI 2 "register_operand" "0")
15203 (clobber (reg:CC FLAGS_REG))]
15204 "TARGET_64BIT && TARGET_GNU2_TLS"
15205 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15206 [(set_attr "type" "call")
15207 (set_attr "length" "2")
15208 (set_attr "length_address" "0")])
15210 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15211 [(set (match_operand:DI 0 "register_operand" "=&a")
15213 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15214 (match_operand:DI 3 "" "")
15217 (const:DI (unspec:DI
15218 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15220 (clobber (reg:CC FLAGS_REG))]
15221 "TARGET_64BIT && TARGET_GNU2_TLS"
15224 [(set (match_dup 0) (match_dup 4))]
15226 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15227 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15232 ;; These patterns match the binary 387 instructions for addM3, subM3,
15233 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15234 ;; SFmode. The first is the normal insn, the second the same insn but
15235 ;; with one operand a conversion, and the third the same insn but with
15236 ;; the other operand a conversion. The conversion may be SFmode or
15237 ;; SImode if the target mode DFmode, but only SImode if the target mode
15240 ;; Gcc is slightly more smart about handling normal two address instructions
15241 ;; so use special patterns for add and mull.
15243 (define_insn "*fop_sf_comm_mixed"
15244 [(set (match_operand:SF 0 "register_operand" "=f,x")
15245 (match_operator:SF 3 "binary_fp_operator"
15246 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15247 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15248 "TARGET_MIX_SSE_I387
15249 && COMMUTATIVE_ARITH_P (operands[3])
15250 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15251 "* return output_387_binary_op (insn, operands);"
15252 [(set (attr "type")
15253 (if_then_else (eq_attr "alternative" "1")
15254 (if_then_else (match_operand:SF 3 "mult_operator" "")
15255 (const_string "ssemul")
15256 (const_string "sseadd"))
15257 (if_then_else (match_operand:SF 3 "mult_operator" "")
15258 (const_string "fmul")
15259 (const_string "fop"))))
15260 (set_attr "mode" "SF")])
15262 (define_insn "*fop_sf_comm_sse"
15263 [(set (match_operand:SF 0 "register_operand" "=x")
15264 (match_operator:SF 3 "binary_fp_operator"
15265 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15266 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15268 && COMMUTATIVE_ARITH_P (operands[3])
15269 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15270 "* return output_387_binary_op (insn, operands);"
15271 [(set (attr "type")
15272 (if_then_else (match_operand:SF 3 "mult_operator" "")
15273 (const_string "ssemul")
15274 (const_string "sseadd")))
15275 (set_attr "mode" "SF")])
15277 (define_insn "*fop_sf_comm_i387"
15278 [(set (match_operand:SF 0 "register_operand" "=f")
15279 (match_operator:SF 3 "binary_fp_operator"
15280 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15281 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15283 && COMMUTATIVE_ARITH_P (operands[3])
15284 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15285 "* return output_387_binary_op (insn, operands);"
15286 [(set (attr "type")
15287 (if_then_else (match_operand:SF 3 "mult_operator" "")
15288 (const_string "fmul")
15289 (const_string "fop")))
15290 (set_attr "mode" "SF")])
15292 (define_insn "*fop_sf_1_mixed"
15293 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15294 (match_operator:SF 3 "binary_fp_operator"
15295 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15296 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15297 "TARGET_MIX_SSE_I387
15298 && !COMMUTATIVE_ARITH_P (operands[3])
15299 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15300 "* return output_387_binary_op (insn, operands);"
15301 [(set (attr "type")
15302 (cond [(and (eq_attr "alternative" "2")
15303 (match_operand:SF 3 "mult_operator" ""))
15304 (const_string "ssemul")
15305 (and (eq_attr "alternative" "2")
15306 (match_operand:SF 3 "div_operator" ""))
15307 (const_string "ssediv")
15308 (eq_attr "alternative" "2")
15309 (const_string "sseadd")
15310 (match_operand:SF 3 "mult_operator" "")
15311 (const_string "fmul")
15312 (match_operand:SF 3 "div_operator" "")
15313 (const_string "fdiv")
15315 (const_string "fop")))
15316 (set_attr "mode" "SF")])
15318 (define_insn "*fop_sf_1_sse"
15319 [(set (match_operand:SF 0 "register_operand" "=x")
15320 (match_operator:SF 3 "binary_fp_operator"
15321 [(match_operand:SF 1 "register_operand" "0")
15322 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15324 && !COMMUTATIVE_ARITH_P (operands[3])"
15325 "* return output_387_binary_op (insn, operands);"
15326 [(set (attr "type")
15327 (cond [(match_operand:SF 3 "mult_operator" "")
15328 (const_string "ssemul")
15329 (match_operand:SF 3 "div_operator" "")
15330 (const_string "ssediv")
15332 (const_string "sseadd")))
15333 (set_attr "mode" "SF")])
15335 ;; This pattern is not fully shadowed by the pattern above.
15336 (define_insn "*fop_sf_1_i387"
15337 [(set (match_operand:SF 0 "register_operand" "=f,f")
15338 (match_operator:SF 3 "binary_fp_operator"
15339 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15340 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15341 "TARGET_80387 && !TARGET_SSE_MATH
15342 && !COMMUTATIVE_ARITH_P (operands[3])
15343 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15344 "* return output_387_binary_op (insn, operands);"
15345 [(set (attr "type")
15346 (cond [(match_operand:SF 3 "mult_operator" "")
15347 (const_string "fmul")
15348 (match_operand:SF 3 "div_operator" "")
15349 (const_string "fdiv")
15351 (const_string "fop")))
15352 (set_attr "mode" "SF")])
15354 ;; ??? Add SSE splitters for these!
15355 (define_insn "*fop_sf_2<mode>_i387"
15356 [(set (match_operand:SF 0 "register_operand" "=f,f")
15357 (match_operator:SF 3 "binary_fp_operator"
15358 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15359 (match_operand:SF 2 "register_operand" "0,0")]))]
15360 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15361 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15362 [(set (attr "type")
15363 (cond [(match_operand:SF 3 "mult_operator" "")
15364 (const_string "fmul")
15365 (match_operand:SF 3 "div_operator" "")
15366 (const_string "fdiv")
15368 (const_string "fop")))
15369 (set_attr "fp_int_src" "true")
15370 (set_attr "mode" "<MODE>")])
15372 (define_insn "*fop_sf_3<mode>_i387"
15373 [(set (match_operand:SF 0 "register_operand" "=f,f")
15374 (match_operator:SF 3 "binary_fp_operator"
15375 [(match_operand:SF 1 "register_operand" "0,0")
15376 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15377 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15378 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15379 [(set (attr "type")
15380 (cond [(match_operand:SF 3 "mult_operator" "")
15381 (const_string "fmul")
15382 (match_operand:SF 3 "div_operator" "")
15383 (const_string "fdiv")
15385 (const_string "fop")))
15386 (set_attr "fp_int_src" "true")
15387 (set_attr "mode" "<MODE>")])
15389 (define_insn "*fop_df_comm_mixed"
15390 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15391 (match_operator:DF 3 "binary_fp_operator"
15392 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15393 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15394 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15395 && COMMUTATIVE_ARITH_P (operands[3])
15396 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15397 "* return output_387_binary_op (insn, operands);"
15398 [(set (attr "type")
15399 (if_then_else (eq_attr "alternative" "1")
15400 (if_then_else (match_operand:DF 3 "mult_operator" "")
15401 (const_string "ssemul")
15402 (const_string "sseadd"))
15403 (if_then_else (match_operand:DF 3 "mult_operator" "")
15404 (const_string "fmul")
15405 (const_string "fop"))))
15406 (set_attr "mode" "DF")])
15408 (define_insn "*fop_df_comm_sse"
15409 [(set (match_operand:DF 0 "register_operand" "=Y")
15410 (match_operator:DF 3 "binary_fp_operator"
15411 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15412 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15413 "TARGET_SSE2 && TARGET_SSE_MATH
15414 && COMMUTATIVE_ARITH_P (operands[3])
15415 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15416 "* return output_387_binary_op (insn, operands);"
15417 [(set (attr "type")
15418 (if_then_else (match_operand:DF 3 "mult_operator" "")
15419 (const_string "ssemul")
15420 (const_string "sseadd")))
15421 (set_attr "mode" "DF")])
15423 (define_insn "*fop_df_comm_i387"
15424 [(set (match_operand:DF 0 "register_operand" "=f")
15425 (match_operator:DF 3 "binary_fp_operator"
15426 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15427 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15429 && COMMUTATIVE_ARITH_P (operands[3])
15430 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15431 "* return output_387_binary_op (insn, operands);"
15432 [(set (attr "type")
15433 (if_then_else (match_operand:DF 3 "mult_operator" "")
15434 (const_string "fmul")
15435 (const_string "fop")))
15436 (set_attr "mode" "DF")])
15438 (define_insn "*fop_df_1_mixed"
15439 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15440 (match_operator:DF 3 "binary_fp_operator"
15441 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15442 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15443 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15444 && !COMMUTATIVE_ARITH_P (operands[3])
15445 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15446 "* return output_387_binary_op (insn, operands);"
15447 [(set (attr "type")
15448 (cond [(and (eq_attr "alternative" "2")
15449 (match_operand:DF 3 "mult_operator" ""))
15450 (const_string "ssemul")
15451 (and (eq_attr "alternative" "2")
15452 (match_operand:DF 3 "div_operator" ""))
15453 (const_string "ssediv")
15454 (eq_attr "alternative" "2")
15455 (const_string "sseadd")
15456 (match_operand:DF 3 "mult_operator" "")
15457 (const_string "fmul")
15458 (match_operand:DF 3 "div_operator" "")
15459 (const_string "fdiv")
15461 (const_string "fop")))
15462 (set_attr "mode" "DF")])
15464 (define_insn "*fop_df_1_sse"
15465 [(set (match_operand:DF 0 "register_operand" "=Y")
15466 (match_operator:DF 3 "binary_fp_operator"
15467 [(match_operand:DF 1 "register_operand" "0")
15468 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15469 "TARGET_SSE2 && TARGET_SSE_MATH
15470 && !COMMUTATIVE_ARITH_P (operands[3])"
15471 "* return output_387_binary_op (insn, operands);"
15472 [(set_attr "mode" "DF")
15474 (cond [(match_operand:DF 3 "mult_operator" "")
15475 (const_string "ssemul")
15476 (match_operand:DF 3 "div_operator" "")
15477 (const_string "ssediv")
15479 (const_string "sseadd")))])
15481 ;; This pattern is not fully shadowed by the pattern above.
15482 (define_insn "*fop_df_1_i387"
15483 [(set (match_operand:DF 0 "register_operand" "=f,f")
15484 (match_operator:DF 3 "binary_fp_operator"
15485 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15486 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15487 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15488 && !COMMUTATIVE_ARITH_P (operands[3])
15489 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15490 "* return 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 "mode" "DF")])
15500 ;; ??? Add SSE splitters for these!
15501 (define_insn "*fop_df_2<mode>_i387"
15502 [(set (match_operand:DF 0 "register_operand" "=f,f")
15503 (match_operator:DF 3 "binary_fp_operator"
15504 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15505 (match_operand:DF 2 "register_operand" "0,0")]))]
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_3<mode>_i387"
15520 [(set (match_operand:DF 0 "register_operand" "=f,f")
15521 (match_operator:DF 3 "binary_fp_operator"
15522 [(match_operand:DF 1 "register_operand" "0,0")
15523 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15524 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15525 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15526 "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
15535 (set_attr "mode" "<MODE>")])
15537 (define_insn "*fop_df_4_i387"
15538 [(set (match_operand:DF 0 "register_operand" "=f,f")
15539 (match_operator:DF 3 "binary_fp_operator"
15540 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15541 (match_operand:DF 2 "register_operand" "0,f")]))]
15542 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15543 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15544 "* return output_387_binary_op (insn, operands);"
15545 [(set (attr "type")
15546 (cond [(match_operand:DF 3 "mult_operator" "")
15547 (const_string "fmul")
15548 (match_operand:DF 3 "div_operator" "")
15549 (const_string "fdiv")
15551 (const_string "fop")))
15552 (set_attr "mode" "SF")])
15554 (define_insn "*fop_df_5_i387"
15555 [(set (match_operand:DF 0 "register_operand" "=f,f")
15556 (match_operator:DF 3 "binary_fp_operator"
15557 [(match_operand:DF 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_df_6_i387"
15572 [(set (match_operand:DF 0 "register_operand" "=f,f")
15573 (match_operator:DF 3 "binary_fp_operator"
15575 (match_operand:SF 1 "register_operand" "0,f"))
15577 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15578 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15579 "* return output_387_binary_op (insn, operands);"
15580 [(set (attr "type")
15581 (cond [(match_operand:DF 3 "mult_operator" "")
15582 (const_string "fmul")
15583 (match_operand:DF 3 "div_operator" "")
15584 (const_string "fdiv")
15586 (const_string "fop")))
15587 (set_attr "mode" "SF")])
15589 (define_insn "*fop_xf_comm_i387"
15590 [(set (match_operand:XF 0 "register_operand" "=f")
15591 (match_operator:XF 3 "binary_fp_operator"
15592 [(match_operand:XF 1 "register_operand" "%0")
15593 (match_operand:XF 2 "register_operand" "f")]))]
15595 && COMMUTATIVE_ARITH_P (operands[3])"
15596 "* return output_387_binary_op (insn, operands);"
15597 [(set (attr "type")
15598 (if_then_else (match_operand:XF 3 "mult_operator" "")
15599 (const_string "fmul")
15600 (const_string "fop")))
15601 (set_attr "mode" "XF")])
15603 (define_insn "*fop_xf_1_i387"
15604 [(set (match_operand:XF 0 "register_operand" "=f,f")
15605 (match_operator:XF 3 "binary_fp_operator"
15606 [(match_operand:XF 1 "register_operand" "0,f")
15607 (match_operand:XF 2 "register_operand" "f,0")]))]
15609 && !COMMUTATIVE_ARITH_P (operands[3])"
15610 "* return output_387_binary_op (insn, operands);"
15611 [(set (attr "type")
15612 (cond [(match_operand:XF 3 "mult_operator" "")
15613 (const_string "fmul")
15614 (match_operand:XF 3 "div_operator" "")
15615 (const_string "fdiv")
15617 (const_string "fop")))
15618 (set_attr "mode" "XF")])
15620 (define_insn "*fop_xf_2<mode>_i387"
15621 [(set (match_operand:XF 0 "register_operand" "=f,f")
15622 (match_operator:XF 3 "binary_fp_operator"
15623 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15624 (match_operand:XF 2 "register_operand" "0,0")]))]
15625 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15626 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15627 [(set (attr "type")
15628 (cond [(match_operand:XF 3 "mult_operator" "")
15629 (const_string "fmul")
15630 (match_operand:XF 3 "div_operator" "")
15631 (const_string "fdiv")
15633 (const_string "fop")))
15634 (set_attr "fp_int_src" "true")
15635 (set_attr "mode" "<MODE>")])
15637 (define_insn "*fop_xf_3<mode>_i387"
15638 [(set (match_operand:XF 0 "register_operand" "=f,f")
15639 (match_operator:XF 3 "binary_fp_operator"
15640 [(match_operand:XF 1 "register_operand" "0,0")
15641 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15642 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15643 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15644 [(set (attr "type")
15645 (cond [(match_operand:XF 3 "mult_operator" "")
15646 (const_string "fmul")
15647 (match_operand:XF 3 "div_operator" "")
15648 (const_string "fdiv")
15650 (const_string "fop")))
15651 (set_attr "fp_int_src" "true")
15652 (set_attr "mode" "<MODE>")])
15654 (define_insn "*fop_xf_4_i387"
15655 [(set (match_operand:XF 0 "register_operand" "=f,f")
15656 (match_operator:XF 3 "binary_fp_operator"
15657 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15658 (match_operand:XF 2 "register_operand" "0,f")]))]
15660 "* return output_387_binary_op (insn, operands);"
15661 [(set (attr "type")
15662 (cond [(match_operand:XF 3 "mult_operator" "")
15663 (const_string "fmul")
15664 (match_operand:XF 3 "div_operator" "")
15665 (const_string "fdiv")
15667 (const_string "fop")))
15668 (set_attr "mode" "SF")])
15670 (define_insn "*fop_xf_5_i387"
15671 [(set (match_operand:XF 0 "register_operand" "=f,f")
15672 (match_operator:XF 3 "binary_fp_operator"
15673 [(match_operand:XF 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")])
15687 (define_insn "*fop_xf_6_i387"
15688 [(set (match_operand:XF 0 "register_operand" "=f,f")
15689 (match_operator:XF 3 "binary_fp_operator"
15691 (match_operand 1 "register_operand" "0,f"))
15693 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15695 "* return output_387_binary_op (insn, operands);"
15696 [(set (attr "type")
15697 (cond [(match_operand:XF 3 "mult_operator" "")
15698 (const_string "fmul")
15699 (match_operand:XF 3 "div_operator" "")
15700 (const_string "fdiv")
15702 (const_string "fop")))
15703 (set_attr "mode" "SF")])
15706 [(set (match_operand 0 "register_operand" "")
15707 (match_operator 3 "binary_fp_operator"
15708 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15709 (match_operand 2 "register_operand" "")]))]
15710 "TARGET_80387 && reload_completed
15711 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15714 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15715 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15716 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15717 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15718 GET_MODE (operands[3]),
15721 ix86_free_from_memory (GET_MODE (operands[1]));
15726 [(set (match_operand 0 "register_operand" "")
15727 (match_operator 3 "binary_fp_operator"
15728 [(match_operand 1 "register_operand" "")
15729 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15730 "TARGET_80387 && reload_completed
15731 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15734 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15735 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15736 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15737 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15738 GET_MODE (operands[3]),
15741 ix86_free_from_memory (GET_MODE (operands[2]));
15745 ;; FPU special functions.
15747 (define_expand "sqrtsf2"
15748 [(set (match_operand:SF 0 "register_operand" "")
15749 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15750 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15752 if (!TARGET_SSE_MATH)
15753 operands[1] = force_reg (SFmode, operands[1]);
15756 (define_insn "*sqrtsf2_mixed"
15757 [(set (match_operand:SF 0 "register_operand" "=f,x")
15758 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15759 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15762 sqrtss\t{%1, %0|%0, %1}"
15763 [(set_attr "type" "fpspc,sse")
15764 (set_attr "mode" "SF,SF")
15765 (set_attr "athlon_decode" "direct,*")
15766 (set_attr "amdfam10_decode" "direct,*")])
15768 (define_insn "*sqrtsf2_sse"
15769 [(set (match_operand:SF 0 "register_operand" "=x")
15770 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15772 "sqrtss\t{%1, %0|%0, %1}"
15773 [(set_attr "type" "sse")
15774 (set_attr "mode" "SF")
15775 (set_attr "athlon_decode" "*")
15776 (set_attr "amdfam10_decode" "*")])
15778 (define_insn "*sqrtsf2_i387"
15779 [(set (match_operand:SF 0 "register_operand" "=f")
15780 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15781 "TARGET_USE_FANCY_MATH_387"
15783 [(set_attr "type" "fpspc")
15784 (set_attr "mode" "SF")
15785 (set_attr "athlon_decode" "direct")
15786 (set_attr "amdfam10_decode" "direct")])
15788 (define_expand "sqrtdf2"
15789 [(set (match_operand:DF 0 "register_operand" "")
15790 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15791 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15793 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15794 operands[1] = force_reg (DFmode, operands[1]);
15797 (define_insn "*sqrtdf2_mixed"
15798 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15799 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15800 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15803 sqrtsd\t{%1, %0|%0, %1}"
15804 [(set_attr "type" "fpspc,sse")
15805 (set_attr "mode" "DF,DF")
15806 (set_attr "athlon_decode" "direct,*")
15807 (set_attr "amdfam10_decode" "direct,*")])
15809 (define_insn "*sqrtdf2_sse"
15810 [(set (match_operand:DF 0 "register_operand" "=Y")
15811 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15812 "TARGET_SSE2 && TARGET_SSE_MATH"
15813 "sqrtsd\t{%1, %0|%0, %1}"
15814 [(set_attr "type" "sse")
15815 (set_attr "mode" "DF")
15816 (set_attr "athlon_decode" "*")
15817 (set_attr "amdfam10_decode" "*")])
15819 (define_insn "*sqrtdf2_i387"
15820 [(set (match_operand:DF 0 "register_operand" "=f")
15821 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15822 "TARGET_USE_FANCY_MATH_387"
15824 [(set_attr "type" "fpspc")
15825 (set_attr "mode" "DF")
15826 (set_attr "athlon_decode" "direct")
15827 (set_attr "amdfam10_decode" "direct")])
15829 (define_insn "*sqrtextendsfdf2_i387"
15830 [(set (match_operand:DF 0 "register_operand" "=f")
15831 (sqrt:DF (float_extend:DF
15832 (match_operand:SF 1 "register_operand" "0"))))]
15833 "TARGET_USE_FANCY_MATH_387
15834 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15836 [(set_attr "type" "fpspc")
15837 (set_attr "mode" "DF")
15838 (set_attr "athlon_decode" "direct")
15839 (set_attr "amdfam10_decode" "direct")])
15841 (define_insn "sqrtxf2"
15842 [(set (match_operand:XF 0 "register_operand" "=f")
15843 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15844 "TARGET_USE_FANCY_MATH_387"
15846 [(set_attr "type" "fpspc")
15847 (set_attr "mode" "XF")
15848 (set_attr "athlon_decode" "direct")
15849 (set_attr "amdfam10_decode" "direct")])
15851 (define_insn "*sqrtextendsfxf2_i387"
15852 [(set (match_operand:XF 0 "register_operand" "=f")
15853 (sqrt:XF (float_extend:XF
15854 (match_operand:SF 1 "register_operand" "0"))))]
15855 "TARGET_USE_FANCY_MATH_387"
15857 [(set_attr "type" "fpspc")
15858 (set_attr "mode" "XF")
15859 (set_attr "athlon_decode" "direct")
15860 (set_attr "amdfam10_decode" "direct")])
15862 (define_insn "*sqrtextenddfxf2_i387"
15863 [(set (match_operand:XF 0 "register_operand" "=f")
15864 (sqrt:XF (float_extend:XF
15865 (match_operand:DF 1 "register_operand" "0"))))]
15866 "TARGET_USE_FANCY_MATH_387"
15868 [(set_attr "type" "fpspc")
15869 (set_attr "mode" "XF")
15870 (set_attr "athlon_decode" "direct")
15871 (set_attr "amdfam10_decode" "direct")])
15873 (define_insn "fpremxf4"
15874 [(set (match_operand:XF 0 "register_operand" "=f")
15875 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15876 (match_operand:XF 3 "register_operand" "1")]
15878 (set (match_operand:XF 1 "register_operand" "=u")
15879 (unspec:XF [(match_dup 2) (match_dup 3)]
15881 (set (reg:CCFP FPSR_REG)
15882 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15883 "TARGET_USE_FANCY_MATH_387
15884 && flag_unsafe_math_optimizations"
15886 [(set_attr "type" "fpspc")
15887 (set_attr "mode" "XF")])
15889 (define_expand "fmodsf3"
15890 [(use (match_operand:SF 0 "register_operand" ""))
15891 (use (match_operand:SF 1 "register_operand" ""))
15892 (use (match_operand:SF 2 "register_operand" ""))]
15893 "TARGET_USE_FANCY_MATH_387
15894 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15895 && flag_unsafe_math_optimizations"
15897 rtx label = gen_label_rtx ();
15899 rtx op1 = gen_reg_rtx (XFmode);
15900 rtx op2 = gen_reg_rtx (XFmode);
15902 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15903 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15905 emit_label (label);
15907 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15908 ix86_emit_fp_unordered_jump (label);
15910 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15914 (define_expand "fmoddf3"
15915 [(use (match_operand:DF 0 "register_operand" ""))
15916 (use (match_operand:DF 1 "register_operand" ""))
15917 (use (match_operand:DF 2 "register_operand" ""))]
15918 "TARGET_USE_FANCY_MATH_387
15919 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15920 && flag_unsafe_math_optimizations"
15922 rtx label = gen_label_rtx ();
15924 rtx op1 = gen_reg_rtx (XFmode);
15925 rtx op2 = gen_reg_rtx (XFmode);
15927 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15928 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15930 emit_label (label);
15932 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15933 ix86_emit_fp_unordered_jump (label);
15935 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15939 (define_expand "fmodxf3"
15940 [(use (match_operand:XF 0 "register_operand" ""))
15941 (use (match_operand:XF 1 "register_operand" ""))
15942 (use (match_operand:XF 2 "register_operand" ""))]
15943 "TARGET_USE_FANCY_MATH_387
15944 && flag_unsafe_math_optimizations"
15946 rtx label = gen_label_rtx ();
15948 emit_label (label);
15950 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15951 operands[1], operands[2]));
15952 ix86_emit_fp_unordered_jump (label);
15954 emit_move_insn (operands[0], operands[1]);
15958 (define_insn "fprem1xf4"
15959 [(set (match_operand:XF 0 "register_operand" "=f")
15960 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15961 (match_operand:XF 3 "register_operand" "1")]
15963 (set (match_operand:XF 1 "register_operand" "=u")
15964 (unspec:XF [(match_dup 2) (match_dup 3)]
15966 (set (reg:CCFP FPSR_REG)
15967 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15968 "TARGET_USE_FANCY_MATH_387
15969 && flag_unsafe_math_optimizations"
15971 [(set_attr "type" "fpspc")
15972 (set_attr "mode" "XF")])
15974 (define_expand "dremsf3"
15975 [(use (match_operand:SF 0 "register_operand" ""))
15976 (use (match_operand:SF 1 "register_operand" ""))
15977 (use (match_operand:SF 2 "register_operand" ""))]
15978 "TARGET_USE_FANCY_MATH_387
15979 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15980 && flag_unsafe_math_optimizations"
15982 rtx label = gen_label_rtx ();
15984 rtx op1 = gen_reg_rtx (XFmode);
15985 rtx op2 = gen_reg_rtx (XFmode);
15987 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15988 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15990 emit_label (label);
15992 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15993 ix86_emit_fp_unordered_jump (label);
15995 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15999 (define_expand "dremdf3"
16000 [(use (match_operand:DF 0 "register_operand" ""))
16001 (use (match_operand:DF 1 "register_operand" ""))
16002 (use (match_operand:DF 2 "register_operand" ""))]
16003 "TARGET_USE_FANCY_MATH_387
16004 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16005 && flag_unsafe_math_optimizations"
16007 rtx label = gen_label_rtx ();
16009 rtx op1 = gen_reg_rtx (XFmode);
16010 rtx op2 = gen_reg_rtx (XFmode);
16012 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16013 emit_insn (gen_extenddfxf2 (op2, operands[2]));
16015 emit_label (label);
16017 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
16018 ix86_emit_fp_unordered_jump (label);
16020 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
16024 (define_expand "dremxf3"
16025 [(use (match_operand:XF 0 "register_operand" ""))
16026 (use (match_operand:XF 1 "register_operand" ""))
16027 (use (match_operand:XF 2 "register_operand" ""))]
16028 "TARGET_USE_FANCY_MATH_387
16029 && flag_unsafe_math_optimizations"
16031 rtx label = gen_label_rtx ();
16033 emit_label (label);
16035 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
16036 operands[1], operands[2]));
16037 ix86_emit_fp_unordered_jump (label);
16039 emit_move_insn (operands[0], operands[1]);
16043 (define_insn "*sindf2"
16044 [(set (match_operand:DF 0 "register_operand" "=f")
16045 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
16046 "TARGET_USE_FANCY_MATH_387
16047 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16048 && flag_unsafe_math_optimizations"
16050 [(set_attr "type" "fpspc")
16051 (set_attr "mode" "DF")])
16053 (define_insn "*sinsf2"
16054 [(set (match_operand:SF 0 "register_operand" "=f")
16055 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
16056 "TARGET_USE_FANCY_MATH_387
16057 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16058 && flag_unsafe_math_optimizations"
16060 [(set_attr "type" "fpspc")
16061 (set_attr "mode" "SF")])
16063 (define_insn "*sinextendsfdf2"
16064 [(set (match_operand:DF 0 "register_operand" "=f")
16065 (unspec:DF [(float_extend:DF
16066 (match_operand:SF 1 "register_operand" "0"))]
16068 "TARGET_USE_FANCY_MATH_387
16069 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16070 && flag_unsafe_math_optimizations"
16072 [(set_attr "type" "fpspc")
16073 (set_attr "mode" "DF")])
16075 (define_insn "*sinxf2"
16076 [(set (match_operand:XF 0 "register_operand" "=f")
16077 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16078 "TARGET_USE_FANCY_MATH_387
16079 && flag_unsafe_math_optimizations"
16081 [(set_attr "type" "fpspc")
16082 (set_attr "mode" "XF")])
16084 (define_insn "*cosdf2"
16085 [(set (match_operand:DF 0 "register_operand" "=f")
16086 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
16087 "TARGET_USE_FANCY_MATH_387
16088 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16089 && flag_unsafe_math_optimizations"
16091 [(set_attr "type" "fpspc")
16092 (set_attr "mode" "DF")])
16094 (define_insn "*cossf2"
16095 [(set (match_operand:SF 0 "register_operand" "=f")
16096 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
16097 "TARGET_USE_FANCY_MATH_387
16098 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16099 && flag_unsafe_math_optimizations"
16101 [(set_attr "type" "fpspc")
16102 (set_attr "mode" "SF")])
16104 (define_insn "*cosextendsfdf2"
16105 [(set (match_operand:DF 0 "register_operand" "=f")
16106 (unspec:DF [(float_extend:DF
16107 (match_operand:SF 1 "register_operand" "0"))]
16109 "TARGET_USE_FANCY_MATH_387
16110 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16111 && flag_unsafe_math_optimizations"
16113 [(set_attr "type" "fpspc")
16114 (set_attr "mode" "DF")])
16116 (define_insn "*cosxf2"
16117 [(set (match_operand:XF 0 "register_operand" "=f")
16118 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16119 "TARGET_USE_FANCY_MATH_387
16120 && flag_unsafe_math_optimizations"
16122 [(set_attr "type" "fpspc")
16123 (set_attr "mode" "XF")])
16125 ;; With sincos pattern defined, sin and cos builtin function will be
16126 ;; expanded to sincos pattern with one of its outputs left unused.
16127 ;; Cse pass will detected, if two sincos patterns can be combined,
16128 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16129 ;; depending on the unused output.
16131 (define_insn "sincosdf3"
16132 [(set (match_operand:DF 0 "register_operand" "=f")
16133 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16134 UNSPEC_SINCOS_COS))
16135 (set (match_operand:DF 1 "register_operand" "=u")
16136 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16137 "TARGET_USE_FANCY_MATH_387
16138 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16139 && flag_unsafe_math_optimizations"
16141 [(set_attr "type" "fpspc")
16142 (set_attr "mode" "DF")])
16145 [(set (match_operand:DF 0 "register_operand" "")
16146 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16147 UNSPEC_SINCOS_COS))
16148 (set (match_operand:DF 1 "register_operand" "")
16149 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16150 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16151 && !reload_completed && !reload_in_progress"
16152 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
16156 [(set (match_operand:DF 0 "register_operand" "")
16157 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16158 UNSPEC_SINCOS_COS))
16159 (set (match_operand:DF 1 "register_operand" "")
16160 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16161 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16162 && !reload_completed && !reload_in_progress"
16163 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
16166 (define_insn "sincossf3"
16167 [(set (match_operand:SF 0 "register_operand" "=f")
16168 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16169 UNSPEC_SINCOS_COS))
16170 (set (match_operand:SF 1 "register_operand" "=u")
16171 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16172 "TARGET_USE_FANCY_MATH_387
16173 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16174 && flag_unsafe_math_optimizations"
16176 [(set_attr "type" "fpspc")
16177 (set_attr "mode" "SF")])
16180 [(set (match_operand:SF 0 "register_operand" "")
16181 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16182 UNSPEC_SINCOS_COS))
16183 (set (match_operand:SF 1 "register_operand" "")
16184 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16185 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16186 && !reload_completed && !reload_in_progress"
16187 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
16191 [(set (match_operand:SF 0 "register_operand" "")
16192 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16193 UNSPEC_SINCOS_COS))
16194 (set (match_operand:SF 1 "register_operand" "")
16195 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16196 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16197 && !reload_completed && !reload_in_progress"
16198 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
16201 (define_insn "*sincosextendsfdf3"
16202 [(set (match_operand:DF 0 "register_operand" "=f")
16203 (unspec:DF [(float_extend:DF
16204 (match_operand:SF 2 "register_operand" "0"))]
16205 UNSPEC_SINCOS_COS))
16206 (set (match_operand:DF 1 "register_operand" "=u")
16207 (unspec:DF [(float_extend:DF
16208 (match_dup 2))] UNSPEC_SINCOS_SIN))]
16209 "TARGET_USE_FANCY_MATH_387
16210 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16211 && flag_unsafe_math_optimizations"
16213 [(set_attr "type" "fpspc")
16214 (set_attr "mode" "DF")])
16217 [(set (match_operand:DF 0 "register_operand" "")
16218 (unspec:DF [(float_extend:DF
16219 (match_operand:SF 2 "register_operand" ""))]
16220 UNSPEC_SINCOS_COS))
16221 (set (match_operand:DF 1 "register_operand" "")
16222 (unspec:DF [(float_extend:DF
16223 (match_dup 2))] UNSPEC_SINCOS_SIN))]
16224 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16225 && !reload_completed && !reload_in_progress"
16226 [(set (match_dup 1) (unspec:DF [(float_extend:DF
16227 (match_dup 2))] UNSPEC_SIN))]
16231 [(set (match_operand:DF 0 "register_operand" "")
16232 (unspec:DF [(float_extend:DF
16233 (match_operand:SF 2 "register_operand" ""))]
16234 UNSPEC_SINCOS_COS))
16235 (set (match_operand:DF 1 "register_operand" "")
16236 (unspec:DF [(float_extend:DF
16237 (match_dup 2))] UNSPEC_SINCOS_SIN))]
16238 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16239 && !reload_completed && !reload_in_progress"
16240 [(set (match_dup 0) (unspec:DF [(float_extend:DF
16241 (match_dup 2))] UNSPEC_COS))]
16244 (define_insn "sincosxf3"
16245 [(set (match_operand:XF 0 "register_operand" "=f")
16246 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16247 UNSPEC_SINCOS_COS))
16248 (set (match_operand:XF 1 "register_operand" "=u")
16249 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16250 "TARGET_USE_FANCY_MATH_387
16251 && flag_unsafe_math_optimizations"
16253 [(set_attr "type" "fpspc")
16254 (set_attr "mode" "XF")])
16257 [(set (match_operand:XF 0 "register_operand" "")
16258 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16259 UNSPEC_SINCOS_COS))
16260 (set (match_operand:XF 1 "register_operand" "")
16261 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16262 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16263 && !reload_completed && !reload_in_progress"
16264 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16268 [(set (match_operand:XF 0 "register_operand" "")
16269 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16270 UNSPEC_SINCOS_COS))
16271 (set (match_operand:XF 1 "register_operand" "")
16272 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16273 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16274 && !reload_completed && !reload_in_progress"
16275 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16278 (define_insn "*tandf3_1"
16279 [(set (match_operand:DF 0 "register_operand" "=f")
16280 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16282 (set (match_operand:DF 1 "register_operand" "=u")
16283 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16284 "TARGET_USE_FANCY_MATH_387
16285 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16286 && flag_unsafe_math_optimizations"
16288 [(set_attr "type" "fpspc")
16289 (set_attr "mode" "DF")])
16291 ;; optimize sequence: fptan
16294 ;; into fptan insn.
16297 [(parallel[(set (match_operand:DF 0 "register_operand" "")
16298 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16300 (set (match_operand:DF 1 "register_operand" "")
16301 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16303 (match_operand:DF 3 "immediate_operand" ""))]
16304 "standard_80387_constant_p (operands[3]) == 2"
16305 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16306 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16309 (define_expand "tandf2"
16310 [(parallel [(set (match_dup 2)
16311 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16313 (set (match_operand:DF 0 "register_operand" "")
16314 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16315 "TARGET_USE_FANCY_MATH_387
16316 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16317 && flag_unsafe_math_optimizations"
16319 operands[2] = gen_reg_rtx (DFmode);
16322 (define_insn "*tansf3_1"
16323 [(set (match_operand:SF 0 "register_operand" "=f")
16324 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16326 (set (match_operand:SF 1 "register_operand" "=u")
16327 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16328 "TARGET_USE_FANCY_MATH_387
16329 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16330 && flag_unsafe_math_optimizations"
16332 [(set_attr "type" "fpspc")
16333 (set_attr "mode" "SF")])
16335 ;; optimize sequence: fptan
16338 ;; into fptan insn.
16341 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16342 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16344 (set (match_operand:SF 1 "register_operand" "")
16345 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16347 (match_operand:SF 3 "immediate_operand" ""))]
16348 "standard_80387_constant_p (operands[3]) == 2"
16349 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16350 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16353 (define_expand "tansf2"
16354 [(parallel [(set (match_dup 2)
16355 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16357 (set (match_operand:SF 0 "register_operand" "")
16358 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16359 "TARGET_USE_FANCY_MATH_387
16360 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16361 && flag_unsafe_math_optimizations"
16363 operands[2] = gen_reg_rtx (SFmode);
16366 (define_insn "*tanxf3_1"
16367 [(set (match_operand:XF 0 "register_operand" "=f")
16368 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16370 (set (match_operand:XF 1 "register_operand" "=u")
16371 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16372 "TARGET_USE_FANCY_MATH_387
16373 && flag_unsafe_math_optimizations"
16375 [(set_attr "type" "fpspc")
16376 (set_attr "mode" "XF")])
16378 ;; optimize sequence: fptan
16381 ;; into fptan insn.
16384 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16385 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16387 (set (match_operand:XF 1 "register_operand" "")
16388 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16390 (match_operand:XF 3 "immediate_operand" ""))]
16391 "standard_80387_constant_p (operands[3]) == 2"
16392 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16393 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16396 (define_expand "tanxf2"
16397 [(parallel [(set (match_dup 2)
16398 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16400 (set (match_operand:XF 0 "register_operand" "")
16401 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16402 "TARGET_USE_FANCY_MATH_387
16403 && flag_unsafe_math_optimizations"
16405 operands[2] = gen_reg_rtx (XFmode);
16408 (define_insn "atan2df3_1"
16409 [(set (match_operand:DF 0 "register_operand" "=f")
16410 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16411 (match_operand:DF 1 "register_operand" "u")]
16413 (clobber (match_scratch:DF 3 "=1"))]
16414 "TARGET_USE_FANCY_MATH_387
16415 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16416 && flag_unsafe_math_optimizations"
16418 [(set_attr "type" "fpspc")
16419 (set_attr "mode" "DF")])
16421 (define_expand "atan2df3"
16422 [(use (match_operand:DF 0 "register_operand" ""))
16423 (use (match_operand:DF 2 "register_operand" ""))
16424 (use (match_operand:DF 1 "register_operand" ""))]
16425 "TARGET_USE_FANCY_MATH_387
16426 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16427 && flag_unsafe_math_optimizations"
16429 rtx copy = gen_reg_rtx (DFmode);
16430 emit_move_insn (copy, operands[1]);
16431 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16435 (define_expand "atandf2"
16436 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16437 (unspec:DF [(match_dup 2)
16438 (match_operand:DF 1 "register_operand" "")]
16440 (clobber (match_scratch:DF 3 ""))])]
16441 "TARGET_USE_FANCY_MATH_387
16442 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16443 && flag_unsafe_math_optimizations"
16445 operands[2] = gen_reg_rtx (DFmode);
16446 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16449 (define_insn "atan2sf3_1"
16450 [(set (match_operand:SF 0 "register_operand" "=f")
16451 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16452 (match_operand:SF 1 "register_operand" "u")]
16454 (clobber (match_scratch:SF 3 "=1"))]
16455 "TARGET_USE_FANCY_MATH_387
16456 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16457 && flag_unsafe_math_optimizations"
16459 [(set_attr "type" "fpspc")
16460 (set_attr "mode" "SF")])
16462 (define_expand "atan2sf3"
16463 [(use (match_operand:SF 0 "register_operand" ""))
16464 (use (match_operand:SF 2 "register_operand" ""))
16465 (use (match_operand:SF 1 "register_operand" ""))]
16466 "TARGET_USE_FANCY_MATH_387
16467 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16468 && flag_unsafe_math_optimizations"
16470 rtx copy = gen_reg_rtx (SFmode);
16471 emit_move_insn (copy, operands[1]);
16472 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16476 (define_expand "atansf2"
16477 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16478 (unspec:SF [(match_dup 2)
16479 (match_operand:SF 1 "register_operand" "")]
16481 (clobber (match_scratch:SF 3 ""))])]
16482 "TARGET_USE_FANCY_MATH_387
16483 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16484 && flag_unsafe_math_optimizations"
16486 operands[2] = gen_reg_rtx (SFmode);
16487 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16490 (define_insn "atan2xf3_1"
16491 [(set (match_operand:XF 0 "register_operand" "=f")
16492 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16493 (match_operand:XF 1 "register_operand" "u")]
16495 (clobber (match_scratch:XF 3 "=1"))]
16496 "TARGET_USE_FANCY_MATH_387
16497 && flag_unsafe_math_optimizations"
16499 [(set_attr "type" "fpspc")
16500 (set_attr "mode" "XF")])
16502 (define_expand "atan2xf3"
16503 [(use (match_operand:XF 0 "register_operand" ""))
16504 (use (match_operand:XF 2 "register_operand" ""))
16505 (use (match_operand:XF 1 "register_operand" ""))]
16506 "TARGET_USE_FANCY_MATH_387
16507 && flag_unsafe_math_optimizations"
16509 rtx copy = gen_reg_rtx (XFmode);
16510 emit_move_insn (copy, operands[1]);
16511 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16515 (define_expand "atanxf2"
16516 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16517 (unspec:XF [(match_dup 2)
16518 (match_operand:XF 1 "register_operand" "")]
16520 (clobber (match_scratch:XF 3 ""))])]
16521 "TARGET_USE_FANCY_MATH_387
16522 && flag_unsafe_math_optimizations"
16524 operands[2] = gen_reg_rtx (XFmode);
16525 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16528 (define_expand "asindf2"
16529 [(set (match_dup 2)
16530 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16531 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16532 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16533 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16534 (parallel [(set (match_dup 7)
16535 (unspec:XF [(match_dup 6) (match_dup 2)]
16537 (clobber (match_scratch:XF 8 ""))])
16538 (set (match_operand:DF 0 "register_operand" "")
16539 (float_truncate:DF (match_dup 7)))]
16540 "TARGET_USE_FANCY_MATH_387
16541 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16542 && flag_unsafe_math_optimizations"
16546 for (i=2; i<8; i++)
16547 operands[i] = gen_reg_rtx (XFmode);
16549 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16552 (define_expand "asinsf2"
16553 [(set (match_dup 2)
16554 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16555 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16556 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16557 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16558 (parallel [(set (match_dup 7)
16559 (unspec:XF [(match_dup 6) (match_dup 2)]
16561 (clobber (match_scratch:XF 8 ""))])
16562 (set (match_operand:SF 0 "register_operand" "")
16563 (float_truncate:SF (match_dup 7)))]
16564 "TARGET_USE_FANCY_MATH_387
16565 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16566 && flag_unsafe_math_optimizations"
16570 for (i=2; i<8; i++)
16571 operands[i] = gen_reg_rtx (XFmode);
16573 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16576 (define_expand "asinxf2"
16577 [(set (match_dup 2)
16578 (mult:XF (match_operand:XF 1 "register_operand" "")
16580 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16581 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16582 (parallel [(set (match_operand:XF 0 "register_operand" "")
16583 (unspec:XF [(match_dup 5) (match_dup 1)]
16585 (clobber (match_scratch:XF 6 ""))])]
16586 "TARGET_USE_FANCY_MATH_387
16587 && flag_unsafe_math_optimizations"
16591 for (i=2; i<6; i++)
16592 operands[i] = gen_reg_rtx (XFmode);
16594 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16597 (define_expand "acosdf2"
16598 [(set (match_dup 2)
16599 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16600 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16601 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16602 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16603 (parallel [(set (match_dup 7)
16604 (unspec:XF [(match_dup 2) (match_dup 6)]
16606 (clobber (match_scratch:XF 8 ""))])
16607 (set (match_operand:DF 0 "register_operand" "")
16608 (float_truncate:DF (match_dup 7)))]
16609 "TARGET_USE_FANCY_MATH_387
16610 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16611 && flag_unsafe_math_optimizations"
16615 for (i=2; i<8; i++)
16616 operands[i] = gen_reg_rtx (XFmode);
16618 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16621 (define_expand "acossf2"
16622 [(set (match_dup 2)
16623 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16624 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16625 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16626 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16627 (parallel [(set (match_dup 7)
16628 (unspec:XF [(match_dup 2) (match_dup 6)]
16630 (clobber (match_scratch:XF 8 ""))])
16631 (set (match_operand:SF 0 "register_operand" "")
16632 (float_truncate:SF (match_dup 7)))]
16633 "TARGET_USE_FANCY_MATH_387
16634 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16635 && flag_unsafe_math_optimizations"
16639 for (i=2; i<8; i++)
16640 operands[i] = gen_reg_rtx (XFmode);
16642 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16645 (define_expand "acosxf2"
16646 [(set (match_dup 2)
16647 (mult:XF (match_operand:XF 1 "register_operand" "")
16649 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16650 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16651 (parallel [(set (match_operand:XF 0 "register_operand" "")
16652 (unspec:XF [(match_dup 1) (match_dup 5)]
16654 (clobber (match_scratch:XF 6 ""))])]
16655 "TARGET_USE_FANCY_MATH_387
16656 && flag_unsafe_math_optimizations"
16660 for (i=2; i<6; i++)
16661 operands[i] = gen_reg_rtx (XFmode);
16663 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16666 (define_insn "fyl2x_xf3"
16667 [(set (match_operand:XF 0 "register_operand" "=f")
16668 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16669 (match_operand:XF 1 "register_operand" "u")]
16671 (clobber (match_scratch:XF 3 "=1"))]
16672 "TARGET_USE_FANCY_MATH_387
16673 && flag_unsafe_math_optimizations"
16675 [(set_attr "type" "fpspc")
16676 (set_attr "mode" "XF")])
16678 (define_expand "logsf2"
16679 [(set (match_dup 2)
16680 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16681 (parallel [(set (match_dup 4)
16682 (unspec:XF [(match_dup 2)
16683 (match_dup 3)] UNSPEC_FYL2X))
16684 (clobber (match_scratch:XF 5 ""))])
16685 (set (match_operand:SF 0 "register_operand" "")
16686 (float_truncate:SF (match_dup 4)))]
16687 "TARGET_USE_FANCY_MATH_387
16688 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16689 && flag_unsafe_math_optimizations"
16693 operands[2] = gen_reg_rtx (XFmode);
16694 operands[3] = gen_reg_rtx (XFmode);
16695 operands[4] = gen_reg_rtx (XFmode);
16697 temp = standard_80387_constant_rtx (4); /* fldln2 */
16698 emit_move_insn (operands[3], temp);
16701 (define_expand "logdf2"
16702 [(set (match_dup 2)
16703 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16704 (parallel [(set (match_dup 4)
16705 (unspec:XF [(match_dup 2)
16706 (match_dup 3)] UNSPEC_FYL2X))
16707 (clobber (match_scratch:XF 5 ""))])
16708 (set (match_operand:DF 0 "register_operand" "")
16709 (float_truncate:DF (match_dup 4)))]
16710 "TARGET_USE_FANCY_MATH_387
16711 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16712 && flag_unsafe_math_optimizations"
16716 operands[2] = gen_reg_rtx (XFmode);
16717 operands[3] = gen_reg_rtx (XFmode);
16718 operands[4] = gen_reg_rtx (XFmode);
16720 temp = standard_80387_constant_rtx (4); /* fldln2 */
16721 emit_move_insn (operands[3], temp);
16724 (define_expand "logxf2"
16725 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16726 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16727 (match_dup 2)] UNSPEC_FYL2X))
16728 (clobber (match_scratch:XF 3 ""))])]
16729 "TARGET_USE_FANCY_MATH_387
16730 && flag_unsafe_math_optimizations"
16734 operands[2] = gen_reg_rtx (XFmode);
16735 temp = standard_80387_constant_rtx (4); /* fldln2 */
16736 emit_move_insn (operands[2], temp);
16739 (define_expand "log10sf2"
16740 [(set (match_dup 2)
16741 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16742 (parallel [(set (match_dup 4)
16743 (unspec:XF [(match_dup 2)
16744 (match_dup 3)] UNSPEC_FYL2X))
16745 (clobber (match_scratch:XF 5 ""))])
16746 (set (match_operand:SF 0 "register_operand" "")
16747 (float_truncate:SF (match_dup 4)))]
16748 "TARGET_USE_FANCY_MATH_387
16749 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16750 && flag_unsafe_math_optimizations"
16754 operands[2] = gen_reg_rtx (XFmode);
16755 operands[3] = gen_reg_rtx (XFmode);
16756 operands[4] = gen_reg_rtx (XFmode);
16758 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16759 emit_move_insn (operands[3], temp);
16762 (define_expand "log10df2"
16763 [(set (match_dup 2)
16764 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16765 (parallel [(set (match_dup 4)
16766 (unspec:XF [(match_dup 2)
16767 (match_dup 3)] UNSPEC_FYL2X))
16768 (clobber (match_scratch:XF 5 ""))])
16769 (set (match_operand:DF 0 "register_operand" "")
16770 (float_truncate:DF (match_dup 4)))]
16771 "TARGET_USE_FANCY_MATH_387
16772 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16773 && flag_unsafe_math_optimizations"
16777 operands[2] = gen_reg_rtx (XFmode);
16778 operands[3] = gen_reg_rtx (XFmode);
16779 operands[4] = gen_reg_rtx (XFmode);
16781 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16782 emit_move_insn (operands[3], temp);
16785 (define_expand "log10xf2"
16786 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16787 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16788 (match_dup 2)] UNSPEC_FYL2X))
16789 (clobber (match_scratch:XF 3 ""))])]
16790 "TARGET_USE_FANCY_MATH_387
16791 && flag_unsafe_math_optimizations"
16795 operands[2] = gen_reg_rtx (XFmode);
16796 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16797 emit_move_insn (operands[2], temp);
16800 (define_expand "log2sf2"
16801 [(set (match_dup 2)
16802 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16803 (parallel [(set (match_dup 4)
16804 (unspec:XF [(match_dup 2)
16805 (match_dup 3)] UNSPEC_FYL2X))
16806 (clobber (match_scratch:XF 5 ""))])
16807 (set (match_operand:SF 0 "register_operand" "")
16808 (float_truncate:SF (match_dup 4)))]
16809 "TARGET_USE_FANCY_MATH_387
16810 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16811 && flag_unsafe_math_optimizations"
16813 operands[2] = gen_reg_rtx (XFmode);
16814 operands[3] = gen_reg_rtx (XFmode);
16815 operands[4] = gen_reg_rtx (XFmode);
16817 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16820 (define_expand "log2df2"
16821 [(set (match_dup 2)
16822 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16823 (parallel [(set (match_dup 4)
16824 (unspec:XF [(match_dup 2)
16825 (match_dup 3)] UNSPEC_FYL2X))
16826 (clobber (match_scratch:XF 5 ""))])
16827 (set (match_operand:DF 0 "register_operand" "")
16828 (float_truncate:DF (match_dup 4)))]
16829 "TARGET_USE_FANCY_MATH_387
16830 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16831 && flag_unsafe_math_optimizations"
16833 operands[2] = gen_reg_rtx (XFmode);
16834 operands[3] = gen_reg_rtx (XFmode);
16835 operands[4] = gen_reg_rtx (XFmode);
16837 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16840 (define_expand "log2xf2"
16841 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16842 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16843 (match_dup 2)] UNSPEC_FYL2X))
16844 (clobber (match_scratch:XF 3 ""))])]
16845 "TARGET_USE_FANCY_MATH_387
16846 && flag_unsafe_math_optimizations"
16848 operands[2] = gen_reg_rtx (XFmode);
16849 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16852 (define_insn "fyl2xp1_xf3"
16853 [(set (match_operand:XF 0 "register_operand" "=f")
16854 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16855 (match_operand:XF 1 "register_operand" "u")]
16857 (clobber (match_scratch:XF 3 "=1"))]
16858 "TARGET_USE_FANCY_MATH_387
16859 && flag_unsafe_math_optimizations"
16861 [(set_attr "type" "fpspc")
16862 (set_attr "mode" "XF")])
16864 (define_expand "log1psf2"
16865 [(use (match_operand:SF 0 "register_operand" ""))
16866 (use (match_operand:SF 1 "register_operand" ""))]
16867 "TARGET_USE_FANCY_MATH_387
16868 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16869 && flag_unsafe_math_optimizations"
16871 rtx op0 = gen_reg_rtx (XFmode);
16872 rtx op1 = gen_reg_rtx (XFmode);
16874 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16875 ix86_emit_i387_log1p (op0, op1);
16876 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16880 (define_expand "log1pdf2"
16881 [(use (match_operand:DF 0 "register_operand" ""))
16882 (use (match_operand:DF 1 "register_operand" ""))]
16883 "TARGET_USE_FANCY_MATH_387
16884 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16885 && flag_unsafe_math_optimizations"
16887 rtx op0 = gen_reg_rtx (XFmode);
16888 rtx op1 = gen_reg_rtx (XFmode);
16890 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16891 ix86_emit_i387_log1p (op0, op1);
16892 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16896 (define_expand "log1pxf2"
16897 [(use (match_operand:XF 0 "register_operand" ""))
16898 (use (match_operand:XF 1 "register_operand" ""))]
16899 "TARGET_USE_FANCY_MATH_387
16900 && flag_unsafe_math_optimizations"
16902 ix86_emit_i387_log1p (operands[0], operands[1]);
16906 (define_insn "*fxtractxf3"
16907 [(set (match_operand:XF 0 "register_operand" "=f")
16908 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16909 UNSPEC_XTRACT_FRACT))
16910 (set (match_operand:XF 1 "register_operand" "=u")
16911 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16912 "TARGET_USE_FANCY_MATH_387
16913 && flag_unsafe_math_optimizations"
16915 [(set_attr "type" "fpspc")
16916 (set_attr "mode" "XF")])
16918 (define_expand "logbsf2"
16919 [(set (match_dup 2)
16920 (float_extend:XF (match_operand:SF 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:SF 0 "register_operand" "")
16926 (float_truncate:SF (match_dup 4)))]
16927 "TARGET_USE_FANCY_MATH_387
16928 && (!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 "logbdf2"
16937 [(set (match_dup 2)
16938 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16939 (parallel [(set (match_dup 3)
16940 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16942 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16943 (set (match_operand:DF 0 "register_operand" "")
16944 (float_truncate:DF (match_dup 4)))]
16945 "TARGET_USE_FANCY_MATH_387
16946 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16947 && flag_unsafe_math_optimizations"
16949 operands[2] = gen_reg_rtx (XFmode);
16950 operands[3] = gen_reg_rtx (XFmode);
16951 operands[4] = gen_reg_rtx (XFmode);
16954 (define_expand "logbxf2"
16955 [(parallel [(set (match_dup 2)
16956 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16957 UNSPEC_XTRACT_FRACT))
16958 (set (match_operand:XF 0 "register_operand" "")
16959 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16960 "TARGET_USE_FANCY_MATH_387
16961 && flag_unsafe_math_optimizations"
16963 operands[2] = gen_reg_rtx (XFmode);
16966 (define_expand "ilogbsi2"
16967 [(parallel [(set (match_dup 2)
16968 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16969 UNSPEC_XTRACT_FRACT))
16970 (set (match_operand:XF 3 "register_operand" "")
16971 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16972 (parallel [(set (match_operand:SI 0 "register_operand" "")
16973 (fix:SI (match_dup 3)))
16974 (clobber (reg:CC FLAGS_REG))])]
16975 "TARGET_USE_FANCY_MATH_387
16976 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16977 && flag_unsafe_math_optimizations"
16979 operands[2] = gen_reg_rtx (XFmode);
16980 operands[3] = gen_reg_rtx (XFmode);
16983 (define_insn "*f2xm1xf2"
16984 [(set (match_operand:XF 0 "register_operand" "=f")
16985 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16987 "TARGET_USE_FANCY_MATH_387
16988 && flag_unsafe_math_optimizations"
16990 [(set_attr "type" "fpspc")
16991 (set_attr "mode" "XF")])
16993 (define_insn "*fscalexf4"
16994 [(set (match_operand:XF 0 "register_operand" "=f")
16995 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16996 (match_operand:XF 3 "register_operand" "1")]
16997 UNSPEC_FSCALE_FRACT))
16998 (set (match_operand:XF 1 "register_operand" "=u")
16999 (unspec:XF [(match_dup 2) (match_dup 3)]
17000 UNSPEC_FSCALE_EXP))]
17001 "TARGET_USE_FANCY_MATH_387
17002 && flag_unsafe_math_optimizations"
17004 [(set_attr "type" "fpspc")
17005 (set_attr "mode" "XF")])
17007 (define_expand "expsf2"
17008 [(set (match_dup 2)
17009 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17010 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17011 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17012 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17013 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17014 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17015 (parallel [(set (match_dup 10)
17016 (unspec:XF [(match_dup 9) (match_dup 5)]
17017 UNSPEC_FSCALE_FRACT))
17018 (set (match_dup 11)
17019 (unspec:XF [(match_dup 9) (match_dup 5)]
17020 UNSPEC_FSCALE_EXP))])
17021 (set (match_operand:SF 0 "register_operand" "")
17022 (float_truncate:SF (match_dup 10)))]
17023 "TARGET_USE_FANCY_MATH_387
17024 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17025 && flag_unsafe_math_optimizations"
17030 for (i=2; i<12; i++)
17031 operands[i] = gen_reg_rtx (XFmode);
17032 temp = standard_80387_constant_rtx (5); /* fldl2e */
17033 emit_move_insn (operands[3], temp);
17034 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
17037 (define_expand "expdf2"
17038 [(set (match_dup 2)
17039 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17040 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17041 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17042 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17043 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17044 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17045 (parallel [(set (match_dup 10)
17046 (unspec:XF [(match_dup 9) (match_dup 5)]
17047 UNSPEC_FSCALE_FRACT))
17048 (set (match_dup 11)
17049 (unspec:XF [(match_dup 9) (match_dup 5)]
17050 UNSPEC_FSCALE_EXP))])
17051 (set (match_operand:DF 0 "register_operand" "")
17052 (float_truncate:DF (match_dup 10)))]
17053 "TARGET_USE_FANCY_MATH_387
17054 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17055 && flag_unsafe_math_optimizations"
17060 for (i=2; i<12; i++)
17061 operands[i] = gen_reg_rtx (XFmode);
17062 temp = standard_80387_constant_rtx (5); /* fldl2e */
17063 emit_move_insn (operands[3], temp);
17064 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
17067 (define_expand "expxf2"
17068 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17070 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17071 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17072 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17073 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17074 (parallel [(set (match_operand:XF 0 "register_operand" "")
17075 (unspec:XF [(match_dup 8) (match_dup 4)]
17076 UNSPEC_FSCALE_FRACT))
17078 (unspec:XF [(match_dup 8) (match_dup 4)]
17079 UNSPEC_FSCALE_EXP))])]
17080 "TARGET_USE_FANCY_MATH_387
17081 && flag_unsafe_math_optimizations"
17086 for (i=2; i<10; i++)
17087 operands[i] = gen_reg_rtx (XFmode);
17088 temp = standard_80387_constant_rtx (5); /* fldl2e */
17089 emit_move_insn (operands[2], temp);
17090 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17093 (define_expand "exp10sf2"
17094 [(set (match_dup 2)
17095 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17096 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17097 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17098 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17099 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17100 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17101 (parallel [(set (match_dup 10)
17102 (unspec:XF [(match_dup 9) (match_dup 5)]
17103 UNSPEC_FSCALE_FRACT))
17104 (set (match_dup 11)
17105 (unspec:XF [(match_dup 9) (match_dup 5)]
17106 UNSPEC_FSCALE_EXP))])
17107 (set (match_operand:SF 0 "register_operand" "")
17108 (float_truncate:SF (match_dup 10)))]
17109 "TARGET_USE_FANCY_MATH_387
17110 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17111 && flag_unsafe_math_optimizations"
17116 for (i=2; i<12; i++)
17117 operands[i] = gen_reg_rtx (XFmode);
17118 temp = standard_80387_constant_rtx (6); /* fldl2t */
17119 emit_move_insn (operands[3], temp);
17120 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
17123 (define_expand "exp10df2"
17124 [(set (match_dup 2)
17125 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17126 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17127 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17128 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17129 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17130 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17131 (parallel [(set (match_dup 10)
17132 (unspec:XF [(match_dup 9) (match_dup 5)]
17133 UNSPEC_FSCALE_FRACT))
17134 (set (match_dup 11)
17135 (unspec:XF [(match_dup 9) (match_dup 5)]
17136 UNSPEC_FSCALE_EXP))])
17137 (set (match_operand:DF 0 "register_operand" "")
17138 (float_truncate:DF (match_dup 10)))]
17139 "TARGET_USE_FANCY_MATH_387
17140 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17141 && flag_unsafe_math_optimizations"
17146 for (i=2; i<12; i++)
17147 operands[i] = gen_reg_rtx (XFmode);
17148 temp = standard_80387_constant_rtx (6); /* fldl2t */
17149 emit_move_insn (operands[3], temp);
17150 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
17153 (define_expand "exp10xf2"
17154 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17156 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17157 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17158 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17159 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17160 (parallel [(set (match_operand:XF 0 "register_operand" "")
17161 (unspec:XF [(match_dup 8) (match_dup 4)]
17162 UNSPEC_FSCALE_FRACT))
17164 (unspec:XF [(match_dup 8) (match_dup 4)]
17165 UNSPEC_FSCALE_EXP))])]
17166 "TARGET_USE_FANCY_MATH_387
17167 && flag_unsafe_math_optimizations"
17172 for (i=2; i<10; i++)
17173 operands[i] = gen_reg_rtx (XFmode);
17174 temp = standard_80387_constant_rtx (6); /* fldl2t */
17175 emit_move_insn (operands[2], temp);
17176 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17179 (define_expand "exp2sf2"
17180 [(set (match_dup 2)
17181 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17182 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17183 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17184 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17185 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17186 (parallel [(set (match_dup 8)
17187 (unspec:XF [(match_dup 7) (match_dup 3)]
17188 UNSPEC_FSCALE_FRACT))
17190 (unspec:XF [(match_dup 7) (match_dup 3)]
17191 UNSPEC_FSCALE_EXP))])
17192 (set (match_operand:SF 0 "register_operand" "")
17193 (float_truncate:SF (match_dup 8)))]
17194 "TARGET_USE_FANCY_MATH_387
17195 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17196 && flag_unsafe_math_optimizations"
17200 for (i=2; i<10; i++)
17201 operands[i] = gen_reg_rtx (XFmode);
17202 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
17205 (define_expand "exp2df2"
17206 [(set (match_dup 2)
17207 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17208 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17209 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17210 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17211 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17212 (parallel [(set (match_dup 8)
17213 (unspec:XF [(match_dup 7) (match_dup 3)]
17214 UNSPEC_FSCALE_FRACT))
17216 (unspec:XF [(match_dup 7) (match_dup 3)]
17217 UNSPEC_FSCALE_EXP))])
17218 (set (match_operand:DF 0 "register_operand" "")
17219 (float_truncate:DF (match_dup 8)))]
17220 "TARGET_USE_FANCY_MATH_387
17221 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17222 && flag_unsafe_math_optimizations"
17226 for (i=2; i<10; i++)
17227 operands[i] = gen_reg_rtx (XFmode);
17228 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
17231 (define_expand "exp2xf2"
17232 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
17233 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17234 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17235 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17236 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17237 (parallel [(set (match_operand:XF 0 "register_operand" "")
17238 (unspec:XF [(match_dup 7) (match_dup 3)]
17239 UNSPEC_FSCALE_FRACT))
17241 (unspec:XF [(match_dup 7) (match_dup 3)]
17242 UNSPEC_FSCALE_EXP))])]
17243 "TARGET_USE_FANCY_MATH_387
17244 && flag_unsafe_math_optimizations"
17248 for (i=2; i<9; i++)
17249 operands[i] = gen_reg_rtx (XFmode);
17250 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
17253 (define_expand "expm1df2"
17254 [(set (match_dup 2)
17255 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17256 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17257 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17258 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17259 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17260 (parallel [(set (match_dup 8)
17261 (unspec:XF [(match_dup 7) (match_dup 5)]
17262 UNSPEC_FSCALE_FRACT))
17264 (unspec:XF [(match_dup 7) (match_dup 5)]
17265 UNSPEC_FSCALE_EXP))])
17266 (parallel [(set (match_dup 11)
17267 (unspec:XF [(match_dup 10) (match_dup 9)]
17268 UNSPEC_FSCALE_FRACT))
17269 (set (match_dup 12)
17270 (unspec:XF [(match_dup 10) (match_dup 9)]
17271 UNSPEC_FSCALE_EXP))])
17272 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17273 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17274 (set (match_operand:DF 0 "register_operand" "")
17275 (float_truncate:DF (match_dup 14)))]
17276 "TARGET_USE_FANCY_MATH_387
17277 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17278 && flag_unsafe_math_optimizations"
17283 for (i=2; i<15; i++)
17284 operands[i] = gen_reg_rtx (XFmode);
17285 temp = standard_80387_constant_rtx (5); /* fldl2e */
17286 emit_move_insn (operands[3], temp);
17287 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17290 (define_expand "expm1sf2"
17291 [(set (match_dup 2)
17292 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17293 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17294 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17295 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17296 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17297 (parallel [(set (match_dup 8)
17298 (unspec:XF [(match_dup 7) (match_dup 5)]
17299 UNSPEC_FSCALE_FRACT))
17301 (unspec:XF [(match_dup 7) (match_dup 5)]
17302 UNSPEC_FSCALE_EXP))])
17303 (parallel [(set (match_dup 11)
17304 (unspec:XF [(match_dup 10) (match_dup 9)]
17305 UNSPEC_FSCALE_FRACT))
17306 (set (match_dup 12)
17307 (unspec:XF [(match_dup 10) (match_dup 9)]
17308 UNSPEC_FSCALE_EXP))])
17309 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17310 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17311 (set (match_operand:SF 0 "register_operand" "")
17312 (float_truncate:SF (match_dup 14)))]
17313 "TARGET_USE_FANCY_MATH_387
17314 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17315 && flag_unsafe_math_optimizations"
17320 for (i=2; i<15; i++)
17321 operands[i] = gen_reg_rtx (XFmode);
17322 temp = standard_80387_constant_rtx (5); /* fldl2e */
17323 emit_move_insn (operands[3], temp);
17324 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17327 (define_expand "expm1xf2"
17328 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17330 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17331 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17332 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17333 (parallel [(set (match_dup 7)
17334 (unspec:XF [(match_dup 6) (match_dup 4)]
17335 UNSPEC_FSCALE_FRACT))
17337 (unspec:XF [(match_dup 6) (match_dup 4)]
17338 UNSPEC_FSCALE_EXP))])
17339 (parallel [(set (match_dup 10)
17340 (unspec:XF [(match_dup 9) (match_dup 8)]
17341 UNSPEC_FSCALE_FRACT))
17342 (set (match_dup 11)
17343 (unspec:XF [(match_dup 9) (match_dup 8)]
17344 UNSPEC_FSCALE_EXP))])
17345 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17346 (set (match_operand:XF 0 "register_operand" "")
17347 (plus:XF (match_dup 12) (match_dup 7)))]
17348 "TARGET_USE_FANCY_MATH_387
17349 && flag_unsafe_math_optimizations"
17354 for (i=2; i<13; i++)
17355 operands[i] = gen_reg_rtx (XFmode);
17356 temp = standard_80387_constant_rtx (5); /* fldl2e */
17357 emit_move_insn (operands[2], temp);
17358 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17361 (define_expand "ldexpdf3"
17362 [(set (match_dup 3)
17363 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17365 (float:XF (match_operand:SI 2 "register_operand" "")))
17366 (parallel [(set (match_dup 5)
17367 (unspec:XF [(match_dup 3) (match_dup 4)]
17368 UNSPEC_FSCALE_FRACT))
17370 (unspec:XF [(match_dup 3) (match_dup 4)]
17371 UNSPEC_FSCALE_EXP))])
17372 (set (match_operand:DF 0 "register_operand" "")
17373 (float_truncate:DF (match_dup 5)))]
17374 "TARGET_USE_FANCY_MATH_387
17375 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17376 && flag_unsafe_math_optimizations"
17380 for (i=3; i<7; i++)
17381 operands[i] = gen_reg_rtx (XFmode);
17384 (define_expand "ldexpsf3"
17385 [(set (match_dup 3)
17386 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17388 (float:XF (match_operand:SI 2 "register_operand" "")))
17389 (parallel [(set (match_dup 5)
17390 (unspec:XF [(match_dup 3) (match_dup 4)]
17391 UNSPEC_FSCALE_FRACT))
17393 (unspec:XF [(match_dup 3) (match_dup 4)]
17394 UNSPEC_FSCALE_EXP))])
17395 (set (match_operand:SF 0 "register_operand" "")
17396 (float_truncate:SF (match_dup 5)))]
17397 "TARGET_USE_FANCY_MATH_387
17398 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17399 && flag_unsafe_math_optimizations"
17403 for (i=3; i<7; i++)
17404 operands[i] = gen_reg_rtx (XFmode);
17407 (define_expand "ldexpxf3"
17408 [(set (match_dup 3)
17409 (float:XF (match_operand:SI 2 "register_operand" "")))
17410 (parallel [(set (match_operand:XF 0 " register_operand" "")
17411 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17413 UNSPEC_FSCALE_FRACT))
17415 (unspec:XF [(match_dup 1) (match_dup 3)]
17416 UNSPEC_FSCALE_EXP))])]
17417 "TARGET_USE_FANCY_MATH_387
17418 && flag_unsafe_math_optimizations"
17422 for (i=3; i<5; i++)
17423 operands[i] = gen_reg_rtx (XFmode);
17427 (define_insn "frndintxf2"
17428 [(set (match_operand:XF 0 "register_operand" "=f")
17429 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17431 "TARGET_USE_FANCY_MATH_387
17432 && flag_unsafe_math_optimizations"
17434 [(set_attr "type" "fpspc")
17435 (set_attr "mode" "XF")])
17437 (define_expand "rintdf2"
17438 [(use (match_operand:DF 0 "register_operand" ""))
17439 (use (match_operand:DF 1 "register_operand" ""))]
17440 "TARGET_USE_FANCY_MATH_387
17441 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17442 && flag_unsafe_math_optimizations"
17444 rtx op0 = gen_reg_rtx (XFmode);
17445 rtx op1 = gen_reg_rtx (XFmode);
17447 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17448 emit_insn (gen_frndintxf2 (op0, op1));
17450 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17454 (define_expand "rintsf2"
17455 [(use (match_operand:SF 0 "register_operand" ""))
17456 (use (match_operand:SF 1 "register_operand" ""))]
17457 "TARGET_USE_FANCY_MATH_387
17458 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17459 && flag_unsafe_math_optimizations"
17461 rtx op0 = gen_reg_rtx (XFmode);
17462 rtx op1 = gen_reg_rtx (XFmode);
17464 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17465 emit_insn (gen_frndintxf2 (op0, op1));
17467 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17471 (define_expand "rintxf2"
17472 [(use (match_operand:XF 0 "register_operand" ""))
17473 (use (match_operand:XF 1 "register_operand" ""))]
17474 "TARGET_USE_FANCY_MATH_387
17475 && flag_unsafe_math_optimizations"
17477 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17481 (define_insn_and_split "*fistdi2_1"
17482 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17483 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17485 "TARGET_USE_FANCY_MATH_387
17486 && flag_unsafe_math_optimizations
17487 && !(reload_completed || reload_in_progress)"
17492 if (memory_operand (operands[0], VOIDmode))
17493 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17496 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17497 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17502 [(set_attr "type" "fpspc")
17503 (set_attr "mode" "DI")])
17505 (define_insn "fistdi2"
17506 [(set (match_operand:DI 0 "memory_operand" "=m")
17507 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17509 (clobber (match_scratch:XF 2 "=&1f"))]
17510 "TARGET_USE_FANCY_MATH_387
17511 && flag_unsafe_math_optimizations"
17512 "* return output_fix_trunc (insn, operands, 0);"
17513 [(set_attr "type" "fpspc")
17514 (set_attr "mode" "DI")])
17516 (define_insn "fistdi2_with_temp"
17517 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17518 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17520 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17521 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17522 "TARGET_USE_FANCY_MATH_387
17523 && flag_unsafe_math_optimizations"
17525 [(set_attr "type" "fpspc")
17526 (set_attr "mode" "DI")])
17529 [(set (match_operand:DI 0 "register_operand" "")
17530 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17532 (clobber (match_operand:DI 2 "memory_operand" ""))
17533 (clobber (match_scratch 3 ""))]
17535 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17536 (clobber (match_dup 3))])
17537 (set (match_dup 0) (match_dup 2))]
17541 [(set (match_operand:DI 0 "memory_operand" "")
17542 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17544 (clobber (match_operand:DI 2 "memory_operand" ""))
17545 (clobber (match_scratch 3 ""))]
17547 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17548 (clobber (match_dup 3))])]
17551 (define_insn_and_split "*fist<mode>2_1"
17552 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17553 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17555 "TARGET_USE_FANCY_MATH_387
17556 && flag_unsafe_math_optimizations
17557 && !(reload_completed || reload_in_progress)"
17562 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17563 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17567 [(set_attr "type" "fpspc")
17568 (set_attr "mode" "<MODE>")])
17570 (define_insn "fist<mode>2"
17571 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17572 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17574 "TARGET_USE_FANCY_MATH_387
17575 && flag_unsafe_math_optimizations"
17576 "* return output_fix_trunc (insn, operands, 0);"
17577 [(set_attr "type" "fpspc")
17578 (set_attr "mode" "<MODE>")])
17580 (define_insn "fist<mode>2_with_temp"
17581 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17582 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17584 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17585 "TARGET_USE_FANCY_MATH_387
17586 && flag_unsafe_math_optimizations"
17588 [(set_attr "type" "fpspc")
17589 (set_attr "mode" "<MODE>")])
17592 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17593 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17595 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17597 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17599 (set (match_dup 0) (match_dup 2))]
17603 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17604 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17606 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17608 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17612 (define_expand "lrint<mode>2"
17613 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17614 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17616 "TARGET_USE_FANCY_MATH_387
17617 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17618 && flag_unsafe_math_optimizations"
17621 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17622 (define_insn_and_split "frndintxf2_floor"
17623 [(set (match_operand:XF 0 "register_operand" "=f")
17624 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17625 UNSPEC_FRNDINT_FLOOR))
17626 (clobber (reg:CC FLAGS_REG))]
17627 "TARGET_USE_FANCY_MATH_387
17628 && flag_unsafe_math_optimizations
17629 && !(reload_completed || reload_in_progress)"
17634 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17636 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17637 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17639 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17640 operands[2], operands[3]));
17643 [(set_attr "type" "frndint")
17644 (set_attr "i387_cw" "floor")
17645 (set_attr "mode" "XF")])
17647 (define_insn "frndintxf2_floor_i387"
17648 [(set (match_operand:XF 0 "register_operand" "=f")
17649 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17650 UNSPEC_FRNDINT_FLOOR))
17651 (use (match_operand:HI 2 "memory_operand" "m"))
17652 (use (match_operand:HI 3 "memory_operand" "m"))]
17653 "TARGET_USE_FANCY_MATH_387
17654 && flag_unsafe_math_optimizations"
17655 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17656 [(set_attr "type" "frndint")
17657 (set_attr "i387_cw" "floor")
17658 (set_attr "mode" "XF")])
17660 (define_expand "floorxf2"
17661 [(use (match_operand:XF 0 "register_operand" ""))
17662 (use (match_operand:XF 1 "register_operand" ""))]
17663 "TARGET_USE_FANCY_MATH_387
17664 && flag_unsafe_math_optimizations"
17666 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17670 (define_expand "floordf2"
17671 [(use (match_operand:DF 0 "register_operand" ""))
17672 (use (match_operand:DF 1 "register_operand" ""))]
17673 "TARGET_USE_FANCY_MATH_387
17674 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17675 && flag_unsafe_math_optimizations"
17677 rtx op0 = gen_reg_rtx (XFmode);
17678 rtx op1 = gen_reg_rtx (XFmode);
17680 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17681 emit_insn (gen_frndintxf2_floor (op0, op1));
17683 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17687 (define_expand "floorsf2"
17688 [(use (match_operand:SF 0 "register_operand" ""))
17689 (use (match_operand:SF 1 "register_operand" ""))]
17690 "TARGET_USE_FANCY_MATH_387
17691 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17692 && flag_unsafe_math_optimizations"
17694 rtx op0 = gen_reg_rtx (XFmode);
17695 rtx op1 = gen_reg_rtx (XFmode);
17697 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17698 emit_insn (gen_frndintxf2_floor (op0, op1));
17700 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17704 (define_insn_and_split "*fist<mode>2_floor_1"
17705 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17706 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17707 UNSPEC_FIST_FLOOR))
17708 (clobber (reg:CC FLAGS_REG))]
17709 "TARGET_USE_FANCY_MATH_387
17710 && flag_unsafe_math_optimizations
17711 && !(reload_completed || reload_in_progress)"
17716 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17718 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17719 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17720 if (memory_operand (operands[0], VOIDmode))
17721 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17722 operands[2], operands[3]));
17725 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17726 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17727 operands[2], operands[3],
17732 [(set_attr "type" "fistp")
17733 (set_attr "i387_cw" "floor")
17734 (set_attr "mode" "<MODE>")])
17736 (define_insn "fistdi2_floor"
17737 [(set (match_operand:DI 0 "memory_operand" "=m")
17738 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17739 UNSPEC_FIST_FLOOR))
17740 (use (match_operand:HI 2 "memory_operand" "m"))
17741 (use (match_operand:HI 3 "memory_operand" "m"))
17742 (clobber (match_scratch:XF 4 "=&1f"))]
17743 "TARGET_USE_FANCY_MATH_387
17744 && flag_unsafe_math_optimizations"
17745 "* return output_fix_trunc (insn, operands, 0);"
17746 [(set_attr "type" "fistp")
17747 (set_attr "i387_cw" "floor")
17748 (set_attr "mode" "DI")])
17750 (define_insn "fistdi2_floor_with_temp"
17751 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17752 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17753 UNSPEC_FIST_FLOOR))
17754 (use (match_operand:HI 2 "memory_operand" "m,m"))
17755 (use (match_operand:HI 3 "memory_operand" "m,m"))
17756 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17757 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17758 "TARGET_USE_FANCY_MATH_387
17759 && flag_unsafe_math_optimizations"
17761 [(set_attr "type" "fistp")
17762 (set_attr "i387_cw" "floor")
17763 (set_attr "mode" "DI")])
17766 [(set (match_operand:DI 0 "register_operand" "")
17767 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17768 UNSPEC_FIST_FLOOR))
17769 (use (match_operand:HI 2 "memory_operand" ""))
17770 (use (match_operand:HI 3 "memory_operand" ""))
17771 (clobber (match_operand:DI 4 "memory_operand" ""))
17772 (clobber (match_scratch 5 ""))]
17774 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17775 (use (match_dup 2))
17776 (use (match_dup 3))
17777 (clobber (match_dup 5))])
17778 (set (match_dup 0) (match_dup 4))]
17782 [(set (match_operand:DI 0 "memory_operand" "")
17783 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17784 UNSPEC_FIST_FLOOR))
17785 (use (match_operand:HI 2 "memory_operand" ""))
17786 (use (match_operand:HI 3 "memory_operand" ""))
17787 (clobber (match_operand:DI 4 "memory_operand" ""))
17788 (clobber (match_scratch 5 ""))]
17790 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17791 (use (match_dup 2))
17792 (use (match_dup 3))
17793 (clobber (match_dup 5))])]
17796 (define_insn "fist<mode>2_floor"
17797 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17798 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17799 UNSPEC_FIST_FLOOR))
17800 (use (match_operand:HI 2 "memory_operand" "m"))
17801 (use (match_operand:HI 3 "memory_operand" "m"))]
17802 "TARGET_USE_FANCY_MATH_387
17803 && flag_unsafe_math_optimizations"
17804 "* return output_fix_trunc (insn, operands, 0);"
17805 [(set_attr "type" "fistp")
17806 (set_attr "i387_cw" "floor")
17807 (set_attr "mode" "<MODE>")])
17809 (define_insn "fist<mode>2_floor_with_temp"
17810 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17811 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17812 UNSPEC_FIST_FLOOR))
17813 (use (match_operand:HI 2 "memory_operand" "m,m"))
17814 (use (match_operand:HI 3 "memory_operand" "m,m"))
17815 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17816 "TARGET_USE_FANCY_MATH_387
17817 && flag_unsafe_math_optimizations"
17819 [(set_attr "type" "fistp")
17820 (set_attr "i387_cw" "floor")
17821 (set_attr "mode" "<MODE>")])
17824 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17825 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17826 UNSPEC_FIST_FLOOR))
17827 (use (match_operand:HI 2 "memory_operand" ""))
17828 (use (match_operand:HI 3 "memory_operand" ""))
17829 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17831 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17832 UNSPEC_FIST_FLOOR))
17833 (use (match_dup 2))
17834 (use (match_dup 3))])
17835 (set (match_dup 0) (match_dup 4))]
17839 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17840 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17841 UNSPEC_FIST_FLOOR))
17842 (use (match_operand:HI 2 "memory_operand" ""))
17843 (use (match_operand:HI 3 "memory_operand" ""))
17844 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17846 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17847 UNSPEC_FIST_FLOOR))
17848 (use (match_dup 2))
17849 (use (match_dup 3))])]
17852 (define_expand "lfloor<mode>2"
17853 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17854 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17855 UNSPEC_FIST_FLOOR))
17856 (clobber (reg:CC FLAGS_REG))])]
17857 "TARGET_USE_FANCY_MATH_387
17858 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17859 && flag_unsafe_math_optimizations"
17862 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17863 (define_insn_and_split "frndintxf2_ceil"
17864 [(set (match_operand:XF 0 "register_operand" "=f")
17865 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17866 UNSPEC_FRNDINT_CEIL))
17867 (clobber (reg:CC FLAGS_REG))]
17868 "TARGET_USE_FANCY_MATH_387
17869 && flag_unsafe_math_optimizations
17870 && !(reload_completed || reload_in_progress)"
17875 ix86_optimize_mode_switching[I387_CEIL] = 1;
17877 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17878 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17880 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17881 operands[2], operands[3]));
17884 [(set_attr "type" "frndint")
17885 (set_attr "i387_cw" "ceil")
17886 (set_attr "mode" "XF")])
17888 (define_insn "frndintxf2_ceil_i387"
17889 [(set (match_operand:XF 0 "register_operand" "=f")
17890 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17891 UNSPEC_FRNDINT_CEIL))
17892 (use (match_operand:HI 2 "memory_operand" "m"))
17893 (use (match_operand:HI 3 "memory_operand" "m"))]
17894 "TARGET_USE_FANCY_MATH_387
17895 && flag_unsafe_math_optimizations"
17896 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17897 [(set_attr "type" "frndint")
17898 (set_attr "i387_cw" "ceil")
17899 (set_attr "mode" "XF")])
17901 (define_expand "ceilxf2"
17902 [(use (match_operand:XF 0 "register_operand" ""))
17903 (use (match_operand:XF 1 "register_operand" ""))]
17904 "TARGET_USE_FANCY_MATH_387
17905 && flag_unsafe_math_optimizations"
17907 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17911 (define_expand "ceildf2"
17912 [(use (match_operand:DF 0 "register_operand" ""))
17913 (use (match_operand:DF 1 "register_operand" ""))]
17914 "TARGET_USE_FANCY_MATH_387
17915 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17916 && flag_unsafe_math_optimizations"
17918 rtx op0 = gen_reg_rtx (XFmode);
17919 rtx op1 = gen_reg_rtx (XFmode);
17921 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17922 emit_insn (gen_frndintxf2_ceil (op0, op1));
17924 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17928 (define_expand "ceilsf2"
17929 [(use (match_operand:SF 0 "register_operand" ""))
17930 (use (match_operand:SF 1 "register_operand" ""))]
17931 "TARGET_USE_FANCY_MATH_387
17932 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17933 && flag_unsafe_math_optimizations"
17935 rtx op0 = gen_reg_rtx (XFmode);
17936 rtx op1 = gen_reg_rtx (XFmode);
17938 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17939 emit_insn (gen_frndintxf2_ceil (op0, op1));
17941 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17945 (define_insn_and_split "*fist<mode>2_ceil_1"
17946 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17947 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17949 (clobber (reg:CC FLAGS_REG))]
17950 "TARGET_USE_FANCY_MATH_387
17951 && flag_unsafe_math_optimizations
17952 && !(reload_completed || reload_in_progress)"
17957 ix86_optimize_mode_switching[I387_CEIL] = 1;
17959 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17960 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17961 if (memory_operand (operands[0], VOIDmode))
17962 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17963 operands[2], operands[3]));
17966 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17967 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17968 operands[2], operands[3],
17973 [(set_attr "type" "fistp")
17974 (set_attr "i387_cw" "ceil")
17975 (set_attr "mode" "<MODE>")])
17977 (define_insn "fistdi2_ceil"
17978 [(set (match_operand:DI 0 "memory_operand" "=m")
17979 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17981 (use (match_operand:HI 2 "memory_operand" "m"))
17982 (use (match_operand:HI 3 "memory_operand" "m"))
17983 (clobber (match_scratch:XF 4 "=&1f"))]
17984 "TARGET_USE_FANCY_MATH_387
17985 && flag_unsafe_math_optimizations"
17986 "* return output_fix_trunc (insn, operands, 0);"
17987 [(set_attr "type" "fistp")
17988 (set_attr "i387_cw" "ceil")
17989 (set_attr "mode" "DI")])
17991 (define_insn "fistdi2_ceil_with_temp"
17992 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17993 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17995 (use (match_operand:HI 2 "memory_operand" "m,m"))
17996 (use (match_operand:HI 3 "memory_operand" "m,m"))
17997 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17998 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17999 "TARGET_USE_FANCY_MATH_387
18000 && flag_unsafe_math_optimizations"
18002 [(set_attr "type" "fistp")
18003 (set_attr "i387_cw" "ceil")
18004 (set_attr "mode" "DI")])
18007 [(set (match_operand:DI 0 "register_operand" "")
18008 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18010 (use (match_operand:HI 2 "memory_operand" ""))
18011 (use (match_operand:HI 3 "memory_operand" ""))
18012 (clobber (match_operand:DI 4 "memory_operand" ""))
18013 (clobber (match_scratch 5 ""))]
18015 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18016 (use (match_dup 2))
18017 (use (match_dup 3))
18018 (clobber (match_dup 5))])
18019 (set (match_dup 0) (match_dup 4))]
18023 [(set (match_operand:DI 0 "memory_operand" "")
18024 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18026 (use (match_operand:HI 2 "memory_operand" ""))
18027 (use (match_operand:HI 3 "memory_operand" ""))
18028 (clobber (match_operand:DI 4 "memory_operand" ""))
18029 (clobber (match_scratch 5 ""))]
18031 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18032 (use (match_dup 2))
18033 (use (match_dup 3))
18034 (clobber (match_dup 5))])]
18037 (define_insn "fist<mode>2_ceil"
18038 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18039 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18041 (use (match_operand:HI 2 "memory_operand" "m"))
18042 (use (match_operand:HI 3 "memory_operand" "m"))]
18043 "TARGET_USE_FANCY_MATH_387
18044 && flag_unsafe_math_optimizations"
18045 "* return output_fix_trunc (insn, operands, 0);"
18046 [(set_attr "type" "fistp")
18047 (set_attr "i387_cw" "ceil")
18048 (set_attr "mode" "<MODE>")])
18050 (define_insn "fist<mode>2_ceil_with_temp"
18051 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18052 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18054 (use (match_operand:HI 2 "memory_operand" "m,m"))
18055 (use (match_operand:HI 3 "memory_operand" "m,m"))
18056 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18057 "TARGET_USE_FANCY_MATH_387
18058 && flag_unsafe_math_optimizations"
18060 [(set_attr "type" "fistp")
18061 (set_attr "i387_cw" "ceil")
18062 (set_attr "mode" "<MODE>")])
18065 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18066 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18068 (use (match_operand:HI 2 "memory_operand" ""))
18069 (use (match_operand:HI 3 "memory_operand" ""))
18070 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18072 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18074 (use (match_dup 2))
18075 (use (match_dup 3))])
18076 (set (match_dup 0) (match_dup 4))]
18080 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18081 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18083 (use (match_operand:HI 2 "memory_operand" ""))
18084 (use (match_operand:HI 3 "memory_operand" ""))
18085 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18087 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18089 (use (match_dup 2))
18090 (use (match_dup 3))])]
18093 (define_expand "lceil<mode>2"
18094 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18095 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18097 (clobber (reg:CC FLAGS_REG))])]
18098 "TARGET_USE_FANCY_MATH_387
18099 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18100 && flag_unsafe_math_optimizations"
18103 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18104 (define_insn_and_split "frndintxf2_trunc"
18105 [(set (match_operand:XF 0 "register_operand" "=f")
18106 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18107 UNSPEC_FRNDINT_TRUNC))
18108 (clobber (reg:CC FLAGS_REG))]
18109 "TARGET_USE_FANCY_MATH_387
18110 && flag_unsafe_math_optimizations
18111 && !(reload_completed || reload_in_progress)"
18116 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18118 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18119 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18121 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18122 operands[2], operands[3]));
18125 [(set_attr "type" "frndint")
18126 (set_attr "i387_cw" "trunc")
18127 (set_attr "mode" "XF")])
18129 (define_insn "frndintxf2_trunc_i387"
18130 [(set (match_operand:XF 0 "register_operand" "=f")
18131 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18132 UNSPEC_FRNDINT_TRUNC))
18133 (use (match_operand:HI 2 "memory_operand" "m"))
18134 (use (match_operand:HI 3 "memory_operand" "m"))]
18135 "TARGET_USE_FANCY_MATH_387
18136 && flag_unsafe_math_optimizations"
18137 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18138 [(set_attr "type" "frndint")
18139 (set_attr "i387_cw" "trunc")
18140 (set_attr "mode" "XF")])
18142 (define_expand "btruncxf2"
18143 [(use (match_operand:XF 0 "register_operand" ""))
18144 (use (match_operand:XF 1 "register_operand" ""))]
18145 "TARGET_USE_FANCY_MATH_387
18146 && flag_unsafe_math_optimizations"
18148 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18152 (define_expand "btruncdf2"
18153 [(use (match_operand:DF 0 "register_operand" ""))
18154 (use (match_operand:DF 1 "register_operand" ""))]
18155 "TARGET_USE_FANCY_MATH_387
18156 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18157 && flag_unsafe_math_optimizations"
18159 rtx op0 = gen_reg_rtx (XFmode);
18160 rtx op1 = gen_reg_rtx (XFmode);
18162 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18163 emit_insn (gen_frndintxf2_trunc (op0, op1));
18165 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18169 (define_expand "btruncsf2"
18170 [(use (match_operand:SF 0 "register_operand" ""))
18171 (use (match_operand:SF 1 "register_operand" ""))]
18172 "TARGET_USE_FANCY_MATH_387
18173 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18174 && flag_unsafe_math_optimizations"
18176 rtx op0 = gen_reg_rtx (XFmode);
18177 rtx op1 = gen_reg_rtx (XFmode);
18179 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18180 emit_insn (gen_frndintxf2_trunc (op0, op1));
18182 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18186 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18187 (define_insn_and_split "frndintxf2_mask_pm"
18188 [(set (match_operand:XF 0 "register_operand" "=f")
18189 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18190 UNSPEC_FRNDINT_MASK_PM))
18191 (clobber (reg:CC FLAGS_REG))]
18192 "TARGET_USE_FANCY_MATH_387
18193 && flag_unsafe_math_optimizations
18194 && !(reload_completed || reload_in_progress)"
18199 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18201 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18202 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18204 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18205 operands[2], operands[3]));
18208 [(set_attr "type" "frndint")
18209 (set_attr "i387_cw" "mask_pm")
18210 (set_attr "mode" "XF")])
18212 (define_insn "frndintxf2_mask_pm_i387"
18213 [(set (match_operand:XF 0 "register_operand" "=f")
18214 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18215 UNSPEC_FRNDINT_MASK_PM))
18216 (use (match_operand:HI 2 "memory_operand" "m"))
18217 (use (match_operand:HI 3 "memory_operand" "m"))]
18218 "TARGET_USE_FANCY_MATH_387
18219 && flag_unsafe_math_optimizations"
18220 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18221 [(set_attr "type" "frndint")
18222 (set_attr "i387_cw" "mask_pm")
18223 (set_attr "mode" "XF")])
18225 (define_expand "nearbyintxf2"
18226 [(use (match_operand:XF 0 "register_operand" ""))
18227 (use (match_operand:XF 1 "register_operand" ""))]
18228 "TARGET_USE_FANCY_MATH_387
18229 && flag_unsafe_math_optimizations"
18231 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18236 (define_expand "nearbyintdf2"
18237 [(use (match_operand:DF 0 "register_operand" ""))
18238 (use (match_operand:DF 1 "register_operand" ""))]
18239 "TARGET_USE_FANCY_MATH_387
18240 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18241 && flag_unsafe_math_optimizations"
18243 rtx op0 = gen_reg_rtx (XFmode);
18244 rtx op1 = gen_reg_rtx (XFmode);
18246 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18247 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18249 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18253 (define_expand "nearbyintsf2"
18254 [(use (match_operand:SF 0 "register_operand" ""))
18255 (use (match_operand:SF 1 "register_operand" ""))]
18256 "TARGET_USE_FANCY_MATH_387
18257 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18258 && flag_unsafe_math_optimizations"
18260 rtx op0 = gen_reg_rtx (XFmode);
18261 rtx op1 = gen_reg_rtx (XFmode);
18263 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18264 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18266 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18271 ;; Block operation instructions
18274 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18277 [(set_attr "type" "cld")])
18279 (define_expand "movmemsi"
18280 [(use (match_operand:BLK 0 "memory_operand" ""))
18281 (use (match_operand:BLK 1 "memory_operand" ""))
18282 (use (match_operand:SI 2 "nonmemory_operand" ""))
18283 (use (match_operand:SI 3 "const_int_operand" ""))]
18284 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18286 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18292 (define_expand "movmemdi"
18293 [(use (match_operand:BLK 0 "memory_operand" ""))
18294 (use (match_operand:BLK 1 "memory_operand" ""))
18295 (use (match_operand:DI 2 "nonmemory_operand" ""))
18296 (use (match_operand:DI 3 "const_int_operand" ""))]
18299 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18305 ;; Most CPUs don't like single string operations
18306 ;; Handle this case here to simplify previous expander.
18308 (define_expand "strmov"
18309 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18310 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18311 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18312 (clobber (reg:CC FLAGS_REG))])
18313 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18314 (clobber (reg:CC FLAGS_REG))])]
18317 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18319 /* If .md ever supports :P for Pmode, these can be directly
18320 in the pattern above. */
18321 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18322 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18324 if (TARGET_SINGLE_STRINGOP || optimize_size)
18326 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18327 operands[2], operands[3],
18328 operands[5], operands[6]));
18332 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18335 (define_expand "strmov_singleop"
18336 [(parallel [(set (match_operand 1 "memory_operand" "")
18337 (match_operand 3 "memory_operand" ""))
18338 (set (match_operand 0 "register_operand" "")
18339 (match_operand 4 "" ""))
18340 (set (match_operand 2 "register_operand" "")
18341 (match_operand 5 "" ""))
18342 (use (reg:SI DIRFLAG_REG))])]
18343 "TARGET_SINGLE_STRINGOP || optimize_size"
18346 (define_insn "*strmovdi_rex_1"
18347 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18348 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18349 (set (match_operand:DI 0 "register_operand" "=D")
18350 (plus:DI (match_dup 2)
18352 (set (match_operand:DI 1 "register_operand" "=S")
18353 (plus:DI (match_dup 3)
18355 (use (reg:SI DIRFLAG_REG))]
18356 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18358 [(set_attr "type" "str")
18359 (set_attr "mode" "DI")
18360 (set_attr "memory" "both")])
18362 (define_insn "*strmovsi_1"
18363 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18364 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18365 (set (match_operand:SI 0 "register_operand" "=D")
18366 (plus:SI (match_dup 2)
18368 (set (match_operand:SI 1 "register_operand" "=S")
18369 (plus:SI (match_dup 3)
18371 (use (reg:SI DIRFLAG_REG))]
18372 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18374 [(set_attr "type" "str")
18375 (set_attr "mode" "SI")
18376 (set_attr "memory" "both")])
18378 (define_insn "*strmovsi_rex_1"
18379 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18380 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18381 (set (match_operand:DI 0 "register_operand" "=D")
18382 (plus:DI (match_dup 2)
18384 (set (match_operand:DI 1 "register_operand" "=S")
18385 (plus:DI (match_dup 3)
18387 (use (reg:SI DIRFLAG_REG))]
18388 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18390 [(set_attr "type" "str")
18391 (set_attr "mode" "SI")
18392 (set_attr "memory" "both")])
18394 (define_insn "*strmovhi_1"
18395 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18396 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18397 (set (match_operand:SI 0 "register_operand" "=D")
18398 (plus:SI (match_dup 2)
18400 (set (match_operand:SI 1 "register_operand" "=S")
18401 (plus:SI (match_dup 3)
18403 (use (reg:SI DIRFLAG_REG))]
18404 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18406 [(set_attr "type" "str")
18407 (set_attr "memory" "both")
18408 (set_attr "mode" "HI")])
18410 (define_insn "*strmovhi_rex_1"
18411 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18412 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18413 (set (match_operand:DI 0 "register_operand" "=D")
18414 (plus:DI (match_dup 2)
18416 (set (match_operand:DI 1 "register_operand" "=S")
18417 (plus:DI (match_dup 3)
18419 (use (reg:SI DIRFLAG_REG))]
18420 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18422 [(set_attr "type" "str")
18423 (set_attr "memory" "both")
18424 (set_attr "mode" "HI")])
18426 (define_insn "*strmovqi_1"
18427 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18428 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18429 (set (match_operand:SI 0 "register_operand" "=D")
18430 (plus:SI (match_dup 2)
18432 (set (match_operand:SI 1 "register_operand" "=S")
18433 (plus:SI (match_dup 3)
18435 (use (reg:SI DIRFLAG_REG))]
18436 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18438 [(set_attr "type" "str")
18439 (set_attr "memory" "both")
18440 (set_attr "mode" "QI")])
18442 (define_insn "*strmovqi_rex_1"
18443 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18444 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18445 (set (match_operand:DI 0 "register_operand" "=D")
18446 (plus:DI (match_dup 2)
18448 (set (match_operand:DI 1 "register_operand" "=S")
18449 (plus:DI (match_dup 3)
18451 (use (reg:SI DIRFLAG_REG))]
18452 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18454 [(set_attr "type" "str")
18455 (set_attr "memory" "both")
18456 (set_attr "mode" "QI")])
18458 (define_expand "rep_mov"
18459 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18460 (set (match_operand 0 "register_operand" "")
18461 (match_operand 5 "" ""))
18462 (set (match_operand 2 "register_operand" "")
18463 (match_operand 6 "" ""))
18464 (set (match_operand 1 "memory_operand" "")
18465 (match_operand 3 "memory_operand" ""))
18466 (use (match_dup 4))
18467 (use (reg:SI DIRFLAG_REG))])]
18471 (define_insn "*rep_movdi_rex64"
18472 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18473 (set (match_operand:DI 0 "register_operand" "=D")
18474 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18476 (match_operand:DI 3 "register_operand" "0")))
18477 (set (match_operand:DI 1 "register_operand" "=S")
18478 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18479 (match_operand:DI 4 "register_operand" "1")))
18480 (set (mem:BLK (match_dup 3))
18481 (mem:BLK (match_dup 4)))
18482 (use (match_dup 5))
18483 (use (reg:SI DIRFLAG_REG))]
18485 "{rep\;movsq|rep movsq}"
18486 [(set_attr "type" "str")
18487 (set_attr "prefix_rep" "1")
18488 (set_attr "memory" "both")
18489 (set_attr "mode" "DI")])
18491 (define_insn "*rep_movsi"
18492 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18493 (set (match_operand:SI 0 "register_operand" "=D")
18494 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18496 (match_operand:SI 3 "register_operand" "0")))
18497 (set (match_operand:SI 1 "register_operand" "=S")
18498 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18499 (match_operand:SI 4 "register_operand" "1")))
18500 (set (mem:BLK (match_dup 3))
18501 (mem:BLK (match_dup 4)))
18502 (use (match_dup 5))
18503 (use (reg:SI DIRFLAG_REG))]
18505 "{rep\;movsl|rep movsd}"
18506 [(set_attr "type" "str")
18507 (set_attr "prefix_rep" "1")
18508 (set_attr "memory" "both")
18509 (set_attr "mode" "SI")])
18511 (define_insn "*rep_movsi_rex64"
18512 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18513 (set (match_operand:DI 0 "register_operand" "=D")
18514 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18516 (match_operand:DI 3 "register_operand" "0")))
18517 (set (match_operand:DI 1 "register_operand" "=S")
18518 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18519 (match_operand:DI 4 "register_operand" "1")))
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\;movsl|rep movsd}"
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"
18532 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18533 (set (match_operand:SI 0 "register_operand" "=D")
18534 (plus:SI (match_operand:SI 3 "register_operand" "0")
18535 (match_operand:SI 5 "register_operand" "2")))
18536 (set (match_operand:SI 1 "register_operand" "=S")
18537 (plus:SI (match_operand:SI 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_insn "*rep_movqi_rex64"
18550 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18551 (set (match_operand:DI 0 "register_operand" "=D")
18552 (plus:DI (match_operand:DI 3 "register_operand" "0")
18553 (match_operand:DI 5 "register_operand" "2")))
18554 (set (match_operand:DI 1 "register_operand" "=S")
18555 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18556 (set (mem:BLK (match_dup 3))
18557 (mem:BLK (match_dup 4)))
18558 (use (match_dup 5))
18559 (use (reg:SI DIRFLAG_REG))]
18561 "{rep\;movsb|rep movsb}"
18562 [(set_attr "type" "str")
18563 (set_attr "prefix_rep" "1")
18564 (set_attr "memory" "both")
18565 (set_attr "mode" "SI")])
18567 (define_expand "setmemsi"
18568 [(use (match_operand:BLK 0 "memory_operand" ""))
18569 (use (match_operand:SI 1 "nonmemory_operand" ""))
18570 (use (match_operand 2 "const_int_operand" ""))
18571 (use (match_operand 3 "const_int_operand" ""))]
18574 /* If value to set is not zero, use the library routine. */
18575 if (operands[2] != const0_rtx)
18578 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18584 (define_expand "setmemdi"
18585 [(use (match_operand:BLK 0 "memory_operand" ""))
18586 (use (match_operand:DI 1 "nonmemory_operand" ""))
18587 (use (match_operand 2 "const_int_operand" ""))
18588 (use (match_operand 3 "const_int_operand" ""))]
18591 /* If value to set is not zero, use the library routine. */
18592 if (operands[2] != const0_rtx)
18595 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18601 ;; Most CPUs don't like single string operations
18602 ;; Handle this case here to simplify previous expander.
18604 (define_expand "strset"
18605 [(set (match_operand 1 "memory_operand" "")
18606 (match_operand 2 "register_operand" ""))
18607 (parallel [(set (match_operand 0 "register_operand" "")
18609 (clobber (reg:CC FLAGS_REG))])]
18612 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18613 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18615 /* If .md ever supports :P for Pmode, this can be directly
18616 in the pattern above. */
18617 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18618 GEN_INT (GET_MODE_SIZE (GET_MODE
18620 if (TARGET_SINGLE_STRINGOP || optimize_size)
18622 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18628 (define_expand "strset_singleop"
18629 [(parallel [(set (match_operand 1 "memory_operand" "")
18630 (match_operand 2 "register_operand" ""))
18631 (set (match_operand 0 "register_operand" "")
18632 (match_operand 3 "" ""))
18633 (use (reg:SI DIRFLAG_REG))])]
18634 "TARGET_SINGLE_STRINGOP || optimize_size"
18637 (define_insn "*strsetdi_rex_1"
18638 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18639 (match_operand:DI 2 "register_operand" "a"))
18640 (set (match_operand:DI 0 "register_operand" "=D")
18641 (plus:DI (match_dup 1)
18643 (use (reg:SI DIRFLAG_REG))]
18644 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18646 [(set_attr "type" "str")
18647 (set_attr "memory" "store")
18648 (set_attr "mode" "DI")])
18650 (define_insn "*strsetsi_1"
18651 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18652 (match_operand:SI 2 "register_operand" "a"))
18653 (set (match_operand:SI 0 "register_operand" "=D")
18654 (plus:SI (match_dup 1)
18656 (use (reg:SI DIRFLAG_REG))]
18657 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18659 [(set_attr "type" "str")
18660 (set_attr "memory" "store")
18661 (set_attr "mode" "SI")])
18663 (define_insn "*strsetsi_rex_1"
18664 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18665 (match_operand:SI 2 "register_operand" "a"))
18666 (set (match_operand:DI 0 "register_operand" "=D")
18667 (plus:DI (match_dup 1)
18669 (use (reg:SI DIRFLAG_REG))]
18670 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18672 [(set_attr "type" "str")
18673 (set_attr "memory" "store")
18674 (set_attr "mode" "SI")])
18676 (define_insn "*strsethi_1"
18677 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18678 (match_operand:HI 2 "register_operand" "a"))
18679 (set (match_operand:SI 0 "register_operand" "=D")
18680 (plus:SI (match_dup 1)
18682 (use (reg:SI DIRFLAG_REG))]
18683 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18685 [(set_attr "type" "str")
18686 (set_attr "memory" "store")
18687 (set_attr "mode" "HI")])
18689 (define_insn "*strsethi_rex_1"
18690 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18691 (match_operand:HI 2 "register_operand" "a"))
18692 (set (match_operand:DI 0 "register_operand" "=D")
18693 (plus:DI (match_dup 1)
18695 (use (reg:SI DIRFLAG_REG))]
18696 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18698 [(set_attr "type" "str")
18699 (set_attr "memory" "store")
18700 (set_attr "mode" "HI")])
18702 (define_insn "*strsetqi_1"
18703 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18704 (match_operand:QI 2 "register_operand" "a"))
18705 (set (match_operand:SI 0 "register_operand" "=D")
18706 (plus:SI (match_dup 1)
18708 (use (reg:SI DIRFLAG_REG))]
18709 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18711 [(set_attr "type" "str")
18712 (set_attr "memory" "store")
18713 (set_attr "mode" "QI")])
18715 (define_insn "*strsetqi_rex_1"
18716 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18717 (match_operand:QI 2 "register_operand" "a"))
18718 (set (match_operand:DI 0 "register_operand" "=D")
18719 (plus:DI (match_dup 1)
18721 (use (reg:SI DIRFLAG_REG))]
18722 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18724 [(set_attr "type" "str")
18725 (set_attr "memory" "store")
18726 (set_attr "mode" "QI")])
18728 (define_expand "rep_stos"
18729 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18730 (set (match_operand 0 "register_operand" "")
18731 (match_operand 4 "" ""))
18732 (set (match_operand 2 "memory_operand" "") (const_int 0))
18733 (use (match_operand 3 "register_operand" ""))
18734 (use (match_dup 1))
18735 (use (reg:SI DIRFLAG_REG))])]
18739 (define_insn "*rep_stosdi_rex64"
18740 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18741 (set (match_operand:DI 0 "register_operand" "=D")
18742 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18744 (match_operand:DI 3 "register_operand" "0")))
18745 (set (mem:BLK (match_dup 3))
18747 (use (match_operand:DI 2 "register_operand" "a"))
18748 (use (match_dup 4))
18749 (use (reg:SI DIRFLAG_REG))]
18751 "{rep\;stosq|rep stosq}"
18752 [(set_attr "type" "str")
18753 (set_attr "prefix_rep" "1")
18754 (set_attr "memory" "store")
18755 (set_attr "mode" "DI")])
18757 (define_insn "*rep_stossi"
18758 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18759 (set (match_operand:SI 0 "register_operand" "=D")
18760 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18762 (match_operand:SI 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_stossi_rex64"
18776 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18777 (set (match_operand:DI 0 "register_operand" "=D")
18778 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18780 (match_operand:DI 3 "register_operand" "0")))
18781 (set (mem:BLK (match_dup 3))
18783 (use (match_operand:SI 2 "register_operand" "a"))
18784 (use (match_dup 4))
18785 (use (reg:SI DIRFLAG_REG))]
18787 "{rep\;stosl|rep stosd}"
18788 [(set_attr "type" "str")
18789 (set_attr "prefix_rep" "1")
18790 (set_attr "memory" "store")
18791 (set_attr "mode" "SI")])
18793 (define_insn "*rep_stosqi"
18794 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18795 (set (match_operand:SI 0 "register_operand" "=D")
18796 (plus:SI (match_operand:SI 3 "register_operand" "0")
18797 (match_operand:SI 4 "register_operand" "1")))
18798 (set (mem:BLK (match_dup 3))
18800 (use (match_operand:QI 2 "register_operand" "a"))
18801 (use (match_dup 4))
18802 (use (reg:SI DIRFLAG_REG))]
18804 "{rep\;stosb|rep stosb}"
18805 [(set_attr "type" "str")
18806 (set_attr "prefix_rep" "1")
18807 (set_attr "memory" "store")
18808 (set_attr "mode" "QI")])
18810 (define_insn "*rep_stosqi_rex64"
18811 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18812 (set (match_operand:DI 0 "register_operand" "=D")
18813 (plus:DI (match_operand:DI 3 "register_operand" "0")
18814 (match_operand:DI 4 "register_operand" "1")))
18815 (set (mem:BLK (match_dup 3))
18817 (use (match_operand:QI 2 "register_operand" "a"))
18818 (use (match_dup 4))
18819 (use (reg:SI DIRFLAG_REG))]
18821 "{rep\;stosb|rep stosb}"
18822 [(set_attr "type" "str")
18823 (set_attr "prefix_rep" "1")
18824 (set_attr "memory" "store")
18825 (set_attr "mode" "QI")])
18827 (define_expand "cmpstrnsi"
18828 [(set (match_operand:SI 0 "register_operand" "")
18829 (compare:SI (match_operand:BLK 1 "general_operand" "")
18830 (match_operand:BLK 2 "general_operand" "")))
18831 (use (match_operand 3 "general_operand" ""))
18832 (use (match_operand 4 "immediate_operand" ""))]
18833 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18835 rtx addr1, addr2, out, outlow, count, countreg, align;
18837 /* Can't use this if the user has appropriated esi or edi. */
18838 if (global_regs[4] || global_regs[5])
18842 if (GET_CODE (out) != REG)
18843 out = gen_reg_rtx (SImode);
18845 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18846 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18847 if (addr1 != XEXP (operands[1], 0))
18848 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18849 if (addr2 != XEXP (operands[2], 0))
18850 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18852 count = operands[3];
18853 countreg = ix86_zero_extend_to_Pmode (count);
18855 /* %%% Iff we are testing strict equality, we can use known alignment
18856 to good advantage. This may be possible with combine, particularly
18857 once cc0 is dead. */
18858 align = operands[4];
18860 emit_insn (gen_cld ());
18861 if (GET_CODE (count) == CONST_INT)
18863 if (INTVAL (count) == 0)
18865 emit_move_insn (operands[0], const0_rtx);
18868 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18869 operands[1], operands[2]));
18874 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18876 emit_insn (gen_cmpsi_1 (countreg, countreg));
18877 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18878 operands[1], operands[2]));
18881 outlow = gen_lowpart (QImode, out);
18882 emit_insn (gen_cmpintqi (outlow));
18883 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18885 if (operands[0] != out)
18886 emit_move_insn (operands[0], out);
18891 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18893 (define_expand "cmpintqi"
18894 [(set (match_dup 1)
18895 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18897 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18898 (parallel [(set (match_operand:QI 0 "register_operand" "")
18899 (minus:QI (match_dup 1)
18901 (clobber (reg:CC FLAGS_REG))])]
18903 "operands[1] = gen_reg_rtx (QImode);
18904 operands[2] = gen_reg_rtx (QImode);")
18906 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18907 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18909 (define_expand "cmpstrnqi_nz_1"
18910 [(parallel [(set (reg:CC FLAGS_REG)
18911 (compare:CC (match_operand 4 "memory_operand" "")
18912 (match_operand 5 "memory_operand" "")))
18913 (use (match_operand 2 "register_operand" ""))
18914 (use (match_operand:SI 3 "immediate_operand" ""))
18915 (use (reg:SI DIRFLAG_REG))
18916 (clobber (match_operand 0 "register_operand" ""))
18917 (clobber (match_operand 1 "register_operand" ""))
18918 (clobber (match_dup 2))])]
18922 (define_insn "*cmpstrnqi_nz_1"
18923 [(set (reg:CC FLAGS_REG)
18924 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18925 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18926 (use (match_operand:SI 6 "register_operand" "2"))
18927 (use (match_operand:SI 3 "immediate_operand" "i"))
18928 (use (reg:SI DIRFLAG_REG))
18929 (clobber (match_operand:SI 0 "register_operand" "=S"))
18930 (clobber (match_operand:SI 1 "register_operand" "=D"))
18931 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18934 [(set_attr "type" "str")
18935 (set_attr "mode" "QI")
18936 (set_attr "prefix_rep" "1")])
18938 (define_insn "*cmpstrnqi_nz_rex_1"
18939 [(set (reg:CC FLAGS_REG)
18940 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18941 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18942 (use (match_operand:DI 6 "register_operand" "2"))
18943 (use (match_operand:SI 3 "immediate_operand" "i"))
18944 (use (reg:SI DIRFLAG_REG))
18945 (clobber (match_operand:DI 0 "register_operand" "=S"))
18946 (clobber (match_operand:DI 1 "register_operand" "=D"))
18947 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18950 [(set_attr "type" "str")
18951 (set_attr "mode" "QI")
18952 (set_attr "prefix_rep" "1")])
18954 ;; The same, but the count is not known to not be zero.
18956 (define_expand "cmpstrnqi_1"
18957 [(parallel [(set (reg:CC FLAGS_REG)
18958 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18960 (compare:CC (match_operand 4 "memory_operand" "")
18961 (match_operand 5 "memory_operand" ""))
18963 (use (match_operand:SI 3 "immediate_operand" ""))
18964 (use (reg:CC FLAGS_REG))
18965 (use (reg:SI DIRFLAG_REG))
18966 (clobber (match_operand 0 "register_operand" ""))
18967 (clobber (match_operand 1 "register_operand" ""))
18968 (clobber (match_dup 2))])]
18972 (define_insn "*cmpstrnqi_1"
18973 [(set (reg:CC FLAGS_REG)
18974 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18976 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18977 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18979 (use (match_operand:SI 3 "immediate_operand" "i"))
18980 (use (reg:CC FLAGS_REG))
18981 (use (reg:SI DIRFLAG_REG))
18982 (clobber (match_operand:SI 0 "register_operand" "=S"))
18983 (clobber (match_operand:SI 1 "register_operand" "=D"))
18984 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18987 [(set_attr "type" "str")
18988 (set_attr "mode" "QI")
18989 (set_attr "prefix_rep" "1")])
18991 (define_insn "*cmpstrnqi_rex_1"
18992 [(set (reg:CC FLAGS_REG)
18993 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18995 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18996 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18998 (use (match_operand:SI 3 "immediate_operand" "i"))
18999 (use (reg:CC FLAGS_REG))
19000 (use (reg:SI DIRFLAG_REG))
19001 (clobber (match_operand:DI 0 "register_operand" "=S"))
19002 (clobber (match_operand:DI 1 "register_operand" "=D"))
19003 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19006 [(set_attr "type" "str")
19007 (set_attr "mode" "QI")
19008 (set_attr "prefix_rep" "1")])
19010 (define_expand "strlensi"
19011 [(set (match_operand:SI 0 "register_operand" "")
19012 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19013 (match_operand:QI 2 "immediate_operand" "")
19014 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19017 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19023 (define_expand "strlendi"
19024 [(set (match_operand:DI 0 "register_operand" "")
19025 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19026 (match_operand:QI 2 "immediate_operand" "")
19027 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19030 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19036 (define_expand "strlenqi_1"
19037 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19038 (use (reg:SI DIRFLAG_REG))
19039 (clobber (match_operand 1 "register_operand" ""))
19040 (clobber (reg:CC FLAGS_REG))])]
19044 (define_insn "*strlenqi_1"
19045 [(set (match_operand:SI 0 "register_operand" "=&c")
19046 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19047 (match_operand:QI 2 "register_operand" "a")
19048 (match_operand:SI 3 "immediate_operand" "i")
19049 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19050 (use (reg:SI DIRFLAG_REG))
19051 (clobber (match_operand:SI 1 "register_operand" "=D"))
19052 (clobber (reg:CC FLAGS_REG))]
19055 [(set_attr "type" "str")
19056 (set_attr "mode" "QI")
19057 (set_attr "prefix_rep" "1")])
19059 (define_insn "*strlenqi_rex_1"
19060 [(set (match_operand:DI 0 "register_operand" "=&c")
19061 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19062 (match_operand:QI 2 "register_operand" "a")
19063 (match_operand:DI 3 "immediate_operand" "i")
19064 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19065 (use (reg:SI DIRFLAG_REG))
19066 (clobber (match_operand:DI 1 "register_operand" "=D"))
19067 (clobber (reg:CC FLAGS_REG))]
19070 [(set_attr "type" "str")
19071 (set_attr "mode" "QI")
19072 (set_attr "prefix_rep" "1")])
19074 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19075 ;; handled in combine, but it is not currently up to the task.
19076 ;; When used for their truth value, the cmpstrn* expanders generate
19085 ;; The intermediate three instructions are unnecessary.
19087 ;; This one handles cmpstrn*_nz_1...
19090 (set (reg:CC FLAGS_REG)
19091 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19092 (mem:BLK (match_operand 5 "register_operand" ""))))
19093 (use (match_operand 6 "register_operand" ""))
19094 (use (match_operand:SI 3 "immediate_operand" ""))
19095 (use (reg:SI DIRFLAG_REG))
19096 (clobber (match_operand 0 "register_operand" ""))
19097 (clobber (match_operand 1 "register_operand" ""))
19098 (clobber (match_operand 2 "register_operand" ""))])
19099 (set (match_operand:QI 7 "register_operand" "")
19100 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19101 (set (match_operand:QI 8 "register_operand" "")
19102 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19103 (set (reg FLAGS_REG)
19104 (compare (match_dup 7) (match_dup 8)))
19106 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19108 (set (reg:CC FLAGS_REG)
19109 (compare:CC (mem:BLK (match_dup 4))
19110 (mem:BLK (match_dup 5))))
19111 (use (match_dup 6))
19112 (use (match_dup 3))
19113 (use (reg:SI DIRFLAG_REG))
19114 (clobber (match_dup 0))
19115 (clobber (match_dup 1))
19116 (clobber (match_dup 2))])]
19119 ;; ...and this one handles cmpstrn*_1.
19122 (set (reg:CC FLAGS_REG)
19123 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19125 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19126 (mem:BLK (match_operand 5 "register_operand" "")))
19128 (use (match_operand:SI 3 "immediate_operand" ""))
19129 (use (reg:CC FLAGS_REG))
19130 (use (reg:SI DIRFLAG_REG))
19131 (clobber (match_operand 0 "register_operand" ""))
19132 (clobber (match_operand 1 "register_operand" ""))
19133 (clobber (match_operand 2 "register_operand" ""))])
19134 (set (match_operand:QI 7 "register_operand" "")
19135 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19136 (set (match_operand:QI 8 "register_operand" "")
19137 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19138 (set (reg FLAGS_REG)
19139 (compare (match_dup 7) (match_dup 8)))
19141 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19143 (set (reg:CC FLAGS_REG)
19144 (if_then_else:CC (ne (match_dup 6)
19146 (compare:CC (mem:BLK (match_dup 4))
19147 (mem:BLK (match_dup 5)))
19149 (use (match_dup 3))
19150 (use (reg:CC FLAGS_REG))
19151 (use (reg:SI DIRFLAG_REG))
19152 (clobber (match_dup 0))
19153 (clobber (match_dup 1))
19154 (clobber (match_dup 2))])]
19159 ;; Conditional move instructions.
19161 (define_expand "movdicc"
19162 [(set (match_operand:DI 0 "register_operand" "")
19163 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19164 (match_operand:DI 2 "general_operand" "")
19165 (match_operand:DI 3 "general_operand" "")))]
19167 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19169 (define_insn "x86_movdicc_0_m1_rex64"
19170 [(set (match_operand:DI 0 "register_operand" "=r")
19171 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19174 (clobber (reg:CC FLAGS_REG))]
19177 ; Since we don't have the proper number of operands for an alu insn,
19178 ; fill in all the blanks.
19179 [(set_attr "type" "alu")
19180 (set_attr "pent_pair" "pu")
19181 (set_attr "memory" "none")
19182 (set_attr "imm_disp" "false")
19183 (set_attr "mode" "DI")
19184 (set_attr "length_immediate" "0")])
19186 (define_insn "*movdicc_c_rex64"
19187 [(set (match_operand:DI 0 "register_operand" "=r,r")
19188 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19189 [(reg FLAGS_REG) (const_int 0)])
19190 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19191 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19192 "TARGET_64BIT && TARGET_CMOVE
19193 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19195 cmov%O2%C1\t{%2, %0|%0, %2}
19196 cmov%O2%c1\t{%3, %0|%0, %3}"
19197 [(set_attr "type" "icmov")
19198 (set_attr "mode" "DI")])
19200 (define_expand "movsicc"
19201 [(set (match_operand:SI 0 "register_operand" "")
19202 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19203 (match_operand:SI 2 "general_operand" "")
19204 (match_operand:SI 3 "general_operand" "")))]
19206 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19208 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19209 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19210 ;; So just document what we're doing explicitly.
19212 (define_insn "x86_movsicc_0_m1"
19213 [(set (match_operand:SI 0 "register_operand" "=r")
19214 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19217 (clobber (reg:CC FLAGS_REG))]
19220 ; Since we don't have the proper number of operands for an alu insn,
19221 ; fill in all the blanks.
19222 [(set_attr "type" "alu")
19223 (set_attr "pent_pair" "pu")
19224 (set_attr "memory" "none")
19225 (set_attr "imm_disp" "false")
19226 (set_attr "mode" "SI")
19227 (set_attr "length_immediate" "0")])
19229 (define_insn "*movsicc_noc"
19230 [(set (match_operand:SI 0 "register_operand" "=r,r")
19231 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19232 [(reg FLAGS_REG) (const_int 0)])
19233 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19234 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19236 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19238 cmov%O2%C1\t{%2, %0|%0, %2}
19239 cmov%O2%c1\t{%3, %0|%0, %3}"
19240 [(set_attr "type" "icmov")
19241 (set_attr "mode" "SI")])
19243 (define_expand "movhicc"
19244 [(set (match_operand:HI 0 "register_operand" "")
19245 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19246 (match_operand:HI 2 "general_operand" "")
19247 (match_operand:HI 3 "general_operand" "")))]
19248 "TARGET_HIMODE_MATH"
19249 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19251 (define_insn "*movhicc_noc"
19252 [(set (match_operand:HI 0 "register_operand" "=r,r")
19253 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19254 [(reg FLAGS_REG) (const_int 0)])
19255 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19256 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19258 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19260 cmov%O2%C1\t{%2, %0|%0, %2}
19261 cmov%O2%c1\t{%3, %0|%0, %3}"
19262 [(set_attr "type" "icmov")
19263 (set_attr "mode" "HI")])
19265 (define_expand "movqicc"
19266 [(set (match_operand:QI 0 "register_operand" "")
19267 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19268 (match_operand:QI 2 "general_operand" "")
19269 (match_operand:QI 3 "general_operand" "")))]
19270 "TARGET_QIMODE_MATH"
19271 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19273 (define_insn_and_split "*movqicc_noc"
19274 [(set (match_operand:QI 0 "register_operand" "=r,r")
19275 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19276 [(match_operand 4 "flags_reg_operand" "")
19278 (match_operand:QI 2 "register_operand" "r,0")
19279 (match_operand:QI 3 "register_operand" "0,r")))]
19280 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19282 "&& reload_completed"
19283 [(set (match_dup 0)
19284 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19287 "operands[0] = gen_lowpart (SImode, operands[0]);
19288 operands[2] = gen_lowpart (SImode, operands[2]);
19289 operands[3] = gen_lowpart (SImode, operands[3]);"
19290 [(set_attr "type" "icmov")
19291 (set_attr "mode" "SI")])
19293 (define_expand "movsfcc"
19294 [(set (match_operand:SF 0 "register_operand" "")
19295 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19296 (match_operand:SF 2 "register_operand" "")
19297 (match_operand:SF 3 "register_operand" "")))]
19298 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19299 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19301 (define_insn "*movsfcc_1_387"
19302 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19303 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19304 [(reg FLAGS_REG) (const_int 0)])
19305 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19306 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19307 "TARGET_80387 && TARGET_CMOVE
19308 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19310 fcmov%F1\t{%2, %0|%0, %2}
19311 fcmov%f1\t{%3, %0|%0, %3}
19312 cmov%O2%C1\t{%2, %0|%0, %2}
19313 cmov%O2%c1\t{%3, %0|%0, %3}"
19314 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19315 (set_attr "mode" "SF,SF,SI,SI")])
19317 (define_expand "movdfcc"
19318 [(set (match_operand:DF 0 "register_operand" "")
19319 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19320 (match_operand:DF 2 "register_operand" "")
19321 (match_operand:DF 3 "register_operand" "")))]
19322 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19323 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19325 (define_insn "*movdfcc_1"
19326 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19327 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19328 [(reg FLAGS_REG) (const_int 0)])
19329 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19330 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19331 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19332 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19334 fcmov%F1\t{%2, %0|%0, %2}
19335 fcmov%f1\t{%3, %0|%0, %3}
19338 [(set_attr "type" "fcmov,fcmov,multi,multi")
19339 (set_attr "mode" "DF")])
19341 (define_insn "*movdfcc_1_rex64"
19342 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19343 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19344 [(reg FLAGS_REG) (const_int 0)])
19345 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19346 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19347 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19348 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19350 fcmov%F1\t{%2, %0|%0, %2}
19351 fcmov%f1\t{%3, %0|%0, %3}
19352 cmov%O2%C1\t{%2, %0|%0, %2}
19353 cmov%O2%c1\t{%3, %0|%0, %3}"
19354 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19355 (set_attr "mode" "DF")])
19358 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19359 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19360 [(match_operand 4 "flags_reg_operand" "")
19362 (match_operand:DF 2 "nonimmediate_operand" "")
19363 (match_operand:DF 3 "nonimmediate_operand" "")))]
19364 "!TARGET_64BIT && reload_completed"
19365 [(set (match_dup 2)
19366 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19370 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19373 "split_di (operands+2, 1, operands+5, operands+6);
19374 split_di (operands+3, 1, operands+7, operands+8);
19375 split_di (operands, 1, operands+2, operands+3);")
19377 (define_expand "movxfcc"
19378 [(set (match_operand:XF 0 "register_operand" "")
19379 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19380 (match_operand:XF 2 "register_operand" "")
19381 (match_operand:XF 3 "register_operand" "")))]
19382 "TARGET_80387 && TARGET_CMOVE"
19383 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19385 (define_insn "*movxfcc_1"
19386 [(set (match_operand:XF 0 "register_operand" "=f,f")
19387 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19388 [(reg FLAGS_REG) (const_int 0)])
19389 (match_operand:XF 2 "register_operand" "f,0")
19390 (match_operand:XF 3 "register_operand" "0,f")))]
19391 "TARGET_80387 && TARGET_CMOVE"
19393 fcmov%F1\t{%2, %0|%0, %2}
19394 fcmov%f1\t{%3, %0|%0, %3}"
19395 [(set_attr "type" "fcmov")
19396 (set_attr "mode" "XF")])
19398 ;; These versions of the min/max patterns are intentionally ignorant of
19399 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19400 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19401 ;; are undefined in this condition, we're certain this is correct.
19403 (define_insn "sminsf3"
19404 [(set (match_operand:SF 0 "register_operand" "=x")
19405 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19406 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19408 "minss\t{%2, %0|%0, %2}"
19409 [(set_attr "type" "sseadd")
19410 (set_attr "mode" "SF")])
19412 (define_insn "smaxsf3"
19413 [(set (match_operand:SF 0 "register_operand" "=x")
19414 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19415 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19417 "maxss\t{%2, %0|%0, %2}"
19418 [(set_attr "type" "sseadd")
19419 (set_attr "mode" "SF")])
19421 (define_insn "smindf3"
19422 [(set (match_operand:DF 0 "register_operand" "=x")
19423 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19424 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19425 "TARGET_SSE2 && TARGET_SSE_MATH"
19426 "minsd\t{%2, %0|%0, %2}"
19427 [(set_attr "type" "sseadd")
19428 (set_attr "mode" "DF")])
19430 (define_insn "smaxdf3"
19431 [(set (match_operand:DF 0 "register_operand" "=x")
19432 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19433 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19434 "TARGET_SSE2 && TARGET_SSE_MATH"
19435 "maxsd\t{%2, %0|%0, %2}"
19436 [(set_attr "type" "sseadd")
19437 (set_attr "mode" "DF")])
19439 ;; These versions of the min/max patterns implement exactly the operations
19440 ;; min = (op1 < op2 ? op1 : op2)
19441 ;; max = (!(op1 < op2) ? op1 : op2)
19442 ;; Their operands are not commutative, and thus they may be used in the
19443 ;; presence of -0.0 and NaN.
19445 (define_insn "*ieee_sminsf3"
19446 [(set (match_operand:SF 0 "register_operand" "=x")
19447 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19448 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19451 "minss\t{%2, %0|%0, %2}"
19452 [(set_attr "type" "sseadd")
19453 (set_attr "mode" "SF")])
19455 (define_insn "*ieee_smaxsf3"
19456 [(set (match_operand:SF 0 "register_operand" "=x")
19457 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19458 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19461 "maxss\t{%2, %0|%0, %2}"
19462 [(set_attr "type" "sseadd")
19463 (set_attr "mode" "SF")])
19465 (define_insn "*ieee_smindf3"
19466 [(set (match_operand:DF 0 "register_operand" "=x")
19467 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19468 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19470 "TARGET_SSE2 && TARGET_SSE_MATH"
19471 "minsd\t{%2, %0|%0, %2}"
19472 [(set_attr "type" "sseadd")
19473 (set_attr "mode" "DF")])
19475 (define_insn "*ieee_smaxdf3"
19476 [(set (match_operand:DF 0 "register_operand" "=x")
19477 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19478 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19480 "TARGET_SSE2 && TARGET_SSE_MATH"
19481 "maxsd\t{%2, %0|%0, %2}"
19482 [(set_attr "type" "sseadd")
19483 (set_attr "mode" "DF")])
19485 ;; Make two stack loads independent:
19487 ;; fld %st(0) -> fld bb
19488 ;; fmul bb fmul %st(1), %st
19490 ;; Actually we only match the last two instructions for simplicity.
19492 [(set (match_operand 0 "fp_register_operand" "")
19493 (match_operand 1 "fp_register_operand" ""))
19495 (match_operator 2 "binary_fp_operator"
19497 (match_operand 3 "memory_operand" "")]))]
19498 "REGNO (operands[0]) != REGNO (operands[1])"
19499 [(set (match_dup 0) (match_dup 3))
19500 (set (match_dup 0) (match_dup 4))]
19502 ;; The % modifier is not operational anymore in peephole2's, so we have to
19503 ;; swap the operands manually in the case of addition and multiplication.
19504 "if (COMMUTATIVE_ARITH_P (operands[2]))
19505 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19506 operands[0], operands[1]);
19508 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19509 operands[1], operands[0]);")
19511 ;; Conditional addition patterns
19512 (define_expand "addqicc"
19513 [(match_operand:QI 0 "register_operand" "")
19514 (match_operand 1 "comparison_operator" "")
19515 (match_operand:QI 2 "register_operand" "")
19516 (match_operand:QI 3 "const_int_operand" "")]
19518 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19520 (define_expand "addhicc"
19521 [(match_operand:HI 0 "register_operand" "")
19522 (match_operand 1 "comparison_operator" "")
19523 (match_operand:HI 2 "register_operand" "")
19524 (match_operand:HI 3 "const_int_operand" "")]
19526 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19528 (define_expand "addsicc"
19529 [(match_operand:SI 0 "register_operand" "")
19530 (match_operand 1 "comparison_operator" "")
19531 (match_operand:SI 2 "register_operand" "")
19532 (match_operand:SI 3 "const_int_operand" "")]
19534 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19536 (define_expand "adddicc"
19537 [(match_operand:DI 0 "register_operand" "")
19538 (match_operand 1 "comparison_operator" "")
19539 (match_operand:DI 2 "register_operand" "")
19540 (match_operand:DI 3 "const_int_operand" "")]
19542 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19545 ;; Misc patterns (?)
19547 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19548 ;; Otherwise there will be nothing to keep
19550 ;; [(set (reg ebp) (reg esp))]
19551 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19552 ;; (clobber (eflags)]
19553 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19555 ;; in proper program order.
19556 (define_insn "pro_epilogue_adjust_stack_1"
19557 [(set (match_operand:SI 0 "register_operand" "=r,r")
19558 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19559 (match_operand:SI 2 "immediate_operand" "i,i")))
19560 (clobber (reg:CC FLAGS_REG))
19561 (clobber (mem:BLK (scratch)))]
19564 switch (get_attr_type (insn))
19567 return "mov{l}\t{%1, %0|%0, %1}";
19570 if (GET_CODE (operands[2]) == CONST_INT
19571 && (INTVAL (operands[2]) == 128
19572 || (INTVAL (operands[2]) < 0
19573 && INTVAL (operands[2]) != -128)))
19575 operands[2] = GEN_INT (-INTVAL (operands[2]));
19576 return "sub{l}\t{%2, %0|%0, %2}";
19578 return "add{l}\t{%2, %0|%0, %2}";
19581 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19582 return "lea{l}\t{%a2, %0|%0, %a2}";
19585 gcc_unreachable ();
19588 [(set (attr "type")
19589 (cond [(eq_attr "alternative" "0")
19590 (const_string "alu")
19591 (match_operand:SI 2 "const0_operand" "")
19592 (const_string "imov")
19594 (const_string "lea")))
19595 (set_attr "mode" "SI")])
19597 (define_insn "pro_epilogue_adjust_stack_rex64"
19598 [(set (match_operand:DI 0 "register_operand" "=r,r")
19599 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19600 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19601 (clobber (reg:CC FLAGS_REG))
19602 (clobber (mem:BLK (scratch)))]
19605 switch (get_attr_type (insn))
19608 return "mov{q}\t{%1, %0|%0, %1}";
19611 if (GET_CODE (operands[2]) == CONST_INT
19612 /* Avoid overflows. */
19613 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19614 && (INTVAL (operands[2]) == 128
19615 || (INTVAL (operands[2]) < 0
19616 && INTVAL (operands[2]) != -128)))
19618 operands[2] = GEN_INT (-INTVAL (operands[2]));
19619 return "sub{q}\t{%2, %0|%0, %2}";
19621 return "add{q}\t{%2, %0|%0, %2}";
19624 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19625 return "lea{q}\t{%a2, %0|%0, %a2}";
19628 gcc_unreachable ();
19631 [(set (attr "type")
19632 (cond [(eq_attr "alternative" "0")
19633 (const_string "alu")
19634 (match_operand:DI 2 "const0_operand" "")
19635 (const_string "imov")
19637 (const_string "lea")))
19638 (set_attr "mode" "DI")])
19640 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19641 [(set (match_operand:DI 0 "register_operand" "=r,r")
19642 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19643 (match_operand:DI 3 "immediate_operand" "i,i")))
19644 (use (match_operand:DI 2 "register_operand" "r,r"))
19645 (clobber (reg:CC FLAGS_REG))
19646 (clobber (mem:BLK (scratch)))]
19649 switch (get_attr_type (insn))
19652 return "add{q}\t{%2, %0|%0, %2}";
19655 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19656 return "lea{q}\t{%a2, %0|%0, %a2}";
19659 gcc_unreachable ();
19662 [(set_attr "type" "alu,lea")
19663 (set_attr "mode" "DI")])
19665 (define_expand "allocate_stack_worker"
19666 [(match_operand:SI 0 "register_operand" "")]
19667 "TARGET_STACK_PROBE"
19669 if (reload_completed)
19672 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19674 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19679 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19681 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19686 (define_insn "allocate_stack_worker_1"
19687 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19688 UNSPECV_STACK_PROBE)
19689 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19690 (clobber (match_scratch:SI 1 "=0"))
19691 (clobber (reg:CC FLAGS_REG))]
19692 "!TARGET_64BIT && TARGET_STACK_PROBE"
19694 [(set_attr "type" "multi")
19695 (set_attr "length" "5")])
19697 (define_expand "allocate_stack_worker_postreload"
19698 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19699 UNSPECV_STACK_PROBE)
19700 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19701 (clobber (match_dup 0))
19702 (clobber (reg:CC FLAGS_REG))])]
19706 (define_insn "allocate_stack_worker_rex64"
19707 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19708 UNSPECV_STACK_PROBE)
19709 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19710 (clobber (match_scratch:DI 1 "=0"))
19711 (clobber (reg:CC FLAGS_REG))]
19712 "TARGET_64BIT && TARGET_STACK_PROBE"
19714 [(set_attr "type" "multi")
19715 (set_attr "length" "5")])
19717 (define_expand "allocate_stack_worker_rex64_postreload"
19718 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19719 UNSPECV_STACK_PROBE)
19720 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19721 (clobber (match_dup 0))
19722 (clobber (reg:CC FLAGS_REG))])]
19726 (define_expand "allocate_stack"
19727 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19728 (minus:SI (reg:SI SP_REG)
19729 (match_operand:SI 1 "general_operand" "")))
19730 (clobber (reg:CC FLAGS_REG))])
19731 (parallel [(set (reg:SI SP_REG)
19732 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19733 (clobber (reg:CC FLAGS_REG))])]
19734 "TARGET_STACK_PROBE"
19736 #ifdef CHECK_STACK_LIMIT
19737 if (GET_CODE (operands[1]) == CONST_INT
19738 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19739 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19743 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19746 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19750 (define_expand "builtin_setjmp_receiver"
19751 [(label_ref (match_operand 0 "" ""))]
19752 "!TARGET_64BIT && flag_pic"
19757 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19758 rtx label_rtx = gen_label_rtx ();
19759 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19760 xops[0] = xops[1] = picreg;
19761 xops[2] = gen_rtx_CONST (SImode,
19762 gen_rtx_MINUS (SImode,
19763 gen_rtx_LABEL_REF (SImode, label_rtx),
19764 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19765 ix86_expand_binary_operator (MINUS, SImode, xops);
19768 emit_insn (gen_set_got (pic_offset_table_rtx));
19772 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19775 [(set (match_operand 0 "register_operand" "")
19776 (match_operator 3 "promotable_binary_operator"
19777 [(match_operand 1 "register_operand" "")
19778 (match_operand 2 "aligned_operand" "")]))
19779 (clobber (reg:CC FLAGS_REG))]
19780 "! TARGET_PARTIAL_REG_STALL && reload_completed
19781 && ((GET_MODE (operands[0]) == HImode
19782 && ((!optimize_size && !TARGET_FAST_PREFIX)
19783 /* ??? next two lines just !satisfies_constraint_K (...) */
19784 || GET_CODE (operands[2]) != CONST_INT
19785 || satisfies_constraint_K (operands[2])))
19786 || (GET_MODE (operands[0]) == QImode
19787 && (TARGET_PROMOTE_QImode || optimize_size)))"
19788 [(parallel [(set (match_dup 0)
19789 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19790 (clobber (reg:CC FLAGS_REG))])]
19791 "operands[0] = gen_lowpart (SImode, operands[0]);
19792 operands[1] = gen_lowpart (SImode, operands[1]);
19793 if (GET_CODE (operands[3]) != ASHIFT)
19794 operands[2] = gen_lowpart (SImode, operands[2]);
19795 PUT_MODE (operands[3], SImode);")
19797 ; Promote the QImode tests, as i386 has encoding of the AND
19798 ; instruction with 32-bit sign-extended immediate and thus the
19799 ; instruction size is unchanged, except in the %eax case for
19800 ; which it is increased by one byte, hence the ! optimize_size.
19802 [(set (match_operand 0 "flags_reg_operand" "")
19803 (match_operator 2 "compare_operator"
19804 [(and (match_operand 3 "aligned_operand" "")
19805 (match_operand 4 "const_int_operand" ""))
19807 (set (match_operand 1 "register_operand" "")
19808 (and (match_dup 3) (match_dup 4)))]
19809 "! TARGET_PARTIAL_REG_STALL && reload_completed
19810 /* Ensure that the operand will remain sign-extended immediate. */
19811 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19813 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19814 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19815 [(parallel [(set (match_dup 0)
19816 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19819 (and:SI (match_dup 3) (match_dup 4)))])]
19822 = gen_int_mode (INTVAL (operands[4])
19823 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19824 operands[1] = gen_lowpart (SImode, operands[1]);
19825 operands[3] = gen_lowpart (SImode, operands[3]);
19828 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19829 ; the TEST instruction with 32-bit sign-extended immediate and thus
19830 ; the instruction size would at least double, which is not what we
19831 ; want even with ! optimize_size.
19833 [(set (match_operand 0 "flags_reg_operand" "")
19834 (match_operator 1 "compare_operator"
19835 [(and (match_operand:HI 2 "aligned_operand" "")
19836 (match_operand:HI 3 "const_int_operand" ""))
19838 "! TARGET_PARTIAL_REG_STALL && reload_completed
19839 /* Ensure that the operand will remain sign-extended immediate. */
19840 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19841 && ! TARGET_FAST_PREFIX
19842 && ! optimize_size"
19843 [(set (match_dup 0)
19844 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19848 = gen_int_mode (INTVAL (operands[3])
19849 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19850 operands[2] = gen_lowpart (SImode, operands[2]);
19854 [(set (match_operand 0 "register_operand" "")
19855 (neg (match_operand 1 "register_operand" "")))
19856 (clobber (reg:CC FLAGS_REG))]
19857 "! TARGET_PARTIAL_REG_STALL && reload_completed
19858 && (GET_MODE (operands[0]) == HImode
19859 || (GET_MODE (operands[0]) == QImode
19860 && (TARGET_PROMOTE_QImode || optimize_size)))"
19861 [(parallel [(set (match_dup 0)
19862 (neg:SI (match_dup 1)))
19863 (clobber (reg:CC FLAGS_REG))])]
19864 "operands[0] = gen_lowpart (SImode, operands[0]);
19865 operands[1] = gen_lowpart (SImode, operands[1]);")
19868 [(set (match_operand 0 "register_operand" "")
19869 (not (match_operand 1 "register_operand" "")))]
19870 "! TARGET_PARTIAL_REG_STALL && reload_completed
19871 && (GET_MODE (operands[0]) == HImode
19872 || (GET_MODE (operands[0]) == QImode
19873 && (TARGET_PROMOTE_QImode || optimize_size)))"
19874 [(set (match_dup 0)
19875 (not:SI (match_dup 1)))]
19876 "operands[0] = gen_lowpart (SImode, operands[0]);
19877 operands[1] = gen_lowpart (SImode, operands[1]);")
19880 [(set (match_operand 0 "register_operand" "")
19881 (if_then_else (match_operator 1 "comparison_operator"
19882 [(reg FLAGS_REG) (const_int 0)])
19883 (match_operand 2 "register_operand" "")
19884 (match_operand 3 "register_operand" "")))]
19885 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19886 && (GET_MODE (operands[0]) == HImode
19887 || (GET_MODE (operands[0]) == QImode
19888 && (TARGET_PROMOTE_QImode || optimize_size)))"
19889 [(set (match_dup 0)
19890 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19891 "operands[0] = gen_lowpart (SImode, operands[0]);
19892 operands[2] = gen_lowpart (SImode, operands[2]);
19893 operands[3] = gen_lowpart (SImode, operands[3]);")
19896 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19897 ;; transform a complex memory operation into two memory to register operations.
19899 ;; Don't push memory operands
19901 [(set (match_operand:SI 0 "push_operand" "")
19902 (match_operand:SI 1 "memory_operand" ""))
19903 (match_scratch:SI 2 "r")]
19904 "!optimize_size && !TARGET_PUSH_MEMORY
19905 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19906 [(set (match_dup 2) (match_dup 1))
19907 (set (match_dup 0) (match_dup 2))]
19911 [(set (match_operand:DI 0 "push_operand" "")
19912 (match_operand:DI 1 "memory_operand" ""))
19913 (match_scratch:DI 2 "r")]
19914 "!optimize_size && !TARGET_PUSH_MEMORY
19915 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19916 [(set (match_dup 2) (match_dup 1))
19917 (set (match_dup 0) (match_dup 2))]
19920 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19923 [(set (match_operand:SF 0 "push_operand" "")
19924 (match_operand:SF 1 "memory_operand" ""))
19925 (match_scratch:SF 2 "r")]
19926 "!optimize_size && !TARGET_PUSH_MEMORY
19927 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19928 [(set (match_dup 2) (match_dup 1))
19929 (set (match_dup 0) (match_dup 2))]
19933 [(set (match_operand:HI 0 "push_operand" "")
19934 (match_operand:HI 1 "memory_operand" ""))
19935 (match_scratch:HI 2 "r")]
19936 "!optimize_size && !TARGET_PUSH_MEMORY
19937 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19938 [(set (match_dup 2) (match_dup 1))
19939 (set (match_dup 0) (match_dup 2))]
19943 [(set (match_operand:QI 0 "push_operand" "")
19944 (match_operand:QI 1 "memory_operand" ""))
19945 (match_scratch:QI 2 "q")]
19946 "!optimize_size && !TARGET_PUSH_MEMORY
19947 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19948 [(set (match_dup 2) (match_dup 1))
19949 (set (match_dup 0) (match_dup 2))]
19952 ;; Don't move an immediate directly to memory when the instruction
19955 [(match_scratch:SI 1 "r")
19956 (set (match_operand:SI 0 "memory_operand" "")
19959 && ! TARGET_USE_MOV0
19960 && TARGET_SPLIT_LONG_MOVES
19961 && get_attr_length (insn) >= ix86_cost->large_insn
19962 && peep2_regno_dead_p (0, FLAGS_REG)"
19963 [(parallel [(set (match_dup 1) (const_int 0))
19964 (clobber (reg:CC FLAGS_REG))])
19965 (set (match_dup 0) (match_dup 1))]
19969 [(match_scratch:HI 1 "r")
19970 (set (match_operand:HI 0 "memory_operand" "")
19973 && ! TARGET_USE_MOV0
19974 && TARGET_SPLIT_LONG_MOVES
19975 && get_attr_length (insn) >= ix86_cost->large_insn
19976 && peep2_regno_dead_p (0, FLAGS_REG)"
19977 [(parallel [(set (match_dup 2) (const_int 0))
19978 (clobber (reg:CC FLAGS_REG))])
19979 (set (match_dup 0) (match_dup 1))]
19980 "operands[2] = gen_lowpart (SImode, operands[1]);")
19983 [(match_scratch:QI 1 "q")
19984 (set (match_operand:QI 0 "memory_operand" "")
19987 && ! TARGET_USE_MOV0
19988 && TARGET_SPLIT_LONG_MOVES
19989 && get_attr_length (insn) >= ix86_cost->large_insn
19990 && peep2_regno_dead_p (0, FLAGS_REG)"
19991 [(parallel [(set (match_dup 2) (const_int 0))
19992 (clobber (reg:CC FLAGS_REG))])
19993 (set (match_dup 0) (match_dup 1))]
19994 "operands[2] = gen_lowpart (SImode, operands[1]);")
19997 [(match_scratch:SI 2 "r")
19998 (set (match_operand:SI 0 "memory_operand" "")
19999 (match_operand:SI 1 "immediate_operand" ""))]
20001 && get_attr_length (insn) >= ix86_cost->large_insn
20002 && TARGET_SPLIT_LONG_MOVES"
20003 [(set (match_dup 2) (match_dup 1))
20004 (set (match_dup 0) (match_dup 2))]
20008 [(match_scratch:HI 2 "r")
20009 (set (match_operand:HI 0 "memory_operand" "")
20010 (match_operand:HI 1 "immediate_operand" ""))]
20011 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20012 && TARGET_SPLIT_LONG_MOVES"
20013 [(set (match_dup 2) (match_dup 1))
20014 (set (match_dup 0) (match_dup 2))]
20018 [(match_scratch:QI 2 "q")
20019 (set (match_operand:QI 0 "memory_operand" "")
20020 (match_operand:QI 1 "immediate_operand" ""))]
20021 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20022 && TARGET_SPLIT_LONG_MOVES"
20023 [(set (match_dup 2) (match_dup 1))
20024 (set (match_dup 0) (match_dup 2))]
20027 ;; Don't compare memory with zero, load and use a test instead.
20029 [(set (match_operand 0 "flags_reg_operand" "")
20030 (match_operator 1 "compare_operator"
20031 [(match_operand:SI 2 "memory_operand" "")
20033 (match_scratch:SI 3 "r")]
20034 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
20035 [(set (match_dup 3) (match_dup 2))
20036 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20039 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20040 ;; Don't split NOTs with a displacement operand, because resulting XOR
20041 ;; will not be pairable anyway.
20043 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20044 ;; represented using a modRM byte. The XOR replacement is long decoded,
20045 ;; so this split helps here as well.
20047 ;; Note: Can't do this as a regular split because we can't get proper
20048 ;; lifetime information then.
20051 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20052 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20054 && peep2_regno_dead_p (0, FLAGS_REG)
20055 && ((TARGET_PENTIUM
20056 && (GET_CODE (operands[0]) != MEM
20057 || !memory_displacement_operand (operands[0], SImode)))
20058 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20059 [(parallel [(set (match_dup 0)
20060 (xor:SI (match_dup 1) (const_int -1)))
20061 (clobber (reg:CC FLAGS_REG))])]
20065 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20066 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20068 && peep2_regno_dead_p (0, FLAGS_REG)
20069 && ((TARGET_PENTIUM
20070 && (GET_CODE (operands[0]) != MEM
20071 || !memory_displacement_operand (operands[0], HImode)))
20072 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20073 [(parallel [(set (match_dup 0)
20074 (xor:HI (match_dup 1) (const_int -1)))
20075 (clobber (reg:CC FLAGS_REG))])]
20079 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20080 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20082 && peep2_regno_dead_p (0, FLAGS_REG)
20083 && ((TARGET_PENTIUM
20084 && (GET_CODE (operands[0]) != MEM
20085 || !memory_displacement_operand (operands[0], QImode)))
20086 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20087 [(parallel [(set (match_dup 0)
20088 (xor:QI (match_dup 1) (const_int -1)))
20089 (clobber (reg:CC FLAGS_REG))])]
20092 ;; Non pairable "test imm, reg" instructions can be translated to
20093 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20094 ;; byte opcode instead of two, have a short form for byte operands),
20095 ;; so do it for other CPUs as well. Given that the value was dead,
20096 ;; this should not create any new dependencies. Pass on the sub-word
20097 ;; versions if we're concerned about partial register stalls.
20100 [(set (match_operand 0 "flags_reg_operand" "")
20101 (match_operator 1 "compare_operator"
20102 [(and:SI (match_operand:SI 2 "register_operand" "")
20103 (match_operand:SI 3 "immediate_operand" ""))
20105 "ix86_match_ccmode (insn, CCNOmode)
20106 && (true_regnum (operands[2]) != 0
20107 || satisfies_constraint_K (operands[3]))
20108 && peep2_reg_dead_p (1, operands[2])"
20110 [(set (match_dup 0)
20111 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20114 (and:SI (match_dup 2) (match_dup 3)))])]
20117 ;; We don't need to handle HImode case, because it will be promoted to SImode
20118 ;; on ! TARGET_PARTIAL_REG_STALL
20121 [(set (match_operand 0 "flags_reg_operand" "")
20122 (match_operator 1 "compare_operator"
20123 [(and:QI (match_operand:QI 2 "register_operand" "")
20124 (match_operand:QI 3 "immediate_operand" ""))
20126 "! TARGET_PARTIAL_REG_STALL
20127 && ix86_match_ccmode (insn, CCNOmode)
20128 && true_regnum (operands[2]) != 0
20129 && peep2_reg_dead_p (1, operands[2])"
20131 [(set (match_dup 0)
20132 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20135 (and:QI (match_dup 2) (match_dup 3)))])]
20139 [(set (match_operand 0 "flags_reg_operand" "")
20140 (match_operator 1 "compare_operator"
20143 (match_operand 2 "ext_register_operand" "")
20146 (match_operand 3 "const_int_operand" ""))
20148 "! TARGET_PARTIAL_REG_STALL
20149 && ix86_match_ccmode (insn, CCNOmode)
20150 && true_regnum (operands[2]) != 0
20151 && peep2_reg_dead_p (1, operands[2])"
20152 [(parallel [(set (match_dup 0)
20161 (set (zero_extract:SI (match_dup 2)
20172 ;; Don't do logical operations with memory inputs.
20174 [(match_scratch:SI 2 "r")
20175 (parallel [(set (match_operand:SI 0 "register_operand" "")
20176 (match_operator:SI 3 "arith_or_logical_operator"
20178 (match_operand:SI 1 "memory_operand" "")]))
20179 (clobber (reg:CC FLAGS_REG))])]
20180 "! optimize_size && ! TARGET_READ_MODIFY"
20181 [(set (match_dup 2) (match_dup 1))
20182 (parallel [(set (match_dup 0)
20183 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20184 (clobber (reg:CC FLAGS_REG))])]
20188 [(match_scratch:SI 2 "r")
20189 (parallel [(set (match_operand:SI 0 "register_operand" "")
20190 (match_operator:SI 3 "arith_or_logical_operator"
20191 [(match_operand:SI 1 "memory_operand" "")
20193 (clobber (reg:CC FLAGS_REG))])]
20194 "! optimize_size && ! TARGET_READ_MODIFY"
20195 [(set (match_dup 2) (match_dup 1))
20196 (parallel [(set (match_dup 0)
20197 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20198 (clobber (reg:CC FLAGS_REG))])]
20201 ; Don't do logical operations with memory outputs
20203 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20204 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20205 ; the same decoder scheduling characteristics as the original.
20208 [(match_scratch:SI 2 "r")
20209 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20210 (match_operator:SI 3 "arith_or_logical_operator"
20212 (match_operand:SI 1 "nonmemory_operand" "")]))
20213 (clobber (reg:CC FLAGS_REG))])]
20214 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20215 [(set (match_dup 2) (match_dup 0))
20216 (parallel [(set (match_dup 2)
20217 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20218 (clobber (reg:CC FLAGS_REG))])
20219 (set (match_dup 0) (match_dup 2))]
20223 [(match_scratch:SI 2 "r")
20224 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20225 (match_operator:SI 3 "arith_or_logical_operator"
20226 [(match_operand:SI 1 "nonmemory_operand" "")
20228 (clobber (reg:CC FLAGS_REG))])]
20229 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20230 [(set (match_dup 2) (match_dup 0))
20231 (parallel [(set (match_dup 2)
20232 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20233 (clobber (reg:CC FLAGS_REG))])
20234 (set (match_dup 0) (match_dup 2))]
20237 ;; Attempt to always use XOR for zeroing registers.
20239 [(set (match_operand 0 "register_operand" "")
20240 (match_operand 1 "const0_operand" ""))]
20241 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20242 && (! TARGET_USE_MOV0 || optimize_size)
20243 && GENERAL_REG_P (operands[0])
20244 && peep2_regno_dead_p (0, FLAGS_REG)"
20245 [(parallel [(set (match_dup 0) (const_int 0))
20246 (clobber (reg:CC FLAGS_REG))])]
20248 operands[0] = gen_lowpart (word_mode, operands[0]);
20252 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20254 "(GET_MODE (operands[0]) == QImode
20255 || GET_MODE (operands[0]) == HImode)
20256 && (! TARGET_USE_MOV0 || optimize_size)
20257 && peep2_regno_dead_p (0, FLAGS_REG)"
20258 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20259 (clobber (reg:CC FLAGS_REG))])])
20261 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20263 [(set (match_operand 0 "register_operand" "")
20265 "(GET_MODE (operands[0]) == HImode
20266 || GET_MODE (operands[0]) == SImode
20267 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20268 && (optimize_size || TARGET_PENTIUM)
20269 && peep2_regno_dead_p (0, FLAGS_REG)"
20270 [(parallel [(set (match_dup 0) (const_int -1))
20271 (clobber (reg:CC FLAGS_REG))])]
20272 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20275 ;; Attempt to convert simple leas to adds. These can be created by
20278 [(set (match_operand:SI 0 "register_operand" "")
20279 (plus:SI (match_dup 0)
20280 (match_operand:SI 1 "nonmemory_operand" "")))]
20281 "peep2_regno_dead_p (0, FLAGS_REG)"
20282 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20283 (clobber (reg:CC FLAGS_REG))])]
20287 [(set (match_operand:SI 0 "register_operand" "")
20288 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20289 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20290 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20291 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20292 (clobber (reg:CC FLAGS_REG))])]
20293 "operands[2] = gen_lowpart (SImode, operands[2]);")
20296 [(set (match_operand:DI 0 "register_operand" "")
20297 (plus:DI (match_dup 0)
20298 (match_operand:DI 1 "x86_64_general_operand" "")))]
20299 "peep2_regno_dead_p (0, FLAGS_REG)"
20300 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20301 (clobber (reg:CC FLAGS_REG))])]
20305 [(set (match_operand:SI 0 "register_operand" "")
20306 (mult:SI (match_dup 0)
20307 (match_operand:SI 1 "const_int_operand" "")))]
20308 "exact_log2 (INTVAL (operands[1])) >= 0
20309 && peep2_regno_dead_p (0, FLAGS_REG)"
20310 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20311 (clobber (reg:CC FLAGS_REG))])]
20312 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20315 [(set (match_operand:DI 0 "register_operand" "")
20316 (mult:DI (match_dup 0)
20317 (match_operand:DI 1 "const_int_operand" "")))]
20318 "exact_log2 (INTVAL (operands[1])) >= 0
20319 && peep2_regno_dead_p (0, FLAGS_REG)"
20320 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20321 (clobber (reg:CC FLAGS_REG))])]
20322 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20325 [(set (match_operand:SI 0 "register_operand" "")
20326 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20327 (match_operand:DI 2 "const_int_operand" "")) 0))]
20328 "exact_log2 (INTVAL (operands[2])) >= 0
20329 && REGNO (operands[0]) == REGNO (operands[1])
20330 && peep2_regno_dead_p (0, FLAGS_REG)"
20331 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20332 (clobber (reg:CC FLAGS_REG))])]
20333 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20335 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20336 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20337 ;; many CPUs it is also faster, since special hardware to avoid esp
20338 ;; dependencies is present.
20340 ;; While some of these conversions may be done using splitters, we use peepholes
20341 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20343 ;; Convert prologue esp subtractions to push.
20344 ;; We need register to push. In order to keep verify_flow_info happy we have
20346 ;; - use scratch and clobber it in order to avoid dependencies
20347 ;; - use already live register
20348 ;; We can't use the second way right now, since there is no reliable way how to
20349 ;; verify that given register is live. First choice will also most likely in
20350 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20351 ;; call clobbered registers are dead. We may want to use base pointer as an
20352 ;; alternative when no register is available later.
20355 [(match_scratch:SI 0 "r")
20356 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20357 (clobber (reg:CC FLAGS_REG))
20358 (clobber (mem:BLK (scratch)))])]
20359 "optimize_size || !TARGET_SUB_ESP_4"
20360 [(clobber (match_dup 0))
20361 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20362 (clobber (mem:BLK (scratch)))])])
20365 [(match_scratch:SI 0 "r")
20366 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20367 (clobber (reg:CC FLAGS_REG))
20368 (clobber (mem:BLK (scratch)))])]
20369 "optimize_size || !TARGET_SUB_ESP_8"
20370 [(clobber (match_dup 0))
20371 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20372 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20373 (clobber (mem:BLK (scratch)))])])
20375 ;; Convert esp subtractions to push.
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 "optimize_size || !TARGET_SUB_ESP_4"
20381 [(clobber (match_dup 0))
20382 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20385 [(match_scratch:SI 0 "r")
20386 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20387 (clobber (reg:CC FLAGS_REG))])]
20388 "optimize_size || !TARGET_SUB_ESP_8"
20389 [(clobber (match_dup 0))
20390 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20391 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20393 ;; Convert epilogue deallocator to pop.
20395 [(match_scratch:SI 0 "r")
20396 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20397 (clobber (reg:CC FLAGS_REG))
20398 (clobber (mem:BLK (scratch)))])]
20399 "optimize_size || !TARGET_ADD_ESP_4"
20400 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20401 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20402 (clobber (mem:BLK (scratch)))])]
20405 ;; Two pops case is tricky, since pop causes dependency on destination register.
20406 ;; We use two registers if available.
20408 [(match_scratch:SI 0 "r")
20409 (match_scratch:SI 1 "r")
20410 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20411 (clobber (reg:CC FLAGS_REG))
20412 (clobber (mem:BLK (scratch)))])]
20413 "optimize_size || !TARGET_ADD_ESP_8"
20414 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20415 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20416 (clobber (mem:BLK (scratch)))])
20417 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20418 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20422 [(match_scratch:SI 0 "r")
20423 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20424 (clobber (reg:CC FLAGS_REG))
20425 (clobber (mem:BLK (scratch)))])]
20427 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20428 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20429 (clobber (mem:BLK (scratch)))])
20430 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20431 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20434 ;; Convert esp additions to pop.
20436 [(match_scratch:SI 0 "r")
20437 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20438 (clobber (reg:CC FLAGS_REG))])]
20440 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20441 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20444 ;; Two pops case is tricky, since pop causes dependency on destination register.
20445 ;; We use two registers if available.
20447 [(match_scratch:SI 0 "r")
20448 (match_scratch:SI 1 "r")
20449 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20450 (clobber (reg:CC FLAGS_REG))])]
20452 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20453 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20454 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20455 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20459 [(match_scratch:SI 0 "r")
20460 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20461 (clobber (reg:CC FLAGS_REG))])]
20463 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20464 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20465 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20466 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20469 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20470 ;; required and register dies. Similarly for 128 to plus -128.
20472 [(set (match_operand 0 "flags_reg_operand" "")
20473 (match_operator 1 "compare_operator"
20474 [(match_operand 2 "register_operand" "")
20475 (match_operand 3 "const_int_operand" "")]))]
20476 "(INTVAL (operands[3]) == -1
20477 || INTVAL (operands[3]) == 1
20478 || INTVAL (operands[3]) == 128)
20479 && ix86_match_ccmode (insn, CCGCmode)
20480 && peep2_reg_dead_p (1, operands[2])"
20481 [(parallel [(set (match_dup 0)
20482 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20483 (clobber (match_dup 2))])]
20487 [(match_scratch:DI 0 "r")
20488 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20489 (clobber (reg:CC FLAGS_REG))
20490 (clobber (mem:BLK (scratch)))])]
20491 "optimize_size || !TARGET_SUB_ESP_4"
20492 [(clobber (match_dup 0))
20493 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20494 (clobber (mem:BLK (scratch)))])])
20497 [(match_scratch:DI 0 "r")
20498 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20499 (clobber (reg:CC FLAGS_REG))
20500 (clobber (mem:BLK (scratch)))])]
20501 "optimize_size || !TARGET_SUB_ESP_8"
20502 [(clobber (match_dup 0))
20503 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20504 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20505 (clobber (mem:BLK (scratch)))])])
20507 ;; Convert esp subtractions to push.
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 "optimize_size || !TARGET_SUB_ESP_4"
20513 [(clobber (match_dup 0))
20514 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20517 [(match_scratch:DI 0 "r")
20518 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20519 (clobber (reg:CC FLAGS_REG))])]
20520 "optimize_size || !TARGET_SUB_ESP_8"
20521 [(clobber (match_dup 0))
20522 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20523 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20525 ;; Convert epilogue deallocator to pop.
20527 [(match_scratch:DI 0 "r")
20528 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20529 (clobber (reg:CC FLAGS_REG))
20530 (clobber (mem:BLK (scratch)))])]
20531 "optimize_size || !TARGET_ADD_ESP_4"
20532 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20533 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20534 (clobber (mem:BLK (scratch)))])]
20537 ;; Two pops case is tricky, since pop causes dependency on destination register.
20538 ;; We use two registers if available.
20540 [(match_scratch:DI 0 "r")
20541 (match_scratch:DI 1 "r")
20542 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20543 (clobber (reg:CC FLAGS_REG))
20544 (clobber (mem:BLK (scratch)))])]
20545 "optimize_size || !TARGET_ADD_ESP_8"
20546 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20547 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20548 (clobber (mem:BLK (scratch)))])
20549 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20550 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20554 [(match_scratch:DI 0 "r")
20555 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20556 (clobber (reg:CC FLAGS_REG))
20557 (clobber (mem:BLK (scratch)))])]
20559 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20560 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20561 (clobber (mem:BLK (scratch)))])
20562 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20563 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20566 ;; Convert esp additions to pop.
20568 [(match_scratch:DI 0 "r")
20569 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20570 (clobber (reg:CC FLAGS_REG))])]
20572 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20573 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20576 ;; Two pops case is tricky, since pop causes dependency on destination register.
20577 ;; We use two registers if available.
20579 [(match_scratch:DI 0 "r")
20580 (match_scratch:DI 1 "r")
20581 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20582 (clobber (reg:CC FLAGS_REG))])]
20584 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20585 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20586 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20587 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20591 [(match_scratch:DI 0 "r")
20592 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20593 (clobber (reg:CC FLAGS_REG))])]
20595 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20596 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20597 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20598 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20601 ;; Convert imul by three, five and nine into lea
20604 [(set (match_operand:SI 0 "register_operand" "")
20605 (mult:SI (match_operand:SI 1 "register_operand" "")
20606 (match_operand:SI 2 "const_int_operand" "")))
20607 (clobber (reg:CC FLAGS_REG))])]
20608 "INTVAL (operands[2]) == 3
20609 || INTVAL (operands[2]) == 5
20610 || INTVAL (operands[2]) == 9"
20611 [(set (match_dup 0)
20612 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20614 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20618 [(set (match_operand:SI 0 "register_operand" "")
20619 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20620 (match_operand:SI 2 "const_int_operand" "")))
20621 (clobber (reg:CC FLAGS_REG))])]
20623 && (INTVAL (operands[2]) == 3
20624 || INTVAL (operands[2]) == 5
20625 || INTVAL (operands[2]) == 9)"
20626 [(set (match_dup 0) (match_dup 1))
20628 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20630 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20634 [(set (match_operand:DI 0 "register_operand" "")
20635 (mult:DI (match_operand:DI 1 "register_operand" "")
20636 (match_operand:DI 2 "const_int_operand" "")))
20637 (clobber (reg:CC FLAGS_REG))])]
20639 && (INTVAL (operands[2]) == 3
20640 || INTVAL (operands[2]) == 5
20641 || INTVAL (operands[2]) == 9)"
20642 [(set (match_dup 0)
20643 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20645 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20649 [(set (match_operand:DI 0 "register_operand" "")
20650 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20651 (match_operand:DI 2 "const_int_operand" "")))
20652 (clobber (reg:CC FLAGS_REG))])]
20655 && (INTVAL (operands[2]) == 3
20656 || INTVAL (operands[2]) == 5
20657 || INTVAL (operands[2]) == 9)"
20658 [(set (match_dup 0) (match_dup 1))
20660 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20662 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20664 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20665 ;; imul $32bit_imm, reg, reg is direct decoded.
20667 [(match_scratch:DI 3 "r")
20668 (parallel [(set (match_operand:DI 0 "register_operand" "")
20669 (mult:DI (match_operand:DI 1 "memory_operand" "")
20670 (match_operand:DI 2 "immediate_operand" "")))
20671 (clobber (reg:CC FLAGS_REG))])]
20672 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20673 && !satisfies_constraint_K (operands[2])"
20674 [(set (match_dup 3) (match_dup 1))
20675 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20676 (clobber (reg:CC FLAGS_REG))])]
20680 [(match_scratch:SI 3 "r")
20681 (parallel [(set (match_operand:SI 0 "register_operand" "")
20682 (mult:SI (match_operand:SI 1 "memory_operand" "")
20683 (match_operand:SI 2 "immediate_operand" "")))
20684 (clobber (reg:CC FLAGS_REG))])]
20685 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20686 && !satisfies_constraint_K (operands[2])"
20687 [(set (match_dup 3) (match_dup 1))
20688 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20689 (clobber (reg:CC FLAGS_REG))])]
20693 [(match_scratch:SI 3 "r")
20694 (parallel [(set (match_operand:DI 0 "register_operand" "")
20696 (mult:SI (match_operand:SI 1 "memory_operand" "")
20697 (match_operand:SI 2 "immediate_operand" ""))))
20698 (clobber (reg:CC FLAGS_REG))])]
20699 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20700 && !satisfies_constraint_K (operands[2])"
20701 [(set (match_dup 3) (match_dup 1))
20702 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20703 (clobber (reg:CC FLAGS_REG))])]
20706 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20707 ;; Convert it into imul reg, reg
20708 ;; It would be better to force assembler to encode instruction using long
20709 ;; immediate, but there is apparently no way to do so.
20711 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20712 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20713 (match_operand:DI 2 "const_int_operand" "")))
20714 (clobber (reg:CC FLAGS_REG))])
20715 (match_scratch:DI 3 "r")]
20716 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20717 && satisfies_constraint_K (operands[2])"
20718 [(set (match_dup 3) (match_dup 2))
20719 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20720 (clobber (reg:CC FLAGS_REG))])]
20722 if (!rtx_equal_p (operands[0], operands[1]))
20723 emit_move_insn (operands[0], operands[1]);
20727 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20728 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20729 (match_operand:SI 2 "const_int_operand" "")))
20730 (clobber (reg:CC FLAGS_REG))])
20731 (match_scratch:SI 3 "r")]
20732 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20733 && satisfies_constraint_K (operands[2])"
20734 [(set (match_dup 3) (match_dup 2))
20735 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20736 (clobber (reg:CC FLAGS_REG))])]
20738 if (!rtx_equal_p (operands[0], operands[1]))
20739 emit_move_insn (operands[0], operands[1]);
20743 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20744 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20745 (match_operand:HI 2 "immediate_operand" "")))
20746 (clobber (reg:CC FLAGS_REG))])
20747 (match_scratch:HI 3 "r")]
20748 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20749 [(set (match_dup 3) (match_dup 2))
20750 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20751 (clobber (reg:CC FLAGS_REG))])]
20753 if (!rtx_equal_p (operands[0], operands[1]))
20754 emit_move_insn (operands[0], operands[1]);
20757 ;; After splitting up read-modify operations, array accesses with memory
20758 ;; operands might end up in form:
20760 ;; movl 4(%esp), %edx
20762 ;; instead of pre-splitting:
20764 ;; addl 4(%esp), %eax
20766 ;; movl 4(%esp), %edx
20767 ;; leal (%edx,%eax,4), %eax
20770 [(parallel [(set (match_operand 0 "register_operand" "")
20771 (ashift (match_operand 1 "register_operand" "")
20772 (match_operand 2 "const_int_operand" "")))
20773 (clobber (reg:CC FLAGS_REG))])
20774 (set (match_operand 3 "register_operand")
20775 (match_operand 4 "x86_64_general_operand" ""))
20776 (parallel [(set (match_operand 5 "register_operand" "")
20777 (plus (match_operand 6 "register_operand" "")
20778 (match_operand 7 "register_operand" "")))
20779 (clobber (reg:CC FLAGS_REG))])]
20780 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20781 /* Validate MODE for lea. */
20782 && ((!TARGET_PARTIAL_REG_STALL
20783 && (GET_MODE (operands[0]) == QImode
20784 || GET_MODE (operands[0]) == HImode))
20785 || GET_MODE (operands[0]) == SImode
20786 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20787 /* We reorder load and the shift. */
20788 && !rtx_equal_p (operands[1], operands[3])
20789 && !reg_overlap_mentioned_p (operands[0], operands[4])
20790 /* Last PLUS must consist of operand 0 and 3. */
20791 && !rtx_equal_p (operands[0], operands[3])
20792 && (rtx_equal_p (operands[3], operands[6])
20793 || rtx_equal_p (operands[3], operands[7]))
20794 && (rtx_equal_p (operands[0], operands[6])
20795 || rtx_equal_p (operands[0], operands[7]))
20796 /* The intermediate operand 0 must die or be same as output. */
20797 && (rtx_equal_p (operands[0], operands[5])
20798 || peep2_reg_dead_p (3, operands[0]))"
20799 [(set (match_dup 3) (match_dup 4))
20800 (set (match_dup 0) (match_dup 1))]
20802 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20803 int scale = 1 << INTVAL (operands[2]);
20804 rtx index = gen_lowpart (Pmode, operands[1]);
20805 rtx base = gen_lowpart (Pmode, operands[3]);
20806 rtx dest = gen_lowpart (mode, operands[5]);
20808 operands[1] = gen_rtx_PLUS (Pmode, base,
20809 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20811 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20812 operands[0] = dest;
20815 ;; Call-value patterns last so that the wildcard operand does not
20816 ;; disrupt insn-recog's switch tables.
20818 (define_insn "*call_value_pop_0"
20819 [(set (match_operand 0 "" "")
20820 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20821 (match_operand:SI 2 "" "")))
20822 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20823 (match_operand:SI 3 "immediate_operand" "")))]
20826 if (SIBLING_CALL_P (insn))
20829 return "call\t%P1";
20831 [(set_attr "type" "callv")])
20833 (define_insn "*call_value_pop_1"
20834 [(set (match_operand 0 "" "")
20835 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20836 (match_operand:SI 2 "" "")))
20837 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20838 (match_operand:SI 3 "immediate_operand" "i")))]
20841 if (constant_call_address_operand (operands[1], Pmode))
20843 if (SIBLING_CALL_P (insn))
20846 return "call\t%P1";
20848 if (SIBLING_CALL_P (insn))
20851 return "call\t%A1";
20853 [(set_attr "type" "callv")])
20855 (define_insn "*call_value_0"
20856 [(set (match_operand 0 "" "")
20857 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20858 (match_operand:SI 2 "" "")))]
20861 if (SIBLING_CALL_P (insn))
20864 return "call\t%P1";
20866 [(set_attr "type" "callv")])
20868 (define_insn "*call_value_0_rex64"
20869 [(set (match_operand 0 "" "")
20870 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20871 (match_operand:DI 2 "const_int_operand" "")))]
20874 if (SIBLING_CALL_P (insn))
20877 return "call\t%P1";
20879 [(set_attr "type" "callv")])
20881 (define_insn "*call_value_1"
20882 [(set (match_operand 0 "" "")
20883 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20884 (match_operand:SI 2 "" "")))]
20885 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20887 if (constant_call_address_operand (operands[1], Pmode))
20888 return "call\t%P1";
20889 return "call\t%A1";
20891 [(set_attr "type" "callv")])
20893 (define_insn "*sibcall_value_1"
20894 [(set (match_operand 0 "" "")
20895 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20896 (match_operand:SI 2 "" "")))]
20897 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20899 if (constant_call_address_operand (operands[1], Pmode))
20903 [(set_attr "type" "callv")])
20905 (define_insn "*call_value_1_rex64"
20906 [(set (match_operand 0 "" "")
20907 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20908 (match_operand:DI 2 "" "")))]
20909 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20911 if (constant_call_address_operand (operands[1], Pmode))
20912 return "call\t%P1";
20913 return "call\t%A1";
20915 [(set_attr "type" "callv")])
20917 (define_insn "*sibcall_value_1_rex64"
20918 [(set (match_operand 0 "" "")
20919 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20920 (match_operand:DI 2 "" "")))]
20921 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20923 [(set_attr "type" "callv")])
20925 (define_insn "*sibcall_value_1_rex64_v"
20926 [(set (match_operand 0 "" "")
20927 (call (mem:QI (reg:DI 40))
20928 (match_operand:DI 1 "" "")))]
20929 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20931 [(set_attr "type" "callv")])
20933 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20934 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20935 ;; caught for use by garbage collectors and the like. Using an insn that
20936 ;; maps to SIGILL makes it more likely the program will rightfully die.
20937 ;; Keeping with tradition, "6" is in honor of #UD.
20938 (define_insn "trap"
20939 [(trap_if (const_int 1) (const_int 6))]
20941 { return ASM_SHORT "0x0b0f"; }
20942 [(set_attr "length" "2")])
20944 (define_expand "sse_prologue_save"
20945 [(parallel [(set (match_operand:BLK 0 "" "")
20946 (unspec:BLK [(reg:DI 21)
20953 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20954 (use (match_operand:DI 1 "register_operand" ""))
20955 (use (match_operand:DI 2 "immediate_operand" ""))
20956 (use (label_ref:DI (match_operand 3 "" "")))])]
20960 (define_insn "*sse_prologue_save_insn"
20961 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20962 (match_operand:DI 4 "const_int_operand" "n")))
20963 (unspec:BLK [(reg:DI 21)
20970 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20971 (use (match_operand:DI 1 "register_operand" "r"))
20972 (use (match_operand:DI 2 "const_int_operand" "i"))
20973 (use (label_ref:DI (match_operand 3 "" "X")))]
20975 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20976 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20980 operands[0] = gen_rtx_MEM (Pmode,
20981 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20982 output_asm_insn (\"jmp\\t%A1\", operands);
20983 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20985 operands[4] = adjust_address (operands[0], DImode, i*16);
20986 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20987 PUT_MODE (operands[4], TImode);
20988 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20989 output_asm_insn (\"rex\", operands);
20990 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20992 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20993 CODE_LABEL_NUMBER (operands[3]));
20997 [(set_attr "type" "other")
20998 (set_attr "length_immediate" "0")
20999 (set_attr "length_address" "0")
21000 (set_attr "length" "135")
21001 (set_attr "memory" "store")
21002 (set_attr "modrm" "0")
21003 (set_attr "mode" "DI")])
21005 (define_expand "prefetch"
21006 [(prefetch (match_operand 0 "address_operand" "")
21007 (match_operand:SI 1 "const_int_operand" "")
21008 (match_operand:SI 2 "const_int_operand" ""))]
21009 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21011 int rw = INTVAL (operands[1]);
21012 int locality = INTVAL (operands[2]);
21014 gcc_assert (rw == 0 || rw == 1);
21015 gcc_assert (locality >= 0 && locality <= 3);
21016 gcc_assert (GET_MODE (operands[0]) == Pmode
21017 || GET_MODE (operands[0]) == VOIDmode);
21019 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21020 supported by SSE counterpart or the SSE prefetch is not available
21021 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21023 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21024 operands[2] = GEN_INT (3);
21026 operands[1] = const0_rtx;
21029 (define_insn "*prefetch_sse"
21030 [(prefetch (match_operand:SI 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_sse_rex"
21048 [(prefetch (match_operand:DI 0 "address_operand" "p")
21050 (match_operand:SI 1 "const_int_operand" ""))]
21051 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21053 static const char * const patterns[4] = {
21054 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21057 int locality = INTVAL (operands[1]);
21058 gcc_assert (locality >= 0 && locality <= 3);
21060 return patterns[locality];
21062 [(set_attr "type" "sse")
21063 (set_attr "memory" "none")])
21065 (define_insn "*prefetch_3dnow"
21066 [(prefetch (match_operand:SI 0 "address_operand" "p")
21067 (match_operand:SI 1 "const_int_operand" "n")
21069 "TARGET_3DNOW && !TARGET_64BIT"
21071 if (INTVAL (operands[1]) == 0)
21072 return "prefetch\t%a0";
21074 return "prefetchw\t%a0";
21076 [(set_attr "type" "mmx")
21077 (set_attr "memory" "none")])
21079 (define_insn "*prefetch_3dnow_rex"
21080 [(prefetch (match_operand:DI 0 "address_operand" "p")
21081 (match_operand:SI 1 "const_int_operand" "n")
21083 "TARGET_3DNOW && TARGET_64BIT"
21085 if (INTVAL (operands[1]) == 0)
21086 return "prefetch\t%a0";
21088 return "prefetchw\t%a0";
21090 [(set_attr "type" "mmx")
21091 (set_attr "memory" "none")])
21093 (define_expand "stack_protect_set"
21094 [(match_operand 0 "memory_operand" "")
21095 (match_operand 1 "memory_operand" "")]
21098 #ifdef TARGET_THREAD_SSP_OFFSET
21100 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21101 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21103 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21104 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21107 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21109 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21114 (define_insn "stack_protect_set_si"
21115 [(set (match_operand:SI 0 "memory_operand" "=m")
21116 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21117 (set (match_scratch:SI 2 "=&r") (const_int 0))
21118 (clobber (reg:CC FLAGS_REG))]
21120 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21121 [(set_attr "type" "multi")])
21123 (define_insn "stack_protect_set_di"
21124 [(set (match_operand:DI 0 "memory_operand" "=m")
21125 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21126 (set (match_scratch:DI 2 "=&r") (const_int 0))
21127 (clobber (reg:CC FLAGS_REG))]
21129 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21130 [(set_attr "type" "multi")])
21132 (define_insn "stack_tls_protect_set_si"
21133 [(set (match_operand:SI 0 "memory_operand" "=m")
21134 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21135 (set (match_scratch:SI 2 "=&r") (const_int 0))
21136 (clobber (reg:CC FLAGS_REG))]
21138 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21139 [(set_attr "type" "multi")])
21141 (define_insn "stack_tls_protect_set_di"
21142 [(set (match_operand:DI 0 "memory_operand" "=m")
21143 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21144 (set (match_scratch:DI 2 "=&r") (const_int 0))
21145 (clobber (reg:CC FLAGS_REG))]
21148 /* The kernel uses a different segment register for performance reasons; a
21149 system call would not have to trash the userspace segment register,
21150 which would be expensive */
21151 if (ix86_cmodel != CM_KERNEL)
21152 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21154 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21156 [(set_attr "type" "multi")])
21158 (define_expand "stack_protect_test"
21159 [(match_operand 0 "memory_operand" "")
21160 (match_operand 1 "memory_operand" "")
21161 (match_operand 2 "" "")]
21164 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21165 ix86_compare_op0 = operands[0];
21166 ix86_compare_op1 = operands[1];
21167 ix86_compare_emitted = flags;
21169 #ifdef TARGET_THREAD_SSP_OFFSET
21171 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21172 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21174 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21175 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21178 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21180 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21182 emit_jump_insn (gen_beq (operands[2]));
21186 (define_insn "stack_protect_test_si"
21187 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21188 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21189 (match_operand:SI 2 "memory_operand" "m")]
21191 (clobber (match_scratch:SI 3 "=&r"))]
21193 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21194 [(set_attr "type" "multi")])
21196 (define_insn "stack_protect_test_di"
21197 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21198 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21199 (match_operand:DI 2 "memory_operand" "m")]
21201 (clobber (match_scratch:DI 3 "=&r"))]
21203 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21204 [(set_attr "type" "multi")])
21206 (define_insn "stack_tls_protect_test_si"
21207 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21208 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21209 (match_operand:SI 2 "const_int_operand" "i")]
21210 UNSPEC_SP_TLS_TEST))
21211 (clobber (match_scratch:SI 3 "=r"))]
21213 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21214 [(set_attr "type" "multi")])
21216 (define_insn "stack_tls_protect_test_di"
21217 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21218 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21219 (match_operand:DI 2 "const_int_operand" "i")]
21220 UNSPEC_SP_TLS_TEST))
21221 (clobber (match_scratch:DI 3 "=r"))]
21224 /* The kernel uses a different segment register for performance reasons; a
21225 system call would not have to trash the userspace segment register,
21226 which would be expensive */
21227 if (ix86_cmodel != CM_KERNEL)
21228 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21230 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21232 [(set_attr "type" "multi")])
21236 (include "sync.md")