[Liftoff] Load memory size as ptr-sized int
Since https://crrev.com/c/1112003, the memory size is stored as size_t instead of uint32_t in order to support 4GB memories. Loading it as uint32_t only works on little-endian systems, and only for memory sizes <4GB. This CL fixes this to load and process the memory size as pointer-sized value. Additional platform-specific methods are added to perform a shift by a constant value. This can be reused to improve the generated code for other shifts. R=titzer@chromium.org Bug: v8:8130, v8:6600 Change-Id: Ifa688a3ed0e2809190571f24bdf47a7f53880b3d Reviewed-on: https://chromium-review.googlesource.com/1203950 Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Reviewed-by: Ben Titzer <titzer@chromium.org> Cr-Commit-Position: refs/heads/master@{#55609}
This commit is contained in:
parent
fa12290de7
commit
0e460c25a0
@ -212,6 +212,10 @@ void LiftoffAssembler::emit_i32_remu(Register dst, Register lhs, Register rhs,
|
||||
BAILOUT("i32_remu");
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_shr(Register dst, Register lhs, int amount) {
|
||||
BAILOUT("i32_shr");
|
||||
}
|
||||
|
||||
bool LiftoffAssembler::emit_i64_divs(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
LiftoffRegister rhs,
|
||||
Label* trap_div_by_zero,
|
||||
@ -237,6 +241,11 @@ bool LiftoffAssembler::emit_i64_remu(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
return false;
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i64_shr(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
int amount) {
|
||||
BAILOUT("i64_shr");
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
|
||||
// This is a nop on arm.
|
||||
}
|
||||
|
@ -391,11 +391,24 @@ void LiftoffAssembler::FillI64Half(Register, uint32_t half_index) {
|
||||
Register amount, LiftoffRegList pinned) { \
|
||||
instruction(dst.W(), src.W(), amount.W()); \
|
||||
}
|
||||
#define I32_SHIFTOP_I(name, instruction) \
|
||||
I32_SHIFTOP(name, instruction) \
|
||||
void LiftoffAssembler::emit_##name(Register dst, Register src, int amount) { \
|
||||
DCHECK(is_uint5(amount)); \
|
||||
instruction(dst.W(), src.W(), amount); \
|
||||
}
|
||||
#define I64_SHIFTOP(name, instruction) \
|
||||
void LiftoffAssembler::emit_##name(LiftoffRegister dst, LiftoffRegister src, \
|
||||
Register amount, LiftoffRegList pinned) { \
|
||||
instruction(dst.gp().X(), src.gp().X(), amount.X()); \
|
||||
}
|
||||
#define I64_SHIFTOP_I(name, instruction) \
|
||||
I64_SHIFTOP(name, instruction) \
|
||||
void LiftoffAssembler::emit_##name(LiftoffRegister dst, LiftoffRegister src, \
|
||||
int amount) { \
|
||||
DCHECK(is_uint6(amount)); \
|
||||
instruction(dst.gp().X(), src.gp().X(), amount); \
|
||||
}
|
||||
|
||||
I32_BINOP(i32_add, Add)
|
||||
I32_BINOP(i32_sub, Sub)
|
||||
@ -405,7 +418,7 @@ I32_BINOP(i32_or, Orr)
|
||||
I32_BINOP(i32_xor, Eor)
|
||||
I32_SHIFTOP(i32_shl, Lsl)
|
||||
I32_SHIFTOP(i32_sar, Asr)
|
||||
I32_SHIFTOP(i32_shr, Lsr)
|
||||
I32_SHIFTOP_I(i32_shr, Lsr)
|
||||
I64_BINOP(i64_add, Add)
|
||||
I64_BINOP(i64_sub, Sub)
|
||||
I64_BINOP(i64_mul, Mul)
|
||||
@ -414,7 +427,7 @@ I64_BINOP(i64_or, Orr)
|
||||
I64_BINOP(i64_xor, Eor)
|
||||
I64_SHIFTOP(i64_shl, Lsl)
|
||||
I64_SHIFTOP(i64_sar, Asr)
|
||||
I64_SHIFTOP(i64_shr, Lsr)
|
||||
I64_SHIFTOP_I(i64_shr, Lsr)
|
||||
FP32_BINOP(f32_add, Fadd)
|
||||
FP32_BINOP(f32_sub, Fsub)
|
||||
FP32_BINOP(f32_mul, Fmul)
|
||||
@ -450,7 +463,9 @@ FP64_UNOP(f64_sqrt, Fsqrt)
|
||||
#undef FP64_UNOP
|
||||
#undef FP64_UNOP_RETURN_TRUE
|
||||
#undef I32_SHIFTOP
|
||||
#undef I32_SHIFTOP_I
|
||||
#undef I64_SHIFTOP
|
||||
#undef I64_SHIFTOP_I
|
||||
|
||||
bool LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
|
||||
Clz(dst.W(), src.W());
|
||||
|
@ -664,6 +664,12 @@ void LiftoffAssembler::emit_i32_shr(Register dst, Register src, Register amount,
|
||||
pinned);
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_shr(Register dst, Register src, int amount) {
|
||||
if (dst != src) mov(dst, src);
|
||||
DCHECK(is_uint5(amount));
|
||||
shr(dst, amount);
|
||||
}
|
||||
|
||||
bool LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
|
||||
Label nonzero_input;
|
||||
Label continuation;
|
||||
@ -879,6 +885,13 @@ void LiftoffAssembler::emit_i64_shr(LiftoffRegister dst, LiftoffRegister src,
|
||||
&TurboAssembler::ShrPair_cl, pinned);
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i64_shr(LiftoffRegister dst, LiftoffRegister src,
|
||||
int amount) {
|
||||
if (dst != src) Move(dst, src, kWasmI64);
|
||||
DCHECK(is_uint6(amount));
|
||||
ShrPair(dst.high_gp(), dst.low_gp(), amount);
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
|
||||
// This is a nop on ia32.
|
||||
}
|
||||
|
@ -399,6 +399,7 @@ class LiftoffAssembler : public TurboAssembler {
|
||||
LiftoffRegList pinned = {});
|
||||
inline void emit_i32_shr(Register dst, Register src, Register amount,
|
||||
LiftoffRegList pinned = {});
|
||||
inline void emit_i32_shr(Register dst, Register src, int amount);
|
||||
|
||||
// i32 unops.
|
||||
inline bool emit_i32_clz(Register dst, Register src);
|
||||
@ -433,6 +434,8 @@ class LiftoffAssembler : public TurboAssembler {
|
||||
Register amount, LiftoffRegList pinned = {});
|
||||
inline void emit_i64_shr(LiftoffRegister dst, LiftoffRegister src,
|
||||
Register amount, LiftoffRegList pinned = {});
|
||||
inline void emit_i64_shr(LiftoffRegister dst, LiftoffRegister src,
|
||||
int amount);
|
||||
|
||||
inline void emit_i32_to_intptr(Register dst, Register src);
|
||||
|
||||
@ -452,6 +455,13 @@ class LiftoffAssembler : public TurboAssembler {
|
||||
emit_i32_sub(dst, lhs, rhs);
|
||||
}
|
||||
}
|
||||
inline void emit_ptrsize_shr(Register dst, Register src, int amount) {
|
||||
if (kPointerSize == 8) {
|
||||
emit_i64_shr(LiftoffRegister(dst), LiftoffRegister(src), amount);
|
||||
} else {
|
||||
emit_i32_shr(dst, src, amount);
|
||||
}
|
||||
}
|
||||
|
||||
// f32 binops.
|
||||
inline void emit_f32_add(DoubleRegister dst, DoubleRegister lhs,
|
||||
|
@ -1535,15 +1535,9 @@ class LiftoffCompiler {
|
||||
}
|
||||
|
||||
void CurrentMemoryPages(FullDecoder* decoder, Value* result) {
|
||||
LiftoffRegList pinned;
|
||||
LiftoffRegister mem_size = pinned.set(__ GetUnusedRegister(kGpReg));
|
||||
LiftoffRegister tmp_const =
|
||||
pinned.set(__ GetUnusedRegister(kGpReg, pinned));
|
||||
LOAD_INSTANCE_FIELD(mem_size, MemorySize, LoadType::kI32Load);
|
||||
// TODO(clemensh): Shift by immediate directly.
|
||||
__ LoadConstant(tmp_const,
|
||||
WasmValue(int32_t{WhichPowerOf2(kWasmPageSize)}));
|
||||
__ emit_i32_shr(mem_size.gp(), mem_size.gp(), tmp_const.gp(), pinned);
|
||||
LiftoffRegister mem_size = __ GetUnusedRegister(kGpReg);
|
||||
LOAD_INSTANCE_FIELD(mem_size, MemorySize, kPointerLoadType);
|
||||
__ emit_ptrsize_shr(mem_size.gp(), mem_size.gp(), kWasmPageSizeLog2);
|
||||
__ PushRegister(kWasmI32, mem_size);
|
||||
}
|
||||
|
||||
|
@ -624,12 +624,20 @@ bool LiftoffAssembler::emit_i32_popcnt(Register dst, Register src) {
|
||||
Register dst, Register src, Register amount, LiftoffRegList pinned) { \
|
||||
instruction(dst, src, amount); \
|
||||
}
|
||||
#define I32_SHIFTOP_I(name, instruction) \
|
||||
I32_SHIFTOP(name, instruction##v) \
|
||||
void LiftoffAssembler::emit_i32_##name(Register dst, Register src, \
|
||||
int amount) { \
|
||||
DCHECK(is_uint5(amount)); \
|
||||
instruction(dst, src, amount); \
|
||||
}
|
||||
|
||||
I32_SHIFTOP(shl, sllv)
|
||||
I32_SHIFTOP(sar, srav)
|
||||
I32_SHIFTOP(shr, srlv)
|
||||
I32_SHIFTOP_I(shr, srl)
|
||||
|
||||
#undef I32_SHIFTOP
|
||||
#undef I32_SHIFTOP_I
|
||||
|
||||
void LiftoffAssembler::emit_i64_mul(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
LiftoffRegister rhs) {
|
||||
@ -745,6 +753,13 @@ void LiftoffAssembler::emit_i64_shr(LiftoffRegister dst, LiftoffRegister src,
|
||||
&TurboAssembler::ShrPair, pinned);
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i64_shr(LiftoffRegister dst, LiftoffRegister src,
|
||||
int amount) {
|
||||
DCHECK(is_uint6(amount));
|
||||
ShrPair(dst.high_gp(), dst.low_gp(), src.high_gp(), src.low_gp(), amount,
|
||||
kScratchReg);
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
|
||||
// This is a nop on mips32.
|
||||
}
|
||||
|
@ -550,12 +550,20 @@ bool LiftoffAssembler::emit_i32_popcnt(Register dst, Register src) {
|
||||
Register dst, Register src, Register amount, LiftoffRegList pinned) { \
|
||||
instruction(dst, src, amount); \
|
||||
}
|
||||
#define I32_SHIFTOP_I(name, instruction) \
|
||||
I32_SHIFTOP(name, instruction##v) \
|
||||
void LiftoffAssembler::emit_i32_##name(Register dst, Register src, \
|
||||
int amount) { \
|
||||
DCHECK(is_uint5(amount)); \
|
||||
instruction(dst, src, amount); \
|
||||
}
|
||||
|
||||
I32_SHIFTOP(shl, sllv)
|
||||
I32_SHIFTOP(sar, srav)
|
||||
I32_SHIFTOP(shr, srlv)
|
||||
I32_SHIFTOP_I(shr, srl)
|
||||
|
||||
#undef I32_SHIFTOP
|
||||
#undef I32_SHIFTOP_I
|
||||
|
||||
void LiftoffAssembler::emit_i64_mul(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
LiftoffRegister rhs) {
|
||||
@ -628,12 +636,20 @@ I64_BINOP(xor, xor_)
|
||||
LiftoffRegList pinned) { \
|
||||
instruction(dst.gp(), src.gp(), amount); \
|
||||
}
|
||||
#define I64_SHIFTOP_I(name, instruction) \
|
||||
I64_SHIFTOP(name, instruction##v) \
|
||||
void LiftoffAssembler::emit_i64_##name(LiftoffRegister dst, \
|
||||
LiftoffRegister src, int amount) { \
|
||||
DCHECK(is_uint6(amount)); \
|
||||
instruction(dst.gp(), src.gp(), amount); \
|
||||
}
|
||||
|
||||
I64_SHIFTOP(shl, dsllv)
|
||||
I64_SHIFTOP(sar, dsrav)
|
||||
I64_SHIFTOP(shr, dsrlv)
|
||||
I64_SHIFTOP_I(shr, dsrl)
|
||||
|
||||
#undef I64_SHIFTOP
|
||||
#undef I64_SHIFTOP_I
|
||||
|
||||
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
|
||||
addu(dst, src, zero_reg);
|
||||
|
@ -217,6 +217,10 @@ void LiftoffAssembler::emit_i32_remu(Register dst, Register lhs, Register rhs,
|
||||
BAILOUT("i32_remu");
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_shr(Register dst, Register lhs, int amount) {
|
||||
BAILOUT("i32_shr");
|
||||
}
|
||||
|
||||
bool LiftoffAssembler::emit_i64_divs(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
LiftoffRegister rhs,
|
||||
Label* trap_div_by_zero,
|
||||
@ -246,6 +250,11 @@ bool LiftoffAssembler::emit_i64_remu(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
return true;
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i64_shr(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
int amount) {
|
||||
BAILOUT("i64_shr");
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
|
||||
#ifdef V8_TARGET_ARCH_PPC64
|
||||
BAILOUT("emit_i32_to_intptr");
|
||||
|
@ -217,6 +217,10 @@ void LiftoffAssembler::emit_i32_remu(Register dst, Register lhs, Register rhs,
|
||||
BAILOUT("i32_remu");
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_shr(Register dst, Register lhs, int amount) {
|
||||
BAILOUT("i32_shr");
|
||||
}
|
||||
|
||||
bool LiftoffAssembler::emit_i64_divs(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
LiftoffRegister rhs,
|
||||
Label* trap_div_by_zero,
|
||||
@ -246,6 +250,11 @@ bool LiftoffAssembler::emit_i64_remu(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
return true;
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i64_shr(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
int amount) {
|
||||
BAILOUT("i64_shr");
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
|
||||
#ifdef V8_TARGET_ARCH_S390X
|
||||
BAILOUT("emit_i32_to_intptr");
|
||||
|
@ -619,6 +619,12 @@ void LiftoffAssembler::emit_i32_shr(Register dst, Register src, Register amount,
|
||||
&Assembler::shrl_cl, pinned);
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_shr(Register dst, Register src, int amount) {
|
||||
if (dst != src) movl(dst, src);
|
||||
DCHECK(is_uint5(amount));
|
||||
shrl(dst, Immediate(amount));
|
||||
}
|
||||
|
||||
bool LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
|
||||
Label nonzero_input;
|
||||
Label continuation;
|
||||
@ -756,6 +762,13 @@ void LiftoffAssembler::emit_i64_shr(LiftoffRegister dst, LiftoffRegister src,
|
||||
&Assembler::shrq_cl, pinned);
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i64_shr(LiftoffRegister dst, LiftoffRegister src,
|
||||
int amount) {
|
||||
if (dst.gp() != src.gp()) movl(dst.gp(), src.gp());
|
||||
DCHECK(is_uint6(amount));
|
||||
shrq(dst.gp(), Immediate(amount));
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
|
||||
movsxlq(dst, src);
|
||||
}
|
||||
|
@ -76,6 +76,7 @@ enum NameSectionKindCode : uint8_t { kModule = 0, kFunction = 1, kLocal = 2 };
|
||||
|
||||
constexpr size_t kWasmPageSize = 0x10000;
|
||||
constexpr uint32_t kWasmPageSizeLog2 = 16;
|
||||
static_assert(kWasmPageSize == size_t{1} << kWasmPageSizeLog2, "consistency");
|
||||
constexpr int kInvalidExceptionTag = -1;
|
||||
|
||||
// TODO(wasm): Wrap WasmCodePosition in a struct.
|
||||
|
Loading…
Reference in New Issue
Block a user