s390x: [liftoff] implement AtomicAdd
Change-Id: Ia4eebe80bdac6a89b2c4c4b072d7e61240755973 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2810416 Reviewed-by: Milad Fa <mfarazma@redhat.com> Commit-Queue: Junliang Yan <junyan@redhat.com> Cr-Commit-Position: refs/heads/master@{#73843}
This commit is contained in:
parent
7989e04979
commit
5655ba89ea
@ -497,7 +497,85 @@ void LiftoffAssembler::AtomicStore(Register dst_addr, Register offset_reg,
|
|||||||
void LiftoffAssembler::AtomicAdd(Register dst_addr, Register offset_reg,
|
void LiftoffAssembler::AtomicAdd(Register dst_addr, Register offset_reg,
|
||||||
uintptr_t offset_imm, LiftoffRegister value,
|
uintptr_t offset_imm, LiftoffRegister value,
|
||||||
LiftoffRegister result, StoreType type) {
|
LiftoffRegister result, StoreType type) {
|
||||||
bailout(kAtomics, "AtomicAdd");
|
Register tmp1 =
|
||||||
|
GetUnusedRegister(
|
||||||
|
kGpReg, LiftoffRegList::ForRegs(dst_addr, offset_reg, value, result))
|
||||||
|
.gp();
|
||||||
|
Register tmp2 =
|
||||||
|
GetUnusedRegister(kGpReg, LiftoffRegList::ForRegs(dst_addr, offset_reg,
|
||||||
|
value, result, tmp1))
|
||||||
|
.gp();
|
||||||
|
|
||||||
|
lay(ip,
|
||||||
|
MemOperand(dst_addr, offset_reg == no_reg ? r0 : offset_reg, offset_imm));
|
||||||
|
|
||||||
|
switch (type.value()) {
|
||||||
|
case StoreType::kI32Store8:
|
||||||
|
case StoreType::kI64Store8: {
|
||||||
|
Label doadd;
|
||||||
|
bind(&doadd);
|
||||||
|
LoadU8(tmp1, MemOperand(ip));
|
||||||
|
AddS32(tmp2, tmp1, value.gp());
|
||||||
|
AtomicCmpExchangeU8(ip, result.gp(), tmp1, tmp2, r0, r1);
|
||||||
|
b(Condition(4), &doadd);
|
||||||
|
LoadU8(result.gp(), result.gp());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case StoreType::kI32Store16:
|
||||||
|
case StoreType::kI64Store16: {
|
||||||
|
Label doadd;
|
||||||
|
bind(&doadd);
|
||||||
|
LoadU16(tmp1, MemOperand(ip));
|
||||||
|
#ifdef V8_TARGET_BIG_ENDIAN
|
||||||
|
lrvr(tmp2, tmp1);
|
||||||
|
ShiftRightU32(tmp2, tmp2, Operand(16));
|
||||||
|
AddS32(tmp2, tmp2, value.gp());
|
||||||
|
lrvr(tmp2, tmp2);
|
||||||
|
ShiftRightU32(tmp2, tmp2, Operand(16));
|
||||||
|
#else
|
||||||
|
AddS32(tmp2, tmp1, value.gp());
|
||||||
|
#endif
|
||||||
|
AtomicCmpExchangeU16(ip, result.gp(), tmp1, tmp2, r0, r1);
|
||||||
|
b(Condition(4), &doadd);
|
||||||
|
LoadU16(result.gp(), result.gp());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case StoreType::kI32Store:
|
||||||
|
case StoreType::kI64Store32: {
|
||||||
|
Label doadd;
|
||||||
|
bind(&doadd);
|
||||||
|
LoadU32(tmp1, MemOperand(ip));
|
||||||
|
#ifdef V8_TARGET_BIG_ENDIAN
|
||||||
|
lrvr(tmp2, tmp1);
|
||||||
|
AddS32(tmp2, tmp2, value.gp());
|
||||||
|
lrvr(tmp2, tmp2);
|
||||||
|
#else
|
||||||
|
AddS32(tmp2, tmp1, value.gp());
|
||||||
|
#endif
|
||||||
|
CmpAndSwap(tmp1, tmp2, MemOperand(ip));
|
||||||
|
b(Condition(4), &doadd);
|
||||||
|
LoadU32(result.gp(), tmp1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case StoreType::kI64Store: {
|
||||||
|
Label doadd;
|
||||||
|
bind(&doadd);
|
||||||
|
LoadU64(tmp1, MemOperand(ip));
|
||||||
|
#ifdef V8_TARGET_BIG_ENDIAN
|
||||||
|
lrvgr(tmp2, tmp1);
|
||||||
|
AddS64(tmp2, tmp2, value.gp());
|
||||||
|
lrvgr(tmp2, tmp2);
|
||||||
|
#else
|
||||||
|
AddS64(tmp2, tmp1, value.gp());
|
||||||
|
#endif
|
||||||
|
CmpAndSwap64(tmp1, tmp2, MemOperand(ip));
|
||||||
|
b(Condition(4), &doadd);
|
||||||
|
mov(result.gp(), tmp1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LiftoffAssembler::AtomicSub(Register dst_addr, Register offset_reg,
|
void LiftoffAssembler::AtomicSub(Register dst_addr, Register offset_reg,
|
||||||
|
Loading…
Reference in New Issue
Block a user