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.

C2000 CLA Compiler v6.1 - __mswapf intrinisic



For my design i'm using the CLA to handle control specific tasks i'm experimenting on the TMX320F28069 control card.

I would like to use the __mswapf intrinisic to swap two floatingpoint variables stored in a global structure
this structure is mapped to the message RAM in which the CLA has read and write access. 

example how i declared the structure in the shared header (C28x and Cla)

struct ClaRW {
    float inputA; 
    float inputB ;
};

external volatile struct ClaRW gClaVars;

In the C28x specific code i declared this, 

#pragma DATA_SECTION("ClaWriteCpuRead")
volatile struct ClaRW gClaVars;

The code works and i begon to optimize my code by using intrinsics
this is where i get a compilation error

Multiple markers at this line
- ClaCode.cla, line 55 [S/W BP]
- #435 qualifiers dropped in binding reference of type "float &" to initializer of type 
"volatile float" __mswapf( gClaVars.InputA, gClaVars.InputB ); 

The compiler reference manual [spru514e] states the following for __mswapf  in the CLA compiler
void __mswapf(float a, float b )--> assembly MSWAPF a, b   --> Swap the contents of a and b.

Question:

Why does this compiler intrinisic not work for this example?
Is it the volatile reference, or should i supply a pointer instead of the actual float to __mswapf? 

Thanks in advance,

Regards Rob,

  • The volatile qualifier is the problem.  Remove volatile to see it build successfully.  This seems like a bug to me.  So I filed SDSCM00044906 in the SDOWP system.  Feel free to follow it with the SDOWP link below in my signature.

    Thanks and regards,

    -George

  • Hi Rob,

    The __mswapf() intrinsic is special in that modifies it's arguments.  We treat the arguments to these type of intrinsics as references. This is similar to what is done if you want to modify a function's argument, you would pass a pointer the argument to be modified.   Since the intrinsics have implied prototypes passing a volatile will fail the internal prototype check.  The error is similar to one you would get if you have a function foo(int *x) and call it using an argument of type 'volatile int *'. 

    To get around this you can cast out the 'volatile' qualifier:

    __mswapf(*(float *)&vfa, *(float *)&vfb);

    Just note that in this context, using the __mswap() for volatile (or global) arguments probably won't generate better code as the operands to the CLA MSWAPF instruction only takes register arguments.  The resulting code will be to load the memory into registers, issue the MSWAPF insruction, and then store the results back to memory. For example:

    MMOV32 MR0, @_vfa

    MMOV32 MR1, @_vfb

    MSWAPF MR0,MR1

    MMOV32 @_vfb, MR1

    MMOV32 @_vfa,MR0

    If you code the usual swap idiom:

    float tmp;

    tmp = vfa;

    vfa = vfb;

    vfb = tmp;

    the resulting code is better than using the mswapf() intrinsic:

    MMOV32 MR0, @_vfa

    MMOV32 MR1, @_vfb

    MMOV32 @_vfb, MR0

    MMOV32 @_vfa,MR1


    The __mswap() intrinsic, IMHO, does not have much utility for global data.  It may be better with local data if the arguments are already allocated to registers.

    Regards,

    John N