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.
Solved! Go to Solution.
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.
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.
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
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.
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();
}
}
}