diff --git a/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp b/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp index f522c7de66b..5f3a52ac90b 100644 --- a/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp +++ b/src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp @@ -2994,7 +2994,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { __ verify_oop(obj); if (tmp != obj) { + assert_different_registers(obj, tmp, SCR1, SCR2, mdo_addr.base(), mdo_addr.index()); __ move(tmp, obj); + } else { + assert_different_registers(obj, SCR1, SCR2, mdo_addr.base(), mdo_addr.index()); } if (do_null) { __ bnez(tmp, update); @@ -3053,10 +3056,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { __ beqz(SCR2, none); __ li(SCR1, (u1)TypeEntries::null_seen); __ beq(SCR2, SCR1, none); - // There is a chance that the checks above (re-reading profiling - // data from memory) fail if another thread has just set the + // There is a chance that the checks above + // fail if another thread has just set the // profiling to this obj's klass membar_acquire(); + __ XOR(tmp, tmp, SCR2); // get back original value before XOR __ ld_d(SCR2, mdo_addr); __ XOR(tmp, tmp, SCR2); assert(TypeEntries::type_klass_mask == -4, "must be"); @@ -3083,6 +3087,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { __ bind(none); // first time here. Set profile type. __ st_d(tmp, mdo_addr); +#ifdef ASSERT + assert(TypeEntries::type_mask == -2, "must be"); + __ bstrpick_d(tmp, tmp, 63, 1); + __ verify_klass_ptr(tmp); +#endif } } else { // There's a single possible klass at this profile point @@ -3116,6 +3125,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { #endif // first time here. Set profile type. __ st_d(tmp, mdo_addr); +#ifdef ASSERT + assert(TypeEntries::type_mask == -2, "must be"); + __ bstrpick_d(tmp, tmp, 63, 1); + __ verify_klass_ptr(tmp); +#endif } else { assert(ciTypeEntries::valid_ciklass(current_klass) != nullptr && ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent"); diff --git a/src/hotspot/cpu/loongarch/c1_Runtime1_loongarch_64.cpp b/src/hotspot/cpu/loongarch/c1_Runtime1_loongarch_64.cpp index aaef45bc4f1..21f7c6f2d00 100644 --- a/src/hotspot/cpu/loongarch/c1_Runtime1_loongarch_64.cpp +++ b/src/hotspot/cpu/loongarch/c1_Runtime1_loongarch_64.cpp @@ -471,6 +471,14 @@ void Runtime1::generate_unwind_exception(StubAssembler *sasm) { const Register exception_pc = A1; const Register handler_addr = A3; + if (AbortVMOnException) { + __ enter(); + save_live_registers(sasm); + __ call_VM_leaf(CAST_FROM_FN_PTR(address, check_abort_on_vm_exception), A0); + restore_live_registers(sasm); + __ leave(); + } + // verify that only A0, is valid at this time __ invalidate_registers(false, true, true, true, true, true); diff --git a/src/hotspot/cpu/loongarch/globalDefinitions_loongarch.hpp b/src/hotspot/cpu/loongarch/globalDefinitions_loongarch.hpp index 196d7057b0e..441882dcaa0 100644 --- a/src/hotspot/cpu/loongarch/globalDefinitions_loongarch.hpp +++ b/src/hotspot/cpu/loongarch/globalDefinitions_loongarch.hpp @@ -52,4 +52,6 @@ const bool CCallingConventionRequiresIntsAsLongs = false; #define USE_POINTERS_TO_REGISTER_IMPL_ARRAY +#define DEFAULT_CACHE_LINE_SIZE 64 + #endif // CPU_LOONGARCH_GLOBALDEFINITIONS_LOONGARCH_HPP diff --git a/src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp b/src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp index 6d505777c41..3790af7406c 100644 --- a/src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp +++ b/src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp @@ -1581,6 +1581,7 @@ void InterpreterMacroAssembler::narrow(Register result) { void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) { + assert_different_registers(obj, AT, T5, mdo_addr.base(), mdo_addr.index()); Label update, next, none; verify_oop(obj); @@ -1619,25 +1620,21 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md xorr(obj, obj, AT); assert(TypeEntries::type_klass_mask == -4, "must be"); - bstrpick_d(AT, obj, 63, 2); - beqz(AT, next); + bstrpick_d(T5, obj, 63, 2); + beqz(T5, next); - andi(AT, obj, TypeEntries::type_unknown); - bnez(AT, next); + andi(T5, obj, TypeEntries::type_unknown); + bnez(T5, next); - if (mdo_addr.index() == noreg) { - ld_d(AT, mdo_addr); - } else { - ld_d(AT, T0, mdo_addr.disp()); - } beqz(AT, none); - addi_d(AT, AT, -(TypeEntries::null_seen)); - beqz(AT, none); + addi_d(T5, AT, -(TypeEntries::null_seen)); + beqz(T5, none); - // There is a chance that the checks above (re-reading profiling - // data from memory) fail if another thread has just set the + // There is a chance that the checks above + // fail if another thread has just set the // profiling to this obj's klass + xorr(obj, obj, AT); // get back original value before XOR if (mdo_addr.index() == noreg) { ld_d(AT, mdo_addr); } else { @@ -1669,6 +1666,11 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md } else { st_d(obj, T0, mdo_addr.disp()); } +#ifdef ASSERT + assert(TypeEntries::type_mask == -2, "must be"); + bstrpick_d(obj, obj, 63, 1); + verify_klass_ptr(obj); +#endif bind(next); if (mdo_addr.index() != noreg) { diff --git a/src/hotspot/cpu/loongarch/loongarch_64.ad b/src/hotspot/cpu/loongarch/loongarch_64.ad index 89df7f869c4..366df18eb9c 100644 --- a/src/hotspot/cpu/loongarch/loongarch_64.ad +++ b/src/hotspot/cpu/loongarch/loongarch_64.ad @@ -4347,7 +4347,8 @@ opclass memory_loadRange(indOffset12, indirect); opclass memory_exclusive(indOffset16, indirect); opclass mRegLorI2L(mRegI2L, mRegL); -opclass mRegIorL2I( mRegI, mRegL2I); +opclass mRegIorL2I(mRegI, mRegL2I); +opclass mRegLorP(mRegL, mRegP); //----------PIPELINE----------------------------------------------------------- // Rules which define the behavior of the target architectures pipeline. @@ -8289,6 +8290,26 @@ instruct cmovD_cmpD_reg_reg(regD dst, regD src, regD tmp1, regD tmp2, cmpOp cop ins_pipe( pipe_slow ); %} +instruct cmovD_cmpF_reg_reg(regD dst, regD src, regF tmp1, regF tmp2, cmpOp cop ) %{ + match(Set dst (CMoveD (Binary cop (CmpF tmp1 tmp2)) (Binary dst src))); + ins_cost(200); + format %{ + "CMP$cop $tmp1, $tmp2\t @cmovD_cmpF_reg_reg\n" + "\tCMOV $dst,$src \t @cmovD_cmpF_reg_reg" + %} + ins_encode %{ + FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg); + FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg); + FloatRegister dst = as_FloatRegister($dst$$reg); + FloatRegister src = as_FloatRegister($src$$reg); + int flag = $cop$$cmpcode; + + __ cmp_cmov(reg_op1, reg_op2, dst, src, (MacroAssembler::CMCompare) flag, true /* is_float */); + %} + + ins_pipe( pipe_slow ); +%} + instruct cmovF_cmpI_reg_reg(regF dst, regF src, mRegI tmp1, mRegI tmp2, cmpOp cop) %{ match(Set dst (CMoveF (Binary cop (CmpI tmp1 tmp2)) (Binary dst src))); ins_cost(200); @@ -8331,6 +8352,27 @@ instruct cmovD_cmpN_reg_reg(regD dst, regD src, mRegN tmp1, mRegN tmp2, cmpOp co ins_pipe( pipe_slow ); %} +instruct cmovF_cmpL_reg_reg(regF dst, regF src, mRegL tmp1, mRegL tmp2, cmpOp cop) %{ + match(Set dst (CMoveF (Binary cop (CmpL tmp1 tmp2)) (Binary dst src))); + ins_cost(200); + format %{ + "CMP$cop $tmp1, $tmp2\t @cmovF_cmpL_reg_reg\n" + "\tCMOV $dst, $src \t @cmovF_cmpL_reg_reg" + %} + + ins_encode %{ + Register op1 = $tmp1$$Register; + Register op2 = $tmp2$$Register; + FloatRegister dst = as_FloatRegister($dst$$reg); + FloatRegister src = as_FloatRegister($src$$reg); + int flag = $cop$$cmpcode; + + __ cmp_cmov(op1, op2, dst, src, (MacroAssembler::CMCompare) flag); + %} + + ins_pipe( pipe_slow ); +%} + instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp cop) %{ match(Set dst (CMoveD (Binary cop (CmpI tmp1 tmp2)) (Binary dst src))); ins_cost(200); @@ -8352,12 +8394,13 @@ instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp co ins_pipe( pipe_slow ); %} -instruct cmovD_cmpP_reg_reg(regD dst, regD src, mRegP tmp1, mRegP tmp2, cmpOp cop) %{ +instruct cmovD_cmpLorP_reg_reg(regD dst, regD src, mRegLorP tmp1, mRegLorP tmp2, cmpOp cop) %{ match(Set dst (CMoveD (Binary cop (CmpP tmp1 tmp2)) (Binary dst src))); + match(Set dst (CMoveD (Binary cop (CmpL tmp1 tmp2)) (Binary dst src))); ins_cost(200); format %{ - "CMP$cop $tmp1, $tmp2\t @cmovD_cmpP_reg_reg\n" - "\tCMOV $dst, $src \t @cmovD_cmpP_reg_reg" + "CMP$cop $tmp1, $tmp2\t @cmovD_cmpLorP_reg_reg\n" + "\tCMOV $dst, $src \t @cmovD_cmpLorP_reg_reg" %} ins_encode %{ @@ -8419,6 +8462,26 @@ instruct cmovF_cmpF_reg_reg(regF dst, regF src, regF tmp1, regF tmp2, cmpOp cop ins_pipe( pipe_slow ); %} +instruct cmovF_cmpD_reg_reg(regF dst, regF src, regD tmp1, regD tmp2, cmpOp cop ) %{ + match(Set dst (CMoveF (Binary cop (CmpD tmp1 tmp2)) (Binary dst src))); + ins_cost(200); + format %{ + "CMP$cop $tmp1, $tmp2\t @cmovF_cmpD_reg_reg\n" + "\tCMOV $dst,$src \t @cmovF_cmpD_reg_reg" + %} + + ins_encode %{ + FloatRegister reg_op1 = $tmp1$$FloatRegister; + FloatRegister reg_op2 = $tmp2$$FloatRegister; + FloatRegister dst = $dst$$FloatRegister; + FloatRegister src = $src$$FloatRegister; + int flag = $cop$$cmpcode; + + __ cmp_cmov(reg_op1, reg_op2, dst, src, (MacroAssembler::CMCompare) flag, false /* is_float */); + %} + ins_pipe( pipe_slow ); +%} + // Manifest a CmpL result in an integer register. Very painful. // This is the test to avoid. instruct cmpL3_reg_zero(mRegI dst, mRegL src1, immL_0 zero) %{