< prev index next >

src/cpu/x86/vm/c1_LIRGenerator_x86.cpp

Print this page




 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::_dpow) {

 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::_dsin:
 825       case vmIntrinsics::_dcos:
 826       case vmIntrinsics::_dtan:
 827       case vmIntrinsics::_dlog10:
 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     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   CallingConvention* cc = NULL;
 893 
 894   if (x->id() == vmIntrinsics::_dpow) {


 906     BasicTypeList signature(1);
 907     signature.append(T_DOUBLE);
 908     cc = frame_map()->c_calling_convention(&signature);
 909     value.load_item_force(cc->at(0));
 910   }
 911 
 912 #ifndef _LP64
 913   LIR_Opr tmp = FrameMap::fpu0_double_opr;
 914   result_reg = tmp;
 915   switch(x->id()) {
 916     case vmIntrinsics::_dexp:
 917       if (VM_Version::supports_sse2()) {
 918         __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args());
 919       } else {
 920         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args());
 921       }
 922       break;
 923     case vmIntrinsics::_dlog:
 924       if (VM_Version::supports_sse2()) {
 925         __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args());
 926       }
 927       else {
 928         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args());
 929       }
 930       break;
 931     case vmIntrinsics::_dpow:
 932       if (VM_Version::supports_sse2()) {
 933         __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args());
 934       }
 935       else {
 936         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), getThreadTemp(), result_reg, cc->args());
 937       }
 938       break;














 939     default:  ShouldNotReachHere();
 940   }
 941 #else
 942   switch (x->id()) {
 943     case vmIntrinsics::_dexp:
 944       __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args());
 945       break;
 946     case vmIntrinsics::_dlog:
 947       __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args());
 948       break;
 949     case vmIntrinsics::_dpow:
 950       __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args());
 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
 971   // call)
 972 
 973 #ifndef _LP64




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


 825       case vmIntrinsics::_dtan:
 826       case vmIntrinsics::_dlog10:
 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     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   CallingConvention* cc = NULL;
 891 
 892   if (x->id() == vmIntrinsics::_dpow) {


 904     BasicTypeList signature(1);
 905     signature.append(T_DOUBLE);
 906     cc = frame_map()->c_calling_convention(&signature);
 907     value.load_item_force(cc->at(0));
 908   }
 909 
 910 #ifndef _LP64
 911   LIR_Opr tmp = FrameMap::fpu0_double_opr;
 912   result_reg = tmp;
 913   switch(x->id()) {
 914     case vmIntrinsics::_dexp:
 915       if (VM_Version::supports_sse2()) {
 916         __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args());
 917       } else {
 918         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args());
 919       }
 920       break;
 921     case vmIntrinsics::_dlog:
 922       if (VM_Version::supports_sse2()) {
 923         __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args());
 924       } else {

 925         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args());
 926       }
 927       break;
 928     case vmIntrinsics::_dpow:
 929       if (VM_Version::supports_sse2()) {
 930         __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args());
 931       } else {

 932         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), getThreadTemp(), result_reg, cc->args());
 933       }
 934       break;
 935     case vmIntrinsics::_dsin:
 936       if (VM_Version::supports_sse2() && StubRoutines::dsin() != NULL) {
 937         __ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args());
 938       } else {
 939         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), getThreadTemp(), result_reg, cc->args());
 940       }
 941       break;
 942     case vmIntrinsics::_dcos:
 943       if (VM_Version::supports_sse2() && StubRoutines::dcos() != NULL) {
 944         __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args());
 945       } else {
 946         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args());
 947       }
 948       break;
 949     default:  ShouldNotReachHere();
 950   }
 951 #else
 952   switch (x->id()) {
 953     case vmIntrinsics::_dexp:
 954       __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args());
 955       break;
 956     case vmIntrinsics::_dlog:
 957       __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args());
 958       break;
 959     case vmIntrinsics::_dpow:
 960       __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args());
 961       break;
 962     case vmIntrinsics::_dsin:
 963       if (StubRoutines::dsin() != NULL) {
 964         __ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args());
 965       } else {
 966         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), getThreadTemp(), result_reg, cc->args());
 967       }
 968       break;
 969     case vmIntrinsics::_dcos:
 970       if (StubRoutines::dcos() != NULL) {
 971         __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args());
 972       } else {
 973         __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args());
 974       }
 975       break;
 976     default:  ShouldNotReachHere();
 977   }
 978 #endif // _LP64
 979   __ move(result_reg, calc_result);
 980 }
 981 
 982 void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
 983   assert(x->number_of_arguments() == 5, "wrong type");
 984 
 985   // Make all state_for calls early since they can emit code
 986   CodeEmitInfo* info = state_for(x, x->state());
 987 
 988   LIRItem src(x->argument_at(0), this);
 989   LIRItem src_pos(x->argument_at(1), this);
 990   LIRItem dst(x->argument_at(2), this);
 991   LIRItem dst_pos(x->argument_at(3), this);
 992   LIRItem length(x->argument_at(4), this);
 993 
 994   // operands for arraycopy must use fixed registers, otherwise
 995   // LinearScan will fail allocation (because arraycopy always needs a
 996   // call)
 997 
 998 #ifndef _LP64


< prev index next >