From cd512c3d833665be9aeaa64e296fb7e907af96c5 Mon Sep 17 00:00:00 2001 From: Zhao Jiazhong Date: Wed, 6 Nov 2019 20:20:47 -0500 Subject: [PATCH] [mips][Liftoff] Implement i64 popcnt port d710756 https://crrev.com/c/1895569 Original Commit Message: [Liftoff] Implement i64 popcnt This is the last remaining missing instruction from the MVP. This CL adds support for ia32, x64, arm, and arm64. For CPUs which do not support the POPCNT instruction, there exists a fallback implementation in C. Change-Id: I2ebc7bc93c2a915f21139248ac1234146a1e8cb9 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1902887 Auto-Submit: Zhao Jiazhong Reviewed-by: Clemens Backes Commit-Queue: Clemens Backes Cr-Commit-Position: refs/heads/master@{#64827} --- src/wasm/baseline/mips/liftoff-assembler-mips.h | 13 +++++++++++++ src/wasm/baseline/mips64/liftoff-assembler-mips64.h | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/src/wasm/baseline/mips/liftoff-assembler-mips.h b/src/wasm/baseline/mips/liftoff-assembler-mips.h index 32dd95133e..3e9b05f6b0 100644 --- a/src/wasm/baseline/mips/liftoff-assembler-mips.h +++ b/src/wasm/baseline/mips/liftoff-assembler-mips.h @@ -898,6 +898,19 @@ void LiftoffAssembler::emit_i64_ctz(LiftoffRegister dst, LiftoffRegister src) { mov(dst.high_gp(), zero_reg); // High word of result is always 0. } +bool LiftoffAssembler::emit_i64_popcnt(LiftoffRegister dst, + LiftoffRegister src) { + // Produce partial popcnts in the two dst registers. + Register src1 = src.high_gp() == dst.low_gp() ? src.high_gp() : src.low_gp(); + Register src2 = src.high_gp() == dst.low_gp() ? src.low_gp() : src.high_gp(); + TurboAssembler::Popcnt(dst.low_gp(), src1); + TurboAssembler::Popcnt(dst.high_gp(), src2); + // Now add the two into the lower dst reg and clear the higher dst reg. + addu(dst.low_gp(), dst.low_gp(), dst.high_gp()); + mov(dst.high_gp(), zero_reg); + return true; +} + void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) { // This is a nop on mips32. } diff --git a/src/wasm/baseline/mips64/liftoff-assembler-mips64.h b/src/wasm/baseline/mips64/liftoff-assembler-mips64.h index d3979925ef..42d2b4a4c2 100644 --- a/src/wasm/baseline/mips64/liftoff-assembler-mips64.h +++ b/src/wasm/baseline/mips64/liftoff-assembler-mips64.h @@ -564,6 +564,12 @@ void LiftoffAssembler::emit_i64_ctz(LiftoffRegister dst, LiftoffRegister src) { Ctz(dst.gp(), src.gp()); } +bool LiftoffAssembler::emit_i64_popcnt(LiftoffRegister dst, + LiftoffRegister src) { + TurboAssembler::Popcnt(dst.gp(), src.gp()); + return true; +} + void LiftoffAssembler::emit_i32_mul(Register dst, Register lhs, Register rhs) { TurboAssembler::Mul(dst, lhs, rhs); }