791 __ cas_int(addr, cmp.result(), val.result(), ill, ill);
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 LIRItem value(x->argument_at(0), this);
812
813 bool use_fpu = false;
814 if (UseSSE >= 2) {
815 switch(x->id()) {
816 case vmIntrinsics::_dsin:
817 case vmIntrinsics::_dcos:
818 case vmIntrinsics::_dtan:
819 case vmIntrinsics::_dlog:
820 case vmIntrinsics::_dlog10:
821 case vmIntrinsics::_dexp:
822 case vmIntrinsics::_dpow:
823 use_fpu = true;
824 }
825 } else {
826 value.set_destroys_register();
827 }
828
829 value.load_item();
830
831 LIR_Opr calc_input = value.result();
832 LIR_Opr calc_input2 = NULL;
833 if (x->id() == vmIntrinsics::_dpow) {
834 LIRItem extra_arg(x->argument_at(1), this);
835 if (UseSSE < 2) {
836 extra_arg.set_destroys_register();
837 }
838 extra_arg.load_item();
839 calc_input2 = extra_arg.result();
840 }
841 LIR_Opr calc_result = rlock_result(x);
853 tmp_start = 2;
854 calc_input2 = tmp;
855 }
856 __ move(calc_input, tmp);
857
858 calc_input = tmp;
859 calc_result = tmp;
860
861 tmp1 = FrameMap::caller_save_fpu_reg_at(tmp_start);
862 tmp2 = FrameMap::caller_save_fpu_reg_at(tmp_start + 1);
863 }
864
865 switch(x->id()) {
866 case vmIntrinsics::_dabs: __ abs (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
867 case vmIntrinsics::_dsqrt: __ sqrt (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
868 case vmIntrinsics::_dsin: __ sin (calc_input, calc_result, tmp1, tmp2); break;
869 case vmIntrinsics::_dcos: __ cos (calc_input, calc_result, tmp1, tmp2); break;
870 case vmIntrinsics::_dtan: __ tan (calc_input, calc_result, tmp1, tmp2); break;
871 case vmIntrinsics::_dlog: __ log (calc_input, calc_result, tmp1); break;
872 case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break;
873 case vmIntrinsics::_dexp: __ exp (calc_input, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); 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
884 void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
885 assert(x->number_of_arguments() == 5, "wrong type");
886
887 // Make all state_for calls early since they can emit code
888 CodeEmitInfo* info = state_for(x, x->state());
889
890 LIRItem src(x->argument_at(0), this);
891 LIRItem src_pos(x->argument_at(1), this);
892 LIRItem dst(x->argument_at(2), this);
893 LIRItem dst_pos(x->argument_at(3), this);
894 LIRItem length(x->argument_at(4), this);
895
896 // operands for arraycopy must use fixed registers, otherwise
897 // LinearScan will fail allocation (because arraycopy always needs a
898 // call)
899
900 #ifndef _LP64
901 src.load_item_force (FrameMap::rcx_oop_opr);
902 src_pos.load_item_force (FrameMap::rdx_opr);
|
791 __ cas_int(addr, cmp.result(), val.result(), ill, ill);
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 }
846 LIR_Opr calc_result = rlock_result(x);
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
930 #ifndef _LP64
931 src.load_item_force (FrameMap::rcx_oop_opr);
932 src_pos.load_item_force (FrameMap::rdx_opr);
|