[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 <kyslie3100@gmail.com>
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64827}
This commit is contained in:
Zhao Jiazhong 2019-11-06 20:20:47 -05:00 committed by Commit Bot
parent 8c0b51a9e5
commit cd512c3d83
2 changed files with 19 additions and 0 deletions

View File

@ -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.
}

View File

@ -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);
}