AnsweredAssumed Answered

VisualDSP 5.0 SHARC compiler generates incorrect code using bset, bclr

Question asked by KimKite on May 16, 2013
Latest reply on Oct 1, 2013 by Caroll

The following code doesn't compile correctly under VisualDSP 5.0, update 9.1 for the ADSP-21363 or ADSP-21489.  I haven't tried to link and execute this simple function, because the problem is apparent from the assembly listing.  I discovered this when testing an actual application though, and then reduced the code to the smallest possible test case shown here.

 

#define     TEST1_BIT  2

#define     TEST2_BIT  3

 

int do_tests, test1, test2, result;

 

void    test_function1(void)

{

    if (do_tests)

    {

        if (test1) {

            result |= (0x1U << TEST1_BIT);

        }

        else {

            result &= ~(0x1U << TEST1_BIT);

        }

 

        if (test2) {

            // This instruction does not get compiled when do_tests and test1 are included above

            // If do_tests or test1 are omitted, it does get compiled.

            result |= (0x1U << TEST2_BIT);

        }

        else {

            result &= ~(0x1U << TEST2_BIT);

        }

    }

}

 

The assembly listing for test1 shows an unconditional bset instruction followed by a conditional bclr instruction, which is correct.  The code for test2 should be similar, but it omits the bset instruction before storing the result.  This means the bit for test2 is never set.

 

_test_function1:

.LN_test_function1:

//-------------------------------------------------------------------

//  Procedure statistics:

//  Frame size            = 2 words

//  Scratch registers used: {r0-r2,i12,acc,scc}

//  No call preserved registers used.

//-------------------------------------------------------------------

// line ".\src\snippet.c":61

    r2=dm(_do_tests);

    r2=pass r2;

    // -- stall --

    if eq jump (pc,.P39L3);

 

.P39L1:

// line 63

    r2=dm(_test1);

    r2=pass r2;

// line 64

    r1=dm(_result);

    r0=2;

    r2=bset r1 by 2;

    if eq r2=bclr r1 by r0;

// line 70

    r1=dm(_test2);

    r1=pass r1;

// line 73

    r1=3;

    if eq r2=bclr r2 by r1;

    dm(_result)=r2;

 

.P39L3:

// line 79

    i12=dm(m7,i6);

    // -- 2 stalls --

    jump (m14,i12) (db); rframe; nop;

.LN._test_function1.end:

._test_function1.end:

}}}

 

What are the chances of seeing a fix for this?  We have been using the version 4.5 compiler for production builds because it took us some time to address some incompatibilities in our code.  But we are moving to the 21489 processor, so will be forced to move to the 5.0 compiler soon.  I was at the point of saying we're ready to change compilers, when I found this problem in some new code I was testing.  I could code around it, but I'm concerned there might be hidden problems in our legacy code.

 

The full source file, with compiler information, command line, and additional examples and observations; and the full assembly listing file are attached.

Attachments

Outcomes