From: SourceForge.net <no...@so...> - 2006-03-20 16:25:22
|
Bugs item #1450796, was opened at 2006-03-15 23:51 Message generated for change (Comment added) made by bernhardheld You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1450796&group_id=599 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: pic16 target Group: fixed Status: Closed Resolution: Fixed Priority: 5 Submitted By: Alexander R. Enzmann (xan-der) Assigned to: Nobody/Anonymous (nobody) Summary: SIGSEGV Compiling pointer offset Initial Comment: SDCC : pic16/pic14 2.5.5 #1226 (Mar 15 2006) (MSVC) sdcc crashes when compiling an offset to a pointer. Compiling the following code will cause the problem: typedef struct _BDT { char Stat; char Cnt; unsigned int ADDR; } BDT; //Buffer Descriptor Table char *inPtr; char x; BDT at 0x0400 ep0Bo; static void SetFeature(char e) { char endpointNum = e; inPtr = (char *)&ep0Bo + (endpointNum * 8); } Command line used to do the compile: sdcc -mpic16 -c badptr1.c Output is: Caught signal 11: SIGSEGV Note that if you replace "ep0Bo" by "x" in the function SetFeature(), sdcc will compile. Eliminating the "at 0x0400" from the declaration of ep0Bo will also result in compilation. Appears the use of a fixed address in the variable declaration leads to the problem. This problem was not in build 1209 so it was introduced somewhere between 1209 and 1226. Xander ---------------------------------------------------------------------- >Comment By: Bernhard Held (bernhardheld) Date: 2006-03-20 17:25 Message: Logged In: YES user_id=203539 Ok, I've to admit that my reply was very 51 oriented, and my statements might be wrong for other micros. The 51 comes with a 8x8->16 bit unsigned multiplication, which would be very effective in this example. The current "behaviour" of sdcc doning 8x8 multiplications is optimized for the 51. If this isn't optimal for other ports just let me know. ---------------------------------------------------------------------- Comment By: Raphael Neider (tecodev) Date: 2006-03-16 22:48 Message: Logged In: YES user_id=1115835 Hmmm... My consideration here is that (char * literal) yields a signed entity of size int (2 bytes). As a (char*) is 3 bytes, I need to expand the left addend to 3 bytes and---as it is now signed (SPEC_USIGN(left) == 0) with left being the result of (endpointNum * 8)---this incurs considerable overhead compared to expanding it always with zero as in the unsigned case, using (unsigned char * unsigned_lit). PIC16-Code (signed case, endpoint*8 in r0x01|r0x00): ; low byte of _inPtr movfw r0x00 movwf _inPtr ; 2nd byte of _inPtr movlw 0x04 addwf r0x01 movwf (_inPtr+1) ; 3rd byte of _inPtr, propagate carry movlw 0x00 clrf (_inPtr+2) btfsc r0x01,7 setf (_inPtr+2) addwfc (_inPtr+2) unsigned case goes down to ; 3rd byte movlw 0x00 clrf (_inPtr+2) addwfc (_inPtr+2) So, inspect the generated code and compare signed vs. unsigned cases if need be. Regards, Raphael ---------------------------------------------------------------------- Comment By: Bernhard Held (bernhardheld) Date: 2006-03-16 16:57 Message: Logged In: YES user_id=203539 "8" is indeed better than "8u". Why? "8" is an integer constant, but sdcc stores it with type "unsigned char". This is possible because if a promotion is required sdcc will promote it to "signed int". If the promotion can be omitted, sdcc will emit better code because of the unsigned type. However "8u" is an unsigned integer constant, which must be store with type "unsigned int". It's not possible to give it the type "unsigned char", because a promotion might change it to "signed int" and the correct signedness gets lost. The promotion rules are hairy, take good care!! ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 2006-03-16 14:41 Message: Logged In: NO Waiting for fix in CVS. BTW, using this: inPtr = (char *)&ep0Bo + (endpointNum * 8u); As described below adds quite a bit of code to the resulting hex file as a direct result of the "8u" instead of "8". Looks like an extra 32 bytes each time. The actual code is all "unsigned char" - the "char" in the example was just to try to make it as small as possible. Xander ---------------------------------------------------------------------- Comment By: Raphael Neider (tecodev) Date: 2006-03-16 10:45 Message: Logged In: YES user_id=1115835 Fixed in SDCC #1227, src/pic16/genarith.c 1.27. For more compact code you might want to use static void SetFeature(char e) { unsigned char endpointNum = e; inPtr = (char *)&ep0Bo + (endpointNum * 8u); } (i.e. unsigned char and 8u to force unsigned multiplication). Regards, Raphael ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1450796&group_id=599 |