I agree with this, if I remember correctly this was original
implementation, but cannot remember why I changed it to the way it
is. It would be great if you can find some time to change the
mcs51 port as well.
[mailto:sdcc-devel-admin@... Behalf Of Kevin Vigor
Sent: Tuesday, May 29, 2001 12:44 PM
Subject: [sdcc-devel] INSRs and register banks
> You reversed what I did in 1.74 because of the
>#if 1 // bug id #223659, fixed in mcs51/ds390/gen.c 20010513
> Now it is broken again for the ds390 port.
Fixed. I did not go back to the old way, however; I changed the rules
here. Now the register bank(s) used by called functions are saved at
entry to the ISR instead of just before the call to the function. This
has the big advantage of only saving the register bank once instead of
the horrible "push the entire bank/call/pop the entire bank" code we got
before (inside a loop even!), and the smaller advantage of allowing me to
keep using my "improved parameter passing" code (which really is better
for the non-ISR case). It has the small disadvantage of requiring the ISR
to save its local in-use registers on the stack before calling any
function, which really shouldn't be necessary if the called function uses
a different register bank. I think it is a net gain overall.
Sandeep, since I think this is a real improvement, I think it should go
in the mcs51 port as well. Let me know if you agree.
I had never before really looked at the whole 'using' thing, and it seems
to me that the rules are not obvious. I think the following rules for
using 'using' are correct. If everybody agrees that these are right, I
think they should be added to the documentation. btw, I think these rules
are the same regardless of my changes.
<begin proposed documentation>
1: The 'using' attribute (which tells the compiler to use a register bank
other than the default bank zero) should only be applied to 'interrupt'
functions (see note A below). This will in most circumstances make the
generated ISR code more efficient since it will not have to save
registers on the stack.
2: The 'using' attribute will have no effect on the generated code for a
non-'interrupt' function (but may occasionally be useful anyway; see note
3: An 'interrupt' function using a non-zero bank will assume that it can
trash that register bank, and will not save it. Since high-priority
interrupts can interrupt low-priority ones on the 8051 and friends, this
means that if a high-priority ISR 'using' a particular bank occurs while
processing a low-priority ISR 'using' the same bank, terrible and bad
things can happen. To prevent this, no single register bank should be
'used' by both a high priority and a low priority ISR. This is probably
most easily done by having all high priority ISRs use one bank and all
low priority ISRs use another. If you have an ISR which can change
priority at runtime, you're on your own: I suggest using the default bank
zero and taking the small performance hit.
4: It is most efficient if your ISR calls no other functions.
5: If your ISR must call other functions, it is most efficient if those
functions use the same bank as the ISR (see note A below); the next best
is if the called functions use bank zero. It is very inefficient to call
a function using a different, non-zero bank from an ISR.
(note A: possible exception: if a function is called ONLY from
'interrupt' functions using a particular bank, it can be declared with the
same 'using' attribute as the calling 'interrupt' functions. For
instance, if you have several ISRs using bank one, and all of them call
memcpy(), it might make sense to create a specialized version of
memcpy() 'using 1', since this would prevent the ISR from having to save
bank zero to the stack on entry and switch to bank zero before calling
<end proposed documentation>
My head hurts.
sdcc-devel mailing list