1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GNU CC.
10 ;; GNU CC 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 ;; GNU CC 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 GNU CC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, 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 #define NOTICE_UPDATE_CC in file i386.h handles condition code
31 ;; updates for most instructions.
33 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
34 ;; constraint letters.
36 ;; The special asm out single letter directives following a '%' are:
37 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
39 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
40 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
41 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
42 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
43 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
44 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
45 ;; 'J' Print the appropriate jump operand.
47 ;; 'b' Print the QImode name of the register for the indicated operand.
48 ;; %b0 would print %al if operands[0] is reg 0.
49 ;; 'w' Likewise, print the HImode name of the register.
50 ;; 'k' Likewise, print the SImode name of the register.
51 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; 'y' Print "st(0)" instead of "st" as a register.
57 [; Relocation specifiers
69 (UNSPEC_STACK_PROBE 10)
70 (UNSPEC_STACK_ALLOC 11)
72 (UNSPEC_SSE_PROLOGUE_SAVE 13)
77 (UNSPEC_TLS_LD_BASE 17)
79 ; Other random patterns
89 ; For SSE/MMX support:
100 (UNSPEC_NOP 45) ; prevents combiner cleverness
122 [(UNSPECV_BLOCKAGE 0)
123 (UNSPECV_EH_RETURN 13)
132 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
135 ;; In C guard expressions, put expressions which may be compile-time
136 ;; constants first. This allows for better optimization. For
137 ;; example, write "TARGET_64BIT && reload_completed", not
138 ;; "reload_completed && TARGET_64BIT".
141 ;; Processor type. This attribute must exactly match the processor_type
142 ;; enumeration in i386.h.
143 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
144 (const (symbol_ref "ix86_tune")))
146 ;; A basic instruction type. Refinements due to arguments to be
147 ;; provided in other attributes.
150 alu,alu1,negnot,imov,imovx,lea,
151 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
152 icmp,test,ibr,setcc,icmov,
153 push,pop,call,callv,leave,
155 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
156 sselog,sseiadd,sseishft,sseimul,
157 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
158 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
159 (const_string "other"))
161 ;; Main data type used by the insn
163 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
164 (const_string "unknown"))
166 ;; The CPU unit operations uses.
167 (define_attr "unit" "integer,i387,sse,mmx,unknown"
168 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
169 (const_string "i387")
170 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
171 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
173 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
175 (eq_attr "type" "other")
176 (const_string "unknown")]
177 (const_string "integer")))
179 ;; The (bounding maximum) length of an instruction immediate.
180 (define_attr "length_immediate" ""
181 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
183 (eq_attr "unit" "i387,sse,mmx")
185 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
187 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
188 (eq_attr "type" "imov,test")
189 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
190 (eq_attr "type" "call")
191 (if_then_else (match_operand 0 "constant_call_address_operand" "")
194 (eq_attr "type" "callv")
195 (if_then_else (match_operand 1 "constant_call_address_operand" "")
198 ;; We don't know the size before shorten_branches. Expect
199 ;; the instruction to fit for better scheduling.
200 (eq_attr "type" "ibr")
203 (symbol_ref "/* Update immediate_length and other attributes! */
206 ;; The (bounding maximum) length of an instruction address.
207 (define_attr "length_address" ""
208 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
210 (and (eq_attr "type" "call")
211 (match_operand 0 "constant_call_address_operand" ""))
213 (and (eq_attr "type" "callv")
214 (match_operand 1 "constant_call_address_operand" ""))
217 (symbol_ref "ix86_attr_length_address_default (insn)")))
219 ;; Set when length prefix is used.
220 (define_attr "prefix_data16" ""
221 (if_then_else (ior (eq_attr "mode" "HI")
222 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
226 ;; Set when string REP prefix is used.
227 (define_attr "prefix_rep" ""
228 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
232 ;; Set when 0f opcode prefix is used.
233 (define_attr "prefix_0f" ""
235 (ior (eq_attr "type" "imovx,setcc,icmov")
236 (eq_attr "unit" "sse,mmx"))
240 ;; Set when 0f opcode prefix is used.
241 (define_attr "prefix_rex" ""
242 (cond [(and (eq_attr "mode" "DI")
243 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
245 (and (eq_attr "mode" "QI")
246 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
249 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
255 ;; Set when modrm byte is used.
256 (define_attr "modrm" ""
257 (cond [(eq_attr "type" "str,cld,leave")
259 (eq_attr "unit" "i387")
261 (and (eq_attr "type" "incdec")
262 (ior (match_operand:SI 1 "register_operand" "")
263 (match_operand:HI 1 "register_operand" "")))
265 (and (eq_attr "type" "push")
266 (not (match_operand 1 "memory_operand" "")))
268 (and (eq_attr "type" "pop")
269 (not (match_operand 0 "memory_operand" "")))
271 (and (eq_attr "type" "imov")
272 (and (match_operand 0 "register_operand" "")
273 (match_operand 1 "immediate_operand" "")))
275 (and (eq_attr "type" "call")
276 (match_operand 0 "constant_call_address_operand" ""))
278 (and (eq_attr "type" "callv")
279 (match_operand 1 "constant_call_address_operand" ""))
284 ;; The (bounding maximum) length of an instruction in bytes.
285 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
286 ;; to split it and compute proper length as for other insns.
287 (define_attr "length" ""
288 (cond [(eq_attr "type" "other,multi,fistp")
290 (eq_attr "type" "fcmp")
292 (eq_attr "unit" "i387")
294 (plus (attr "prefix_data16")
295 (attr "length_address")))]
296 (plus (plus (attr "modrm")
297 (plus (attr "prefix_0f")
298 (plus (attr "prefix_rex")
300 (plus (attr "prefix_rep")
301 (plus (attr "prefix_data16")
302 (plus (attr "length_immediate")
303 (attr "length_address")))))))
305 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
306 ;; `store' if there is a simple memory reference therein, or `unknown'
307 ;; if the instruction is complex.
309 (define_attr "memory" "none,load,store,both,unknown"
310 (cond [(eq_attr "type" "other,multi,str")
311 (const_string "unknown")
312 (eq_attr "type" "lea,fcmov,fpspc,cld")
313 (const_string "none")
314 (eq_attr "type" "fistp,leave")
315 (const_string "both")
316 (eq_attr "type" "push")
317 (if_then_else (match_operand 1 "memory_operand" "")
318 (const_string "both")
319 (const_string "store"))
320 (eq_attr "type" "pop")
321 (if_then_else (match_operand 0 "memory_operand" "")
322 (const_string "both")
323 (const_string "load"))
324 (eq_attr "type" "setcc")
325 (if_then_else (match_operand 0 "memory_operand" "")
326 (const_string "store")
327 (const_string "none"))
328 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
329 (if_then_else (ior (match_operand 0 "memory_operand" "")
330 (match_operand 1 "memory_operand" ""))
331 (const_string "load")
332 (const_string "none"))
333 (eq_attr "type" "ibr")
334 (if_then_else (match_operand 0 "memory_operand" "")
335 (const_string "load")
336 (const_string "none"))
337 (eq_attr "type" "call")
338 (if_then_else (match_operand 0 "constant_call_address_operand" "")
339 (const_string "none")
340 (const_string "load"))
341 (eq_attr "type" "callv")
342 (if_then_else (match_operand 1 "constant_call_address_operand" "")
343 (const_string "none")
344 (const_string "load"))
345 (and (eq_attr "type" "alu1,negnot")
346 (match_operand 1 "memory_operand" ""))
347 (const_string "both")
348 (and (match_operand 0 "memory_operand" "")
349 (match_operand 1 "memory_operand" ""))
350 (const_string "both")
351 (match_operand 0 "memory_operand" "")
352 (const_string "store")
353 (match_operand 1 "memory_operand" "")
354 (const_string "load")
357 imov,imovx,icmp,test,
359 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
360 mmx,mmxmov,mmxcmp,mmxcvt")
361 (match_operand 2 "memory_operand" ""))
362 (const_string "load")
363 (and (eq_attr "type" "icmov")
364 (match_operand 3 "memory_operand" ""))
365 (const_string "load")
367 (const_string "none")))
369 ;; Indicates if an instruction has both an immediate and a displacement.
371 (define_attr "imm_disp" "false,true,unknown"
372 (cond [(eq_attr "type" "other,multi")
373 (const_string "unknown")
374 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
375 (and (match_operand 0 "memory_displacement_operand" "")
376 (match_operand 1 "immediate_operand" "")))
377 (const_string "true")
378 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
379 (and (match_operand 0 "memory_displacement_operand" "")
380 (match_operand 2 "immediate_operand" "")))
381 (const_string "true")
383 (const_string "false")))
385 ;; Indicates if an FP operation has an integer source.
387 (define_attr "fp_int_src" "false,true"
388 (const_string "false"))
390 ;; Describe a user's asm statement.
391 (define_asm_attributes
392 [(set_attr "length" "128")
393 (set_attr "type" "multi")])
395 (include "pentium.md")
398 (include "athlon.md")
400 ;; Compare instructions.
402 ;; All compare insns have expanders that save the operands away without
403 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
404 ;; after the cmp) will actually emit the cmpM.
406 (define_expand "cmpdi"
408 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
409 (match_operand:DI 1 "x86_64_general_operand" "")))]
412 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
413 operands[0] = force_reg (DImode, operands[0]);
414 ix86_compare_op0 = operands[0];
415 ix86_compare_op1 = operands[1];
419 (define_expand "cmpsi"
421 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
422 (match_operand:SI 1 "general_operand" "")))]
425 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
426 operands[0] = force_reg (SImode, operands[0]);
427 ix86_compare_op0 = operands[0];
428 ix86_compare_op1 = operands[1];
432 (define_expand "cmphi"
434 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
435 (match_operand:HI 1 "general_operand" "")))]
438 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
439 operands[0] = force_reg (HImode, operands[0]);
440 ix86_compare_op0 = operands[0];
441 ix86_compare_op1 = operands[1];
445 (define_expand "cmpqi"
447 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
448 (match_operand:QI 1 "general_operand" "")))]
451 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
452 operands[0] = force_reg (QImode, operands[0]);
453 ix86_compare_op0 = operands[0];
454 ix86_compare_op1 = operands[1];
458 (define_insn "cmpdi_ccno_1_rex64"
460 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
461 (match_operand:DI 1 "const0_operand" "n,n")))]
462 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
464 test{q}\t{%0, %0|%0, %0}
465 cmp{q}\t{%1, %0|%0, %1}"
466 [(set_attr "type" "test,icmp")
467 (set_attr "length_immediate" "0,1")
468 (set_attr "mode" "DI")])
470 (define_insn "*cmpdi_minus_1_rex64"
472 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
473 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
475 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
476 "cmp{q}\t{%1, %0|%0, %1}"
477 [(set_attr "type" "icmp")
478 (set_attr "mode" "DI")])
480 (define_expand "cmpdi_1_rex64"
482 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
483 (match_operand:DI 1 "general_operand" "")))]
487 (define_insn "cmpdi_1_insn_rex64"
489 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
490 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
491 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
492 "cmp{q}\t{%1, %0|%0, %1}"
493 [(set_attr "type" "icmp")
494 (set_attr "mode" "DI")])
497 (define_insn "*cmpsi_ccno_1"
499 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
500 (match_operand:SI 1 "const0_operand" "n,n")))]
501 "ix86_match_ccmode (insn, CCNOmode)"
503 test{l}\t{%0, %0|%0, %0}
504 cmp{l}\t{%1, %0|%0, %1}"
505 [(set_attr "type" "test,icmp")
506 (set_attr "length_immediate" "0,1")
507 (set_attr "mode" "SI")])
509 (define_insn "*cmpsi_minus_1"
511 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
512 (match_operand:SI 1 "general_operand" "ri,mr"))
514 "ix86_match_ccmode (insn, CCGOCmode)"
515 "cmp{l}\t{%1, %0|%0, %1}"
516 [(set_attr "type" "icmp")
517 (set_attr "mode" "SI")])
519 (define_expand "cmpsi_1"
521 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
522 (match_operand:SI 1 "general_operand" "ri,mr")))]
526 (define_insn "*cmpsi_1_insn"
528 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
529 (match_operand:SI 1 "general_operand" "ri,mr")))]
530 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
531 && ix86_match_ccmode (insn, CCmode)"
532 "cmp{l}\t{%1, %0|%0, %1}"
533 [(set_attr "type" "icmp")
534 (set_attr "mode" "SI")])
536 (define_insn "*cmphi_ccno_1"
538 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
539 (match_operand:HI 1 "const0_operand" "n,n")))]
540 "ix86_match_ccmode (insn, CCNOmode)"
542 test{w}\t{%0, %0|%0, %0}
543 cmp{w}\t{%1, %0|%0, %1}"
544 [(set_attr "type" "test,icmp")
545 (set_attr "length_immediate" "0,1")
546 (set_attr "mode" "HI")])
548 (define_insn "*cmphi_minus_1"
550 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
551 (match_operand:HI 1 "general_operand" "ri,mr"))
553 "ix86_match_ccmode (insn, CCGOCmode)"
554 "cmp{w}\t{%1, %0|%0, %1}"
555 [(set_attr "type" "icmp")
556 (set_attr "mode" "HI")])
558 (define_insn "*cmphi_1"
560 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
561 (match_operand:HI 1 "general_operand" "ri,mr")))]
562 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
563 && ix86_match_ccmode (insn, CCmode)"
564 "cmp{w}\t{%1, %0|%0, %1}"
565 [(set_attr "type" "icmp")
566 (set_attr "mode" "HI")])
568 (define_insn "*cmpqi_ccno_1"
570 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
571 (match_operand:QI 1 "const0_operand" "n,n")))]
572 "ix86_match_ccmode (insn, CCNOmode)"
574 test{b}\t{%0, %0|%0, %0}
575 cmp{b}\t{$0, %0|%0, 0}"
576 [(set_attr "type" "test,icmp")
577 (set_attr "length_immediate" "0,1")
578 (set_attr "mode" "QI")])
580 (define_insn "*cmpqi_1"
582 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
583 (match_operand:QI 1 "general_operand" "qi,mq")))]
584 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
585 && ix86_match_ccmode (insn, CCmode)"
586 "cmp{b}\t{%1, %0|%0, %1}"
587 [(set_attr "type" "icmp")
588 (set_attr "mode" "QI")])
590 (define_insn "*cmpqi_minus_1"
592 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
593 (match_operand:QI 1 "general_operand" "qi,mq"))
595 "ix86_match_ccmode (insn, CCGOCmode)"
596 "cmp{b}\t{%1, %0|%0, %1}"
597 [(set_attr "type" "icmp")
598 (set_attr "mode" "QI")])
600 (define_insn "*cmpqi_ext_1"
603 (match_operand:QI 0 "general_operand" "Qm")
606 (match_operand 1 "ext_register_operand" "Q")
609 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
610 "cmp{b}\t{%h1, %0|%0, %h1}"
611 [(set_attr "type" "icmp")
612 (set_attr "mode" "QI")])
614 (define_insn "*cmpqi_ext_1_rex64"
617 (match_operand:QI 0 "register_operand" "Q")
620 (match_operand 1 "ext_register_operand" "Q")
623 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
624 "cmp{b}\t{%h1, %0|%0, %h1}"
625 [(set_attr "type" "icmp")
626 (set_attr "mode" "QI")])
628 (define_insn "*cmpqi_ext_2"
633 (match_operand 0 "ext_register_operand" "Q")
636 (match_operand:QI 1 "const0_operand" "n")))]
637 "ix86_match_ccmode (insn, CCNOmode)"
639 [(set_attr "type" "test")
640 (set_attr "length_immediate" "0")
641 (set_attr "mode" "QI")])
643 (define_expand "cmpqi_ext_3"
648 (match_operand 0 "ext_register_operand" "")
651 (match_operand:QI 1 "general_operand" "")))]
655 (define_insn "cmpqi_ext_3_insn"
660 (match_operand 0 "ext_register_operand" "Q")
663 (match_operand:QI 1 "general_operand" "Qmn")))]
664 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665 "cmp{b}\t{%1, %h0|%h0, %1}"
666 [(set_attr "type" "icmp")
667 (set_attr "mode" "QI")])
669 (define_insn "cmpqi_ext_3_insn_rex64"
674 (match_operand 0 "ext_register_operand" "Q")
677 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
678 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679 "cmp{b}\t{%1, %h0|%h0, %1}"
680 [(set_attr "type" "icmp")
681 (set_attr "mode" "QI")])
683 (define_insn "*cmpqi_ext_4"
688 (match_operand 0 "ext_register_operand" "Q")
693 (match_operand 1 "ext_register_operand" "Q")
696 "ix86_match_ccmode (insn, CCmode)"
697 "cmp{b}\t{%h1, %h0|%h0, %h1}"
698 [(set_attr "type" "icmp")
699 (set_attr "mode" "QI")])
701 ;; These implement float point compares.
702 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
703 ;; which would allow mix and match FP modes on the compares. Which is what
704 ;; the old patterns did, but with many more of them.
706 (define_expand "cmpxf"
708 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
709 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
710 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
712 ix86_compare_op0 = operands[0];
713 ix86_compare_op1 = operands[1];
717 (define_expand "cmptf"
719 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
720 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
723 ix86_compare_op0 = operands[0];
724 ix86_compare_op1 = operands[1];
728 (define_expand "cmpdf"
730 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
731 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
732 "TARGET_80387 || TARGET_SSE2"
734 ix86_compare_op0 = operands[0];
735 ix86_compare_op1 = operands[1];
739 (define_expand "cmpsf"
741 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
742 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
743 "TARGET_80387 || TARGET_SSE"
745 ix86_compare_op0 = operands[0];
746 ix86_compare_op1 = operands[1];
750 ;; FP compares, step 1:
751 ;; Set the FP condition codes.
753 ;; CCFPmode compare with exceptions
754 ;; CCFPUmode compare with no exceptions
756 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
757 ;; and that fp moves clobber the condition codes, and that there is
758 ;; currently no way to describe this fact to reg-stack. So there are
759 ;; no splitters yet for this.
761 ;; %%% YIKES! This scheme does not retain a strong connection between
762 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
763 ;; work! Only allow tos/mem with tos in op 0.
765 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
766 ;; things aren't as bad as they sound...
768 (define_insn "*cmpfp_0"
769 [(set (match_operand:HI 0 "register_operand" "=a")
771 [(compare:CCFP (match_operand 1 "register_operand" "f")
772 (match_operand 2 "const0_operand" "X"))]
775 && FLOAT_MODE_P (GET_MODE (operands[1]))
776 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
778 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
779 return "ftst\;fnstsw\t%0\;fstp\t%y0";
781 return "ftst\;fnstsw\t%0";
783 [(set_attr "type" "multi")
785 (cond [(match_operand:SF 1 "" "")
787 (match_operand:DF 1 "" "")
790 (const_string "XF")))])
792 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
793 ;; used to manage the reg stack popping would not be preserved.
795 (define_insn "*cmpfp_2_sf"
798 (match_operand:SF 0 "register_operand" "f")
799 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
801 "* return output_fp_compare (insn, operands, 0, 0);"
802 [(set_attr "type" "fcmp")
803 (set_attr "mode" "SF")])
805 (define_insn "*cmpfp_2_sf_1"
806 [(set (match_operand:HI 0 "register_operand" "=a")
809 (match_operand:SF 1 "register_operand" "f")
810 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
813 "* return output_fp_compare (insn, operands, 2, 0);"
814 [(set_attr "type" "fcmp")
815 (set_attr "mode" "SF")])
817 (define_insn "*cmpfp_2_df"
820 (match_operand:DF 0 "register_operand" "f")
821 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
823 "* return output_fp_compare (insn, operands, 0, 0);"
824 [(set_attr "type" "fcmp")
825 (set_attr "mode" "DF")])
827 (define_insn "*cmpfp_2_df_1"
828 [(set (match_operand:HI 0 "register_operand" "=a")
831 (match_operand:DF 1 "register_operand" "f")
832 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
835 "* return output_fp_compare (insn, operands, 2, 0);"
836 [(set_attr "type" "multi")
837 (set_attr "mode" "DF")])
839 (define_insn "*cmpfp_2_xf"
842 (match_operand:XF 0 "register_operand" "f")
843 (match_operand:XF 1 "register_operand" "f")))]
844 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
845 "* return output_fp_compare (insn, operands, 0, 0);"
846 [(set_attr "type" "fcmp")
847 (set_attr "mode" "XF")])
849 (define_insn "*cmpfp_2_tf"
852 (match_operand:TF 0 "register_operand" "f")
853 (match_operand:TF 1 "register_operand" "f")))]
855 "* return output_fp_compare (insn, operands, 0, 0);"
856 [(set_attr "type" "fcmp")
857 (set_attr "mode" "XF")])
859 (define_insn "*cmpfp_2_xf_1"
860 [(set (match_operand:HI 0 "register_operand" "=a")
863 (match_operand:XF 1 "register_operand" "f")
864 (match_operand:XF 2 "register_operand" "f"))]
866 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
867 "* return output_fp_compare (insn, operands, 2, 0);"
868 [(set_attr "type" "multi")
869 (set_attr "mode" "XF")])
871 (define_insn "*cmpfp_2_tf_1"
872 [(set (match_operand:HI 0 "register_operand" "=a")
875 (match_operand:TF 1 "register_operand" "f")
876 (match_operand:TF 2 "register_operand" "f"))]
879 "* return output_fp_compare (insn, operands, 2, 0);"
880 [(set_attr "type" "multi")
881 (set_attr "mode" "XF")])
883 (define_insn "*cmpfp_2u"
886 (match_operand 0 "register_operand" "f")
887 (match_operand 1 "register_operand" "f")))]
889 && FLOAT_MODE_P (GET_MODE (operands[0]))
890 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
891 "* return output_fp_compare (insn, operands, 0, 1);"
892 [(set_attr "type" "fcmp")
894 (cond [(match_operand:SF 1 "" "")
896 (match_operand:DF 1 "" "")
899 (const_string "XF")))])
901 (define_insn "*cmpfp_2u_1"
902 [(set (match_operand:HI 0 "register_operand" "=a")
905 (match_operand 1 "register_operand" "f")
906 (match_operand 2 "register_operand" "f"))]
909 && FLOAT_MODE_P (GET_MODE (operands[1]))
910 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
911 "* return output_fp_compare (insn, operands, 2, 1);"
912 [(set_attr "type" "multi")
914 (cond [(match_operand:SF 1 "" "")
916 (match_operand:DF 1 "" "")
919 (const_string "XF")))])
921 ;; Patterns to match the SImode-in-memory ficom instructions.
923 ;; %%% Play games with accepting gp registers, as otherwise we have to
924 ;; force them to memory during rtl generation, which is no good. We
925 ;; can get rid of this once we teach reload to do memory input reloads
928 (define_insn "*ficom_1"
931 (match_operand 0 "register_operand" "f,f")
932 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
933 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
934 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
937 ;; Split the not-really-implemented gp register case into a
938 ;; push-op-pop sequence.
940 ;; %%% This is most efficient, but am I gonna get in trouble
941 ;; for separating cc0_setter and cc0_user?
946 (match_operand:SF 0 "register_operand" "")
947 (float (match_operand:SI 1 "register_operand" ""))))]
948 "0 && TARGET_80387 && reload_completed"
949 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
950 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
951 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
952 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
953 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
954 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
956 ;; FP compares, step 2
957 ;; Move the fpsw to ax.
959 (define_insn "*x86_fnstsw_1"
960 [(set (match_operand:HI 0 "register_operand" "=a")
961 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
964 [(set_attr "length" "2")
965 (set_attr "mode" "SI")
966 (set_attr "unit" "i387")
967 (set_attr "ppro_uops" "few")])
969 ;; FP compares, step 3
970 ;; Get ax into flags, general case.
972 (define_insn "x86_sahf_1"
974 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
977 [(set_attr "length" "1")
978 (set_attr "athlon_decode" "vector")
979 (set_attr "mode" "SI")
980 (set_attr "ppro_uops" "one")])
982 ;; Pentium Pro can do steps 1 through 3 in one go.
984 (define_insn "*cmpfp_i"
986 (compare:CCFP (match_operand 0 "register_operand" "f")
987 (match_operand 1 "register_operand" "f")))]
988 "TARGET_80387 && TARGET_CMOVE
989 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990 && FLOAT_MODE_P (GET_MODE (operands[0]))
991 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
992 "* return output_fp_compare (insn, operands, 1, 0);"
993 [(set_attr "type" "fcmp")
995 (cond [(match_operand:SF 1 "" "")
997 (match_operand:DF 1 "" "")
1000 (const_string "XF")))
1001 (set_attr "athlon_decode" "vector")])
1003 (define_insn "*cmpfp_i_sse"
1005 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1006 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1009 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1010 "* return output_fp_compare (insn, operands, 1, 0);"
1011 [(set_attr "type" "fcmp,ssecomi")
1013 (if_then_else (match_operand:SF 1 "" "")
1015 (const_string "DF")))
1016 (set_attr "athlon_decode" "vector")])
1018 (define_insn "*cmpfp_i_sse_only"
1020 (compare:CCFP (match_operand 0 "register_operand" "x")
1021 (match_operand 1 "nonimmediate_operand" "xm")))]
1022 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1023 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1024 "* return output_fp_compare (insn, operands, 1, 0);"
1025 [(set_attr "type" "ssecomi")
1027 (if_then_else (match_operand:SF 1 "" "")
1029 (const_string "DF")))
1030 (set_attr "athlon_decode" "vector")])
1032 (define_insn "*cmpfp_iu"
1033 [(set (reg:CCFPU 17)
1034 (compare:CCFPU (match_operand 0 "register_operand" "f")
1035 (match_operand 1 "register_operand" "f")))]
1036 "TARGET_80387 && TARGET_CMOVE
1037 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038 && FLOAT_MODE_P (GET_MODE (operands[0]))
1039 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040 "* return output_fp_compare (insn, operands, 1, 1);"
1041 [(set_attr "type" "fcmp")
1043 (cond [(match_operand:SF 1 "" "")
1045 (match_operand:DF 1 "" "")
1048 (const_string "XF")))
1049 (set_attr "athlon_decode" "vector")])
1051 (define_insn "*cmpfp_iu_sse"
1052 [(set (reg:CCFPU 17)
1053 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1054 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1056 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1057 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1058 "* return output_fp_compare (insn, operands, 1, 1);"
1059 [(set_attr "type" "fcmp,ssecomi")
1061 (if_then_else (match_operand:SF 1 "" "")
1063 (const_string "DF")))
1064 (set_attr "athlon_decode" "vector")])
1066 (define_insn "*cmpfp_iu_sse_only"
1067 [(set (reg:CCFPU 17)
1068 (compare:CCFPU (match_operand 0 "register_operand" "x")
1069 (match_operand 1 "nonimmediate_operand" "xm")))]
1070 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1071 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1072 "* return output_fp_compare (insn, operands, 1, 1);"
1073 [(set_attr "type" "ssecomi")
1075 (if_then_else (match_operand:SF 1 "" "")
1077 (const_string "DF")))
1078 (set_attr "athlon_decode" "vector")])
1080 ;; Move instructions.
1082 ;; General case of fullword move.
1084 (define_expand "movsi"
1085 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1086 (match_operand:SI 1 "general_operand" ""))]
1088 "ix86_expand_move (SImode, operands); DONE;")
1090 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1093 ;; %%% We don't use a post-inc memory reference because x86 is not a
1094 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1095 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1096 ;; targets without our curiosities, and it is just as easy to represent
1097 ;; this differently.
1099 (define_insn "*pushsi2"
1100 [(set (match_operand:SI 0 "push_operand" "=<")
1101 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1104 [(set_attr "type" "push")
1105 (set_attr "mode" "SI")])
1107 ;; For 64BIT abi we always round up to 8 bytes.
1108 (define_insn "*pushsi2_rex64"
1109 [(set (match_operand:SI 0 "push_operand" "=X")
1110 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1113 [(set_attr "type" "push")
1114 (set_attr "mode" "SI")])
1116 (define_insn "*pushsi2_prologue"
1117 [(set (match_operand:SI 0 "push_operand" "=<")
1118 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1119 (clobber (mem:BLK (scratch)))]
1122 [(set_attr "type" "push")
1123 (set_attr "mode" "SI")])
1125 (define_insn "*popsi1_epilogue"
1126 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1127 (mem:SI (reg:SI 7)))
1129 (plus:SI (reg:SI 7) (const_int 4)))
1130 (clobber (mem:BLK (scratch)))]
1133 [(set_attr "type" "pop")
1134 (set_attr "mode" "SI")])
1136 (define_insn "popsi1"
1137 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1138 (mem:SI (reg:SI 7)))
1140 (plus:SI (reg:SI 7) (const_int 4)))]
1143 [(set_attr "type" "pop")
1144 (set_attr "mode" "SI")])
1146 (define_insn "*movsi_xor"
1147 [(set (match_operand:SI 0 "register_operand" "=r")
1148 (match_operand:SI 1 "const0_operand" "i"))
1149 (clobber (reg:CC 17))]
1150 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1151 "xor{l}\t{%0, %0|%0, %0}"
1152 [(set_attr "type" "alu1")
1153 (set_attr "mode" "SI")
1154 (set_attr "length_immediate" "0")])
1156 (define_insn "*movsi_or"
1157 [(set (match_operand:SI 0 "register_operand" "=r")
1158 (match_operand:SI 1 "immediate_operand" "i"))
1159 (clobber (reg:CC 17))]
1160 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1161 && INTVAL (operands[1]) == -1
1162 && (TARGET_PENTIUM || optimize_size)"
1164 operands[1] = constm1_rtx;
1165 return "or{l}\t{%1, %0|%0, %1}";
1167 [(set_attr "type" "alu1")
1168 (set_attr "mode" "SI")
1169 (set_attr "length_immediate" "1")])
1171 (define_insn "*movsi_1"
1172 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1173 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1174 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1175 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1177 switch (get_attr_type (insn))
1180 if (get_attr_mode (insn) == MODE_TI)
1181 return "movdqa\t{%1, %0|%0, %1}";
1182 return "movd\t{%1, %0|%0, %1}";
1185 if (get_attr_mode (insn) == MODE_DI)
1186 return "movq\t{%1, %0|%0, %1}";
1187 return "movd\t{%1, %0|%0, %1}";
1190 return "lea{l}\t{%1, %0|%0, %1}";
1193 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1195 return "mov{l}\t{%1, %0|%0, %1}";
1199 (cond [(eq_attr "alternative" "2,3,4")
1200 (const_string "mmxmov")
1201 (eq_attr "alternative" "5,6,7")
1202 (const_string "ssemov")
1203 (and (ne (symbol_ref "flag_pic") (const_int 0))
1204 (match_operand:SI 1 "symbolic_operand" ""))
1205 (const_string "lea")
1207 (const_string "imov")))
1208 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1210 (define_insn "*movsi_1_nointernunit"
1211 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1212 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1213 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1214 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1216 switch (get_attr_type (insn))
1219 if (get_attr_mode (insn) == MODE_TI)
1220 return "movdqa\t{%1, %0|%0, %1}";
1221 return "movd\t{%1, %0|%0, %1}";
1224 if (get_attr_mode (insn) == MODE_DI)
1225 return "movq\t{%1, %0|%0, %1}";
1226 return "movd\t{%1, %0|%0, %1}";
1229 return "lea{l}\t{%1, %0|%0, %1}";
1232 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1234 return "mov{l}\t{%1, %0|%0, %1}";
1238 (cond [(eq_attr "alternative" "2,3,4")
1239 (const_string "mmxmov")
1240 (eq_attr "alternative" "5,6,7")
1241 (const_string "ssemov")
1242 (and (ne (symbol_ref "flag_pic") (const_int 0))
1243 (match_operand:SI 1 "symbolic_operand" ""))
1244 (const_string "lea")
1246 (const_string "imov")))
1247 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1249 ;; Stores and loads of ax to arbitrary constant address.
1250 ;; We fake an second form of instruction to force reload to load address
1251 ;; into register when rax is not available
1252 (define_insn "*movabssi_1_rex64"
1253 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1254 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1257 movabs{l}\t{%1, %P0|%P0, %1}
1258 mov{l}\t{%1, %a0|%a0, %1}
1259 movabs{l}\t{%1, %a0|%a0, %1}"
1260 [(set_attr "type" "imov")
1261 (set_attr "modrm" "0,*,*")
1262 (set_attr "length_address" "8,0,0")
1263 (set_attr "length_immediate" "0,*,*")
1264 (set_attr "memory" "store")
1265 (set_attr "mode" "SI")])
1267 (define_insn "*movabssi_2_rex64"
1268 [(set (match_operand:SI 0 "register_operand" "=a,r")
1269 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1272 movabs{l}\t{%P1, %0|%0, %P1}
1273 mov{l}\t{%a1, %0|%0, %a1}"
1274 [(set_attr "type" "imov")
1275 (set_attr "modrm" "0,*")
1276 (set_attr "length_address" "8,0")
1277 (set_attr "length_immediate" "0")
1278 (set_attr "memory" "load")
1279 (set_attr "mode" "SI")])
1281 (define_insn "*swapsi"
1282 [(set (match_operand:SI 0 "register_operand" "+r")
1283 (match_operand:SI 1 "register_operand" "+r"))
1288 [(set_attr "type" "imov")
1289 (set_attr "pent_pair" "np")
1290 (set_attr "athlon_decode" "vector")
1291 (set_attr "mode" "SI")
1292 (set_attr "modrm" "0")
1293 (set_attr "ppro_uops" "few")])
1295 (define_expand "movhi"
1296 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1297 (match_operand:HI 1 "general_operand" ""))]
1299 "ix86_expand_move (HImode, operands); DONE;")
1301 (define_insn "*pushhi2"
1302 [(set (match_operand:HI 0 "push_operand" "=<,<")
1303 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1306 push{w}\t{|WORD PTR }%1
1308 [(set_attr "type" "push")
1309 (set_attr "mode" "HI")])
1311 ;; For 64BIT abi we always round up to 8 bytes.
1312 (define_insn "*pushhi2_rex64"
1313 [(set (match_operand:HI 0 "push_operand" "=X")
1314 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1317 [(set_attr "type" "push")
1318 (set_attr "mode" "QI")])
1320 (define_insn "*movhi_1"
1321 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1322 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1323 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1325 switch (get_attr_type (insn))
1328 /* movzwl is faster than movw on p2 due to partial word stalls,
1329 though not as fast as an aligned movl. */
1330 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1332 if (get_attr_mode (insn) == MODE_SI)
1333 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1335 return "mov{w}\t{%1, %0|%0, %1}";
1339 (cond [(and (eq_attr "alternative" "0")
1340 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1342 (eq (symbol_ref "TARGET_HIMODE_MATH")
1344 (const_string "imov")
1345 (and (eq_attr "alternative" "1,2")
1346 (match_operand:HI 1 "aligned_operand" ""))
1347 (const_string "imov")
1348 (and (ne (symbol_ref "TARGET_MOVX")
1350 (eq_attr "alternative" "0,2"))
1351 (const_string "imovx")
1353 (const_string "imov")))
1355 (cond [(eq_attr "type" "imovx")
1357 (and (eq_attr "alternative" "1,2")
1358 (match_operand:HI 1 "aligned_operand" ""))
1360 (and (eq_attr "alternative" "0")
1361 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1363 (eq (symbol_ref "TARGET_HIMODE_MATH")
1367 (const_string "HI")))])
1369 ;; Stores and loads of ax to arbitrary constant address.
1370 ;; We fake an second form of instruction to force reload to load address
1371 ;; into register when rax is not available
1372 (define_insn "*movabshi_1_rex64"
1373 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1374 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1377 movabs{w}\t{%1, %P0|%P0, %1}
1378 mov{w}\t{%1, %a0|%a0, %1}
1379 movabs{w}\t{%1, %a0|%a0, %1}"
1380 [(set_attr "type" "imov")
1381 (set_attr "modrm" "0,*,*")
1382 (set_attr "length_address" "8,0,0")
1383 (set_attr "length_immediate" "0,*,*")
1384 (set_attr "memory" "store")
1385 (set_attr "mode" "HI")])
1387 (define_insn "*movabshi_2_rex64"
1388 [(set (match_operand:HI 0 "register_operand" "=a,r")
1389 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1392 movabs{w}\t{%P1, %0|%0, %P1}
1393 mov{w}\t{%a1, %0|%0, %a1}"
1394 [(set_attr "type" "imov")
1395 (set_attr "modrm" "0,*")
1396 (set_attr "length_address" "8,0")
1397 (set_attr "length_immediate" "0")
1398 (set_attr "memory" "load")
1399 (set_attr "mode" "HI")])
1401 (define_insn "*swaphi_1"
1402 [(set (match_operand:HI 0 "register_operand" "+r")
1403 (match_operand:HI 1 "register_operand" "+r"))
1406 "TARGET_PARTIAL_REG_STALL"
1408 [(set_attr "type" "imov")
1409 (set_attr "pent_pair" "np")
1410 (set_attr "mode" "HI")
1411 (set_attr "modrm" "0")
1412 (set_attr "ppro_uops" "few")])
1414 (define_insn "*swaphi_2"
1415 [(set (match_operand:HI 0 "register_operand" "+r")
1416 (match_operand:HI 1 "register_operand" "+r"))
1419 "! TARGET_PARTIAL_REG_STALL"
1421 [(set_attr "type" "imov")
1422 (set_attr "pent_pair" "np")
1423 (set_attr "mode" "SI")
1424 (set_attr "modrm" "0")
1425 (set_attr "ppro_uops" "few")])
1427 (define_expand "movstricthi"
1428 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1429 (match_operand:HI 1 "general_operand" ""))]
1430 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1432 /* Don't generate memory->memory moves, go through a register */
1433 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1434 operands[1] = force_reg (HImode, operands[1]);
1437 (define_insn "*movstricthi_1"
1438 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1439 (match_operand:HI 1 "general_operand" "rn,m"))]
1440 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1441 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1442 "mov{w}\t{%1, %0|%0, %1}"
1443 [(set_attr "type" "imov")
1444 (set_attr "mode" "HI")])
1446 (define_insn "*movstricthi_xor"
1447 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1448 (match_operand:HI 1 "const0_operand" "i"))
1449 (clobber (reg:CC 17))]
1451 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1452 "xor{w}\t{%0, %0|%0, %0}"
1453 [(set_attr "type" "alu1")
1454 (set_attr "mode" "HI")
1455 (set_attr "length_immediate" "0")])
1457 (define_expand "movqi"
1458 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1459 (match_operand:QI 1 "general_operand" ""))]
1461 "ix86_expand_move (QImode, operands); DONE;")
1463 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1464 ;; "push a byte". But actually we use pushw, which has the effect
1465 ;; of rounding the amount pushed up to a halfword.
1467 (define_insn "*pushqi2"
1468 [(set (match_operand:QI 0 "push_operand" "=X,X")
1469 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1472 push{w}\t{|word ptr }%1
1474 [(set_attr "type" "push")
1475 (set_attr "mode" "HI")])
1477 ;; For 64BIT abi we always round up to 8 bytes.
1478 (define_insn "*pushqi2_rex64"
1479 [(set (match_operand:QI 0 "push_operand" "=X")
1480 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1483 [(set_attr "type" "push")
1484 (set_attr "mode" "QI")])
1486 ;; Situation is quite tricky about when to choose full sized (SImode) move
1487 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1488 ;; partial register dependency machines (such as AMD Athlon), where QImode
1489 ;; moves issue extra dependency and for partial register stalls machines
1490 ;; that don't use QImode patterns (and QImode move cause stall on the next
1493 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1494 ;; register stall machines with, where we use QImode instructions, since
1495 ;; partial register stall can be caused there. Then we use movzx.
1496 (define_insn "*movqi_1"
1497 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1498 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1499 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1501 switch (get_attr_type (insn))
1504 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1506 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1508 if (get_attr_mode (insn) == MODE_SI)
1509 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1511 return "mov{b}\t{%1, %0|%0, %1}";
1515 (cond [(and (eq_attr "alternative" "3")
1516 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1518 (eq (symbol_ref "TARGET_QIMODE_MATH")
1520 (const_string "imov")
1521 (eq_attr "alternative" "3,5")
1522 (const_string "imovx")
1523 (and (ne (symbol_ref "TARGET_MOVX")
1525 (eq_attr "alternative" "2"))
1526 (const_string "imovx")
1528 (const_string "imov")))
1530 (cond [(eq_attr "alternative" "3,4,5")
1532 (eq_attr "alternative" "6")
1534 (eq_attr "type" "imovx")
1536 (and (eq_attr "type" "imov")
1537 (and (eq_attr "alternative" "0,1,2")
1538 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1541 ;; Avoid partial register stalls when not using QImode arithmetic
1542 (and (eq_attr "type" "imov")
1543 (and (eq_attr "alternative" "0,1,2")
1544 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1546 (eq (symbol_ref "TARGET_QIMODE_MATH")
1550 (const_string "QI")))])
1552 (define_expand "reload_outqi"
1553 [(parallel [(match_operand:QI 0 "" "=m")
1554 (match_operand:QI 1 "register_operand" "r")
1555 (match_operand:QI 2 "register_operand" "=&q")])]
1559 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1561 if (reg_overlap_mentioned_p (op2, op0))
1563 if (! q_regs_operand (op1, QImode))
1565 emit_insn (gen_movqi (op2, op1));
1568 emit_insn (gen_movqi (op0, op1));
1572 (define_insn "*swapqi"
1573 [(set (match_operand:QI 0 "register_operand" "+r")
1574 (match_operand:QI 1 "register_operand" "+r"))
1579 [(set_attr "type" "imov")
1580 (set_attr "pent_pair" "np")
1581 (set_attr "mode" "QI")
1582 (set_attr "modrm" "0")
1583 (set_attr "ppro_uops" "few")])
1585 (define_expand "movstrictqi"
1586 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1587 (match_operand:QI 1 "general_operand" ""))]
1588 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1590 /* Don't generate memory->memory moves, go through a register. */
1591 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1592 operands[1] = force_reg (QImode, operands[1]);
1595 (define_insn "*movstrictqi_1"
1596 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1597 (match_operand:QI 1 "general_operand" "*qn,m"))]
1598 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1599 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1600 "mov{b}\t{%1, %0|%0, %1}"
1601 [(set_attr "type" "imov")
1602 (set_attr "mode" "QI")])
1604 (define_insn "*movstrictqi_xor"
1605 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1606 (match_operand:QI 1 "const0_operand" "i"))
1607 (clobber (reg:CC 17))]
1608 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1609 "xor{b}\t{%0, %0|%0, %0}"
1610 [(set_attr "type" "alu1")
1611 (set_attr "mode" "QI")
1612 (set_attr "length_immediate" "0")])
1614 (define_insn "*movsi_extv_1"
1615 [(set (match_operand:SI 0 "register_operand" "=R")
1616 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1620 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1621 [(set_attr "type" "imovx")
1622 (set_attr "mode" "SI")])
1624 (define_insn "*movhi_extv_1"
1625 [(set (match_operand:HI 0 "register_operand" "=R")
1626 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1630 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1631 [(set_attr "type" "imovx")
1632 (set_attr "mode" "SI")])
1634 (define_insn "*movqi_extv_1"
1635 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1636 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1641 switch (get_attr_type (insn))
1644 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1646 return "mov{b}\t{%h1, %0|%0, %h1}";
1650 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1651 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1652 (ne (symbol_ref "TARGET_MOVX")
1654 (const_string "imovx")
1655 (const_string "imov")))
1657 (if_then_else (eq_attr "type" "imovx")
1659 (const_string "QI")))])
1661 (define_insn "*movqi_extv_1_rex64"
1662 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1663 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1668 switch (get_attr_type (insn))
1671 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1673 return "mov{b}\t{%h1, %0|%0, %h1}";
1677 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1678 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1679 (ne (symbol_ref "TARGET_MOVX")
1681 (const_string "imovx")
1682 (const_string "imov")))
1684 (if_then_else (eq_attr "type" "imovx")
1686 (const_string "QI")))])
1688 ;; Stores and loads of ax to arbitrary constant address.
1689 ;; We fake an second form of instruction to force reload to load address
1690 ;; into register when rax is not available
1691 (define_insn "*movabsqi_1_rex64"
1692 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1693 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
1696 movabs{b}\t{%1, %P0|%P0, %1}
1697 mov{b}\t{%1, %a0|%a0, %1}
1698 movabs{b}\t{%1, %a0|%a0, %1}"
1699 [(set_attr "type" "imov")
1700 (set_attr "modrm" "0,*,*")
1701 (set_attr "length_address" "8,0,0")
1702 (set_attr "length_immediate" "0,*,*")
1703 (set_attr "memory" "store")
1704 (set_attr "mode" "QI")])
1706 (define_insn "*movabsqi_2_rex64"
1707 [(set (match_operand:QI 0 "register_operand" "=a,r")
1708 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1711 movabs{b}\t{%P1, %0|%0, %P1}
1712 mov{b}\t{%a1, %0|%0, %a1}"
1713 [(set_attr "type" "imov")
1714 (set_attr "modrm" "0,*")
1715 (set_attr "length_address" "8,0")
1716 (set_attr "length_immediate" "0")
1717 (set_attr "memory" "load")
1718 (set_attr "mode" "QI")])
1720 (define_insn "*movsi_extzv_1"
1721 [(set (match_operand:SI 0 "register_operand" "=R")
1722 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1726 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1727 [(set_attr "type" "imovx")
1728 (set_attr "mode" "SI")])
1730 (define_insn "*movqi_extzv_2"
1731 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1732 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1737 switch (get_attr_type (insn))
1740 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1742 return "mov{b}\t{%h1, %0|%0, %h1}";
1746 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1747 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1748 (ne (symbol_ref "TARGET_MOVX")
1750 (const_string "imovx")
1751 (const_string "imov")))
1753 (if_then_else (eq_attr "type" "imovx")
1755 (const_string "QI")))])
1757 (define_insn "*movqi_extzv_2_rex64"
1758 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1759 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1764 switch (get_attr_type (insn))
1767 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1769 return "mov{b}\t{%h1, %0|%0, %h1}";
1773 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774 (ne (symbol_ref "TARGET_MOVX")
1776 (const_string "imovx")
1777 (const_string "imov")))
1779 (if_then_else (eq_attr "type" "imovx")
1781 (const_string "QI")))])
1783 (define_insn "movsi_insv_1"
1784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1787 (match_operand:SI 1 "general_operand" "Qmn"))]
1789 "mov{b}\t{%b1, %h0|%h0, %b1}"
1790 [(set_attr "type" "imov")
1791 (set_attr "mode" "QI")])
1793 (define_insn "*movsi_insv_1_rex64"
1794 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1797 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1799 "mov{b}\t{%b1, %h0|%h0, %b1}"
1800 [(set_attr "type" "imov")
1801 (set_attr "mode" "QI")])
1803 (define_insn "*movqi_insv_2"
1804 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1807 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1811 "mov{b}\t{%h1, %h0|%h0, %h1}"
1812 [(set_attr "type" "imov")
1813 (set_attr "mode" "QI")])
1815 (define_expand "movdi"
1816 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1817 (match_operand:DI 1 "general_operand" ""))]
1819 "ix86_expand_move (DImode, operands); DONE;")
1821 (define_insn "*pushdi"
1822 [(set (match_operand:DI 0 "push_operand" "=<")
1823 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1827 (define_insn "pushdi2_rex64"
1828 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1829 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1834 [(set_attr "type" "push,multi")
1835 (set_attr "mode" "DI")])
1837 ;; Convert impossible pushes of immediate to existing instructions.
1838 ;; First try to get scratch register and go through it. In case this
1839 ;; fails, push sign extended lower part first and then overwrite
1840 ;; upper part by 32bit move.
1842 [(match_scratch:DI 2 "r")
1843 (set (match_operand:DI 0 "push_operand" "")
1844 (match_operand:DI 1 "immediate_operand" ""))]
1845 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1846 && !x86_64_immediate_operand (operands[1], DImode)"
1847 [(set (match_dup 2) (match_dup 1))
1848 (set (match_dup 0) (match_dup 2))]
1851 ;; We need to define this as both peepholer and splitter for case
1852 ;; peephole2 pass is not run.
1854 [(set (match_operand:DI 0 "push_operand" "")
1855 (match_operand:DI 1 "immediate_operand" ""))]
1856 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1857 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1858 [(set (match_dup 0) (match_dup 1))
1859 (set (match_dup 2) (match_dup 3))]
1860 "split_di (operands + 1, 1, operands + 2, operands + 3);
1861 operands[1] = gen_lowpart (DImode, operands[2]);
1862 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1867 [(set (match_operand:DI 0 "push_operand" "")
1868 (match_operand:DI 1 "immediate_operand" ""))]
1869 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
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 7)))
1893 (plus:DI (reg:DI 7) (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 7)))
1904 (plus:DI (reg:DI 7) (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 17))]
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 17))]
1925 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1927 && GET_CODE (operands[1]) == CONST_INT
1928 && INTVAL (operands[1]) == -1"
1930 operands[1] = constm1_rtx;
1931 return "or{q}\t{%1, %0|%0, %1}";
1933 [(set_attr "type" "alu1")
1934 (set_attr "mode" "DI")
1935 (set_attr "length_immediate" "1")])
1937 (define_insn "*movdi_2"
1938 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1939 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1941 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1945 movq\t{%1, %0|%0, %1}
1946 movq\t{%1, %0|%0, %1}
1947 movq\t{%1, %0|%0, %1}
1948 movdqa\t{%1, %0|%0, %1}
1949 movq\t{%1, %0|%0, %1}"
1950 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1951 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1954 [(set (match_operand:DI 0 "push_operand" "")
1955 (match_operand:DI 1 "general_operand" ""))]
1956 "!TARGET_64BIT && reload_completed
1957 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1959 "ix86_split_long_move (operands); DONE;")
1961 ;; %%% This multiword shite has got to go.
1963 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1964 (match_operand:DI 1 "general_operand" ""))]
1965 "!TARGET_64BIT && reload_completed
1966 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1967 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1969 "ix86_split_long_move (operands); DONE;")
1971 (define_insn "*movdi_1_rex64"
1972 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1973 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1975 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1976 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1978 switch (get_attr_type (insn))
1981 if (get_attr_mode (insn) == MODE_TI)
1982 return "movdqa\t{%1, %0|%0, %1}";
1985 /* Moves from and into integer register is done using movd opcode with
1987 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1988 return "movd\t{%1, %0|%0, %1}";
1989 return "movq\t{%1, %0|%0, %1}";
1993 return "lea{q}\t{%a1, %0|%0, %a1}";
1995 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1997 if (get_attr_mode (insn) == MODE_SI)
1998 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1999 else if (which_alternative == 2)
2000 return "movabs{q}\t{%1, %0|%0, %1}";
2002 return "mov{q}\t{%1, %0|%0, %1}";
2006 (cond [(eq_attr "alternative" "5,6,7")
2007 (const_string "mmxmov")
2008 (eq_attr "alternative" "8,9,10")
2009 (const_string "ssemov")
2010 (eq_attr "alternative" "4")
2011 (const_string "multi")
2012 (and (ne (symbol_ref "flag_pic") (const_int 0))
2013 (match_operand:DI 1 "symbolic_operand" ""))
2014 (const_string "lea")
2016 (const_string "imov")))
2017 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2018 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2019 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2021 (define_insn "*movdi_1_rex64_nointerunit"
2022 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2023 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2025 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2026 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2028 switch (get_attr_type (insn))
2031 if (get_attr_mode (insn) == MODE_TI)
2032 return "movdqa\t{%1, %0|%0, %1}";
2035 return "movq\t{%1, %0|%0, %1}";
2039 return "lea{q}\t{%a1, %0|%0, %a1}";
2041 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2043 if (get_attr_mode (insn) == MODE_SI)
2044 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2045 else if (which_alternative == 2)
2046 return "movabs{q}\t{%1, %0|%0, %1}";
2048 return "mov{q}\t{%1, %0|%0, %1}";
2052 (cond [(eq_attr "alternative" "5,6,7")
2053 (const_string "mmxmov")
2054 (eq_attr "alternative" "8,9,10")
2055 (const_string "ssemov")
2056 (eq_attr "alternative" "4")
2057 (const_string "multi")
2058 (and (ne (symbol_ref "flag_pic") (const_int 0))
2059 (match_operand:DI 1 "symbolic_operand" ""))
2060 (const_string "lea")
2062 (const_string "imov")))
2063 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2064 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2065 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2067 ;; Stores and loads of ax to arbitrary constant address.
2068 ;; We fake an second form of instruction to force reload to load address
2069 ;; into register when rax is not available
2070 (define_insn "*movabsdi_1_rex64"
2071 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2072 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2075 movabs{q}\t{%1, %P0|%P0, %1}
2076 mov{q}\t{%1, %a0|%a0, %1}
2077 movabs{q}\t{%1, %a0|%a0, %1}"
2078 [(set_attr "type" "imov")
2079 (set_attr "modrm" "0,*,*")
2080 (set_attr "length_address" "8,0,0")
2081 (set_attr "length_immediate" "0,*,*")
2082 (set_attr "memory" "store")
2083 (set_attr "mode" "DI")])
2085 (define_insn "*movabsdi_2_rex64"
2086 [(set (match_operand:DI 0 "register_operand" "=a,r")
2087 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2090 movabs{q}\t{%P1, %0|%0, %P1}
2091 mov{q}\t{%a1, %0|%0, %a1}"
2092 [(set_attr "type" "imov")
2093 (set_attr "modrm" "0,*")
2094 (set_attr "length_address" "8,0")
2095 (set_attr "length_immediate" "0")
2096 (set_attr "memory" "load")
2097 (set_attr "mode" "DI")])
2099 ;; Convert impossible stores of immediate to existing instructions.
2100 ;; First try to get scratch register and go through it. In case this
2101 ;; fails, move by 32bit parts.
2103 [(match_scratch:DI 2 "r")
2104 (set (match_operand:DI 0 "memory_operand" "")
2105 (match_operand:DI 1 "immediate_operand" ""))]
2106 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2107 && !x86_64_immediate_operand (operands[1], DImode)"
2108 [(set (match_dup 2) (match_dup 1))
2109 (set (match_dup 0) (match_dup 2))]
2112 ;; We need to define this as both peepholer and splitter for case
2113 ;; peephole2 pass is not run.
2115 [(set (match_operand:DI 0 "memory_operand" "")
2116 (match_operand:DI 1 "immediate_operand" ""))]
2117 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2118 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2119 [(set (match_dup 2) (match_dup 3))
2120 (set (match_dup 4) (match_dup 5))]
2121 "split_di (operands, 2, operands + 2, operands + 4);")
2124 [(set (match_operand:DI 0 "memory_operand" "")
2125 (match_operand:DI 1 "immediate_operand" ""))]
2126 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2127 && !symbolic_operand (operands[1], DImode)
2128 && !x86_64_immediate_operand (operands[1], DImode)"
2129 [(set (match_dup 2) (match_dup 3))
2130 (set (match_dup 4) (match_dup 5))]
2131 "split_di (operands, 2, operands + 2, operands + 4);")
2133 (define_insn "*swapdi_rex64"
2134 [(set (match_operand:DI 0 "register_operand" "+r")
2135 (match_operand:DI 1 "register_operand" "+r"))
2140 [(set_attr "type" "imov")
2141 (set_attr "pent_pair" "np")
2142 (set_attr "athlon_decode" "vector")
2143 (set_attr "mode" "DI")
2144 (set_attr "modrm" "0")
2145 (set_attr "ppro_uops" "few")])
2148 (define_expand "movsf"
2149 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2150 (match_operand:SF 1 "general_operand" ""))]
2152 "ix86_expand_move (SFmode, operands); DONE;")
2154 (define_insn "*pushsf"
2155 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2156 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2159 switch (which_alternative)
2162 return "push{l}\t%1";
2165 /* This insn should be already splitted before reg-stack. */
2169 [(set_attr "type" "multi,push,multi")
2170 (set_attr "mode" "SF,SI,SF")])
2172 (define_insn "*pushsf_rex64"
2173 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2174 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2177 switch (which_alternative)
2180 return "push{q}\t%q1";
2183 /* This insn should be already splitted before reg-stack. */
2187 [(set_attr "type" "multi,push,multi")
2188 (set_attr "mode" "SF,DI,SF")])
2191 [(set (match_operand:SF 0 "push_operand" "")
2192 (match_operand:SF 1 "memory_operand" ""))]
2194 && GET_CODE (operands[1]) == MEM
2195 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2196 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2199 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2202 ;; %%% Kill this when call knows how to work this out.
2204 [(set (match_operand:SF 0 "push_operand" "")
2205 (match_operand:SF 1 "any_fp_register_operand" ""))]
2207 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2208 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2211 [(set (match_operand:SF 0 "push_operand" "")
2212 (match_operand:SF 1 "any_fp_register_operand" ""))]
2214 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2215 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2217 (define_insn "*movsf_1"
2218 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2219 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2220 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2221 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2222 && (reload_in_progress || reload_completed
2223 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2224 || GET_CODE (operands[1]) != CONST_DOUBLE
2225 || memory_operand (operands[0], SFmode))"
2227 switch (which_alternative)
2230 if (REG_P (operands[1])
2231 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2233 else if (STACK_TOP_P (operands[0]))
2234 return "fld%z1\t%y1";
2239 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2240 return "fstp%z0\t%y0";
2242 return "fst%z0\t%y0";
2245 return standard_80387_constant_opcode (operands[1]);
2249 return "mov{l}\t{%1, %0|%0, %1}";
2251 if (get_attr_mode (insn) == MODE_TI)
2252 return "pxor\t%0, %0";
2254 return "xorps\t%0, %0";
2256 if (get_attr_mode (insn) == MODE_V4SF)
2257 return "movaps\t{%1, %0|%0, %1}";
2259 return "movss\t{%1, %0|%0, %1}";
2262 return "movss\t{%1, %0|%0, %1}";
2266 return "movd\t{%1, %0|%0, %1}";
2269 return "movq\t{%1, %0|%0, %1}";
2275 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2277 (cond [(eq_attr "alternative" "3,4,9,10")
2279 (eq_attr "alternative" "5")
2281 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2283 (ne (symbol_ref "TARGET_SSE2")
2285 (eq (symbol_ref "optimize_size")
2288 (const_string "V4SF"))
2289 /* For architectures resolving dependencies on
2290 whole SSE registers use APS move to break dependency
2291 chains, otherwise use short move to avoid extra work.
2293 Do the same for architectures resolving dependencies on
2294 the parts. While in DF mode it is better to always handle
2295 just register parts, the SF mode is different due to lack
2296 of instructions to load just part of the register. It is
2297 better to maintain the whole registers in single format
2298 to avoid problems on using packed logical operations. */
2299 (eq_attr "alternative" "6")
2301 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2303 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2305 (const_string "V4SF")
2306 (const_string "SF"))
2307 (eq_attr "alternative" "11")
2308 (const_string "DI")]
2309 (const_string "SF")))])
2311 (define_insn "*movsf_1_nointerunit"
2312 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2313 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2314 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2315 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2316 && (reload_in_progress || reload_completed
2317 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2318 || GET_CODE (operands[1]) != CONST_DOUBLE
2319 || memory_operand (operands[0], SFmode))"
2321 switch (which_alternative)
2324 if (REG_P (operands[1])
2325 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2327 if (REGNO (operands[0]) == FIRST_STACK_REG
2328 && TARGET_USE_FFREEP)
2329 return "ffreep\t%y0";
2332 else if (STACK_TOP_P (operands[0]))
2333 return "fld%z1\t%y1";
2338 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2339 return "fstp%z0\t%y0";
2341 return "fst%z0\t%y0";
2344 return standard_80387_constant_opcode (operands[1]);
2348 return "mov{l}\t{%1, %0|%0, %1}";
2350 if (get_attr_mode (insn) == MODE_TI)
2351 return "pxor\t%0, %0";
2353 return "xorps\t%0, %0";
2355 if (get_attr_mode (insn) == MODE_V4SF)
2356 return "movaps\t{%1, %0|%0, %1}";
2358 return "movss\t{%1, %0|%0, %1}";
2361 return "movss\t{%1, %0|%0, %1}";
2365 return "movd\t{%1, %0|%0, %1}";
2368 return "movq\t{%1, %0|%0, %1}";
2374 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2376 (cond [(eq_attr "alternative" "3,4,9,10")
2378 (eq_attr "alternative" "5")
2380 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2382 (ne (symbol_ref "TARGET_SSE2")
2384 (eq (symbol_ref "optimize_size")
2387 (const_string "V4SF"))
2388 /* For architectures resolving dependencies on
2389 whole SSE registers use APS move to break dependency
2390 chains, otherwise use short move to avoid extra work.
2392 Do the same for architectures resolving dependencies on
2393 the parts. While in DF mode it is better to always handle
2394 just register parts, the SF mode is different due to lack
2395 of instructions to load just part of the register. It is
2396 better to maintain the whole registers in single format
2397 to avoid problems on using packed logical operations. */
2398 (eq_attr "alternative" "6")
2400 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2402 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2404 (const_string "V4SF")
2405 (const_string "SF"))
2406 (eq_attr "alternative" "11")
2407 (const_string "DI")]
2408 (const_string "SF")))])
2410 (define_insn "*swapsf"
2411 [(set (match_operand:SF 0 "register_operand" "+f")
2412 (match_operand:SF 1 "register_operand" "+f"))
2415 "reload_completed || !TARGET_SSE"
2417 if (STACK_TOP_P (operands[0]))
2422 [(set_attr "type" "fxch")
2423 (set_attr "mode" "SF")])
2425 (define_expand "movdf"
2426 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2427 (match_operand:DF 1 "general_operand" ""))]
2429 "ix86_expand_move (DFmode, operands); DONE;")
2431 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2432 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2433 ;; On the average, pushdf using integers can be still shorter. Allow this
2434 ;; pattern for optimize_size too.
2436 (define_insn "*pushdf_nointeger"
2437 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2438 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2439 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2441 /* This insn should be already splitted before reg-stack. */
2444 [(set_attr "type" "multi")
2445 (set_attr "mode" "DF,SI,SI,DF")])
2447 (define_insn "*pushdf_integer"
2448 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2449 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2450 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2452 /* This insn should be already splitted before reg-stack. */
2455 [(set_attr "type" "multi")
2456 (set_attr "mode" "DF,SI,DF")])
2458 ;; %%% Kill this when call knows how to work this out.
2460 [(set (match_operand:DF 0 "push_operand" "")
2461 (match_operand:DF 1 "any_fp_register_operand" ""))]
2462 "!TARGET_64BIT && reload_completed"
2463 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2464 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2468 [(set (match_operand:DF 0 "push_operand" "")
2469 (match_operand:DF 1 "any_fp_register_operand" ""))]
2470 "TARGET_64BIT && reload_completed"
2471 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2472 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2476 [(set (match_operand:DF 0 "push_operand" "")
2477 (match_operand:DF 1 "general_operand" ""))]
2480 "ix86_split_long_move (operands); DONE;")
2482 ;; Moving is usually shorter when only FP registers are used. This separate
2483 ;; movdf pattern avoids the use of integer registers for FP operations
2484 ;; when optimizing for size.
2486 (define_insn "*movdf_nointeger"
2487 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2488 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2489 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2490 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2491 && (reload_in_progress || reload_completed
2492 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2493 || GET_CODE (operands[1]) != CONST_DOUBLE
2494 || memory_operand (operands[0], DFmode))"
2496 switch (which_alternative)
2499 if (REG_P (operands[1])
2500 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2502 if (REGNO (operands[0]) == FIRST_STACK_REG
2503 && TARGET_USE_FFREEP)
2504 return "ffreep\t%y0";
2507 else if (STACK_TOP_P (operands[0]))
2508 return "fld%z1\t%y1";
2513 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2514 return "fstp%z0\t%y0";
2516 return "fst%z0\t%y0";
2519 return standard_80387_constant_opcode (operands[1]);
2525 switch (get_attr_mode (insn))
2528 return "xorps\t%0, %0";
2530 return "xorpd\t%0, %0";
2532 return "pxor\t%0, %0";
2537 switch (get_attr_mode (insn))
2540 return "movaps\t{%1, %0|%0, %1}";
2542 return "movapd\t{%1, %0|%0, %1}";
2544 return "movsd\t{%1, %0|%0, %1}";
2549 if (get_attr_mode (insn) == MODE_V2DF)
2550 return "movlpd\t{%1, %0|%0, %1}";
2552 return "movsd\t{%1, %0|%0, %1}";
2554 return "movsd\t{%1, %0|%0, %1}";
2560 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2562 (cond [(eq_attr "alternative" "3,4")
2564 /* xorps is one byte shorter. */
2565 (eq_attr "alternative" "5")
2566 (cond [(ne (symbol_ref "optimize_size")
2568 (const_string "V4SF")
2569 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2571 (const_string "TI")]
2572 (const_string "V2DF"))
2573 /* For architectures resolving dependencies on
2574 whole SSE registers use APD move to break dependency
2575 chains, otherwise use short move to avoid extra work.
2577 movaps encodes one byte shorter. */
2578 (eq_attr "alternative" "6")
2580 [(ne (symbol_ref "optimize_size")
2582 (const_string "V4SF")
2583 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2585 (const_string "V2DF")]
2586 (const_string "DF"))
2587 /* For architectures resolving dependencies on register
2588 parts we may avoid extra work to zero out upper part
2590 (eq_attr "alternative" "7")
2592 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2594 (const_string "V2DF")
2595 (const_string "DF"))]
2596 (const_string "DF")))])
2598 (define_insn "*movdf_integer"
2599 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2600 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2601 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2602 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2603 && (reload_in_progress || reload_completed
2604 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2605 || GET_CODE (operands[1]) != CONST_DOUBLE
2606 || memory_operand (operands[0], DFmode))"
2608 switch (which_alternative)
2611 if (REG_P (operands[1])
2612 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2614 if (REGNO (operands[0]) == FIRST_STACK_REG
2615 && TARGET_USE_FFREEP)
2616 return "ffreep\t%y0";
2619 else if (STACK_TOP_P (operands[0]))
2620 return "fld%z1\t%y1";
2625 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2626 return "fstp%z0\t%y0";
2628 return "fst%z0\t%y0";
2631 return standard_80387_constant_opcode (operands[1]);
2638 switch (get_attr_mode (insn))
2641 return "xorps\t%0, %0";
2643 return "xorpd\t%0, %0";
2645 return "pxor\t%0, %0";
2650 switch (get_attr_mode (insn))
2653 return "movaps\t{%1, %0|%0, %1}";
2655 return "movapd\t{%1, %0|%0, %1}";
2657 return "movsd\t{%1, %0|%0, %1}";
2662 if (get_attr_mode (insn) == MODE_V2DF)
2663 return "movlpd\t{%1, %0|%0, %1}";
2665 return "movsd\t{%1, %0|%0, %1}";
2667 return "movsd\t{%1, %0|%0, %1}";
2673 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2675 (cond [(eq_attr "alternative" "3,4")
2677 /* xorps is one byte shorter. */
2678 (eq_attr "alternative" "5")
2679 (cond [(ne (symbol_ref "optimize_size")
2681 (const_string "V4SF")
2682 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2684 (const_string "TI")]
2685 (const_string "V2DF"))
2686 /* For architectures resolving dependencies on
2687 whole SSE registers use APD move to break dependency
2688 chains, otherwise use short move to avoid extra work.
2690 movaps encodes one byte shorter. */
2691 (eq_attr "alternative" "6")
2693 [(ne (symbol_ref "optimize_size")
2695 (const_string "V4SF")
2696 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2698 (const_string "V2DF")]
2699 (const_string "DF"))
2700 /* For architectures resolving dependencies on register
2701 parts we may avoid extra work to zero out upper part
2703 (eq_attr "alternative" "7")
2705 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2707 (const_string "V2DF")
2708 (const_string "DF"))]
2709 (const_string "DF")))])
2712 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2713 (match_operand:DF 1 "general_operand" ""))]
2715 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2716 && ! (ANY_FP_REG_P (operands[0]) ||
2717 (GET_CODE (operands[0]) == SUBREG
2718 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2719 && ! (ANY_FP_REG_P (operands[1]) ||
2720 (GET_CODE (operands[1]) == SUBREG
2721 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2723 "ix86_split_long_move (operands); DONE;")
2725 (define_insn "*swapdf"
2726 [(set (match_operand:DF 0 "register_operand" "+f")
2727 (match_operand:DF 1 "register_operand" "+f"))
2730 "reload_completed || !TARGET_SSE2"
2732 if (STACK_TOP_P (operands[0]))
2737 [(set_attr "type" "fxch")
2738 (set_attr "mode" "DF")])
2740 (define_expand "movxf"
2741 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2742 (match_operand:XF 1 "general_operand" ""))]
2743 "!TARGET_128BIT_LONG_DOUBLE"
2744 "ix86_expand_move (XFmode, operands); DONE;")
2746 (define_expand "movtf"
2747 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2748 (match_operand:TF 1 "general_operand" ""))]
2750 "ix86_expand_move (TFmode, operands); DONE;")
2752 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2753 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2754 ;; Pushing using integer instructions is longer except for constants
2755 ;; and direct memory references.
2756 ;; (assuming that any given constant is pushed only once, but this ought to be
2757 ;; handled elsewhere).
2759 (define_insn "*pushxf_nointeger"
2760 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2761 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2762 "!TARGET_128BIT_LONG_DOUBLE && optimize_size"
2764 /* This insn should be already splitted before reg-stack. */
2767 [(set_attr "type" "multi")
2768 (set_attr "mode" "XF,SI,SI")])
2770 (define_insn "*pushtf_nointeger"
2771 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2772 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2775 /* This insn should be already splitted before reg-stack. */
2778 [(set_attr "type" "multi")
2779 (set_attr "mode" "XF,SI,SI")])
2781 (define_insn "*pushxf_integer"
2782 [(set (match_operand:XF 0 "push_operand" "=<,<")
2783 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2784 "!TARGET_128BIT_LONG_DOUBLE && !optimize_size"
2786 /* This insn should be already splitted before reg-stack. */
2789 [(set_attr "type" "multi")
2790 (set_attr "mode" "XF,SI")])
2792 (define_insn "*pushtf_integer"
2793 [(set (match_operand:TF 0 "push_operand" "=<,<")
2794 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2797 /* This insn should be already splitted before reg-stack. */
2800 [(set_attr "type" "multi")
2801 (set_attr "mode" "XF,SI")])
2804 [(set (match_operand 0 "push_operand" "")
2805 (match_operand 1 "general_operand" ""))]
2807 && (GET_MODE (operands[0]) == XFmode
2808 || GET_MODE (operands[0]) == TFmode
2809 || GET_MODE (operands[0]) == DFmode)
2810 && !ANY_FP_REG_P (operands[1])"
2812 "ix86_split_long_move (operands); DONE;")
2815 [(set (match_operand:XF 0 "push_operand" "")
2816 (match_operand:XF 1 "any_fp_register_operand" ""))]
2817 "!TARGET_128BIT_LONG_DOUBLE"
2818 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2819 (set (mem:XF (reg:SI 7)) (match_dup 1))])
2822 [(set (match_operand:TF 0 "push_operand" "")
2823 (match_operand:TF 1 "any_fp_register_operand" ""))]
2825 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2826 (set (mem:TF (reg:SI 7)) (match_dup 1))])
2829 [(set (match_operand:TF 0 "push_operand" "")
2830 (match_operand:TF 1 "any_fp_register_operand" ""))]
2832 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
2833 (set (mem:TF (reg:DI 7)) (match_dup 1))])
2835 ;; Do not use integer registers when optimizing for size
2836 (define_insn "*movxf_nointeger"
2837 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2838 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2839 "!TARGET_128BIT_LONG_DOUBLE
2841 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2842 && (reload_in_progress || reload_completed
2843 || GET_CODE (operands[1]) != CONST_DOUBLE
2844 || memory_operand (operands[0], XFmode))"
2846 switch (which_alternative)
2849 if (REG_P (operands[1])
2850 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2852 if (REGNO (operands[0]) == FIRST_STACK_REG
2853 && TARGET_USE_FFREEP)
2854 return "ffreep\t%y0";
2857 else if (STACK_TOP_P (operands[0]))
2858 return "fld%z1\t%y1";
2863 /* There is no non-popping store to memory for XFmode. So if
2864 we need one, follow the store with a load. */
2865 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2866 return "fstp%z0\t%y0\;fld%z0\t%y0";
2868 return "fstp%z0\t%y0";
2871 return standard_80387_constant_opcode (operands[1]);
2878 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2879 (set_attr "mode" "XF,XF,XF,SI,SI")])
2881 (define_insn "*movtf_nointeger"
2882 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2883 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2884 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2886 && (reload_in_progress || reload_completed
2887 || GET_CODE (operands[1]) != CONST_DOUBLE
2888 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2889 || memory_operand (operands[0], TFmode))"
2891 switch (which_alternative)
2894 if (REG_P (operands[1])
2895 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2897 if (REGNO (operands[0]) == FIRST_STACK_REG
2898 && TARGET_USE_FFREEP)
2899 return "ffreep\t%y0";
2902 else if (STACK_TOP_P (operands[0]))
2903 return "fld%z1\t%y1";
2908 /* There is no non-popping store to memory for XFmode. So if
2909 we need one, follow the store with a load. */
2910 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2911 return "fstp%z0\t%y0\;fld%z0\t%y0";
2913 return "fstp%z0\t%y0";
2916 return standard_80387_constant_opcode (operands[1]);
2923 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2924 (set_attr "mode" "XF,XF,XF,SI,SI")])
2926 (define_insn "*movxf_integer"
2927 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2928 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2929 "!TARGET_128BIT_LONG_DOUBLE
2931 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2932 && (reload_in_progress || reload_completed
2933 || GET_CODE (operands[1]) != CONST_DOUBLE
2934 || memory_operand (operands[0], XFmode))"
2936 switch (which_alternative)
2939 if (REG_P (operands[1])
2940 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2942 if (REGNO (operands[0]) == FIRST_STACK_REG
2943 && TARGET_USE_FFREEP)
2944 return "ffreep\t%y0";
2947 else if (STACK_TOP_P (operands[0]))
2948 return "fld%z1\t%y1";
2953 /* There is no non-popping store to memory for XFmode. So if
2954 we need one, follow the store with a load. */
2955 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2956 return "fstp%z0\t%y0\;fld%z0\t%y0";
2958 return "fstp%z0\t%y0";
2961 return standard_80387_constant_opcode (operands[1]);
2968 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2969 (set_attr "mode" "XF,XF,XF,SI,SI")])
2971 (define_insn "*movtf_integer"
2972 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2973 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2974 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2976 && (reload_in_progress || reload_completed
2977 || GET_CODE (operands[1]) != CONST_DOUBLE
2978 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2979 || memory_operand (operands[0], TFmode))"
2981 switch (which_alternative)
2984 if (REG_P (operands[1])
2985 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2987 if (REGNO (operands[0]) == FIRST_STACK_REG
2988 && TARGET_USE_FFREEP)
2989 return "ffreep\t%y0";
2992 else if (STACK_TOP_P (operands[0]))
2993 return "fld%z1\t%y1";
2998 /* There is no non-popping store to memory for XFmode. So if
2999 we need one, follow the store with a load. */
3000 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3001 return "fstp%z0\t%y0\;fld%z0\t%y0";
3003 return "fstp%z0\t%y0";
3006 return standard_80387_constant_opcode (operands[1]);
3013 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3014 (set_attr "mode" "XF,XF,XF,SI,SI")])
3017 [(set (match_operand 0 "nonimmediate_operand" "")
3018 (match_operand 1 "general_operand" ""))]
3020 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3021 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3022 && ! (ANY_FP_REG_P (operands[0]) ||
3023 (GET_CODE (operands[0]) == SUBREG
3024 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3025 && ! (ANY_FP_REG_P (operands[1]) ||
3026 (GET_CODE (operands[1]) == SUBREG
3027 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3029 "ix86_split_long_move (operands); DONE;")
3032 [(set (match_operand 0 "register_operand" "")
3033 (match_operand 1 "memory_operand" ""))]
3035 && GET_CODE (operands[1]) == MEM
3036 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3037 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3038 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3039 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3040 && (!(SSE_REG_P (operands[0]) ||
3041 (GET_CODE (operands[0]) == SUBREG
3042 && SSE_REG_P (SUBREG_REG (operands[0]))))
3043 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3044 && (!(FP_REG_P (operands[0]) ||
3045 (GET_CODE (operands[0]) == SUBREG
3046 && FP_REG_P (SUBREG_REG (operands[0]))))
3047 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3050 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3052 (define_insn "swapxf"
3053 [(set (match_operand:XF 0 "register_operand" "+f")
3054 (match_operand:XF 1 "register_operand" "+f"))
3059 if (STACK_TOP_P (operands[0]))
3064 [(set_attr "type" "fxch")
3065 (set_attr "mode" "XF")])
3067 (define_insn "swaptf"
3068 [(set (match_operand:TF 0 "register_operand" "+f")
3069 (match_operand:TF 1 "register_operand" "+f"))
3074 if (STACK_TOP_P (operands[0]))
3079 [(set_attr "type" "fxch")
3080 (set_attr "mode" "XF")])
3082 ;; Zero extension instructions
3084 (define_expand "zero_extendhisi2"
3085 [(set (match_operand:SI 0 "register_operand" "")
3086 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3089 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3091 operands[1] = force_reg (HImode, operands[1]);
3092 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3097 (define_insn "zero_extendhisi2_and"
3098 [(set (match_operand:SI 0 "register_operand" "=r")
3099 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3100 (clobber (reg:CC 17))]
3101 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3103 [(set_attr "type" "alu1")
3104 (set_attr "mode" "SI")])
3107 [(set (match_operand:SI 0 "register_operand" "")
3108 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3109 (clobber (reg:CC 17))]
3110 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3111 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3112 (clobber (reg:CC 17))])]
3115 (define_insn "*zero_extendhisi2_movzwl"
3116 [(set (match_operand:SI 0 "register_operand" "=r")
3117 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3118 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3119 "movz{wl|x}\t{%1, %0|%0, %1}"
3120 [(set_attr "type" "imovx")
3121 (set_attr "mode" "SI")])
3123 (define_expand "zero_extendqihi2"
3125 [(set (match_operand:HI 0 "register_operand" "")
3126 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3127 (clobber (reg:CC 17))])]
3131 (define_insn "*zero_extendqihi2_and"
3132 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3133 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3134 (clobber (reg:CC 17))]
3135 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3137 [(set_attr "type" "alu1")
3138 (set_attr "mode" "HI")])
3140 (define_insn "*zero_extendqihi2_movzbw_and"
3141 [(set (match_operand:HI 0 "register_operand" "=r,r")
3142 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3143 (clobber (reg:CC 17))]
3144 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3146 [(set_attr "type" "imovx,alu1")
3147 (set_attr "mode" "HI")])
3149 (define_insn "*zero_extendqihi2_movzbw"
3150 [(set (match_operand:HI 0 "register_operand" "=r")
3151 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3152 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3153 "movz{bw|x}\t{%1, %0|%0, %1}"
3154 [(set_attr "type" "imovx")
3155 (set_attr "mode" "HI")])
3157 ;; For the movzbw case strip only the clobber
3159 [(set (match_operand:HI 0 "register_operand" "")
3160 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3161 (clobber (reg:CC 17))]
3163 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3164 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3165 [(set (match_operand:HI 0 "register_operand" "")
3166 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3168 ;; When source and destination does not overlap, clear destination
3169 ;; first and then do the movb
3171 [(set (match_operand:HI 0 "register_operand" "")
3172 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3173 (clobber (reg:CC 17))]
3175 && ANY_QI_REG_P (operands[0])
3176 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3177 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3178 [(set (match_dup 0) (const_int 0))
3179 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3180 "operands[2] = gen_lowpart (QImode, operands[0]);")
3182 ;; Rest is handled by single and.
3184 [(set (match_operand:HI 0 "register_operand" "")
3185 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3186 (clobber (reg:CC 17))]
3188 && true_regnum (operands[0]) == true_regnum (operands[1])"
3189 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3190 (clobber (reg:CC 17))])]
3193 (define_expand "zero_extendqisi2"
3195 [(set (match_operand:SI 0 "register_operand" "")
3196 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3197 (clobber (reg:CC 17))])]
3201 (define_insn "*zero_extendqisi2_and"
3202 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3203 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3204 (clobber (reg:CC 17))]
3205 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3207 [(set_attr "type" "alu1")
3208 (set_attr "mode" "SI")])
3210 (define_insn "*zero_extendqisi2_movzbw_and"
3211 [(set (match_operand:SI 0 "register_operand" "=r,r")
3212 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3213 (clobber (reg:CC 17))]
3214 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3216 [(set_attr "type" "imovx,alu1")
3217 (set_attr "mode" "SI")])
3219 (define_insn "*zero_extendqisi2_movzbw"
3220 [(set (match_operand:SI 0 "register_operand" "=r")
3221 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3222 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3223 "movz{bl|x}\t{%1, %0|%0, %1}"
3224 [(set_attr "type" "imovx")
3225 (set_attr "mode" "SI")])
3227 ;; For the movzbl case strip only the clobber
3229 [(set (match_operand:SI 0 "register_operand" "")
3230 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3231 (clobber (reg:CC 17))]
3233 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3234 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3236 (zero_extend:SI (match_dup 1)))])
3238 ;; When source and destination does not overlap, clear destination
3239 ;; first and then do the movb
3241 [(set (match_operand:SI 0 "register_operand" "")
3242 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3243 (clobber (reg:CC 17))]
3245 && ANY_QI_REG_P (operands[0])
3246 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3247 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3248 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3249 [(set (match_dup 0) (const_int 0))
3250 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3251 "operands[2] = gen_lowpart (QImode, operands[0]);")
3253 ;; Rest is handled by single and.
3255 [(set (match_operand:SI 0 "register_operand" "")
3256 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3257 (clobber (reg:CC 17))]
3259 && true_regnum (operands[0]) == true_regnum (operands[1])"
3260 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3261 (clobber (reg:CC 17))])]
3264 ;; %%% Kill me once multi-word ops are sane.
3265 (define_expand "zero_extendsidi2"
3266 [(set (match_operand:DI 0 "register_operand" "=r")
3267 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3271 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3276 (define_insn "zero_extendsidi2_32"
3277 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3278 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3279 (clobber (reg:CC 17))]
3282 [(set_attr "mode" "SI")])
3284 (define_insn "zero_extendsidi2_rex64"
3285 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3286 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3289 mov\t{%k1, %k0|%k0, %k1}
3291 [(set_attr "type" "imovx,imov")
3292 (set_attr "mode" "SI,DI")])
3295 [(set (match_operand:DI 0 "memory_operand" "")
3296 (zero_extend:DI (match_dup 0)))]
3298 [(set (match_dup 4) (const_int 0))]
3299 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3302 [(set (match_operand:DI 0 "register_operand" "")
3303 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3304 (clobber (reg:CC 17))]
3305 "!TARGET_64BIT && reload_completed
3306 && true_regnum (operands[0]) == true_regnum (operands[1])"
3307 [(set (match_dup 4) (const_int 0))]
3308 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3311 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3312 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3313 (clobber (reg:CC 17))]
3314 "!TARGET_64BIT && reload_completed"
3315 [(set (match_dup 3) (match_dup 1))
3316 (set (match_dup 4) (const_int 0))]
3317 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3319 (define_insn "zero_extendhidi2"
3320 [(set (match_operand:DI 0 "register_operand" "=r,r")
3321 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3324 movz{wl|x}\t{%1, %k0|%k0, %1}
3325 movz{wq|x}\t{%1, %0|%0, %1}"
3326 [(set_attr "type" "imovx")
3327 (set_attr "mode" "SI,DI")])
3329 (define_insn "zero_extendqidi2"
3330 [(set (match_operand:DI 0 "register_operand" "=r,r")
3331 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3334 movz{bl|x}\t{%1, %k0|%k0, %1}
3335 movz{bq|x}\t{%1, %0|%0, %1}"
3336 [(set_attr "type" "imovx")
3337 (set_attr "mode" "SI,DI")])
3339 ;; Sign extension instructions
3341 (define_expand "extendsidi2"
3342 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3343 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3344 (clobber (reg:CC 17))
3345 (clobber (match_scratch:SI 2 ""))])]
3350 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3355 (define_insn "*extendsidi2_1"
3356 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3357 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3358 (clobber (reg:CC 17))
3359 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3363 (define_insn "extendsidi2_rex64"
3364 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3365 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3369 movs{lq|x}\t{%1,%0|%0, %1}"
3370 [(set_attr "type" "imovx")
3371 (set_attr "mode" "DI")
3372 (set_attr "prefix_0f" "0")
3373 (set_attr "modrm" "0,1")])
3375 (define_insn "extendhidi2"
3376 [(set (match_operand:DI 0 "register_operand" "=r")
3377 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3379 "movs{wq|x}\t{%1,%0|%0, %1}"
3380 [(set_attr "type" "imovx")
3381 (set_attr "mode" "DI")])
3383 (define_insn "extendqidi2"
3384 [(set (match_operand:DI 0 "register_operand" "=r")
3385 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]