ICL 1900 Calling Sequence

The language independant procedure/function/subroutine calling sequence on ICL machines is: The return value for a function is placed in X6, or the floating point accumulator as appropriate.

For example, a PLAN program could call a FORTRAN integer function with two arguments like this:

      CALL  1  ISUM
      LDN   3  LOWVAL1     [ get addr of lower variable to X3
      LDX   3  'UPVAL2'    [ get addr if upper variable to X3
      STO   6  SOMEWHERE   [ store result of function
If ISUM were coded in PLAN it could look like this:
#PROGRAM       /ISUM
#LOWER
               LINK
               ARG1
               ARG2
#PROGRAM
      STO   1  LINK          [ save link address
      OBEY     0(1)          [ get addr of 1st arg
      LDX   0  0(3)          [ get value of 1st arg
      STO   0  ARG1
      OBEY     1(1)          [ get addr of 2nd arg
      LDX   0  0(3)          [ get value of 2nd arg
      STO   0  ARG2
      ...
      LDX   6  RESULT        [ get result to X6
      LDX   1  LINK          [ restore link
      EXIT  1  2             [ return

Call-by-name from ALGOL

If the calling program is written in ALGOL then things can get more exciting: value arguments are passed as for FORTRAN, but call-by-name arguments are passed by thunk functions, which may destroy all registers other than X1 when they are OBEYed.

Arrays

Arrays can be passed in one of two ways:
  1. By passing the name of the array in the call:
           DIMENSION X(22)
           ...
           CALL PLANSUB (X)
    
    This passes the address of an array descriptor block to the PLAN function.

    The FORTRAN library provides a funcion GETAH to transform the array descriptor into an array header that can be manipulated by PLAN to find the actual elements of the array. The same format of array descriptor is used by ALGOL.

  2. By passing one element of the array:
           CALL PLANSUB (X (5))
    
    This passes the address of the element with one or both of the top two bits of the address set.

    Note that if the address is used directly for character instructions (LDCH, DCH, BCHX) then the two high bits should be masked out.

    COBOL has no way of generating FORTRAN/ALGOL compatible array headers, but a trick can be used to pass a character pointer to the array which Fortran will interpret as a pointer to an element of the array.

    From tp4449 Fortran - George 3 and 4 compilers:

    PASSING INFORMATION VIA ARRAYS

    If a dummy argument of a FORTRAN subroutine is an array name, then the actual argument may be an array name or an array element reference. If it is an array name, the address of the array header is passed to the subroutine. If the actual argument is an array element, the address of that element is passed to the subroutine. FORTRAN distinguishes between the two by checking whether or not either of the top two bits of the address passed to it is set. If set the argument is treated as an array element, if not set it is treated as an array header. Therefore to pass an integer table across from COBOL to FORTRAN, either of the two top bits of the address passed across must be set. The following technique may be used: the COBOL field must start on a word boundary and the parameter in the ENTER statement must be a field defined to start at the second character position.

    Example

    A FORTRAN subroutine is to be called from a COBOL program
           SUBROUTINE FORT(M,N)
           DIMENSION M(N)
           END
    ...
    
           02 TABLE
              03 ELEMENTS PIC 9(6) COMP SYNC RIGHT OCCURS 25 DEPENDING ON N.
           02 ARRAY REDEFINES TABLE.
              03 FILLER PIC X.
              03 CHARADD PIC X.
              03 FILLER PIC X OCCURS 98.
           ENTER FORTRAN FORT USING CHARADD,N.
    
    The address of CHARADD is passed across in character modifier form. As it is the second character of a word, the address is passed across with one of the top two bits set, so FORTRAN interprets this as the address of an array element, and this will point to the first word of TABLE.