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 support@ccsinfo.com

Isn't it a bug ? CCS 3.202 version

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



Joined: 01 Mar 2004
Posts: 22
Location: Nice, France

View user's profile Send private message

Isn't it a bug ? CCS 3.202 version
PostPosted: Wed Jun 02, 2004 1:38 am     Reply with quote

I'm not fluent in assembly langage but the last instruction in this for(;;) loop seems to take an absolute address instead of the relative jump specified for BRA instruction ?

In 3.191 version a goto instruction with an absolute jump was used and everything works perfectly well in my soft. With 3.202 everything is messed up.

Is it a bug in 3.202 version or am I missing something ?

Code:

....................          for(i=0; i<(LONGUEUR_TRAME_EMISSION-1); i++) trame_emission[(LONGUEUR_TRAME_EMISSION-1)]^=trame_emission[i];
24D2:  MOVLB  5
24D4:  CLRF   i
24D6:  MOVF   i,W
24D8:  SUBLW  11
24DA:  BNC   24F6
24DC:  CLRF   @03
24DE:  MOVF   i,W
24E0:  ADDLW  trame_emission
24E2:  MOVWF  FSR0L
24E4:  MOVLW  trame_emission+-118
24E6:  ADDWFC @03,W
24E8:  MOVWF  FSR0H
24EA:  MOVF   INDF0,W
24EC:  MOVLB  0
24EE:  XORWF  trame_emission+18,F
24F0:  MOVLB  5
24F2:  INCF   i,F
24F4:  BRA    24D6
C-H Wu
Guest







false alarm ?
PostPosted: Wed Jun 02, 2004 4:27 am     Reply with quote

'GOTO' takes 2 words while 'BRA' takes only 1. Using BRA for short jump is the new default optimization for 3.202 such that the code size can be reduced by 10 ~ 15%. If you don't like it, you can use #opt 5 or #opt 7 to go back to the old days.

Instead of using the symbolic listing, try Microchip format for the LST file by Option -> File format, then you can read the OP code to find out that 'BRA' is in fact short jump, the symbolic listing shows the absolute address just for easy reading.

By the way, did you test your code ? Anything wrong other than code size reduction ?

Best regards

C-H Wu
Schmobol



Joined: 01 Mar 2004
Posts: 22
Location: Nice, France

View user's profile Send private message

False alarm
PostPosted: Wed Jun 02, 2004 8:45 am     Reply with quote

Thank you for your help

Yes, I tested it. It doesn't work. I have a subroutine tha displays graphic icons on LCD. No icon displayed. This is probably the visible part of the iceberg, I didn't tracked down the problem any further to get back to work and came back to the 3.191 version.
Schmobol



Joined: 01 Mar 2004
Posts: 22
Location: Nice, France

View user's profile Send private message

Additional information
PostPosted: Wed Jun 02, 2004 8:52 am     Reply with quote

I've just tested version 3.202 with the #opt 5 you mentionned. And now icons are displayed perfectly well. I had a look at the lst file and find GOTO instructions instead of BRA at the end of for(;;) loops.
C-H Wu
Guest







Re: False alarm
PostPosted: Wed Jun 02, 2004 10:10 am     Reply with quote

Schmobol wrote:
Thank you for your help

Yes, I tested it. It doesn't work. I have a subroutine tha displays graphic icons on LCD. No icon displayed. This is probably the visible part of the iceberg, I didn't tracked down the problem any further to get back to work and came back to the 3.191 version.


Well, sounds like a real bug ! Crying or Very sad

If you have time, please try to narrow in the problem and send a bug report to CCS, we will be grateful to your help.

Also, be careful with the delay_us() bug, it is still there in 3.191 although 3.201 fixed this bug.
Code:
// bug_3191_delay_us.c 

#include <18F458.H>

#fuses HS, NOLVP, NOWDT, NODEBUG, PUT

#use delay(clock= 40000000)
#use RS232(baud = 115200, xmit= PIN_C6, rcv= PIN_C7)

void main()
{
   int16 i; int8 k= 0;

   while ( 1 )
   {
      for(i=0;i< 5000;i++) delay_us(200);

      printf("%u ", ++k); // numbers should come out once every second,
                          // but ... it runs like crazy with 3.191 !
   }
}


delay_us( n ) has bug if n > 153 in this case. The problem is, which version shall we call it 'stable' ? My feeling is 3.202 with #opt 5 might be better than 3.191. Confused

Best regards

C-H Wu
kory
Guest







#opt 5 didn't help me
PostPosted: Wed Jun 02, 2004 1:11 pm     Reply with quote

I'm having the same problem (absolute jumps to bad addresses) but adding the "#opt 5" didn't help at all. I even tried #opt 4 and 3.

Kory
Schmobol



Joined: 01 Mar 2004
Posts: 22
Location: Nice, France

View user's profile Send private message

bug identified
PostPosted: Thu Jun 03, 2004 3:25 am     Reply with quote

I think I finally found a problem. Hereafter is a Branch instruction at the end of a for(;;) loop

Address Opcode Disassembly
1B9E D277 BRA 0x208E

The code optimization replaces a GOTO instruction by the BRA instrution (that takes a relative jump between -1023 and 1024). The goal is to jump to absolute address 0x208E but the compiler doesn't seem to realise that 0x208E - 0x1B9E = 0x4f0 (1264 in decimal) is greater that the range of the BRA argument.

The opcode D277 makes a relative jump of 0x277 to 0x1B9E + 0x277 = 0x1E15, which is obviously erroneous.

It seems that the compiler doesn't verify the range of the jump before replacing a GOTO instruction (in previous compiler version) to BRA instruction for optimization.
Schmobol



Joined: 01 Mar 2004
Posts: 22
Location: Nice, France

View user's profile Send private message

Bug identified
PostPosted: Thu Jun 03, 2004 3:39 am     Reply with quote

Bug has been reported to CCS. For those of you who are experiencing the same problem, I solved this specific problem by adding #opt 5 while keeping 3.202 version.

Thanks to C-H Wu for this good advice. By the way, where is the "#opt x" command documented ?
Schmobol



Joined: 01 Mar 2004
Posts: 22
Location: Nice, France

View user's profile Send private message

Not a bug
PostPosted: Thu Jun 03, 2004 4:10 am     Reply with quote

I missed something int he calculation of the relative jump. As specified by the datasheet the relative jump is calculated by the following formula 2n+2. And the BRA instruction previoulsy mentionned is correct.

The problem is somewhere else !
Guest








Re: Bug identified
PostPosted: Thu Jun 03, 2004 4:34 am     Reply with quote

Help -> index -> #opt

#OPT

Syntax:
#OPT n

Elements:
n is the optimization level 0-9

Purpose:
The optimization level is set with this directive. The directive applies to the entire program and may appear anywhere in the file. Optimization level 5 will set the level to be the same as the PCB,PCM,PCH stand-alone compilers. The PCW default is 9 for full optimization. This may be used to set a PCW compile to look exactly like a PCM compile for example. It may also be used if an optimization error is suspected to reduce optimization.

Examples:
#opt 5
C-H Wu
Guest







Is it a bug, or some ANSI ?
PostPosted: Sat Jun 05, 2004 10:59 am     Reply with quote

Hi, All:

I have a question for the following code for 18F458:

Code:
int8  x = 0x10;
int1  bit_a = 0;

bit_a = x & 0x30;    printf(" %u ", bit_a);


PCWH 3.202 returns 0 for bit_a while 3.187 returns 1 Shocked !!!!!

There are no error or warning message.

What should be the result under ANSI ? Confused

It took me a couple of hours to find out this _NEW_ feature.

Thanks for your comments and ...

Best wishes

C-H Wu
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: Is it a bug, or some ANSI ?
PostPosted: Mon Jun 07, 2004 1:30 pm     Reply with quote

Quote:
I have a question for the following code for 18F458:

Code:
int8  x = 0x10;
int1  bit_a = 0;
bit_a = x & 0x30;
printf(" %u ", bit_a);


PCWH 3.202 returns 0 for bit_a while 3.187 returns 1
There are no error or warning message.
What should be the result under ANSI ?
It took me a couple of hours to find out this _NEW_ feature.


I tested this problem with PCM vs. 3.188 and 3.202, and I saw
a similar result. I looked at the ASM code in the LST file.
In 3.188, the compiler acts as if int1 is an built-in Boolean data type.
It checks if the expression on the right is non-zero, and if so, it
sets the int1 variable = 1. In other words, it does a type conversion
on the result of the expression, and converts it to a boolean type.

In PCM vs. 3.202, it's done differently. The code just checks bit 0
of the expression result and sets the int1 variable equal to that value.
That's completely different ! The compiler is now acting as if an
int1 variable is a 1-bit wide integer. So if you assign an integer of
a larger width to an integer of a smaller size, the upper portion of
the integer is truncated. That's correct, in terms of doing a type
conversion.

But this is a huge change in philosophy on the treatment of int1
variables, and there is no notice given in the Readme file.

That being said, when I first saw your test program, my first thought
was "I would never write code like that". I would have written it like this:
Code:
if(x & 0x30)
   bit_a = 1;
else
   bit_a = 0;

Or if I was feeling really strict with myself, I would do it like this:
Code:
if((x & 0x30) != 0)
   bit_a = 1;
else
   bit_a = 0;

I can't really tell you why I write code like this. I just automatically
do it. Maybe I have been "trained" by CCS to do it this way. Rolling Eyes

But you can see the difference. Your method requires a basic trust
that a proper type conversion will be done. My method does not.

I have seen one method of converting an integer expression to a
boolean type. It uses the "logical negation operator".

bit_a = !!(x & 0x30);

This works because the first negation automatically turns the
expression result into a Boolean value. The 2nd negation then
turns that result into positive logic.

The only reason I would not use this method is because it's very easy
to type in only one exclamation point, by accident.
---------------
Since you discovered this problem, do you want to email CCS about it ?
C-H Wu
Guest







Is 'int1' boolean ? or integer ?
PostPosted: Mon Jun 07, 2004 8:23 pm     Reply with quote

PCM programmer:

Thanks for your reply.

Regarding the _NEW_ feature of 3.202 in int1 variable operation :
Code:
int8  x = 0x10;
int1  bit_a = 0;
bit_a = x & 0x30;


1. I wrote to CCS asking for a warning meesage, no response yet, well, its Monday, I will wait. BTW, they raise an error message to bit_a = 0x30; in 3.202 but not in 3.187, 188 or 3.191.

2. the 'stable' version 3.191, also return 1. The change seems to started from 3.200 (?).

3. I fully agree that I should _NEVER_ write code like that because of the _ambiguity_ behind the code. But, it just happened during the time I was trying, playing and learning bit operation with mask using CCS. And I told myself, gee, CCS is a _SPECIAL_ C-compiler that allow you to save some typing. It was 8 monthes ago when I left the code like that, which is part of a general purpose library for many ongoing projects not just my project, so, what will happen if I tell my people let's go for the new 3.202 ? Shocked (motto: _NEVER_ upgrade CCS unless you really need it.) Now I modified the code after this surprise with more considerations on reliability and future maintenance
Code:
   bit_a =(x & 0x30) > 0 ;         
   bit_a =(x & 0x30) > 0 ? 1 : 0;
   bit_a = x & 0x30      ? 1 : 0;   
My personal choice is the second one with the '?' operator since it is just another expression of the if-else statement, less typing, ANSI standard, although it is a little bit less explicit than the if-else statement.

Is 'int1' boolean or integer ? What will be the result of bit_a = x & 0x30 according to the philosophy of ANSI ? I looked into K&R's 2nd ed.,section 6.9, Bit-fields, page 149, seems like that int1 should be treated as a _small_ integer instead of boolean.

I just hope no one else got this kind of bite like me.

Best wishes

C-H Wu

BTW, I will use my story as a 'lesson' for students. Very Happy
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Jun 08, 2004 1:37 am     Reply with quote

Quote:
Code:
   bit_a =(x & 0x30) > 0 ;         
   bit_a =(x & 0x30) > 0 ? 1 : 0;
   bit_a = x & 0x30      ? 1 : 0;


In ANSI-C an expression is TRUE when the result is not equal to 0. Your code will work well most of the times because of an other curiosity of the CCS compiler, variables are standard unsigned instead of signed. Your code might fail in the case of signed integers therefor I suggest:

Code:
   bit_a =(x & 0x30) != 0 ;         
   bit_a =(x & 0x30) != 0 ? 1 : 0;
   bit_a = x & 0x30       ? 1 : 0;
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