arch/powerpc/math-emu/udivmodti4.c

Source file repositories/reference/linux-study-clean/arch/powerpc/math-emu/udivmodti4.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/math-emu/udivmodti4.c
Extension
.c
Size
3531 bytes
Lines
193
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny.  */

#include <math-emu/soft-fp.h>

#undef count_leading_zeros
#define count_leading_zeros  __FP_CLZ

void
_fp_udivmodti4(_FP_W_TYPE q[2], _FP_W_TYPE r[2],
	       _FP_W_TYPE n1, _FP_W_TYPE n0,
	       _FP_W_TYPE d1, _FP_W_TYPE d0)
{
  _FP_W_TYPE q0, q1, r0, r1;
  _FP_I_TYPE b, bm;

  if (d1 == 0)
    {
#if !UDIV_NEEDS_NORMALIZATION
      if (d0 > n1)
	{
	  /* 0q = nn / 0D */

	  udiv_qrnnd (q0, n0, n1, n0, d0);
	  q1 = 0;

	  /* Remainder in n0.  */
	}
      else
	{
	  /* qq = NN / 0d */

	  if (d0 == 0)
	    d0 = 1 / d0;	/* Divide intentionally by zero.  */

	  udiv_qrnnd (q1, n1, 0, n1, d0);
	  udiv_qrnnd (q0, n0, n1, n0, d0);

	  /* Remainder in n0.  */
	}

      r0 = n0;
      r1 = 0;

#else /* UDIV_NEEDS_NORMALIZATION */

      if (d0 > n1)
	{
	  /* 0q = nn / 0D */

	  count_leading_zeros (bm, d0);

	  if (bm != 0)
	    {
	      /* Normalize, i.e. make the most significant bit of the
		 denominator set.  */

	      d0 = d0 << bm;
	      n1 = (n1 << bm) | (n0 >> (_FP_W_TYPE_SIZE - bm));
	      n0 = n0 << bm;
	    }

	  udiv_qrnnd (q0, n0, n1, n0, d0);
	  q1 = 0;

	  /* Remainder in n0 >> bm.  */
	}
      else
	{
	  /* qq = NN / 0d */

	  if (d0 == 0)
	    d0 = 1 / d0;	/* Divide intentionally by zero.  */

	  count_leading_zeros (bm, d0);

	  if (bm == 0)
	    {
	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
		 conclude (the most significant bit of n1 is set) /\ (the
		 leading quotient digit q1 = 1).

		 This special case is necessary, not an optimization.
		 (Shifts counts of SI_TYPE_SIZE are undefined.)  */

	      n1 -= d0;
	      q1 = 1;
	    }
	  else
	    {

Annotation

Implementation Notes