From: Jordi Vaquero Date: Tue, 7 Jan 2020 11:25:49 +0000 (+0100) Subject: arch-arm: Implement ARMv8.3-JSConv X-Git-Tag: v19.0.0.0~38 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4d039064b0b16c957c62f51b0879b7244e51960e;p=gem5.git arch-arm: Implement ARMv8.3-JSConv This commit implements Armv8 javascript float point convertion instructions VJVCT and FJCVTZS. Change-Id: I1b24839daef775bbb1eb9da5f32c4bb3843e0b28 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/25023 Reviewed-by: Giacomo Travaglini Maintainer: Giacomo Travaglini Tested-by: kokoro --- diff --git a/src/arch/arm/insts/fplib.cc b/src/arch/arm/insts/fplib.cc index 49305ecf2..460ca7c18 100644 --- a/src/arch/arm/insts/fplib.cc +++ b/src/arch/arm/insts/fplib.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2013, 2017-2018 ARM Limited +* Copyright (c) 2020 Metempsy Technology Consulting * All rights reserved * * The license below extends only to copyright in the software and shall @@ -37,10 +38,10 @@ * Authors: Edmund Grimley Evans * Thomas Grocutt */ - #include #include +#include #include "base/logging.hh" #include "fplib.hh" @@ -429,6 +430,8 @@ static inline void fp64_unpack(int *sgn, int *exp, uint64_t *mnt, uint64_t x, int mode, int *flags) { + + *sgn = x >> (FP64_BITS - 1); *exp = FP64_EXP(x); *mnt = FP64_MANT(x); @@ -4737,6 +4740,71 @@ fplibFPToFixed(uint64_t op, int fbits, bool u, FPRounding rounding, FPSCR &fpscr return result; } +uint32_t +fplibFPToFixedJS(uint64_t op, FPSCR &fpscr, bool is64, uint8_t& nz) +{ + int flags = 0; + uint32_t result; + bool Z = true; + + uint32_t sgn = bits(op, 63); + int32_t exp = bits(op, 62, 52); + uint64_t mnt = bits(op, 51, 0); + + if (exp == 0) { + if (mnt != 0) { + if (fpscr.fz) { + flags |= FPLIB_IDC; + } else { + flags |= FPLIB_IXC; + Z = 0; + } + } + result = 0; + } else if (exp == 0x7ff) { + flags |= FPLIB_IOC; + result = 0; + Z = 0; + } else { + mnt |= 1ULL << FP64_MANT_BITS; + int mnt_shft = exp - FP64_EXP_BIAS - 52; + bool err = true; + + if (abs(mnt_shft) >= FP64_BITS) { + result = 0; + Z = 0; + } else if (mnt_shft >= 0) { + result = lsl64(mnt, mnt_shft); + } else if (mnt_shft < 0) { + err = lsl64(mnt, mnt_shft+FP64_BITS) != 0; + result = lsr64(mnt, abs(mnt_shft)); + } + uint64_t max_result = (1UL << (FP32_BITS - 1)) -!sgn; + if ((exp - FP64_EXP_BIAS) > 31 || result > max_result) { + flags |= FPLIB_IOC; + Z = false; + } else if (err) { + flags |= FPLIB_IXC; + Z = false; + } + result = sgn ? -result : result; + } + if (sgn == 1 && result == 0) + Z = false; + + if (is64) { + nz = Z? 0x1: 0x0; + } else { + fpscr.n = 0; + fpscr.z = (int)Z; + fpscr.c = 0; + fpscr.v = 0; + } + + set_fpscr0(fpscr, flags); + return result; +} + template <> uint64_t fplibFPToFixed(uint16_t op, int fbits, bool u, FPRounding rounding, diff --git a/src/arch/arm/insts/fplib.hh b/src/arch/arm/insts/fplib.hh index d3d77908c..a90999d5d 100644 --- a/src/arch/arm/insts/fplib.hh +++ b/src/arch/arm/insts/fplib.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2013, 2017-2018 ARM Limited + * Copyright (c) 2020 Metempsy Technology Consulting * All rights reserved * * The license below extends only to copyright in the software and shall @@ -174,6 +175,8 @@ T fplibInfinity(int sgn); /** Foating-point value for default NaN. */ template T fplibDefaultNaN(); +/** Floating-point JS convert to a signed integer, with rounding to zero. */ +uint32_t fplibFPToFixedJS(uint64_t op, FPSCR &fpscr, bool Is64, uint8_t &nz); /* Function specializations... */ template <> diff --git a/src/arch/arm/isa/formats/aarch64.isa b/src/arch/arm/isa/formats/aarch64.isa index 55959f506..76c7fd57e 100644 --- a/src/arch/arm/isa/formats/aarch64.isa +++ b/src/arch/arm/isa/formats/aarch64.isa @@ -2790,6 +2790,8 @@ namespace Aarch64 if (rmode != 0) return new Unknown64(machInst); return new FmovRegCoreW(machInst, rd, rn); + case 2: + return new FJcvtFpSFixedDW(machInst, rd, rn); case 3: // FMOV Xd = Dn if (rmode != 0) return new Unknown64(machInst); diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa index 133f918d9..42f0ee830 100644 --- a/src/arch/arm/isa/formats/fp.isa +++ b/src/arch/arm/isa/formats/fp.isa @@ -2761,6 +2761,14 @@ let {{ return new VcvtSIntFpD(machInst, vd, vm); } } + case 0x9: + if (bits(machInst, 31, 28) != 0xF + && bits(machInst, 27, 23) == 0x1D) { + vd = (IntRegIndex)(bits(machInst, 22) | + (bits(machInst, 15, 12) << 1)); + return new VjcvtSFixedFpD(machInst, vd, vm); + } + break; case 0xa: { const bool half = (bits(machInst, 7) == 0); diff --git a/src/arch/arm/isa/insts/fp.isa b/src/arch/arm/isa/insts/fp.isa index df4d58308..5e6a0a698 100644 --- a/src/arch/arm/isa/insts/fp.isa +++ b/src/arch/arm/isa/insts/fp.isa @@ -977,6 +977,24 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpDIop); exec_output += PredOpExecute.subst(vcvtSIntFpDIop); + vjcvtSFixedFpDCode = vfpEnabledCheckCode + ''' + FPSCR fpscr = (FPSCR) FpscrExc; + VfpSavedState state = prepFpState(fpscr.rMode); + uint64_t cOp1 = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32)); + uint8_t nz; + FpDest_uw = fplibFPToFixedJS(cOp1, fpscr, false, nz); + finishVfp(fpscr, state, fpscr.fz); + FpCondCodes = fpscr & FpCondCodesMask; + FpscrExc = fpscr; + ''' + vjcvtSFixedFpDIop = InstObjParams("vjcvt", "VjcvtSFixedFpD", "FpRegRegOp", + { "code": vjcvtSFixedFpDCode, + "predicate_test": predicateTest, + "op_class": "SimdFloatCvtOp" }, []) + header_output += FpRegRegOpDeclare.subst(vjcvtSFixedFpDIop); + decoder_output += FpRegRegOpConstructor.subst(vjcvtSFixedFpDIop); + exec_output += PredOpExecute.subst(vjcvtSFixedFpDIop); + vcvtFpUIntSRCode = vfpEnabledCheckCode + ''' FPSCR fpscr = (FPSCR) FpscrExc; VfpSavedState state = prepFpState(fpscr.rMode); diff --git a/src/arch/arm/isa/insts/fp64.isa b/src/arch/arm/isa/insts/fp64.isa index 7decbac25..409780aa0 100644 --- a/src/arch/arm/isa/insts/fp64.isa +++ b/src/arch/arm/isa/insts/fp64.isa @@ -837,6 +837,29 @@ let {{ decoder_output += AA64FpRegRegImmOpConstructor.subst(fcvtFpFixedIop); exec_output += BasicExecute.subst(fcvtFpFixedIop); + def buildFpJsCvtFixedOp(): + global header_output, decoder_output, exec_output + + fcvtFpFixedCode = vfp64EnabledCheckCode + ''' + FPSCR fpscr = (FPSCR) FpscrExc; + uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32; + uint8_t nz; + WDest = fplibFPToFixedJS(cOp1, fpscr, true, nz); + CondCodesNZ = nz; + CondCodesV = 0; + CondCodesC = 0; + FpscrExc = fpscr; + '''; + + instName = "FJcvtFpSFixedDW" + mnem = "fjcvtzs" + fcvtFpFixedIop = InstObjParams(mnem, instName, "FpRegRegOp", + { "code": fcvtFpFixedCode, + "op_class": "FloatCvtOp" }, []) + header_output += FpRegRegOpDeclare.subst(fcvtFpFixedIop); + decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpFixedIop); + exec_output += BasicExecute.subst(fcvtFpFixedIop); + # Generates the variants of the fixed to floating point instructions def buildFixedCvtFpOp(isSigned, isDouble, isXReg): global header_output, decoder_output, exec_output @@ -886,6 +909,7 @@ let {{ for isSigned in True, False: buildFpCvtFixedOp(isSigned, isDouble, isXReg) buildFixedCvtFpOp(isSigned, isDouble, isXReg) + buildFpJsCvtFixedOp(); }}; let {{