From c0dd4e1bea9ca1666f46a24e761ffd2acc648a2d Mon Sep 17 00:00:00 2001 From: Robbin Ehn Date: Wed, 27 Nov 2024 18:29:35 +0100 Subject: [PATCH] baseline --- .../gtest/riscv/test_assembler_riscv.cpp | 198 ++++++++++++++++++ 1 file changed, 198 insertions(+) diff --git a/test/hotspot/gtest/riscv/test_assembler_riscv.cpp b/test/hotspot/gtest/riscv/test_assembler_riscv.cpp index 152b997b3c8cd..f0fda98c1bb91 100644 --- a/test/hotspot/gtest/riscv/test_assembler_riscv.cpp +++ b/test/hotspot/gtest/riscv/test_assembler_riscv.cpp @@ -106,4 +106,202 @@ 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) { + 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); + _masm.ret(); + } + _masm.flush(); + OrderAccess::cross_modify_fence(); + TESTSIZE ret = ((cmpxchg_func)entry)(addr, expected, new_value, result); + 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 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); + + data = 1337; + ret = CmpxchgTester::simple_cmpxchg_spec2((intptr_t)&data, 1337, 42, true); + ASSERT_EQ(ret, 1); + ASSERT_EQ(data, 42); + + data = 1337; + ret = CmpxchgTester::simple_cmpxchg_spec1((intptr_t)&data, 1336, 42, true); + ASSERT_EQ(ret, 0); + ASSERT_EQ(data, 1337); + + data = 1337; + ret = CmpxchgTester::simple_cmpxchg_spec2((intptr_t)&data, 1336, 42, true); + ASSERT_EQ(ret, 0); + ASSERT_EQ(data, 1337); + + // 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); + + data = 1337; + ret = CmpxchgTester::simple_cmpxchg_spec3((intptr_t)&data, 1336, /* dummy */ 66); + ASSERT_EQ(ret, 1337); + ASSERT_EQ(data, 1337); + + data = 1337; + ret = CmpxchgTester::simple_cmpxchg_spec3((intptr_t)&data, 1337, /* dummy */ 66, true); + ASSERT_EQ(ret, 1); + ASSERT_EQ(data, 1337); + + data = 1337; + ret = CmpxchgTester::simple_cmpxchg_spec3((intptr_t)&data, 1336, /* dummy */ 66, true); + ASSERT_EQ(ret, 0); + ASSERT_EQ(data, 1337); +} + +TEST_VM(RiscV, cmpxchg_int64_plain_lr_sc) { + bool zacas = UseZacas; + UseZacas = false; + run_plain_cmpxchg_tests(); + UseZacas = zacas; +} + +TEST_VM(RiscV, cmpxchg_int64_plain_zacas) { + if (UseZacas) { + run_plain_cmpxchg_tests(); + } +} + +TEST_VM(RiscV, cmpxchg_int32_plain_lr_sc) { + bool zacas = UseZacas; + UseZacas = false; + run_plain_cmpxchg_tests(); + UseZacas = zacas; +} + +TEST_VM(RiscV, cmpxchg_int32_plain_zacas) { + if (UseZacas) { + run_plain_cmpxchg_tests(); + } +} + #endif // RISCV