// SPDX-License-Identifier: GPL-2.01/* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny. */23#include <math-emu/soft-fp.h>45#undef count_leading_zeros6#define count_leading_zeros __FP_CLZ78void9_fp_udivmodti4(_FP_W_TYPE q[2], _FP_W_TYPE r[2],10_FP_W_TYPE n1, _FP_W_TYPE n0,11_FP_W_TYPE d1, _FP_W_TYPE d0)12{13_FP_W_TYPE q0, q1, r0, r1;14_FP_I_TYPE b, bm;1516if (d1 == 0)17{18#if !UDIV_NEEDS_NORMALIZATION19if (d0 > n1)20{21/* 0q = nn / 0D */2223udiv_qrnnd (q0, n0, n1, n0, d0);24q1 = 0;2526/* Remainder in n0. */27}28else29{30/* qq = NN / 0d */3132if (d0 == 0)33d0 = 1 / d0; /* Divide intentionally by zero. */3435udiv_qrnnd (q1, n1, 0, n1, d0);36udiv_qrnnd (q0, n0, n1, n0, d0);3738/* Remainder in n0. */39}4041r0 = n0;42r1 = 0;4344#else /* UDIV_NEEDS_NORMALIZATION */4546if (d0 > n1)47{48/* 0q = nn / 0D */4950count_leading_zeros (bm, d0);5152if (bm != 0)53{54/* Normalize, i.e. make the most significant bit of the55denominator set. */5657d0 = d0 << bm;58n1 = (n1 << bm) | (n0 >> (_FP_W_TYPE_SIZE - bm));59n0 = n0 << bm;60}6162udiv_qrnnd (q0, n0, n1, n0, d0);63q1 = 0;6465/* Remainder in n0 >> bm. */66}67else68{69/* qq = NN / 0d */7071if (d0 == 0)72d0 = 1 / d0; /* Divide intentionally by zero. */7374count_leading_zeros (bm, d0);7576if (bm == 0)77{78/* From (n1 >= d0) /\ (the most significant bit of d0 is set),79conclude (the most significant bit of n1 is set) /\ (the80leading quotient digit q1 = 1).8182This special case is necessary, not an optimization.83(Shifts counts of SI_TYPE_SIZE are undefined.) */8485n1 -= d0;86q1 = 1;87}88else89{90_FP_W_TYPE n2;9192/* Normalize. */9394b = _FP_W_TYPE_SIZE - bm;9596d0 = d0 << bm;97n2 = n1 >> b;98n1 = (n1 << bm) | (n0 >> b);99n0 = n0 << bm;100101udiv_qrnnd (q1, n1, n2, n1, d0);102}103104/* n1 != d0... */105106udiv_qrnnd (q0, n0, n1, n0, d0);107108/* Remainder in n0 >> bm. */109}110111r0 = n0 >> bm;112r1 = 0;113#endif /* UDIV_NEEDS_NORMALIZATION */114}115else116{117if (d1 > n1)118{119/* 00 = nn / DD */120121q0 = 0;122q1 = 0;123124/* Remainder in n1n0. */125r0 = n0;126r1 = n1;127}128else129{130/* 0q = NN / dd */131132count_leading_zeros (bm, d1);133if (bm == 0)134{135/* From (n1 >= d1) /\ (the most significant bit of d1 is set),136conclude (the most significant bit of n1 is set) /\ (the137quotient digit q0 = 0 or 1).138139This special case is necessary, not an optimization. */140141/* The condition on the next line takes advantage of that142n1 >= d1 (true due to program flow). */143if (n1 > d1 || n0 >= d0)144{145q0 = 1;146sub_ddmmss (n1, n0, n1, n0, d1, d0);147}148else149q0 = 0;150151q1 = 0;152153r0 = n0;154r1 = n1;155}156else157{158_FP_W_TYPE m1, m0, n2;159160/* Normalize. */161162b = _FP_W_TYPE_SIZE - bm;163164d1 = (d1 << bm) | (d0 >> b);165d0 = d0 << bm;166n2 = n1 >> b;167n1 = (n1 << bm) | (n0 >> b);168n0 = n0 << bm;169170udiv_qrnnd (q0, n1, n2, n1, d1);171umul_ppmm (m1, m0, q0, d0);172173if (m1 > n1 || (m1 == n1 && m0 > n0))174{175q0--;176sub_ddmmss (m1, m0, m1, m0, d1, d0);177}178179q1 = 0;180181/* Remainder in (n1n0 - m1m0) >> bm. */182sub_ddmmss (n1, n0, n1, n0, m1, m0);183r0 = (n1 << b) | (n0 >> bm);184r1 = n1 >> bm;185}186}187}188189q[0] = q0; q[1] = q1;190r[0] = r0, r[1] = r1;191}192193194