comparison src/cpu/x86/vm/x86_32.ad @ 415:4d9884b01ba6

6754519: don't emit flag fixup for NaN when condition being tested doesn't need it Reviewed-by: kvn, rasbold
author never
date Tue, 28 Oct 2008 09:31:30 -0700
parents b744678d4d71
children a1980da045cc
comparison
equal deleted inserted replaced
407:ebfd4ae89bf6 415:4d9884b01ba6
493 //============================================================================= 493 //=============================================================================
494 #ifndef PRODUCT 494 #ifndef PRODUCT
495 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { 495 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
496 Compile* C = ra_->C; 496 Compile* C = ra_->C;
497 if( C->in_24_bit_fp_mode() ) { 497 if( C->in_24_bit_fp_mode() ) {
498 tty->print("FLDCW 24 bit fpu control word"); 498 st->print("FLDCW 24 bit fpu control word");
499 tty->print_cr(""); tty->print("\t"); 499 st->print_cr(""); st->print("\t");
500 } 500 }
501 501
502 int framesize = C->frame_slots() << LogBytesPerInt; 502 int framesize = C->frame_slots() << LogBytesPerInt;
503 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 503 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
504 // Remove two words for return addr and rbp, 504 // Remove two words for return addr and rbp,
508 // We require that their callers must bang for them. But be careful, because 508 // We require that their callers must bang for them. But be careful, because
509 // some VM calls (such as call site linkage) can use several kilobytes of 509 // some VM calls (such as call site linkage) can use several kilobytes of
510 // stack. But the stack safety zone should account for that. 510 // stack. But the stack safety zone should account for that.
511 // See bugs 4446381, 4468289, 4497237. 511 // See bugs 4446381, 4468289, 4497237.
512 if (C->need_stack_bang(framesize)) { 512 if (C->need_stack_bang(framesize)) {
513 tty->print_cr("# stack bang"); tty->print("\t"); 513 st->print_cr("# stack bang"); st->print("\t");
514 } 514 }
515 tty->print_cr("PUSHL EBP"); tty->print("\t"); 515 st->print_cr("PUSHL EBP"); st->print("\t");
516 516
517 if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth 517 if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth
518 tty->print("PUSH 0xBADB100D\t# Majik cookie for stack depth check"); 518 st->print("PUSH 0xBADB100D\t# Majik cookie for stack depth check");
519 tty->print_cr(""); tty->print("\t"); 519 st->print_cr(""); st->print("\t");
520 framesize -= wordSize; 520 framesize -= wordSize;
521 } 521 }
522 522
523 if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) { 523 if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) {
524 if (framesize) { 524 if (framesize) {
525 tty->print("SUB ESP,%d\t# Create frame",framesize); 525 st->print("SUB ESP,%d\t# Create frame",framesize);
526 } 526 }
527 } else { 527 } else {
528 tty->print("SUB ESP,%d\t# Create frame",framesize); 528 st->print("SUB ESP,%d\t# Create frame",framesize);
529 } 529 }
530 } 530 }
531 #endif 531 #endif
532 532
533 533
723 } 723 }
724 assert(r->is_XMMRegister(), "must be"); 724 assert(r->is_XMMRegister(), "must be");
725 return rc_xmm; 725 return rc_xmm;
726 } 726 }
727 727
728 static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg, int opcode, const char *op_str, int size ) { 728 static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg,
729 int opcode, const char *op_str, int size, outputStream* st ) {
729 if( cbuf ) { 730 if( cbuf ) {
730 emit_opcode (*cbuf, opcode ); 731 emit_opcode (*cbuf, opcode );
731 encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, false); 732 encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, false);
732 #ifndef PRODUCT 733 #ifndef PRODUCT
733 } else if( !do_size ) { 734 } else if( !do_size ) {
734 if( size != 0 ) tty->print("\n\t"); 735 if( size != 0 ) st->print("\n\t");
735 if( opcode == 0x8B || opcode == 0x89 ) { // MOV 736 if( opcode == 0x8B || opcode == 0x89 ) { // MOV
736 if( is_load ) tty->print("%s %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset); 737 if( is_load ) st->print("%s %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
737 else tty->print("%s [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]); 738 else st->print("%s [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
738 } else { // FLD, FST, PUSH, POP 739 } else { // FLD, FST, PUSH, POP
739 tty->print("%s [ESP + #%d]",op_str,offset); 740 st->print("%s [ESP + #%d]",op_str,offset);
740 } 741 }
741 #endif 742 #endif
742 } 743 }
743 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4); 744 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
744 return size+3+offset_size; 745 return size+3+offset_size;
745 } 746 }
746 747
747 // Helper for XMM registers. Extra opcode bits, limited syntax. 748 // Helper for XMM registers. Extra opcode bits, limited syntax.
748 static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load, 749 static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
749 int offset, int reg_lo, int reg_hi, int size ) { 750 int offset, int reg_lo, int reg_hi, int size, outputStream* st ) {
750 if( cbuf ) { 751 if( cbuf ) {
751 if( reg_lo+1 == reg_hi ) { // double move? 752 if( reg_lo+1 == reg_hi ) { // double move?
752 if( is_load && !UseXmmLoadAndClearUpper ) 753 if( is_load && !UseXmmLoadAndClearUpper )
753 emit_opcode(*cbuf, 0x66 ); // use 'movlpd' for load 754 emit_opcode(*cbuf, 0x66 ); // use 'movlpd' for load
754 else 755 else
762 else 763 else
763 emit_opcode(*cbuf, is_load ? 0x10 : 0x11 ); 764 emit_opcode(*cbuf, is_load ? 0x10 : 0x11 );
764 encode_RegMem(*cbuf, Matcher::_regEncode[reg_lo], ESP_enc, 0x4, 0, offset, false); 765 encode_RegMem(*cbuf, Matcher::_regEncode[reg_lo], ESP_enc, 0x4, 0, offset, false);
765 #ifndef PRODUCT 766 #ifndef PRODUCT
766 } else if( !do_size ) { 767 } else if( !do_size ) {
767 if( size != 0 ) tty->print("\n\t"); 768 if( size != 0 ) st->print("\n\t");
768 if( reg_lo+1 == reg_hi ) { // double move? 769 if( reg_lo+1 == reg_hi ) { // double move?
769 if( is_load ) tty->print("%s %s,[ESP + #%d]", 770 if( is_load ) st->print("%s %s,[ESP + #%d]",
770 UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD", 771 UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
771 Matcher::regName[reg_lo], offset); 772 Matcher::regName[reg_lo], offset);
772 else tty->print("MOVSD [ESP + #%d],%s", 773 else st->print("MOVSD [ESP + #%d],%s",
773 offset, Matcher::regName[reg_lo]); 774 offset, Matcher::regName[reg_lo]);
774 } else { 775 } else {
775 if( is_load ) tty->print("MOVSS %s,[ESP + #%d]", 776 if( is_load ) st->print("MOVSS %s,[ESP + #%d]",
776 Matcher::regName[reg_lo], offset); 777 Matcher::regName[reg_lo], offset);
777 else tty->print("MOVSS [ESP + #%d],%s", 778 else st->print("MOVSS [ESP + #%d],%s",
778 offset, Matcher::regName[reg_lo]); 779 offset, Matcher::regName[reg_lo]);
779 } 780 }
780 #endif 781 #endif
781 } 782 }
782 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4); 783 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
783 return size+5+offset_size; 784 return size+5+offset_size;
784 } 785 }
785 786
786 787
787 static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 788 static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
788 int src_hi, int dst_hi, int size ) { 789 int src_hi, int dst_hi, int size, outputStream* st ) {
789 if( UseXmmRegToRegMoveAll ) {//Use movaps,movapd to move between xmm registers 790 if( UseXmmRegToRegMoveAll ) {//Use movaps,movapd to move between xmm registers
790 if( cbuf ) { 791 if( cbuf ) {
791 if( (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ) { 792 if( (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ) {
792 emit_opcode(*cbuf, 0x66 ); 793 emit_opcode(*cbuf, 0x66 );
793 } 794 }
794 emit_opcode(*cbuf, 0x0F ); 795 emit_opcode(*cbuf, 0x0F );
795 emit_opcode(*cbuf, 0x28 ); 796 emit_opcode(*cbuf, 0x28 );
796 emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] ); 797 emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
797 #ifndef PRODUCT 798 #ifndef PRODUCT
798 } else if( !do_size ) { 799 } else if( !do_size ) {
799 if( size != 0 ) tty->print("\n\t"); 800 if( size != 0 ) st->print("\n\t");
800 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move? 801 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
801 tty->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); 802 st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
802 } else { 803 } else {
803 tty->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); 804 st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
804 } 805 }
805 #endif 806 #endif
806 } 807 }
807 return size + ((src_lo+1 == src_hi && dst_lo+1 == dst_hi) ? 4 : 3); 808 return size + ((src_lo+1 == src_hi && dst_lo+1 == dst_hi) ? 4 : 3);
808 } else { 809 } else {
811 emit_opcode(*cbuf, 0x0F ); 812 emit_opcode(*cbuf, 0x0F );
812 emit_opcode(*cbuf, 0x10 ); 813 emit_opcode(*cbuf, 0x10 );
813 emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] ); 814 emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
814 #ifndef PRODUCT 815 #ifndef PRODUCT
815 } else if( !do_size ) { 816 } else if( !do_size ) {
816 if( size != 0 ) tty->print("\n\t"); 817 if( size != 0 ) st->print("\n\t");
817 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move? 818 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
818 tty->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); 819 st->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
819 } else { 820 } else {
820 tty->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); 821 st->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
821 } 822 }
822 #endif 823 #endif
823 } 824 }
824 return size+4; 825 return size+4;
825 } 826 }
826 } 827 }
827 828
828 static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size ) { 829 static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size, outputStream* st ) {
829 if( cbuf ) { 830 if( cbuf ) {
830 emit_opcode(*cbuf, 0x8B ); 831 emit_opcode(*cbuf, 0x8B );
831 emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] ); 832 emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] );
832 #ifndef PRODUCT 833 #ifndef PRODUCT
833 } else if( !do_size ) { 834 } else if( !do_size ) {
834 if( size != 0 ) tty->print("\n\t"); 835 if( size != 0 ) st->print("\n\t");
835 tty->print("MOV %s,%s",Matcher::regName[dst],Matcher::regName[src]); 836 st->print("MOV %s,%s",Matcher::regName[dst],Matcher::regName[src]);
836 #endif 837 #endif
837 } 838 }
838 return size+2; 839 return size+2;
839 } 840 }
840 841
841 static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi, int offset, int size ) { 842 static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi,
843 int offset, int size, outputStream* st ) {
842 if( src_lo != FPR1L_num ) { // Move value to top of FP stack, if not already there 844 if( src_lo != FPR1L_num ) { // Move value to top of FP stack, if not already there
843 if( cbuf ) { 845 if( cbuf ) {
844 emit_opcode( *cbuf, 0xD9 ); // FLD (i.e., push it) 846 emit_opcode( *cbuf, 0xD9 ); // FLD (i.e., push it)
845 emit_d8( *cbuf, 0xC0-1+Matcher::_regEncode[src_lo] ); 847 emit_d8( *cbuf, 0xC0-1+Matcher::_regEncode[src_lo] );
846 #ifndef PRODUCT 848 #ifndef PRODUCT
847 } else if( !do_size ) { 849 } else if( !do_size ) {
848 if( size != 0 ) tty->print("\n\t"); 850 if( size != 0 ) st->print("\n\t");
849 tty->print("FLD %s",Matcher::regName[src_lo]); 851 st->print("FLD %s",Matcher::regName[src_lo]);
850 #endif 852 #endif
851 } 853 }
852 size += 2; 854 size += 2;
853 } 855 }
854 856
862 op_str = (src_lo != FPR1L_num) ? "FSTP_S" : "FST_S "; 864 op_str = (src_lo != FPR1L_num) ? "FSTP_S" : "FST_S ";
863 op = 0xD9; 865 op = 0xD9;
864 assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" ); 866 assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" );
865 } 867 }
866 868
867 return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size); 869 return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size, st);
868 } 870 }
869 871
870 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const { 872 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
871 // Get registers to move 873 // Get registers to move
872 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 874 OptoReg::Name src_second = ra_->get_reg_second(in(1));
890 // -------------------------------------- 892 // --------------------------------------
891 // Check for mem-mem move. push/pop to move. 893 // Check for mem-mem move. push/pop to move.
892 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 894 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
893 if( src_second == dst_first ) { // overlapping stack copy ranges 895 if( src_second == dst_first ) { // overlapping stack copy ranges
894 assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" ); 896 assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" );
895 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size); 897 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st);
896 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size); 898 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st);
897 src_second_rc = dst_second_rc = rc_bad; // flag as already moved the second bits 899 src_second_rc = dst_second_rc = rc_bad; // flag as already moved the second bits
898 } 900 }
899 // move low bits 901 // move low bits
900 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH ",size); 902 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH ",size, st);
901 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP ",size); 903 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP ",size, st);
902 if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits 904 if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits
903 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size); 905 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st);
904 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size); 906 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st);
905 } 907 }
906 return size; 908 return size;
907 } 909 }
908 910
909 // -------------------------------------- 911 // --------------------------------------
910 // Check for integer reg-reg copy 912 // Check for integer reg-reg copy
911 if( src_first_rc == rc_int && dst_first_rc == rc_int ) 913 if( src_first_rc == rc_int && dst_first_rc == rc_int )
912 size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size); 914 size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size, st);
913 915
914 // Check for integer store 916 // Check for integer store
915 if( src_first_rc == rc_int && dst_first_rc == rc_stack ) 917 if( src_first_rc == rc_int && dst_first_rc == rc_stack )
916 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size); 918 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size, st);
917 919
918 // Check for integer load 920 // Check for integer load
919 if( dst_first_rc == rc_int && src_first_rc == rc_stack ) 921 if( dst_first_rc == rc_int && src_first_rc == rc_stack )
920 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size); 922 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size, st);
921 923
922 // -------------------------------------- 924 // --------------------------------------
923 // Check for float reg-reg copy 925 // Check for float reg-reg copy
924 if( src_first_rc == rc_float && dst_first_rc == rc_float ) { 926 if( src_first_rc == rc_float && dst_first_rc == rc_float ) {
925 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) || 927 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) ||
949 return size + ((src_first != FPR1L_num) ? 2+2 : 2); 951 return size + ((src_first != FPR1L_num) ? 2+2 : 2);
950 } 952 }
951 953
952 // Check for float store 954 // Check for float store
953 if( src_first_rc == rc_float && dst_first_rc == rc_stack ) { 955 if( src_first_rc == rc_float && dst_first_rc == rc_stack ) {
954 return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size); 956 return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size, st);
955 } 957 }
956 958
957 // Check for float load 959 // Check for float load
958 if( dst_first_rc == rc_float && src_first_rc == rc_stack ) { 960 if( dst_first_rc == rc_float && src_first_rc == rc_stack ) {
959 int offset = ra_->reg2offset(src_first); 961 int offset = ra_->reg2offset(src_first);
985 // Check for xmm reg-reg copy 987 // Check for xmm reg-reg copy
986 if( src_first_rc == rc_xmm && dst_first_rc == rc_xmm ) { 988 if( src_first_rc == rc_xmm && dst_first_rc == rc_xmm ) {
987 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) || 989 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) ||
988 (src_first+1 == src_second && dst_first+1 == dst_second), 990 (src_first+1 == src_second && dst_first+1 == dst_second),
989 "no non-adjacent float-moves" ); 991 "no non-adjacent float-moves" );
990 return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size); 992 return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st);
991 } 993 }
992 994
993 // Check for xmm store 995 // Check for xmm store
994 if( src_first_rc == rc_xmm && dst_first_rc == rc_stack ) { 996 if( src_first_rc == rc_xmm && dst_first_rc == rc_stack ) {
995 return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size); 997 return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size, st);
996 } 998 }
997 999
998 // Check for float xmm load 1000 // Check for float xmm load
999 if( dst_first_rc == rc_xmm && src_first_rc == rc_stack ) { 1001 if( dst_first_rc == rc_xmm && src_first_rc == rc_stack ) {
1000 return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size); 1002 return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size, st);
1001 } 1003 }
1002 1004
1003 // Copy from float reg to xmm reg 1005 // Copy from float reg to xmm reg
1004 if( dst_first_rc == rc_xmm && src_first_rc == rc_float ) { 1006 if( dst_first_rc == rc_xmm && src_first_rc == rc_float ) {
1005 // copy to the top of stack from floating point reg 1007 // copy to the top of stack from floating point reg
1015 st->print("LEA ESP,[ESP-8]"); 1017 st->print("LEA ESP,[ESP-8]");
1016 #endif 1018 #endif
1017 } 1019 }
1018 size += 4; 1020 size += 4;
1019 1021
1020 size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size); 1022 size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size, st);
1021 1023
1022 // Copy from the temp memory to the xmm reg. 1024 // Copy from the temp memory to the xmm reg.
1023 size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size); 1025 size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size, st);
1024 1026
1025 if( cbuf ) { 1027 if( cbuf ) {
1026 emit_opcode(*cbuf,0x8D); // LEA ESP,[ESP+8] 1028 emit_opcode(*cbuf,0x8D); // LEA ESP,[ESP+8]
1027 emit_rm(*cbuf, 0x1, ESP_enc, 0x04); 1029 emit_rm(*cbuf, 0x1, ESP_enc, 0x04);
1028 emit_rm(*cbuf, 0x0, 0x04, ESP_enc); 1030 emit_rm(*cbuf, 0x0, 0x04, ESP_enc);
1045 return size; // Self copy; no move 1047 return size; // Self copy; no move
1046 assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" ); 1048 assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" );
1047 1049
1048 // Check for second word int-int move 1050 // Check for second word int-int move
1049 if( src_second_rc == rc_int && dst_second_rc == rc_int ) 1051 if( src_second_rc == rc_int && dst_second_rc == rc_int )
1050 return impl_mov_helper(cbuf,do_size,src_second,dst_second,size); 1052 return impl_mov_helper(cbuf,do_size,src_second,dst_second,size, st);
1051 1053
1052 // Check for second word integer store 1054 // Check for second word integer store
1053 if( src_second_rc == rc_int && dst_second_rc == rc_stack ) 1055 if( src_second_rc == rc_int && dst_second_rc == rc_stack )
1054 return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size); 1056 return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size, st);
1055 1057
1056 // Check for second word integer load 1058 // Check for second word integer load
1057 if( dst_second_rc == rc_int && src_second_rc == rc_stack ) 1059 if( dst_second_rc == rc_int && src_second_rc == rc_stack )
1058 return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size); 1060 return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size, st);
1059 1061
1060 1062
1061 Unimplemented(); 1063 Unimplemented();
1062 } 1064 }
1063 1065
1316 1318
1317 // Is this branch offset short enough that a short branch can be used? 1319 // Is this branch offset short enough that a short branch can be used?
1318 // 1320 //
1319 // NOTE: If the platform does not provide any short branch variants, then 1321 // NOTE: If the platform does not provide any short branch variants, then
1320 // this method should return false for offset 0. 1322 // this method should return false for offset 0.
1321 bool Matcher::is_short_branch_offset(int offset) { 1323 bool Matcher::is_short_branch_offset(int rule, int offset) {
1324 // the short version of jmpConUCF2 contains multiple branches,
1325 // making the reach slightly less
1326 if (rule == jmpConUCF2_rule)
1327 return (-126 <= offset && offset <= 125);
1322 return (-128 <= offset && offset <= 127); 1328 return (-128 <= offset && offset <= 127);
1323 } 1329 }
1324 1330
1325 const bool Matcher::isSimpleConstant64(jlong value) { 1331 const bool Matcher::isSimpleConstant64(jlong value) {
1326 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1332 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
5270 5276
5271 format %{ "EFLAGS_U" %} 5277 format %{ "EFLAGS_U" %}
5272 interface(REG_INTER); 5278 interface(REG_INTER);
5273 %} 5279 %}
5274 5280
5281 operand eFlagsRegUCF() %{
5282 constraint(ALLOC_IN_RC(int_flags));
5283 match(RegFlags);
5284 predicate(false);
5285
5286 format %{ "EFLAGS_U_CF" %}
5287 interface(REG_INTER);
5288 %}
5289
5275 // Condition Code Register used by long compare 5290 // Condition Code Register used by long compare
5276 operand flagsReg_long_LTGE() %{ 5291 operand flagsReg_long_LTGE() %{
5277 constraint(ALLOC_IN_RC(int_flags)); 5292 constraint(ALLOC_IN_RC(int_flags));
5278 match(RegFlags); 5293 match(RegFlags);
5279 format %{ "FLAGS_LTGE" %} 5294 format %{ "FLAGS_LTGE" %}
5747 operand cmpOp() %{ 5762 operand cmpOp() %{
5748 match(Bool); 5763 match(Bool);
5749 5764
5750 format %{ "" %} 5765 format %{ "" %}
5751 interface(COND_INTER) %{ 5766 interface(COND_INTER) %{
5752 equal(0x4); 5767 equal(0x4, "e");
5753 not_equal(0x5); 5768 not_equal(0x5, "ne");
5754 less(0xC); 5769 less(0xC, "l");
5755 greater_equal(0xD); 5770 greater_equal(0xD, "ge");
5756 less_equal(0xE); 5771 less_equal(0xE, "le");
5757 greater(0xF); 5772 greater(0xF, "g");
5758 %} 5773 %}
5759 %} 5774 %}
5760 5775
5761 // Comparison Code, unsigned compare. Used by FP also, with 5776 // Comparison Code, unsigned compare. Used by FP also, with
5762 // C2 (unordered) turned into GT or LT already. The other bits 5777 // C2 (unordered) turned into GT or LT already. The other bits
5764 operand cmpOpU() %{ 5779 operand cmpOpU() %{
5765 match(Bool); 5780 match(Bool);
5766 5781
5767 format %{ "" %} 5782 format %{ "" %}
5768 interface(COND_INTER) %{ 5783 interface(COND_INTER) %{
5769 equal(0x4); 5784 equal(0x4, "e");
5770 not_equal(0x5); 5785 not_equal(0x5, "ne");
5771 less(0x2); 5786 less(0x2, "b");
5772 greater_equal(0x3); 5787 greater_equal(0x3, "nb");
5773 less_equal(0x6); 5788 less_equal(0x6, "be");
5774 greater(0x7); 5789 greater(0x7, "nbe");
5790 %}
5791 %}
5792
5793 // Floating comparisons that don't require any fixup for the unordered case
5794 operand cmpOpUCF() %{
5795 match(Bool);
5796 predicate(n->as_Bool()->_test._test == BoolTest::lt ||
5797 n->as_Bool()->_test._test == BoolTest::ge ||
5798 n->as_Bool()->_test._test == BoolTest::le ||
5799 n->as_Bool()->_test._test == BoolTest::gt);
5800 format %{ "" %}
5801 interface(COND_INTER) %{
5802 equal(0x4, "e");
5803 not_equal(0x5, "ne");
5804 less(0x2, "b");
5805 greater_equal(0x3, "nb");
5806 less_equal(0x6, "be");
5807 greater(0x7, "nbe");
5808 %}
5809 %}
5810
5811
5812 // Floating comparisons that can be fixed up with extra conditional jumps
5813 operand cmpOpUCF2() %{
5814 match(Bool);
5815 predicate(n->as_Bool()->_test._test == BoolTest::ne ||
5816 n->as_Bool()->_test._test == BoolTest::eq);
5817 format %{ "" %}
5818 interface(COND_INTER) %{
5819 equal(0x4, "e");
5820 not_equal(0x5, "ne");
5821 less(0x2, "b");
5822 greater_equal(0x3, "nb");
5823 less_equal(0x6, "be");
5824 greater(0x7, "nbe");
5775 %} 5825 %}
5776 %} 5826 %}
5777 5827
5778 // Comparison Code for FP conditional move 5828 // Comparison Code for FP conditional move
5779 operand cmpOp_fcmov() %{ 5829 operand cmpOp_fcmov() %{
5794 operand cmpOp_commute() %{ 5844 operand cmpOp_commute() %{
5795 match(Bool); 5845 match(Bool);
5796 5846
5797 format %{ "" %} 5847 format %{ "" %}
5798 interface(COND_INTER) %{ 5848 interface(COND_INTER) %{
5799 equal(0x4); 5849 equal(0x4, "e");
5800 not_equal(0x5); 5850 not_equal(0x5, "ne");
5801 less(0xF); 5851 less(0xF, "g");
5802 greater_equal(0xE); 5852 greater_equal(0xE, "le");
5803 less_equal(0xD); 5853 less_equal(0xD, "ge");
5804 greater(0xC); 5854 greater(0xC, "l");
5805 %} 5855 %}
5806 %} 5856 %}
5807 5857
5808 //----------OPERAND CLASSES---------------------------------------------------- 5858 //----------OPERAND CLASSES----------------------------------------------------
5809 // Operand Classes are groups of operands that are used as to simplify 5859 // Operand Classes are groups of operands that are used as to simplify
7355 opcode(0x0F,0x40); 7405 opcode(0x0F,0x40);
7356 ins_encode( enc_cmov(cop), RegReg( dst, src ) ); 7406 ins_encode( enc_cmov(cop), RegReg( dst, src ) );
7357 ins_pipe( pipe_cmov_reg ); 7407 ins_pipe( pipe_cmov_reg );
7358 %} 7408 %}
7359 7409
7360 instruct cmovI_regU( eRegI dst, eRegI src, eFlagsRegU cr, cmpOpU cop ) %{ 7410 instruct cmovI_regU( cmpOpU cop, eFlagsRegU cr, eRegI dst, eRegI src ) %{
7361 predicate(VM_Version::supports_cmov() ); 7411 predicate(VM_Version::supports_cmov() );
7362 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7412 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7363 ins_cost(200); 7413 ins_cost(200);
7364 format %{ "CMOV$cop $dst,$src" %} 7414 format %{ "CMOV$cop $dst,$src" %}
7365 opcode(0x0F,0x40); 7415 opcode(0x0F,0x40);
7366 ins_encode( enc_cmov(cop), RegReg( dst, src ) ); 7416 ins_encode( enc_cmov(cop), RegReg( dst, src ) );
7367 ins_pipe( pipe_cmov_reg ); 7417 ins_pipe( pipe_cmov_reg );
7418 %}
7419
7420 instruct cmovI_regUCF( cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, eRegI src ) %{
7421 predicate(VM_Version::supports_cmov() );
7422 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7423 ins_cost(200);
7424 expand %{
7425 cmovI_regU(cop, cr, dst, src);
7426 %}
7368 %} 7427 %}
7369 7428
7370 // Conditional move 7429 // Conditional move
7371 instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{ 7430 instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{
7372 predicate(VM_Version::supports_cmov() ); 7431 predicate(VM_Version::supports_cmov() );
7377 ins_encode( enc_cmov(cop), RegMem( dst, src ) ); 7436 ins_encode( enc_cmov(cop), RegMem( dst, src ) );
7378 ins_pipe( pipe_cmov_mem ); 7437 ins_pipe( pipe_cmov_mem );
7379 %} 7438 %}
7380 7439
7381 // Conditional move 7440 // Conditional move
7382 instruct cmovI_memu(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{ 7441 instruct cmovI_memU(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
7383 predicate(VM_Version::supports_cmov() ); 7442 predicate(VM_Version::supports_cmov() );
7384 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7443 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7385 ins_cost(250); 7444 ins_cost(250);
7386 format %{ "CMOV$cop $dst,$src" %} 7445 format %{ "CMOV$cop $dst,$src" %}
7387 opcode(0x0F,0x40); 7446 opcode(0x0F,0x40);
7388 ins_encode( enc_cmov(cop), RegMem( dst, src ) ); 7447 ins_encode( enc_cmov(cop), RegMem( dst, src ) );
7389 ins_pipe( pipe_cmov_mem ); 7448 ins_pipe( pipe_cmov_mem );
7449 %}
7450
7451 instruct cmovI_memUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, memory src) %{
7452 predicate(VM_Version::supports_cmov() );
7453 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7454 ins_cost(250);
7455 expand %{
7456 cmovI_memU(cop, cr, dst, src);
7457 %}
7390 %} 7458 %}
7391 7459
7392 // Conditional move 7460 // Conditional move
7393 instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{ 7461 instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{
7394 predicate(VM_Version::supports_cmov() ); 7462 predicate(VM_Version::supports_cmov() );
7414 ins_encode( enc_cmov_branch(cop, 0x2), OpcP, RegReg(dst, src)); 7482 ins_encode( enc_cmov_branch(cop, 0x2), OpcP, RegReg(dst, src));
7415 ins_pipe( pipe_cmov_reg ); 7483 ins_pipe( pipe_cmov_reg );
7416 %} 7484 %}
7417 7485
7418 // Conditional move 7486 // Conditional move
7419 instruct cmovP_regU(eRegP dst, eRegP src, eFlagsRegU cr, cmpOpU cop ) %{ 7487 instruct cmovP_regU(cmpOpU cop, eFlagsRegU cr, eRegP dst, eRegP src ) %{
7420 predicate(VM_Version::supports_cmov() ); 7488 predicate(VM_Version::supports_cmov() );
7421 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7489 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7422 ins_cost(200); 7490 ins_cost(200);
7423 format %{ "CMOV$cop $dst,$src\t# ptr" %} 7491 format %{ "CMOV$cop $dst,$src\t# ptr" %}
7424 opcode(0x0F,0x40); 7492 opcode(0x0F,0x40);
7425 ins_encode( enc_cmov(cop), RegReg( dst, src ) ); 7493 ins_encode( enc_cmov(cop), RegReg( dst, src ) );
7426 ins_pipe( pipe_cmov_reg ); 7494 ins_pipe( pipe_cmov_reg );
7495 %}
7496
7497 instruct cmovP_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegP dst, eRegP src ) %{
7498 predicate(VM_Version::supports_cmov() );
7499 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7500 ins_cost(200);
7501 expand %{
7502 cmovP_regU(cop, cr, dst, src);
7503 %}
7427 %} 7504 %}
7428 7505
7429 // DISABLED: Requires the ADLC to emit a bottom_type call that 7506 // DISABLED: Requires the ADLC to emit a bottom_type call that
7430 // correctly meets the two pointer arguments; one is an incoming 7507 // correctly meets the two pointer arguments; one is an incoming
7431 // register but the other is a memory operand. ALSO appears to 7508 // register but the other is a memory operand. ALSO appears to
7553 __ bind(skip); 7630 __ bind(skip);
7554 %} 7631 %}
7555 ins_pipe( pipe_slow ); 7632 ins_pipe( pipe_slow );
7556 %} 7633 %}
7557 7634
7635 instruct fcmovX_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regX dst, regX src) %{
7636 predicate (UseSSE>=1);
7637 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7638 ins_cost(200);
7639 expand %{
7640 fcmovX_regU(cop, cr, dst, src);
7641 %}
7642 %}
7643
7558 // unsigned version 7644 // unsigned version
7559 instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{ 7645 instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{
7560 predicate (UseSSE>=2); 7646 predicate (UseSSE>=2);
7561 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7647 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7562 ins_cost(200); 7648 ins_cost(200);
7571 __ bind(skip); 7657 __ bind(skip);
7572 %} 7658 %}
7573 ins_pipe( pipe_slow ); 7659 ins_pipe( pipe_slow );
7574 %} 7660 %}
7575 7661
7662 instruct fcmovXD_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regXD dst, regXD src) %{
7663 predicate (UseSSE>=2);
7664 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7665 ins_cost(200);
7666 expand %{
7667 fcmovXD_regU(cop, cr, dst, src);
7668 %}
7669 %}
7670
7576 instruct cmovL_reg(cmpOp cop, eFlagsReg cr, eRegL dst, eRegL src) %{ 7671 instruct cmovL_reg(cmpOp cop, eFlagsReg cr, eRegL dst, eRegL src) %{
7577 predicate(VM_Version::supports_cmov() ); 7672 predicate(VM_Version::supports_cmov() );
7578 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7673 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7579 ins_cost(200); 7674 ins_cost(200);
7580 format %{ "CMOV$cop $dst.lo,$src.lo\n\t" 7675 format %{ "CMOV$cop $dst.lo,$src.lo\n\t"
7591 format %{ "CMOV$cop $dst.lo,$src.lo\n\t" 7686 format %{ "CMOV$cop $dst.lo,$src.lo\n\t"
7592 "CMOV$cop $dst.hi,$src.hi" %} 7687 "CMOV$cop $dst.hi,$src.hi" %}
7593 opcode(0x0F,0x40); 7688 opcode(0x0F,0x40);
7594 ins_encode( enc_cmov(cop), RegReg_Lo2( dst, src ), enc_cmov(cop), RegReg_Hi2( dst, src ) ); 7689 ins_encode( enc_cmov(cop), RegReg_Lo2( dst, src ), enc_cmov(cop), RegReg_Hi2( dst, src ) );
7595 ins_pipe( pipe_cmov_reg_long ); 7690 ins_pipe( pipe_cmov_reg_long );
7691 %}
7692
7693 instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
7694 predicate(VM_Version::supports_cmov() );
7695 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7696 ins_cost(200);
7697 expand %{
7698 cmovL_regU(cop, cr, dst, src);
7699 %}
7596 %} 7700 %}
7597 7701
7598 //----------Arithmetic Instructions-------------------------------------------- 7702 //----------Arithmetic Instructions--------------------------------------------
7599 //----------Addition Instructions---------------------------------------------- 7703 //----------Addition Instructions----------------------------------------------
7600 // Integer Addition Instructions 7704 // Integer Addition Instructions
9198 OpcP, RegOpc(src2), 9302 OpcP, RegOpc(src2),
9199 cmpF_P6_fixup ); 9303 cmpF_P6_fixup );
9200 ins_pipe( pipe_slow ); 9304 ins_pipe( pipe_slow );
9201 %} 9305 %}
9202 9306
9307 instruct cmpD_cc_P6CF(eFlagsRegUCF cr, regD src1, regD src2) %{
9308 predicate(VM_Version::supports_cmov() && UseSSE <=1);
9309 match(Set cr (CmpD src1 src2));
9310 ins_cost(150);
9311 format %{ "FLD $src1\n\t"
9312 "FUCOMIP ST,$src2 // P6 instruction" %}
9313 opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
9314 ins_encode( Push_Reg_D(src1),
9315 OpcP, RegOpc(src2));
9316 ins_pipe( pipe_slow );
9317 %}
9318
9203 // Compare & branch 9319 // Compare & branch
9204 instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{ 9320 instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{
9205 predicate(UseSSE<=1); 9321 predicate(UseSSE<=1);
9206 match(Set cr (CmpD src1 src2)); 9322 match(Set cr (CmpD src1 src2));
9207 effect(KILL rax); 9323 effect(KILL rax);
9262 opcode(0x66, 0x0F, 0x2F); 9378 opcode(0x66, 0x0F, 0x2F);
9263 ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src), cmpF_P6_fixup); 9379 ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src), cmpF_P6_fixup);
9264 ins_pipe( pipe_slow ); 9380 ins_pipe( pipe_slow );
9265 %} 9381 %}
9266 9382
9383 instruct cmpXD_ccCF(eFlagsRegUCF cr, regXD dst, regXD src) %{
9384 predicate(UseSSE>=2);
9385 match(Set cr (CmpD dst src));
9386 ins_cost(100);
9387 format %{ "COMISD $dst,$src" %}
9388 opcode(0x66, 0x0F, 0x2F);
9389 ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
9390 ins_pipe( pipe_slow );
9391 %}
9392
9267 // float compare and set condition codes in EFLAGS by XMM regs 9393 // float compare and set condition codes in EFLAGS by XMM regs
9268 instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{ 9394 instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{
9269 predicate(UseSSE>=2); 9395 predicate(UseSSE>=2);
9270 match(Set cr (CmpD dst (LoadD src))); 9396 match(Set cr (CmpD dst (LoadD src)));
9271 effect(KILL rax); 9397 effect(KILL rax);
9275 "\tMOV ah,1 // saw a NaN, set CF\n" 9401 "\tMOV ah,1 // saw a NaN, set CF\n"
9276 "\tSAHF\n" 9402 "\tSAHF\n"
9277 "exit:\tNOP // avoid branch to branch" %} 9403 "exit:\tNOP // avoid branch to branch" %}
9278 opcode(0x66, 0x0F, 0x2F); 9404 opcode(0x66, 0x0F, 0x2F);
9279 ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src), cmpF_P6_fixup); 9405 ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src), cmpF_P6_fixup);
9406 ins_pipe( pipe_slow );
9407 %}
9408
9409 instruct cmpXD_ccmemCF(eFlagsRegUCF cr, regXD dst, memory src) %{
9410 predicate(UseSSE>=2);
9411 match(Set cr (CmpD dst (LoadD src)));
9412 ins_cost(100);
9413 format %{ "COMISD $dst,$src" %}
9414 opcode(0x66, 0x0F, 0x2F);
9415 ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src));
9280 ins_pipe( pipe_slow ); 9416 ins_pipe( pipe_slow );
9281 %} 9417 %}
9282 9418
9283 // Compare into -1,0,1 in XMM 9419 // Compare into -1,0,1 in XMM
9284 instruct cmpXD_reg(eRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{ 9420 instruct cmpXD_reg(eRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{
10165 OpcP, RegOpc(src2), 10301 OpcP, RegOpc(src2),
10166 cmpF_P6_fixup ); 10302 cmpF_P6_fixup );
10167 ins_pipe( pipe_slow ); 10303 ins_pipe( pipe_slow );
10168 %} 10304 %}
10169 10305
10306 instruct cmpF_cc_P6CF(eFlagsRegUCF cr, regF src1, regF src2) %{
10307 predicate(VM_Version::supports_cmov() && UseSSE == 0);
10308 match(Set cr (CmpF src1 src2));
10309 ins_cost(100);
10310 format %{ "FLD $src1\n\t"
10311 "FUCOMIP ST,$src2 // P6 instruction" %}
10312 opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
10313 ins_encode( Push_Reg_D(src1),
10314 OpcP, RegOpc(src2));
10315 ins_pipe( pipe_slow );
10316 %}
10317
10170 10318
10171 // Compare & branch 10319 // Compare & branch
10172 instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{ 10320 instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{
10173 predicate(UseSSE == 0); 10321 predicate(UseSSE == 0);
10174 match(Set cr (CmpF src1 src2)); 10322 match(Set cr (CmpF src1 src2));
10230 opcode(0x0F, 0x2F); 10378 opcode(0x0F, 0x2F);
10231 ins_encode(OpcP, OpcS, RegReg(dst, src), cmpF_P6_fixup); 10379 ins_encode(OpcP, OpcS, RegReg(dst, src), cmpF_P6_fixup);
10232 ins_pipe( pipe_slow ); 10380 ins_pipe( pipe_slow );
10233 %} 10381 %}
10234 10382
10383 instruct cmpX_ccCF(eFlagsRegUCF cr, regX dst, regX src) %{
10384 predicate(UseSSE>=1);
10385 match(Set cr (CmpF dst src));
10386 ins_cost(100);
10387 format %{ "COMISS $dst,$src" %}
10388 opcode(0x0F, 0x2F);
10389 ins_encode(OpcP, OpcS, RegReg(dst, src));
10390 ins_pipe( pipe_slow );
10391 %}
10392
10235 // float compare and set condition codes in EFLAGS by XMM regs 10393 // float compare and set condition codes in EFLAGS by XMM regs
10236 instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{ 10394 instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{
10237 predicate(UseSSE>=1); 10395 predicate(UseSSE>=1);
10238 match(Set cr (CmpF dst (LoadF src))); 10396 match(Set cr (CmpF dst (LoadF src)));
10239 effect(KILL rax); 10397 effect(KILL rax);
10243 "\tMOV ah,1 // saw a NaN, set CF\n" 10401 "\tMOV ah,1 // saw a NaN, set CF\n"
10244 "\tSAHF\n" 10402 "\tSAHF\n"
10245 "exit:\tNOP // avoid branch to branch" %} 10403 "exit:\tNOP // avoid branch to branch" %}
10246 opcode(0x0F, 0x2F); 10404 opcode(0x0F, 0x2F);
10247 ins_encode(OpcP, OpcS, RegMem(dst, src), cmpF_P6_fixup); 10405 ins_encode(OpcP, OpcS, RegMem(dst, src), cmpF_P6_fixup);
10406 ins_pipe( pipe_slow );
10407 %}
10408
10409 instruct cmpX_ccmemCF(eFlagsRegUCF cr, regX dst, memory src) %{
10410 predicate(UseSSE>=1);
10411 match(Set cr (CmpF dst (LoadF src)));
10412 ins_cost(100);
10413 format %{ "COMISS $dst,$src" %}
10414 opcode(0x0F, 0x2F);
10415 ins_encode(OpcP, OpcS, RegMem(dst, src));
10248 ins_pipe( pipe_slow ); 10416 ins_pipe( pipe_slow );
10249 %} 10417 %}
10250 10418
10251 // Compare into -1,0,1 in XMM 10419 // Compare into -1,0,1 in XMM
10252 instruct cmpX_reg(eRegI dst, regX src1, regX src2, eFlagsReg cr) %{ 10420 instruct cmpX_reg(eRegI dst, regX src1, regX src2, eFlagsReg cr) %{
12097 ins_encode( Jcc( cop, labl) ); 12265 ins_encode( Jcc( cop, labl) );
12098 ins_pipe( pipe_jcc ); 12266 ins_pipe( pipe_jcc );
12099 ins_pc_relative(1); 12267 ins_pc_relative(1);
12100 %} 12268 %}
12101 12269
12270 instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
12271 match(CountedLoopEnd cop cmp);
12272 effect(USE labl);
12273
12274 ins_cost(200);
12275 format %{ "J$cop,u $labl\t# Loop end" %}
12276 size(6);
12277 opcode(0x0F, 0x80);
12278 ins_encode( Jcc( cop, labl) );
12279 ins_pipe( pipe_jcc );
12280 ins_pc_relative(1);
12281 %}
12282
12102 // Jump Direct Conditional - using unsigned comparison 12283 // Jump Direct Conditional - using unsigned comparison
12103 instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{ 12284 instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
12104 match(If cop cmp); 12285 match(If cop cmp);
12105 effect(USE labl); 12286 effect(USE labl);
12106 12287
12107 ins_cost(300); 12288 ins_cost(300);
12108 format %{ "J$cop,u $labl" %} 12289 format %{ "J$cop,u $labl" %}
12109 size(6); 12290 size(6);
12110 opcode(0x0F, 0x80); 12291 opcode(0x0F, 0x80);
12111 ins_encode( Jcc( cop, labl) ); 12292 ins_encode(Jcc(cop, labl));
12112 ins_pipe( pipe_jcc ); 12293 ins_pipe(pipe_jcc);
12294 ins_pc_relative(1);
12295 %}
12296
12297 instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
12298 match(If cop cmp);
12299 effect(USE labl);
12300
12301 ins_cost(200);
12302 format %{ "J$cop,u $labl" %}
12303 size(6);
12304 opcode(0x0F, 0x80);
12305 ins_encode(Jcc(cop, labl));
12306 ins_pipe(pipe_jcc);
12307 ins_pc_relative(1);
12308 %}
12309
12310 instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
12311 match(If cop cmp);
12312 effect(USE labl);
12313
12314 ins_cost(200);
12315 format %{ $$template
12316 if ($cop$$cmpcode == Assembler::notEqual) {
12317 $$emit$$"JP,u $labl\n\t"
12318 $$emit$$"J$cop,u $labl"
12319 } else {
12320 $$emit$$"JP,u done\n\t"
12321 $$emit$$"J$cop,u $labl\n\t"
12322 $$emit$$"done:"
12323 }
12324 %}
12325 size(12);
12326 opcode(0x0F, 0x80);
12327 ins_encode %{
12328 Label* l = $labl$$label;
12329 $$$emit8$primary;
12330 emit_cc(cbuf, $secondary, Assembler::parity);
12331 int parity_disp = -1;
12332 bool ok = false;
12333 if ($cop$$cmpcode == Assembler::notEqual) {
12334 // the two jumps 6 bytes apart so the jump distances are too
12335 parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
12336 } else if ($cop$$cmpcode == Assembler::equal) {
12337 parity_disp = 6;
12338 ok = true;
12339 } else {
12340 ShouldNotReachHere();
12341 }
12342 emit_d32(cbuf, parity_disp);
12343 $$$emit8$primary;
12344 emit_cc(cbuf, $secondary, $cop$$cmpcode);
12345 int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
12346 emit_d32(cbuf, disp);
12347 %}
12348 ins_pipe(pipe_jcc);
12113 ins_pc_relative(1); 12349 ins_pc_relative(1);
12114 %} 12350 %}
12115 12351
12116 // ============================================================================ 12352 // ============================================================================
12117 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12353 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
12206 instruct jmpLoopEnd_short(cmpOp cop, eFlagsReg cr, label labl) %{ 12442 instruct jmpLoopEnd_short(cmpOp cop, eFlagsReg cr, label labl) %{
12207 match(CountedLoopEnd cop cr); 12443 match(CountedLoopEnd cop cr);
12208 effect(USE labl); 12444 effect(USE labl);
12209 12445
12210 ins_cost(300); 12446 ins_cost(300);
12211 format %{ "J$cop,s $labl" %} 12447 format %{ "J$cop,s $labl\t# Loop end" %}
12212 size(2); 12448 size(2);
12213 opcode(0x70); 12449 opcode(0x70);
12214 ins_encode( JccShort( cop, labl) ); 12450 ins_encode( JccShort( cop, labl) );
12215 ins_pipe( pipe_jcc ); 12451 ins_pipe( pipe_jcc );
12216 ins_pc_relative(1); 12452 ins_pc_relative(1);
12218 %} 12454 %}
12219 12455
12220 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12456 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12221 instruct jmpLoopEndU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{ 12457 instruct jmpLoopEndU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
12222 match(CountedLoopEnd cop cmp); 12458 match(CountedLoopEnd cop cmp);
12459 effect(USE labl);
12460
12461 ins_cost(300);
12462 format %{ "J$cop,us $labl\t# Loop end" %}
12463 size(2);
12464 opcode(0x70);
12465 ins_encode( JccShort( cop, labl) );
12466 ins_pipe( pipe_jcc );
12467 ins_pc_relative(1);
12468 ins_short_branch(1);
12469 %}
12470
12471 instruct jmpLoopEndUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
12472 match(CountedLoopEnd cop cmp);
12473 effect(USE labl);
12474
12475 ins_cost(300);
12476 format %{ "J$cop,us $labl\t# Loop end" %}
12477 size(2);
12478 opcode(0x70);
12479 ins_encode( JccShort( cop, labl) );
12480 ins_pipe( pipe_jcc );
12481 ins_pc_relative(1);
12482 ins_short_branch(1);
12483 %}
12484
12485 // Jump Direct Conditional - using unsigned comparison
12486 instruct jmpConU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
12487 match(If cop cmp);
12223 effect(USE labl); 12488 effect(USE labl);
12224 12489
12225 ins_cost(300); 12490 ins_cost(300);
12226 format %{ "J$cop,us $labl" %} 12491 format %{ "J$cop,us $labl" %}
12227 size(2); 12492 size(2);
12230 ins_pipe( pipe_jcc ); 12495 ins_pipe( pipe_jcc );
12231 ins_pc_relative(1); 12496 ins_pc_relative(1);
12232 ins_short_branch(1); 12497 ins_short_branch(1);
12233 %} 12498 %}
12234 12499
12235 // Jump Direct Conditional - using unsigned comparison 12500 instruct jmpConUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
12236 instruct jmpConU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
12237 match(If cop cmp); 12501 match(If cop cmp);
12238 effect(USE labl); 12502 effect(USE labl);
12239 12503
12240 ins_cost(300); 12504 ins_cost(300);
12241 format %{ "J$cop,us $labl" %} 12505 format %{ "J$cop,us $labl" %}
12242 size(2); 12506 size(2);
12243 opcode(0x70); 12507 opcode(0x70);
12244 ins_encode( JccShort( cop, labl) ); 12508 ins_encode( JccShort( cop, labl) );
12245 ins_pipe( pipe_jcc ); 12509 ins_pipe( pipe_jcc );
12510 ins_pc_relative(1);
12511 ins_short_branch(1);
12512 %}
12513
12514 instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
12515 match(If cop cmp);
12516 effect(USE labl);
12517
12518 ins_cost(300);
12519 format %{ $$template
12520 if ($cop$$cmpcode == Assembler::notEqual) {
12521 $$emit$$"JP,u,s $labl\n\t"
12522 $$emit$$"J$cop,u,s $labl"
12523 } else {
12524 $$emit$$"JP,u,s done\n\t"
12525 $$emit$$"J$cop,u,s $labl\n\t"
12526 $$emit$$"done:"
12527 }
12528 %}
12529 size(4);
12530 opcode(0x70);
12531 ins_encode %{
12532 Label* l = $labl$$label;
12533 emit_cc(cbuf, $primary, Assembler::parity);
12534 int parity_disp = -1;
12535 if ($cop$$cmpcode == Assembler::notEqual) {
12536 parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
12537 } else if ($cop$$cmpcode == Assembler::equal) {
12538 parity_disp = 2;
12539 } else {
12540 ShouldNotReachHere();
12541 }
12542 emit_d8(cbuf, parity_disp);
12543 emit_cc(cbuf, $primary, $cop$$cmpcode);
12544 int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
12545 emit_d8(cbuf, disp);
12546 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
12547 assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
12548 %}
12549 ins_pipe(pipe_jcc);
12246 ins_pc_relative(1); 12550 ins_pc_relative(1);
12247 ins_short_branch(1); 12551 ins_short_branch(1);
12248 %} 12552 %}
12249 12553
12250 // ============================================================================ 12554 // ============================================================================