Commit 6ce09628 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[Liftoff] Implement i32.rol and i32.ror

These opcodes will always call out to a C function for now.

R=titzer@chromium.org

Bug: v8:6600
Change-Id: I0ba8984d593c0203b46c2814dec4c091754df99a
Reviewed-on: https://chromium-review.googlesource.com/860924
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50551}
parent 10f2a1a6
......@@ -1012,6 +1012,16 @@ ExternalReference ExternalReference::wasm_word64_popcnt(Isolate* isolate) {
Redirect(isolate, FUNCTION_ADDR(wasm::word64_popcnt_wrapper)));
}
ExternalReference ExternalReference::wasm_word32_rol(Isolate* isolate) {
return ExternalReference(
Redirect(isolate, FUNCTION_ADDR(wasm::word32_rol_wrapper)));
}
ExternalReference ExternalReference::wasm_word32_ror(Isolate* isolate) {
return ExternalReference(
Redirect(isolate, FUNCTION_ADDR(wasm::word32_ror_wrapper)));
}
static void f64_acos_wrapper(double* param) {
WriteDoubleValue(param, base::ieee754::acos(ReadDoubleValue(param)));
}
......
......@@ -873,6 +873,8 @@ class ExternalReference BASE_EMBEDDED {
static ExternalReference wasm_word64_ctz(Isolate* isolate);
static ExternalReference wasm_word32_popcnt(Isolate* isolate);
static ExternalReference wasm_word64_popcnt(Isolate* isolate);
static ExternalReference wasm_word32_rol(Isolate* isolate);
static ExternalReference wasm_word32_ror(Isolate* isolate);
static ExternalReference wasm_float64_pow(Isolate* isolate);
static ExternalReference wasm_set_thread_in_wasm_flag(Isolate* isolate);
static ExternalReference wasm_clear_thread_in_wasm_flag(Isolate* isolate);
......
......@@ -473,11 +473,9 @@ class LiftoffCompiler {
void I32UnOp(bool (LiftoffAssembler::*emit_fn)(Register, Register),
ExternalReference (*fallback_fn)(Isolate*)) {
LiftoffRegList pinned_regs;
LiftoffRegister dst_reg =
pinned_regs.set(__ GetUnaryOpTargetRegister(kGpReg));
LiftoffRegister src_reg =
pinned_regs.set(__ PopToRegister(kGpReg, pinned_regs));
LiftoffRegList pinned;
LiftoffRegister dst_reg = pinned.set(__ GetUnaryOpTargetRegister(kGpReg));
LiftoffRegister src_reg = pinned.set(__ PopToRegister(kGpReg, pinned));
if (!emit_fn || !(asm_->*emit_fn)(dst_reg.gp(), src_reg.gp())) {
ExternalReference ext_ref = fallback_fn(asm_->isolate());
Register args[] = {src_reg.gp()};
......@@ -506,25 +504,32 @@ class LiftoffCompiler {
void I32BinOp(void (LiftoffAssembler::*emit_fn)(Register, Register,
Register)) {
LiftoffRegList pinned_regs;
LiftoffRegister target_reg =
pinned_regs.set(__ GetBinaryOpTargetRegister(kGpReg));
LiftoffRegister rhs_reg =
pinned_regs.set(__ PopToRegister(kGpReg, pinned_regs));
LiftoffRegister lhs_reg = __ PopToRegister(kGpReg, pinned_regs);
(asm_->*emit_fn)(target_reg.gp(), lhs_reg.gp(), rhs_reg.gp());
__ PushRegister(kWasmI32, target_reg);
LiftoffRegList pinned;
LiftoffRegister dst_reg = pinned.set(__ GetBinaryOpTargetRegister(kGpReg));
LiftoffRegister rhs_reg = pinned.set(__ PopToRegister(kGpReg, pinned));
LiftoffRegister lhs_reg = __ PopToRegister(kGpReg, pinned);
(asm_->*emit_fn)(dst_reg.gp(), lhs_reg.gp(), rhs_reg.gp());
__ PushRegister(kWasmI32, dst_reg);
}
void I32CCallBinOp(ExternalReference ext_ref) {
LiftoffRegList pinned;
LiftoffRegister dst_reg = pinned.set(__ GetBinaryOpTargetRegister(kGpReg));
LiftoffRegister rhs_reg = pinned.set(__ PopToRegister(kGpReg, pinned));
LiftoffRegister lhs_reg = __ PopToRegister(kGpReg, pinned);
Register args[] = {lhs_reg.gp(), rhs_reg.gp()};
GenerateCCall(dst_reg.gp(), arraysize(args), args, ext_ref);
__ PushRegister(kWasmI32, dst_reg);
}
void F32BinOp(void (LiftoffAssembler::*emit_fn)(DoubleRegister,
DoubleRegister,
DoubleRegister)) {
LiftoffRegList pinned_regs;
LiftoffRegList pinned;
LiftoffRegister target_reg =
pinned_regs.set(__ GetBinaryOpTargetRegister(kFpReg));
LiftoffRegister rhs_reg =
pinned_regs.set(__ PopToRegister(kFpReg, pinned_regs));
LiftoffRegister lhs_reg = __ PopToRegister(kFpReg, pinned_regs);
pinned.set(__ GetBinaryOpTargetRegister(kFpReg));
LiftoffRegister rhs_reg = pinned.set(__ PopToRegister(kFpReg, pinned));
LiftoffRegister lhs_reg = __ PopToRegister(kFpReg, pinned);
(asm_->*emit_fn)(target_reg.fp(), lhs_reg.fp(), rhs_reg.fp());
__ PushRegister(kWasmF32, target_reg);
}
......@@ -534,6 +539,10 @@ class LiftoffCompiler {
#define CASE_BINOP(opcode, type, fn) \
case WasmOpcode::kExpr##opcode: \
return type##BinOp(&LiftoffAssembler::emit_##fn);
#define CASE_CCALL_BINOP(opcode, type, ext_ref_fn) \
case WasmOpcode::kExpr##opcode: \
type##CCallBinOp(ExternalReference::ext_ref_fn(asm_->isolate())); \
break;
switch (opcode) {
CASE_BINOP(I32Add, I32, i32_add)
CASE_BINOP(I32Sub, I32, i32_sub)
......@@ -544,6 +553,8 @@ class LiftoffCompiler {
CASE_BINOP(I32Shl, I32, i32_shl)
CASE_BINOP(I32ShrS, I32, i32_sar)
CASE_BINOP(I32ShrU, I32, i32_shr)
CASE_CCALL_BINOP(I32Rol, I32, wasm_word32_rol)
CASE_CCALL_BINOP(I32Ror, I32, wasm_word32_ror)
CASE_BINOP(F32Add, F32, f32_add)
CASE_BINOP(F32Sub, F32, f32_sub)
CASE_BINOP(F32Mul, F32, f32_mul)
......@@ -551,6 +562,7 @@ class LiftoffCompiler {
return unsupported(decoder, WasmOpcodes::OpcodeName(opcode));
}
#undef CASE_BINOP
#undef CASE_CCALL_BINOP
}
void I32Const(Decoder* decoder, Value* result, int32_t value) {
......
......@@ -201,21 +201,29 @@ int32_t uint64_mod_wrapper(uint64_t* dst, uint64_t* src) {
}
uint32_t word32_ctz_wrapper(uint32_t* input) {
return static_cast<uint32_t>(base::bits::CountTrailingZeros(*input));
return base::bits::CountTrailingZeros(*input);
}
uint32_t word64_ctz_wrapper(uint64_t* input) {
return static_cast<uint32_t>(
base::bits::CountTrailingZeros(ReadUnalignedValue<uint64_t>(input)));
return base::bits::CountTrailingZeros(ReadUnalignedValue<uint64_t>(input));
}
uint32_t word32_popcnt_wrapper(uint32_t* input) {
return static_cast<uint32_t>(base::bits::CountPopulation(*input));
return base::bits::CountPopulation(*input);
}
uint32_t word64_popcnt_wrapper(uint64_t* input) {
return static_cast<uint32_t>(
base::bits::CountPopulation(ReadUnalignedValue<uint64_t>(input)));
return base::bits::CountPopulation(ReadUnalignedValue<uint64_t>(input));
}
uint32_t word32_rol_wrapper(uint32_t* input_p, uint32_t* shift_p) {
uint32_t shift = (*shift_p & 31);
return (*input_p << shift) | (*input_p >> (32 - shift));
}
uint32_t word32_ror_wrapper(uint32_t* input_p, uint32_t* shift_p) {
uint32_t shift = (*shift_p & 31);
return (*input_p >> shift) | (*input_p << (32 - shift));
}
void float64_pow_wrapper(double* param0, double* param1) {
......
......@@ -59,6 +59,10 @@ uint32_t word32_popcnt_wrapper(uint32_t* input);
uint32_t word64_popcnt_wrapper(uint64_t* input);
uint32_t word32_rol_wrapper(uint32_t* input_p, uint32_t* shift_p);
uint32_t word32_ror_wrapper(uint32_t* input_p, uint32_t* shift_p);
void float64_pow_wrapper(double* param0, double* param1);
void set_thread_in_wasm_flag();
......
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