% -*- Mode: LaTeX;  -*-
% File: compiler.tex
% Author: Mike Bolotski (misha@ai.mit.edu)
% Copyright (C) Artificial Intelligence Laboratory, 1996
%*-------------------------------------------------------------------------
%
%* PURPOSE:
%*
%* HISTORY:
%%% * Last edited: Jun  6 17:59 1996 (misha)
%* Created: Wed Jun  5 15:29:42 1996 (misha)
%*-------------------------------------------------------------------------

%%% $Log$

\section{Compiler Notes}

The compiler (and therefore the performance measures) target a slightly
different machine than the Abacus-1 chip.  

\paragraph{On-Chip Address Register} Specifically, we assume the
ability to operate on the external memory address register in each chip. In
the current design, the register can only be loaded externally. This is not
a problem if all the program is doing is accessing absolute memory
locations, since the overhead of an additional \texttt{load-PMAR} compared
to a 40-cycle load is minimal. The performance hit is on the order of
2.5\%.

However, if the PMAR is relative, as in the case of a parallel
memory stack (parameter passing, local memory allocation), then the
PMAR value manipulation must take place in the scalar unit, which is
several times slower than the parallel array.  Thus, a sequence of
\begin{verbatim}
LOAD      RS1, PMAR_MEM
RS1       := RS1 + 2
STORE     PMAR_MEM, RS1
LOAD-PMAR RS1
\end{verbatim}
will take 7 cycles.

This is still not bad, but is a more substantial overhead of 15\%.


\subsection{Calling Convention}

Procedures in this language can return multiple arguments on the stack.

\begin{minipage}[t]{3in}
\footnotesize
\begin{verbatim}
                      ; PMAR = 40
STORE PMAR[0], ARG0   ; MEM[40] := ARG0
STORE PMAR[1], ARG1   ; MEM[41] := ARG1
JSR FOOPROC           ; upon return, PMAR = 40
LOAD  VAL0, PMAR[0]  ; VAL0 := MEM[40] (ret0)
LOAD  VAL1, PMAR[1]  ; VAL1 := MEM[41] (ret1)
LOAD  VAL2, PMAR[2]  ; VAL2 := MEM[42] (ret2)
\end{verbatim}
\end{minipage}
\begin{minipage}[t]{3in}
\footnotesize
\begin{verbatim}
PMAR := PMAR + 2      ; PMAR = 42
LOAD  PAR0, PMAR[-2]  ; PAR0 := MEM[40]  (arg0)
LOAD  PAR1, PMAR[-1]  ; PAR1 := MEM[41]  (arg1)
routine body
STORE PMAR[0],  RET0  ; MEM[40] := RET0
STORE PMAR[1],  RET1  ; MEM[41] := RET1
STORE PMAR[2],  RET2  ; MEM[42] := RET2
PMAR = PMAR - 2       ; PMAR = 40
RTS
\end{verbatim}
\end{minipage}

Points to note:
\begin{itemize}
\item Return results must be grabbed off the stack immediately, before any
  subsequent procedure calls, or the results will be overwritten. This
  means that explicit transfer instructions are required, instead of just
  entering the current variable location in the tables.%
  \emph{Note: Can this cause problems for register-based parameter passing
    now?}

\item This technique is compatible with local storage allocation.
  Unfortunately, lexically scoped variables are \emph{not} compatible, as
  pointers to previous stack frames must be passed around. For now, the
  compiler still does not support re-entrant procedures.\emph{Note: change
    the scoping to C-like only. Easy: when looking up names in environment,
    only allow ones declared in this procedure or in top.}
\end{itemize}


\subsection{Pseudo-Instruction Translation}

Some intermediate code instructions produced by the first phase of the
compiler do not map directly to machine language instructions and must be
translated.

\paragraph{Push-parameter}  These PIs push parameters onto the stack. They 
Push-param pseudo-instructions are processed by the register allocator, as
the variables must be in registers before they are stored.  The
instructions are translated to register stores at object-generation time.

\texttt{push-param v, i} is mapped to \texttt{store pmar[i'], v}, where
$i'$ is $i-max-1$. Eg, $i=4$, $max=3$, $i' = 0$. This means that the PMAR
must be set to the start of the parameter  block.

Pop-params are a different story.





%%% Local Variables: 
%%% TeX-master: "main"
%%% comment-start: "%%% "  
%%% End: ***

