Commit 24cfb075 authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[Liftoff] Implement i64_rol and i64_ror

For now, both are implemented via a C call, just like i32_rol and
i32_ror. If they turn out to be critical for performance, we can still
implement them via hardware instructions on selected platforms.

R=jkummerow@chromium.org

Bug: v8:9919
Change-Id: I16affdfe397a08ef6a51d310f018b3a099e80e44
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1900454
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64816}
parent bcd55e15
......@@ -287,6 +287,8 @@ FUNCTION_REFERENCE(wasm_word32_popcnt, wasm::word32_popcnt_wrapper)
FUNCTION_REFERENCE(wasm_word64_popcnt, wasm::word64_popcnt_wrapper)
FUNCTION_REFERENCE(wasm_word32_rol, wasm::word32_rol_wrapper)
FUNCTION_REFERENCE(wasm_word32_ror, wasm::word32_ror_wrapper)
FUNCTION_REFERENCE(wasm_word64_rol, wasm::word64_rol_wrapper)
FUNCTION_REFERENCE(wasm_word64_ror, wasm::word64_ror_wrapper)
FUNCTION_REFERENCE(wasm_memory_copy, wasm::memory_copy_wrapper)
FUNCTION_REFERENCE(wasm_memory_fill, wasm::memory_fill_wrapper)
......
......@@ -196,6 +196,8 @@ class StatsCounter;
V(wasm_word32_popcnt, "wasm::word32_popcnt") \
V(wasm_word32_rol, "wasm::word32_rol") \
V(wasm_word32_ror, "wasm::word32_ror") \
V(wasm_word64_rol, "wasm::word64_rol") \
V(wasm_word64_ror, "wasm::word64_ror") \
V(wasm_word64_ctz, "wasm::word64_ctz") \
V(wasm_word64_popcnt, "wasm::word64_popcnt") \
V(wasm_memory_copy, "wasm::memory_copy") \
......
......@@ -3001,13 +3001,11 @@ Node* WasmGraphBuilder::BuildI64Rol(Node* left, Node* right) {
// Implement Rol by Ror since TurboFan does not have Rol opcode.
// TODO(weiliang): support Word64Rol opcode in TurboFan.
Int64Matcher m(right);
if (m.HasValue()) {
return Binop(wasm::kExprI64Ror, left,
mcgraph()->Int64Constant(64 - (m.Value() & 0x3F)));
} else {
return Binop(wasm::kExprI64Ror, left,
Binop(wasm::kExprI64Sub, mcgraph()->Int64Constant(64), right));
}
Node* inv_right =
m.HasValue()
? mcgraph()->Int64Constant(64 - (m.Value() & 0x3F))
: Binop(wasm::kExprI64Sub, mcgraph()->Int64Constant(64), right);
return Binop(wasm::kExprI64Ror, left, inv_right);
}
Node* WasmGraphBuilder::Invert(Node* node) {
......
......@@ -1023,13 +1023,15 @@ class LiftoffCompiler {
});
#define CASE_CCALL_BINOP(opcode, type, ext_ref_fn) \
case kExpr##opcode: \
return EmitBinOp<kWasmI32, kWasmI32>( \
return EmitBinOp<kWasm##type, kWasm##type>( \
[=](LiftoffRegister dst, LiftoffRegister lhs, LiftoffRegister rhs) { \
LiftoffRegister args[] = {lhs, rhs}; \
auto ext_ref = ExternalReference::ext_ref_fn(); \
ValueType sig_i_ii_reps[] = {kWasmI32, kWasmI32, kWasmI32}; \
FunctionSig sig_i_ii(1, 2, sig_i_ii_reps); \
GenerateCCall(&dst, &sig_i_ii, kWasmStmt, args, ext_ref); \
ValueType sig_reps[] = {kWasm##type, kWasm##type, kWasm##type}; \
const bool out_via_stack = kWasm##type == kWasmI64; \
FunctionSig sig(out_via_stack ? 0 : 1, 2, sig_reps); \
ValueType out_arg_type = out_via_stack ? kWasmI64 : kWasmStmt; \
GenerateCCall(&dst, &sig, out_arg_type, args, ext_ref); \
});
switch (opcode) {
CASE_I32_BINOPI(I32Add, i32_add)
......@@ -1079,11 +1081,13 @@ class LiftoffCompiler {
CASE_I32_BINOPI(I32Shl, i32_shl)
CASE_I32_BINOPI(I32ShrS, i32_sar)
CASE_I32_BINOPI(I32ShrU, i32_shr)
CASE_CCALL_BINOP(I32Rol, I32, wasm_word32_rol)
CASE_CCALL_BINOP(I32Ror, I32, wasm_word32_ror)
CASE_I64_SHIFTOP(I64Shl, i64_shl)
CASE_I64_SHIFTOP(I64ShrS, i64_sar)
CASE_I64_SHIFTOP(I64ShrU, i64_shr)
CASE_CCALL_BINOP(I32Rol, I32, wasm_word32_rol)
CASE_CCALL_BINOP(I32Ror, I32, wasm_word32_ror)
CASE_CCALL_BINOP(I64Rol, I64, wasm_word64_rol)
CASE_CCALL_BINOP(I64Ror, I64, wasm_word64_ror)
CASE_FLOAT_BINOP(F32Add, F32, f32_add)
CASE_FLOAT_BINOP(F32Sub, F32, f32_sub)
CASE_FLOAT_BINOP(F32Mul, F32, f32_mul)
......@@ -1197,10 +1201,6 @@ class LiftoffCompiler {
}
});
break;
case kExprI64Rol:
case kExprI64Ror:
return unsupported(decoder, kComplexOperation,
WasmOpcodes::OpcodeName(opcode));
default:
UNREACHABLE();
}
......
......@@ -303,6 +303,20 @@ uint32_t word32_ror_wrapper(Address data) {
return (input >> shift) | (input << ((32 - shift) & 31));
}
void word64_rol_wrapper(Address data) {
uint64_t input = ReadUnalignedValue<uint64_t>(data);
uint64_t shift = ReadUnalignedValue<uint64_t>(data + sizeof(input)) & 63;
uint64_t result = (input << shift) | (input >> ((64 - shift) & 63));
WriteUnalignedValue<uint64_t>(data, result);
}
void word64_ror_wrapper(Address data) {
uint64_t input = ReadUnalignedValue<uint64_t>(data);
uint64_t shift = ReadUnalignedValue<uint64_t>(data + sizeof(input)) & 63;
uint64_t result = (input >> shift) | (input << ((64 - shift) & 63));
WriteUnalignedValue<uint64_t>(data, result);
}
void float64_pow_wrapper(Address data) {
double x = ReadUnalignedValue<double>(data);
double y = ReadUnalignedValue<double>(data + sizeof(x));
......
......@@ -65,6 +65,10 @@ V8_EXPORT_PRIVATE uint32_t word32_rol_wrapper(Address data);
V8_EXPORT_PRIVATE uint32_t word32_ror_wrapper(Address data);
V8_EXPORT_PRIVATE void word64_rol_wrapper(Address data);
V8_EXPORT_PRIVATE void word64_ror_wrapper(Address data);
V8_EXPORT_PRIVATE void float64_pow_wrapper(Address data);
void memory_copy_wrapper(Address dst, Address src, uint32_t size);
......
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