< prev index next >

src/cpu/x86/vm/c1_LIRGenerator_x86.cpp

Print this page




 793   else if (type == longType)
 794     __ cas_long(addr, cmp.result(), val.result(), ill, ill);
 795   else {
 796     ShouldNotReachHere();
 797   }
 798 
 799   // generate conditional move of boolean result
 800   LIR_Opr result = rlock_result(x);
 801   __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
 802            result, as_BasicType(type));
 803   if (type == objectType) {   // Write-barrier needed for Object fields.
 804     // Seems to be precise
 805     post_barrier(addr, val.result());
 806   }
 807 }
 808 
 809 
 810 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
 811   assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type");
 812 
 813   if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog) {

 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::_dsin:
 824       case vmIntrinsics::_dcos:
 825       case vmIntrinsics::_dtan:
 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   }
 846   LIR_Opr calc_result = rlock_result(x);
 847 
 848   // sin, cos, pow and exp need two free fpu stack slots, so register


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














 918     default:  ShouldNotReachHere();
 919   }
 920 #else
 921   switch (x->id()) {
 922     case vmIntrinsics::_dexp:
 923       __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args());
 924       break;
 925     case vmIntrinsics::_dlog:
 926       __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args());














 927       break;
 928   }
 929 #endif
 930   __ move(result_reg, calc_result);
 931 }
 932 
 933 void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
 934   assert(x->number_of_arguments() == 5, "wrong type");
 935 
 936   // Make all state_for calls early since they can emit code
 937   CodeEmitInfo* info = state_for(x, x->state());
 938 
 939   LIRItem src(x->argument_at(0), this);
 940   LIRItem src_pos(x->argument_at(1), this);
 941   LIRItem dst(x->argument_at(2), this);
 942   LIRItem dst_pos(x->argument_at(3), this);
 943   LIRItem length(x->argument_at(4), this);
 944 
 945   // operands for arraycopy must use fixed registers, otherwise
 946   // LinearScan will fail allocation (because arraycopy always needs a




 793   else if (type == longType)
 794     __ cas_long(addr, cmp.result(), val.result(), ill, ill);
 795   else {
 796     ShouldNotReachHere();
 797   }
 798 
 799   // generate conditional move of boolean result
 800   LIR_Opr result = rlock_result(x);
 801   __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
 802            result, as_BasicType(type));
 803   if (type == objectType) {   // Write-barrier needed for Object fields.
 804     // Seems to be precise
 805     post_barrier(addr, val.result());
 806   }
 807 }
 808 
 809 
 810 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
 811   assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type");
 812 
 813   if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog ||
 814       x->id() == vmIntrinsics::_dcos || x->id() == vmIntrinsics::_dsin) {
 815     do_LibmIntrinsic(x);
 816     return;
 817   }
 818 
 819   LIRItem value(x->argument_at(0), this);
 820 
 821   bool use_fpu = false;
 822   if (UseSSE >= 2) {
 823     switch (x->id()) {


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


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

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


< prev index next >