Way to find location of the first 1 bit from MSB

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

Way to find location of the first 1 bit from MSB

跳至解决方案
3,757 次查看
Gildarai
Contributor II

I use s12zvml and Code warrior for MCU v11.1.

I want to make a code to find first bit value is 1 from MSB.

And I try to use assembly or builtin function such like "__builtin_fbcl" from xc16. because of it have to called rapidly periodic, I'm tring to reduce execution time.

Please help me.

标记 (3)
0 项奖励
回复
1 解答
3,517 次查看
fqh
Contributor II

Hi,

You can use CLB (Count Leading Sign-Bits) instruction to get the leading bit position. But there is no intrinsic function to do this. Embedded asm is a better solution.

#define findLeadingBit32(val, num) {asm LD D6, val; asm CLB D6, D0; asm LD D1, #30; asm SUB D1, D0; asm ST D1, num;}

U8 numbit;
U32 value;

value = 0x8000;

findLeadingBit32(value, numbit);

NOTE: for 16 bits or 8 bits, the macro should be changed accordingly. If value is 0, numbit will be 0xFF.

在原帖中查看解决方案

0 项奖励
回复
4 回复数
3,518 次查看
fqh
Contributor II

Hi,

You can use CLB (Count Leading Sign-Bits) instruction to get the leading bit position. But there is no intrinsic function to do this. Embedded asm is a better solution.

#define findLeadingBit32(val, num) {asm LD D6, val; asm CLB D6, D0; asm LD D1, #30; asm SUB D1, D0; asm ST D1, num;}

U8 numbit;
U32 value;

value = 0x8000;

findLeadingBit32(value, numbit);

NOTE: for 16 bits or 8 bits, the macro should be changed accordingly. If value is 0, numbit will be 0xFF.

0 项奖励
回复
3,730 次查看
lama
NXP TechSupport
NXP TechSupport

HI,

 

If you use C coding then simply

if (variable & 0x0100) { .... ;}

else { ...  ;}

 

If you use ASM coding then (I am not sure about syntax but insgructions you can use are presented):
CPU S12Z Reference Manual -. download or atttached

   LDD D6, variable

   BRCLR D6,#8, jump1

   nop

   BRA jump2

jump1:

   nop

jump2::

 

Best regards,

Ladislav

 

0 项奖励
回复
3,712 次查看
Gildarai
Contributor II

Thank you Ladislav.

I want to make a function that finds and returns the number of bits starting from the MSB that are first 1.

 

if I make C code,

 

unsigned int findbitexample(unsigned int value)

{

    unsigned int bitMask = 0x8000;

    unsigned int bitCount;

 

    while(bitCount <= 15){

        if((bitMask & value) == 0){

            bitMask = bitMask >> 1;

            bitCount = bitCount+1;

        }

        else{

            break;

        }

    }

    return bitCount;

}

 

But I cannot use while/for loop problem with task execution time.

So I'm trying to make assembly code or use builtin function if it can be.

 

0 项奖励
回复
3,689 次查看
lama
NXP TechSupport
NXP TechSupport

Hi,

speed is usually paid for by size. This is just suggestion how to exclude/bypass parameters passing, cycles logic,....   probably it is faster, you can test.

#include <hidef.h>      /* common defines and macros */

#include "derivative.h"      /* derivative-specific definitions */

//**********************************************************************

//global variables to do not send parameter to function

volatile unsigned int value;

volatile unsigned char *pvH=(unsigned char*)(&value);

volatile unsigned char *pvL=(unsigned char*)    (   ( (unsigned char*)(&value) )        +1);

//**********************************************************************

unsigned char find1(void)

{

  if(*pvH)

   {

    if(*pvH & 0B11110000) 

     {

       if(*pvH & 0B11000000) 

        {

         if(*pvH & 0B10000000) 

          {

            return 15;  //1000 0000

          } 

         else

          {

            return 14;  //0100 0000

          }

        } 

       else

        {

         if(*pvH & 0B00100000) 

          {

            return 13;  //0010 0000

          } 

         else

          {

            return 12;  //0001 0000

          }

        }

     } 

    else

     {

       if(*pvH & 0B00001100) 

        {

         if(*pvH & 0B00001000) 

          {

            return 11;  //1000 0000

          } 

         else

          {

            return 10;  //0100 0000

          }

        } 

       else

        {

         if(*pvH & 0B00000010) 

          {

            return 9;  //0010 0000

          } 

         else

          {

            return 8;  //0001 0000

          }

        }

 

     }

   } 

  else 

   {

    if(*pvL & 0B11110000) 

     {

       if(*pvL & 0B11000000) 

        {

         if(*pvL & 0B10000000) 

          {

            return 7;  //1000 0000

          } 

         else

          {

            return 6;  //0100 0000

          }

        } 

       else

        {

         if(*pvL & 0B00100000) 

          {

            return 5;  //0010 0000

          } 

         else

          {

            return 4;  //0001 0000

          }

        }

     } 

    else

     {

       if(*pvL & 0B00001100) 

        {

         if(*pvL & 0B00001000) 

          {

            return 3;  //1000 0000

          } 

         else

          {

            return 2;  //0100 0000

          }

        } 

       else

        {

         if(*pvL & 0B00000010) 

          {

            return 1;  //0010 0000

          } 

         else

          {

            return 0;  //0001 0000

          }

        }

 

     }

 

   

   }

  return 55;

}

//**********************************************************************

void main(void) 

{

  static unsigned char pos;

 

  for(;;) 

   {

     for(value=0; value < 0xFFFF; value++) 

      {

        if (value != 0)

            pos = find1();

      }

   }

}

0 项奖励
回复