806 else if (type == intType)
807 __ cas_int(addr, cmp.result(), val.result(), ill, ill);
808 else if (type == longType)
809 __ cas_long(addr, cmp.result(), val.result(), ill, ill);
810 else {
811 ShouldNotReachHere();
812 }
813
814 // generate conditional move of boolean result
815 LIR_Opr result = rlock_result(x);
816 __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
817 result, as_BasicType(type));
818 if (type == objectType) { // Write-barrier needed for Object fields.
819 // Seems to be precise
820 post_barrier(addr, val.result());
821 }
822 }
823
824
825 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
826 assert(x->number_of_arguments() == 1, "wrong type");
827 LIRItem value(x->argument_at(0), this);
828
829 bool use_fpu = false;
830 if (UseSSE >= 2) {
831 switch(x->id()) {
832 case vmIntrinsics::_dsin:
833 case vmIntrinsics::_dcos:
834 case vmIntrinsics::_dtan:
835 case vmIntrinsics::_dlog:
836 case vmIntrinsics::_dlog10:
837 use_fpu = true;
838 }
839 } else {
840 value.set_destroys_register();
841 }
842
843 value.load_item();
844
845 LIR_Opr calc_input = value.result();
846 LIR_Opr calc_result = rlock_result(x);
847
848 // sin and cos need two free fpu stack slots, so register two temporary operands
849 LIR_Opr tmp1 = FrameMap::caller_save_fpu_reg_at(0);
850 LIR_Opr tmp2 = FrameMap::caller_save_fpu_reg_at(1);
851
852 if (use_fpu) {
853 LIR_Opr tmp = FrameMap::fpu0_double_opr;
854 __ move(calc_input, tmp);
855
856 calc_input = tmp;
857 calc_result = tmp;
858 tmp1 = FrameMap::caller_save_fpu_reg_at(1);
859 tmp2 = FrameMap::caller_save_fpu_reg_at(2);
860 }
861
862 switch(x->id()) {
863 case vmIntrinsics::_dabs: __ abs (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
864 case vmIntrinsics::_dsqrt: __ sqrt (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
865 case vmIntrinsics::_dsin: __ sin (calc_input, calc_result, tmp1, tmp2); break;
866 case vmIntrinsics::_dcos: __ cos (calc_input, calc_result, tmp1, tmp2); break;
867 case vmIntrinsics::_dtan: __ tan (calc_input, calc_result, tmp1, tmp2); break;
868 case vmIntrinsics::_dlog: __ log (calc_input, calc_result, tmp1); break;
869 case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break;
870 default: ShouldNotReachHere();
871 }
872
873 if (use_fpu) {
874 __ move(calc_result, x->operand());
875 }
876 }
877
878
879 void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
880 assert(x->number_of_arguments() == 5, "wrong type");
881
882 // Make all state_for calls early since they can emit code
883 CodeEmitInfo* info = state_for(x, x->state());
884
885 LIRItem src(x->argument_at(0), this);
886 LIRItem src_pos(x->argument_at(1), this);
887 LIRItem dst(x->argument_at(2), this);
888 LIRItem dst_pos(x->argument_at(3), this);
889 LIRItem length(x->argument_at(4), this);
|
806 else if (type == intType)
807 __ cas_int(addr, cmp.result(), val.result(), ill, ill);
808 else if (type == longType)
809 __ cas_long(addr, cmp.result(), val.result(), ill, ill);
810 else {
811 ShouldNotReachHere();
812 }
813
814 // generate conditional move of boolean result
815 LIR_Opr result = rlock_result(x);
816 __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
817 result, as_BasicType(type));
818 if (type == objectType) { // Write-barrier needed for Object fields.
819 // Seems to be precise
820 post_barrier(addr, val.result());
821 }
822 }
823
824
825 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
826 assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type");
827 LIRItem value(x->argument_at(0), this);
828
829 bool use_fpu = false;
830 if (UseSSE >= 2) {
831 switch(x->id()) {
832 case vmIntrinsics::_dsin:
833 case vmIntrinsics::_dcos:
834 case vmIntrinsics::_dtan:
835 case vmIntrinsics::_dlog:
836 case vmIntrinsics::_dlog10:
837 case vmIntrinsics::_dexp:
838 case vmIntrinsics::_dpow:
839 use_fpu = true;
840 }
841 } else {
842 value.set_destroys_register();
843 }
844
845 value.load_item();
846
847 LIR_Opr calc_input = value.result();
848 LIR_Opr calc_input2 = NULL;
849 if (x->id() == vmIntrinsics::_dpow) {
850 LIRItem extra_arg(x->argument_at(1), this);
851 calc_input2 = extra_arg.result();
852 }
853 LIR_Opr calc_result = rlock_result(x);
854
855 // sin, cos, pow and exp need two free fpu stack slots, so register
856 // two temporary operands
857 LIR_Opr tmp1 = FrameMap::caller_save_fpu_reg_at(0);
858 LIR_Opr tmp2 = FrameMap::caller_save_fpu_reg_at(1);
859
860 if (use_fpu) {
861 LIR_Opr tmp = FrameMap::fpu0_double_opr;
862 int tmp_start = 1;
863 if (calc_input2 != NULL) {
864 __ move(calc_input2, tmp);
865 tmp_start = 2;
866 calc_input2 = tmp;
867 }
868 __ move(calc_input, tmp);
869
870 calc_input = tmp;
871 calc_result = tmp;
872
873 tmp1 = FrameMap::caller_save_fpu_reg_at(tmp_start);
874 tmp2 = FrameMap::caller_save_fpu_reg_at(tmp_start + 1);
875 }
876
877 switch(x->id()) {
878 case vmIntrinsics::_dabs: __ abs (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
879 case vmIntrinsics::_dsqrt: __ sqrt (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
880 case vmIntrinsics::_dsin: __ sin (calc_input, calc_result, tmp1, tmp2); break;
881 case vmIntrinsics::_dcos: __ cos (calc_input, calc_result, tmp1, tmp2); break;
882 case vmIntrinsics::_dtan: __ tan (calc_input, calc_result, tmp1, tmp2); break;
883 case vmIntrinsics::_dlog: __ log (calc_input, calc_result, tmp1); break;
884 case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break;
885 case vmIntrinsics::_dexp: __ exp (calc_input, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break;
886 case vmIntrinsics::_dpow: __ pow (calc_input, calc_input2, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break;
887 default: ShouldNotReachHere();
888 }
889
890 if (use_fpu) {
891 __ move(calc_result, x->operand());
892 }
893 }
894
895
896 void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
897 assert(x->number_of_arguments() == 5, "wrong type");
898
899 // Make all state_for calls early since they can emit code
900 CodeEmitInfo* info = state_for(x, x->state());
901
902 LIRItem src(x->argument_at(0), this);
903 LIRItem src_pos(x->argument_at(1), this);
904 LIRItem dst(x->argument_at(2), this);
905 LIRItem dst_pos(x->argument_at(3), this);
906 LIRItem length(x->argument_at(4), this);
|