This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTS library help needed

Other Parts Discussed in Thread: TMS320C6416

I tried to use RTS library for double multiplication in C6416 simulator using _mpyd() intrinsic but the result is zero for any input.I can not understand why is this happening.

My source code is very simple 

 

#include<stdio.h>

#include<iso646.h>

#define SW_MAX 32767 

#define SW_MIN -32768 

#define MAX_40  549755813883.0

#define MIN_40 -549755813884.0

 

double L40_mac1( short int var1, short int var2)

{

double result=0;  

result = _mpyd((double)var1,((double)var2 * 2));

if (result > MAX_40){

result = MAX_40;                  /* Overflow = 1; */

        }

if (result < MIN_40){

result = MIN_40;               /* undererflow = 1; */

      }

return(result);

}

int main()

{

short int a=SW_MAX,b=SW_MIN;

double c=0;

c=_mpyd( (double)b , (double)a );

// c=L40_mac1(a,b);

printf("c1=%f\n",c);

return (0);

}

The result obtained is c1=0.

I have also tried it for other input values but still answer was zero.

My build option are -g -ol1 -fr"$(Proj_dir)\Debug" -d"_DEBUG" -ms0 -mv6400.

Kindly help me as soon as possible because it is part of my project for optimization.Any other suggestion will be appreciated.

Thanx in advance

 

 

  • This was moved to the Compiler forum since it is a software question and not a DSP hardware question.

    Following are some suggestions, questions, ideas for your debug process:

    • Add #include <c6x.h> at the top of all C6000 C source files.
    • Find out where _mpyd is declared in a header file, or at least add a declaration in your own file.
    • Did you get any compiler or linker warnings (or errors)?
    • "short int" is inefficient for simple variables. The native storage is a 32-bit register, so use "int" instead unless you need to pack data in an array or struct.
    • Create temp variables that are double, and make the assignments into them prior to the _mpyd call. Use those variables in the _mpyd call. In the simulator, single-step and look at the variables in the Watch Window to see if they get the values you expect.
    • Try different values such as 2.4 and 1.2 instead of stress values like range extremes.

    Please let us know if any of this helps, or if you find the problem during this process, or if you need additional help.

    Regards,
    RandyP

  • There is no _mpyd instrinsic.  _mpyd is a compiler helper function, and you should not attempt to call it directly.  Just use the plain C expression:

    c = (double)b * a;
    result = (double)var1 * var2 * 2;
  • Hi Randy,

    i tried all of your suggestions but non worked.But i found a solution my self.I am bound to use short int because you know only 16*16 multiplication is possible in

    TMS320C6416 board.Also it is needed because my input values (var1,var2) are always short. The solution that i found is


        acc = _lsadd ( acc, ( long ) _smpy ( var1,  var2 ) );

    because 16*16 multiplication results in 32 bits value for max. short value (32767,-32768).

    So first i multiplied them with shift ,type cast into " long " and then added and my required result is produced.

    Thanks for you reply.

    can you tell me where exactly these RTS function are defined.because i found them in only "rts.src" file.(means header file and source code in .asm file).

    Regards

    Raju

     

     

  • Raju,

    Since you have a solution, we are very pleased that you found it and appreciate you sharing it with the community.

    I am a little confused. My confusion does not affect your application, of course, but I want to ask for some clarification and say some clarification.

    In your original post, you were trying to do floating point operations but your solution is now using fixed point operations. This will be much better for performance, but since it is very different, it does confuse me.

    Muhammad Rashid said:
    I am bound to use short int because you know only 16*16 multiplication is possible in TMS320C6416 board.

    The C6416 can do 16 x 32 multiplies also, although that does not look to be of interest in your case.

    Muhammad Rashid said:
    Also it is needed because my input values (var1,var2) are always short.

    The compiler may generate slightly more optimized code if your 16-bit short input values are cast into 32-bit int temporary variables. Even though only the lower 16 bits will be used, the compiler will not be tempted to mask out the extra bits in some cases. The improvement may be small, and the ease-of-use may be a problem for your code, but if you ever need to squeeze some extra performance out of your code, that might be an option to consider.

    Muhammad Rashid said:
    acc = _lsadd ( acc, ( long ) _smpy ( var1,  var2 ) );

    The 40-bit "long" data type is often confused with the 64-bit "long long" data type. "long" is really a compatibility holdover from the original C6000 family where there were 8-bit extensions for some registers to make 40-bit accumulators. In the _lsadd intrinsics, the first argument is always a 32-bit signed integer, so using it to accept the saturated 40-bit result of _lsadd and then using it again as an accumulator in another _lsadd as src1 may result in sign and truncation errors. A solution may be to swap the acc and _smpy, if acc is defined as a long. My comments here may be confusing, and that is partly because I do not understand what the final intention is, but you do.

    Muhammad Rashid said:
    can you tell me where exactly these RTS function are defined.because i found them in only "rts.src" file.(means header file and source code in .asm file).

    _lsadd and _smpy are intrinsics which map directly to assembly instructions. The intrinsics are listed and described in the C Compiler User's Guide and I believe they are defined in #include <c6x.h>

    RTS functions are in the various rtsxxxx.lib library files. These may be included automatically or they may be added to your project manually. The function declarations are in the various standard C header files, like #include <stdio.h>

    Regards,
    RandyP

  • Thanx Randy for your attention.

    i am using short in my code and dealing with integers not floating points.

    thanx for telling me about the parameters of _lsadd.i have not noticed it and faced problem.

    can you suggest me a long long addition intrinsic? I am attaching RTS library routines.kindly tell me how i can use these func.if you can not find them then send me your email id.

    Thanx again for so much cooperation.

    Regards

    Raju

     

     

    SPRU653.pdf
  • Muhammad Rashid,

    Your attachment was a TI document, the FastRTS Library Programmer's Reference. What did you want me to do with that?

    As the very wise Archaeologist has suggested, you can write your code using simple C. There may be no need for intrinsics, which are very close to assembly language programming.

    If you allocate a long long variable and add to it, then you will get 64-bit operations to be done. If the C compiler, with optimization turned on, writes the code with the performance you need, then you do not need to do any more digging into other methods.

    For example,

    long long llAccumulator = 0;
    short sVarA, sVarb;

    sVarA = 32767;
    sVarB = -32768;

    llAccumulator += (int)sVarA * (int)sVarB;

    This may not give you the same shift-and-saturate, but maybe you do not need that.

    Is this helping at all?

    Regards,
    RandyP

  • Hi Randy

    Thanks a lot for your support.I gain much from your advices.

    The purpose of attachment  was to know whether these are intrinsics or not.If yes then how can we use? 

    Thanx again.

    Rashid

  • Rashid,

    We may both be confused, but I know that I am.

    The RTS library is a set of functions that you can call. The document you sent explains what they do and what the arguments for the functions are. To me, that is "how to use them".

    Intrinsics are described in the C Compiler User's Guide. These are used in the way you were using _lsadd, which is an intrinsic. Intrinsics are functions that give you direct access to special assembly instructions, like SADD, from the C programming environment. You can use C variable names and expressions and still get the special assembly instruction. The UG lists all of the available intrinsics. You may need to have #include <c6x.h> at the top of your C file.

    Does this help at all?

    Regards,
    RandyP