792 else if (type == longType) 793 __ cas_long(addr, cmp.result(), val.result(), ill, ill); 794 else { 795 ShouldNotReachHere(); 796 } 797 798 // generate conditional move of boolean result 799 LIR_Opr result = rlock_result(x); 800 __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), 801 result, as_BasicType(type)); 802 if (type == objectType) { // Write-barrier needed for Object fields. 803 // Seems to be precise 804 post_barrier(addr, val.result()); 805 } 806 } 807 808 809 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { 810 assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type"); 811 812 if (x->id() == vmIntrinsics::_dexp) { 813 do_ExpIntrinsic(x); 814 return; 815 } 816 817 LIRItem value(x->argument_at(0), this); 818 819 bool use_fpu = false; 820 if (UseSSE >= 2) { 821 switch(x->id()) { 822 case vmIntrinsics::_dsin: 823 case vmIntrinsics::_dcos: 824 case vmIntrinsics::_dtan: 825 case vmIntrinsics::_dlog: 826 case vmIntrinsics::_dlog10: 827 case vmIntrinsics::_dpow: 828 use_fpu = true; 829 } 830 } else { 831 value.set_destroys_register(); 832 } 833 834 value.load_item(); 835 836 LIR_Opr calc_input = value.result(); 837 LIR_Opr calc_input2 = NULL; 838 if (x->id() == vmIntrinsics::_dpow) { 839 LIRItem extra_arg(x->argument_at(1), this); 840 if (UseSSE < 2) { 841 extra_arg.set_destroys_register(); 842 } 843 extra_arg.load_item(); 844 calc_input2 = extra_arg.result(); 845 } 856 if (calc_input2 != NULL) { 857 __ move(calc_input2, tmp); 858 tmp_start = 2; 859 calc_input2 = tmp; 860 } 861 __ move(calc_input, tmp); 862 863 calc_input = tmp; 864 calc_result = tmp; 865 866 tmp1 = FrameMap::caller_save_fpu_reg_at(tmp_start); 867 tmp2 = FrameMap::caller_save_fpu_reg_at(tmp_start + 1); 868 } 869 870 switch(x->id()) { 871 case vmIntrinsics::_dabs: __ abs (calc_input, calc_result, LIR_OprFact::illegalOpr); break; 872 case vmIntrinsics::_dsqrt: __ sqrt (calc_input, calc_result, LIR_OprFact::illegalOpr); break; 873 case vmIntrinsics::_dsin: __ sin (calc_input, calc_result, tmp1, tmp2); break; 874 case vmIntrinsics::_dcos: __ cos (calc_input, calc_result, tmp1, tmp2); break; 875 case vmIntrinsics::_dtan: __ tan (calc_input, calc_result, tmp1, tmp2); break; 876 case vmIntrinsics::_dlog: __ log (calc_input, calc_result, tmp1); break; 877 case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break; 878 case vmIntrinsics::_dpow: __ pow (calc_input, calc_input2, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break; 879 default: ShouldNotReachHere(); 880 } 881 882 if (use_fpu) { 883 __ move(calc_result, x->operand()); 884 } 885 } 886 887 void LIRGenerator::do_ExpIntrinsic(Intrinsic* x) { 888 LIRItem value(x->argument_at(0), this); 889 value.set_destroys_register(); 890 891 LIR_Opr calc_result = rlock_result(x); 892 LIR_Opr result_reg = result_register_for(x->type()); 893 894 BasicTypeList signature(1); 895 signature.append(T_DOUBLE); 896 CallingConvention* cc = frame_map()->c_calling_convention(&signature); 897 898 value.load_item_force(cc->at(0)); 899 900 #ifndef _LP64 901 LIR_Opr tmp = FrameMap::fpu0_double_opr; 902 result_reg = tmp; 903 if (VM_Version::supports_sse2()) { 904 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); 905 } else { 906 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args()); 907 } 908 #else 909 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); 910 #endif 911 __ move(result_reg, calc_result); 912 } 913 914 void LIRGenerator::do_ArrayCopy(Intrinsic* x) { 915 assert(x->number_of_arguments() == 5, "wrong type"); 916 917 // Make all state_for calls early since they can emit code 918 CodeEmitInfo* info = state_for(x, x->state()); 919 920 LIRItem src(x->argument_at(0), this); 921 LIRItem src_pos(x->argument_at(1), this); 922 LIRItem dst(x->argument_at(2), this); 923 LIRItem dst_pos(x->argument_at(3), this); 924 LIRItem length(x->argument_at(4), this); 925 926 // operands for arraycopy must use fixed registers, otherwise 927 // LinearScan will fail allocation (because arraycopy always needs a 928 // call) 929 | 792 else if (type == longType) 793 __ cas_long(addr, cmp.result(), val.result(), ill, ill); 794 else { 795 ShouldNotReachHere(); 796 } 797 798 // generate conditional move of boolean result 799 LIR_Opr result = rlock_result(x); 800 __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), 801 result, as_BasicType(type)); 802 if (type == objectType) { // Write-barrier needed for Object fields. 803 // Seems to be precise 804 post_barrier(addr, val.result()); 805 } 806 } 807 808 809 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { 810 assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type"); 811 812 if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog) { 813 do_LibmIntrinsic(x); 814 return; 815 } 816 817 LIRItem value(x->argument_at(0), this); 818 819 bool use_fpu = false; 820 if (UseSSE >= 2) { 821 switch(x->id()) { 822 case vmIntrinsics::_dsin: 823 case vmIntrinsics::_dcos: 824 case vmIntrinsics::_dtan: 825 case vmIntrinsics::_dlog10: 826 case vmIntrinsics::_dpow: 827 use_fpu = true; 828 } 829 } else { 830 value.set_destroys_register(); 831 } 832 833 value.load_item(); 834 835 LIR_Opr calc_input = value.result(); 836 LIR_Opr calc_input2 = NULL; 837 if (x->id() == vmIntrinsics::_dpow) { 838 LIRItem extra_arg(x->argument_at(1), this); 839 if (UseSSE < 2) { 840 extra_arg.set_destroys_register(); 841 } 842 extra_arg.load_item(); 843 calc_input2 = extra_arg.result(); 844 } 855 if (calc_input2 != NULL) { 856 __ move(calc_input2, tmp); 857 tmp_start = 2; 858 calc_input2 = tmp; 859 } 860 __ move(calc_input, tmp); 861 862 calc_input = tmp; 863 calc_result = tmp; 864 865 tmp1 = FrameMap::caller_save_fpu_reg_at(tmp_start); 866 tmp2 = FrameMap::caller_save_fpu_reg_at(tmp_start + 1); 867 } 868 869 switch(x->id()) { 870 case vmIntrinsics::_dabs: __ abs (calc_input, calc_result, LIR_OprFact::illegalOpr); break; 871 case vmIntrinsics::_dsqrt: __ sqrt (calc_input, calc_result, LIR_OprFact::illegalOpr); break; 872 case vmIntrinsics::_dsin: __ sin (calc_input, calc_result, tmp1, tmp2); break; 873 case vmIntrinsics::_dcos: __ cos (calc_input, calc_result, tmp1, tmp2); break; 874 case vmIntrinsics::_dtan: __ tan (calc_input, calc_result, tmp1, tmp2); break; 875 case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break; 876 case vmIntrinsics::_dpow: __ pow (calc_input, calc_input2, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break; 877 default: ShouldNotReachHere(); 878 } 879 880 if (use_fpu) { 881 __ move(calc_result, x->operand()); 882 } 883 } 884 885 void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) { 886 LIRItem value(x->argument_at(0), this); 887 value.set_destroys_register(); 888 889 LIR_Opr calc_result = rlock_result(x); 890 LIR_Opr result_reg = result_register_for(x->type()); 891 892 BasicTypeList signature(1); 893 signature.append(T_DOUBLE); 894 CallingConvention* cc = frame_map()->c_calling_convention(&signature); 895 896 value.load_item_force(cc->at(0)); 897 898 #ifndef _LP64 899 LIR_Opr tmp = FrameMap::fpu0_double_opr; 900 result_reg = tmp; 901 switch(x->id()) { 902 case vmIntrinsics::_dexp: 903 if (VM_Version::supports_sse2()) { 904 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); 905 } else { 906 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args()); 907 } 908 break; 909 case vmIntrinsics::_dlog: 910 if (VM_Version::supports_sse2()) { 911 __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args()); 912 } 913 else { 914 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args()); 915 } 916 break; 917 default: ShouldNotReachHere(); 918 } 919 #else 920 switch (x->id()) { 921 case vmIntrinsics::_dexp: 922 __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args()); 923 break; 924 case vmIntrinsics::_dlog: 925 __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args()); 926 break; 927 } 928 #endif 929 __ move(result_reg, calc_result); 930 } 931 932 void LIRGenerator::do_ArrayCopy(Intrinsic* x) { 933 assert(x->number_of_arguments() == 5, "wrong type"); 934 935 // Make all state_for calls early since they can emit code 936 CodeEmitInfo* info = state_for(x, x->state()); 937 938 LIRItem src(x->argument_at(0), this); 939 LIRItem src_pos(x->argument_at(1), this); 940 LIRItem dst(x->argument_at(2), this); 941 LIRItem dst_pos(x->argument_at(3), this); 942 LIRItem length(x->argument_at(4), this); 943 944 // operands for arraycopy must use fixed registers, otherwise 945 // LinearScan will fail allocation (because arraycopy always needs a 946 // call) 947 |