From 732fd6cdc9c7db7eea6b72cb0e27564b511b599a Mon Sep 17 00:00:00 2001 From: Zhao Jiazhong Date: Wed, 6 Nov 2019 02:31:39 -0500 Subject: [PATCH] [mips][Liftoff] Implement i64.clz and i64.ctz port e554dec [Liftoff] https://crrev.com/c/1893343 Original Commit Message: These are two of the remaining missing instructions from the MVP. This CL adds support to {LiftoffCompiler} and provides assembly implementations for ia32, x64, arm, and arm64. Change-Id: I9ebe177c4a8861c31f78af89d893cf9f2128b45b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1898832 Reviewed-by: Clemens Backes Commit-Queue: Clemens Backes Auto-Submit: Zhao Jiazhong Cr-Commit-Position: refs/heads/master@{#64797} --- .../baseline/mips/liftoff-assembler-mips.h | 34 +++++++++++++++++++ .../mips64/liftoff-assembler-mips64.h | 8 +++++ 2 files changed, 42 insertions(+) diff --git a/src/wasm/baseline/mips/liftoff-assembler-mips.h b/src/wasm/baseline/mips/liftoff-assembler-mips.h index 4509005891..3763c96b80 100644 --- a/src/wasm/baseline/mips/liftoff-assembler-mips.h +++ b/src/wasm/baseline/mips/liftoff-assembler-mips.h @@ -864,6 +864,40 @@ void LiftoffAssembler::emit_i64_shr(LiftoffRegister dst, LiftoffRegister src, kScratchReg); } +void LiftoffAssembler::emit_i64_clz(LiftoffRegister dst, LiftoffRegister src) { + // return high == 0 ? 32 + CLZ32(low) : CLZ32(high); + Label done; + Label high_is_zero; + Branch(&high_is_zero, eq, src.high_gp(), Operand(zero_reg)); + + clz(dst.low_gp(), src.high_gp()); + jmp(&done); + + bind(&high_is_zero); + clz(dst.low_gp(), src.low_gp()); + Addu(dst.low_gp(), dst.low_gp(), Operand(32)); + + bind(&done); + mov(dst.high_gp(), zero_reg); // High word of result is always 0. +} + +void LiftoffAssembler::emit_i64_ctz(LiftoffRegister dst, LiftoffRegister src) { + // return low == 0 ? 32 + CTZ32(high) : CTZ32(low); + Label done; + Label low_is_zero; + Branch(&low_is_zero, eq, src.low_gp(), Operand(zero_reg)); + + Ctz(dst.low_gp(), src.low_gp()); + jmp(&done); + + bind(&low_is_zero); + Ctz(dst.low_gp(), src.high_gp()); + Addu(dst.low_gp(), dst.low_gp(), Operand(32)); + + bind(&done); + mov(dst.high_gp(), zero_reg); // High word of result is always 0. +} + 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 b20cd69a36..6a85e5d24d 100644 --- a/src/wasm/baseline/mips64/liftoff-assembler-mips64.h +++ b/src/wasm/baseline/mips64/liftoff-assembler-mips64.h @@ -556,6 +556,14 @@ void LiftoffAssembler::FillStackSlotsWithZero(uint32_t index, uint32_t count) { } } +void LiftoffAssembler::emit_i64_clz(LiftoffRegister dst, LiftoffRegister src) { + Clz(dst.gp(), src.gp()); +} + +void LiftoffAssembler::emit_i64_ctz(LiftoffRegister dst, LiftoffRegister src) { + Ctz(dst.gp(), src.gp()); +} + void LiftoffAssembler::emit_i32_mul(Register dst, Register lhs, Register rhs) { TurboAssembler::Mul(dst, lhs, rhs); }