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.

Compiler/TMS320F28335: C2000 compiler version 6.4.9: Bit field bug?

Guru 20045 points
Part Number: TMS320F28335


Tool/software: TI C/C++ Compiler

Hello,

Please see C and associated disassembly and expression window below.  

Why isn't abc.a3 being stored in the most upper nibble of the first first word?  I expected the result to be 0x00004305 instead of 0x00040305.

Stephen

C-Code:

typedef unsigned int UWORD;

typedef union
{
  long Message;
  struct{
	  unsigned int a1:8;
	  unsigned int a2:4;
	  unsigned int a3:6;
	  unsigned int a4:1;
	  unsigned int a5:1;
	  unsigned int a6:1;
	  unsigned int a7:1;
	  unsigned int a8:5;
	  unsigned int a9:1;
	  unsigned int a10:1;
	  unsigned int a11;
  }bits;
} ID;

ID abc;


int main(void)
{
	abc.bits.a1=5;
	abc.bits.a2=3;
	abc.bits.a3=4;
	
	return 0;
}

Disassembly:

29      	abc.bits.a1=5;
        main:
009078:   761F0300    MOVW         DP, #0x300
00907a:   CC00FF00    AND          AL, @0x0, #0xff00
00907c:   5005        ORB          AL, #0x5
00907d:   9600        MOV          @0x0, AL
30      	abc.bits.a2=3;
00907e:   CC00F0FF    AND          AL, @0x0, #0xf0ff
009080:   1AA90300    OR           @AL, #0x0300
009082:   9600        MOV          @0x0, AL
31      	abc.bits.a3=4;
009083:   CC01FFC0    AND          AL, @0x1, #0xffc0
009085:   5004        ORB          AL, #0x4
009086:   9601        MOV          @0x1, AL
33      	return 0;
009087:   9A00        MOVB         AL, #0x0
34      }
009088:   0006        LRETR        
        _register_unlock:
009089:   761F0300    MOVW         DP, #0x300
00908b:   A80A        MOVL         @0xa, XAR4
00908c:   0006        LRETR        
        _register_lock:
00908d:   761F0300    MOVW         DP, #0x300
00908f:   A808        MOVL         @0x8, XAR4
009090:   0006        LRETR        
        _nop:
009091:   0006        LRETR        

Expression Window:

abc	union <anonymous_union>	{...} (Hex)	0x0000C000@Data	
	Message	long	0x00040305 (Hex)	0x0000C000@Data	
	bits	struct <unnamed>	{...} (Hex)	0x0000C000@Data	
		a1	unsigned int : 8	0x05 (Hex)	0x0000C000@Data bit 0-7	
		a2	unsigned int : 4	0x3 (Hex)	0x0000C000@Data bit 8-11	
		a3	unsigned int : 6	0x4 (Hex)	0x0000C001@Data bit 0-5	
		a4	unsigned int : 1	0x0 (Hex)	0x0000C001@Data bit 6	
		a5	unsigned int : 1	0x0 (Hex)	0x0000C001@Data bit 7	
		a6	unsigned int : 1	0x0 (Hex)	0x0000C001@Data bit 8	
		a7	unsigned int : 1	0x0 (Hex)	0x0000C001@Data bit 9	
		a8	unsigned int : 5	0x0 (Hex)	0x0000C001@Data bit 10-14	
		a9	unsigned int : 1	0x0 (Hex)	0x0000C001@Data bit 15	
		a10	unsigned int : 1	0x0 (Hex)	0x0000C002@Data bit 0	
		a11	unsigned int	0x0000 (Hex)	0x0000C003@Data	

  • This might be a display bug.  What tool produces this output?

    stevenh said:

    Expression Window:

    abc	union <anonymous_union>	{...} (Hex)	0x0000C000@Data	
    	Message	long	0x00040305 (Hex)	0x0000C000@Data	

    Thanks and regards,

    -George

  • Hello George,

    CCS5.5 using the C2000 simulator. Another co-worker had the same issue when using the actual target. I believe he is using CCS v6.2.

    Please see the disassembly at the bottom of my last post. According to the disassembly, the display is showing the correct output.

    Stephen
  • This is correct ...

    		a1	unsigned int : 8	0x05 (Hex)	0x0000C000@Data bit 0-7	
    		a2	unsigned int : 4	0x3 (Hex)	0x0000C000@Data bit 8-11	
    		a3	unsigned int : 6	0x4 (Hex)	0x0000C001@Data bit 0-5	

    What it does not show you is that bits 12-15 at address 0x0000C000 are unused.  This is because no bit field is allowed to span a 16-bit (or word) boundary. Once fields a1 and a2 are placed, there are only 4-bits left in the word.  The field a3 must go next.  It is 6-bits wide, larger than 4-bits.  So it goes in the next word.

    I apologize for missing this earlier.

    Thanks and regards,

    -George

  • I thought that was it, but I don't see why it should be an issue.

    Is this true all TI compilers, including ARM? I would think that some of the hardware bit fields would expand across word boundary or do the chip system designer make sure that doesn't happen?

    Is there a reason for the restriction?

    Thanks,
    Stephen
  • According to both the C2000 and MSP430 compiler manual, bit fields can not overlap words and I believe that is true in general.
  • Bit-field layout is a bit complicated, and it differs between COFF and EABI. In EABI, you can indeed have a bit-field that spans a word boundary if the declared type is a type that spans a word boundary, such as "long." See the MSP430 EABI documentation.