From: Johan K. <joh...@id...> - 2001-01-24 19:37:46
|
Hi, All The following code produces incorrect results: unsigned int address; unsigned short counterPage; for (counterPage=12; counterPage<=15; counterPage++) { address=(counterPage<<5)+31; printf ("counterPage: 0x%02bx, address: 0x%04x\n", counterPage, address); } because the expression (counterPage<<5) is performed in 8-bit although it is used in an assignment to a 16-bit variable. I know I mentioned something like this before and I though it was fixed, but it isn't (anymore?). Of course a type cast fixes the problem, but when porting a large application to sdcc (like the complete ow package) this is not an option. Also, multi-dimensional array's are handle very well by sdcc except when used as a function parameter. E.g. something like: int FindDevices(int portnum, char FamilySN[][8], int family_code, int MAXDEVICES); int FindDevices(int portnum, char FamilySN[][8], int family_code, int MAXDEVICES) { body } produces a compiler error like: findtype.c(79):error *** Actual Argument type different from declaration 2 I am very close at finishing my sdcc-tini-bios with support for a system clock, two independant irq-ed serial ports, the rtc, i2c, multi-channel ow, lcd, SMC etc, but this still bothers me. Johan |
From: Kevin V. <ke...@vi...> - 2001-01-24 21:43:22
|
On 24-Jan-2001 Johan Knol wrote: > because the expression (counterPage<<5) is performed in 8-bit although > it is > used in an assignment to a 16-bit variable. I know I mentioned > something > like this before and I though it was fixed, but it isn't (anymore?). Yep, still here. Well, I thought SDCC was behaving properly here, but I took a look at the ISO C spec, and to my suprise, you're right: a compiler is required to promote both arguments to the shift operators to type int. So this is indeed a bug, and I'll look at it. Peace, Kevin |
From: Kevin V. <ke...@vi...> - 2001-01-24 22:10:50
|
On 24-Jan-2001 Kevin Vigor wrote: > So this is indeed a bug, and I'll look at it. Fix committed. Will look at the array problem next. Peace, Kevin |
From: Kevin V. <ke...@vi...> - 2001-01-24 23:43:48
|
On 24-Jan-2001 Kevin Vigor wrote: > Fix committed. Will look at the array problem next. Fix for array argument problem comitted. Peace, Kevin |
From: Johan K. <joh...@id...> - 2001-01-25 11:34:47
|
----- Original Message ----- From: Kevin Vigor <ke...@vi...> To: <sdc...@li...> Sent: Thursday, January 25, 2001 12:44 AM Subject: RE: [sdcc-devel]bug reports, Kevin: are you still listening? > > On 24-Jan-2001 Kevin Vigor wrote: > > Fix committed. Will look at the array problem next. > > Fix for array argument problem comitted. > > Peace, > Kevin Not quite: extern int FindDevices(int, char FamilySN[][8], int, int); // global serial numbers uchar FamilySN[MAXDEVICES][8]; #define COUNT_FAMILY 0x1d #define MAXDEVICES 20 . . NumDevices = FindDevices(portnum, &FamilySN[0], COUNT_FAMILY, MAXDEVICES); . . does a: ; genCast mov dptr,#_FindDevices_PARM_2 mov a,#_FamilySN movx @dptr,a ;<---- this should be a generic pointer ; genAssign ; genAssign: resultIsFar = TRUE mov dptr,#_FindDevices_PARM_3 ; Kevin's better literal load code mov a,#0x1D movx @dptr,a clr a inc dptr movx @dptr,a ; genAssign ; genAssign: resultIsFar = TRUE mov dptr,#_FindDevices_PARM_4 ; Kevin's better literal load code mov a,#0x14 movx @dptr,a clr a inc dptr movx @dptr,a ; genCall ; Peephole 181 used 16 bit load of dptr mov dptr,#0x0000 lcall _FindDevices Thanks in advance Kevin, Johan |
From: Kevin V. <kv...@lu...> - 2001-01-25 18:38:39
|
Hmm. This one was a little hairy, but what I think is the proper fix is comitted. The basic problem is that array function parameters in prototypes are internally converted to pointers (I broke this code out into the function aggregateArgToPointer in one of yesterday's checkins). Unfortunately, they were apparently being changed to data pointers rather than the generic pointers we'd expect. So I brute-force-and-ignoranced it and forced them to generic pointers without really understanding how it all works. If anybody wants to take a look at my changes to SDCCsymt.c and see if there's a better way, I'd love to hear it... Anyway, give it a spin; should be fixed. Peace, Kevin On 25-Jan-2001 Johan Knol wrote: > Not quite: > > extern int FindDevices(int, char FamilySN[][8], int, int); > > // global serial numbers > uchar FamilySN[MAXDEVICES][8]; > >#define COUNT_FAMILY 0x1d >#define MAXDEVICES 20 > . > . > NumDevices = FindDevices(portnum, &FamilySN[0], COUNT_FAMILY, > MAXDEVICES); > . > . > > does a: > ; genCast > mov dptr,#_FindDevices_PARM_2 > mov a,#_FamilySN > movx @dptr,a ;<---- > this > should be a generic pointer > ; genAssign > ; genAssign: resultIsFar = TRUE > mov dptr,#_FindDevices_PARM_3 > ; Kevin's better literal load code > mov a,#0x1D > movx @dptr,a > clr a > inc dptr > movx @dptr,a > ; genAssign > ; genAssign: resultIsFar = TRUE > mov dptr,#_FindDevices_PARM_4 > ; Kevin's better literal load code > mov a,#0x14 > movx @dptr,a > clr a > inc dptr > movx @dptr,a > ; genCall > ; Peephole 181 used 16 bit load of dptr > mov dptr,#0x0000 > lcall _FindDevices |
From: Johan K. <joh...@id...> - 2001-01-25 10:25:46
|
----- Original Message ----- From: Kevin Vigor <ke...@vi...> To: <sdc...@li...> Sent: Wednesday, January 24, 2001 11:11 PM Subject: RE: [sdcc-devel]bug reports, Kevin: are you still listening? > > On 24-Jan-2001 Kevin Vigor wrote: > > So this is indeed a bug, and I'll look at it. > Fix committed. Will look at the array problem next. Thank you very much. I am not sure, but how about this one? unsigned int address; unsigned short counterPage; for (counterPage=12; counterPage<=15; counterPage++) { address=(counterPage+counterPage)+230; printf ("counterPage: 0x%02bx, address: 0x%04x\n", counterPage, address); } Johan |
From: Kevin V. <kv...@lu...> - 2001-01-25 21:02:08
|
It turns out that in ANSI C, this should work. Following the "usual binary conversions", both operands to arithmetic operations should be widened to int if shorter, then forced to be the larger of the two resulting types (plus additional rules for dealing with signed/unsigned conflicts; see any good C reference for the ugly details). SDCC simply converts the two operands to be the larger of the initial two types. I have comitted code to fix this, but I am reluctant to turn it on by default, because this is relatively expensive, and there are a lot of places where the old bahavior generates more efficient (if now ANSI-compliant) code. So I have added a new command line option, -ansiint. Adding this option to your compiles will cause SDCC to use the less efficient ANSI-compliant integer promotions; compiling without this option will use the "classic" method. Let me know if you see any problems. Now, on to arguments to varags functions... Peace, Kevin On 25-Jan-2001 Johan Knol wrote: > Thank you very much. I am not sure, but how about this one? > > unsigned int address; > unsigned short counterPage; > for (counterPage=12; counterPage<=15; counterPage++) { > address=(counterPage+counterPage)+230; > printf ("counterPage: 0x%02bx, address: 0x%04x\n", > counterPage, address); > } |
From: Sandeep D. <sa...@dd...> - 2001-01-25 21:24:15
|
Kevin, Iam currently swamped at my paying job, so cannot focus on SDCC, thanks for picking up the slack. I have a suggestion for all these integral promotions. While these promotions do enhance the compiler's adherence the ANSI standards, they also have a rather serious impact on code size. The shift case for example , all shifts will now be promoted to INTTYPE. Here is my suggestion. This needs to be implemented in SDCCast.c. For assignment check the type of the left hand side, then push a cast down to all the leaf nodes of right hand side if they have a size less than the size of left hand side. This will modify only those subtrees that actually need the promotion. i.e. intvar = charvar1 << charvar2 ---> intvar = ((int)charvar1) << ((int) charvar2) whereas charvar = charvar1 << charvar2 --> would remain unchanged. The promotion code you put into SDCCicode.c then can be taken out. The code that just wants to shift a char will not pay the price. Regards Sandeep -----Original Message----- From: sdc...@li... [mailto:sdc...@li...]On Behalf Of Kevin Vigor Sent: Thursday, January 25, 2001 1:03 PM To: sdc...@li... Subject: Re: [sdcc-devel]bug reports, Kevin: are you still listening? It turns out that in ANSI C, this should work. Following the "usual binary conversions", both operands to arithmetic operations should be widened to int if shorter, then forced to be the larger of the two resulting types (plus additional rules for dealing with signed/unsigned conflicts; see any good C reference for the ugly details). SDCC simply converts the two operands to be the larger of the initial two types. I have comitted code to fix this, but I am reluctant to turn it on by default, because this is relatively expensive, and there are a lot of places where the old bahavior generates more efficient (if now ANSI-compliant) code. So I have added a new command line option, -ansiint. Adding this option to your compiles will cause SDCC to use the less efficient ANSI-compliant integer promotions; compiling without this option will use the "classic" method. Let me know if you see any problems. Now, on to arguments to varags functions... Peace, Kevin On 25-Jan-2001 Johan Knol wrote: > Thank you very much. I am not sure, but how about this one? > > unsigned int address; > unsigned short counterPage; > for (counterPage=12; counterPage<=15; counterPage++) { > address=(counterPage+counterPage)+230; > printf ("counterPage: 0x%02bx, address: 0x%04x\n", > counterPage, address); > } _______________________________________________ sdcc-devel mailing list sdc...@li... http://lists.sourceforge.net/lists/listinfo/sdcc-devel |
From: Kevin V. <ke...@vi...> - 2001-01-25 21:38:07
|
On 25-Jan-2001 Sandeep Dutta wrote: > I have a suggestion for all these integral > promotions. While these promotions do enhance the compiler's adherence > the ANSI standards, they also have a rather serious impact on code > size. Fortunately, my job is pretty slack right now, which is why I've ben hacking like a lunatic these last few days... that may change soon, though. And yes, I do agree that the generated code is much less efficient in many cases; that's why I made it a command line option and left the default code generation alone. > The shift case for example , all shifts will now be promoted to > INTTYPE. (though I forgot to fix shifts back; this should be controlled by the -ansiint option too; I'll fix that). > Here is my suggestion. This needs to be implemented in SDCCast.c. This does look like a better idea. I will take a look and see if I understand the code well enough to implement it. Peace, Kevin |
From: Kevin V. <ke...@vi...> - 2001-01-26 00:55:14
|
On 25-Jan-2001 Sandeep Dutta wrote: > For assignment check the type of the left hand side, then push a cast > down to all the leaf nodes of right hand side if they have a size less > than > the size of left hand side. This will modify only those subtrees that > actually > need the promotion. Well, much to my amazement, I have coded this up and it seems to work. So, following the usual exhaustive stress-testing (it compiled the libraries, didn't it?), I have just comitted this change. Since this is a pretty intrusive change, I have surrounded it with #ifdef DEMAND_INTEGER_PROMOTION in SDCCast.c. So if somthing blows up, undefine this symbol in SDCCast.c. If that fixes your problem, then I did it; please let me know. By the way, as coded it also goes the other way: it will down-cast the RHS of the expression if the result is of a smaller type than the expression. For instance: char c; int i1, i2; c = i1 + i2; Previously, the addition of i1 and i2 would be done in 16 bits, and the result truncated to 8. Now we only do 8 bit addition. I can't think of any instances in which this will cause incorrect behavior, but if you do, please let me know. The stricter ANSI promotion code is still checked in and can be enabled with the -ansiint command line option, but I think Sandeep's solution will handle all the cases Johan ran into, and is clearly more efficient. OK, I'm really going to look at those parameters to varargs functions now. Or maybe tomorrow. It's getting late... Peace, Kevin |
From: Johan K. <joh...@id...> - 2001-01-26 09:26:57
|
> Since this is a pretty intrusive change, I have surrounded it with #ifdef > DEMAND_INTEGER_PROMOTION in SDCCast.c. So if somthing blows up, undefine > this symbol in SDCCast.c. If that fixes your problem, then I did it; > please let me know. Right now sdcc segmentaion-faults when compiling _schar2fs (-mds390). Commenting out #define DEMAND.. gives an undefined reference to 'pushTypeCastToLeaves' at line 2759 of SDCCast.c. Adding another #ifdef solves that. But at least my &FamilySN[0] argument problem is now solved, thanks. Johan |
From: <Mic...@t-...> - 2001-01-26 13:05:37
|
yes i can say that this is so here too. ----- Original Message ----- From: "Johan Knol" <joh...@id...> > Right now sdcc segmentaion-faults when compiling _schar2fs (-mds390). michael schmitt |
From: Kevin V. <kv...@lu...> - 2001-01-26 17:11:48
|
On 26-Jan-2001 Johan Knol wrote: > Right now sdcc segmentaion-faults when compiling _schar2fs (-mds390). > Commenting out #define DEMAND.. gives an undefined reference to > 'pushTypeCastToLeaves' at line 2759 of SDCCast.c. Adding another #ifdef > solves that. Whoops; sorry about that. Fixed. Also realised once I got some sleep that there are many kinds of expressions where the "down-casting" behavior would be wrong (e.g: int i = 0xff00; char c = i >> 8; truncating i to char before doing the shift (which the code I checked in yesterday would have done) obviously generates a bogus result in c. So I have fixed this by only pushing the typecast down to the expression leaves when the result is larger than the expression type. Peace, Kevin |
From: Johan K. <joh...@id...> - 2001-01-26 11:59:32
|
> By the way, as coded it also goes the other way: it will down-cast the > RHS of the expression if the result is of a smaller type than the > expression. For instance: > > char c; > int i1, i2; > > c = i1 + i2; > > Previously, the addition of i1 and i2 would be done in 16 bits, and the > result truncated to 8. Now we only do 8 bit addition. I can't think of > any instances in which this will cause incorrect behavior, but if you do, > please let me know. I can't test it yet (see my previous post) but I hope it doesn't screw my: #define OSCILLATOR 18432000L ... unsigned long baud=115200; ... void Serial390Init(void) { ... TL1 = TH1 = -(OSCILLATOR/(32L*baud)); ... } Johan |
From: Scott H. <sh...@da...> - 2001-01-24 21:48:38
|
Johan, I just encountered this same problem. In our header file, ownet.h, we define a ushort. I just added #ifdef SDCC, I make ushort actually be an unsigned int. Maybe I'm just "thinking inside the box", but I didn't expect the left shift to automatically "widen" my data type for me. Scott -- Scott Hughes - sh...@da... Engineer, Auto Information Dallas Semiconductor > -----Original Message----- > From: sdc...@li... > [mailto:sdc...@li...]On Behalf Of Johan Knol > Sent: Wednesday, January 24, 2001 1:38 PM > To: sdc...@li... > Cc: Kevin Vigor > Subject: [sdcc-devel]bug reports, Kevin: are you still listening? > > > Hi, All > > The following code produces incorrect results: > > unsigned int address; > unsigned short counterPage; > for (counterPage=12; counterPage<=15; counterPage++) { > address=(counterPage<<5)+31; > printf ("counterPage: 0x%02bx, address: 0x%04x\n", > counterPage, address); > } > > because the expression (counterPage<<5) is performed in 8-bit > although it is > used in an assignment to a 16-bit variable. I know I mentioned something > like this before and I though it was fixed, but it isn't (anymore?). Of > course a type cast fixes the problem, but when porting a large application > to sdcc (like the complete ow package) this is not an option. > > Also, multi-dimensional array's are handle very well by sdcc except when > used as a function parameter. E.g. something like: > > int FindDevices(int portnum, char FamilySN[][8], int family_code, int > MAXDEVICES); > > int FindDevices(int portnum, char FamilySN[][8], int family_code, int > MAXDEVICES) > { > body > } > > produces a compiler error like: > > findtype.c(79):error *** Actual Argument type different from > declaration 2 > > I am very close at finishing my sdcc-tini-bios with support for a system > clock, two independant irq-ed serial ports, the rtc, i2c, > multi-channel ow, > lcd, SMC etc, but this still bothers me. > > Johan > > > > > > > _______________________________________________ > sdcc-devel mailing list > sdc...@li... > http://lists.sourceforge.net/lists/listinfo/sdcc-devel |
From: Scott H. <sh...@da...> - 2001-01-24 23:29:16
|
Thanks for the feedback about the pointer to the sfr. Guess I'm stuck with the if statements. So, I've got both serial ports on the tini working now and it's pretty easy to switch between the two... But I'm seeing some pretty strange behaviour from printf. With the following code: printf("%01X\r\n",0x0f); printf("%02X\r\n",0x0f); printf("%03X\r\n",0x0f); printf("%04X\r\n",0x0f); printf("%01X\r\n",0xff); printf("%02X\r\n",0xff); printf("%03X\r\n",0xff); printf("%04X\r\n",0xff); printf("%05X\r\n",0xff); I'd expect: F 0F 00F 000F FF FF 0FF 000FF But instead I see: F01 F01 F01 0F01 FF01 FF01 FF01 FF01 0FF01 I've tried tracing through vsprintf, but that's not the easiest code to trace. I have some other bugs which I think are related. For example, in one test program from the 1-Wire api, I have a string that I know to be valid and it can be printed fine with puts(char*). But use that same string with printf("%s",char*) and it hangs the tini. Scott -- Scott Hughes - sh...@da... Engineer, Auto Information Dallas Semiconductor |
From: Kevin V. <ke...@vi...> - 2001-01-25 00:01:15
|
On 24-Jan-2001 Scott Hughes wrote: > Thanks for the feedback about the pointer to the sfr. Guess I'm stuck But I'm seeing some pretty strange > behaviour > from printf. With the following code: > printf("%01X\r\n",0x0f); SDCC is passing the constant parameter 0x0f as a single byte; the %X format specifier wants an int argument. This may be a bug (I'm not sure offhand if the constant should be promoted to int), but in the meantime, you should be able to work around it either by typecasting the constant to int, or by using the 'b' modifier in your printf format string (btw, I believe this is non-standard and should be changed to 'h', which is standard, someday), like so: printf("%01bX\r\n",0x0f); (I am not near a working TINI, so I can't actually test this right now). > one test program from the 1-Wire api, I have a string that I know to be > valid and it can be printed fine with puts(char*). But use that same > string > with printf("%s",char*) and it hangs the tini. Probably a similar problem: the %s printf conversion expects a generic pointer to char. The following code will blow up: char _xdata *str; printf("%s",str); (quite apart from the fact that str is uninitialized) because str is passed to printf as an xdata * rather than a generic *. Because puts() has a proper prototype instead of a varargs ..., the compiler can do the proper conversions for you (if necessary). The only workaround for this one is an explicit typecast: char _xdata *str; printf("%s",(char _generic *)str); Take-home lesson here: varargs functions (like printf) are weird, and SDCC probably doesn't follow all the rules for argument promotion properly. Peace, Kevin |
From: John T. V. <jt...@e-...> - 2001-01-25 04:14:17
|
Kevin, I've been following this thread and I may be able to help out here. The= parameter to the printf (0x0f) should be int (per the C99 spec). The only= two ways to specify that a character data type is passed to a function is= via a cast of an int to char or by specifying the constant as '\x0f' (or= '\017'). Even then, most compilers will still pass an int to standardize= the parameter passing mechanism. Hope this helps. John *********** REPLY SEPARATOR *********** On 1/24/01 at 5:01 PM Kevin Vigor wrote: >On 24-Jan-2001 Scott Hughes wrote: >> Thanks for the feedback about the pointer to the sfr. Guess I'm stuck > But I'm seeing some pretty strange >> behaviour >> from printf. With the following code: >> printf("%01X\r\n",0x0f); > >SDCC is passing the constant parameter 0x0f as a single byte; the %X >format specifier wants an int argument. This may be a bug (I'm not sure >offhand if the constant should be promoted to int), but in the meantime, >you should be able to work around it either by typecasting the constant >to int, or by using the 'b' modifier in your printf format string (btw, I >believe this is non-standard and should be changed to 'h', which is >standard, someday), like so: > > printf("%01bX\r\n",0x0f); > >(I am not near a working TINI, so I can't actually test this right now). > > >> one test program from the 1-Wire api, I have a string that I know to be >> valid and it can be printed fine with puts(char*). But use that same >> string >> with printf("%s",char*) and it hangs the tini. > >Probably a similar problem: the %s printf conversion expects a generic >pointer to char. The following code will blow up: > > char _xdata *str; > printf("%s",str); > >(quite apart from the fact that str is uninitialized) because str is >passed to printf as an xdata * rather than a generic *. > >Because puts() has a proper prototype instead of a varargs ..., the >compiler can do the proper conversions for you (if necessary). > >The only workaround for this one is an explicit typecast: > > char _xdata *str; > printf("%s",(char _generic *)str); > >Take-home lesson here: varargs functions (like printf) are weird, and >SDCC probably doesn't follow all the rules for argument promotion >properly. > > Peace, > Kevin > > >_______________________________________________ >sdcc-devel mailing list >sdc...@li... >http://lists.sourceforge.net/lists/listinfo/sdcc-devel |
From: Scott H. <sh...@da...> - 2001-01-25 17:24:23
|
Thanks.. That fixed my printf hex problem. That isn't the way it works with gcc, so I assumed it was a bug. I'm still getting some weird behaviour from printf and sprintf on a few strings. I'm trying to compile tstfind.c from the 1-Wire public domain kit. There's a string which I changed from: char return_msg[128]; to: char msg_buf[128]; char _generic *return_msg = (char _generic*)&msg_buf[0]; Then it's sent to a function defined in owsesu.c: int owAcquire(int,char *,char *); Which I changed all references to char * into char _generic *; Yet still, I sprintf a few bits of text into the return_msg buffer and upon return from that function call, the return_msg buffer contains whatever was in that memory location from the last time I successfully put anything there (i.e. from several test applications ago)... but not the text inserted by owAcquire. In fact, it looks like: printf("return_msg=%s\r\n",(char _generic*)return_msg);> sprintf((char _generic*)return_msg, "testing"); printf("return_msg=%s\r\n",(char _generic*)return_msg); Shows no change to the return_msg. Am I doing something wrong? Thanks in advance... Scott -- Scott Hughes - sh...@da... Engineer, Auto Information Dallas Semiconductor -----Original Message----- > From: sdc...@li... > [mailto:sdc...@li...]On Behalf Of Kevin Vigor > Sent: Wednesday, January 24, 2001 6:02 PM > To: sdc...@li... > Subject: RE: [sdcc-devel]weird printf behaviour > > > > On 24-Jan-2001 Scott Hughes wrote: > > Thanks for the feedback about the pointer to the sfr. Guess I'm stuck > But I'm seeing some pretty strange > > behaviour > > from printf. With the following code: > > printf("%01X\r\n",0x0f); > > SDCC is passing the constant parameter 0x0f as a single byte; the %X > format specifier wants an int argument. This may be a bug (I'm not sure > offhand if the constant should be promoted to int), but in the meantime, > you should be able to work around it either by typecasting the constant > to int, or by using the 'b' modifier in your printf format string (btw, I > believe this is non-standard and should be changed to 'h', which is > standard, someday), like so: > > printf("%01bX\r\n",0x0f); > > (I am not near a working TINI, so I can't actually test this right now). > > > > one test program from the 1-Wire api, I have a string that I know to be > > valid and it can be printed fine with puts(char*). But use that same > > string > > with printf("%s",char*) and it hangs the tini. > > Probably a similar problem: the %s printf conversion expects a generic > pointer to char. The following code will blow up: > > char _xdata *str; > printf("%s",str); > > (quite apart from the fact that str is uninitialized) because str is > passed to printf as an xdata * rather than a generic *. > > Because puts() has a proper prototype instead of a varargs ..., the > compiler can do the proper conversions for you (if necessary). > > The only workaround for this one is an explicit typecast: > > char _xdata *str; > printf("%s",(char _generic *)str); > > Take-home lesson here: varargs functions (like printf) are weird, and > SDCC probably doesn't follow all the rules for argument promotion > properly. > > Peace, > Kevin > > > _______________________________________________ > sdcc-devel mailing list > sdc...@li... > http://lists.sourceforge.net/lists/listinfo/sdcc-devel |
From: Kevin V. <kv...@lu...> - 2001-01-25 18:33:06
|
On 25-Jan-2001 Scott Hughes wrote: > In fact, it looks like: > printf("return_msg=%s\r\n",(char _generic*)return_msg);> > sprintf((char _generic*)return_msg, "testing"); > printf("return_msg=%s\r\n",(char _generic*)return_msg); > > Shows no change to the return_msg. Am I doing something wrong? Just a guess, but I suspect that the constant string "testing" will get passed as an xdata pointer (actually, a code space pointer, but that's the same in this case). Try an explicit cast (I know, yuck...), like so: sprintf((char _generic*)return_msg, (char _generic*)"testing"); As I say, just a guess right now. Peace, Kevin |
From: Scott H. <sh...@da...> - 2001-01-25 18:52:43
|
> Just a guess, but I suspect that the constant string "testing" will get > passed as an xdata pointer (actually, a code space pointer, but that's > the same in this case). Try an explicit cast (I know, yuck...), like so: > > sprintf((char _generic*)return_msg, (char _generic*)"testing"); That seems to have fixed it... And to think, I was worried about my if-elses all over the place.. Now I'm a casting fool. :) That sort of problem is going to make porting of any code a real pain in the neck. Scott -- Scott Hughes - sh...@da... Engineer, Auto Information Dallas Semiconductor |
From: Kevin V. <ke...@vi...> - 2001-01-25 19:35:11
|
On 25-Jan-2001 Scott Hughes wrote: > That seems to have fixed it... > > And to think, I was worried about my if-elses all over the place.. Now > I'm > a casting fool. :) > > That sort of problem is going to make porting of any code a real pain > in the > neck. Yeah, it is a hassle, though it only affects varargs functions. Unfortunately, printf() and friends are one of the first things anybody getting started is going to use... In an ideal world, pointer parameters to varargs functions should be converted to generic pointers by default, but an escape-hatch (like an explicit cast) should be available to override this. I'll take a look at doing that, but I'm not sure it's within my abilities. Peace, Kevin |
From: Johan K. <joh...@id...> - 2001-01-25 19:39:31
|
Hi Scott, You might want to know that I have most of the ow pd kit running (that is the whole WS and the needed ow*.c's, but not yet the owfile stuff) with minimal changes starting from ulinuxgnu. You have to remember that sdcc is targetted towards microcomputers that runs processes standalone in a limited environment. So e.g. we don't want to cast char's to int's in vararg functions (like printf, so said Sandeep, do we Kevin?) since stack space is limited, nor can we pass arguments to main or expect it to return something usefull. Those really are the only changes I made so far (ok, I temporary removed the return_msg's because they are useless in a standalone environment anyway). Kevin is working right now on the multi-dimensional array problem (what your return_msg issue is all about, forget the _generic's: they are default). I expect to release my ow pd port (just as an example of what sdcc can do for you) before the end of this weekend, so instead please try to convince your collegues to send me some of their new sensors (like the DS-ADI-401) so I can test them as well :) You can find the preliminary tstfind.hex, temp.hex and counter.hex at www.iduna.nl/sdcc/ds390/ow You have to run Javakit at 9600 baud, since serial0 (for now, i'm working on it) uses timer1 and so does (has to!) serial1. If you are using Linux (and you should:) you could use "tinitalk -c -b 115200 -B 9600 execute tstfind.hex" that will download the file at 115200baud and start the application at 9600baud. Johan ----- Original Message ----- From: Scott Hughes <sh...@da...> To: <sdc...@li...> Sent: Thursday, January 25, 2001 6:26 PM Subject: RE: [sdcc-devel]weird printf behaviour > Thanks.. That fixed my printf hex problem. That isn't the way it works > with gcc, so I assumed it was a bug. I'm still getting some weird behaviour > from printf and sprintf on a few strings. > > I'm trying to compile tstfind.c from the 1-Wire public domain kit. There's > a string which I changed from: > char return_msg[128]; > > to: > char msg_buf[128]; > char _generic *return_msg = (char _generic*)&msg_buf[0]; > > Then it's sent to a function defined in owsesu.c: > int owAcquire(int,char *,char *); > > Which I changed all references to char * into char _generic *; > > Yet still, I sprintf a few bits of text into the return_msg buffer and upon > return from that function call, the return_msg buffer contains whatever was > in that memory location from the last time I successfully put anything there > (i.e. from several test applications ago)... but not the text inserted by > owAcquire. > > In fact, it looks like: > printf("return_msg=%s\r\n",(char _generic*)return_msg);> > sprintf((char _generic*)return_msg, "testing"); > printf("return_msg=%s\r\n",(char _generic*)return_msg); > > Shows no change to the return_msg. Am I doing something wrong? > > Thanks in advance... > > Scott > > -- > Scott Hughes - sh...@da... > Engineer, Auto Information > Dallas Semiconductor > > > > -----Original Message----- > > From: sdc...@li... > > [mailto:sdc...@li...]On Behalf Of Kevin Vigor > > Sent: Wednesday, January 24, 2001 6:02 PM > > To: sdc...@li... > > Subject: RE: [sdcc-devel]weird printf behaviour > > > > > > > > On 24-Jan-2001 Scott Hughes wrote: > > > Thanks for the feedback about the pointer to the sfr. Guess I'm stuck > > But I'm seeing some pretty strange > > > behaviour > > > from printf. With the following code: > > > printf("%01X\r\n",0x0f); > > > > SDCC is passing the constant parameter 0x0f as a single byte; the %X > > format specifier wants an int argument. This may be a bug (I'm not sure > > offhand if the constant should be promoted to int), but in the meantime, > > you should be able to work around it either by typecasting the constant > > to int, or by using the 'b' modifier in your printf format string (btw, I > > believe this is non-standard and should be changed to 'h', which is > > standard, someday), like so: > > > > printf("%01bX\r\n",0x0f); > > > > (I am not near a working TINI, so I can't actually test this right now). > > > > > > > one test program from the 1-Wire api, I have a string that I know to be > > > valid and it can be printed fine with puts(char*). But use that same > > > string > > > with printf("%s",char*) and it hangs the tini. > > > > Probably a similar problem: the %s printf conversion expects a generic > > pointer to char. The following code will blow up: > > > > char _xdata *str; > > printf("%s",str); > > > > (quite apart from the fact that str is uninitialized) because str is > > passed to printf as an xdata * rather than a generic *. > > > > Because puts() has a proper prototype instead of a varargs ..., the > > compiler can do the proper conversions for you (if necessary). > > > > The only workaround for this one is an explicit typecast: > > > > char _xdata *str; > > printf("%s",(char _generic *)str); > > > > Take-home lesson here: varargs functions (like printf) are weird, and > > SDCC probably doesn't follow all the rules for argument promotion > > properly. > > > > Peace, > > Kevin > > > > > > _______________________________________________ > > sdcc-devel mailing list > > sdc...@li... > > http://lists.sourceforge.net/lists/listinfo/sdcc-devel > > > _______________________________________________ > sdcc-devel mailing list > sdc...@li... > http://lists.sourceforge.net/lists/listinfo/sdcc-devel > |
From: Scott H. <sh...@da...> - 2001-01-25 20:20:41
|
> for you) before the end of this weekend, so instead please try to convince > your collegues to send me some of their new sensors (like the > DS-ADI-401) so > I can test them as well :) I'll see what I can do.. ;) > You can find the preliminary tstfind.hex, temp.hex and counter.hex at > www.iduna.nl/sdcc/ds390/ow > You have to run Javakit at 9600 baud, since serial0 (for now, i'm > working on > it) uses timer1 and so does (has to!) serial1. If you are using Linux (and > you should:) you could use "tinitalk -c -b 115200 -B 9600 execute > tstfind.hex" that will download the file at 115200baud and start the > application at 9600baud. I'm using win2k with a cygwin environment for all of my development. I wanted to try to build your tinitalk, but I'm missing tini.h. Here's my modified Serial390Init routine, in case it helps.. Setting up timer2 for serial0 was a pretty simple fix: void Serial390Init(void) { //Setup Timer1 for baud generation TR1 = 0; // stop timer 1 TL1 = TH1 = DEFAULT_CONSOLE_BAUD; TMOD = (TMOD&0x0f) | 0x20; // timer 1 is an 8bit auto-reload counter TF1 = 0; // clear timer 1 overflow flag TR1 = 1; // start timer 1 #if USE_TIMER2_FOR_SERIAL0 //Setup Timer2 for baud generation TR2 = 1; // stop timer 2 TH2 = RCAP2H = 0xFF; TL2 = RCAP2L = DEFAULT_CONSOLE_BAUD; T2CON |= 0x30; //enable Timer2 control for serial1 T2MOD = (T2MOD&0x0f) | 0x20; // timer 2 is an 8bit auto-reload counter TF2 = 0; // clear timer 2 overflow flag TR2 = 1; // start timer 2 #else T2CON &= 0xCF; //disable Timer2 control for serial1 #endif OpenCOM(0,0);//initialize serial0's buffers so we're ready for the console } Scott -- Scott Hughes - sh...@da... Engineer, Auto Information Dallas Semiconductor |