Steve Fink wrote:

IMCC doesn't handle bsr with non-constant args. A test program would
be something like

  L: $I0 = addr L
     bsr $I0

It will complain that it can't fixup the label '$I0'.

Yep. That's missing. I'll hvae a look at it. (But you could invoke a Sub, which is ok IIRC).


In tracking this down, I also noticed that imcc seems to assume that
you will do a saveall/restoreall pair around bsr calls. (At least,
that's what a comment says.)

Yes, that's correct. Currently imcc does register allocation per compilation units (.sub/.end) and doesn't know anything about calling conventions and specially assumes, that "bsr" doesn't change registers.

This can of course be considered as a bug. It evolved in this direction due to the P6C code generator always did subroutines in this form.

So imcc has to learn somethin about calling conventions, and imcc has to get some information from the HL about these: Does the HL use pdd03_calling_convetions or do bsrs preserve all registers, or whatever.

... I haven't written a test case to see if
this assumption matters, but the code I generate tends to use bsr
specifically for lightweight situations where I do not want to
preserve registers. (Or do a full invoke op.)
It won't work, when you rely on the register allocator:
.sub _test
$I0 = 2
$I1 = 3
bsr L
print $I0
print $I1
print "\n"
end
L: $I2 = 4
$I3 = 5
ret
.end

25

($I2 and $I3 both get register I0)

This shouldn't be to hard to fix - from imcc.y:

if (!strcmp(name, "bsr") || !strcmp(name, "ret")) {
/* ignore subcalls and ret
* because they saveall
*/
}
else {
/* XXX: assume the jump is relative and to the last arg.
* usually true.
*/
ins->type = ITBRANCH | (1 << (nargs-1));

So "bsr" here is treated not as a branch (which of course it is) and no control flow is generated, so the register allocator will fail.

So, we need some definitions about calling conventions and a way how to tell imcc what the HL intended with "bsr"s and the like.

leo

Reply via email to