diff --git a/test/hotspot/gtest/riscv/test_assembler_riscv.cpp b/test/hotspot/gtest/riscv/test_assembler_riscv.cpp index f0fda98c1bb91..368cda5459b5e 100644 --- a/test/hotspot/gtest/riscv/test_assembler_riscv.cpp +++ b/test/hotspot/gtest/riscv/test_assembler_riscv.cpp @@ -106,23 +106,47 @@ TEST_VM(RiscV, cmov) { } } - template class CmpxchgTester { public: typedef TESTSIZE (*cmpxchg_func)(intptr_t addr, TESTSIZE expected, TESTSIZE new_value, TESTSIZE result); - typedef TESTSIZE (*cmpxchg_func_spec)(intptr_t addr, TESTSIZE expected, TESTSIZE new_value); - static TESTSIZE simple_cmpxchg(intptr_t addr, TESTSIZE expected, TESTSIZE new_value, TESTSIZE result, bool boolean_result = false) { + static TESTSIZE base_cmpxchg(int variant, intptr_t addr, TESTSIZE expected, TESTSIZE new_value, TESTSIZE result, bool boolean_result = false) { BufferBlob* bb = BufferBlob::create("riscvTest", 128); CodeBuffer code(bb); MacroAssembler _masm(&code); address entry = _masm.pc(); { - _masm.cmpxchg(/*addr*/ c_rarg0, /*expected*/ c_rarg1, /*new_value*/c_rarg2, - ASMSIZE, Assembler::relaxed, Assembler::relaxed, - /*result*/ c_rarg3, boolean_result); - _masm.mv(c_rarg0, c_rarg3); + switch(variant) { + default: + _masm.cmpxchg(/*addr*/ c_rarg0, /*expected*/ c_rarg1, /*new_value*/c_rarg2, + ASMSIZE, Assembler::relaxed, Assembler::relaxed, + /*result*/ c_rarg3, boolean_result); + _masm.mv(c_rarg0, c_rarg3); + break; + case 1: + // expected == result + _masm.cmpxchg(/*addr*/ c_rarg0, /*expected*/ c_rarg1, /*new_value*/c_rarg2, + ASMSIZE, Assembler::relaxed, Assembler::relaxed, + /*result*/ c_rarg1, boolean_result); + _masm.mv(c_rarg0, c_rarg1); + break; + case 2: + // new_value == result + _masm.cmpxchg(/*addr*/ c_rarg0, /*expected*/ c_rarg1, /*new_value*/c_rarg2, + ASMSIZE, Assembler::relaxed, Assembler::relaxed, + /*result*/ c_rarg2, boolean_result); + _masm.mv(c_rarg0, c_rarg2); + break; + case 3: + // expected == new_value + _masm.cmpxchg(/*addr*/ c_rarg0, /*expected*/ c_rarg1, /*new_value*/ c_rarg1, + ASMSIZE, Assembler::relaxed, Assembler::relaxed, + /*result*/ c_rarg2, boolean_result); + _masm.mv(c_rarg0, c_rarg2); + break; + + } _masm.ret(); } _masm.flush(); @@ -131,151 +155,85 @@ class CmpxchgTester { BufferBlob::free(bb); return ret; } - - // expected == result - static TESTSIZE simple_cmpxchg_spec1(intptr_t addr, TESTSIZE expected, TESTSIZE new_value, bool boolean_result = false) { - BufferBlob* bb = BufferBlob::create("riscvTest", 128); - CodeBuffer code(bb); - MacroAssembler _masm(&code); - address entry = _masm.pc(); - { - _masm.cmpxchg(/*addr*/ c_rarg0, /*expected*/ c_rarg1, /*new_value*/c_rarg2, - ASMSIZE, Assembler::relaxed, Assembler::relaxed, - /*result*/ c_rarg1, boolean_result); - _masm.mv(c_rarg0, c_rarg1); - _masm.ret(); - } - _masm.flush(); - OrderAccess::cross_modify_fence(); - TESTSIZE ret = ((cmpxchg_func_spec)entry)(addr, expected, new_value); - BufferBlob::free(bb); - return ret; - } - - // new_value == result - static TESTSIZE simple_cmpxchg_spec2(intptr_t addr, TESTSIZE expected, TESTSIZE new_value, bool boolean_result = false) { - BufferBlob* bb = BufferBlob::create("riscvTest", 128); - CodeBuffer code(bb); - MacroAssembler _masm(&code); - address entry = _masm.pc(); - { - _masm.cmpxchg(/*addr*/ c_rarg0, /*expected*/ c_rarg1, /*new_value*/c_rarg2, - ASMSIZE, Assembler::relaxed, Assembler::relaxed, - /*result*/ c_rarg2, boolean_result); - _masm.mv(c_rarg0, c_rarg2); - _masm.ret(); - } - _masm.flush(); - OrderAccess::cross_modify_fence(); - TESTSIZE ret = ((cmpxchg_func_spec)entry)(addr, expected, new_value); - BufferBlob::free(bb); - return ret; - } - - // expected == new_value - static TESTSIZE simple_cmpxchg_spec3(intptr_t addr, TESTSIZE new_value, TESTSIZE result, bool boolean_result = false) { - BufferBlob* bb = BufferBlob::create("riscvTest", 128); - CodeBuffer code(bb); - MacroAssembler _masm(&code); - address entry = _masm.pc(); - { - _masm.cmpxchg(/*addr*/ c_rarg0, /*expected*/ c_rarg1, /*new_value*/ c_rarg1, - ASMSIZE, Assembler::relaxed, Assembler::relaxed, - /*result*/ c_rarg2, boolean_result); - _masm.mv(c_rarg0, c_rarg2); - _masm.ret(); - } - _masm.flush(); - OrderAccess::cross_modify_fence(); - TESTSIZE ret = ((cmpxchg_func_spec)entry)(addr, new_value, result); - BufferBlob::free(bb); - return ret; - } }; +template +void plain_cmpxchg_test(int variant, TESTSIZE dv, TESTSIZE ex, TESTSIZE nv, TESTSIZE eret, TESTSIZE edata, bool bv) { + TESTSIZE data = dv; + TESTSIZE ret = CmpxchgTester::base_cmpxchg(variant, (intptr_t)&data, ex, nv, /* dummy */ 67, bv); + ASSERT_EQ(ret, eret); + ASSERT_EQ(data, edata); +} + template void run_plain_cmpxchg_tests() { - TESTSIZE data = 1337; - TESTSIZE ret = CmpxchgTester::simple_cmpxchg((intptr_t)&data, 1337, 42, /* dummy */ 67); - ASSERT_EQ(ret, 1337); // ret should be old value - ASSERT_EQ(data, 42); // data should be new value - - data = 1337; - ret = CmpxchgTester::simple_cmpxchg((intptr_t)&data, 1336, 42, /* dummy */ 67); - ASSERT_EQ(ret, 1337); // ret should be old value - ASSERT_EQ(data, 1337); // data should be new value - - data = 1337; - ret = CmpxchgTester::simple_cmpxchg((intptr_t)&data, 1337, 42, /* dummy */ 67, true); - ASSERT_EQ(ret, 1); // ret should be boolean truee - ASSERT_EQ(data, 42); // data should be new value - - data = 1337; - ret = CmpxchgTester::simple_cmpxchg((intptr_t)&data, 1336, 42, /* dummy */ 67, true); - ASSERT_EQ(ret, 0); // ret should be boolean false - ASSERT_EQ(data, 1337); // data should be new value - - // Register _result_ may be the same register as _new_val_ or _expected_. - data = 1337; - ret = CmpxchgTester::simple_cmpxchg_spec1((intptr_t)&data, 1337, 42); - ASSERT_EQ(ret, 1337); // ret should be old value - ASSERT_EQ(data, 42); // data should be new value - - data = 1337; - ret = CmpxchgTester::simple_cmpxchg_spec2((intptr_t)&data, 1337, 42); - ASSERT_EQ(ret, 1337); // ret should be old value - ASSERT_EQ(data, 42); // data should be new value - - data = 1337; - ret = CmpxchgTester::simple_cmpxchg_spec1((intptr_t)&data, 1336, 42); - ASSERT_EQ(ret, 1337); // ret should be old value - ASSERT_EQ(data, 1337); // data should be new value - - data = 1337; - ret = CmpxchgTester::simple_cmpxchg_spec2((intptr_t)&data, 1336, 42); - ASSERT_EQ(ret, 1337); // ret should be old value - ASSERT_EQ(data, 1337); // data should be new value - - data = 1337; - ret = CmpxchgTester::simple_cmpxchg_spec1((intptr_t)&data, 1337, 42, true); - ASSERT_EQ(ret, 1); - ASSERT_EQ(data, 42); + // Normal + plain_cmpxchg_test( 0 /* variant */ , 1337 /* start value*/, + 1337 /* expected */, 42 /* new value */, + 1337 /* return */ , 42 /* end value*/, false /* boolean ret*/); + + plain_cmpxchg_test( 0 /* variant */ , 1337 /* start value*/, + 1336 /* expected */, 42 /* new value */, + 1337 /* return */ , 1337 /* end value*/, false /* boolean ret*/); - data = 1337; - ret = CmpxchgTester::simple_cmpxchg_spec2((intptr_t)&data, 1337, 42, true); - ASSERT_EQ(ret, 1); - ASSERT_EQ(data, 42); + plain_cmpxchg_test( 0 /* variant */ , 1337 /* start value*/, + 1337 /* expected */, 42 /* new value */, + 1 /* return */ , 42 /* end value*/, true /* boolean ret*/); + + plain_cmpxchg_test( 0 /* variant */ , 1337 /* start value*/, + 1336 /* expected */, 42 /* new value */, + 0 /* return */ , 1337 /* end value*/, true /* boolean ret*/); - data = 1337; - ret = CmpxchgTester::simple_cmpxchg_spec1((intptr_t)&data, 1336, 42, true); - ASSERT_EQ(ret, 0); - ASSERT_EQ(data, 1337); + // result == expected register + plain_cmpxchg_test( 1 /* variant */ , 1337 /* start value*/, + 1337 /* expected */, 42 /* new value */, + 1337 /* return */ , 42 /* end value*/, false /* boolean ret*/); + + plain_cmpxchg_test( 1 /* variant */ , 1337 /* start value*/, + 1336 /* expected */, 42 /* new value */, + 1337 /* return */ , 1337 /* end value*/, false /* boolean ret*/); - data = 1337; - ret = CmpxchgTester::simple_cmpxchg_spec2((intptr_t)&data, 1336, 42, true); - ASSERT_EQ(ret, 0); - ASSERT_EQ(data, 1337); + plain_cmpxchg_test( 1 /* variant */ , 1337 /* start value*/, + 1337 /* expected */, 42 /* new value */, + 1 /* return */ , 42 /* end value*/, true /* boolean ret*/); + + plain_cmpxchg_test( 1 /* variant */ , 1337 /* start value*/, + 1336 /* expected */, 42 /* new value */, + 0 /* return */ , 1337 /* end value*/, true /* boolean ret*/); - // Register _expected_ may be the same register as _new_val_ and is assumed to be preserved. - data = 1337; - ret = CmpxchgTester::simple_cmpxchg_spec3((intptr_t)&data, 1337, /* dummy */ 66); - ASSERT_EQ(ret, 1337); - ASSERT_EQ(data, 1337); + // new_value == result register + plain_cmpxchg_test( 2 /* variant */ , 1337 /* start value*/, + 1337 /* expected */, 42 /* new value */, + 1337 /* return */ , 42 /* end value*/, false /* boolean ret*/); + + plain_cmpxchg_test( 2 /* variant */ , 1337 /* start value*/, + 1336 /* expected */, 42 /* new value */, + 1337 /* return */ , 1337 /* end value*/, false /* boolean ret*/); - data = 1337; - ret = CmpxchgTester::simple_cmpxchg_spec3((intptr_t)&data, 1336, /* dummy */ 66); - ASSERT_EQ(ret, 1337); - ASSERT_EQ(data, 1337); + plain_cmpxchg_test( 2 /* variant */ , 1337 /* start value*/, + 1337 /* expected */, 42 /* new value */, + 1 /* return */ , 42 /* end value*/, true /* boolean ret*/); + + plain_cmpxchg_test( 2 /* variant */ , 1337 /* start value*/, + 1336 /* expected */, 42 /* new value */, + 0 /* return */ , 1337 /* end value*/, true /* boolean ret*/); - data = 1337; - ret = CmpxchgTester::simple_cmpxchg_spec3((intptr_t)&data, 1337, /* dummy */ 66, true); - ASSERT_EQ(ret, 1); - ASSERT_EQ(data, 1337); + // expected == new_value register + plain_cmpxchg_test( 3 /* variant */ , 1337 /* start value*/, + 1337 /* expected */, 42 /* new value */, + 1337 /* return */ , 1337 /* end value*/, false /* boolean ret*/); + + plain_cmpxchg_test( 3 /* variant */ , 1337 /* start value*/, + 1336 /* expected */, 42 /* new value */, + 1337 /* return */ , 1337 /* end value*/, false /* boolean ret*/); - data = 1337; - ret = CmpxchgTester::simple_cmpxchg_spec3((intptr_t)&data, 1336, /* dummy */ 66, true); - ASSERT_EQ(ret, 0); - ASSERT_EQ(data, 1337); + plain_cmpxchg_test( 3 /* variant */ , 1337 /* start value*/, + 1337 /* expected */, 42 /* new value */, + 1 /* return */ , 1337 /* end value*/, true /* boolean ret*/); + + plain_cmpxchg_test( 3 /* variant */ , 1337 /* start value*/, + 1336 /* expected */, 42 /* new value */, + 0 /* return */ , 1337 /* end value*/, true /* boolean ret*/); } TEST_VM(RiscV, cmpxchg_int64_plain_lr_sc) { @@ -285,7 +243,7 @@ TEST_VM(RiscV, cmpxchg_int64_plain_lr_sc) { UseZacas = zacas; } -TEST_VM(RiscV, cmpxchg_int64_plain_zacas) { +TEST_VM(RiscV, cmpxchg_int64_plain_maybe_zacas) { if (UseZacas) { run_plain_cmpxchg_tests(); } @@ -298,7 +256,7 @@ TEST_VM(RiscV, cmpxchg_int32_plain_lr_sc) { UseZacas = zacas; } -TEST_VM(RiscV, cmpxchg_int32_plain_zacas) { +TEST_VM(RiscV, cmpxchg_int32_plain_maybe_zacas) { if (UseZacas) { run_plain_cmpxchg_tests(); }