Dan --

> >Looks like I'm going to have to write some real logic in jakoc
> >pretty soon...
> 
> Aaaaahhh! The horror! :-)

:)

> Seriously, the conventions are geared towards full-blown compilers with a 
> reasonable register ordering module at the very least, which isn't 
> unreasonable to expect for a language implementation. (And folks that want 
> to fake out using a stack will probably work with the top few registers to 
> avoid having to deal with parameter conflicts)

I am thinking about having Jako take the position that it doesn't use
those regs except for calls, and values are immediately copied from
those regs to the real regs for the variables as the tail end of the
callee part of the subroutine linkage. That will at least permit Jako
to be correct even if it isn't as efficient as possible. Later I can
worry about being smarter. Heck, right now Jako sometimes generates
code with a branch to the next instruction (ah, the joy of simple
code generators...).

> > > *) The callee is responsible for saving and restoring non-scratch registers
> >
> >Nice for callee since if its work fits into five regs of each type
> >its not going to have to do any saves or restores. Caller, though, is
> >going to have to vacate those regs. So, if caller got args in those
> >regs and then calls anyone else, it has to move them from those regs (or
> >save them).
> 
> Caller will only have to vacate those registers if they're being used and 
> need to last past the call to the function. If the register assignment 
> algorithm's clever (which is a big if) the lifetime of temporaries will 
> keep function calls in mind.

Big "if" indeed. At least for Jako's near future.

> > > *) The first five registers (I0-I4, S0-S4, P0-P4, N0-N4) are scratch 
> > and do
> > > not have to be preserved by the callee
> >
> >Still thinking about this... We are reducing the overall number of reg
> >copies going on by adding these special cases. I just wish we had an
> >approach that was both uniform (simple, no special cases) and fast too.
> 
> You, and me, and about a zillion other people. Generally speaking the 
> choices are fast, uniform, and scalable. Choose two.

Hmmmm. I tried reading section 29 (Subroutine Linkage) of the MMIXware
book (pages 32-34) for inspiration, but I didn't see how anything there
could help us. MMIX has 256 logical general-purpose 64-bit registers.
That's a handy reg size since a reasonable float can sit in there as
well as an unreasonable int. The local-marginal-global register
distinction used by MMIX is interesting, but I think it might lose its
appeal with 4 distinct typed register files.

Knuth does make the statement:

    These conventions for parameter passing are admittedly a bit
    confusing in the general case, and I suppose people who use them
    extensively might sometime find themselves talking about "the
    infamous MMIX register shuffle." However, there is good use for
    subroutines that convert a sequence of register contents like
    (x, a, b, c) into (f, a, b, c) where f is a function of a, b,
    and c but not x. Moreover PUSHGO and POP can be implemented with
    great efficiency, and subroutine linkage tends to be a significant
    bottleneck when other conventions are used.

Its that last sentence that got my attention... But, I still don't
know if we could make use of any of those ideas. I can imagine
having separate L and G for each register file, and otherwise
following the same procedure, but I suspect we'd be unhappy with
the MMIX conventions without having a larger number of registers.

BTW, how did you choose 32 for the number of regs?

> This is really only an issue for folks writing code generators by hand, and 
> with 32 of each register type most people won't hit it. Plain parser 
> add-ons will use the core code generator, so they won't need to worry about it.

Yeah. I'm trying very hard not to put anything really sophisticated
into jakoc (at least not yet). Right now I can still tweak things
reasonably well. If I add much more complexity, I'm going to have
to actually write a real compiler, and if I write a real compiler I
probably won't be able to resist the temptation to turn Jako into the
language I *really* wish I had, and that would be a bigger project.

> > > *) The callee is responsible for making sure the stack is cleaned off.
> >
> >So, in the case of zero args, do we still push a zero on the stack to
> >make a proper frame? I think yes...
> 
> If the function is listed as taking a variable number of args, yes. 
> Functions marked as taking no args at all don't get anything put on the stack.

I'm thinking yes because of stack unwinding. Don't we need to have
parity between return addresses on their stack and frames of args
on their stack? Oh wait. We're popping (restoring) those off the stack
on subroutine entry, so in general the arg stack should be empty
most of the time, right? Adding to that the fact that most of the
time our args and results will be passed in regs, and I guess I
can see that we won't need it. Except for the variable arg and variable
result case, which is what Jako does today.


> > > If there are a variable number of arguments, all the *non* fixed
> > > args go on the stack.
> >
> >So for right now, just pretend that all Jako subroutines take a variable
> >number of args.. :) (Until I get the time to write fully compatible
> >conventions in jakoc, anyway).
> 
> That's fine. A perfectly workable solution.

Cool.

> >Can we have ops to inquire on the type of the topmost stack entry?
> 
> In the works, yep.

Cool.


Regards,
 
-- Gregor
 _____________________________________________________________________ 
/     perl -e 'srand(-2091643526); print chr rand 90 for (0..4)'      \

   Gregor N. Purdy                          [EMAIL PROTECTED]
   Focus Research, Inc.                http://www.focusresearch.com/
   8080 Beckett Center Drive #203                   513-860-3570 vox
   West Chester, OH 45069                           513-860-3579 fax
\_____________________________________________________________________/

Reply via email to