wrong assembler output when using bitwise inversion?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
RaAl_264636
Level 6
Level 6
50 sign-ins 25 sign-ins 10 solutions authored

Hi,

   

 

   

I've a problem with a simple comparison of two variables. Both are of type uint8_t, one contains the bitwise inversion of the other (0x80 and 0x7F). The comparison is 'if(A == ~B) {...}. I'd expect true as result of the comparison. However, debbuging the disassembly shows that the result of ~B is 0xFFFFFF80 is stored in the register, therefore the compare instruction fails.

   

IMHO this is a bug, because both variables are of type uint8_t, so the result of the inversion should be stripped down to 8 bit. Used PSoC Creator version is 3.3 CP3 & 4.0, GCC for both Creator installations is 'ARM GCC 4.9-2015-q1-update'. Used hardware is a CY8CKIT-059.

   

Attached is a simple project to show the behaviour. If the variables are made non-volatile, the optimization level must be set to 'none', otherwise the test loop would be optimized out.

   

 

   

Regards,

   

 

   

Ralf

0 Likes
1 Solution
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Yes, astonishing! Quite more astonishing is, that this is correct.

   

See chapter 2.8.1 conversions, where the cast to int for a ~ operator is explicitly mentioned.

   

int main(void)
{
uint8 A;
uint8 B;

   

    for(;;)
    {
        A = 0x80;
        B = 0x7F;

   

        if(A == (uint8)~B) {        //wrong assembler output here, the bitwise inversion
                            //result is 0xFFFFFF80
            B = ~A;            //dummy instruction
        }
    }

   


I set the compiler optimization to "none" which made the volatile declaration obsolete.

   

 

   

Bob

View solution in original post

0 Likes
3 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Yes, astonishing! Quite more astonishing is, that this is correct.

   

See chapter 2.8.1 conversions, where the cast to int for a ~ operator is explicitly mentioned.

   

int main(void)
{
uint8 A;
uint8 B;

   

    for(;;)
    {
        A = 0x80;
        B = 0x7F;

   

        if(A == (uint8)~B) {        //wrong assembler output here, the bitwise inversion
                            //result is 0xFFFFFF80
            B = ~A;            //dummy instruction
        }
    }

   


I set the compiler optimization to "none" which made the volatile declaration obsolete.

   

 

   

Bob

0 Likes
RaAl_264636
Level 6
Level 6
50 sign-ins 25 sign-ins 10 solutions authored

Hi Bob & hli,

   

 

   

ah, now I see. The result of the ~operator has the 'natural' bit width of the platform used, right? Thanks a lot for your help.

   

 

   

Regards,

   

 

   

Ralf

0 Likes