PPC/s390: [wasm][memory64] Fix atomics

Port 76a817e03a

Original Commit Message:

    This fixes a TODO about atomics and memory64 and removes the explicit
    CHECK that checks for the unsupported situation.
    Similar to other memory accesses, the memory index is supposed to be a
    64-bit value if memory64 is being used.
    The bounds checking implementation in Liftoff and TurboFan is shared
    with non-atomic memory accesses, so this is already prepared for
    memory64. We only need to fix the expected type in the function body
    decoder, and prepare the assembler for 64-bit values.

R=clemensb@chromium.org, joransiu@ca.ibm.com, junyan@redhat.com, midawson@redhat.com
BUG=
LOG=N

Change-Id: I61bb3106c9661f7b8aa72b27ed439a8d94890192
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4204353
Commit-Queue: Milad Farazmand <mfarazma@redhat.com>
Reviewed-by: Junliang Yan <junyan@redhat.com>
Reviewed-by: Joran Siu <joransiu@ca.ibm.com>
Cr-Commit-Position: refs/heads/main@{#85552}
This commit is contained in:
Milad Fa 2023-01-30 17:42:53 +00:00 committed by V8 LUCI CQ
parent 8131315998
commit 35964e2418
2 changed files with 94 additions and 126 deletions

View File

@ -544,16 +544,19 @@ void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
void LiftoffAssembler::AtomicLoad(LiftoffRegister dst, Register src_addr,
Register offset_reg, uintptr_t offset_imm,
LoadType type, LiftoffRegList /* pinned */) {
Load(dst, src_addr, offset_reg, offset_imm, type, nullptr, true);
LoadType type, LiftoffRegList /* pinned */,
bool i64_offset) {
Load(dst, src_addr, offset_reg, offset_imm, type, nullptr, true, i64_offset);
lwsync();
}
void LiftoffAssembler::AtomicStore(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister src,
StoreType type, LiftoffRegList pinned) {
StoreType type, LiftoffRegList pinned,
bool i64_offset) {
lwsync();
Store(dst_addr, offset_reg, offset_imm, src, type, pinned, nullptr, true);
Store(dst_addr, offset_reg, offset_imm, src, type, pinned, nullptr, true,
i64_offset);
sync();
}
@ -565,17 +568,19 @@ constexpr bool is_be = false;
#define ATOMIC_OP(instr) \
{ \
if (!i64_offset && offset_reg != no_reg) { \
ZeroExtWord32(ip, offset_reg); \
offset_reg = ip; \
} \
\
Register offset = r0; \
if (offset_imm != 0) { \
mov(ip, Operand(offset_imm)); \
if (offset_reg != no_reg) { \
add(ip, ip, offset_reg); \
} \
mov(offset, Operand(offset_imm)); \
if (offset_reg != no_reg) add(offset, offset, offset_reg); \
mr(ip, offset); \
offset = ip; \
} else { \
if (offset_reg != no_reg) { \
offset = offset_reg; \
} \
} else if (offset_reg != no_reg) { \
offset = offset_reg; \
} \
\
MemOperand dst = MemOperand(offset, dst_addr); \
@ -652,49 +657,57 @@ constexpr bool is_be = false;
void LiftoffAssembler::AtomicAdd(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister value,
LiftoffRegister result, StoreType type) {
LiftoffRegister result, StoreType type,
bool i64_offset) {
ATOMIC_OP(add);
}
void LiftoffAssembler::AtomicSub(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister value,
LiftoffRegister result, StoreType type) {
LiftoffRegister result, StoreType type,
bool i64_offset) {
ATOMIC_OP(sub);
}
void LiftoffAssembler::AtomicAnd(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister value,
LiftoffRegister result, StoreType type) {
LiftoffRegister result, StoreType type,
bool i64_offset) {
ATOMIC_OP(and_);
}
void LiftoffAssembler::AtomicOr(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister value,
LiftoffRegister result, StoreType type) {
LiftoffRegister result, StoreType type,
bool i64_offset) {
ATOMIC_OP(orx);
}
void LiftoffAssembler::AtomicXor(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister value,
LiftoffRegister result, StoreType type) {
LiftoffRegister result, StoreType type,
bool i64_offset) {
ATOMIC_OP(xor_);
}
void LiftoffAssembler::AtomicExchange(Register dst_addr, Register offset_reg,
uintptr_t offset_imm,
LiftoffRegister value,
LiftoffRegister result, StoreType type) {
LiftoffRegister result, StoreType type,
bool i64_offset) {
if (!i64_offset && offset_reg != no_reg) {
ZeroExtWord32(ip, offset_reg);
offset_reg = ip;
}
Register offset = r0;
if (offset_imm != 0) {
mov(ip, Operand(offset_imm));
if (offset_reg != no_reg) {
add(ip, ip, offset_reg);
}
mov(offset, Operand(offset_imm));
if (offset_reg != no_reg) add(offset, offset, offset_reg);
mr(ip, offset);
offset = ip;
} else {
if (offset_reg != no_reg) {
offset = offset_reg;
}
} else if (offset_reg != no_reg) {
offset = offset_reg;
}
MemOperand dst = MemOperand(offset, dst_addr);
switch (type.value()) {
@ -749,18 +762,20 @@ void LiftoffAssembler::AtomicExchange(Register dst_addr, Register offset_reg,
void LiftoffAssembler::AtomicCompareExchange(
Register dst_addr, Register offset_reg, uintptr_t offset_imm,
LiftoffRegister expected, LiftoffRegister new_value, LiftoffRegister result,
StoreType type) {
StoreType type, bool i64_offset) {
if (!i64_offset && offset_reg != no_reg) {
ZeroExtWord32(ip, offset_reg);
offset_reg = ip;
}
Register offset = r0;
if (offset_imm != 0) {
mov(ip, Operand(offset_imm));
if (offset_reg != no_reg) {
add(ip, ip, offset_reg);
}
mov(offset, Operand(offset_imm));
if (offset_reg != no_reg) add(offset, offset, offset_reg);
mr(ip, offset);
offset = ip;
} else {
if (offset_reg != no_reg) {
offset = offset_reg;
}
} else if (offset_reg != no_reg) {
offset = offset_reg;
}
MemOperand dst = MemOperand(offset, dst_addr);
switch (type.value()) {

View File

@ -450,27 +450,29 @@ void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
}
}
#define PREP_MEM_OPERAND(offset_reg, offset_imm, scratch) \
if (offset_reg != no_reg && !i64_offset) { \
/* Clear the upper 32 bits of the 64 bit offset register.*/ \
llgfr(scratch, offset_reg); \
offset_reg = scratch; \
} \
if (!is_int20(offset_imm)) { \
if (offset_reg != no_reg) { \
mov(r0, Operand(offset_imm)); \
AddS64(r0, offset_reg); \
mov(scratch, r0); \
} else { \
mov(scratch, Operand(offset_imm)); \
} \
offset_reg = scratch; \
offset_imm = 0; \
}
void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister src,
StoreType type, LiftoffRegList /* pinned */,
uint32_t* protected_store_pc, bool is_store_mem,
bool i64_offset) {
if (offset_reg != no_reg && !i64_offset) {
// Clear the upper 32 bits of the 64 bit offset register.
llgfr(ip, offset_reg);
offset_reg = ip;
}
if (!is_int20(offset_imm)) {
if (offset_reg != no_reg) {
mov(r0, Operand(offset_imm));
AddS64(r0, offset_reg);
mov(ip, r0);
} else {
mov(ip, Operand(offset_imm));
}
offset_reg = ip;
offset_imm = 0;
}
PREP_MEM_OPERAND(offset_reg, offset_imm, ip)
MemOperand dst_op =
MemOperand(dst_addr, offset_reg == no_reg ? r0 : offset_reg, offset_imm);
if (protected_store_pc) *protected_store_pc = pc_offset();
@ -531,22 +533,16 @@ void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
void LiftoffAssembler::AtomicLoad(LiftoffRegister dst, Register src_addr,
Register offset_reg, uintptr_t offset_imm,
LoadType type, LiftoffRegList /* pinned */) {
Load(dst, src_addr, offset_reg, offset_imm, type, nullptr, true);
LoadType type, LiftoffRegList /* pinned */,
bool i64_offset) {
Load(dst, src_addr, offset_reg, offset_imm, type, nullptr, true, i64_offset);
}
void LiftoffAssembler::AtomicStore(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister src,
StoreType type,
LiftoffRegList /* pinned */) {
if (!is_int20(offset_imm)) {
mov(ip, Operand(offset_imm));
if (offset_reg != no_reg) {
AddS64(ip, offset_reg);
}
offset_reg = ip;
offset_imm = 0;
}
StoreType type, LiftoffRegList /* pinned */,
bool i64_offset) {
PREP_MEM_OPERAND(offset_reg, offset_imm, ip)
lay(ip,
MemOperand(dst_addr, offset_reg == no_reg ? r0 : offset_reg, offset_imm));
@ -601,7 +597,8 @@ void LiftoffAssembler::AtomicStore(Register dst_addr, Register offset_reg,
void LiftoffAssembler::AtomicAdd(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister value,
LiftoffRegister result, StoreType type) {
LiftoffRegister result, StoreType type,
bool i64_offset) {
Register tmp1 = GetUnusedRegister(kGpReg, LiftoffRegList{dst_addr, offset_reg,
value, result})
.gp();
@ -609,14 +606,7 @@ void LiftoffAssembler::AtomicAdd(Register dst_addr, Register offset_reg,
value, result, tmp1})
.gp();
if (!is_int20(offset_imm)) {
mov(ip, Operand(offset_imm));
if (offset_reg != no_reg) {
AddS64(ip, offset_reg);
}
offset_reg = ip;
offset_imm = 0;
}
PREP_MEM_OPERAND(offset_reg, offset_imm, ip)
lay(ip,
MemOperand(dst_addr, offset_reg == no_reg ? r0 : offset_reg, offset_imm));
@ -701,7 +691,8 @@ void LiftoffAssembler::AtomicAdd(Register dst_addr, Register offset_reg,
void LiftoffAssembler::AtomicSub(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister value,
LiftoffRegister result, StoreType type) {
LiftoffRegister result, StoreType type,
bool i64_offset) {
Register tmp1 = GetUnusedRegister(kGpReg, LiftoffRegList{dst_addr, offset_reg,
value, result})
.gp();
@ -709,14 +700,7 @@ void LiftoffAssembler::AtomicSub(Register dst_addr, Register offset_reg,
value, result, tmp1})
.gp();
if (!is_int20(offset_imm)) {
mov(ip, Operand(offset_imm));
if (offset_reg != no_reg) {
AddS64(ip, offset_reg);
}
offset_reg = ip;
offset_imm = 0;
}
PREP_MEM_OPERAND(offset_reg, offset_imm, ip)
lay(ip,
MemOperand(dst_addr, offset_reg == no_reg ? r0 : offset_reg, offset_imm));
@ -801,7 +785,8 @@ void LiftoffAssembler::AtomicSub(Register dst_addr, Register offset_reg,
void LiftoffAssembler::AtomicAnd(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister value,
LiftoffRegister result, StoreType type) {
LiftoffRegister result, StoreType type,
bool i64_offset) {
Register tmp1 = GetUnusedRegister(kGpReg, LiftoffRegList{dst_addr, offset_reg,
value, result})
.gp();
@ -809,14 +794,7 @@ void LiftoffAssembler::AtomicAnd(Register dst_addr, Register offset_reg,
value, result, tmp1})
.gp();
if (!is_int20(offset_imm)) {
mov(ip, Operand(offset_imm));
if (offset_reg != no_reg) {
AddS64(ip, offset_reg);
}
offset_reg = ip;
offset_imm = 0;
}
PREP_MEM_OPERAND(offset_reg, offset_imm, ip)
lay(ip,
MemOperand(dst_addr, offset_reg == no_reg ? r0 : offset_reg, offset_imm));
@ -901,7 +879,8 @@ void LiftoffAssembler::AtomicAnd(Register dst_addr, Register offset_reg,
void LiftoffAssembler::AtomicOr(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister value,
LiftoffRegister result, StoreType type) {
LiftoffRegister result, StoreType type,
bool i64_offset) {
Register tmp1 = GetUnusedRegister(kGpReg, LiftoffRegList{dst_addr, offset_reg,
value, result})
.gp();
@ -909,14 +888,7 @@ void LiftoffAssembler::AtomicOr(Register dst_addr, Register offset_reg,
value, result, tmp1})
.gp();
if (!is_int20(offset_imm)) {
mov(ip, Operand(offset_imm));
if (offset_reg != no_reg) {
AddS64(ip, offset_reg);
}
offset_reg = ip;
offset_imm = 0;
}
PREP_MEM_OPERAND(offset_reg, offset_imm, ip)
lay(ip,
MemOperand(dst_addr, offset_reg == no_reg ? r0 : offset_reg, offset_imm));
@ -1001,7 +973,8 @@ void LiftoffAssembler::AtomicOr(Register dst_addr, Register offset_reg,
void LiftoffAssembler::AtomicXor(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister value,
LiftoffRegister result, StoreType type) {
LiftoffRegister result, StoreType type,
bool i64_offset) {
Register tmp1 = GetUnusedRegister(kGpReg, LiftoffRegList{dst_addr, offset_reg,
value, result})
.gp();
@ -1009,14 +982,7 @@ void LiftoffAssembler::AtomicXor(Register dst_addr, Register offset_reg,
value, result, tmp1})
.gp();
if (!is_int20(offset_imm)) {
mov(ip, Operand(offset_imm));
if (offset_reg != no_reg) {
AddS64(ip, offset_reg);
}
offset_reg = ip;
offset_imm = 0;
}
PREP_MEM_OPERAND(offset_reg, offset_imm, ip)
lay(ip,
MemOperand(dst_addr, offset_reg == no_reg ? r0 : offset_reg, offset_imm));
@ -1102,15 +1068,9 @@ void LiftoffAssembler::AtomicXor(Register dst_addr, Register offset_reg,
void LiftoffAssembler::AtomicExchange(Register dst_addr, Register offset_reg,
uintptr_t offset_imm,
LiftoffRegister value,
LiftoffRegister result, StoreType type) {
if (!is_int20(offset_imm)) {
mov(ip, Operand(offset_imm));
if (offset_reg != no_reg) {
AddS64(ip, offset_reg);
}
offset_reg = ip;
offset_imm = 0;
}
LiftoffRegister result, StoreType type,
bool i64_offset) {
PREP_MEM_OPERAND(offset_reg, offset_imm, ip)
lay(ip,
MemOperand(dst_addr, offset_reg == no_reg ? r0 : offset_reg, offset_imm));
@ -1178,15 +1138,8 @@ void LiftoffAssembler::AtomicExchange(Register dst_addr, Register offset_reg,
void LiftoffAssembler::AtomicCompareExchange(
Register dst_addr, Register offset_reg, uintptr_t offset_imm,
LiftoffRegister expected, LiftoffRegister new_value, LiftoffRegister result,
StoreType type) {
if (!is_int20(offset_imm)) {
mov(ip, Operand(offset_imm));
if (offset_reg != no_reg) {
AddS64(ip, offset_reg);
}
offset_reg = ip;
offset_imm = 0;
}
StoreType type, bool i64_offset) {
PREP_MEM_OPERAND(offset_reg, offset_imm, ip)
lay(ip,
MemOperand(dst_addr, offset_reg == no_reg ? r0 : offset_reg, offset_imm));