This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Why does the Keil compiler generate bad code for the DS400C80?

The following code:
fwsUniChar c;
fwsUniChar *temp;

temp=p->inPtr;
c = *temp;
temp++;
p->inPtr = temp;
correctly increments the pointer p by 0x01


instead of
fwsUniChar c = p->inPtr++;
which incorrectly increments the pointer p by 0x101
This code compiles and runs correctly with ANSI C compilers



Also
routine1() reentrant
{
enum ElementTagType type;

routine2(&type);
}

routine2(enum ElementTagType *type)
{
type = START_TAG;
}


does not work (i.e. type in routine1 is not set to START_TAG after calling routine 2.

There is a default XBPSTACK

Any Ideas

Thanks

Barry

  • Regarding the second problem, what you probably want is:

    routine2(enum ElementTagType *type)
    {
        *type = START_TAG;
    }
    

  • "The following code:

    fwsUniChar c;
    fwsUniChar *temp;
    
    temp=p->inPtr;
    c = *temp;
    temp++;
    p->inPtr = temp;
    correctly increments the pointer p by 0x01"

    You did not show us how p is declared. That aside, wouldn't that be incrementing the inPtr member of whatever p is pointing to, not p?.

    "instead of
    fwsUniChar c = p->inPtr++;
    which incorrectly increments the pointer p by 0x101"


    Again, see above. Also, are you certain that storing into c, the value of the inPtr member of whatever p is pointing to, is what you are trying to achieve here? If the inPtr member is a pointer, wouldn't you want:
    fwsUniChar c = *p->inPtr++;

  • Sorry for the typo

    The original code was

    *type = START_TAG;

    as you correctly point out.

    The compiler is still generating bad code my typo notwithstanding. Any ideas?

    Thanks

  • Sorry another typo

    The originally incorrectly compiled code was

    enum RuleResult Produce_Digit(struct ParsingContext *p)
    {
    fwsUniChar c = *p->inPtr++;

    I believe the sytax is correct to fetch the charater and increment the pointer by 1 (not 0x101) and the structure is a lot smaller than 0x100.

    Any ideas why the code is incorrectly generated?

  • At the risk of asking the obvious, with whatever tool you are using to inspect the pointer, are you sure you are looking at the address part of the 3-byte generic pointer? I take it that you are using the large memory model, so your pointers are likely pointing to XDATA, which is identified by a memory type byte of 0x01 as part of the pointer.

    I guess the other way to present this, is to verify that the 3 bytes representing the pointer (assuming generic pointer p points to a byte at XDATA address zero) does not change from 0x01 0x00 0x00 to 0x01 0x00 0x01 like we'd expect (if you have not already done so).

  • I tried to duplicate the first problem using the following example code and couldn't:

    struct info_st
      {
      char *ptr;
      int  number_1;
      long number_2;
      };
    
    char junk[] = "1234567890";
    
    char *check_struct_ptr_inc (struct info_st *p)
    {
    volatile char c;
    c = *p->ptr++;
    return (c);
    }
    
    void main (void)
    {
    struct info_st ppp = { junk, 12, 123456789L };
    check_struct_ptr_inc (&ppp);
    while (1);
    }

    I tried this in LARGE, 512K Contiguous, and 16M Contiguous ROM models and the program ran just fine.

    I used C51 V7.06a from the update section of the web site.

    Jon

  • Sorry, bad example use of the ubiquitous name p in this case, since your parameter is also named p. Using your specific example, you would look at the memory allocated to p->inPtr and verify that the 3-byte generic pointer inPtr member changed (or not) as I described.

  • I am using a MetaLink ICE for the DS80C400 to look at the pointers.

    I am using version 7.06a (the latest version of the compiler) large memory model and the pointer and contents are in XDATA.

    When I use the work-around the pointer changes from 0x01748f to 0x17490 and the program runs correctly.

    When I use the original code the pointer changes from 0x01748f to 0x17590 and the program fails. I inspected the characters addressed by the pointers as a sanity check.

    Barry

  • I am using version 7.06a (the latest version of the compiler)and a large memory model.

    I'll try your test program on Monday, and try to determine what the problem is.

    Thanks

    Barry

  • "When I use the original code the pointer changes from 0x01748f to 0x17590 and the program fails."

    You might try inspecting the assembly code/listing looking to see whether 257 is added to the pointer "all at once" or is spread out more (e.g., pointer incremented by one, then 256 added to it elsewhere). That might help point us in the right direction.

  • This simple example fails on the DS80C400.

    Before call
    PPP->PTR X:010676


    After call
    PPP->PTR X:010777


    The compiler does not work for the DS80C400.

  • Hmmm. It works just fine here. Maybe we have different project options. I'm using LX51 and AX51 with LARGE memory model (variables in XDATA) and 512K contiguous mode.

    Jon

  • Jon,

    I am using the same tools for the Dallas 400 chip.

    Keil has reproduced both prolems and is working on a fix (I hope).

    I have also found another reentrant and &ptr problem. Which I have reported to Keil.

    Thanks for the simple example.

    Barry