// Copyright 2024 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef jit_riscv64_extension_Extension_riscv_zfa_h_ #define jit_riscv64_extension_Extension_riscv_zfa_h_ #include #include "jit/riscv64/base/base-assembler-riscv.h" #include "jit/riscv64/Register-riscv64.h" namespace js::jit { // Zfa Extension: Additional Floating-Point Instructions // Provides IEEE 754-2019 compliant operations and additional conversions. class AssemblerRISCVZfa : public AssemblerRiscvBase { public: // ========================================================================= // Single-Precision Zfa Instructions // ========================================================================= // fli.s: Load floating-point immediate (predefined constants) // The imm5 field (rs1) encodes which constant to load: // 0: reserved // 1: minimum positive normal // 2-29: various constants (0.5, 1.0, 2.0, 4.0, etc.) // 30: +infinity // 31: canonical NaN void fli_s(FPURegister rd, uint8_t imm5); // fminm.s / fmaxm.s: IEEE 754-2019 minimum/maximum (NaN-propagating) void fminm_s(FPURegister rd, FPURegister rs1, FPURegister rs2); void fmaxm_s(FPURegister rd, FPURegister rs1, FPURegister rs2); // fround.s: Round to integer according to rounding mode void fround_s(FPURegister rd, FPURegister rs1, FPURoundingMode frm = RNE); // froundnx.s: Round to integer with inexact exception void froundnx_s(FPURegister rd, FPURegister rs1, FPURoundingMode frm = RNE); // fleq.s / fltq.s: Quiet comparisons (no signaling on NaN) void fleq_s(Register rd, FPURegister rs1, FPURegister rs2); void fltq_s(Register rd, FPURegister rs1, FPURegister rs2); // ========================================================================= // Double-Precision Zfa Instructions // ========================================================================= // fli.d: Load floating-point immediate (predefined constants) // The imm5 field (rs1) encodes which constant to load (same values as fli.s, // but with double-precision representation) void fli_d(FPURegister rd, uint8_t imm5); // fminm.d / fmaxm.d: IEEE 754-2019 minimum/maximum (NaN-propagating) void fminm_d(FPURegister rd, FPURegister rs1, FPURegister rs2); void fmaxm_d(FPURegister rd, FPURegister rs1, FPURegister rs2); // fround.d: Round to integer according to rounding mode void fround_d(FPURegister rd, FPURegister rs1, FPURoundingMode frm = RNE); // froundnx.d: Round to integer with inexact exception void froundnx_d(FPURegister rd, FPURegister rs1, FPURoundingMode frm = RNE); // fcvtmod.w.d: Convert double to signed 32-bit integer modulo 2^32 void fcvtmod_w_d(Register rd, FPURegister rs1); // fleq.d / fltq.d: Quiet comparisons (no signaling on NaN) void fleq_d(Register rd, FPURegister rs1, FPURegister rs2); void fltq_d(Register rd, FPURegister rs1, FPURegister rs2); }; // ============================================================================= // FLI (Floating-Point Load Immediate) Constants // ============================================================================= // The FLI instruction loads one of 32 predefined floating-point constants. // The constant is selected by a 5-bit immediate (imm5) in the rs1 field. // // imm5 encoding: // 0: -1.0 // 1: minimum positive normal (FLT_MIN / DBL_MIN) // 2: 1.0 × 2⁻¹⁶ // 3: 1.0 × 2⁻¹⁵ // ... // 16: 1.0 // ... // 30: +∞ // 31: Canonical NaN // Returns the single-precision floating-point value for the given FLI.S // immediate encoding (imm5). // Precondition: imm5 <= 31 float GetFLISValue(uint8_t imm5); // Returns the double-precision floating-point value for the given FLI.D // immediate encoding (imm5). // Precondition: imm5 <= 31 double GetFLIDValue(uint8_t imm5); // Returns the FLI.S immediate encoding (imm5) for the given single-precision // floating-point value, or -1 if the value cannot be encoded by FLI.S. int GetImm5ForFLIS(float value); // Returns the FLI.D immediate encoding (imm5) for the given double-precision // floating-point value, or -1 if the value cannot be encoded by FLI.D. int GetImm5ForFLID(double value); } // namespace js::jit #endif // jit_riscv64_extension_Extension_riscv_zfa_h_