CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

[solved] code gen bug - uses local var for function param?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
akohlsmith



Joined: 25 Apr 2012
Posts: 26

View user's profile Send private message

[solved] code gen bug - uses local var for function param?
PostPosted: Wed Sep 11, 2013 8:12 am     Reply with quote

I've got an odd little code generation bug. I have allocated 10 bytes for local storage. I use that local storage and call a function with a single parameter. The last local storage byte gets overwritten with the parameter I pass to the function.

Please refer to the following listing:
Code:

.................... void tx_status(void)
.................... {
*
09DA:  MOV     W5,[W15++]
....................    int8 i, resp[9];
.................... 
/*** snipped, just filling out resp[0] to resp[7] ***/

....................    resp[8] = (advance_paused) ? 1 : 0;
0A34:  BTSS.B  9FE.2
0A36:  BRA     A3C
0A38:  MOV.B   #1,W0L
0A3A:  BRA     A3E
0A3C:  CLR.B   W0
0A3E:  MOV.B   W0L,A2C
.................... 
....................    blank_display(TRUE);
0A40:  MOV.B   #1,W0L
0A42:  MOV.B   W0L,A2C
0A44:  CALL    348
....................    for (i = 0; i < sizeof(resp); i++) {
0A48:  CLR.B   A22
0A4A:  MOV     A22,W4
0A4C:  CP.B    W4L,#9
0A4E:  BRA     GE,A68
....................       fputc(resp[i], RADIO);
0A50:  MOV.B   A22,W0L
0A52:  SE      W0,W0
0A54:  MOV     #A24,W4
0A56:  ADD     W0,W4,W0
0A58:  MOV.B   [W0],W5L
0A5A:  MOV.B   W5L,W0L
0A5C:  BTSS.B  223.0
0A5E:  BRA     A5C
0A60:  MOV.B   W0L,224
0A62:  CLR.B   225
....................    }
0A64:  INC.B   0A22
0A66:  BRA     A4A
.................... }
0A68:  MOV     [--W15],W5
0A6A:  RETURN 


The problem occurs between 0xa3c and 0xa42.

As you can see, resp[8] has memory location 0xa2c. The code correctly sets or clears the byte based on whether the advance_paused boolean variable is true or not. In my particular bug, advance_paused is FALSE, which causes the branch at 0xa34 to NOT be taken, so the branch to 0xa3c is taken and 0xa2c is written with value 0. I have verified that this code operates correctly, and with a breakpoint at 0xa40 the memory location 0xa2c correctly stores 0x00.

However the very next line which calls blank_display(TRUE) sets 0xa2c with a value of 1 (the value of TRUE). I believe this is erroneous, as I have allocated 9 bytes for int8 resp[9].

I'm using CCS 4.135 and my compiler options are "+DF +LS +T +A +M -Z +Y=0 +EA". This code generation bug occurs with optimization turned off, as shown in the compiler options. The target processor is a PIC24F32KA304.

I'm a little surprised to see that function parameters are implemented with fixed memory locations and not by passing values in the working register set. Perhaps that is an optimization which I've got turned off.


Last edited by akohlsmith on Wed Sep 11, 2013 8:46 am; edited 1 time in total
alan



Joined: 12 Nov 2012
Posts: 357
Location: South Africa

View user's profile Send private message

PostPosted: Wed Sep 11, 2013 8:28 am     Reply with quote

Looking at yout listing it seems that you declared the array mid code. Change it to beginning of function and check lst file. It has been mentioned here on the forum that sometimes this mid code declaration does give problems.

Regards
akohlsmith



Joined: 25 Apr 2012
Posts: 26

View user's profile Send private message

PostPosted: Wed Sep 11, 2013 8:46 am     Reply with quote

alan wrote:
Looking at yout listing it seems that you declared the array mid code. Change it to beginning of function and check lst file. It has been mentioned here on the forum that sometimes this mid code declaration does give problems.


My C code actually declares it at the top of the function:

Code:
void tx_status(void)
{
   int8 i, resp[9];

   resp[0] = radio_address | 0x80;
   resp[1] = eedata.upper_limit_temp;
   resp[2] = eedata.adv_rate + 1;      /* status version of this is 1-8, not 0-7 */
   resp[3] = eedata.set_temp;
   resp[4] = eedata.adv_stop_temp;
   resp[5] = drybulb_temp / 10;
   resp[6] = wetbulb_temp / 10;

   resp[7] = 0;
   if (burner_feedback) resp[7] |= (1 << 0);
   if (wetbulb_bad) resp[7] |= (1 << 4);
   if (drybulb_bad) resp[7] |= (1 << 5);

   resp[8] = (advance_paused) ? 1 : 0;

   blank_display(TRUE);
   for (i = 0; i < sizeof(resp); i++) {
      fputc(resp[i], RADIO);
   }
}


Now taking what you said in mind, I changed the first line to

Code:
   int8 resp[9], i;


and rebuilt, and the bug is gone. Interestingly enough, it's not gone because variable "i" is now being overwritten, it is gone because the compiler is correctly using an unused RAM location to store the TRUE value it passes to blank_display().

I was creating a tiny program to recreate the issue for a bug report, but I could not get the same code generation bug to occur, even with all the global vars copied directly from the large application source and copying tx_status() and blank_display() verbatim. It looks like this is definitely a corner case issue.

Thank you so much for posting your hunch!
Ttelmah



Joined: 11 Mar 2010
Posts: 19540

View user's profile Send private message

PostPosted: Thu Sep 12, 2013 11:09 am     Reply with quote

Word alignment....

Is a compiler problem. Has been mentioned in some other threads to do with structures (but never something as simple as an array...).

Problem is that things really have to start on 16bit boundaries. Looks as if when the array is declared immediately after the int, it 'rounds down' the start address. Generically you can't really have a 9 byte array and a 1 byte variable 'comfortably' declared' one after the other on a PIC24. Some bugs on alignment, were fixed in later V4 releases.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group