Using more than a 32 bit integer with CW on the S12P MCU

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Using more than a 32 bit integer with CW on the S12P MCU

Jump to solution
1,741 Views
datamstr
Contributor II

Hi all,

 

I need to multiply a 32 bit integer by a 16 bit integer and divide that result by a 16 bit integer. For the intermediate result I need more than 32 bits. I am programming in C using CW. Any ideas on implementing an unsigned long long variable?

 

Thanks,
David

Labels (1)
0 Kudos
1 Solution
669 Views
kef
Specialist I

You didn't say if you tolerate assembler. Here's my code:

 

 

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */


typedef struct
{
   unsigned short hibits;
   unsigned long  lobits;
}  u48;


// *product  = m32 * m16
void mul32x16_48(u48 *product, unsigned long m32, unsigned short m16)
{
   asm
   {
      LDX   product
      LDD   m32:2
      LDY   m16
      EMUL
      STD   4,x
      STY   2,x
      LDD   m32
      LDY   m16
      EMUL
      ADDD  2,x
      STD   2,x
      TFR   Y,D
      ADCB  #0
      ADCA  #0
      STD   0,x
   }
}

// *q = *nom / denom
void div48x16(u48 *q, u48 *nom, unsigned short denom)
{
u48 qtmp;

   asm
   {
      LDY   nom
      LDD   0,y
      LDX   denom
      IDIV 
      STX   qtmp:0
      TFR   D,X
      LDD   2,y
      LDY   denom
      EXG   Y,X
      EDIV
      STY   qtmp:2
      LDY   nom
      LDY   4,y
      EXG   D,Y
      EDIV
      STY   qtmp:4
   }
   *q = qtmp;
}

u48 product;
u48 quot;

void main(void) {
  /* put your own code here */
 
   mul32x16_48(&product, 0x9876543F, 0xF765);
   div48x16(&quot, &product, 0xEDAB);

 EnableInterrupts;


  for(;:smileywink: {
    _FEED_COP(); /* feeds the dog */
  } /* loop forever */
  /* please make sure that you never leave main */
}

View solution in original post

0 Kudos
5 Replies
670 Views
kef
Specialist I

You didn't say if you tolerate assembler. Here's my code:

 

 

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */


typedef struct
{
   unsigned short hibits;
   unsigned long  lobits;
}  u48;


// *product  = m32 * m16
void mul32x16_48(u48 *product, unsigned long m32, unsigned short m16)
{
   asm
   {
      LDX   product
      LDD   m32:2
      LDY   m16
      EMUL
      STD   4,x
      STY   2,x
      LDD   m32
      LDY   m16
      EMUL
      ADDD  2,x
      STD   2,x
      TFR   Y,D
      ADCB  #0
      ADCA  #0
      STD   0,x
   }
}

// *q = *nom / denom
void div48x16(u48 *q, u48 *nom, unsigned short denom)
{
u48 qtmp;

   asm
   {
      LDY   nom
      LDD   0,y
      LDX   denom
      IDIV 
      STX   qtmp:0
      TFR   D,X
      LDD   2,y
      LDY   denom
      EXG   Y,X
      EDIV
      STY   qtmp:2
      LDY   nom
      LDY   4,y
      EXG   D,Y
      EDIV
      STY   qtmp:4
   }
   *q = qtmp;
}

u48 product;
u48 quot;

void main(void) {
  /* put your own code here */
 
   mul32x16_48(&product, 0x9876543F, 0xF765);
   div48x16(&quot, &product, 0xEDAB);

 EnableInterrupts;


  for(;:smileywink: {
    _FEED_COP(); /* feeds the dog */
  } /* loop forever */
  /* please make sure that you never leave main */
}

0 Kudos
669 Views
datamstr
Contributor II

Hey kef,

 

Works great!!!

 

Thanks so much!!

 

David

0 Kudos
669 Views
datamstr
Contributor II

Hi kef,

 

Do you have a divide routine for 48 bits divided by 24 bits?

 

Thanks,
David

0 Kudos
669 Views
kef
Specialist I

No, I don't. 24bits divider is well more complicated using S12 division instructions. Shift-subtract loop is the easy way to go. But shift-subtract is slow and new code requires some debugging. Then why not just using double precision floating point arithmetics? Since double mantissa is 52bits wide, double can contain up to 52bits wide integers without any rounding or loss of precision issues.

 

0 Kudos
669 Views
datamstr
Contributor II

I am avoiding use the floating point math library to keep the code smaller.

 

Thanks,
David

0 Kudos