@@ -260,4 +260,85 @@ TEST_VM(RiscV, cmpxchg_int32_plain_maybe_zacas) {
260
260
}
261
261
}
262
262
263
+ template <typename TESTSIZE, Assembler::operand_size ASMSIZE>
264
+ class NarrowCmpxchgTester {
265
+ public:
266
+ typedef TESTSIZE (*cmpxchg_func)(intptr_t addr, TESTSIZE expected, TESTSIZE new_value, TESTSIZE result,
267
+ int64_t scratch0, int64_t scratch1, int64_t scratch2);
268
+
269
+ static TESTSIZE narrow_cmpxchg (intptr_t addr, TESTSIZE expected, TESTSIZE new_value, TESTSIZE result, bool boolean_result = false ) {
270
+ BufferBlob* bb = BufferBlob::create (" riscvTest" , 128 );
271
+ CodeBuffer code (bb);
272
+ MacroAssembler _masm (&code);
273
+ address entry = _masm.pc ();
274
+ {
275
+ _masm.cmpxchg_narrow_value (/* addr*/ c_rarg0, /* expected*/ c_rarg1, /* new_value*/ c_rarg2,
276
+ ASMSIZE, Assembler::relaxed, Assembler::relaxed,
277
+ /* result*/ c_rarg3, boolean_result, c_rarg4, c_rarg5, c_rarg6); /* Uses also t0-t1, caller saved */
278
+ _masm.mv (c_rarg0, c_rarg3);
279
+ _masm.ret ();
280
+ }
281
+ _masm.flush (); // icache invalidate
282
+ TESTSIZE ret = ((cmpxchg_func)entry)(addr, expected, new_value, result, -1 , -1 , -1 );
283
+ BufferBlob::free (bb);
284
+ return ret;
285
+ }
286
+ };
287
+
288
+ template <typename TESTSIZE, Assembler::operand_size ASMSIZE>
289
+ void run_narrow_cmpxchg_tests () {
290
+ // Assume natural aligned
291
+ TESTSIZE data[8 ];
292
+ TESTSIZE ret;
293
+ for (int i = 0 ; i < 7 ; i++) {
294
+ memset (data, -1 , sizeof (data));
295
+
296
+ data[i] = 121 ;
297
+ ret = NarrowCmpxchgTester<TESTSIZE, ASMSIZE>::narrow_cmpxchg ((intptr_t )&data[i], 121 , 42 , /* result */ 67 , false );
298
+ ASSERT_EQ (ret, 121 );
299
+ ASSERT_EQ (data[i], 42 );
300
+
301
+ data[i] = 121 ;
302
+ ret = NarrowCmpxchgTester<TESTSIZE, ASMSIZE>::narrow_cmpxchg ((intptr_t )&data[i], 120 , 42 , /* result */ 67 , false );
303
+ ASSERT_EQ (ret, 121 );
304
+ ASSERT_EQ (data[i], 121 );
305
+
306
+ data[i] = 121 ;
307
+ ret = NarrowCmpxchgTester<TESTSIZE, ASMSIZE>::narrow_cmpxchg ((intptr_t )&data[i], 121 , 42 , /* result */ 67 , true );
308
+ ASSERT_EQ (ret, 1 );
309
+ ASSERT_EQ (data[i], 42 );
310
+
311
+ data[i] = 121 ;
312
+ ret = NarrowCmpxchgTester<TESTSIZE, ASMSIZE>::narrow_cmpxchg ((intptr_t )&data[i], 120 , 42 , /* result */ 67 , true );
313
+ ASSERT_EQ (ret, 0 );
314
+ ASSERT_EQ (data[i], 121 );
315
+ }
316
+ }
317
+
318
+ TEST_VM (RiscV, cmpxchg_int16_lr_sc) {
319
+ bool zacas = UseZacas;
320
+ UseZacas = false ;
321
+ run_narrow_cmpxchg_tests<int16_t , Assembler::int16>();
322
+ UseZacas = zacas;
323
+ }
324
+
325
+ TEST_VM (RiscV, cmpxchg_int8_lr_sc) {
326
+ bool zacas = UseZacas;
327
+ UseZacas = false ;
328
+ run_narrow_cmpxchg_tests<int8_t , Assembler::int8>();
329
+ UseZacas = zacas;
330
+ }
331
+
332
+ TEST_VM (RiscV, cmpxchg_int16_maybe_zacas) {
333
+ if (UseZacas) {
334
+ run_narrow_cmpxchg_tests<int16_t , Assembler::int16>();
335
+ }
336
+ }
337
+
338
+ TEST_VM (RiscV, cmpxchg_int8_maybe_zacas) {
339
+ if (UseZacas) {
340
+ run_narrow_cmpxchg_tests<int8_t , Assembler::int8>();
341
+ }
342
+ }
343
+
263
344
#endif // RISCV
0 commit comments