I don't think God intended mortals to write re-entrant C code on PIC's :)
Now MCS51 is a different story. I think God intends people to write
re-entrant C code on them, only to make compiler writers(Sandeep?) pay for
mistakes in previous lives :)
At 01:38 AM 3/7/01 -0600, you wrote:
>pCode = post code generation optimization
>The PIC doesn't have a data stack. Bummer. This was made painfully clear by
>void inc(unsigned char k)
> uchar0 = uchar0 + k;
>void nested_call(unsigned char u)
> uchar1 = uchar1 + u;
>each of these functions saves a local copy of the input parameter. The logic of
>SDCC is such that these get saved into the same registers. Consequently when
>`nested_call' calls `inc', the state of nested_call's local variables must be
>preserved. This is done quite easily with a PUSH, easily that is if you have a
>The way I thought of getting around this issue on the PIC Port was to advantage
>of pCode. But I'd like to bounce this idea off of others to see if it's
>Here's how it would work. Instead of statically assigning local registers,
>dynamic scheme. Designate a block of memory to be used as this `dynamic'
>allocation area. This is loosely analogous to designating RAM for a stack.
>designation is mostly for conceptual purposes, because the algorithm
>automatically determines the max amount of storage needed for the`stack'.)
>The code generation logic in ralloc.c/gen.c can remain essentially the same.
>However, when the pCode is expanded into assembly, the pCodes for push and pop
>will demarcate ranges for which local variables may conflict. So for each push,
>a flow analysis will be performed to ascertain the register usage up to the
>point of the matching pop. In a sense, this is like the live range calculation
>except that it can cross ebb's or function boundaries. Based on this flow
>analysis, the push/pop pair can be removed by reassigning the location of the
>register being pushed.
>So taking the above example, each function will designate say r0 as the
>for storing the local copy of the parameter being passed in. In the pCode
>expansion of `nested call', the PUSH pCode is encountered. The flow is traced
>and when the CALL pCode is encountered the flow analysis will be directed
>accordingly. Upon analyzing the pCode for the function `inc()', it's determined
>that register r0 is being used. When inc()'s return is encountered, the flow
>analysis again returns to 'nested_call()' and the pCode for the matching POP is
>found. The flow analysis stops. From this it's determined that the flow between
>the matching PUSH and POP's uses r0. Consequently, nested_call()'s usage of r0
>is changed to say r1.
>Caveat - this would have to go into the linker. But I'm already convinced that
>to get the most out of pCode optimization that linker logic will necessarily be
>One of the benefits of this approach is that it will automatically
>maximum space needed for 'stack' storage. (It may not determine the optimum,
>Except for the complications of recursion (and the related issue of calling the
>same function more than once in a string of calls) does anyone see anything
>wrong with this approach?
>I hope this explanation was not too confusing.
>sdcc-devel mailing list