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

C compiler FOR loop

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



Joined: 03 Aug 2006
Posts: 5

View user's profile Send private message

C compiler FOR loop
PostPosted: Thu Aug 03, 2006 12:20 pm     Reply with quote

I can't find any reference to this problem in the archives.

A particular instance of a C FOR loop generates code that on termination branches to the correct instruction +1. In this case, it is a BCF 03.5 instruction to reset the memory bank that it fails to execute, causing a crash. The instruction is there in the code listing at 061A, but the FOR termination jumps to 061B instead. Inserting an explicit Bit_Clear(*3,5) in the C is a clumsy work-around.

Any comments on the problem (not about the functionality of the routine)?


Code:
#include <16f877a.h>
///////////////////////////////////////////////////////
// Send a long value in decimal down the serial line //
// This function avoids mult and div of longs        //
///////////////////////////////////////////////////////
void send_value(long val)
{
   long const dectab[5] = {10000,1000,100,10,1};
   long v;
   v = val;
   if (v == 0) OutChar('0');   // spare us the print loop if zero
   else
   {
      short lead = 0;
      int i;
      for (i = 0; i<5; ++i)   // this branches to the wrong place on termination
      {
         int dig;
         long div;
         div = dectab[i];
         for (dig=0; v>=div; ++dig) v-=div;   // subtract until v too small
         if (lead || dig)         //   print character unless leading zero
         {
            OutChar(dig + '0');
            lead = 1;         // flag to say we have a leading character
         }
      }
   }
   Bit_Clear(*3,5);         // work around compiler bug
   Eol();
}

void Eol(void)
{
   putc('\r');   // Send Eol
}

void OutChar(char ch)
{
   putc(ch);           // Send the character
}

Generated code listing:
....................             int i; 
....................             for (i = 0; i<5; ++i) 
05E3:  CLRF   50
05E4:  MOVF   50,W
05E5:  SUBLW  04
05E6:  BTFSS  03.0
05E7:  GOTO   61B
.
.
.
....................             } 
0618:  INCF   50,F
0619:  GOTO   5E4
061A:  BCF    03.5
....................          } 
....................          Bit_Clear(*3,5); 
061B:  BCF    03.5
....................          Eol(); 
061C:  CALL   4A3
061D:  RETLW  00
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 03, 2006 12:26 pm     Reply with quote

What is your compiler version ?
CED123



Joined: 03 Aug 2006
Posts: 5

View user's profile Send private message

PostPosted: Thu Aug 03, 2006 12:30 pm     Reply with quote

Quote:
What is your compiler version ?

3.098
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 03, 2006 1:03 pm     Reply with quote

Before I research your problem, look at this section of the CCS versions
page. CCS added some "improvements" and then spent the next 30
days fixing them. I don't know if this will work, but try putting #opt 7
near the top of your program, right after the #include line. See if it affects the problem.
Quote:

3.097 Optimization improvments
3.099 Fixed optimization problems (#opt 7 removes new opt, #opt 8 uses it)
3.100 Baseline version - passes all internal tests
3.101 More optimization improvments
3.103 Optimization bug fix
3.103 Some fuses that were not working are fixed
3.104 Another optimization bug fix
Guest








PostPosted: Fri Aug 04, 2006 5:58 am     Reply with quote

Adding #opt 7 causes a small shift in the code addresses but does not fix the problem.
CED123



Joined: 03 Aug 2006
Posts: 5

View user's profile Send private message

PostPosted: Fri Aug 04, 2006 6:00 am     Reply with quote

For some reason that last post named me as "Guest" even though I had logged in. I've logged in again now and am posting this as a test.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 04, 2006 10:02 am     Reply with quote

Report the bug to CCS support and show the C source and the ASM code.
Explain to them how this bank select bug makes your version unusable.

Give them your version of the compiler and your customer number,
and ask if they will give you an upgrade to a later, working version.
CED123



Joined: 03 Aug 2006
Posts: 5

View user's profile Send private message

PostPosted: Fri Aug 04, 2006 10:21 am     Reply with quote

OK, I'll do that.

I've tried stripping code out of the loop, and the minimum it seems to need to produce the problem is:
(1) an IF statement with the true condition calling a function in a different bank
(2) a FOR loop in the ELSE clause

Example follows. Note that the BCF 03.5 at 0635 is unreachable, but is needed if the ELSE clause is executed.
Code:
void sv(long v)
{
   if (v == 0) OutChar('0');
   else
   {
      int i;
      for (i = 0; i<5; ++i) {}
   }
   Eol();
}

.................... void sv(long v) 
.................... { 
....................       if (v == 0) OutChar('0');                  
*
0622:  MOVF   54,F
0623:  BTFSS  03.2
0624:  GOTO   62E
0625:  MOVF   55,F
0626:  BTFSS  03.2
0627:  GOTO   62E
0628:  MOVLW  30
0629:  MOVWF  57
062A:  BCF    03.5
062B:  CALL   46C
....................       else 
062C:  GOTO   636
062D:  BSF    03.5
....................       { 
....................          int i; 
....................          for (i = 0; i<5; ++i) {} 
062E:  CLRF   56
062F:  MOVF   56,W
0630:  SUBLW  04
0631:  BTFSS  03.0
0632:  GOTO   636
0633:  INCF   56,F
0634:  GOTO   62F
0635:  BCF    03.5
....................       } 
....................       Eol(); 
0636:  CALL   4A3
.................... } 
CED123



Joined: 03 Aug 2006
Posts: 5

View user's profile Send private message

PostPosted: Mon Aug 07, 2006 3:36 am     Reply with quote

Thanks for your help on this one. CCS kindly sent me V3.125. This fixes the FOR loop bug at the expense of slower execution time and greater ROM usage. When waiting for character output, extra time is not a problem, of course, but there are time-critical loops in other parts of the code that I will have to check.
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