Commit e834ebce authored by Lu Yahan's avatar Lu Yahan Committed by V8 LUCI CQ

[riscv64] Fix atomic timeout

port 49c95bd9

Change-Id: I69baf80d85e172014f4037fd4d345f0f0a634684
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3578101
Commit-Queue: Yahan Lu <yahan@iscas.ac.cn>
Auto-Submit: Yahan Lu <yahan@iscas.ac.cn>
Reviewed-by: 's avatarji qiu <qiuji@iscas.ac.cn>
Commit-Queue: ji qiu <qiuji@iscas.ac.cn>
Cr-Commit-Position: refs/heads/main@{#79906}
parent 5d8d1846
...@@ -864,69 +864,81 @@ void LiftoffAssembler::AtomicExchange(Register dst_addr, Register offset_reg, ...@@ -864,69 +864,81 @@ void LiftoffAssembler::AtomicExchange(Register dst_addr, Register offset_reg,
type, liftoff::Binop::kExchange); type, liftoff::Binop::kExchange);
} }
#define ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(load_linked, \
store_conditional) \
do { \
Label compareExchange; \
Label exit; \
sync(); \
bind(&compareExchange); \
load_linked(result.gp(), MemOperand(temp0, 0)); \
BranchShort(&exit, ne, expected.gp(), Operand(result.gp())); \
mv(temp2, new_value.gp()); \
store_conditional(temp2, MemOperand(temp0, 0)); \
BranchShort(&compareExchange, eq, temp2, Operand(zero_reg)); \
bind(&exit); \
sync(); \
} while (0)
#define ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT( \
load_linked, store_conditional, size, aligned) \
do { \
Label compareExchange; \
Label exit; \
andi(temp1, temp0, aligned); \
Sub64(temp0, temp0, Operand(temp1)); \
Sll32(temp1, temp1, 3); \
sync(); \
bind(&compareExchange); \
load_linked(temp2, MemOperand(temp0, 0)); \
ExtractBits(result.gp(), temp2, temp1, size, false); \
ExtractBits(temp2, expected.gp(), zero_reg, size, false); \
BranchShort(&exit, ne, temp2, Operand(result.gp())); \
InsertBits(temp2, new_value.gp(), temp1, size); \
store_conditional(temp2, MemOperand(temp0, 0)); \
BranchShort(&compareExchange, eq, temp2, Operand(zero_reg)); \
bind(&exit); \
sync(); \
} while (0)
void LiftoffAssembler::AtomicCompareExchange( void LiftoffAssembler::AtomicCompareExchange(
Register dst_addr, Register offset_reg, uintptr_t offset_imm, Register dst_addr, Register offset_reg, uintptr_t offset_imm,
LiftoffRegister expected, LiftoffRegister new_value, LiftoffRegister result, LiftoffRegister expected, LiftoffRegister new_value, LiftoffRegister result,
StoreType type) { StoreType type) {
LiftoffRegList pinned = {dst_addr, offset_reg, expected, new_value}; LiftoffRegList pinned = {dst_addr, offset_reg, expected, new_value, result};
Register temp0 = pinned.set(GetUnusedRegister(kGpReg, pinned)).gp();
Register result_reg = result.gp(); Register temp1 = pinned.set(GetUnusedRegister(kGpReg, pinned)).gp();
if (pinned.has(result)) { Register temp2 = pinned.set(GetUnusedRegister(kGpReg, pinned)).gp();
result_reg = GetUnusedRegister(kGpReg, pinned).gp(); MemOperand dst_op = liftoff::GetMemOp(this, dst_addr, offset_reg, offset_imm);
} Add64(temp0, dst_op.rm(), dst_op.offset());
UseScratchRegisterScope temps(this);
Register actual_addr = liftoff::CalculateActualAddress(
this, dst_addr, offset_reg, offset_imm, temps.Acquire());
Register store_result = temps.Acquire();
Label retry;
Label done;
bind(&retry);
switch (type.value()) { switch (type.value()) {
case StoreType::kI64Store8: case StoreType::kI64Store8:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, 8, 7);
break;
case StoreType::kI32Store8: case StoreType::kI32Store8:
lbu(result_reg, actual_addr, 0); ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, 8, 3);
sync();
Branch(&done, ne, result.gp(), Operand(expected.gp()));
sync();
sb(new_value.gp(), actual_addr, 0);
sync();
mv(store_result, zero_reg);
break; break;
case StoreType::kI64Store16: case StoreType::kI64Store16:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, 16, 7);
break;
case StoreType::kI32Store16: case StoreType::kI32Store16:
lhu(result_reg, actual_addr, 0); ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Ll, Sc, 16, 3);
sync();
Branch(&done, ne, result.gp(), Operand(expected.gp()));
sync();
sh(new_value.gp(), actual_addr, 0);
sync();
mv(store_result, zero_reg);
break; break;
case StoreType::kI64Store32: case StoreType::kI64Store32:
ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT(Lld, Scd, 32, 7);
break;
case StoreType::kI32Store: case StoreType::kI32Store:
lr_w(true, true, result_reg, actual_addr); ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Ll, Sc);
Branch(&done, ne, result.gp(), Operand(expected.gp()));
sc_w(true, true, store_result, new_value.gp(), actual_addr);
break; break;
case StoreType::kI64Store: case StoreType::kI64Store:
lr_d(true, true, result_reg, actual_addr); ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Lld, Scd);
Branch(&done, ne, result.gp(), Operand(expected.gp()));
sc_d(true, true, store_result, new_value.gp(), actual_addr);
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
bnez(store_result, &retry);
bind(&done);
if (result_reg != result.gp()) {
mv(result.gp(), result_reg);
}
} }
#undef ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER
#undef ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER_EXT
void LiftoffAssembler::AtomicFence() { sync(); } void LiftoffAssembler::AtomicFence() { sync(); }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment