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.

F28335 compiler doubles address offset when parens are used?

Other Parts Discussed in Thread: TMS320F28335

Is this a compiler bug? Adding a set of parentheses around an address changes the way it is computed. This caused a failure in the code that

took quite a while to track down. No parens, the offset is 0xAA. Use parens, the offset is 0x55. See C code and generated assembly below.

Running CCS 6.1.3.00033, compiler TI v15.12.3.LTS, chip TMS320F28335

    *((volatile unsigned long*) FLASH_BASE + 0x55 )    = 0x00980098;

     795 000000f7 9A98          MOV       AL,#152               ; [CPU_] |126|
     796 000000f8 9B98          MOV       AH,#152               ; [CPU_] |126|
     797 000000f9 8F20          MOVL      XAR4,#2097322         ; [CPU_U] |126|
         000000fa 00AA
     798 000000fb 1EC4          MOVL      *+XAR4[0],ACC         ; [CPU_] |126|

     -------------------------------------------------------
    
     *((volatile unsigned long*) (FLASH_BASE + 0x55) )    = 0x00980098;

     795 000000f7 9A98          MOV       AL,#152               ; [CPU_] |126|
     796 000000f8 9B98          MOV       AH,#152               ; [CPU_] |126|
     797 000000f9 8F20          MOVL      XAR4,#2097237         ; [CPU_U] |126|
         000000fa 0055
     798 000000fb 1EC4          MOVL      *+XAR4[0],ACC         ; [CPU_] |126|

Thanks,
Lloyd

  • The compiler handles this expression correctly.  The parenthesis does change the computation in a meaningful way.  

    The linchpin idea is, for some pointer expression "ptr + int-type-expression", that int-type-expression is scaled, or multiplied, by the size of whatever is pointed to by ptr.  So this expression ...

    (volatile unsigned long*) FLASH_BASE + 0x55

    Means to change FLASH_BASE to type "volatile unsigned long *", then added a scaled 0x55 to it.  In this specific case, that means multiply 0x55 by sizeof(unsigned long) == 2, to get 0xAA.  

    By contrast, this expression ...

    (volatile unsigned long*) (FLASH_BASE + 0x55)

    Means to add 0x55 to FLASH_BASE before changing the type.  Because the scaling for this pointer addition is 1, evidenced by adding only 0x55, then the type of FLASH_BASE must be "int *", or something equivalent.

    Thanks and regards,

    -George

  • I've done 30 years of C programming and there's still something to learn. Thanks very much for the education!