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:
parent
8131315998
commit
35964e2418
@ -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()) {
|
||||
|
@ -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));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user