From e95e3f1252fc6131fec0e146550bdab0f6f66070 Mon Sep 17 00:00:00 2001 From: Ng Zhi An Date: Wed, 16 Sep 2020 21:29:59 -0700 Subject: [PATCH] [wasm-simd][liftoff][arm][arm64] Implement floating-point roundings Implement f32x4 and f64x2 nearest, trunc, ceil, and floor for arm and arm64. arm implementation will check for ARMv8 support, and bail out to runtime call if not supported. Bug: v8:10906 Change-Id: Ia473f63de3717d02d4cea2fc888befb3681e20aa Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2415769 Reviewed-by: Bill Budge Commit-Queue: Zhi An Ng Cr-Commit-Position: refs/heads/master@{#70004} --- src/wasm/baseline/arm/liftoff-assembler-arm.h | 64 ++++++++++++++++--- .../baseline/arm64/liftoff-assembler-arm64.h | 16 ++--- 2 files changed, 64 insertions(+), 16 deletions(-) diff --git a/src/wasm/baseline/arm/liftoff-assembler-arm.h b/src/wasm/baseline/arm/liftoff-assembler-arm.h index 189544990c..b55cb9fba4 100644 --- a/src/wasm/baseline/arm/liftoff-assembler-arm.h +++ b/src/wasm/baseline/arm/liftoff-assembler-arm.h @@ -2335,25 +2335,49 @@ void LiftoffAssembler::emit_f64x2_sqrt(LiftoffRegister dst, bool LiftoffAssembler::emit_f64x2_ceil(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f64x2.ceil"); + if (!CpuFeatures::IsSupported(ARMv8)) { + return false; + } + + CpuFeatureScope scope(this, ARMv8); + vrintp(dst.low_fp(), src.low_fp()); + vrintp(dst.high_fp(), src.high_fp()); return true; } bool LiftoffAssembler::emit_f64x2_floor(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f64x2.floor"); + if (!CpuFeatures::IsSupported(ARMv8)) { + return false; + } + + CpuFeatureScope scope(this, ARMv8); + vrintm(dst.low_fp(), src.low_fp()); + vrintm(dst.high_fp(), src.high_fp()); return true; } bool LiftoffAssembler::emit_f64x2_trunc(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f64x2.trunc"); + if (!CpuFeatures::IsSupported(ARMv8)) { + return false; + } + + CpuFeatureScope scope(this, ARMv8); + vrintz(dst.low_fp(), src.low_fp()); + vrintz(dst.high_fp(), src.high_fp()); return true; } bool LiftoffAssembler::emit_f64x2_nearest_int(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f64x2.nearest_int"); + if (!CpuFeatures::IsSupported(ARMv8)) { + return false; + } + + CpuFeatureScope scope(this, ARMv8); + vrintn(dst.low_fp(), src.low_fp()); + vrintn(dst.high_fp(), src.high_fp()); return true; } @@ -2486,25 +2510,49 @@ void LiftoffAssembler::emit_f32x4_sqrt(LiftoffRegister dst, bool LiftoffAssembler::emit_f32x4_ceil(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f32x4.ceil"); + if (!CpuFeatures::IsSupported(ARMv8)) { + return false; + } + + CpuFeatureScope scope(this, ARMv8); + vrintp(NeonS32, liftoff::GetSimd128Register(dst), + liftoff::GetSimd128Register(src)); return true; } bool LiftoffAssembler::emit_f32x4_floor(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f32x4.floor"); + if (!CpuFeatures::IsSupported(ARMv8)) { + return false; + } + + CpuFeatureScope scope(this, ARMv8); + vrintm(NeonS32, liftoff::GetSimd128Register(dst), + liftoff::GetSimd128Register(src)); return true; } bool LiftoffAssembler::emit_f32x4_trunc(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f32x4.trunc"); + if (!CpuFeatures::IsSupported(ARMv8)) { + return false; + } + + CpuFeatureScope scope(this, ARMv8); + vrintz(NeonS32, liftoff::GetSimd128Register(dst), + liftoff::GetSimd128Register(src)); return true; } bool LiftoffAssembler::emit_f32x4_nearest_int(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f32x4.nearest_int"); + if (!CpuFeatures::IsSupported(ARMv8)) { + return false; + } + + CpuFeatureScope scope(this, ARMv8); + vrintn(NeonS32, liftoff::GetSimd128Register(dst), + liftoff::GetSimd128Register(src)); return true; } diff --git a/src/wasm/baseline/arm64/liftoff-assembler-arm64.h b/src/wasm/baseline/arm64/liftoff-assembler-arm64.h index 03cc28af07..9bb9c07794 100644 --- a/src/wasm/baseline/arm64/liftoff-assembler-arm64.h +++ b/src/wasm/baseline/arm64/liftoff-assembler-arm64.h @@ -1566,25 +1566,25 @@ void LiftoffAssembler::emit_f64x2_sqrt(LiftoffRegister dst, bool LiftoffAssembler::emit_f64x2_ceil(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f64x2.ceil"); + Frintp(dst.fp().V2D(), src.fp().V2D()); return true; } bool LiftoffAssembler::emit_f64x2_floor(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f64x2.floor"); + Frintm(dst.fp().V2D(), src.fp().V2D()); return true; } bool LiftoffAssembler::emit_f64x2_trunc(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f64x2.trunc"); + Frintz(dst.fp().V2D(), src.fp().V2D()); return true; } bool LiftoffAssembler::emit_f64x2_nearest_int(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f64x2.nearest_int"); + Frintn(dst.fp().V2D(), src.fp().V2D()); return true; } @@ -1690,25 +1690,25 @@ void LiftoffAssembler::emit_f32x4_sqrt(LiftoffRegister dst, bool LiftoffAssembler::emit_f32x4_ceil(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f32x4.ceil"); + Frintp(dst.fp().V4S(), src.fp().V4S()); return true; } bool LiftoffAssembler::emit_f32x4_floor(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f32x4.floor"); + Frintm(dst.fp().V4S(), src.fp().V4S()); return true; } bool LiftoffAssembler::emit_f32x4_trunc(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f32x4.trunc"); + Frintz(dst.fp().V4S(), src.fp().V4S()); return true; } bool LiftoffAssembler::emit_f32x4_nearest_int(LiftoffRegister dst, LiftoffRegister src) { - bailout(kSimd, "f32x4.nearest_int"); + Frintn(dst.fp().V4S(), src.fp().V4S()); return true; }