浏览代码

waterDataStatisticsCrossAssociation correlativeCalculationWaterTankFireHydrant.c 徐寅秋 commit at 2021-04-06

徐寅秋 4 年之前
父节点
当前提交
537ecf029c

+ 142 - 0
waterDataStatisticsCrossAssociation/waterTankDataAssociation/correlativeCalculationWaterTankFireHydrant.c

@@ -1100,3 +1100,145 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr)
 	 */
 	 */
 	if (tm & VFP_INFINITY || tn & VFP_ZERO)
 	if (tm & VFP_INFINITY || tn & VFP_ZERO)
 		goto zero;
 		goto zero;
+
+	if (tn & VFP_DENORMAL)
+		vfp_single_normalise_denormal(&vsn);
+	if (tm & VFP_DENORMAL)
+		vfp_single_normalise_denormal(&vsm);
+
+	/*
+	 * Ok, we have two numbers, we can perform division.
+	 */
+	vsd.exponent = vsn.exponent - vsm.exponent + 127 - 1;
+	vsm.significand <<= 1;
+	if (vsm.significand <= (2 * vsn.significand)) {
+		vsn.significand >>= 1;
+		vsd.exponent++;
+	}
+	{
+		u64 significand = (u64)vsn.significand << 32;
+		do_div(significand, vsm.significand);
+		vsd.significand = significand;
+	}
+	if ((vsd.significand & 0x3f) == 0)
+		vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32);
+
+	return vfp_single_normaliseround(sd, &vsd, fpscr, 0, "fdiv");
+
+ vsn_nan:
+	exceptions = vfp_propagate_nan(&vsd, &vsn, &vsm, fpscr);
+ pack:
+	vfp_put_float(vfp_single_pack(&vsd), sd);
+	return exceptions;
+
+ vsm_nan:
+	exceptions = vfp_propagate_nan(&vsd, &vsm, &vsn, fpscr);
+	goto pack;
+
+ zero:
+	vsd.exponent = 0;
+	vsd.significand = 0;
+	goto pack;
+
+ divzero:
+	exceptions = FPSCR_DZC;
+ infinity:
+	vsd.exponent = 255;
+	vsd.significand = 0;
+	goto pack;
+
+ invalid:
+	vfp_put_float(vfp_single_pack(&vfp_single_default_qnan), sd);
+	return FPSCR_IOC;
+}
+
+static struct op fops[16] = {
+	[FOP_TO_IDX(FOP_FMAC)]	= { vfp_single_fmac,  0 },
+	[FOP_TO_IDX(FOP_FNMAC)]	= { vfp_single_fnmac, 0 },
+	[FOP_TO_IDX(FOP_FMSC)]	= { vfp_single_fmsc,  0 },
+	[FOP_TO_IDX(FOP_FNMSC)]	= { vfp_single_fnmsc, 0 },
+	[FOP_TO_IDX(FOP_FMUL)]	= { vfp_single_fmul,  0 },
+	[FOP_TO_IDX(FOP_FNMUL)]	= { vfp_single_fnmul, 0 },
+	[FOP_TO_IDX(FOP_FADD)]	= { vfp_single_fadd,  0 },
+	[FOP_TO_IDX(FOP_FSUB)]	= { vfp_single_fsub,  0 },
+	[FOP_TO_IDX(FOP_FDIV)]	= { vfp_single_fdiv,  0 },
+};
+
+#define FREG_BANK(x)	((x) & 0x18)
+#define FREG_IDX(x)	((x) & 7)
+
+u32 vfp_single_cpdo(u32 inst, u32 fpscr)
+{
+	u32 op = inst & FOP_MASK;
+	u32 exceptions = 0;
+	unsigned int dest;
+	unsigned int sn = vfp_get_sn(inst);
+	unsigned int sm = vfp_get_sm(inst);
+	unsigned int vecitr, veclen, vecstride;
+	struct op *fop;
+
+	vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK);
+
+	fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)];
+
+	/*
+	 * fcvtsd takes a dN register number as destination, not sN.
+	 * Technically, if bit 0 of dd is set, this is an invalid
+	 * instruction.  However, we ignore this for efficiency.
+	 * It also only operates on scalars.
+	 */
+	if (fop->flags & OP_DD)
+		dest = vfp_get_dd(inst);
+	else
+		dest = vfp_get_sd(inst);
+
+	/*
+	 * If destination bank is zero, vector length is always '1'.
+	 * ARM DDI0100F C5.1.3, C5.3.2.
+	 */
+	if ((fop->flags & OP_SCALAR) || FREG_BANK(dest) == 0)
+		veclen = 0;
+	else
+		veclen = fpscr & FPSCR_LENGTH_MASK;
+
+	pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
+		 (veclen >> FPSCR_LENGTH_BIT) + 1);
+
+	if (!fop->fn)
+		goto invalid;
+
+	for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) {
+		s32 m = vfp_get_float(sm);
+		u32 except;
+		char type;
+
+		type = fop->flags & OP_DD ? 'd' : 's';
+		if (op == FOP_EXT)
+			pr_debug("VFP: itr%d (%c%u) = op[%u] (s%u=%08x)\n",
+				 vecitr >> FPSCR_LENGTH_BIT, type, dest, sn,
+				 sm, m);
+		else
+			pr_debug("VFP: itr%d (%c%u) = (s%u) op[%u] (s%u=%08x)\n",
+				 vecitr >> FPSCR_LENGTH_BIT, type, dest, sn,
+				 FOP_TO_IDX(op), sm, m);
+
+		except = fop->fn(dest, sn, m, fpscr);
+		pr_debug("VFP: itr%d: exceptions=%08x\n",
+			 vecitr >> FPSCR_LENGTH_BIT, except);
+
+		exceptions |= except;
+
+		/*
+		 * CHECK: It appears to be undefined whether we stop when
+		 * we encounter an exception.  We continue.
+		 */
+		dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 7);
+		sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7);
+		if (FREG_BANK(sm) != 0)
+			sm = FREG_BANK(sm) + ((FREG_IDX(sm) + vecstride) & 7);
+	}
+	return exceptions;
+
+ invalid:
+	return (u32)-1;
+}