\ Generischer Aufruf einer C-Funktion mit Adresse a-addr.
\
\ Ãœbergabe von x1..x4 als Argumente der Funktion (in Registern).  Weitere
\ Argumente i*x kann die Funktion vom Forth-Stack beziehen, allerdings muss
\ man diese (und nur diese) in umgekehrter Reihenfolge auf den Stack legen,
\ und am Ende selbst wieder vom Stack entfernen.
\
\ Rückgabewerte der Funktion werden als x5 und x6 zurückgegeben.  Je nachdem,
\ ob und wieviel die Funktion zurückliefert, enthalten diese keine sinnreichen
\ Werte.  Z.B. liegen zurückgelieferte 'int' Werte nur in x5.
ABI-CODE funcall  ( i*x x1 x2 x3 x4 a-addr -- i*x x5 x6 )
   29   29  -12  addiu,   \ Register 4, 31, 16 sichern
   4   0 29  sw,
   31   4 29  sw,
   16   8 29  sw,

   \ Tausche Stackpointer von C-Stack und Forth-Stack
   \ Achtung Stackpointeroffset: Registerargumente in C reservieren auch
   \ (ungenutzten) Platz auf dem Stack!
   16   29   move,        \ C-Stackpointer in Register 16 sichern
   29   4   4  addiu,     \ Forth-Stackpointer zu C-Stackpointer 
   
   25   0 4  lw,          \ a-addr laden
   7   4 4  lw,           \ Argumentregister 5-7 laden
   6   8 4  lw,
   5   12 4  lw,

   31   25  jalr,         \ Funktionsaufruf
   4   16 4  lw,          \ und Argument 4 laden (Sprungverzögerung beachten!)
   
   29   16  move,         \ C-Stackpointer wiederhestellen
   4   0 29  lw,          \ Register 4, 31, 16 wiederherstellen
   31   4 29  lw,
   16   8 29  lw,
   29   29  12  addiu,  
   
   2   16 4 sw,           \ Resultatregister 2, 3 auf Forth-Stack
   3   12 4 sw,      
   31 jr,                 \ Funktions-Return
   2 4 12 addiu,          \ neuer Forth-Stackpointer in Reg. 2 zurück
END-CODE

\ Funktionsaufrufe von C-Funktionen mit bestimmter Zahl an
\ Parametern/Rückgabewerten.  Achtung: auch hier müssen ab dem 5. Argument
\ alle Argumente in umgekehrter Reihenfolge übergeben werden!
: void(void)  >r 0 0 0 0 r>  funcall 2drop ;
: void(int)  >r 0 0 0 r>  funcall 2drop ;
: void(2xint)  >r 0 0 r>  funcall 2drop ;
: int(void)  >r 0 0 0 0 r>  funcall drop ;
: int(int)  >r 0 0 0 r>  funcall drop ;
: int(2xint)  >r 0 0 r>  funcall drop ;
: int(3xint)  >r 0 r>  funcall drop ;
: int(4xint)  funcall drop ;
: int(6xint)  funcall drop nip nip ;