18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/* multi_arith.h: multi-precision integer arithmetic functions, needed
38c2ecf20Sopenharmony_ci   to do extended-precision floating point.
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci   (c) 1998 David Huggins-Daines.
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci   Somewhat based on arch/alpha/math-emu/ieee-math.c, which is (c)
88c2ecf20Sopenharmony_ci   David Mosberger-Tang.
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/* Note:
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci   These are not general multi-precision math routines.  Rather, they
158c2ecf20Sopenharmony_ci   implement the subset of integer arithmetic that we need in order to
168c2ecf20Sopenharmony_ci   multiply, divide, and normalize 128-bit unsigned mantissae.  */
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#ifndef MULTI_ARITH_H
198c2ecf20Sopenharmony_ci#define MULTI_ARITH_H
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_cistatic inline void fp_denormalize(struct fp_ext *reg, unsigned int cnt)
228c2ecf20Sopenharmony_ci{
238c2ecf20Sopenharmony_ci	reg->exp += cnt;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	switch (cnt) {
268c2ecf20Sopenharmony_ci	case 0 ... 8:
278c2ecf20Sopenharmony_ci		reg->lowmant = reg->mant.m32[1] << (8 - cnt);
288c2ecf20Sopenharmony_ci		reg->mant.m32[1] = (reg->mant.m32[1] >> cnt) |
298c2ecf20Sopenharmony_ci				   (reg->mant.m32[0] << (32 - cnt));
308c2ecf20Sopenharmony_ci		reg->mant.m32[0] = reg->mant.m32[0] >> cnt;
318c2ecf20Sopenharmony_ci		break;
328c2ecf20Sopenharmony_ci	case 9 ... 32:
338c2ecf20Sopenharmony_ci		reg->lowmant = reg->mant.m32[1] >> (cnt - 8);
348c2ecf20Sopenharmony_ci		if (reg->mant.m32[1] << (40 - cnt))
358c2ecf20Sopenharmony_ci			reg->lowmant |= 1;
368c2ecf20Sopenharmony_ci		reg->mant.m32[1] = (reg->mant.m32[1] >> cnt) |
378c2ecf20Sopenharmony_ci				   (reg->mant.m32[0] << (32 - cnt));
388c2ecf20Sopenharmony_ci		reg->mant.m32[0] = reg->mant.m32[0] >> cnt;
398c2ecf20Sopenharmony_ci		break;
408c2ecf20Sopenharmony_ci	case 33 ... 39:
418c2ecf20Sopenharmony_ci		asm volatile ("bfextu %1{%2,#8},%0" : "=d" (reg->lowmant)
428c2ecf20Sopenharmony_ci			: "m" (reg->mant.m32[0]), "d" (64 - cnt));
438c2ecf20Sopenharmony_ci		if (reg->mant.m32[1] << (40 - cnt))
448c2ecf20Sopenharmony_ci			reg->lowmant |= 1;
458c2ecf20Sopenharmony_ci		reg->mant.m32[1] = reg->mant.m32[0] >> (cnt - 32);
468c2ecf20Sopenharmony_ci		reg->mant.m32[0] = 0;
478c2ecf20Sopenharmony_ci		break;
488c2ecf20Sopenharmony_ci	case 40 ... 71:
498c2ecf20Sopenharmony_ci		reg->lowmant = reg->mant.m32[0] >> (cnt - 40);
508c2ecf20Sopenharmony_ci		if ((reg->mant.m32[0] << (72 - cnt)) || reg->mant.m32[1])
518c2ecf20Sopenharmony_ci			reg->lowmant |= 1;
528c2ecf20Sopenharmony_ci		reg->mant.m32[1] = reg->mant.m32[0] >> (cnt - 32);
538c2ecf20Sopenharmony_ci		reg->mant.m32[0] = 0;
548c2ecf20Sopenharmony_ci		break;
558c2ecf20Sopenharmony_ci	default:
568c2ecf20Sopenharmony_ci		reg->lowmant = reg->mant.m32[0] || reg->mant.m32[1];
578c2ecf20Sopenharmony_ci		reg->mant.m32[0] = 0;
588c2ecf20Sopenharmony_ci		reg->mant.m32[1] = 0;
598c2ecf20Sopenharmony_ci		break;
608c2ecf20Sopenharmony_ci	}
618c2ecf20Sopenharmony_ci}
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_cistatic inline int fp_overnormalize(struct fp_ext *reg)
648c2ecf20Sopenharmony_ci{
658c2ecf20Sopenharmony_ci	int shift;
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	if (reg->mant.m32[0]) {
688c2ecf20Sopenharmony_ci		asm ("bfffo %1{#0,#32},%0" : "=d" (shift) : "dm" (reg->mant.m32[0]));
698c2ecf20Sopenharmony_ci		reg->mant.m32[0] = (reg->mant.m32[0] << shift) | (reg->mant.m32[1] >> (32 - shift));
708c2ecf20Sopenharmony_ci		reg->mant.m32[1] = (reg->mant.m32[1] << shift);
718c2ecf20Sopenharmony_ci	} else {
728c2ecf20Sopenharmony_ci		asm ("bfffo %1{#0,#32},%0" : "=d" (shift) : "dm" (reg->mant.m32[1]));
738c2ecf20Sopenharmony_ci		reg->mant.m32[0] = (reg->mant.m32[1] << shift);
748c2ecf20Sopenharmony_ci		reg->mant.m32[1] = 0;
758c2ecf20Sopenharmony_ci		shift += 32;
768c2ecf20Sopenharmony_ci	}
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	return shift;
798c2ecf20Sopenharmony_ci}
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_cistatic inline int fp_addmant(struct fp_ext *dest, struct fp_ext *src)
828c2ecf20Sopenharmony_ci{
838c2ecf20Sopenharmony_ci	int carry;
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	/* we assume here, gcc only insert move and a clr instr */
868c2ecf20Sopenharmony_ci	asm volatile ("add.b %1,%0" : "=d,g" (dest->lowmant)
878c2ecf20Sopenharmony_ci		: "g,d" (src->lowmant), "0,0" (dest->lowmant));
888c2ecf20Sopenharmony_ci	asm volatile ("addx.l %1,%0" : "=d" (dest->mant.m32[1])
898c2ecf20Sopenharmony_ci		: "d" (src->mant.m32[1]), "0" (dest->mant.m32[1]));
908c2ecf20Sopenharmony_ci	asm volatile ("addx.l %1,%0" : "=d" (dest->mant.m32[0])
918c2ecf20Sopenharmony_ci		: "d" (src->mant.m32[0]), "0" (dest->mant.m32[0]));
928c2ecf20Sopenharmony_ci	asm volatile ("addx.l %0,%0" : "=d" (carry) : "0" (0));
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	return carry;
958c2ecf20Sopenharmony_ci}
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_cistatic inline int fp_addcarry(struct fp_ext *reg)
988c2ecf20Sopenharmony_ci{
998c2ecf20Sopenharmony_ci	if (++reg->exp == 0x7fff) {
1008c2ecf20Sopenharmony_ci		if (reg->mant.m64)
1018c2ecf20Sopenharmony_ci			fp_set_sr(FPSR_EXC_INEX2);
1028c2ecf20Sopenharmony_ci		reg->mant.m64 = 0;
1038c2ecf20Sopenharmony_ci		fp_set_sr(FPSR_EXC_OVFL);
1048c2ecf20Sopenharmony_ci		return 0;
1058c2ecf20Sopenharmony_ci	}
1068c2ecf20Sopenharmony_ci	reg->lowmant = (reg->mant.m32[1] << 7) | (reg->lowmant ? 1 : 0);
1078c2ecf20Sopenharmony_ci	reg->mant.m32[1] = (reg->mant.m32[1] >> 1) |
1088c2ecf20Sopenharmony_ci			   (reg->mant.m32[0] << 31);
1098c2ecf20Sopenharmony_ci	reg->mant.m32[0] = (reg->mant.m32[0] >> 1) | 0x80000000;
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci	return 1;
1128c2ecf20Sopenharmony_ci}
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_cistatic inline void fp_submant(struct fp_ext *dest, struct fp_ext *src1,
1158c2ecf20Sopenharmony_ci			      struct fp_ext *src2)
1168c2ecf20Sopenharmony_ci{
1178c2ecf20Sopenharmony_ci	/* we assume here, gcc only insert move and a clr instr */
1188c2ecf20Sopenharmony_ci	asm volatile ("sub.b %1,%0" : "=d,g" (dest->lowmant)
1198c2ecf20Sopenharmony_ci		: "g,d" (src2->lowmant), "0,0" (src1->lowmant));
1208c2ecf20Sopenharmony_ci	asm volatile ("subx.l %1,%0" : "=d" (dest->mant.m32[1])
1218c2ecf20Sopenharmony_ci		: "d" (src2->mant.m32[1]), "0" (src1->mant.m32[1]));
1228c2ecf20Sopenharmony_ci	asm volatile ("subx.l %1,%0" : "=d" (dest->mant.m32[0])
1238c2ecf20Sopenharmony_ci		: "d" (src2->mant.m32[0]), "0" (src1->mant.m32[0]));
1248c2ecf20Sopenharmony_ci}
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci#define fp_mul64(desth, destl, src1, src2) ({				\
1278c2ecf20Sopenharmony_ci	asm ("mulu.l %2,%1:%0" : "=d" (destl), "=d" (desth)		\
1288c2ecf20Sopenharmony_ci		: "dm" (src1), "0" (src2));				\
1298c2ecf20Sopenharmony_ci})
1308c2ecf20Sopenharmony_ci#define fp_div64(quot, rem, srch, srcl, div)				\
1318c2ecf20Sopenharmony_ci	asm ("divu.l %2,%1:%0" : "=d" (quot), "=d" (rem)		\
1328c2ecf20Sopenharmony_ci		: "dm" (div), "1" (srch), "0" (srcl))
1338c2ecf20Sopenharmony_ci#define fp_add64(dest1, dest2, src1, src2) ({				\
1348c2ecf20Sopenharmony_ci	asm ("add.l %1,%0" : "=d,dm" (dest2)				\
1358c2ecf20Sopenharmony_ci		: "dm,d" (src2), "0,0" (dest2));			\
1368c2ecf20Sopenharmony_ci	asm ("addx.l %1,%0" : "=d" (dest1)				\
1378c2ecf20Sopenharmony_ci		: "d" (src1), "0" (dest1));				\
1388c2ecf20Sopenharmony_ci})
1398c2ecf20Sopenharmony_ci#define fp_addx96(dest, src) ({						\
1408c2ecf20Sopenharmony_ci	/* we assume here, gcc only insert move and a clr instr */	\
1418c2ecf20Sopenharmony_ci	asm volatile ("add.l %1,%0" : "=d,g" (dest->m32[2])		\
1428c2ecf20Sopenharmony_ci		: "g,d" (temp.m32[1]), "0,0" (dest->m32[2]));		\
1438c2ecf20Sopenharmony_ci	asm volatile ("addx.l %1,%0" : "=d" (dest->m32[1])		\
1448c2ecf20Sopenharmony_ci		: "d" (temp.m32[0]), "0" (dest->m32[1]));		\
1458c2ecf20Sopenharmony_ci	asm volatile ("addx.l %1,%0" : "=d" (dest->m32[0])		\
1468c2ecf20Sopenharmony_ci		: "d" (0), "0" (dest->m32[0]));				\
1478c2ecf20Sopenharmony_ci})
1488c2ecf20Sopenharmony_ci#define fp_sub64(dest, src) ({						\
1498c2ecf20Sopenharmony_ci	asm ("sub.l %1,%0" : "=d,dm" (dest.m32[1])			\
1508c2ecf20Sopenharmony_ci		: "dm,d" (src.m32[1]), "0,0" (dest.m32[1]));		\
1518c2ecf20Sopenharmony_ci	asm ("subx.l %1,%0" : "=d" (dest.m32[0])			\
1528c2ecf20Sopenharmony_ci		: "d" (src.m32[0]), "0" (dest.m32[0]));			\
1538c2ecf20Sopenharmony_ci})
1548c2ecf20Sopenharmony_ci#define fp_sub96c(dest, srch, srcm, srcl) ({				\
1558c2ecf20Sopenharmony_ci	char carry;							\
1568c2ecf20Sopenharmony_ci	asm ("sub.l %1,%0" : "=d,dm" (dest.m32[2])			\
1578c2ecf20Sopenharmony_ci		: "dm,d" (srcl), "0,0" (dest.m32[2]));			\
1588c2ecf20Sopenharmony_ci	asm ("subx.l %1,%0" : "=d" (dest.m32[1])			\
1598c2ecf20Sopenharmony_ci		: "d" (srcm), "0" (dest.m32[1]));			\
1608c2ecf20Sopenharmony_ci	asm ("subx.l %2,%1; scs %0" : "=d" (carry), "=d" (dest.m32[0])	\
1618c2ecf20Sopenharmony_ci		: "d" (srch), "1" (dest.m32[0]));			\
1628c2ecf20Sopenharmony_ci	carry;								\
1638c2ecf20Sopenharmony_ci})
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_cistatic inline void fp_multiplymant(union fp_mant128 *dest, struct fp_ext *src1,
1668c2ecf20Sopenharmony_ci				   struct fp_ext *src2)
1678c2ecf20Sopenharmony_ci{
1688c2ecf20Sopenharmony_ci	union fp_mant64 temp;
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci	fp_mul64(dest->m32[0], dest->m32[1], src1->mant.m32[0], src2->mant.m32[0]);
1718c2ecf20Sopenharmony_ci	fp_mul64(dest->m32[2], dest->m32[3], src1->mant.m32[1], src2->mant.m32[1]);
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci	fp_mul64(temp.m32[0], temp.m32[1], src1->mant.m32[0], src2->mant.m32[1]);
1748c2ecf20Sopenharmony_ci	fp_addx96(dest, temp);
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci	fp_mul64(temp.m32[0], temp.m32[1], src1->mant.m32[1], src2->mant.m32[0]);
1778c2ecf20Sopenharmony_ci	fp_addx96(dest, temp);
1788c2ecf20Sopenharmony_ci}
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_cistatic inline void fp_dividemant(union fp_mant128 *dest, struct fp_ext *src,
1818c2ecf20Sopenharmony_ci				 struct fp_ext *div)
1828c2ecf20Sopenharmony_ci{
1838c2ecf20Sopenharmony_ci	union fp_mant128 tmp;
1848c2ecf20Sopenharmony_ci	union fp_mant64 tmp64;
1858c2ecf20Sopenharmony_ci	unsigned long *mantp = dest->m32;
1868c2ecf20Sopenharmony_ci	unsigned long fix, rem, first, dummy;
1878c2ecf20Sopenharmony_ci	int i;
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci	/* the algorithm below requires dest to be smaller than div,
1908c2ecf20Sopenharmony_ci	   but both have the high bit set */
1918c2ecf20Sopenharmony_ci	if (src->mant.m64 >= div->mant.m64) {
1928c2ecf20Sopenharmony_ci		fp_sub64(src->mant, div->mant);
1938c2ecf20Sopenharmony_ci		*mantp = 1;
1948c2ecf20Sopenharmony_ci	} else
1958c2ecf20Sopenharmony_ci		*mantp = 0;
1968c2ecf20Sopenharmony_ci	mantp++;
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	/* basic idea behind this algorithm: we can't divide two 64bit numbers
1998c2ecf20Sopenharmony_ci	   (AB/CD) directly, but we can calculate AB/C0, but this means this
2008c2ecf20Sopenharmony_ci	   quotient is off by C0/CD, so we have to multiply the first result
2018c2ecf20Sopenharmony_ci	   to fix the result, after that we have nearly the correct result
2028c2ecf20Sopenharmony_ci	   and only a few corrections are needed. */
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci	/* C0/CD can be precalculated, but it's an 64bit division again, but
2058c2ecf20Sopenharmony_ci	   we can make it a bit easier, by dividing first through C so we get
2068c2ecf20Sopenharmony_ci	   10/1D and now only a single shift and the value fits into 32bit. */
2078c2ecf20Sopenharmony_ci	fix = 0x80000000;
2088c2ecf20Sopenharmony_ci	dummy = div->mant.m32[1] / div->mant.m32[0] + 1;
2098c2ecf20Sopenharmony_ci	dummy = (dummy >> 1) | fix;
2108c2ecf20Sopenharmony_ci	fp_div64(fix, dummy, fix, 0, dummy);
2118c2ecf20Sopenharmony_ci	fix--;
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci	for (i = 0; i < 3; i++, mantp++) {
2148c2ecf20Sopenharmony_ci		if (src->mant.m32[0] == div->mant.m32[0]) {
2158c2ecf20Sopenharmony_ci			fp_div64(first, rem, 0, src->mant.m32[1], div->mant.m32[0]);
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_ci			fp_mul64(*mantp, dummy, first, fix);
2188c2ecf20Sopenharmony_ci			*mantp += fix;
2198c2ecf20Sopenharmony_ci		} else {
2208c2ecf20Sopenharmony_ci			fp_div64(first, rem, src->mant.m32[0], src->mant.m32[1], div->mant.m32[0]);
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci			fp_mul64(*mantp, dummy, first, fix);
2238c2ecf20Sopenharmony_ci		}
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci		fp_mul64(tmp.m32[0], tmp.m32[1], div->mant.m32[0], first - *mantp);
2268c2ecf20Sopenharmony_ci		fp_add64(tmp.m32[0], tmp.m32[1], 0, rem);
2278c2ecf20Sopenharmony_ci		tmp.m32[2] = 0;
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci		fp_mul64(tmp64.m32[0], tmp64.m32[1], *mantp, div->mant.m32[1]);
2308c2ecf20Sopenharmony_ci		fp_sub96c(tmp, 0, tmp64.m32[0], tmp64.m32[1]);
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci		src->mant.m32[0] = tmp.m32[1];
2338c2ecf20Sopenharmony_ci		src->mant.m32[1] = tmp.m32[2];
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci		while (!fp_sub96c(tmp, 0, div->mant.m32[0], div->mant.m32[1])) {
2368c2ecf20Sopenharmony_ci			src->mant.m32[0] = tmp.m32[1];
2378c2ecf20Sopenharmony_ci			src->mant.m32[1] = tmp.m32[2];
2388c2ecf20Sopenharmony_ci			*mantp += 1;
2398c2ecf20Sopenharmony_ci		}
2408c2ecf20Sopenharmony_ci	}
2418c2ecf20Sopenharmony_ci}
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_cistatic inline void fp_putmant128(struct fp_ext *dest, union fp_mant128 *src,
2448c2ecf20Sopenharmony_ci				 int shift)
2458c2ecf20Sopenharmony_ci{
2468c2ecf20Sopenharmony_ci	unsigned long tmp;
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci	switch (shift) {
2498c2ecf20Sopenharmony_ci	case 0:
2508c2ecf20Sopenharmony_ci		dest->mant.m64 = src->m64[0];
2518c2ecf20Sopenharmony_ci		dest->lowmant = src->m32[2] >> 24;
2528c2ecf20Sopenharmony_ci		if (src->m32[3] || (src->m32[2] << 8))
2538c2ecf20Sopenharmony_ci			dest->lowmant |= 1;
2548c2ecf20Sopenharmony_ci		break;
2558c2ecf20Sopenharmony_ci	case 1:
2568c2ecf20Sopenharmony_ci		asm volatile ("lsl.l #1,%0"
2578c2ecf20Sopenharmony_ci			: "=d" (tmp) : "0" (src->m32[2]));
2588c2ecf20Sopenharmony_ci		asm volatile ("roxl.l #1,%0"
2598c2ecf20Sopenharmony_ci			: "=d" (dest->mant.m32[1]) : "0" (src->m32[1]));
2608c2ecf20Sopenharmony_ci		asm volatile ("roxl.l #1,%0"
2618c2ecf20Sopenharmony_ci			: "=d" (dest->mant.m32[0]) : "0" (src->m32[0]));
2628c2ecf20Sopenharmony_ci		dest->lowmant = tmp >> 24;
2638c2ecf20Sopenharmony_ci		if (src->m32[3] || (tmp << 8))
2648c2ecf20Sopenharmony_ci			dest->lowmant |= 1;
2658c2ecf20Sopenharmony_ci		break;
2668c2ecf20Sopenharmony_ci	case 31:
2678c2ecf20Sopenharmony_ci		asm volatile ("lsr.l #1,%1; roxr.l #1,%0"
2688c2ecf20Sopenharmony_ci			: "=d" (dest->mant.m32[0])
2698c2ecf20Sopenharmony_ci			: "d" (src->m32[0]), "0" (src->m32[1]));
2708c2ecf20Sopenharmony_ci		asm volatile ("roxr.l #1,%0"
2718c2ecf20Sopenharmony_ci			: "=d" (dest->mant.m32[1]) : "0" (src->m32[2]));
2728c2ecf20Sopenharmony_ci		asm volatile ("roxr.l #1,%0"
2738c2ecf20Sopenharmony_ci			: "=d" (tmp) : "0" (src->m32[3]));
2748c2ecf20Sopenharmony_ci		dest->lowmant = tmp >> 24;
2758c2ecf20Sopenharmony_ci		if (src->m32[3] << 7)
2768c2ecf20Sopenharmony_ci			dest->lowmant |= 1;
2778c2ecf20Sopenharmony_ci		break;
2788c2ecf20Sopenharmony_ci	case 32:
2798c2ecf20Sopenharmony_ci		dest->mant.m32[0] = src->m32[1];
2808c2ecf20Sopenharmony_ci		dest->mant.m32[1] = src->m32[2];
2818c2ecf20Sopenharmony_ci		dest->lowmant = src->m32[3] >> 24;
2828c2ecf20Sopenharmony_ci		if (src->m32[3] << 8)
2838c2ecf20Sopenharmony_ci			dest->lowmant |= 1;
2848c2ecf20Sopenharmony_ci		break;
2858c2ecf20Sopenharmony_ci	}
2868c2ecf20Sopenharmony_ci}
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci#endif	/* MULTI_ARITH_H */
289