/*
* 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
* Authors: Edmund Grimley Evans
* Thomas Grocutt
*/
-
#include <stdint.h>
#include <cassert>
+#include <cmath>
#include "base/logging.hh"
#include "fplib.hh"
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);
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,
/*
* 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
/** Foating-point value for default NaN. */
template <class T>
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 <>
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);
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);
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);
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
for isSigned in True, False:
buildFpCvtFixedOp(isSigned, isDouble, isXReg)
buildFixedCvtFpOp(isSigned, isDouble, isXReg)
+ buildFpJsCvtFixedOp();
}};
let {{