Sign in

username or email:

password:



Not a member?
Forgot your password?

Search adsp



Search tips

Subscribe to adsp



Ads

Discussion Groups

See Also

Embedded SystemsFPGA

Discussion Groups | Analog Devices DSPs | problem with log( ) implementation

Good morning,I'm trying to implement the function log() on a DSP blackfin using the assembly language...

  

Post a new Thread



Is this thread worth a thumbs up?

0

problem with log( ) implementation - Safa Ouerghi - Nov 16 8:55:44 2011

Good morning,
I'm trying to implement the function log() on a DSP blackfin using the assembly
language. I found this C code:
[code]
 int fxlog(int x) {
  int t,y;

  y=0xa65af;
  if(x<0x00008000) x<<=16,              y-=0xb1721;
  if(x<0x00800000) x<<= 8,              y-=0x58b91;
  if(x<0x08000000) x<<= 4,              y-=0x2c5c8;
  if(x<0x20000000) x<<= 2,              y-=0x162e4;
  if(x<0x40000000) x<<= 1,              y-=0x0b172;
  t=x+(x>>1); if((t&0x80000000)==0) x=t,y-=0x067cd;
  t=x+(x>>2); if((t&0x80000000)==0) x=t,y-=0x03920;
  t=x+(x>>3); if((t&0x80000000)==0) x=t,y-=0x01e27;
  t=x+(x>>4); if((t&0x80000000)==0) x=t,y-=0x00f85;
  t=x+(x>>5); if((t&0x80000000)==0) x=t,y-=0x007e1;
  t=x+(x>>6); if((t&0x80000000)==0) x=t,y-=0x003f8;
  t=x+(x>>7); if((t&0x80000000)==0) x=t,y-=0x001fe;
  x=0x80000000-x;
  y-=x>>15;
  return y;
  }
[\code]

so i tried to convert it to assembly using the 16.16 format.

[code]
.section L1_data_a;
.byte4 _x[2]={0x360000,0x22};
.byte4
_val[12]={0xb1721,0x58b91,0x2c5c8,0x162e4,0x0b172,0x067cd,0x03920,0x01e27,0x00f8
5,0x007e1,0x003f8,0x001fe};
.section L1_code;
.global _log;

_log:

I0.h=_val;
I0.l=_val;
//I0=B0;
//L0=48;
I3.H=_x;//variable x
I3.L=_x;
//***initialisation des registres***

R0.l= 0x65AF ; //y0=0xa65af
R0.h=0xA ;

R1.l=0x8000 ;// lim1 de x
R1.H=0x0;

R2.H=0x80 ; //lim2 de x
R2.L=0x0;

R3.H=0x800 ;//lim3 de x
R3.L=0x0;

R4.H=0x2000 ;//lim4 de x
R4.L=0x0;

R5.H=0x4000 ;//lim5 de x
R5.L=0x0;
R6=[I3++];//charger la valeur de x de 32 bits

R7=[I0++];//charger la valeur ln(x) qu'on va soustraire de y

cc=R6<R1;

if !cc jump _case2;

R6=R6<<16;

R0=R0-R7 (ns); //R7 contient la valeur de y

_case2:

cc=R6<R2;
if !cc jump _case3;

R6=R6<<8;

R7=[I0++];

R0=R0-R7(ns); //R7 contient la valeur de y

_case3: 
cc=R6<R3;
if !cc jump _case4;

R6=R6<<4;

R7=[I0++];

R0=R0-R7(ns); //R7 contient la valeur de y

_case4:

cc=R6<R4;
if !cc jump _case5;

R6=R6<<2;

R7=[I0++];

R0=R0-R7(ns); //R7 contient la valeur de y

_case5:

cc=R6<R5;
if !cc jump _rest;

R6=R6<<1;

R7=[I0++];

R0=R0-R7(ns); //R7 contient la valeur de y

_rest: 

nop;

R1=R6>>1;//x>>1
R2=R1+R6; //valeur de t dans R2
cc=BITTST(R2,31);
if cc jump  _op2;
R6=R2;
R7=[I0++];
R0=R0-R7 (ns);
_op2: 

R1=R6>>2;
R2=R1+R6; //valeur de t dans R2
cc=BITTST(R2,31);
if cc jump  _op3;
R6=R2;
R7=[I0++];
R0=R0-R7 (ns);

_op3:
R1=R6>>3;
R2=R1+R6; //valeur de t dans R2
cc=BITTST(R2,31);
if cc jump  _op4;
R6=R2;
R7=[I0++];
R0=R0-R7 (ns);

_op4:
R1=R6>>4;
R2=R1+R6; //valeur de t dans R2
cc=BITTST(R2,31);
if cc jump  _op5;
R6=R2;
R7=[I0++];
R0=R0-R7 (ns);

_op5:
R1=R6>>5;
R2=R1+R6; //valeur de t dans R2
cc=BITTST(R2,31);
if cc jump  _op6;
R6=R2;
R7=[I0++];
R0=R0-R7 (ns);

_op6:
R1=R6>>6;
R2=R1+R6; //valeur de t dans R2
cc=BITTST(R2,31);
if cc jump  _op7;
R6=R2;
R7=[I0++];
R0=R0-R7 (ns);

_op7:
R1=R6>>7;
R2=R1+R6; //valeur de t dans R2
cc=BITTST(R2,31);
if cc jump  _linearisation;
R6=R2;
R7=[I0++];
R0=R0-R7 (ns);

_linearisation:
nop;
R4.H=0x8000 ;//0x800000000 dans R4
R4.L=0x0;

R6=R4-R6 (ns);
R6=R6>>15;
R0=R0-R6 (ns);

rts;
_log.end:
[\code]

The results are not those expected.Please help me

Sincerely,
syrine
______________________________
New Code Sharing Section now Live on DSPRelated.com. Learn about the Reward Program for Contributors here.



(You need to be a member of adsp -- send a blank email to adsp-subscribe@yahoogroups.com )

Re: problem with log( ) implementation - Mike Rosing - Nov 16 10:26:51 2011

Howdy Safa,

The first question is what were you expecting?  If you input ints for C 
and use fractions for assembler you will see some difference.

You should be able to printf in C for every step that you can debug with 
assembler.  So you can watch the registers and compare every step with 
what you expect.  If the difference starts at some point you can then 
determine why, and fix your code.

If the C code works (you should verify that with several values useful to 
your problem) then you have an ideal situation - you can put in the exact 
same values and follow every step of the way.  If it's the first step, it 
will take a while to debug the whole thing, more likely it's in the middle 
some where and just finding where the difference between what you want and 
what you have is the major debuggin chore.  Once you find the problem, 
fixing it is pretty easy.

Patience, persistence, truth,
Dr. mike

  On Wed, 16 Nov 2011, Safa Ouerghi wrote:

> Good morning,
> I'm trying to implement the function log() on a DSP blackfin using the
assembly language. I found this C code:
> [code]
>  int fxlog(int x) {
>   int t,y;
>
>   y=0xa65af;
>   if(x<0x00008000) x<<=16,              y-=0xb1721;
>   if(x<0x00800000) x<<= 8,              y-=0x58b91;
>   if(x<0x08000000) x<<= 4,              y-=0x2c5c8;
>   if(x<0x20000000) x<<= 2,              y-=0x162e4;
>   if(x<0x40000000) x<<= 1,              y-=0x0b172;
>   t=x+(x>>1); if((t&0x80000000)==0) x=t,y-=0x067cd;
>   t=x+(x>>2); if((t&0x80000000)==0) x=t,y-=0x03920;
>   t=x+(x>>3); if((t&0x80000000)==0) x=t,y-=0x01e27;
>   t=x+(x>>4); if((t&0x80000000)==0) x=t,y-=0x00f85;
>   t=x+(x>>5); if((t&0x80000000)==0) x=t,y-=0x007e1;
>   t=x+(x>>6); if((t&0x80000000)==0) x=t,y-=0x003f8;
>   t=x+(x>>7); if((t&0x80000000)==0) x=t,y-=0x001fe;
>   x=0x80000000-x;
>   y-=x>>15;
>   return y;
>   }
> [\code]
>
> so i tried to convert it to assembly using the 16.16 format.
>
> [code]
> .section L1_data_a;
> .byte4 _x[2]={0x360000,0x22};
> .byte4
_val[12]={0xb1721,0x58b91,0x2c5c8,0x162e4,0x0b172,0x067cd,0x03920,0x01e27,0x00f8
5,0x007e1,0x003f8,0x001fe};
> .section L1_code;
> .global _log;
>
> _log:
>
> I0.h=_val;
> I0.l=_val;
> //I0=B0;
> //L0=48;
> I3.H=_x;//variable x
> I3.L=_x;
> //***initialisation des registres***
>
> R0.l= 0x65AF ; //y0=0xa65af
> R0.h=0xA ;
>
> R1.l=0x8000 ;// lim1 de x
> R1.H=0x0;
>
> R2.H=0x80 ; //lim2 de x
> R2.L=0x0;
>
> R3.H=0x800 ;//lim3 de x
> R3.L=0x0;
>
> R4.H=0x2000 ;//lim4 de x
> R4.L=0x0;
>
> R5.H=0x4000 ;//lim5 de x
> R5.L=0x0;
> R6=[I3++];//charger la valeur de x de 32 bits
>
> R7=[I0++];//charger la valeur ln(x) qu'on va soustraire de y
>
> cc=R6<R1;
>
> if !cc jump _case2;
>
> R6=R6<<16;
>
> R0=R0-R7 (ns); //R7 contient la valeur de y
>
> _case2:
>
> cc=R6<R2;
> if !cc jump _case3;
>
> R6=R6<<8;
>
> R7=[I0++];
>
> R0=R0-R7(ns); //R7 contient la valeur de y
>
> _case3: 
> cc=R6<R3;
> if !cc jump _case4;
>
> R6=R6<<4;
>
> R7=[I0++];
>
> R0=R0-R7(ns); //R7 contient la valeur de y
>
> _case4:
>
> cc=R6<R4;
> if !cc jump _case5;
>
> R6=R6<<2;
>
> R7=[I0++];
>
> R0=R0-R7(ns); //R7 contient la valeur de y
>
> _case5:
>
> cc=R6<R5;
> if !cc jump _rest;
>
> R6=R6<<1;
>
> R7=[I0++];
>
> R0=R0-R7(ns); //R7 contient la valeur de y
>
> _rest: 
>
> nop;
>
> R1=R6>>1;//x>>1
> R2=R1+R6; //valeur de t dans R2
> cc=BITTST(R2,31);
> if cc jump  _op2;
> R6=R2;
> R7=[I0++];
> R0=R0-R7 (ns);
> _op2: 
>
> R1=R6>>2;
> R2=R1+R6; //valeur de t dans R2
> cc=BITTST(R2,31);
> if cc jump  _op3;
> R6=R2;
> R7=[I0++];
> R0=R0-R7 (ns);
>
> _op3:
> R1=R6>>3;
> R2=R1+R6; //valeur de t dans R2
> cc=BITTST(R2,31);
> if cc jump  _op4;
> R6=R2;
> R7=[I0++];
> R0=R0-R7 (ns);
>
> _op4:
> R1=R6>>4;
> R2=R1+R6; //valeur de t dans R2
> cc=BITTST(R2,31);
> if cc jump  _op5;
> R6=R2;
> R7=[I0++];
> R0=R0-R7 (ns);
>
> _op5:
> R1=R6>>5;
> R2=R1+R6; //valeur de t dans R2
> cc=BITTST(R2,31);
> if cc jump  _op6;
> R6=R2;
> R7=[I0++];
> R0=R0-R7 (ns);
>
> _op6:
> R1=R6>>6;
> R2=R1+R6; //valeur de t dans R2
> cc=BITTST(R2,31);
> if cc jump  _op7;
> R6=R2;
> R7=[I0++];
> R0=R0-R7 (ns);
>
> _op7:
> R1=R6>>7;
> R2=R1+R6; //valeur de t dans R2
> cc=BITTST(R2,31);
> if cc jump  _linearisation;
> R6=R2;
> R7=[I0++];
> R0=R0-R7 (ns);
>
> _linearisation:
> nop;
> R4.H=0x8000 ;//0x800000000 dans R4
> R4.L=0x0;
>
> R6=R4-R6 (ns);
> R6=R6>>15;
> R0=R0-R6 (ns);
>
> rts;
> _log.end:
> [\code]
>
> The results are not those expected.Please help me
>
> Sincerely,
> syrine





(You need to be a member of adsp -- send a blank email to adsp-subscribe@yahoogroups.com )

Re: problem with log( ) implementation - Andrew Nesterov - Nov 21 15:21:06 2011

Syrine,

You forgot to post the link to the original C code, which seem to be found at
this address:

http://www.quinapalus.com/efunc.html

I tried to test it, I mean the C code; and it seem to be working as expected:

For 65536, which is 1.0 in Q32.16, it returns 0, and for 178,145, which is
the Euler's number in Q32.16, it returns 65537 - pretty close to 1.0 in Q32.16.

You use index register I0 to load the y constants that are stored into an
array; that means that your code loads them _sequentially_, but now imagine
that your code jumps after an appropriate cc has been computed, what would
happen than?

Correct; not the value that is needed for the step after the jump; on the
contrary, a value that _was_ needed on the _previous_ step (provided that there
were no jump) would be loaded. You have to correct the way your code processes
these constants.

Rgds,

Andrew

> Subject: problem with log( ) implementation
> Posted by: "Safa Ouerghi" s...@yahoo.com safa.ouerghi
> Date: Wed Nov 16, 2011 5:55 am ((PST))
>
> Good morning,
> I'm trying to implement the function log() on a DSP blackfin using the 
> assembly language. I found this C code:
> [code]
>  int fxlog(int x) {
>   int t,y;
>
>   y=0xa65af;
>   if(x<0x00008000) x<<=16,              y-=0xb1721;
>   if(x<0x00800000) x<<= 8,              y-=0x58b91;
>   if(x<0x08000000) x<<= 4,              y-=0x2c5c8;
>   if(x<0x20000000) x<<= 2,              y-=0x162e4;
>   if(x<0x40000000) x<<= 1,              y-=0x0b172;
>   t=x+(x>>1); if((t&0x80000000)==0) x=t,y-=0x067cd;
>   t=x+(x>>2); if((t&0x80000000)==0) x=t,y-=0x03920;
>   t=x+(x>>3); if((t&0x80000000)==0) x=t,y-=0x01e27;
>   t=x+(x>>4); if((t&0x80000000)==0) x=t,y-=0x00f85;
>   t=x+(x>>5); if((t&0x80000000)==0) x=t,y-=0x007e1;
>   t=x+(x>>6); if((t&0x80000000)==0) x=t,y-=0x003f8;
>   t=x+(x>>7); if((t&0x80000000)==0) x=t,y-=0x001fe;
>   x=0x80000000-x;
>   y-=x>>15;
>   return y;
>   }
> [\code]
>
> so i tried to convert it to assembly using the 16.16 format.
>
> [code]
> .section L1_data_a;
> .byte4 _x[2]={0x360000,0x22};
> .byte4
_val[12]={0xb1721,0x58b91,0x2c5c8,0x162e4,0x0b172,0x067cd,0x03920,0x01e27,0x00f8
5,0x007e1,0x003f8,0x001fe};
> .section L1_code;
> .global _log;
>
> _log:
>
> I0.h=_val;
> I0.l=_val;
> //I0=B0;
> //L0=48;
> I3.H=_x;//variable x
> I3.L=_x;
> //***initialisation des registres***
>
> R0.l= 0x65AF ; //y0=0xa65af
> R0.h=0xA ;
>
> R1.l=0x8000 ;// lim1 de x
> R1.H=0x0;
>
> R2.H=0x80 ; //lim2 de x
> R2.L=0x0;
>
> R3.H=0x800 ;//lim3 de x
> R3.L=0x0;
>
> R4.H=0x2000 ;//lim4 de x
> R4.L=0x0;
>
> R5.H=0x4000 ;//lim5 de x
> R5.L=0x0;
> R6=[I3++];//charger la valeur de x de 32 bits
>
> R7=[I0++];//charger la valeur ln(x) qu'on va soustraire de y
>
> cc=R6<R1;
>
> if !cc jump _case2;
>
> R6=R6<<16;
>
> R0=R0-R7 (ns); //R7 contient la valeur de y
>
> _case2:
>
> cc=R6<R2;
> if !cc jump _case3;
>
> R6=R6<<8;
>
> R7=[I0++];
>
> R0=R0-R7(ns); //R7 contient la valeur de y
>
> _case3:
>
> cc=R6<R3;
> if !cc jump _case4;
>
> R6=R6<<4;
>
> R7=[I0++];
>
> R0=R0-R7(ns); //R7 contient la valeur de y
>
> _case4:
>
> cc=R6<R4;
> if !cc jump _case5;
>
> R6=R6<<2;
>
> R7=[I0++];
>
> R0=R0-R7(ns); //R7 contient la valeur de y
>
> _case5:
>
> cc=R6<R5;
> if !cc jump _rest;
>
> R6=R6<<1;
>
> R7=[I0++];
>
> R0=R0-R7(ns); //R7 contient la valeur de y
>
> _rest:
>
> nop;
>
> R1=R6>>1;//x>>1
> R2=R1+R6; //valeur de t dans R2
> cc=BITTST(R2,31);
> if cc jump  _op2;
> R6=R2;
> R7=[I0++];
> R0=R0-R7 (ns);
> _op2:
>
> R1=R6>>2;
> R2=R1+R6; //valeur de t dans R2
> cc=BITTST(R2,31);
> if cc jump  _op3;
> R6=R2;
> R7=[I0++];
> R0=R0-R7 (ns);
>
> _op3:
> R1=R6>>3;
> R2=R1+R6; //valeur de t dans R2
> cc=BITTST(R2,31);
> if cc jump  _op4;
> R6=R2;
> R7=[I0++];
> R0=R0-R7 (ns);
>
> _op4:
> R1=R6>>4;
> R2=R1+R6; //valeur de t dans R2
> cc=BITTST(R2,31);
> if cc jump  _op5;
> R6=R2;
> R7=[I0++];
> R0=R0-R7 (ns);
>
> _op5:
> R1=R6>>5;
> R2=R1+R6; //valeur de t dans R2
> cc=BITTST(R2,31);
> if cc jump  _op6;
> R6=R2;
> R7=[I0++];
> R0=R0-R7 (ns);
>
> _op6:
> R1=R6>>6;
> R2=R1+R6; //valeur de t dans R2
> cc=BITTST(R2,31);
> if cc jump  _op7;
> R6=R2;
> R7=[I0++];
> R0=R0-R7 (ns);
>
> _op7:
> R1=R6>>7;
> R2=R1+R6; //valeur de t dans R2
> cc=BITTST(R2,31);
> if cc jump  _linearisation;
> R6=R2;
> R7=[I0++];
> R0=R0-R7 (ns);
>
> _linearisation:
> nop;
> R4.H=0x8000 ;//0x800000000 dans R4
> R4.L=0x0;
>
> R6=R4-R6 (ns);
> R6=R6>>15;
> R0=R0-R6 (ns);
>
> rts;
> _log.end:
> [\code]
>
> The results are not those expected.Please help me
>
> Sincerely,
> syrine
>

______________________________
New Code Sharing Section now Live on DSPRelated.com. Learn about the Reward Program for Contributors here.



(You need to be a member of adsp -- send a blank email to adsp-subscribe@yahoogroups.com )