1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 30)
98 (UNSPEC_NOP 38) ; prevents combiner cleverness
109 ; Generic math support
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
125 (UNSPEC_FRNDINT_FLOOR 70)
126 (UNSPEC_FRNDINT_CEIL 71)
127 (UNSPEC_FRNDINT_TRUNC 72)
128 (UNSPEC_FRNDINT_MASK_PM 73)
129 (UNSPEC_FIST_FLOOR 74)
130 (UNSPEC_FIST_CEIL 75)
132 ; x87 Double output FP
133 (UNSPEC_SINCOS_COS 80)
134 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
149 (UNSPEC_SP_TLS_SET 102)
150 (UNSPEC_SP_TLS_TEST 103)
154 [(UNSPECV_BLOCKAGE 0)
155 (UNSPECV_STACK_PROBE 1)
164 (UNSPECV_CMPXCHG_1 10)
165 (UNSPECV_CMPXCHG_2 11)
170 ;; Registers by name.
179 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
182 ;; In C guard expressions, put expressions which may be compile-time
183 ;; constants first. This allows for better optimization. For
184 ;; example, write "TARGET_64BIT && reload_completed", not
185 ;; "reload_completed && TARGET_64BIT".
188 ;; Processor type. This attribute must exactly match the processor_type
189 ;; enumeration in i386.h.
190 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona,generic32,generic64"
191 (const (symbol_ref "ix86_tune")))
193 ;; A basic instruction type. Refinements due to arguments to be
194 ;; provided in other attributes.
197 alu,alu1,negnot,imov,imovx,lea,
198 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
199 icmp,test,ibr,setcc,icmov,
200 push,pop,call,callv,leave,
202 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
203 sselog,sselog1,sseiadd,sseishft,sseimul,
204 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
205 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
206 (const_string "other"))
208 ;; Main data type used by the insn
210 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
211 (const_string "unknown"))
213 ;; The CPU unit operations uses.
214 (define_attr "unit" "integer,i387,sse,mmx,unknown"
215 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
216 (const_string "i387")
217 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
218 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
220 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
222 (eq_attr "type" "other")
223 (const_string "unknown")]
224 (const_string "integer")))
226 ;; The (bounding maximum) length of an instruction immediate.
227 (define_attr "length_immediate" ""
228 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
230 (eq_attr "unit" "i387,sse,mmx")
232 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
234 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
235 (eq_attr "type" "imov,test")
236 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
237 (eq_attr "type" "call")
238 (if_then_else (match_operand 0 "constant_call_address_operand" "")
241 (eq_attr "type" "callv")
242 (if_then_else (match_operand 1 "constant_call_address_operand" "")
245 ;; We don't know the size before shorten_branches. Expect
246 ;; the instruction to fit for better scheduling.
247 (eq_attr "type" "ibr")
250 (symbol_ref "/* Update immediate_length and other attributes! */
251 gcc_unreachable (),1")))
253 ;; The (bounding maximum) length of an instruction address.
254 (define_attr "length_address" ""
255 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
257 (and (eq_attr "type" "call")
258 (match_operand 0 "constant_call_address_operand" ""))
260 (and (eq_attr "type" "callv")
261 (match_operand 1 "constant_call_address_operand" ""))
264 (symbol_ref "ix86_attr_length_address_default (insn)")))
266 ;; Set when length prefix is used.
267 (define_attr "prefix_data16" ""
268 (if_then_else (ior (eq_attr "mode" "HI")
269 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
273 ;; Set when string REP prefix is used.
274 (define_attr "prefix_rep" ""
275 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
279 ;; Set when 0f opcode prefix is used.
280 (define_attr "prefix_0f" ""
282 (ior (eq_attr "type" "imovx,setcc,icmov")
283 (eq_attr "unit" "sse,mmx"))
287 ;; Set when REX opcode prefix is used.
288 (define_attr "prefix_rex" ""
289 (cond [(and (eq_attr "mode" "DI")
290 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
292 (and (eq_attr "mode" "QI")
293 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
296 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
302 ;; Set when modrm byte is used.
303 (define_attr "modrm" ""
304 (cond [(eq_attr "type" "str,cld,leave")
306 (eq_attr "unit" "i387")
308 (and (eq_attr "type" "incdec")
309 (ior (match_operand:SI 1 "register_operand" "")
310 (match_operand:HI 1 "register_operand" "")))
312 (and (eq_attr "type" "push")
313 (not (match_operand 1 "memory_operand" "")))
315 (and (eq_attr "type" "pop")
316 (not (match_operand 0 "memory_operand" "")))
318 (and (eq_attr "type" "imov")
319 (ior (and (match_operand 0 "register_operand" "")
320 (match_operand 1 "immediate_operand" ""))
321 (ior (and (match_operand 0 "ax_reg_operand" "")
322 (match_operand 1 "memory_displacement_only_operand" ""))
323 (and (match_operand 0 "memory_displacement_only_operand" "")
324 (match_operand 1 "ax_reg_operand" "")))))
326 (and (eq_attr "type" "call")
327 (match_operand 0 "constant_call_address_operand" ""))
329 (and (eq_attr "type" "callv")
330 (match_operand 1 "constant_call_address_operand" ""))
335 ;; The (bounding maximum) length of an instruction in bytes.
336 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
337 ;; Later we may want to split them and compute proper length as for
339 (define_attr "length" ""
340 (cond [(eq_attr "type" "other,multi,fistp,frndint")
342 (eq_attr "type" "fcmp")
344 (eq_attr "unit" "i387")
346 (plus (attr "prefix_data16")
347 (attr "length_address")))]
348 (plus (plus (attr "modrm")
349 (plus (attr "prefix_0f")
350 (plus (attr "prefix_rex")
352 (plus (attr "prefix_rep")
353 (plus (attr "prefix_data16")
354 (plus (attr "length_immediate")
355 (attr "length_address")))))))
357 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
358 ;; `store' if there is a simple memory reference therein, or `unknown'
359 ;; if the instruction is complex.
361 (define_attr "memory" "none,load,store,both,unknown"
362 (cond [(eq_attr "type" "other,multi,str")
363 (const_string "unknown")
364 (eq_attr "type" "lea,fcmov,fpspc,cld")
365 (const_string "none")
366 (eq_attr "type" "fistp,leave")
367 (const_string "both")
368 (eq_attr "type" "frndint")
369 (const_string "load")
370 (eq_attr "type" "push")
371 (if_then_else (match_operand 1 "memory_operand" "")
372 (const_string "both")
373 (const_string "store"))
374 (eq_attr "type" "pop")
375 (if_then_else (match_operand 0 "memory_operand" "")
376 (const_string "both")
377 (const_string "load"))
378 (eq_attr "type" "setcc")
379 (if_then_else (match_operand 0 "memory_operand" "")
380 (const_string "store")
381 (const_string "none"))
382 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
383 (if_then_else (ior (match_operand 0 "memory_operand" "")
384 (match_operand 1 "memory_operand" ""))
385 (const_string "load")
386 (const_string "none"))
387 (eq_attr "type" "ibr")
388 (if_then_else (match_operand 0 "memory_operand" "")
389 (const_string "load")
390 (const_string "none"))
391 (eq_attr "type" "call")
392 (if_then_else (match_operand 0 "constant_call_address_operand" "")
393 (const_string "none")
394 (const_string "load"))
395 (eq_attr "type" "callv")
396 (if_then_else (match_operand 1 "constant_call_address_operand" "")
397 (const_string "none")
398 (const_string "load"))
399 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
400 (match_operand 1 "memory_operand" ""))
401 (const_string "both")
402 (and (match_operand 0 "memory_operand" "")
403 (match_operand 1 "memory_operand" ""))
404 (const_string "both")
405 (match_operand 0 "memory_operand" "")
406 (const_string "store")
407 (match_operand 1 "memory_operand" "")
408 (const_string "load")
410 "!alu1,negnot,ishift1,
411 imov,imovx,icmp,test,
413 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
414 mmx,mmxmov,mmxcmp,mmxcvt")
415 (match_operand 2 "memory_operand" ""))
416 (const_string "load")
417 (and (eq_attr "type" "icmov")
418 (match_operand 3 "memory_operand" ""))
419 (const_string "load")
421 (const_string "none")))
423 ;; Indicates if an instruction has both an immediate and a displacement.
425 (define_attr "imm_disp" "false,true,unknown"
426 (cond [(eq_attr "type" "other,multi")
427 (const_string "unknown")
428 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
429 (and (match_operand 0 "memory_displacement_operand" "")
430 (match_operand 1 "immediate_operand" "")))
431 (const_string "true")
432 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
433 (and (match_operand 0 "memory_displacement_operand" "")
434 (match_operand 2 "immediate_operand" "")))
435 (const_string "true")
437 (const_string "false")))
439 ;; Indicates if an FP operation has an integer source.
441 (define_attr "fp_int_src" "false,true"
442 (const_string "false"))
444 ;; Defines rounding mode of an FP operation.
446 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
447 (const_string "any"))
449 ;; Describe a user's asm statement.
450 (define_asm_attributes
451 [(set_attr "length" "128")
452 (set_attr "type" "multi")])
454 ;; All x87 floating point modes
455 (define_mode_macro X87MODEF [SF DF XF])
457 ;; All integer modes handled by x87 fisttp operator.
458 (define_mode_macro X87MODEI [HI SI DI])
460 ;; All integer modes handled by integer x87 operators.
461 (define_mode_macro X87MODEI12 [HI SI])
463 ;; All SSE floating point modes
464 (define_mode_macro SSEMODEF [SF DF])
466 ;; All integer modes handled by SSE cvtts?2si* operators.
467 (define_mode_macro SSEMODEI24 [SI DI])
470 ;; Scheduling descriptions
472 (include "pentium.md")
475 (include "athlon.md")
478 ;; Operand and operator predicates
480 (include "predicates.md")
483 ;; Compare instructions.
485 ;; All compare insns have expanders that save the operands away without
486 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
487 ;; after the cmp) will actually emit the cmpM.
489 (define_expand "cmpti"
490 [(set (reg:CC FLAGS_REG)
491 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
492 (match_operand:TI 1 "x86_64_general_operand" "")))]
495 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
496 operands[0] = force_reg (TImode, operands[0]);
497 ix86_compare_op0 = operands[0];
498 ix86_compare_op1 = operands[1];
502 (define_expand "cmpdi"
503 [(set (reg:CC FLAGS_REG)
504 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
505 (match_operand:DI 1 "x86_64_general_operand" "")))]
508 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
509 operands[0] = force_reg (DImode, operands[0]);
510 ix86_compare_op0 = operands[0];
511 ix86_compare_op1 = operands[1];
515 (define_expand "cmpsi"
516 [(set (reg:CC FLAGS_REG)
517 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
518 (match_operand:SI 1 "general_operand" "")))]
521 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
522 operands[0] = force_reg (SImode, operands[0]);
523 ix86_compare_op0 = operands[0];
524 ix86_compare_op1 = operands[1];
528 (define_expand "cmphi"
529 [(set (reg:CC FLAGS_REG)
530 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
531 (match_operand:HI 1 "general_operand" "")))]
534 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
535 operands[0] = force_reg (HImode, operands[0]);
536 ix86_compare_op0 = operands[0];
537 ix86_compare_op1 = operands[1];
541 (define_expand "cmpqi"
542 [(set (reg:CC FLAGS_REG)
543 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
544 (match_operand:QI 1 "general_operand" "")))]
547 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
548 operands[0] = force_reg (QImode, operands[0]);
549 ix86_compare_op0 = operands[0];
550 ix86_compare_op1 = operands[1];
554 (define_insn "cmpdi_ccno_1_rex64"
555 [(set (reg FLAGS_REG)
556 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
557 (match_operand:DI 1 "const0_operand" "n,n")))]
558 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
560 test{q}\t{%0, %0|%0, %0}
561 cmp{q}\t{%1, %0|%0, %1}"
562 [(set_attr "type" "test,icmp")
563 (set_attr "length_immediate" "0,1")
564 (set_attr "mode" "DI")])
566 (define_insn "*cmpdi_minus_1_rex64"
567 [(set (reg FLAGS_REG)
568 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
569 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
571 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
572 "cmp{q}\t{%1, %0|%0, %1}"
573 [(set_attr "type" "icmp")
574 (set_attr "mode" "DI")])
576 (define_expand "cmpdi_1_rex64"
577 [(set (reg:CC FLAGS_REG)
578 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
579 (match_operand:DI 1 "general_operand" "")))]
583 (define_insn "cmpdi_1_insn_rex64"
584 [(set (reg FLAGS_REG)
585 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
586 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
587 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
588 "cmp{q}\t{%1, %0|%0, %1}"
589 [(set_attr "type" "icmp")
590 (set_attr "mode" "DI")])
593 (define_insn "*cmpsi_ccno_1"
594 [(set (reg FLAGS_REG)
595 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
596 (match_operand:SI 1 "const0_operand" "n,n")))]
597 "ix86_match_ccmode (insn, CCNOmode)"
599 test{l}\t{%0, %0|%0, %0}
600 cmp{l}\t{%1, %0|%0, %1}"
601 [(set_attr "type" "test,icmp")
602 (set_attr "length_immediate" "0,1")
603 (set_attr "mode" "SI")])
605 (define_insn "*cmpsi_minus_1"
606 [(set (reg FLAGS_REG)
607 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
608 (match_operand:SI 1 "general_operand" "ri,mr"))
610 "ix86_match_ccmode (insn, CCGOCmode)"
611 "cmp{l}\t{%1, %0|%0, %1}"
612 [(set_attr "type" "icmp")
613 (set_attr "mode" "SI")])
615 (define_expand "cmpsi_1"
616 [(set (reg:CC FLAGS_REG)
617 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
618 (match_operand:SI 1 "general_operand" "ri,mr")))]
622 (define_insn "*cmpsi_1_insn"
623 [(set (reg FLAGS_REG)
624 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625 (match_operand:SI 1 "general_operand" "ri,mr")))]
626 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
627 && ix86_match_ccmode (insn, CCmode)"
628 "cmp{l}\t{%1, %0|%0, %1}"
629 [(set_attr "type" "icmp")
630 (set_attr "mode" "SI")])
632 (define_insn "*cmphi_ccno_1"
633 [(set (reg FLAGS_REG)
634 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
635 (match_operand:HI 1 "const0_operand" "n,n")))]
636 "ix86_match_ccmode (insn, CCNOmode)"
638 test{w}\t{%0, %0|%0, %0}
639 cmp{w}\t{%1, %0|%0, %1}"
640 [(set_attr "type" "test,icmp")
641 (set_attr "length_immediate" "0,1")
642 (set_attr "mode" "HI")])
644 (define_insn "*cmphi_minus_1"
645 [(set (reg FLAGS_REG)
646 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
647 (match_operand:HI 1 "general_operand" "ri,mr"))
649 "ix86_match_ccmode (insn, CCGOCmode)"
650 "cmp{w}\t{%1, %0|%0, %1}"
651 [(set_attr "type" "icmp")
652 (set_attr "mode" "HI")])
654 (define_insn "*cmphi_1"
655 [(set (reg FLAGS_REG)
656 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
657 (match_operand:HI 1 "general_operand" "ri,mr")))]
658 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
659 && ix86_match_ccmode (insn, CCmode)"
660 "cmp{w}\t{%1, %0|%0, %1}"
661 [(set_attr "type" "icmp")
662 (set_attr "mode" "HI")])
664 (define_insn "*cmpqi_ccno_1"
665 [(set (reg FLAGS_REG)
666 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
667 (match_operand:QI 1 "const0_operand" "n,n")))]
668 "ix86_match_ccmode (insn, CCNOmode)"
670 test{b}\t{%0, %0|%0, %0}
671 cmp{b}\t{$0, %0|%0, 0}"
672 [(set_attr "type" "test,icmp")
673 (set_attr "length_immediate" "0,1")
674 (set_attr "mode" "QI")])
676 (define_insn "*cmpqi_1"
677 [(set (reg FLAGS_REG)
678 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
679 (match_operand:QI 1 "general_operand" "qi,mq")))]
680 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
681 && ix86_match_ccmode (insn, CCmode)"
682 "cmp{b}\t{%1, %0|%0, %1}"
683 [(set_attr "type" "icmp")
684 (set_attr "mode" "QI")])
686 (define_insn "*cmpqi_minus_1"
687 [(set (reg FLAGS_REG)
688 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
689 (match_operand:QI 1 "general_operand" "qi,mq"))
691 "ix86_match_ccmode (insn, CCGOCmode)"
692 "cmp{b}\t{%1, %0|%0, %1}"
693 [(set_attr "type" "icmp")
694 (set_attr "mode" "QI")])
696 (define_insn "*cmpqi_ext_1"
697 [(set (reg FLAGS_REG)
699 (match_operand:QI 0 "general_operand" "Qm")
702 (match_operand 1 "ext_register_operand" "Q")
705 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
706 "cmp{b}\t{%h1, %0|%0, %h1}"
707 [(set_attr "type" "icmp")
708 (set_attr "mode" "QI")])
710 (define_insn "*cmpqi_ext_1_rex64"
711 [(set (reg FLAGS_REG)
713 (match_operand:QI 0 "register_operand" "Q")
716 (match_operand 1 "ext_register_operand" "Q")
719 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720 "cmp{b}\t{%h1, %0|%0, %h1}"
721 [(set_attr "type" "icmp")
722 (set_attr "mode" "QI")])
724 (define_insn "*cmpqi_ext_2"
725 [(set (reg FLAGS_REG)
729 (match_operand 0 "ext_register_operand" "Q")
732 (match_operand:QI 1 "const0_operand" "n")))]
733 "ix86_match_ccmode (insn, CCNOmode)"
735 [(set_attr "type" "test")
736 (set_attr "length_immediate" "0")
737 (set_attr "mode" "QI")])
739 (define_expand "cmpqi_ext_3"
740 [(set (reg:CC FLAGS_REG)
744 (match_operand 0 "ext_register_operand" "")
747 (match_operand:QI 1 "general_operand" "")))]
751 (define_insn "cmpqi_ext_3_insn"
752 [(set (reg FLAGS_REG)
756 (match_operand 0 "ext_register_operand" "Q")
759 (match_operand:QI 1 "general_operand" "Qmn")))]
760 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
761 "cmp{b}\t{%1, %h0|%h0, %1}"
762 [(set_attr "type" "icmp")
763 (set_attr "mode" "QI")])
765 (define_insn "cmpqi_ext_3_insn_rex64"
766 [(set (reg FLAGS_REG)
770 (match_operand 0 "ext_register_operand" "Q")
773 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
774 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
775 "cmp{b}\t{%1, %h0|%h0, %1}"
776 [(set_attr "type" "icmp")
777 (set_attr "mode" "QI")])
779 (define_insn "*cmpqi_ext_4"
780 [(set (reg FLAGS_REG)
784 (match_operand 0 "ext_register_operand" "Q")
789 (match_operand 1 "ext_register_operand" "Q")
792 "ix86_match_ccmode (insn, CCmode)"
793 "cmp{b}\t{%h1, %h0|%h0, %h1}"
794 [(set_attr "type" "icmp")
795 (set_attr "mode" "QI")])
797 ;; These implement float point compares.
798 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
799 ;; which would allow mix and match FP modes on the compares. Which is what
800 ;; the old patterns did, but with many more of them.
802 (define_expand "cmpxf"
803 [(set (reg:CC FLAGS_REG)
804 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
805 (match_operand:XF 1 "nonmemory_operand" "")))]
808 ix86_compare_op0 = operands[0];
809 ix86_compare_op1 = operands[1];
813 (define_expand "cmpdf"
814 [(set (reg:CC FLAGS_REG)
815 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
816 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
817 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
819 ix86_compare_op0 = operands[0];
820 ix86_compare_op1 = operands[1];
824 (define_expand "cmpsf"
825 [(set (reg:CC FLAGS_REG)
826 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
827 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
828 "TARGET_80387 || TARGET_SSE_MATH"
830 ix86_compare_op0 = operands[0];
831 ix86_compare_op1 = operands[1];
835 ;; FP compares, step 1:
836 ;; Set the FP condition codes.
838 ;; CCFPmode compare with exceptions
839 ;; CCFPUmode compare with no exceptions
841 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
842 ;; used to manage the reg stack popping would not be preserved.
844 (define_insn "*cmpfp_0"
845 [(set (match_operand:HI 0 "register_operand" "=a")
848 (match_operand 1 "register_operand" "f")
849 (match_operand 2 "const0_operand" "X"))]
852 && FLOAT_MODE_P (GET_MODE (operands[1]))
853 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
854 "* return output_fp_compare (insn, operands, 0, 0);"
855 [(set_attr "type" "multi")
856 (set_attr "unit" "i387")
858 (cond [(match_operand:SF 1 "" "")
860 (match_operand:DF 1 "" "")
863 (const_string "XF")))])
865 (define_insn "*cmpfp_sf"
866 [(set (match_operand:HI 0 "register_operand" "=a")
869 (match_operand:SF 1 "register_operand" "f")
870 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
873 "* return output_fp_compare (insn, operands, 0, 0);"
874 [(set_attr "type" "multi")
875 (set_attr "unit" "i387")
876 (set_attr "mode" "SF")])
878 (define_insn "*cmpfp_df"
879 [(set (match_operand:HI 0 "register_operand" "=a")
882 (match_operand:DF 1 "register_operand" "f")
883 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
886 "* return output_fp_compare (insn, operands, 0, 0);"
887 [(set_attr "type" "multi")
888 (set_attr "unit" "i387")
889 (set_attr "mode" "DF")])
891 (define_insn "*cmpfp_xf"
892 [(set (match_operand:HI 0 "register_operand" "=a")
895 (match_operand:XF 1 "register_operand" "f")
896 (match_operand:XF 2 "register_operand" "f"))]
899 "* return output_fp_compare (insn, operands, 0, 0);"
900 [(set_attr "type" "multi")
901 (set_attr "unit" "i387")
902 (set_attr "mode" "XF")])
904 (define_insn "*cmpfp_u"
905 [(set (match_operand:HI 0 "register_operand" "=a")
908 (match_operand 1 "register_operand" "f")
909 (match_operand 2 "register_operand" "f"))]
912 && FLOAT_MODE_P (GET_MODE (operands[1]))
913 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
914 "* return output_fp_compare (insn, operands, 0, 1);"
915 [(set_attr "type" "multi")
916 (set_attr "unit" "i387")
918 (cond [(match_operand:SF 1 "" "")
920 (match_operand:DF 1 "" "")
923 (const_string "XF")))])
925 (define_insn "*cmpfp_<mode>"
926 [(set (match_operand:HI 0 "register_operand" "=a")
929 (match_operand 1 "register_operand" "f")
930 (match_operator 3 "float_operator"
931 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
933 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
934 && FLOAT_MODE_P (GET_MODE (operands[1]))
935 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
936 "* return output_fp_compare (insn, operands, 0, 0);"
937 [(set_attr "type" "multi")
938 (set_attr "unit" "i387")
939 (set_attr "fp_int_src" "true")
940 (set_attr "mode" "<MODE>")])
942 ;; FP compares, step 2
943 ;; Move the fpsw to ax.
945 (define_insn "x86_fnstsw_1"
946 [(set (match_operand:HI 0 "register_operand" "=a")
947 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
950 [(set_attr "length" "2")
951 (set_attr "mode" "SI")
952 (set_attr "unit" "i387")])
954 ;; FP compares, step 3
955 ;; Get ax into flags, general case.
957 (define_insn "x86_sahf_1"
958 [(set (reg:CC FLAGS_REG)
959 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
962 [(set_attr "length" "1")
963 (set_attr "athlon_decode" "vector")
964 (set_attr "mode" "SI")])
966 ;; Pentium Pro can do steps 1 through 3 in one go.
968 (define_insn "*cmpfp_i_mixed"
969 [(set (reg:CCFP FLAGS_REG)
970 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
971 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
973 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
974 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
975 "* return output_fp_compare (insn, operands, 1, 0);"
976 [(set_attr "type" "fcmp,ssecomi")
978 (if_then_else (match_operand:SF 1 "" "")
980 (const_string "DF")))
981 (set_attr "athlon_decode" "vector")])
983 (define_insn "*cmpfp_i_sse"
984 [(set (reg:CCFP FLAGS_REG)
985 (compare:CCFP (match_operand 0 "register_operand" "x")
986 (match_operand 1 "nonimmediate_operand" "xm")))]
988 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
989 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
990 "* return output_fp_compare (insn, operands, 1, 0);"
991 [(set_attr "type" "ssecomi")
993 (if_then_else (match_operand:SF 1 "" "")
995 (const_string "DF")))
996 (set_attr "athlon_decode" "vector")])
998 (define_insn "*cmpfp_i_i387"
999 [(set (reg:CCFP FLAGS_REG)
1000 (compare:CCFP (match_operand 0 "register_operand" "f")
1001 (match_operand 1 "register_operand" "f")))]
1002 "TARGET_80387 && TARGET_CMOVE
1003 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1004 && FLOAT_MODE_P (GET_MODE (operands[0]))
1005 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006 "* return output_fp_compare (insn, operands, 1, 0);"
1007 [(set_attr "type" "fcmp")
1009 (cond [(match_operand:SF 1 "" "")
1011 (match_operand:DF 1 "" "")
1014 (const_string "XF")))
1015 (set_attr "athlon_decode" "vector")])
1017 (define_insn "*cmpfp_iu_mixed"
1018 [(set (reg:CCFPU FLAGS_REG)
1019 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1020 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1021 "TARGET_MIX_SSE_I387
1022 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1023 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1024 "* return output_fp_compare (insn, operands, 1, 1);"
1025 [(set_attr "type" "fcmp,ssecomi")
1027 (if_then_else (match_operand:SF 1 "" "")
1029 (const_string "DF")))
1030 (set_attr "athlon_decode" "vector")])
1032 (define_insn "*cmpfp_iu_sse"
1033 [(set (reg:CCFPU FLAGS_REG)
1034 (compare:CCFPU (match_operand 0 "register_operand" "x")
1035 (match_operand 1 "nonimmediate_operand" "xm")))]
1037 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039 "* return output_fp_compare (insn, operands, 1, 1);"
1040 [(set_attr "type" "ssecomi")
1042 (if_then_else (match_operand:SF 1 "" "")
1044 (const_string "DF")))
1045 (set_attr "athlon_decode" "vector")])
1047 (define_insn "*cmpfp_iu_387"
1048 [(set (reg:CCFPU FLAGS_REG)
1049 (compare:CCFPU (match_operand 0 "register_operand" "f")
1050 (match_operand 1 "register_operand" "f")))]
1051 "TARGET_80387 && TARGET_CMOVE
1052 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1053 && FLOAT_MODE_P (GET_MODE (operands[0]))
1054 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055 "* return output_fp_compare (insn, operands, 1, 1);"
1056 [(set_attr "type" "fcmp")
1058 (cond [(match_operand:SF 1 "" "")
1060 (match_operand:DF 1 "" "")
1063 (const_string "XF")))
1064 (set_attr "athlon_decode" "vector")])
1066 ;; Move instructions.
1068 ;; General case of fullword move.
1070 (define_expand "movsi"
1071 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1072 (match_operand:SI 1 "general_operand" ""))]
1074 "ix86_expand_move (SImode, operands); DONE;")
1076 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1079 ;; %%% We don't use a post-inc memory reference because x86 is not a
1080 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1081 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1082 ;; targets without our curiosities, and it is just as easy to represent
1083 ;; this differently.
1085 (define_insn "*pushsi2"
1086 [(set (match_operand:SI 0 "push_operand" "=<")
1087 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1090 [(set_attr "type" "push")
1091 (set_attr "mode" "SI")])
1093 ;; For 64BIT abi we always round up to 8 bytes.
1094 (define_insn "*pushsi2_rex64"
1095 [(set (match_operand:SI 0 "push_operand" "=X")
1096 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1099 [(set_attr "type" "push")
1100 (set_attr "mode" "SI")])
1102 (define_insn "*pushsi2_prologue"
1103 [(set (match_operand:SI 0 "push_operand" "=<")
1104 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1105 (clobber (mem:BLK (scratch)))]
1108 [(set_attr "type" "push")
1109 (set_attr "mode" "SI")])
1111 (define_insn "*popsi1_epilogue"
1112 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1113 (mem:SI (reg:SI SP_REG)))
1114 (set (reg:SI SP_REG)
1115 (plus:SI (reg:SI SP_REG) (const_int 4)))
1116 (clobber (mem:BLK (scratch)))]
1119 [(set_attr "type" "pop")
1120 (set_attr "mode" "SI")])
1122 (define_insn "popsi1"
1123 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1124 (mem:SI (reg:SI SP_REG)))
1125 (set (reg:SI SP_REG)
1126 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1129 [(set_attr "type" "pop")
1130 (set_attr "mode" "SI")])
1132 (define_insn "*movsi_xor"
1133 [(set (match_operand:SI 0 "register_operand" "=r")
1134 (match_operand:SI 1 "const0_operand" "i"))
1135 (clobber (reg:CC FLAGS_REG))]
1136 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1137 "xor{l}\t{%0, %0|%0, %0}"
1138 [(set_attr "type" "alu1")
1139 (set_attr "mode" "SI")
1140 (set_attr "length_immediate" "0")])
1142 (define_insn "*movsi_or"
1143 [(set (match_operand:SI 0 "register_operand" "=r")
1144 (match_operand:SI 1 "immediate_operand" "i"))
1145 (clobber (reg:CC FLAGS_REG))]
1147 && operands[1] == constm1_rtx
1148 && (TARGET_PENTIUM || optimize_size)"
1150 operands[1] = constm1_rtx;
1151 return "or{l}\t{%1, %0|%0, %1}";
1153 [(set_attr "type" "alu1")
1154 (set_attr "mode" "SI")
1155 (set_attr "length_immediate" "1")])
1157 (define_insn "*movsi_1"
1158 [(set (match_operand:SI 0 "nonimmediate_operand"
1159 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1160 (match_operand:SI 1 "general_operand"
1161 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1162 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1164 switch (get_attr_type (insn))
1167 if (get_attr_mode (insn) == MODE_TI)
1168 return "pxor\t%0, %0";
1169 return "xorps\t%0, %0";
1172 switch (get_attr_mode (insn))
1175 return "movdqa\t{%1, %0|%0, %1}";
1177 return "movaps\t{%1, %0|%0, %1}";
1179 return "movd\t{%1, %0|%0, %1}";
1181 return "movss\t{%1, %0|%0, %1}";
1187 return "pxor\t%0, %0";
1190 if (get_attr_mode (insn) == MODE_DI)
1191 return "movq\t{%1, %0|%0, %1}";
1192 return "movd\t{%1, %0|%0, %1}";
1195 return "lea{l}\t{%1, %0|%0, %1}";
1198 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1199 return "mov{l}\t{%1, %0|%0, %1}";
1203 (cond [(eq_attr "alternative" "2")
1204 (const_string "mmxadd")
1205 (eq_attr "alternative" "3,4,5")
1206 (const_string "mmxmov")
1207 (eq_attr "alternative" "6")
1208 (const_string "sselog1")
1209 (eq_attr "alternative" "7,8,9,10,11")
1210 (const_string "ssemov")
1211 (match_operand:DI 1 "pic_32bit_operand" "")
1212 (const_string "lea")
1214 (const_string "imov")))
1216 (cond [(eq_attr "alternative" "2,3")
1218 (eq_attr "alternative" "6,7")
1220 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1221 (const_string "V4SF")
1222 (const_string "TI"))
1223 (and (eq_attr "alternative" "8,9,10,11")
1224 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1227 (const_string "SI")))])
1229 ;; Stores and loads of ax to arbitrary constant address.
1230 ;; We fake an second form of instruction to force reload to load address
1231 ;; into register when rax is not available
1232 (define_insn "*movabssi_1_rex64"
1233 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1234 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1235 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1237 movabs{l}\t{%1, %P0|%P0, %1}
1238 mov{l}\t{%1, %a0|%a0, %1}"
1239 [(set_attr "type" "imov")
1240 (set_attr "modrm" "0,*")
1241 (set_attr "length_address" "8,0")
1242 (set_attr "length_immediate" "0,*")
1243 (set_attr "memory" "store")
1244 (set_attr "mode" "SI")])
1246 (define_insn "*movabssi_2_rex64"
1247 [(set (match_operand:SI 0 "register_operand" "=a,r")
1248 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1249 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1251 movabs{l}\t{%P1, %0|%0, %P1}
1252 mov{l}\t{%a1, %0|%0, %a1}"
1253 [(set_attr "type" "imov")
1254 (set_attr "modrm" "0,*")
1255 (set_attr "length_address" "8,0")
1256 (set_attr "length_immediate" "0")
1257 (set_attr "memory" "load")
1258 (set_attr "mode" "SI")])
1260 (define_insn "*swapsi"
1261 [(set (match_operand:SI 0 "register_operand" "+r")
1262 (match_operand:SI 1 "register_operand" "+r"))
1267 [(set_attr "type" "imov")
1268 (set_attr "mode" "SI")
1269 (set_attr "pent_pair" "np")
1270 (set_attr "athlon_decode" "vector")])
1272 (define_expand "movhi"
1273 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1274 (match_operand:HI 1 "general_operand" ""))]
1276 "ix86_expand_move (HImode, operands); DONE;")
1278 (define_insn "*pushhi2"
1279 [(set (match_operand:HI 0 "push_operand" "=X")
1280 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1283 [(set_attr "type" "push")
1284 (set_attr "mode" "SI")])
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288 [(set (match_operand:HI 0 "push_operand" "=X")
1289 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1292 [(set_attr "type" "push")
1293 (set_attr "mode" "DI")])
1295 (define_insn "*movhi_1"
1296 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1300 switch (get_attr_type (insn))
1303 /* movzwl is faster than movw on p2 due to partial word stalls,
1304 though not as fast as an aligned movl. */
1305 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1307 if (get_attr_mode (insn) == MODE_SI)
1308 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1310 return "mov{w}\t{%1, %0|%0, %1}";
1314 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1315 (const_string "imov")
1316 (and (eq_attr "alternative" "0")
1317 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1319 (eq (symbol_ref "TARGET_HIMODE_MATH")
1321 (const_string "imov")
1322 (and (eq_attr "alternative" "1,2")
1323 (match_operand:HI 1 "aligned_operand" ""))
1324 (const_string "imov")
1325 (and (ne (symbol_ref "TARGET_MOVX")
1327 (eq_attr "alternative" "0,2"))
1328 (const_string "imovx")
1330 (const_string "imov")))
1332 (cond [(eq_attr "type" "imovx")
1334 (and (eq_attr "alternative" "1,2")
1335 (match_operand:HI 1 "aligned_operand" ""))
1337 (and (eq_attr "alternative" "0")
1338 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1340 (eq (symbol_ref "TARGET_HIMODE_MATH")
1344 (const_string "HI")))])
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1354 movabs{w}\t{%1, %P0|%P0, %1}
1355 mov{w}\t{%1, %a0|%a0, %1}"
1356 [(set_attr "type" "imov")
1357 (set_attr "modrm" "0,*")
1358 (set_attr "length_address" "8,0")
1359 (set_attr "length_immediate" "0,*")
1360 (set_attr "memory" "store")
1361 (set_attr "mode" "HI")])
1363 (define_insn "*movabshi_2_rex64"
1364 [(set (match_operand:HI 0 "register_operand" "=a,r")
1365 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1368 movabs{w}\t{%P1, %0|%0, %P1}
1369 mov{w}\t{%a1, %0|%0, %a1}"
1370 [(set_attr "type" "imov")
1371 (set_attr "modrm" "0,*")
1372 (set_attr "length_address" "8,0")
1373 (set_attr "length_immediate" "0")
1374 (set_attr "memory" "load")
1375 (set_attr "mode" "HI")])
1377 (define_insn "*swaphi_1"
1378 [(set (match_operand:HI 0 "register_operand" "+r")
1379 (match_operand:HI 1 "register_operand" "+r"))
1382 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1384 [(set_attr "type" "imov")
1385 (set_attr "mode" "SI")
1386 (set_attr "pent_pair" "np")
1387 (set_attr "athlon_decode" "vector")])
1389 (define_insn "*swaphi_2"
1390 [(set (match_operand:HI 0 "register_operand" "+r")
1391 (match_operand:HI 1 "register_operand" "+r"))
1394 "TARGET_PARTIAL_REG_STALL"
1396 [(set_attr "type" "imov")
1397 (set_attr "mode" "HI")
1398 (set_attr "pent_pair" "np")
1399 (set_attr "athlon_decode" "vector")])
1401 (define_expand "movstricthi"
1402 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403 (match_operand:HI 1 "general_operand" ""))]
1404 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1406 /* Don't generate memory->memory moves, go through a register */
1407 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408 operands[1] = force_reg (HImode, operands[1]);
1411 (define_insn "*movstricthi_1"
1412 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413 (match_operand:HI 1 "general_operand" "rn,m"))]
1414 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416 "mov{w}\t{%1, %0|%0, %1}"
1417 [(set_attr "type" "imov")
1418 (set_attr "mode" "HI")])
1420 (define_insn "*movstricthi_xor"
1421 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422 (match_operand:HI 1 "const0_operand" "i"))
1423 (clobber (reg:CC FLAGS_REG))]
1425 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426 "xor{w}\t{%0, %0|%0, %0}"
1427 [(set_attr "type" "alu1")
1428 (set_attr "mode" "HI")
1429 (set_attr "length_immediate" "0")])
1431 (define_expand "movqi"
1432 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433 (match_operand:QI 1 "general_operand" ""))]
1435 "ix86_expand_move (QImode, operands); DONE;")
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte". But actually we use pushl, which has the effect
1439 ;; of rounding the amount pushed up to a word.
1441 (define_insn "*pushqi2"
1442 [(set (match_operand:QI 0 "push_operand" "=X")
1443 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1446 [(set_attr "type" "push")
1447 (set_attr "mode" "SI")])
1449 ;; For 64BIT abi we always round up to 8 bytes.
1450 (define_insn "*pushqi2_rex64"
1451 [(set (match_operand:QI 0 "push_operand" "=X")
1452 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1455 [(set_attr "type" "push")
1456 (set_attr "mode" "DI")])
1458 ;; Situation is quite tricky about when to choose full sized (SImode) move
1459 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1460 ;; partial register dependency machines (such as AMD Athlon), where QImode
1461 ;; moves issue extra dependency and for partial register stalls machines
1462 ;; that don't use QImode patterns (and QImode move cause stall on the next
1465 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1466 ;; register stall machines with, where we use QImode instructions, since
1467 ;; partial register stall can be caused there. Then we use movzx.
1468 (define_insn "*movqi_1"
1469 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1470 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1471 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1473 switch (get_attr_type (insn))
1476 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1477 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1479 if (get_attr_mode (insn) == MODE_SI)
1480 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1482 return "mov{b}\t{%1, %0|%0, %1}";
1486 (cond [(and (eq_attr "alternative" "5")
1487 (not (match_operand:QI 1 "aligned_operand" "")))
1488 (const_string "imovx")
1489 (ne (symbol_ref "optimize_size") (const_int 0))
1490 (const_string "imov")
1491 (and (eq_attr "alternative" "3")
1492 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1494 (eq (symbol_ref "TARGET_QIMODE_MATH")
1496 (const_string "imov")
1497 (eq_attr "alternative" "3,5")
1498 (const_string "imovx")
1499 (and (ne (symbol_ref "TARGET_MOVX")
1501 (eq_attr "alternative" "2"))
1502 (const_string "imovx")
1504 (const_string "imov")))
1506 (cond [(eq_attr "alternative" "3,4,5")
1508 (eq_attr "alternative" "6")
1510 (eq_attr "type" "imovx")
1512 (and (eq_attr "type" "imov")
1513 (and (eq_attr "alternative" "0,1")
1514 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1516 (and (eq (symbol_ref "optimize_size")
1518 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1521 ;; Avoid partial register stalls when not using QImode arithmetic
1522 (and (eq_attr "type" "imov")
1523 (and (eq_attr "alternative" "0,1")
1524 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1526 (eq (symbol_ref "TARGET_QIMODE_MATH")
1530 (const_string "QI")))])
1532 (define_expand "reload_outqi"
1533 [(parallel [(match_operand:QI 0 "" "=m")
1534 (match_operand:QI 1 "register_operand" "r")
1535 (match_operand:QI 2 "register_operand" "=&q")])]
1539 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1541 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1542 if (! q_regs_operand (op1, QImode))
1544 emit_insn (gen_movqi (op2, op1));
1547 emit_insn (gen_movqi (op0, op1));
1551 (define_insn "*swapqi_1"
1552 [(set (match_operand:QI 0 "register_operand" "+r")
1553 (match_operand:QI 1 "register_operand" "+r"))
1556 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1558 [(set_attr "type" "imov")
1559 (set_attr "mode" "SI")
1560 (set_attr "pent_pair" "np")
1561 (set_attr "athlon_decode" "vector")])
1563 (define_insn "*swapqi_2"
1564 [(set (match_operand:QI 0 "register_operand" "+q")
1565 (match_operand:QI 1 "register_operand" "+q"))
1568 "TARGET_PARTIAL_REG_STALL"
1570 [(set_attr "type" "imov")
1571 (set_attr "mode" "QI")
1572 (set_attr "pent_pair" "np")
1573 (set_attr "athlon_decode" "vector")])
1575 (define_expand "movstrictqi"
1576 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1577 (match_operand:QI 1 "general_operand" ""))]
1578 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1580 /* Don't generate memory->memory moves, go through a register. */
1581 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1582 operands[1] = force_reg (QImode, operands[1]);
1585 (define_insn "*movstrictqi_1"
1586 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1587 (match_operand:QI 1 "general_operand" "*qn,m"))]
1588 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1589 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1590 "mov{b}\t{%1, %0|%0, %1}"
1591 [(set_attr "type" "imov")
1592 (set_attr "mode" "QI")])
1594 (define_insn "*movstrictqi_xor"
1595 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1596 (match_operand:QI 1 "const0_operand" "i"))
1597 (clobber (reg:CC FLAGS_REG))]
1598 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1599 "xor{b}\t{%0, %0|%0, %0}"
1600 [(set_attr "type" "alu1")
1601 (set_attr "mode" "QI")
1602 (set_attr "length_immediate" "0")])
1604 (define_insn "*movsi_extv_1"
1605 [(set (match_operand:SI 0 "register_operand" "=R")
1606 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1610 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1611 [(set_attr "type" "imovx")
1612 (set_attr "mode" "SI")])
1614 (define_insn "*movhi_extv_1"
1615 [(set (match_operand:HI 0 "register_operand" "=R")
1616 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1620 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1621 [(set_attr "type" "imovx")
1622 (set_attr "mode" "SI")])
1624 (define_insn "*movqi_extv_1"
1625 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1626 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1631 switch (get_attr_type (insn))
1634 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1636 return "mov{b}\t{%h1, %0|%0, %h1}";
1640 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1641 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1642 (ne (symbol_ref "TARGET_MOVX")
1644 (const_string "imovx")
1645 (const_string "imov")))
1647 (if_then_else (eq_attr "type" "imovx")
1649 (const_string "QI")))])
1651 (define_insn "*movqi_extv_1_rex64"
1652 [(set (match_operand:QI 0 "register_operand" "=Q,?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 ;; Stores and loads of ax to arbitrary constant address.
1679 ;; We fake an second form of instruction to force reload to load address
1680 ;; into register when rax is not available
1681 (define_insn "*movabsqi_1_rex64"
1682 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1683 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1684 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1686 movabs{b}\t{%1, %P0|%P0, %1}
1687 mov{b}\t{%1, %a0|%a0, %1}"
1688 [(set_attr "type" "imov")
1689 (set_attr "modrm" "0,*")
1690 (set_attr "length_address" "8,0")
1691 (set_attr "length_immediate" "0,*")
1692 (set_attr "memory" "store")
1693 (set_attr "mode" "QI")])
1695 (define_insn "*movabsqi_2_rex64"
1696 [(set (match_operand:QI 0 "register_operand" "=a,r")
1697 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1698 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1700 movabs{b}\t{%P1, %0|%0, %P1}
1701 mov{b}\t{%a1, %0|%0, %a1}"
1702 [(set_attr "type" "imov")
1703 (set_attr "modrm" "0,*")
1704 (set_attr "length_address" "8,0")
1705 (set_attr "length_immediate" "0")
1706 (set_attr "memory" "load")
1707 (set_attr "mode" "QI")])
1709 (define_insn "*movdi_extzv_1"
1710 [(set (match_operand:DI 0 "register_operand" "=R")
1711 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1715 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1716 [(set_attr "type" "imovx")
1717 (set_attr "mode" "DI")])
1719 (define_insn "*movsi_extzv_1"
1720 [(set (match_operand:SI 0 "register_operand" "=R")
1721 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1725 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1726 [(set_attr "type" "imovx")
1727 (set_attr "mode" "SI")])
1729 (define_insn "*movqi_extzv_2"
1730 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1731 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1736 switch (get_attr_type (insn))
1739 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1741 return "mov{b}\t{%h1, %0|%0, %h1}";
1745 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1746 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1747 (ne (symbol_ref "TARGET_MOVX")
1749 (const_string "imovx")
1750 (const_string "imov")))
1752 (if_then_else (eq_attr "type" "imovx")
1754 (const_string "QI")))])
1756 (define_insn "*movqi_extzv_2_rex64"
1757 [(set (match_operand:QI 0 "register_operand" "=Q,?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 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1773 (ne (symbol_ref "TARGET_MOVX")
1775 (const_string "imovx")
1776 (const_string "imov")))
1778 (if_then_else (eq_attr "type" "imovx")
1780 (const_string "QI")))])
1782 (define_insn "movsi_insv_1"
1783 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1786 (match_operand:SI 1 "general_operand" "Qmn"))]
1788 "mov{b}\t{%b1, %h0|%h0, %b1}"
1789 [(set_attr "type" "imov")
1790 (set_attr "mode" "QI")])
1792 (define_insn "movdi_insv_1_rex64"
1793 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1796 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1798 "mov{b}\t{%b1, %h0|%h0, %b1}"
1799 [(set_attr "type" "imov")
1800 (set_attr "mode" "QI")])
1802 (define_insn "*movqi_insv_2"
1803 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1806 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1809 "mov{b}\t{%h1, %h0|%h0, %h1}"
1810 [(set_attr "type" "imov")
1811 (set_attr "mode" "QI")])
1813 (define_expand "movdi"
1814 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1815 (match_operand:DI 1 "general_operand" ""))]
1817 "ix86_expand_move (DImode, operands); DONE;")
1819 (define_insn "*pushdi"
1820 [(set (match_operand:DI 0 "push_operand" "=<")
1821 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1825 (define_insn "*pushdi2_rex64"
1826 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1827 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1832 [(set_attr "type" "push,multi")
1833 (set_attr "mode" "DI")])
1835 ;; Convert impossible pushes of immediate to existing instructions.
1836 ;; First try to get scratch register and go through it. In case this
1837 ;; fails, push sign extended lower part first and then overwrite
1838 ;; upper part by 32bit move.
1840 [(match_scratch:DI 2 "r")
1841 (set (match_operand:DI 0 "push_operand" "")
1842 (match_operand:DI 1 "immediate_operand" ""))]
1843 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1844 && !x86_64_immediate_operand (operands[1], DImode)"
1845 [(set (match_dup 2) (match_dup 1))
1846 (set (match_dup 0) (match_dup 2))]
1849 ;; We need to define this as both peepholer and splitter for case
1850 ;; peephole2 pass is not run.
1851 ;; "&& 1" is needed to keep it from matching the previous pattern.
1853 [(set (match_operand:DI 0 "push_operand" "")
1854 (match_operand:DI 1 "immediate_operand" ""))]
1855 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1856 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1857 [(set (match_dup 0) (match_dup 1))
1858 (set (match_dup 2) (match_dup 3))]
1859 "split_di (operands + 1, 1, operands + 2, operands + 3);
1860 operands[1] = gen_lowpart (DImode, operands[2]);
1861 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1866 [(set (match_operand:DI 0 "push_operand" "")
1867 (match_operand:DI 1 "immediate_operand" ""))]
1868 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1869 ? flow2_completed : reload_completed)
1870 && !symbolic_operand (operands[1], DImode)
1871 && !x86_64_immediate_operand (operands[1], DImode)"
1872 [(set (match_dup 0) (match_dup 1))
1873 (set (match_dup 2) (match_dup 3))]
1874 "split_di (operands + 1, 1, operands + 2, operands + 3);
1875 operands[1] = gen_lowpart (DImode, operands[2]);
1876 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1880 (define_insn "*pushdi2_prologue_rex64"
1881 [(set (match_operand:DI 0 "push_operand" "=<")
1882 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1883 (clobber (mem:BLK (scratch)))]
1886 [(set_attr "type" "push")
1887 (set_attr "mode" "DI")])
1889 (define_insn "*popdi1_epilogue_rex64"
1890 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1891 (mem:DI (reg:DI SP_REG)))
1892 (set (reg:DI SP_REG)
1893 (plus:DI (reg:DI SP_REG) (const_int 8)))
1894 (clobber (mem:BLK (scratch)))]
1897 [(set_attr "type" "pop")
1898 (set_attr "mode" "DI")])
1900 (define_insn "popdi1"
1901 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1902 (mem:DI (reg:DI SP_REG)))
1903 (set (reg:DI SP_REG)
1904 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1907 [(set_attr "type" "pop")
1908 (set_attr "mode" "DI")])
1910 (define_insn "*movdi_xor_rex64"
1911 [(set (match_operand:DI 0 "register_operand" "=r")
1912 (match_operand:DI 1 "const0_operand" "i"))
1913 (clobber (reg:CC FLAGS_REG))]
1914 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1915 && reload_completed"
1916 "xor{l}\t{%k0, %k0|%k0, %k0}"
1917 [(set_attr "type" "alu1")
1918 (set_attr "mode" "SI")
1919 (set_attr "length_immediate" "0")])
1921 (define_insn "*movdi_or_rex64"
1922 [(set (match_operand:DI 0 "register_operand" "=r")
1923 (match_operand:DI 1 "const_int_operand" "i"))
1924 (clobber (reg:CC FLAGS_REG))]
1925 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1927 && operands[1] == constm1_rtx"
1929 operands[1] = constm1_rtx;
1930 return "or{q}\t{%1, %0|%0, %1}";
1932 [(set_attr "type" "alu1")
1933 (set_attr "mode" "DI")
1934 (set_attr "length_immediate" "1")])
1936 (define_insn "*movdi_2"
1937 [(set (match_operand:DI 0 "nonimmediate_operand"
1938 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1939 (match_operand:DI 1 "general_operand"
1940 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1941 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1946 movq\t{%1, %0|%0, %1}
1947 movq\t{%1, %0|%0, %1}
1949 movq\t{%1, %0|%0, %1}
1950 movdqa\t{%1, %0|%0, %1}
1951 movq\t{%1, %0|%0, %1}
1953 movlps\t{%1, %0|%0, %1}
1954 movaps\t{%1, %0|%0, %1}
1955 movlps\t{%1, %0|%0, %1}"
1956 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1957 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1960 [(set (match_operand:DI 0 "push_operand" "")
1961 (match_operand:DI 1 "general_operand" ""))]
1962 "!TARGET_64BIT && reload_completed
1963 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1965 "ix86_split_long_move (operands); DONE;")
1967 ;; %%% This multiword shite has got to go.
1969 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1970 (match_operand:DI 1 "general_operand" ""))]
1971 "!TARGET_64BIT && reload_completed
1972 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1973 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1975 "ix86_split_long_move (operands); DONE;")
1977 (define_insn "*movdi_1_rex64"
1978 [(set (match_operand:DI 0 "nonimmediate_operand"
1979 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1980 (match_operand:DI 1 "general_operand"
1981 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1982 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1984 switch (get_attr_type (insn))
1987 if (which_alternative == 13)
1988 return "movq2dq\t{%1, %0|%0, %1}";
1990 return "movdq2q\t{%1, %0|%0, %1}";
1992 if (get_attr_mode (insn) == MODE_TI)
1993 return "movdqa\t{%1, %0|%0, %1}";
1996 /* Moves from and into integer register is done using movd opcode with
1998 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1999 return "movd\t{%1, %0|%0, %1}";
2000 return "movq\t{%1, %0|%0, %1}";
2003 return "pxor\t%0, %0";
2007 return "lea{q}\t{%a1, %0|%0, %a1}";
2009 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2010 if (get_attr_mode (insn) == MODE_SI)
2011 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2012 else if (which_alternative == 2)
2013 return "movabs{q}\t{%1, %0|%0, %1}";
2015 return "mov{q}\t{%1, %0|%0, %1}";
2019 (cond [(eq_attr "alternative" "5")
2020 (const_string "mmxadd")
2021 (eq_attr "alternative" "6,7,8")
2022 (const_string "mmxmov")
2023 (eq_attr "alternative" "9")
2024 (const_string "sselog1")
2025 (eq_attr "alternative" "10,11,12")
2026 (const_string "ssemov")
2027 (eq_attr "alternative" "13,14")
2028 (const_string "ssecvt")
2029 (eq_attr "alternative" "4")
2030 (const_string "multi")
2031 (match_operand:DI 1 "pic_32bit_operand" "")
2032 (const_string "lea")
2034 (const_string "imov")))
2035 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2036 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2037 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2039 ;; Stores and loads of ax to arbitrary constant address.
2040 ;; We fake an second form of instruction to force reload to load address
2041 ;; into register when rax is not available
2042 (define_insn "*movabsdi_1_rex64"
2043 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2044 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2045 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2047 movabs{q}\t{%1, %P0|%P0, %1}
2048 mov{q}\t{%1, %a0|%a0, %1}"
2049 [(set_attr "type" "imov")
2050 (set_attr "modrm" "0,*")
2051 (set_attr "length_address" "8,0")
2052 (set_attr "length_immediate" "0,*")
2053 (set_attr "memory" "store")
2054 (set_attr "mode" "DI")])
2056 (define_insn "*movabsdi_2_rex64"
2057 [(set (match_operand:DI 0 "register_operand" "=a,r")
2058 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2059 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2061 movabs{q}\t{%P1, %0|%0, %P1}
2062 mov{q}\t{%a1, %0|%0, %a1}"
2063 [(set_attr "type" "imov")
2064 (set_attr "modrm" "0,*")
2065 (set_attr "length_address" "8,0")
2066 (set_attr "length_immediate" "0")
2067 (set_attr "memory" "load")
2068 (set_attr "mode" "DI")])
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it. In case this
2072 ;; fails, move by 32bit parts.
2074 [(match_scratch:DI 2 "r")
2075 (set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode)"
2079 [(set (match_dup 2) (match_dup 1))
2080 (set (match_dup 0) (match_dup 2))]
2083 ;; We need to define this as both peepholer and splitter for case
2084 ;; peephole2 pass is not run.
2085 ;; "&& 1" is needed to keep it from matching the previous pattern.
2087 [(set (match_operand:DI 0 "memory_operand" "")
2088 (match_operand:DI 1 "immediate_operand" ""))]
2089 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2090 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2091 [(set (match_dup 2) (match_dup 3))
2092 (set (match_dup 4) (match_dup 5))]
2093 "split_di (operands, 2, operands + 2, operands + 4);")
2096 [(set (match_operand:DI 0 "memory_operand" "")
2097 (match_operand:DI 1 "immediate_operand" ""))]
2098 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2099 ? flow2_completed : reload_completed)
2100 && !symbolic_operand (operands[1], DImode)
2101 && !x86_64_immediate_operand (operands[1], DImode)"
2102 [(set (match_dup 2) (match_dup 3))
2103 (set (match_dup 4) (match_dup 5))]
2104 "split_di (operands, 2, operands + 2, operands + 4);")
2106 (define_insn "*swapdi_rex64"
2107 [(set (match_operand:DI 0 "register_operand" "+r")
2108 (match_operand:DI 1 "register_operand" "+r"))
2113 [(set_attr "type" "imov")
2114 (set_attr "mode" "DI")
2115 (set_attr "pent_pair" "np")
2116 (set_attr "athlon_decode" "vector")])
2118 (define_expand "movti"
2119 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2120 (match_operand:TI 1 "nonimmediate_operand" ""))]
2121 "TARGET_SSE || TARGET_64BIT"
2124 ix86_expand_move (TImode, operands);
2126 ix86_expand_vector_move (TImode, operands);
2130 (define_insn "*movti_internal"
2131 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2132 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2133 "TARGET_SSE && !TARGET_64BIT
2134 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2136 switch (which_alternative)
2139 if (get_attr_mode (insn) == MODE_V4SF)
2140 return "xorps\t%0, %0";
2142 return "pxor\t%0, %0";
2145 if (get_attr_mode (insn) == MODE_V4SF)
2146 return "movaps\t{%1, %0|%0, %1}";
2148 return "movdqa\t{%1, %0|%0, %1}";
2153 [(set_attr "type" "sselog1,ssemov,ssemov")
2155 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2156 (ne (symbol_ref "optimize_size") (const_int 0)))
2157 (const_string "V4SF")
2158 (and (eq_attr "alternative" "2")
2159 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2161 (const_string "V4SF")]
2162 (const_string "TI")))])
2164 (define_insn "*movti_rex64"
2165 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2166 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2168 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2170 switch (which_alternative)
2176 if (get_attr_mode (insn) == MODE_V4SF)
2177 return "xorps\t%0, %0";
2179 return "pxor\t%0, %0";
2182 if (get_attr_mode (insn) == MODE_V4SF)
2183 return "movaps\t{%1, %0|%0, %1}";
2185 return "movdqa\t{%1, %0|%0, %1}";
2190 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2192 (cond [(eq_attr "alternative" "2,3")
2194 (ne (symbol_ref "optimize_size")
2196 (const_string "V4SF")
2197 (const_string "TI"))
2198 (eq_attr "alternative" "4")
2200 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2202 (ne (symbol_ref "optimize_size")
2204 (const_string "V4SF")
2205 (const_string "TI"))]
2206 (const_string "DI")))])
2209 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2210 (match_operand:TI 1 "general_operand" ""))]
2211 "reload_completed && !SSE_REG_P (operands[0])
2212 && !SSE_REG_P (operands[1])"
2214 "ix86_split_long_move (operands); DONE;")
2216 (define_expand "movsf"
2217 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2218 (match_operand:SF 1 "general_operand" ""))]
2220 "ix86_expand_move (SFmode, operands); DONE;")
2222 (define_insn "*pushsf"
2223 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2224 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2227 /* Anything else should be already split before reg-stack. */
2228 gcc_assert (which_alternative == 1);
2229 return "push{l}\t%1";
2231 [(set_attr "type" "multi,push,multi")
2232 (set_attr "unit" "i387,*,*")
2233 (set_attr "mode" "SF,SI,SF")])
2235 (define_insn "*pushsf_rex64"
2236 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2237 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2240 /* Anything else should be already split before reg-stack. */
2241 gcc_assert (which_alternative == 1);
2242 return "push{q}\t%q1";
2244 [(set_attr "type" "multi,push,multi")
2245 (set_attr "unit" "i387,*,*")
2246 (set_attr "mode" "SF,DI,SF")])
2249 [(set (match_operand:SF 0 "push_operand" "")
2250 (match_operand:SF 1 "memory_operand" ""))]
2252 && GET_CODE (operands[1]) == MEM
2253 && constant_pool_reference_p (operands[1])"
2256 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2259 ;; %%% Kill this when call knows how to work this out.
2261 [(set (match_operand:SF 0 "push_operand" "")
2262 (match_operand:SF 1 "any_fp_register_operand" ""))]
2264 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2265 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2268 [(set (match_operand:SF 0 "push_operand" "")
2269 (match_operand:SF 1 "any_fp_register_operand" ""))]
2271 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2272 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2274 (define_insn "*movsf_1"
2275 [(set (match_operand:SF 0 "nonimmediate_operand"
2276 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2277 (match_operand:SF 1 "general_operand"
2278 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2279 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2280 && (reload_in_progress || reload_completed
2281 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2282 || GET_CODE (operands[1]) != CONST_DOUBLE
2283 || memory_operand (operands[0], SFmode))"
2285 switch (which_alternative)
2288 return output_387_reg_move (insn, operands);
2291 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2292 return "fstp%z0\t%y0";
2294 return "fst%z0\t%y0";
2297 return standard_80387_constant_opcode (operands[1]);
2301 return "mov{l}\t{%1, %0|%0, %1}";
2303 if (get_attr_mode (insn) == MODE_TI)
2304 return "pxor\t%0, %0";
2306 return "xorps\t%0, %0";
2308 if (get_attr_mode (insn) == MODE_V4SF)
2309 return "movaps\t{%1, %0|%0, %1}";
2311 return "movss\t{%1, %0|%0, %1}";
2314 return "movss\t{%1, %0|%0, %1}";
2318 return "movd\t{%1, %0|%0, %1}";
2321 return "movq\t{%1, %0|%0, %1}";
2327 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2329 (cond [(eq_attr "alternative" "3,4,9,10")
2331 (eq_attr "alternative" "5")
2333 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2335 (ne (symbol_ref "TARGET_SSE2")
2337 (eq (symbol_ref "optimize_size")
2340 (const_string "V4SF"))
2341 /* For architectures resolving dependencies on
2342 whole SSE registers use APS move to break dependency
2343 chains, otherwise use short move to avoid extra work.
2345 Do the same for architectures resolving dependencies on
2346 the parts. While in DF mode it is better to always handle
2347 just register parts, the SF mode is different due to lack
2348 of instructions to load just part of the register. It is
2349 better to maintain the whole registers in single format
2350 to avoid problems on using packed logical operations. */
2351 (eq_attr "alternative" "6")
2353 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2355 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2357 (const_string "V4SF")
2358 (const_string "SF"))
2359 (eq_attr "alternative" "11")
2360 (const_string "DI")]
2361 (const_string "SF")))])
2363 (define_insn "*swapsf"
2364 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2365 (match_operand:SF 1 "fp_register_operand" "+f"))
2368 "reload_completed || TARGET_80387"
2370 if (STACK_TOP_P (operands[0]))
2375 [(set_attr "type" "fxch")
2376 (set_attr "mode" "SF")])
2378 (define_expand "movdf"
2379 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2380 (match_operand:DF 1 "general_operand" ""))]
2382 "ix86_expand_move (DFmode, operands); DONE;")
2384 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2385 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2386 ;; On the average, pushdf using integers can be still shorter. Allow this
2387 ;; pattern for optimize_size too.
2389 (define_insn "*pushdf_nointeger"
2390 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2391 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2392 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2394 /* This insn should be already split before reg-stack. */
2397 [(set_attr "type" "multi")
2398 (set_attr "unit" "i387,*,*,*")
2399 (set_attr "mode" "DF,SI,SI,DF")])
2401 (define_insn "*pushdf_integer"
2402 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2403 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2404 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2406 /* This insn should be already split before reg-stack. */
2409 [(set_attr "type" "multi")
2410 (set_attr "unit" "i387,*,*")
2411 (set_attr "mode" "DF,SI,DF")])
2413 ;; %%% Kill this when call knows how to work this out.
2415 [(set (match_operand:DF 0 "push_operand" "")
2416 (match_operand:DF 1 "any_fp_register_operand" ""))]
2417 "!TARGET_64BIT && reload_completed"
2418 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2419 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2423 [(set (match_operand:DF 0 "push_operand" "")
2424 (match_operand:DF 1 "any_fp_register_operand" ""))]
2425 "TARGET_64BIT && reload_completed"
2426 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2427 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2431 [(set (match_operand:DF 0 "push_operand" "")
2432 (match_operand:DF 1 "general_operand" ""))]
2435 "ix86_split_long_move (operands); DONE;")
2437 ;; Moving is usually shorter when only FP registers are used. This separate
2438 ;; movdf pattern avoids the use of integer registers for FP operations
2439 ;; when optimizing for size.
2441 (define_insn "*movdf_nointeger"
2442 [(set (match_operand:DF 0 "nonimmediate_operand"
2443 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ")
2444 (match_operand:DF 1 "general_operand"
2445 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))]
2446 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2447 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2448 && (reload_in_progress || reload_completed
2449 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2450 || GET_CODE (operands[1]) != CONST_DOUBLE
2451 || memory_operand (operands[0], DFmode))"
2453 switch (which_alternative)
2456 return output_387_reg_move (insn, operands);
2459 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2460 return "fstp%z0\t%y0";
2462 return "fst%z0\t%y0";
2465 return standard_80387_constant_opcode (operands[1]);
2471 switch (get_attr_mode (insn))
2474 return "xorps\t%0, %0";
2476 return "xorpd\t%0, %0";
2478 return "pxor\t%0, %0";
2485 switch (get_attr_mode (insn))
2488 return "movaps\t{%1, %0|%0, %1}";
2490 return "movapd\t{%1, %0|%0, %1}";
2492 return "movdqa\t{%1, %0|%0, %1}";
2494 return "movq\t{%1, %0|%0, %1}";
2496 return "movsd\t{%1, %0|%0, %1}";
2498 return "movlpd\t{%1, %0|%0, %1}";
2500 return "movlps\t{%1, %0|%0, %1}";
2509 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2511 (cond [(eq_attr "alternative" "0,1,2")
2513 (eq_attr "alternative" "3,4")
2516 /* For SSE1, we have many fewer alternatives. */
2517 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2518 (cond [(eq_attr "alternative" "5,6")
2519 (const_string "V4SF")
2521 (const_string "V2SF"))
2523 /* xorps is one byte shorter. */
2524 (eq_attr "alternative" "5")
2525 (cond [(ne (symbol_ref "optimize_size")
2527 (const_string "V4SF")
2528 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2532 (const_string "V2DF"))
2534 /* For architectures resolving dependencies on
2535 whole SSE registers use APD move to break dependency
2536 chains, otherwise use short move to avoid extra work.
2538 movaps encodes one byte shorter. */
2539 (eq_attr "alternative" "6")
2541 [(ne (symbol_ref "optimize_size")
2543 (const_string "V4SF")
2544 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2546 (const_string "V2DF")
2548 (const_string "DF"))
2549 /* For architectures resolving dependencies on register
2550 parts we may avoid extra work to zero out upper part
2552 (eq_attr "alternative" "7")
2554 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2556 (const_string "V1DF")
2557 (const_string "DF"))
2559 (const_string "DF")))])
2561 (define_insn "*movdf_integer"
2562 [(set (match_operand:DF 0 "nonimmediate_operand"
2563 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2564 (match_operand:DF 1 "general_operand"
2565 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))]
2566 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2567 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2568 && (reload_in_progress || reload_completed
2569 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2570 || GET_CODE (operands[1]) != CONST_DOUBLE
2571 || memory_operand (operands[0], DFmode))"
2573 switch (which_alternative)
2576 return output_387_reg_move (insn, operands);
2579 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2580 return "fstp%z0\t%y0";
2582 return "fst%z0\t%y0";
2585 return standard_80387_constant_opcode (operands[1]);
2592 switch (get_attr_mode (insn))
2595 return "xorps\t%0, %0";
2597 return "xorpd\t%0, %0";
2599 return "pxor\t%0, %0";
2606 switch (get_attr_mode (insn))
2609 return "movaps\t{%1, %0|%0, %1}";
2611 return "movapd\t{%1, %0|%0, %1}";
2613 return "movdqa\t{%1, %0|%0, %1}";
2615 return "movq\t{%1, %0|%0, %1}";
2617 return "movsd\t{%1, %0|%0, %1}";
2619 return "movlpd\t{%1, %0|%0, %1}";
2621 return "movlps\t{%1, %0|%0, %1}";
2630 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2632 (cond [(eq_attr "alternative" "0,1,2")
2634 (eq_attr "alternative" "3,4")
2637 /* For SSE1, we have many fewer alternatives. */
2638 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2639 (cond [(eq_attr "alternative" "5,6")
2640 (const_string "V4SF")
2642 (const_string "V2SF"))
2644 /* xorps is one byte shorter. */
2645 (eq_attr "alternative" "5")
2646 (cond [(ne (symbol_ref "optimize_size")
2648 (const_string "V4SF")
2649 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2653 (const_string "V2DF"))
2655 /* For architectures resolving dependencies on
2656 whole SSE registers use APD move to break dependency
2657 chains, otherwise use short move to avoid extra work.
2659 movaps encodes one byte shorter. */
2660 (eq_attr "alternative" "6")
2662 [(ne (symbol_ref "optimize_size")
2664 (const_string "V4SF")
2665 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2667 (const_string "V2DF")
2669 (const_string "DF"))
2670 /* For architectures resolving dependencies on register
2671 parts we may avoid extra work to zero out upper part
2673 (eq_attr "alternative" "7")
2675 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2677 (const_string "V1DF")
2678 (const_string "DF"))
2680 (const_string "DF")))])
2683 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2684 (match_operand:DF 1 "general_operand" ""))]
2686 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2687 && ! (ANY_FP_REG_P (operands[0]) ||
2688 (GET_CODE (operands[0]) == SUBREG
2689 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2690 && ! (ANY_FP_REG_P (operands[1]) ||
2691 (GET_CODE (operands[1]) == SUBREG
2692 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2694 "ix86_split_long_move (operands); DONE;")
2696 (define_insn "*swapdf"
2697 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2698 (match_operand:DF 1 "fp_register_operand" "+f"))
2701 "reload_completed || TARGET_80387"
2703 if (STACK_TOP_P (operands[0]))
2708 [(set_attr "type" "fxch")
2709 (set_attr "mode" "DF")])
2711 (define_expand "movxf"
2712 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2713 (match_operand:XF 1 "general_operand" ""))]
2715 "ix86_expand_move (XFmode, operands); DONE;")
2717 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2719 ;; Pushing using integer instructions is longer except for constants
2720 ;; and direct memory references.
2721 ;; (assuming that any given constant is pushed only once, but this ought to be
2722 ;; handled elsewhere).
2724 (define_insn "*pushxf_nointeger"
2725 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2726 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2729 /* This insn should be already split before reg-stack. */
2732 [(set_attr "type" "multi")
2733 (set_attr "unit" "i387,*,*")
2734 (set_attr "mode" "XF,SI,SI")])
2736 (define_insn "*pushxf_integer"
2737 [(set (match_operand:XF 0 "push_operand" "=<,<")
2738 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2741 /* This insn should be already split before reg-stack. */
2744 [(set_attr "type" "multi")
2745 (set_attr "unit" "i387,*")
2746 (set_attr "mode" "XF,SI")])
2749 [(set (match_operand 0 "push_operand" "")
2750 (match_operand 1 "general_operand" ""))]
2752 && (GET_MODE (operands[0]) == XFmode
2753 || GET_MODE (operands[0]) == DFmode)
2754 && !ANY_FP_REG_P (operands[1])"
2756 "ix86_split_long_move (operands); DONE;")
2759 [(set (match_operand:XF 0 "push_operand" "")
2760 (match_operand:XF 1 "any_fp_register_operand" ""))]
2762 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2763 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2764 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2767 [(set (match_operand:XF 0 "push_operand" "")
2768 (match_operand:XF 1 "any_fp_register_operand" ""))]
2770 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2771 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2772 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774 ;; Do not use integer registers when optimizing for size
2775 (define_insn "*movxf_nointeger"
2776 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2777 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2779 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2780 && (reload_in_progress || reload_completed
2781 || GET_CODE (operands[1]) != CONST_DOUBLE
2782 || memory_operand (operands[0], XFmode))"
2784 switch (which_alternative)
2787 return output_387_reg_move (insn, operands);
2790 /* There is no non-popping store to memory for XFmode. So if
2791 we need one, follow the store with a load. */
2792 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2793 return "fstp%z0\t%y0\;fld%z0\t%y0";
2795 return "fstp%z0\t%y0";
2798 return standard_80387_constant_opcode (operands[1]);
2806 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2807 (set_attr "mode" "XF,XF,XF,SI,SI")])
2809 (define_insn "*movxf_integer"
2810 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2811 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2813 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2814 && (reload_in_progress || reload_completed
2815 || GET_CODE (operands[1]) != CONST_DOUBLE
2816 || memory_operand (operands[0], XFmode))"
2818 switch (which_alternative)
2821 return output_387_reg_move (insn, operands);
2824 /* There is no non-popping store to memory for XFmode. So if
2825 we need one, follow the store with a load. */
2826 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2827 return "fstp%z0\t%y0\;fld%z0\t%y0";
2829 return "fstp%z0\t%y0";
2832 return standard_80387_constant_opcode (operands[1]);
2841 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2842 (set_attr "mode" "XF,XF,XF,SI,SI")])
2845 [(set (match_operand 0 "nonimmediate_operand" "")
2846 (match_operand 1 "general_operand" ""))]
2848 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2849 && GET_MODE (operands[0]) == XFmode
2850 && ! (ANY_FP_REG_P (operands[0]) ||
2851 (GET_CODE (operands[0]) == SUBREG
2852 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2853 && ! (ANY_FP_REG_P (operands[1]) ||
2854 (GET_CODE (operands[1]) == SUBREG
2855 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2857 "ix86_split_long_move (operands); DONE;")
2860 [(set (match_operand 0 "register_operand" "")
2861 (match_operand 1 "memory_operand" ""))]
2863 && GET_CODE (operands[1]) == MEM
2864 && (GET_MODE (operands[0]) == XFmode
2865 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2866 && constant_pool_reference_p (operands[1])"
2867 [(set (match_dup 0) (match_dup 1))]
2869 rtx c = avoid_constant_pool_reference (operands[1]);
2870 rtx r = operands[0];
2872 if (GET_CODE (r) == SUBREG)
2877 if (!standard_sse_constant_p (c))
2880 else if (FP_REG_P (r))
2882 if (!standard_80387_constant_p (c))
2885 else if (MMX_REG_P (r))
2891 (define_insn "swapxf"
2892 [(set (match_operand:XF 0 "register_operand" "+f")
2893 (match_operand:XF 1 "register_operand" "+f"))
2898 if (STACK_TOP_P (operands[0]))
2903 [(set_attr "type" "fxch")
2904 (set_attr "mode" "XF")])
2906 (define_expand "movtf"
2907 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2908 (match_operand:TF 1 "nonimmediate_operand" ""))]
2911 ix86_expand_move (TFmode, operands);
2915 (define_insn "*movtf_internal"
2916 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2917 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2919 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2921 switch (which_alternative)
2927 if (get_attr_mode (insn) == MODE_V4SF)
2928 return "xorps\t%0, %0";
2930 return "pxor\t%0, %0";
2933 if (get_attr_mode (insn) == MODE_V4SF)
2934 return "movaps\t{%1, %0|%0, %1}";
2936 return "movdqa\t{%1, %0|%0, %1}";
2941 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2943 (cond [(eq_attr "alternative" "2,3")
2945 (ne (symbol_ref "optimize_size")
2947 (const_string "V4SF")
2948 (const_string "TI"))
2949 (eq_attr "alternative" "4")
2951 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2953 (ne (symbol_ref "optimize_size")
2955 (const_string "V4SF")
2956 (const_string "TI"))]
2957 (const_string "DI")))])
2960 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2961 (match_operand:TF 1 "general_operand" ""))]
2962 "reload_completed && !SSE_REG_P (operands[0])
2963 && !SSE_REG_P (operands[1])"
2965 "ix86_split_long_move (operands); DONE;")
2967 ;; Zero extension instructions
2969 (define_expand "zero_extendhisi2"
2970 [(set (match_operand:SI 0 "register_operand" "")
2971 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2974 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2976 operands[1] = force_reg (HImode, operands[1]);
2977 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2982 (define_insn "zero_extendhisi2_and"
2983 [(set (match_operand:SI 0 "register_operand" "=r")
2984 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2985 (clobber (reg:CC FLAGS_REG))]
2986 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2988 [(set_attr "type" "alu1")
2989 (set_attr "mode" "SI")])
2992 [(set (match_operand:SI 0 "register_operand" "")
2993 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2994 (clobber (reg:CC FLAGS_REG))]
2995 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2996 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2997 (clobber (reg:CC FLAGS_REG))])]
3000 (define_insn "*zero_extendhisi2_movzwl"
3001 [(set (match_operand:SI 0 "register_operand" "=r")
3002 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3003 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3004 "movz{wl|x}\t{%1, %0|%0, %1}"
3005 [(set_attr "type" "imovx")
3006 (set_attr "mode" "SI")])
3008 (define_expand "zero_extendqihi2"
3010 [(set (match_operand:HI 0 "register_operand" "")
3011 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3012 (clobber (reg:CC FLAGS_REG))])]
3016 (define_insn "*zero_extendqihi2_and"
3017 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3018 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3019 (clobber (reg:CC FLAGS_REG))]
3020 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3022 [(set_attr "type" "alu1")
3023 (set_attr "mode" "HI")])
3025 (define_insn "*zero_extendqihi2_movzbw_and"
3026 [(set (match_operand:HI 0 "register_operand" "=r,r")
3027 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3028 (clobber (reg:CC FLAGS_REG))]
3029 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3031 [(set_attr "type" "imovx,alu1")
3032 (set_attr "mode" "HI")])
3034 ; zero extend to SImode here to avoid partial register stalls
3035 (define_insn "*zero_extendqihi2_movzbl"
3036 [(set (match_operand:HI 0 "register_operand" "=r")
3037 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3038 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3039 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3040 [(set_attr "type" "imovx")
3041 (set_attr "mode" "SI")])
3043 ;; For the movzbw case strip only the clobber
3045 [(set (match_operand:HI 0 "register_operand" "")
3046 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3047 (clobber (reg:CC FLAGS_REG))]
3049 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3050 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3051 [(set (match_operand:HI 0 "register_operand" "")
3052 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3054 ;; When source and destination does not overlap, clear destination
3055 ;; first and then do the movb
3057 [(set (match_operand:HI 0 "register_operand" "")
3058 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3059 (clobber (reg:CC FLAGS_REG))]
3061 && ANY_QI_REG_P (operands[0])
3062 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3063 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3064 [(set (match_dup 0) (const_int 0))
3065 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3066 "operands[2] = gen_lowpart (QImode, operands[0]);")
3068 ;; Rest is handled by single and.
3070 [(set (match_operand:HI 0 "register_operand" "")
3071 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3072 (clobber (reg:CC FLAGS_REG))]
3074 && true_regnum (operands[0]) == true_regnum (operands[1])"
3075 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3076 (clobber (reg:CC FLAGS_REG))])]
3079 (define_expand "zero_extendqisi2"
3081 [(set (match_operand:SI 0 "register_operand" "")
3082 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3083 (clobber (reg:CC FLAGS_REG))])]
3087 (define_insn "*zero_extendqisi2_and"
3088 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3089 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3090 (clobber (reg:CC FLAGS_REG))]
3091 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3093 [(set_attr "type" "alu1")
3094 (set_attr "mode" "SI")])
3096 (define_insn "*zero_extendqisi2_movzbw_and"
3097 [(set (match_operand:SI 0 "register_operand" "=r,r")
3098 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3099 (clobber (reg:CC FLAGS_REG))]
3100 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3102 [(set_attr "type" "imovx,alu1")
3103 (set_attr "mode" "SI")])
3105 (define_insn "*zero_extendqisi2_movzbw"
3106 [(set (match_operand:SI 0 "register_operand" "=r")
3107 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3108 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3109 "movz{bl|x}\t{%1, %0|%0, %1}"
3110 [(set_attr "type" "imovx")
3111 (set_attr "mode" "SI")])
3113 ;; For the movzbl case strip only the clobber
3115 [(set (match_operand:SI 0 "register_operand" "")
3116 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3117 (clobber (reg:CC FLAGS_REG))]
3119 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3120 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3122 (zero_extend:SI (match_dup 1)))])
3124 ;; When source and destination does not overlap, clear destination
3125 ;; first and then do the movb
3127 [(set (match_operand:SI 0 "register_operand" "")
3128 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3129 (clobber (reg:CC FLAGS_REG))]
3131 && ANY_QI_REG_P (operands[0])
3132 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3133 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3134 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3135 [(set (match_dup 0) (const_int 0))
3136 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3137 "operands[2] = gen_lowpart (QImode, operands[0]);")
3139 ;; Rest is handled by single and.
3141 [(set (match_operand:SI 0 "register_operand" "")
3142 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3143 (clobber (reg:CC FLAGS_REG))]
3145 && true_regnum (operands[0]) == true_regnum (operands[1])"
3146 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3147 (clobber (reg:CC FLAGS_REG))])]
3150 ;; %%% Kill me once multi-word ops are sane.
3151 (define_expand "zero_extendsidi2"
3152 [(set (match_operand:DI 0 "register_operand" "=r")
3153 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3157 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3162 (define_insn "zero_extendsidi2_32"
3163 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3164 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3165 (clobber (reg:CC FLAGS_REG))]
3171 movd\t{%1, %0|%0, %1}
3172 movd\t{%1, %0|%0, %1}"
3173 [(set_attr "mode" "SI,SI,SI,DI,TI")
3174 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3176 (define_insn "zero_extendsidi2_rex64"
3177 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3178 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3181 mov\t{%k1, %k0|%k0, %k1}
3183 movd\t{%1, %0|%0, %1}
3184 movd\t{%1, %0|%0, %1}"
3185 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3186 (set_attr "mode" "SI,DI,SI,SI")])
3189 [(set (match_operand:DI 0 "memory_operand" "")
3190 (zero_extend:DI (match_dup 0)))]
3192 [(set (match_dup 4) (const_int 0))]
3193 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3196 [(set (match_operand:DI 0 "register_operand" "")
3197 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3198 (clobber (reg:CC FLAGS_REG))]
3199 "!TARGET_64BIT && reload_completed
3200 && true_regnum (operands[0]) == true_regnum (operands[1])"
3201 [(set (match_dup 4) (const_int 0))]
3202 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3206 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3207 (clobber (reg:CC FLAGS_REG))]
3208 "!TARGET_64BIT && reload_completed
3209 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3210 [(set (match_dup 3) (match_dup 1))
3211 (set (match_dup 4) (const_int 0))]
3212 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3214 (define_insn "zero_extendhidi2"
3215 [(set (match_operand:DI 0 "register_operand" "=r")
3216 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3218 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3219 [(set_attr "type" "imovx")
3220 (set_attr "mode" "DI")])
3222 (define_insn "zero_extendqidi2"
3223 [(set (match_operand:DI 0 "register_operand" "=r")
3224 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3226 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3227 [(set_attr "type" "imovx")
3228 (set_attr "mode" "DI")])
3230 ;; Sign extension instructions
3232 (define_expand "extendsidi2"
3233 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3234 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3235 (clobber (reg:CC FLAGS_REG))
3236 (clobber (match_scratch:SI 2 ""))])]
3241 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3246 (define_insn "*extendsidi2_1"
3247 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3248 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3249 (clobber (reg:CC FLAGS_REG))
3250 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3254 (define_insn "extendsidi2_rex64"
3255 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3256 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3260 movs{lq|x}\t{%1,%0|%0, %1}"
3261 [(set_attr "type" "imovx")
3262 (set_attr "mode" "DI")
3263 (set_attr "prefix_0f" "0")
3264 (set_attr "modrm" "0,1")])
3266 (define_insn "extendhidi2"
3267 [(set (match_operand:DI 0 "register_operand" "=r")
3268 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3270 "movs{wq|x}\t{%1,%0|%0, %1}"
3271 [(set_attr "type" "imovx")
3272 (set_attr "mode" "DI")])
3274 (define_insn "extendqidi2"
3275 [(set (match_operand:DI 0 "register_operand" "=r")
3276 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278 "movs{bq|x}\t{%1,%0|%0, %1}"
3279 [(set_attr "type" "imovx")
3280 (set_attr "mode" "DI")])
3282 ;; Extend to memory case when source register does die.
3284 [(set (match_operand:DI 0 "memory_operand" "")
3285 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3286 (clobber (reg:CC FLAGS_REG))
3287 (clobber (match_operand:SI 2 "register_operand" ""))]
3289 && dead_or_set_p (insn, operands[1])
3290 && !reg_mentioned_p (operands[1], operands[0]))"
3291 [(set (match_dup 3) (match_dup 1))
3292 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3293 (clobber (reg:CC FLAGS_REG))])
3294 (set (match_dup 4) (match_dup 1))]
3295 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3297 ;; Extend to memory case when source register does not die.
3299 [(set (match_operand:DI 0 "memory_operand" "")
3300 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3301 (clobber (reg:CC FLAGS_REG))
3302 (clobber (match_operand:SI 2 "register_operand" ""))]
3306 split_di (&operands[0], 1, &operands[3], &operands[4]);
3308 emit_move_insn (operands[3], operands[1]);
3310 /* Generate a cltd if possible and doing so it profitable. */
3311 if (true_regnum (operands[1]) == 0
3312 && true_regnum (operands[2]) == 1
3313 && (optimize_size || TARGET_USE_CLTD))
3315 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3319 emit_move_insn (operands[2], operands[1]);
3320 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3322 emit_move_insn (operands[4], operands[2]);
3326 ;; Extend to register case. Optimize case where source and destination
3327 ;; registers match and cases where we can use cltd.
3329 [(set (match_operand:DI 0 "register_operand" "")
3330 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3331 (clobber (reg:CC FLAGS_REG))
3332 (clobber (match_scratch:SI 2 ""))]
3336 split_di (&operands[0], 1, &operands[3], &operands[4]);
3338 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3339 emit_move_insn (operands[3], operands[1]);
3341 /* Generate a cltd if possible and doing so it profitable. */
3342 if (true_regnum (operands[3]) == 0
3343 && (optimize_size || TARGET_USE_CLTD))
3345 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3349 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3350 emit_move_insn (operands[4], operands[1]);
3352 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3356 (define_insn "extendhisi2"
3357 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3358 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3361 switch (get_attr_prefix_0f (insn))
3364 return "{cwtl|cwde}";
3366 return "movs{wl|x}\t{%1,%0|%0, %1}";
3369 [(set_attr "type" "imovx")
3370 (set_attr "mode" "SI")
3371 (set (attr "prefix_0f")
3372 ;; movsx is short decodable while cwtl is vector decoded.
3373 (if_then_else (and (eq_attr "cpu" "!k6")
3374 (eq_attr "alternative" "0"))