=head1 NAME

IMCC - calling conventions

=head1 VERSION

=over 4

=item 0.1 initial proposal

=item 0.2 initial, checked in

=item 0.3 updated parrot calling conventions and invoke

=back

=head1 OVERVIEW

This document describes subroutine calling conventions.

=head1 DESCRIPTION

As imcc does register allocation, it has to track the life span of
variables. This includes the (possible) data flow in and out of
subroutines.

=head1 Parrot calling conventions - CPS

=head2 PASM Subroutines

  newsub $P0, .Sub, _sub_label
  newsub $P1, .Continuation, ret_addr
  ...
  .pcc_begin prototyped|non_prototyped
  .arg x	# I5
  .arg y	# I6
  .arg z	# I7
  .pcc_call $P0, $P1	# r = _sub_label(x, y, z)
  ret_addr:
  .local int r  # optional - new result var
  .result r
  .pcc_end

  .pcc_sub _sub_label [prototyped|non_prototyped]
   .param int a # I5
   .param int b # I6
   .param int c # I7
  ...
  .pcc_begin_return
   .return xy   # e.g. I5
  .pcc_end_return
  ...
  .end

Notes:

=over 4

=item * B<prototyped>, B<non_rototyped>

If a subroutine doesn't have any prototyped specifier, code gets
emitted to receive parameters by both flavors.

=item * B<newsub>

Currently needs the B<.Class> syntax, i.e. a B<dot> in front of the
class name.

=item * B<pcc_call>

Takes either 2 arguments: the sub and the return continuation, or the
sub only. For the latter case an B<invokecc> gets emitted.

=item * Saved Regs:

Only the top half of registers are preserved currently.

=item * B<.args>, B<.param>, B<.result>, and B<.return> are optional.

=item * B<.param>

The B<.param> declarations must be the first statements in the
sub if any. No other statements are allowed between B<.param>.

=back

=head2 NCI

Proposed syntax:

  $P0 = load_lib "libname"
  $P1 = dlfunc $P0, "funcname", "signature"
  ...
  .nci_begin
  .arg x	# I5
  .arg y	# I6
  .arg z	# I7
  invoke $P1	# r = funcname(x, y, z)
  .local int r  # optional - new result var
  .result r
  .nci_end

This prepares parameters as described in
F<pdd03_calling_conventions.pod>, saves the registers and invokes the
function.  The B<.arg> pseudo ops put the given argument into
increasing registers of the appropriate type.

=head2 Status

Partially implemented, s. t/*/pcc.t.

=head1 Exception handlers

TBD.

=head1 Stack calling conventions

Arguments are B<save>d in reverse order onto the user stack:

   .arg y	# save args in reversed order
   .arg x
   call _foo	#(r, s) = _foo(x,y)
   .local int r
   .local int s
   .result r	# restore results in order
   .result s	#

and return values are B<restore>d in argument order from there.

The subroutine is responsible for preserving registers.

 .sub _foo		# sub foo(int a, int b)
   saveall
   .param int a         # receive arguments from left to right
   .param int b
   ...

   .return mi		# return (pl, mi), push results
   .return pl		# in reverse order
   restoreall
   ret
 .end

=head2 Rational

Pushing arguments in reversed order on the user stack makes the left
most argument the top of stack entry. This allows for a variable
number of function arguments (and return values), where the left most
argument before a variable number of following arguments is the
argument count.

=head2 Status

Implemented. When the subroutine is in the same compilation unit, the
callee can B<saveall> registers; when the subroutine is in a different
compilation unit, the callee must preserve all used registers.

=head1 Invoking subroutines

IMCC tries to keep track of the address where the B<invoke> will branch
to, but can only succeed to do so when the B<set_addr> and the
B<invoke> opcodes are located together.

  $P10 = new Sub
  $I1 = addr _the_sub
  $P10 = $I1
  invoke $P10   # ok

But not:

    bsr get_addr
    invoke $P10 # error
    ...
  get_addr:
    $P10 = new Sub
    $I1 = addr _the_sub
    $P10 = $I1
    ret

The latter example will very likely lead to an incorrect CFG and thus to
incorrect register allocation.

=head2 Status

Implemented. When the subroutine does B<saveall>/B<restoreall>, the
branch from the B<ret> statement back is ignored in the CFG.

=head1 Namespaces and lexicals

 - Should imcc keep track of pad opcodes?
 - Should imcc even emit such opcodes from e.g. .local directives?

=head1 FILES

F<imcc.y>, F<t/syn/bsr.t>

=head1 AUTHOR

Leopold Toetsch <lt@toetsch.at>

=cut

# vim: expandtab shiftwidth=4 tw=70:

