@@ -3313,14 +3313,11 @@ void MacroAssembler::store_conditional(Register dst,
3313
3313
}
3314
3314
3315
3315
3316
- void MacroAssembler::cmpxchg_narrow_value_helper (Register addr, Register expected,
3317
- Register new_val,
3316
+ void MacroAssembler::cmpxchg_narrow_value_helper (Register addr, Register expected, Register new_val,
3318
3317
enum operand_size size,
3319
- Register tmp1 , Register tmp2 , Register tmp3 ) {
3318
+ Register shift , Register mask , Register aligned_addr ) {
3320
3319
assert (size == int8 || size == int16, " unsupported operand size" );
3321
3320
3322
- Register aligned_addr = t1, shift = tmp1, mask = tmp2, not_mask = tmp3;
3323
-
3324
3321
andi (shift, addr, 3 );
3325
3322
slli (shift, shift, 3 );
3326
3323
@@ -3335,8 +3332,6 @@ void MacroAssembler::cmpxchg_narrow_value_helper(Register addr, Register expecte
3335
3332
}
3336
3333
sll (mask, mask, shift);
3337
3334
3338
- notr (not_mask, mask);
3339
-
3340
3335
sll (expected, expected, shift);
3341
3336
andr (expected, expected, mask);
3342
3337
@@ -3353,35 +3348,46 @@ void MacroAssembler::cmpxchg_narrow_value(Register addr, Register expected,
3353
3348
Assembler::Aqrl acquire, Assembler::Aqrl release,
3354
3349
Register result, bool result_as_bool,
3355
3350
Register tmp1, Register tmp2, Register tmp3) {
3356
- Register aligned_addr = t1, shift = tmp1, mask = tmp2, not_mask = tmp3, old = result, tmp = t0;
3357
- assert_different_registers (addr, old, mask, not_mask, new_val, expected, shift, tmp);
3358
- cmpxchg_narrow_value_helper (addr, expected, new_val, size, tmp1, tmp2, tmp3);
3351
+ assert_different_registers (addr, expected, new_val, result, tmp1, tmp2, tmp3, t0, t1);
3359
3352
3360
- Label retry, fail, done;
3353
+ Register scratch0 = t0, aligned_addr = t1;
3354
+ Register shift = tmp1, mask = tmp2, scratch1 = tmp3;
3355
+
3356
+ cmpxchg_narrow_value_helper (addr, expected, new_val, size, shift, mask, aligned_addr);
3361
3357
3362
- bind ( retry) ;
3358
+ Label retry, fail, done ;
3363
3359
3364
3360
if (UseZacas) {
3365
- lw (old, aligned_addr);
3361
+ lw (result, aligned_addr);
3362
+
3363
+ bind (retry); // amocas loads the current value into result
3364
+ notr (scratch1, mask);
3366
3365
3367
- // if old & mask != expected
3368
- andr (tmp, old, mask);
3369
- bne (tmp, expected , fail);
3366
+ andr (scratch0, result, scratch1); // scratch0 = word - cas bits
3367
+ orr (scratch1, expected, scratch0); // scratch1 = non-cas bits + cas bits
3368
+ bne (result, scratch1 , fail); // cas bits differ, cas failed
3370
3369
3371
- andr (tmp, old, not_mask);
3372
- orr (tmp, tmp, new_val);
3370
+ // result is the same as expected, use as expected value.
3373
3371
3374
- atomic_cas (old, tmp, aligned_addr, operand_size::int32, acquire, release);
3375
- bne (tmp, old, retry);
3372
+ // scratch0 is still = word - cas bits
3373
+ // Or in the new value to create complete new value.
3374
+ orr (scratch0, scratch0, new_val);
3375
+
3376
+ mv (scratch1, result); // save our expected value
3377
+ atomic_cas (result, scratch0, aligned_addr, operand_size::int32, acquire, release);
3378
+ bne (scratch1, result, retry);
3376
3379
} else {
3377
- lr_w (old, aligned_addr, acquire);
3378
- andr (tmp, old, mask);
3379
- bne (tmp, expected, fail);
3380
+ notr (scratch1, mask);
3381
+ bind (retry);
3382
+
3383
+ lr_w (result, aligned_addr, acquire);
3384
+ andr (scratch0, result, mask);
3385
+ bne (scratch0, expected, fail);
3380
3386
3381
- andr (tmp, old, not_mask);
3382
- orr (tmp, tmp , new_val);
3383
- sc_w (tmp, tmp , aligned_addr, release);
3384
- bnez (tmp , retry);
3387
+ andr (scratch0, result, scratch1); // scratch1 is ~mask
3388
+ orr (scratch0, scratch0 , new_val);
3389
+ sc_w (scratch0, scratch0 , aligned_addr, release);
3390
+ bnez (scratch0 , retry);
3385
3391
}
3386
3392
3387
3393
if (result_as_bool) {
@@ -3393,10 +3399,10 @@ void MacroAssembler::cmpxchg_narrow_value(Register addr, Register expected,
3393
3399
3394
3400
bind (done);
3395
3401
} else {
3396
- andr (tmp, old, mask);
3397
-
3398
3402
bind (fail);
3399
- srl (result, tmp, shift);
3403
+
3404
+ andr (scratch0, result, mask);
3405
+ srl (result, scratch0, shift);
3400
3406
3401
3407
if (size == int8) {
3402
3408
sign_extend (result, result, 8 );
@@ -3416,33 +3422,44 @@ void MacroAssembler::weak_cmpxchg_narrow_value(Register addr, Register expected,
3416
3422
Assembler::Aqrl acquire, Assembler::Aqrl release,
3417
3423
Register result,
3418
3424
Register tmp1, Register tmp2, Register tmp3) {
3419
- Register aligned_addr = t1, shift = tmp1, mask = tmp2, not_mask = tmp3, old = result, tmp = t0;
3420
- assert_different_registers (addr, old, mask, not_mask, new_val, expected, shift, tmp);
3421
- cmpxchg_narrow_value_helper (addr, expected, new_val, size, tmp1, tmp2, tmp3);
3425
+ assert_different_registers (addr, expected, new_val, result, tmp1, tmp2, tmp3, t0, t1);
3426
+
3427
+ Register scratch0 = t0, aligned_addr = t1;
3428
+ Register shift = tmp1, mask = tmp2, scratch1 = tmp3;
3429
+
3430
+ cmpxchg_narrow_value_helper (addr, expected, new_val, size, shift, mask, aligned_addr);
3422
3431
3423
3432
Label fail, done;
3424
3433
3425
3434
if (UseZacas) {
3426
- lw (old , aligned_addr);
3435
+ lw (result , aligned_addr);
3427
3436
3428
- // if old & mask != expected
3429
- andr (tmp, old, mask);
3430
- bne (tmp, expected, fail);
3437
+ notr (scratch1, mask);
3431
3438
3432
- andr (tmp, old, not_mask);
3433
- orr (tmp, tmp, new_val);
3439
+ andr (scratch0, result, scratch1); // scratch0 = word - cas bits
3440
+ orr (scratch1, expected, scratch0); // scratch1 = non-cas bits + cas bits
3441
+ bne (result, scratch1, fail); // cas bits differ, cas failed
3434
3442
3435
- atomic_cas (tmp, new_val, addr, operand_size::int32, acquire, release);
3436
- bne (tmp, old, fail);
3443
+ // result is the same as expected, use as expected value.
3444
+
3445
+ // scratch0 is still = word - cas bits
3446
+ // Or in the new value to create complete new value.
3447
+ orr (scratch0, scratch0, new_val);
3448
+
3449
+ mv (scratch1, result); // save our expected value
3450
+ atomic_cas (result, scratch0, aligned_addr, operand_size::int32, acquire, release);
3451
+ bne (scratch1, result, fail); // This weak, so just bail-out.
3437
3452
} else {
3438
- lr_w (old, aligned_addr, acquire);
3439
- andr (tmp, old, mask);
3440
- bne (tmp, expected, fail);
3441
-
3442
- andr (tmp, old, not_mask);
3443
- orr (tmp, tmp, new_val);
3444
- sc_w (tmp, tmp, aligned_addr, release);
3445
- bnez (tmp, fail);
3453
+ notr (scratch1, mask);
3454
+
3455
+ lr_w (result, aligned_addr, acquire);
3456
+ andr (scratch0, result, mask);
3457
+ bne (scratch0, expected, fail);
3458
+
3459
+ andr (scratch0, result, scratch1); // scratch1 is ~mask
3460
+ orr (scratch0, scratch0, new_val);
3461
+ sc_w (scratch0, scratch0, aligned_addr, release);
3462
+ bnez (scratch0, fail);
3446
3463
}
3447
3464
3448
3465
// Success
1 commit comments
openjdk-notifier[bot] commentedon Nov 26, 2024
Review
Issues