please dont rip this site

Microchip Pfu Pfu.c

/ *======================================================================*
 |	Planet Fastest Unsigned PICmicro Math				|
 |	(c) 1999 Jose Luiz Pinto Souto					|
 |	    souto@cryogen.com						|
 |									|
 |	Loop version, smallest code. All timming includes CALL and 	|
 |	RETURN instructions.						|
 |									|
 |	Compiled with CC5X, see also CC5xfree, a free 1K limited	|
 |	C compiler from B. Knudsen Data - http://www.bknd.com. 		|
 |									|
 |	For algorithm details see Microchip's application note AN617.	|
 |	PICmicro is registered Trademark of Microchip Technology Inc.	|
 |      Alpha version - please report any bug to e-mail above.          |
 |      If any faster algorithm is found, please report.                |
 *======================================================================*/

/* this software has been released to increase critical-mass PIC usage */

/*
   YOU MAY USE THIS SOFTWARE OR PART OF IT AS LONG AS YOU KEEP THE
   COPYRIGHT NOTICE. COMERCIAL PRODUCTS SHOULD HAVE A PUBLIC REFERENCE
   TO AUTHOR.

   THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
   EXPRESSED, IMPLIED OR OTHERWISE, INCLUDING AND WITHOUT LIMITATION, 
   ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INCIDENTAL, 
   INDIRECT OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT 
   LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, LOSS 
   OF INFORMATION, OR ANY OTHER LOSS) , WHETHER OR NOT ADVISED OF THE 
   POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF 
   OR IN CONNECTION WITH THE USE OR INABILITY TO USE THIS SOFTWARE. 
*/


#include <16c62a.h>
#pragma update_RP 0   	// OFF

#define uns40 unsigned int
#define uns48 unsigned int
#define uns56 unsigned int
#define uns64 unsigned int

uns8  a8;		// Load the 1st operand (  8 bits )
uns16 a16;		// Load the 1st operand ( 16 bits )
uns24 a24;		// Load the 1st operand ( 24 bits )
uns32 a32;		// Load the 1st operand ( 32 bits )

uns8  b8;		// Load the 2nd operand (  8 bits )
uns16 b16;		// Load the 2nd operand ( 16 bits )
uns24 b24;		// Load the 2nd operand ( 24 bits )
uns32 b32;		// Load the 2nd operand ( 32 bits )

uns8  r8;		// The  8 bits result
uns16 r16;		// The 16 bits result
uns24 r24;		// The 24 bits result
uns32 r32;		// The 32 bits result
uns40 r40[5];		// The 40 bits result
uns48 r48[6];		// The 48 bits result
uns64 r64[8];		// The 64 bits result

bit   Overflow;		// Division Overflow flag
bit   ZeroDiv;		// Division Divisin by Zero flag

uns8  q8;		// The  8 bits quotient
uns16 q16;		// The 16 bits quotient
uns24 q24;		// The 24 bits quotient

/*======================================================================*/
/*	Prototypes							*/
/*======================================================================*/

void negate8  (void);
void negate16 (void);
void negate24 (void);
void negate32 (void);

void negate8a  (void);
void negate16a (void);
void negate24a (void);
void negate32a (void);

void negate8b  (void);
void negate16b (void);
void negate24b (void);
void negate32b (void);

/*----------------*/

void add8  (void);
void add16 (void);
void add24 (void);
void add32 (void);

void add8a  (void);
void add16a (void);
void add24a (void);
void add32a (void);

void add8b  (void);
void add16b (void);
void add24b (void);
void add32b (void);

/*----------------*/

void sub8  (void);
void sub16 (void);
void sub24 (void);
void sub32 (void);

void sub8a  (void);
void sub16a (void);
void sub24a (void);
void sub32a (void);

/*-------------------*/

void mpy8x8 (void);

void mpy16x8 (void);
void mpy24x8 (void);
void mpy32x8 (void);

void mpy16x8a (void);
void mpy24x8a (void);
void mpy32x8a (void);

void mpy16x16 (void);
void mpy24x16 (void);
void mpy32x16 (void);

void mpy16x16a (void);
void mpy24x16a (void);
void mpy32x16a (void);

void mpy32x32  (void);
void mpy32x32a (void);


/*======================================================================*/
void negate8 (void)					      // r8 = -b8
/*======================================================================*/

{
  r8  = ~b8;
  r8++;

} // 4 instructions, 5 cycles

/*======================================================================*/
void negate8a (void)					      // b8 = -b8
/*======================================================================*/

{
  b8 = ~b8;
  b8++;

} // 3 instructions, 4 cycles

/*======================================================================*/
void negate8b (void)					    // INDF = -b8
/*======================================================================*/

{
  INDF = ~b8;
  INDF++;

} // 4 instructions, 5 cycles

/*======================================================================*/
void negate16 (void)					    // r16 = -b16
/*======================================================================*/

{
  r16.high8 = ~b16.high8;
  r16.low8  = ~b16.low8;
  r16.low8  = incsz(r16.low8);
  return;
  r16.high8++;

} // 8 instructions, min:7 max:9 cycles

/*======================================================================*/
void negate16a (void)					    // b16 = -b16
/*======================================================================*/

{
  b16.high8 = ~b16.high8;
  b16.low8  = ~b16.low8;
  b16.low8  = incsz(b16.low8);
  return;
  b16.high8++;

} // 6 instructions, min:5 max:7 cycles

/*======================================================================*/
void negate16b (void)					  // INDF = -INDF
/*======================================================================*/

{
  INDF = ~INDF;
  FSR++;
  INDF = ~INDF;
  FSR--;
  INDF = incsz(INDF);
  return;
  FSR++;
  INDF++;

} // 9 instructions, min:7 max:10 cycles

/*======================================================================*/
void negate24 (void)					    // r24 = -b24
/*======================================================================*/

{
  r24.high8 = ~b24.high8;
  r24.midL8 = ~b24.midL8;
  r24.low8  = ~b24.low8;
  r24.low8  = incsz(r24.low8);
  return;
  r24.midL8 = incsz(r24.midL8);
  return;
  r24.high8++;

} // 12 instructions, min:12 max:16 cycles

/*======================================================================*/
void negate24a (void)					    // b24 = -b24
/*======================================================================*/

{
  b24.high8 = ~b24.high8;
  b24.midL8 = ~b24.midL8;
  b24.low8  = ~b24.low8;

  b24.low8 = incsz(b24.low8);
  return;
  b24.midL8 = incsz(b24.midL8);
  return;
  b24.high8++;

} // 9 instructions, min:6 max:10 cycles

/*======================================================================*/
void negate24b (void)					  // INDF = -INDF
/*======================================================================*/

{
  W    = FSR;
  INDF = ~INDF;
  FSR++;
  INDF = ~INDF;
  FSR++;
  INDF = ~INDF;
  FSR  = W;

  INDF = incsz(INDF);
  return;
  FSR++;
  INDF = incsz(INDF);
  return;
  FSR++;
  INDF++;

} // 15 instructions, min:10 max:16 cycles

/*======================================================================*/
void negate32 (void)					    // r32 = -b32
/*======================================================================*/

{
  r32.high8 = ~b32.high8;
  r32.midH8 = ~b32.midH8;
  r32.midL8 = ~b32.midL8;
  r32.low8  = ~b32.low8;

  r32.low8 = incsz(r32.low8);
  return;
  r32.midL8 = incsz(r32.midL8);
  return;
  r32.midH8 = incsz(r32.midH8);
  return;
  r32.high8++;

} // 16 instructions, min:14 max:20 cycles

/*======================================================================*/
void negate32a (void)					    // b32 = -b32
/*======================================================================*/

{
  b32.high8 = ~b32.high8;
  b32.midH8 = ~b32.midH8;
  b32.midL8 = ~b32.midL8;
  b32.low8  = ~b32.low8;

  b32.low8 = incsz(b32.low8);
  return;
  b32.midL8 = incsz(b32.midL8);
  return;
  b32.midH8 = incsz(b32.midH8);
  return;
  b32.high8++;

} // 12 instructions, min:10 max:16 cycles

/*======================================================================*/
void negate32b (void)					   // INDF = -b32
/*======================================================================*/

{
  uns8 ww;

  ww   = FSR;
  INDF = ~b32.low8;
  FSR++;
  INDF = ~b32.midL8;
  FSR++;
  INDF = ~b32.midH8;
  FSR++;
  INDF = ~b32.high8;
  FSR  = ww;

  INDF = incsz(INDF);
  return;
  FSR++;
  INDF = incsz(INDF);
  return;
  FSR++;
  INDF = incsz(INDF);
  return;
  FSR++;
  INDF++;

} // 27 instructions, min:18 max:27 cycles

/*======================================================================*/
void add8 (void)					  // r8 = a8 + b8
/*======================================================================*/

{
  W  = b8;
  W  = a8 + W;
  r8 = W;

} // 4 instructions, 5 cycles

/*======================================================================*/
void add8a (void)					      // a8 += b8
/*======================================================================*/

{
  W   = b8;
  a8 += W;

} // 3 instructions, 4 cycles

/*======================================================================*/
void add8b (void)					    // INDF += b8
/*======================================================================*/

{
  INDF += b8;

} // 3 instructions, 4 cycles

/*======================================================================*/
void add16 (void)				       // r16 = a16 + b16
/*======================================================================*/

{
  r16.low8  = a16.low8 + b16.low8;
  r16.high8 = a16.high8;

  W = b16.high8;
  if (Carry) W = incsz(b16.high8);
  r16.high8 += W;

} // 10 instructions, 11 cycles

/*======================================================================*/
void add16a (void)					    // a16 += b16
/*======================================================================*/

{
  a16.low8 += b16.low8;

  W = b16.high8;
  if (Carry) W = incsz(b16.high8);
  a16.high8 += W;

} // 7 instructions, 8 cycles

/*======================================================================*/
void add16b (void)					   // INDF += b16
/*======================================================================*/

{
  INDF += b16.low8;
  FSR++;
  W = b16.high8;
  if (Carry) W = incsz(b16.high8);
  INDF += W;

} // 8 instructions, 9 cycles

/*======================================================================*/
void add24 (void)				       // r24 = a24 + b24
/*======================================================================*/

{
  r24.low8 = a24.low8 + b24.low8;

  r24.midL8 = a24.midL8;
  W = b24.midL8;
  if (Carry) W = incsz(b24.midL8);
  r24.midL8 += W;

  r24.high8 = a24.high8;
  W = b24.high8;
  if (Carry) W = incsz(b24.high8);
  r24.high8 += W;

} // 16 instructions, 17 cycles

/*======================================================================*/
void add24a (void)					    // a24 += b24
/*======================================================================*/

{
  a24.low8 += b24.low8;

  W = b24.midL8;
  if (Carry) W = incsz(b24.midL8);
  a16.midL8 += W;

  W = b24.high8;
  if (Carry) W = incsz(b24.high8);
  a16.high8 += W;

} // 11 instructions, 12 cycles

/*======================================================================*/
void add24b (void)					   // INDF += b24
/*======================================================================*/

{
  INDF += b24.low8;
  FSR++;

  W = b24.midL8;
  if (Carry) W = incsz(b24.midL8);
  INDF += W;
  FSR++;

  W = b24.high8;
  if (Carry) W = incsz(b24.high8);
  INDF += W;

} // 13 instructions, 14 cycles

/*======================================================================*/
void add32 (void)				       // r32 = a32 + b32
/*======================================================================*/

{
  r32.low8 = a32.low8 + b32.low8;

  r32.midL8 = a32.midL8;
  W = b32.midL8;
  if (Carry) W = incsz(b32.midL8);
  r32.midL8 += W;

  r32.midH8 = a32.midH8;
  W = b32.midH8;
  if (Carry) W = incsz(b32.midH8);
  r32.midH8 += W;

  r32.high8 = a32.high8;
  W = b32.high8;
  if (Carry) W = incsz(b32.high8);
  r32.high8 += W;

} // 22 instructions, 23 cycles

/*======================================================================*/
void add32a (void)					    // a32 += b32
/*======================================================================*/

{
  a32.low8 += b32.low8;

  W = b32.midL8;
  if (Carry) W = incsz(b32.midL8);
  a32.midL8 += W;

  W = b32.midH8;
  if (Carry) W = incsz(b32.midH8);
  a32.midH8 += W;

  W = b32.high8;
  if (Carry) W = incsz(b32.high8);
  a32.high8 += W;

} // 15 instructions, 16 cycles

/*======================================================================*/
void add32b (void)					   // INDF += b32
/*======================================================================*/

{
  INDF += b32.low8;
  FSR++;

  W = b32.midL8;
  if (Carry) W = incsz(b32.midL8);
  INDF += W;
  FSR++;

  W = b32.midH8;
  if (Carry) W = incsz(b32.midH8);
  INDF += W;
  FSR++;

  W = b32.high8;
  if (Carry) W = incsz(b32.high8);
  INDF += W;

} // 18 instructions, 19 cycles

/*======================================================================*/
void sub8 (void)					  // r8 = a8 - b8
/*======================================================================*/

{
  r8 = a8 - b8;

} // 4 instructions, 5 cycles

/*======================================================================*/
void sub8a (void)					      // a8 -= b8
/*======================================================================*/

{

  a8 -= b8;

} // 3 instructions, 4 cycles

/*======================================================================*/
void sub8b (void)					    // INDF -= b8
/*======================================================================*/

{

  INDF -= b8;

} // 3 instructions, 4 cycles

/*======================================================================*/
void sub16 (void)				       // r16 = a16 - b16
/*======================================================================*/

{
  r16.low8  = a16.low8 - b16.low8;
  r16.high8 = a16.high8;

  W = b16.high8;
  if (!Carry) W = incsz(b16.high8);
  r16.high8 -= W;

} // 10 instructions, 11 cycles

/*======================================================================*/
void sub16a (void)					    // a16 -= b16
/*======================================================================*/

{
  a16.low8 -= b16.low8;

  W = b16.high8;
  if (!Carry) W = incsz(b16.high8);
  a16.high8 -= W;

} // 7 instructions, 8 cycles

/*======================================================================*/
void sub16b (void)					   // INDF -= b16
/*======================================================================*/

{
  INDF -= b16.low8;
  FSR++;
  W = b16.high8;
  if (!Carry) W = incsz(b16.high8);
  INDF -= W;

} // 8 instructions, 9 cycles

/*======================================================================*/
void sub24 (void)				       // r24 = a24 - b24
/*======================================================================*/

{
  r24.low8 = a24.low8 - b24.low8;

  r24.midL8 = a24.midL8;
  W = b24.midL8;
  if (!Carry) W = incsz(b24.midL8);
  r24.midL8 -= W;

  r24.high8 = a24.high8;
  W = b24.high8;
  if (!Carry) W = incsz(b24.high8);
  r24.high8 -= W;

} // 16 instructions, 17 cycles

/*======================================================================*/
void sub24a (void)					    // a24 -= b24
/*======================================================================*/

{
  a24.low8  -= b24.low8;

  W = b24.midL8;
  if (!Carry) W = incsz(b24.midL8);
  a24.midL8 -= W;

  W = b24.high8;
  if (!Carry) W = incsz(b24.high8);
  a24.high8 -= W;

} // 11 instructions, 12 cycles

/*======================================================================*/
void sub24b (void)					   // INDF -= b24
/*======================================================================*/

{
  INDF -= b24.low8;
  FSR++;

  W = b24.midL8;
  if (!Carry) W = incsz(b24.midL8);
  INDF -= W;
  FSR++;

  W = b24.high8;
  if (!Carry) W = incsz(b24.high8);
  INDF -= W;

} // 13 instructions, 14 cycles

/*======================================================================*/
void sub32 (void)				       // r32 = a32 - b32
/*======================================================================*/

{
  r32.low8 = a32.low8 - b32.low8;

  r32.midL8 = a32.midL8;
  W = b32.midL8;
  if (!Carry) W = incsz(b32.midL8);
  r32.midL8 -= W;

  r32.midH8 = a32.midH8;
  W = b32.midH8;
  if (!Carry) W = incsz(b32.midH8);
  r32.midH8 -= W;

  r32.high8 = a32.high8;
  W = b32.high8;
  if (!Carry) W = incsz(b32.high8);
  r32.high8 -= W;

} // 22 instructions, 23 cycles

/*======================================================================*/
void sub32a (void)					    // a32 -= b32
/*======================================================================*/

{
  a32.low8 -= b32.low8;

  W = b32.midL8;
  if (!Carry) W = incsz(b32.midL8);
  a32.midL8 -= W;

  W = b32.midH8;
  if (!Carry) W = incsz(b32.midH8);
  a32.midH8 -= W;

  W = b32.high8;
  if (!Carry) W = incsz(b32.high8);
  a32.high8 -= W;

} // 15 instructions, 19 cycles

/*======================================================================*/
void sub32b (void)					   // INDF -= b32
/*======================================================================*/

{
  INDF -= b32.low8;
  FSR++;

  W = b32.midL8;
  if (!Carry) W = incsz(b32.midL8);
  INDF -= W;
  FSR++;

  W = b32.midH8;
  if (!Carry) W = incsz(b32.midH8);
  INDF -= W;
  FSR++;

  W = b32.high8;
  if (!Carry) W = incsz(b32.high8);
  INDF -= W;

} // 18 instructions, 19 cycles

/*======================================================================*/
void mpy8x8 (void)					 // r16 = a8 * b8
/*======================================================================*/

{
  uns8 ix;

  r16 = 0;
  W = b8;
  if (W)
  {
    r16.low8 = W;
    ix = 8;
    W = a8;
    do
    {
      Carry = 0;
      if (r16.0) r16.high8 += W;
      r16.high8 = rr (r16.high8);
      r16.low8  = rr (r16.low8);
    }
    while (--ix);
  }
} // 17 instructions, min:11, max:77 cycles

/*======================================================================*/
void mpy8x8a (void)					// INDF = a8 * b8
/*======================================================================*/

{
  uns8 ix, m;

  INDF = 0;
  FSR++;
  INDF = 0;
  W    = b8;
  if (W)
  {
    m  = W;
    ix = 8;
    W  = a8;
    do
    {
      Carry = 0;
      if (m.0) INDF += W;
      INDF = rr (INDF);
      FSR--;
      INDF = rr (INDF);
      FSR++;
      m = rr (m);
    }
    while (--ix);
  }
} // 21 instructions, min:8, max:?? cycles

/*======================================================================*/
void mpy16x8 (void)					// r24 = a16 * b8
/*======================================================================*/

{
  uns8  ix;

  W = b8;
  if (!W)
  {
    r24.high8 = 0;
    r24.low16 = 0;
  }
  else
  {
    r24.low8 = W ^ 1;
    r24.high16 = a16;
    ix = 8;
    do
    {
      W = rr(r24.low8);
      if (Carry)
      {
        r24.midL8 += a16.low8;
        W = a16.high8;
        if (Carry) W = incsz(a16.high8);
        r24.high8 += W;
      }
      r24.high8 = rr(r24.high8);
      r24.midL8 = rr(r24.midL8);
      r24.low8  = rr(r24.low8);
    }
    while (--ix);
  }
} // 30 instructions, min:10, max:131 cycles

/*======================================================================*/
void mpy16x8a (void)				       // INDF = a16 * b8
/*======================================================================*/

{
  uns8  ix, m;

  INDF = 0;
  FSR++;		// 1
  INDF = 0;
  FSR++;		// 2
  INDF = 0;
  W = b8;
  if (W)
  {
    m  = W;
    FSR--;		// 1
    ix = 8;
    do
    {
      Carry = 0;
      if (m.0)
      {
        INDF += a16.low8;
        FSR++;		// 2
        W = a16.high8;
        if (Carry) W = incsz(a16.high8);
        INDF += W;
        FSR--;		// 1
      }
      FSR++;		// 2
      INDF = rr(INDF);
      FSR--;		// 1
      INDF = rr(INDF);
      FSR--;		// 0
      INDF  = rr(INDF);
      FSR++;		// 1
      m = rr(m);
    }
    while (--ix);
  }
} // 34 instructions, min:??, max:??? cycles

/*======================================================================*/
void mpy24x8 (void)					// r32 = a24 * b8
/*======================================================================*/

{
  uns8  ix;

  W = b8;
  if (!W)
  {
    r32.high16 = 0;
    r32.low16 = 0;
  }
  else
  {
    r32.low8 = W ^ 1;
    r32.midL8 = a24.low8;
    r32.high16 = a24.high16;
    ix = 8;
    do
    {
      W = rr(r32.low8);
      if (Carry)
      {
        r32.midL8 += a24.low8;
        W = a24.midL8;
        if (Carry) W = incsz(a24.midL8);
        r32.midH8 += W;
        W = a24.high8;
        if (Carry) W = incsz(a24.high8);
        r32.high8 += W;
      }
      r32.high8 = rr(r32.high8);
      r32.midH8 = rr(r32.midH8);
      r32.midL8 = rr(r32.midL8);
      r32.low8  = rr(r32.low8);
    }
    while (--ix);
  }
} // 38 instructions, min:14, max:169 cycles

/*======================================================================*/
void mpy24x8a (void)				       // INDF = a24 * b8
/*======================================================================*/

{
  uns8  ix, m, p;

  INDF = 0;
  FSR++;		// 1
  INDF = 0;
  FSR++;		// 2
  INDF = 0;
  FSR++;		// 3
  INDF = 0;
  
  W = b8;
  if (W)
  {
    m  = W;
    ix = 8;
    p  = FSR;
    FSR--;		// 2
    FSR--;		// 1
    do
    {
      W = rr(m);
      if (Carry)
      {
        INDF += a24.low8;
        FSR++;		// 2
        W = a24.midL8;
        if (Carry) W = incsz(a24.midL8);
        INDF += W;
        FSR++;		// 3
        W = a24.high8;
        if (Carry) W = incsz(a24.high8);
        INDF += W;
      }			// else !Carry
      FSR = p;
      INDF = rr(INDF);
      FSR--;		// 2
      INDF = rr(INDF);
      FSR--;		// 1
      INDF = rr(INDF);
      FSR--;		// 0
      INDF = rr(INDF);
      FSR++;		// 1
      m = rr(m);
    }
    while (--ix);
  }
} // 46 instructions, min:13, max:??? cycles

/*======================================================================*/
void mpy32x8 (void)					// r40 = a32 * b8
/*======================================================================*/

{
  uns8  ix;

  W = b8;
  if (!W)
  {
    r40[4] = 0;
    r40[3] = 0;
    r40[2] = 0;
    r40[1] = 0;
    r40[0] = 0;
  }
  else
  {
    r40[0] = a32.high8;
    r40[1] = a32.midH8;
    r40[2] = a32.midL8;
    r40[3] = a32.low8;
    r40[4] = b8 ^ 1;
    ix = 8;
    do
    {
      Carry = 0;
      {
      if (r40[4].0)
      {
        r40[3] += a32.low8;

        W = a32.midL8;
        if (Carry) W = incsz(a32.midL8);
        r40[2] += W;

        W = a32.midH8;
        if (Carry) W = incsz(a32.midH8);
        r40[1] += W;

        W = a32.high8;
        if (Carry) W = incsz(a32.high8);
        r40[0] += W;
      }
      }
#asm
	rrf	r40+0,F		;     r40[0] = rr(r40[0]);
	rrf	r40+1,F		;     r40[1] = rr(r40[1]);
	rrf	r40+2,F		;     r40[2] = rr(r40[2]);
	rrf	r40+3,F		;     r40[3] = rr(r40[3]);
	rrf	r40+4,F		;     r40[4] = rr(r40[4]);
#endasm
    }
    while (--ix);
  }
} // 47 instructions, min:15, max:208 cycles

/*======================================================================*/
void mpy32x8a (void)				       // INDF = a32 * b8
/*======================================================================*/

{
  uns8  ix, m, p;

  INDF = 0;
  FSR++;		// 1
  INDF = 0;
  FSR++;		// 2
  INDF = 0;
  FSR++;		// 3
  INDF = 0;
  FSR++;		// 4
  INDF = 0;

  W = b8;
  if (W)
  {
    m  = W;
    ix = 8;
    p  = FSR;
    FSR--;		// 3
    FSR--;		// 2
    FSR--;		// 1
    do
    {
      W = rr(m);
      {
      if (Carry)
      {
        INDF += a32.low8;
        FSR++;		// 2
        W = a32.midL8;
        if (Carry) W = incsz(a32.midL8);
        INDF += W;
        FSR++;		// 3
        W = a32.midH8;
        if (Carry) W = incsz(a32.midH8);
        INDF += W;
        FSR++;		// 4
        W = a32.high8;
        if (Carry) W = incsz(a32.high8);
        INDF += W;
      }
      }			// else !Carry
        FSR = p;	// 4
#asm
	rrf	INDF,F
        decf    FSR,f		; 3
	rrf	INDF,F
        decf    FSR,f		; 2
	rrf	INDF,F
        decf    FSR,f		; 1
	rrf	INDF,F
        decf    FSR,f		; 0
	rrf	INDF,F
        incf    FSR,f		; 1
#endasm
    }
    while (--ix);
  }
} // 55 instructions, min:15, max:??? cycles

/*======================================================================*/
void mpy16x16 (void)				       // r32 = a16 * b16
/*======================================================================*/

{
  uns8  ix;				// temporary

  if (!b16)
  {
    r32.high16 = 0;
    r32.low16 = 0;
  }
  else
  {
    r32.high16 = a16;
    r32.midL8 = b16.high8;
    r32.low8 = b16.low8 ^ 1;
    ix = 16;
    do
    {
      Carry = 0;
      if (r32.0)
      {
        r32.midH8 += a16.low8;
        W = b16.high8;
        if (Carry) W = incsz(a16.high8);
        r32.high8 += W;
      }
      r32.high8 = rr(r32.high8);
      r32.midH8 = rr(r32.midH8);
      r32.midL8 = rr(r32.midL8);
      r32.low8  = rr(r32.low8);
    }
    while (--ix);
  }
} // 36 instructions, min:15, max:271 cycles

/*======================================================================*/
void mpy16x16a (void)				       // r32 = a16 * b16
/*======================================================================*/

{
  uns8  ix;				// temporary

  r32.high16 = 0;
  r32.low16 = 0;
  if (b16)
  {
    r32.low16 = b16;
    ix = 16;
    do
    {
      W = rr(r32.low8);
      if (Carry)
      {
        r32.midH8 += a16.low8;
        W = b16.high8;
        if (Carry) W = incsz(a16.high8);
        r32.high8 += W;
      }
      r32.high8 = rr(r32.high8);
      r32.midH8 = rr(r32.midH8);
      r32.midL8 = rr(r32.midL8);
      r32.low8  = rr(r32.low8);
    }
    while (--ix);
  }
} // 30 instructions, min:14, max:274 cycles

/*======================================================================*/
void mpy24x16 (void)				       // r40 = a24 * b16
/*======================================================================*/

{
  uns8  ix;				// temporary

  if (!b16)
  {
    r40[4] = 0;
    r40[3] = 0;
    r40[2] = 0;
    r40[1] = 0;
    r40[0] = 0;
  }
  else
  {
    r40[0] = a24.high8;
    r40[1] = a24.midL8;
    r40[2] = a24.low8;
    r40[3] = b16.high8;
    r40[4] = b16.low8 ^ 1;
    ix = 16;
    do
    {
      Carry = 0;
      {
      if (r40[4].0)
      {
        r40[2] += a24.low8;

        W = a24.midL8;
        if (Carry) W = incsz(a24.midL8);
        r40[1] += W;

        W = a24.high8;
        if (Carry) W = incsz(a24.high8);
        r40[0] += W;
      }
      }
#asm
	rrf	r40+0,F		;     r40[0] = rr(r40[0]);
	rrf	r40+1,F		;     r40[1] = rr(r40[1]);
	rrf	r40+2,F		;     r40[2] = rr(r40[2]);
	rrf	r40+3,F		;     r40[3] = rr(r40[3]);
	rrf	r40+4,F		;     r40[4] = rr(r40[4]);
#endasm
    }
    while (--ix);
  }
} // 44 instructions, min:16, max:349 cycles

/*======================================================================*/
void mpy24x16a (void)				       // r40 = a24 * b16
/*======================================================================*/

{
  uns8  ix;				// temporary

  r40[4] = 0;
  r40[3] = 0;
  r40[2] = 0;
  r40[1] = 0;
  r40[0] = 0;
  if (b16)
  {
    r40[3] = b16.high8;
    r40[4] = b16.low8 ^ 1;
    ix = 16;
    do
    {
      Carry = 0;
      {
      if (r40[4].0)
      {
        r40[2] += a24.low8;

        W = a24.midL8;
        if (Carry) W = incsz(a24.midL8);
        r40[1] += W;

        W = a24.high8;
        if (Carry) W = incsz(a24.high8);
        r40[0] += W;
      }
      }
#asm
	rrf	r40+0,F		;     r40[0] = rr(r40[0]);
	rrf	r40+1,F		;     r40[1] = rr(r40[1]);
	rrf	r40+2,F		;     r40[2] = rr(r40[2]);
	rrf	r40+3,F		;     r40[3] = rr(r40[3]);
	rrf	r40+4,F		;     r40[4] = rr(r40[4]);
#endasm
    }
    while (--ix);
  }
} // ?? instructions, min:15, max:347 cycles

/*======================================================================*/
void mpy32x16 (void)				       // r48 = a32 * b16
/*======================================================================*/

{
  uns8  ix;

  if (!b16)
  {
    r48[0] = 0;
    r48[1] = 0;
    r48[2] = 0;
    r48[3] = 0;
    r48[4] = 0;
    r48[5] = 0;
  }
  else
  {
    r48[0] = a32.high8;
    r48[1] = a32.midH8;
    r48[2] = a32.midL8;
    r48[3] = a32.low8;
    r48[4] = b16.high8;
    r48[5] = b16.low8 ^ 1;
    ix = 16;
    do
    {
      Carry = 0;
      {
      if (r48[5].0)
      {
        r48[3] += a32.low8;

        W = a32.midL8;
        if (Carry) W = incsz(a32.midL8);
        r48[2] += W;

        W = a32.midH8;
        if (Carry) W = incsz(a32.midH8);
        r48[1] += W;

        W = a32.high8;
        if (Carry) W = incsz(a32.high8);
        r48[0] += W;
      }
      }
#asm
	rrf	r48+0,F		;     r48[0] = rr(r48[0]);
	rrf	r48+1,F		;     r48[1] = rr(r48[1]);
	rrf	r48+2,F		;     r48[2] = rr(r48[2]);
	rrf	r48+3,F		;     r48[3] = rr(r48[3]);
	rrf	r48+4,F		;     r48[4] = rr(r48[4]);
	rrf	r48+5,F		;     r48[5] = rr(r48[5]);
#endasm
    }
    while (--ix);
  }
} // 52 instructions, min:17, max:427 cycles

/*======================================================================*/
void mpy32x16a (void)				       // r48 = a32 * b16
/*======================================================================*/

{

  uns8  ix;

  r48[0] = 0;
  r48[1] = 0;
  r48[2] = 0;
  r48[3] = 0;
  r48[4] = 0;
  r48[5] = 0;
  if (b16)
  {
    r48[4] = b16.high8;
    r48[5] = b16.low8;
    ix = 16;
    do
    {
      Carry = 0;
      {
      if (r48[5].0)
      {
        r48[3] += a32.low8;

        W = a32.midL8;
        if (Carry) W = incsz(a32.midL8);
        r48[2] += W;

        W = a32.midH8;
        if (Carry) W = incsz(a32.midH8);
        r48[1] += W;

        W = a32.high8;
        if (Carry) W = incsz(a32.high8);
        r48[0] += W;
      }
      }
#asm
	rrf	r48+0,F		;     r48[0] = rr(r48[0]);
	rrf	r48+1,F		;     r48[1] = rr(r48[1]);
	rrf	r48+2,F		;     r48[2] = rr(r48[2]);
	rrf	r48+3,F		;     r48[3] = rr(r48[3]);
	rrf	r48+4,F		;     r48[4] = rr(r48[4]);
	rrf	r48+5,F		;     r48[5] = rr(r48[5]);
#endasm
    }
    while (--ix);
  }

} // 42 instructions, min:16, max:436 cycles

/*======================================================================*/
void mpy32x32 (void)				       // r64 = a32 * b32
/*======================================================================*/

{

  uns8  ix;

  W = b32.high8 | b32.midH8;
  W = b32.midL8 | W;
  W = b32.low8  | W;
  if (Zero_)
  {
    r64[0] = 0;
    r64[1] = 0;
    r64[2] = 0;
    r64[3] = 0;
    r64[4] = 0;
    r64[5] = 0;
    r64[6] = 0;
    r64[7] = 0;
  }
  else
  {
    r64[0] = a32.high8;
    r64[1] = a32.midH8;
    r64[2] = a32.midL8;
    r64[3] = a32.low8;
    r64[4] = b32.high8;
    r64[5] = b32.midH8;
    r64[6] = b32.midL8;
    r64[7] = b32.low8 ^ 1;
    ix = 32;
    do
    {
      Carry = 0;
      {
      if (r64[7].0)
      {
        r64[3] += a32.low8;

        W = a32.midL8;
        if (Carry) W = incsz(a32.midL8);
        r64[2] += W;

        W = a32.midH8;
        if (Carry) W = incsz(a32.midH8);
        r64[1] += W;

        W = a32.high8;
        if (Carry) W = incsz(a32.high8);
        r64[0] += W;
      }
      }
#asm
	rrf	r64+0,F		//    r64[0] = rr(r64[0]);
	rrf	r64+1,F		//    r64[1] = rr(r64[1]);
	rrf	r64+2,F		//    r64[2] = rr(r64[2]);
	rrf	r64+3,F		//    r64[3] = rr(r64[3]);
	rrf	r64+4,F		//    r64[4] = rr(r64[4]);
	rrf	r64+5,F		//    r64[5] = rr(r64[5]);
	rrf	r64+6,F		//    r64[6] = rr(r64[6]);
	rrf	r64+7,F		//    r64[7] = rr(r64[7]);
#endasm
    }
    while (--ix);
  }

} // 62 instructions, min:21, max:913 cycles

/*======================================================================*/
void mpy32x32a (void)				       // r64 = a32 * b32
/*======================================================================*/

{

  uns8  ix;

  r64[0] = 0;
  r64[1] = 0;
  r64[2] = 0;
  r64[3] = 0;
  r64[4] = 0;
  r64[5] = 0;
  r64[6] = 0;
  r64[7] = 0;

  W = b32.high8 | b32.midH8;
  W = b32.midL8 | W;
  W = b32.low8  | W;
  if (!Zero_)
  {
    r64[4] = b32.high8;
    r64[5] = b32.midH8;
    r64[6] = b32.midL8;
    r64[7] = b32.low8;
    ix = 32;
    do
    {
      Carry = 0;
      {
      if (r64[7].0)
      {
        r64[3] += a32.low8;

        W = a32.midL8;
        if (Carry) W = incsz(a32.midL8);
        r64[2] += W;

        W = a32.midH8;
        if (Carry) W = incsz(a32.midH8);
        r64[1] += W;

        W = a32.high8;
        if (Carry) W = incsz(a32.high8);
        r64[0] += W;
      }
      }
#asm
	rrf	r64+0,F		//    r64[0] = rr(r64[0]);
	rrf	r64+1,F		//    r64[1] = rr(r64[1]);
	rrf	r64+2,F		//    r64[2] = rr(r64[2]);
	rrf	r64+3,F		//    r64[3] = rr(r64[3]);
	rrf	r64+4,F		//    r64[4] = rr(r64[4]);
	rrf	r64+5,F		//    r64[5] = rr(r64[5]);
	rrf	r64+6,F		//    r64[6] = rr(r64[6]);
	rrf	r64+7,F		//    r64[7] = rr(r64[7]);
#endasm
    }
    while (--ix);
  }

} // 52 instructions, min:20, max:924 cycles

/*======================================================================*/
void div16x8 (void)				     // q8,r8 =  a16 / b8
/*======================================================================*/

{
  char ix, oldCy;

  ZeroDiv = 1;
  W = b8;
  if (!Zero_)
  {
    Overflow = 1;				// assume error
    if (a16.high8<b8)
    {
      Overflow = 0;			// no error
      r8 = a16.high8;
      q8 = a16.low8;

      ix = 8;				// 8 bits divisor
      W = b8;				// pre-fetch : BK
      do
      {
        q8 *= 2;			// shift dividend
        r8 = rl(r8);
        oldCy = rl(oldCy);		// save carry over
        r8 -= W;			// fits ?
        if (oldCy.0 || Carry)
          q8.0 = 1;			// yes
        else
          r8 += W;			// restore dividend
      }
      while ( --ix);
    }
  }
}// 31 words

/*======================================================================*/
void div24x8 (void)				    // q16,r8 =  a24 / b8
/*======================================================================*/

{
/*
  char ix, oldCy;

  ZeroDiv = 1;
  W = b8;
  if (!Zero_)
  {
    Overflow = 1;			// assume error
    if (a24.high8<b8)
    {
      Overflow = 0;			// no error
      r8 = a24.high8;
      q16 = a24.low16;

      ix = 16;				// 8 bits divisor
      W = b8;				// pre-fetch : BK
      do
      {
        q16 *= 2;			// shift dividend
        r8 = rl(r8);
        oldCy = rl(oldCy);		// save carry over
        r8 -= W;			// fits ?
        if (oldCy.0 || Carry)
          q16.0 = 1;			// yes
        else
          r8 += W;			// restore dividend
      }
      while ( --ix);
    }
  }
*/
}// 34 words

/*======================================================================*/
void div32x8 (void)				    // q24,r8 =  a32 / b8
/*======================================================================*/

{
/*
  char ix, oldCy;

  ZeroDiv = 1;
  W = b8;
  if (!Zero_)
  {
    Overflow = 1;
    if (a32.high8<b8)
    {
      Overflow = 0;
      r8 = a32.high8;
      q24.high8 = a32.midH8;
      q24.low16 = a32.low16;

      ix = 24;
      W = b8;
      do
      {
        q24.low16 *= 2;
        q24.high8 = rl(q24.high8);
        r8 = rl(r8);
        oldCy = rl(oldCy);
        r8 -= W;
        if (oldCy.0 || Carry)
          q24.0 = 1;
        else
          r8 += W;
      }
      while ( --ix);
    }
  }
*/
}// ?? words

/*======================================================================*/
void div24x16 (void)				    // q8,r8 =  a24 / b16
/*======================================================================*/

{
/*
  char ix, oldCy;

  ZeroDiv = 1;
  if (b16)
  {
    Overflow = 1;
    if (a24.high16<b16)
    {
      Overflow = 0;
      r16 = a24.high16;
      q8 = a24.low8;

      ix = 24;
      do
      {
        q8 *= 2;
        r16.low8 = rl(r16.low8);
        r16.high8 = rl(r16.high8);
        oldCy = rl(oldCy);
        r16.low8 -= b16.low8;
        W = b16.high8;
        if (!Carry) W = incsz(b16.high8);
        r16.high8 -= W;
        if (oldCy.0 || Carry)
          q8.0 = 1;
        else
        {
          r16.low8 += b16.low8;
          W = b16.high8;
          if (Carry) W = incsz(b16.high8);
          r16.high8 += W;
        }
      }
      while ( --ix);
    }
  }
*/
}// ?? words

/*======================================================================*/
void Load0 (void)
/*======================================================================*/

{
/*
  a8	     = 0;
  b8         = 0;
  a16	     = 0;
  b16        = 0;
  a24.high8  = 0;
  a24.low16  = 0;
  b24.high8  = 0;
  b24.low16  = 0;
  a32.high16 = 0;
  a32.low16  = 0;
  b32.high16 = 0;
  b32.low16  = 0;
*/
}

/*======================================================================*/
void Load1 (void)
/*======================================================================*/

{
/*
  a8	     = 0xFF;
  b8         = 0xFF;
  a16	     = 0xFFFF;
  b16        = 0xFFFF;
  a24.high8  = 0xFF;
  a24.low16  = 0xFFFF;
  b24.high8  = 0xFF;
  b24.low16  = 0xFFFF;
  a32.high16 = 0xFFFF;
  a32.low16  = 0xFFFF;
  b32.high16 = 0xFFFF;
  b32.low16  = 0xFFFF;
*/
}

/*======================================================================*/
void Load2 (void)
/*======================================================================*/

{
  a8	     = 0xFF;
  a16	     = 0xFFFF;
  a24.high8  = 0xFE;
  a24.low16  = 0xFFFF;
  a32.high16 = 0xFFFF;
  a32.low16  = 0xFFFF;

  b8         = 0x1F;
  b16        = 0xFFFF;
  b24.high8  = 0x1F;
  b24.low16  = 0xFFFF;
  b32.high16 = 0x1FFF;
  b32.low16  = 0xFFFF;
  a32.high16 = 0xFEFF;
  a32.low16  = 0xFF0F;

}

/*======================================================================*/
void main (void)
/*======================================================================*/

{

  b8         = 0xD2;
  a16	     = 0x56B8;
  div16x8 ();				     // q8,r8 =  a16 / b8


  Load2();
  div24x16();

  if(Overflow || ZeroDiv) /*do something*/;

  Load1();
  div24x16();
  if(Overflow || ZeroDiv) /*do something*/;

  Load0();
  div24x16();
  if(Overflow || ZeroDiv) /*do something*/;

}

/*======================================================================*/
/*				END					*/
/*======================================================================*/


/* 
(See
http://techref.massmind.org/techref/microchip/pfu/PFU.ASM
for details of exactly how this translates into PIC assembly language)
*/


file: /Techref/microchip/pfu/pfu.c, 38KB, , updated: 2005/8/12 18:42, local time: 2024/11/17 16:17,
TOP NEW HELP FIND: 
18.227.105.140:LOG IN

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://massmind.org/techref/microchip/pfu/pfu.c"> microchip pfu pfu</A>

Did you find what you needed?

 

Welcome to massmind.org!

 

Welcome to massmind.org!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .