Jump to content

Boostc Incorrect Code Generation For +=

Recommended Posts



IDE version: 6.70

Compiler: BoostC for PIC18

Compiler version: 6.70

Target device: PIC18F25J10

OS: Windows XP SP2



The += statement at the end of this code segment compiles incorrectly:


#include <system.h>

typedef struct _SOCKET_INFO
   unsigned char smState;

   unsigned char TxBuffer;
   unsigned int TxCount;
   unsigned int RxCount;

   unsigned long SND_SEQ;
   unsigned SND_ACK;


void main(void) {

   ps = &TCB[1];

// This statement compiles incorrectly
ps->SND_SEQ += (unsigned long)ps->TxCount;



The assembler produced is:


	ps->SND_SEQ += (unsigned long)ps->TxCount;
000C  5032     	 MOVF main_1_ps+D'1', W
000E  6EEA     	 MOVWF	FSR0H
0010  5031     	 MOVF main_1_ps, W
0012  6EE9     	 MOVWF FSR0L
0014  0E06     	 MOVLW 0x06
0016  26E9     	 ADDWF FSR0L, F
0018  50EF     	 MOVF INDF0, W
001A  6E37     	 MOVWF CompTempVar494
001C  50EC     	 MOVF PREINC0, W
001E  6E38     	 MOVWF CompTempVar494+D'1'
0020  50EC     	 MOVF PREINC0, W
0022  6E39     	 MOVWF CompTempVar494+D'2'
0024  50EC     	 MOVF PREINC0, W
0026  6E3A     	 MOVWF CompTempVar494+D'3'
0028  5032     	 MOVF main_1_ps+D'1', W
002A  6EEA     	 MOVWF	FSR0H
002C  5031     	 MOVF main_1_ps, W
002E  6EE9     	 MOVWF FSR0L
0030  0E02     	 MOVLW 0x02
0032  26E9     	 ADDWF FSR0L, F
0034  50EE     	 MOVF POSTINC0, W
0036  6E33     	 MOVWF CompTempVar492
0038  50EF     	 MOVF INDF0, W
003A  6E34     	 MOVWF CompTempVar492+D'1'
003C  6A35     	 CLRF CompTempVar492+D'2'
003E  6A36     	 CLRF CompTempVar492+D'3'
0040  5033     	 MOVF CompTempVar492, W
0042  2637     	 ADDWF CompTempVar494, F
0044  5034     	 MOVF CompTempVar492+D'1', W
0046  2238     	 ADDWFC CompTempVar494+D'1', F
0048  5035     	 MOVF CompTempVar492+D'2', W
004A  2239     	 ADDWFC CompTempVar494+D'2', F
004C  5036     	 MOVF CompTempVar492+D'3', W
004E  223A     	 ADDWFC CompTempVar494+D'3', F
0050  5037     	 MOVF CompTempVar494, W
0052  06E9     	 DECF FSR0L, F
0054  06E9     	 DECF FSR0L, F
0056  06E9     	 DECF FSR0L, F
0058  6EEF     	 MOVWF INDF0
005A  5038     	 MOVF CompTempVar494+D'1', W
005C  6EEC     	 MOVWF PREINC0
005E  5039     	 MOVF CompTempVar494+D'2', W
0060  6EEC     	 MOVWF PREINC0
0062  503A     	 MOVF CompTempVar494+D'3', W
0064  6EEC     	 MOVWF PREINC0


Note that TxCount is at offset 2 in the structure and SND_SEQ is at offset 6. The assembler code first loads the SND_SEQ member into CompTempVar494 then the TxCount member into CompTempVar492, correctly promoting the 16 bit int to a 32 bit long by clearing the two upper bytes. The 32 bit addition goes into CompTempVar494 and then this is written to the wrong location: the compiler is behaving as if the last location read was the destination of the +=, which it is not. Furthermore, because FSR0 has been incremented only once reading the 2 byte value TxCount, the adjustment of the FSR0 pointer back by 3 bytes means that the 32 bit result is written starting two bytes before the TxCount member, so the two char members smState and TxBuffer are clobbered as well as TxCount.


Writing the += as an explict ps->SND_SEQ = ps->SND_SEQ + ps->TxCount produces code that looks correct.


The += statement also seems to work if there is no promotion involved eg if we use ps->RxCount in place of ps->SND_SEQ (assembler does addition in-place).





Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...