< prev index next >

src/cpu/x86/vm/c1_LIRGenerator_x86.cpp

Print this page




 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   }
 845   LIR_Opr calc_result = rlock_result(x);
 846 
 847   // sin, cos, pow and exp need two free fpu stack slots, so register


 852   if (use_fpu) {
 853     LIR_Opr tmp = FrameMap::fpu0_double_opr;
 854     int tmp_start = 1;
 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




 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       x->id() == vmIntrinsics::_dcos || x->id() == vmIntrinsics::_dsin) {
 814     do_LibmIntrinsic(x);
 815     return;
 816   }
 817 
 818   LIRItem value(x->argument_at(0), this);
 819 
 820   bool use_fpu = false;
 821   if (UseSSE >= 2) {
 822     switch (x->id()) {


 823       case vmIntrinsics::_dtan:
 824       case vmIntrinsics::_dlog10:
 825       case vmIntrinsics::_dpow:
 826         use_fpu = true;
 827         break;
 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   }
 845   LIR_Opr calc_result = rlock_result(x);
 846 
 847   // sin, cos, pow and exp need two free fpu stack slots, so register


 852   if (use_fpu) {
 853     LIR_Opr tmp = FrameMap::fpu0_double_opr;
 854     int tmp_start = 1;
 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::_dtan:   __ tan  (calc_input, calc_result, tmp1, tmp2);              break;
 873     case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1);                    break;
 874     case vmIntrinsics::_dpow:   __ pow  (calc_input, calc_input2, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break;
 875     default:                    ShouldNotReachHere();
 876   }
 877 
 878   if (use_fpu) {
 879     __ move(calc_result, x->operand());
 880   }
 881 }
 882 
 883 void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) {
 884   LIRItem value(x->argument_at(0), this);
 885   value.set_destroys_register();
 886 
 887   LIR_Opr calc_result = rlock_result(x);
 888   LIR_Opr result_reg = result_register_for(x->type());
 889 
 890   BasicTypeList signature(1);
 891   signature.append(T_DOUBLE);
 892   CallingConvention* cc = frame_map()->c_calling_convention(&signature);
 893 
 894   value.load_item_force(cc->at(0));
 895 
 896 #ifndef _LP64
 897   LIR_Opr tmp = FrameMap::fpu0_double_opr;
 898   result_reg = tmp;
 899   switch(x->id()) {
 900     case vmIntrinsics::_dexp:
 901       if (VM_Version::supports_sse2()) {
 902         __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args());
 903       } else {
 904         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args());
 905       }
 906       break;
 907     case vmIntrinsics::_dlog:
 908       if (VM_Version::supports_sse2()) {
 909         __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args());
 910       } else {

 911         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args());
 912       }
 913       break;
 914     case vmIntrinsics::_dsin:
 915       if (VM_Version::supports_sse2() && StubRoutines::dsin() != NULL) {
 916         __ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args());
 917       } else {
 918         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), getThreadTemp(), result_reg, cc->args());
 919       }
 920       break;
 921     case vmIntrinsics::_dcos:
 922       if (VM_Version::supports_sse2() && StubRoutines::dcos() != NULL) {
 923         __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args());
 924       } else {
 925         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args());
 926       }
 927       break;
 928     default:  ShouldNotReachHere();
 929   }
 930 #else
 931   switch (x->id()) {
 932     case vmIntrinsics::_dexp:
 933       __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args());
 934       break;
 935     case vmIntrinsics::_dlog:
 936       __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args());
 937       break;
 938     case vmIntrinsics::_dsin:
 939       if (StubRoutines::dsin() != NULL) {
 940         __ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args());
 941       } else {
 942         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), getThreadTemp(), result_reg, cc->args());
 943       }
 944       break;
 945     case vmIntrinsics::_dcos:
 946       if (StubRoutines::dcos() != NULL) {
 947         __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args());
 948       } else {
 949         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args());
 950       }
 951       break;
 952   }
 953 #endif
 954   __ move(result_reg, calc_result);
 955 }
 956 
 957 void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
 958   assert(x->number_of_arguments() == 5, "wrong type");
 959 
 960   // Make all state_for calls early since they can emit code
 961   CodeEmitInfo* info = state_for(x, x->state());
 962 
 963   LIRItem src(x->argument_at(0), this);
 964   LIRItem src_pos(x->argument_at(1), this);
 965   LIRItem dst(x->argument_at(2), this);
 966   LIRItem dst_pos(x->argument_at(3), this);
 967   LIRItem length(x->argument_at(4), this);
 968 
 969   // operands for arraycopy must use fixed registers, otherwise
 970   // LinearScan will fail allocation (because arraycopy always needs a


< prev index next >