gtpa2m2bApplication Programming

Calling Other Functions and Programs

The following TARGET(TPF) calls are not supported:

The compilers that support the TARGET(TPF) compiler option also provide the appropriate linkage for other function calls. Ensure that you do the following:

  1. You must include the tpflink.h header file by using #include. This file contains the #pragma directive for the library.
  2. Parameter passing.

Function Linkage:

In ISO-C the linkage type is automatically defined by the linkage editor or online service.

#pragma Compiler Directive for TARGET(TPF)

A #pragma directive is an implementation-defined instruction to the compiler used for assembly language programs or library functions in TARGET(TPF). When a TPF program is compiled, the #pragma directive is used to communicate critical information to the compiler concerning:

When a C function is compiled for use in the TPF system environment, the compiler needs to know which TPF program segment will contain the compiled code. For entry points, the function name is initially assumed to match the TPF segment name. However, from the C programmer's point of view this is not always desirable, and there is the additional problem of the library functions, of which none of the names match TPF segment names.

The compiler is notified of the segment name to which a function name maps by the #pragma map directive. Figure 21 shows the format of the #pragma map statement.

Figure 21. TARGET(TPF) C #pragma map Statement Format


          #pragma map(internal_name, "external_name")
 

#pragma
is the compiler directive used to pass information to the compiler

map
identifies the type of data being passed

internal_name
is the name by which the C function is known

external_name
is the name used when generating linkage to the function.

For example, the statement

     #pragma map(accept_trans, "QZZ0")

maps the TPF segment name QZZ0 to C function accept_trans.

When the compiler finds a call to another C function, the compiler needs to know what type of function call expansion to generate. When compiling the called function, the compiler needs to know what type of return linkage to generate.

The #pragma linkage with type TPF statement is not supported in ISO-C and should be removed from any TARGET(TPF) programs that are being migrated to ISO-C. In TARGET(TPF), linkage information is passed to the compiler by the #pragma linkage directive. Figure 22 shows the format of the #pragma linkage statement for TARGET(TPF). #pragma linkage of type TPF is not valid for ISO-C.

Figure 22. C #pragma Linkage Statement Format for TARGET(TPF)


          #pragma linkage(internal_name,TPF,tpftype)
 

#pragma
is the compiler directive used to pass information to the compiler.

linkage
identifies the type of data being passed.

internal_name
is the name by which the C function is known.

TPF
is the string that identifies the TPF programming environment. This
is valid for TARGET(TPF) only.

tpftype
describes the type of object being linked to:

  1. C indicates a C entry point. This is the default type used if no
    linkage statement is found.
  2. N indicates that the function is an assembler program.
  3. An integer in the 0-999 range indicates that the function is a
    library function.


Note:
This value is not range-checked at compile time.


For example, the statement

     #pragma linkage(malloc, TPF, 42)

identifies malloc as a library function and assigns it an index number of 42 in the quick enter directory.

If no #pragma linkage directive is found for a given function, the compiler will assume a type-C linkage.

All of the #pragma directives required for the C/370 run-time library programs are collected into a single header file, tpflink.h. The tpflink.h header is included by tpfeq.h. Because tpfeq.h is required to be the first header in every TARGET(TPF) C program, all linkage information for the C/370 library functions required by the compiler is guaranteed to be available to application programs.

Parameter Passing (from C to C)

There are no special considerations for parameter passing between C functions or programs in TPF systems, except for the passing of structures.

Note:
The following information is a TARGET(TPF) restriction only. Although structures are passed by value (as are all parameters), this can take up a lot of stack storage, and stack storage is a scarce commodity. One way to preserve stack storage is to pass addresses of structures (using the & operator), rather than passing the structures themselves. The parameter should be declared as const in the called function (to prevent unintentional modification of the structure passed by reference). This practice is strongly recommended.

Calling a C Program (from Assembler)

There can be times when you want to call a segment written in C from a segment written in assembler. This is done using an Enter function. When doing so, it is important to know whether the C segment being called is TARGET(TPF) or ISO-C because the register conventions are different in each. See TPF Program Development Support Reference for more information about register conventions.

Note:
The preceding information does not apply to C++ functions except for those that use extern "C" linkage.

Assembler Calling C: The C Parameter List

Because C entry points are normally called using the TPF Enter mechanism, it is possible to start a C entry point function from an assembler program using one of the Enter macros. The assembler program must construct a C parameter list in the format expected by the C compiler-generated code. This section explains the format of the C parameter list for ISO-C and TARGET(TPF).

Note:
The format of the C parameter list is an IBM restricted interface, and could change in future releases. Do not use this interface unless absolutely necessary.

The compiler-generated code allocates storage for the parameter list in the calling function's stack frame. All parameters are passed by value. This applies to structures as well; the entire structure is copied to parameter list storage. (Arrays are treated as pointers; the address of the array is passed by value.)

The compiled code assumes that R1 contains the address of the parameter list for ISO-C and R6 contains the address of the parameter list for TARGET(TPF). The format of the parameter list takes one of two forms, depending on the type of value returned by the function. If the function returns type integer, character, or pointer, the parameter list has the structure shown in Figure 23.

Figure 23. C Parameter List (Part I)




Each parameter occupies one fullword of storage, except for float and double, which occupy two consecutive fullwords. Unsigned parameter values are right justified and padded on the left with binary zeros. Signed parameters are right justified and have sign extension on the left.

If the function returns type float, double, struct, or union, the parameter list has the structure shown in Figure 24.

The first fullword of the parameter list contains the address of an area of sufficient size to contain the returned float, double, structure, or union. The called function simply stores its result in the area indicated.

Figure 24. C Parameter List (Part II)




Calling an Assembler Program (from C)

This section describes the interface requirements for assembler and C language.

Entry points implemented in assembler language can be called from ISO-C without any special calling protocol. When the assembler segment is called, the run-time parameter linkage is automatically handled by the control program.

Figure 25. TPF_regs Structure. Used to pass parameters to assembler programs in registers.


struct  TPF_regs
  {
  long int    r0;
  long int    r1;
  long int    r2;
  long int    r3;
  long int    r4;
  long int    r5;
  long int    r6;
  long int    r7;
  };

In TARGET(TPF), entry points (TPF segments) written in assembler are typically called N-type linkage segments, which comes from their required #pragma linkage statement:

    #pragma linkage(SEG1, TPF, N)

The N in this statement means Non-C. N-type linkage implies that the segment to be called has no knowledge of the existence or format of a C compiler parameter list and may, therefore, be expecting some or all of its parameters in registers.

In either ISO-C or TARGET(TPF), to call an assembler program in C language, you must code a valid C prototype statement for the assembler program, passing the TPF_regs structure as follows:

    void seg1(struct TPF_regs *);

Including this prototype statement allows the compiler to do type checking during compilation, and instructs the compiler not to generate or expect any return value. These prototype statements are declared as returning type void, although in ISO-C a NULL pointer can be passed instead of the register structure. Even though C prototype for assembler programs specify void return, assembler program's R0-R7 are returned in TPF_regs. Because most assembler programs are unaware of the mechanisms of returning values to a C calling function, declaring another return type can cause unpredictable results.

The TPF_regs structure is predefined in tpfregs.h, as shown in Figure 25. TPF_regs can be used in either ISO-C or TARGET(TPF).

Whenever an assembly language program is called, the only argument must be a pointer to type TPF_regs.

Programming Rule

When calling an assembly language program declare prototype statements to take 1, and only 1, argument: a pointer to a structure of type TPF_regs. For ISO-C a null pointer can be coded for TPF_regs.

TARGET(TPF) Restriction

If the N-type linkage function does not take any arguments in registers, allocate the space for a TPF_regs structure and pass a pointer to it anyway. This is necessary because the linkage code uses the second part of the TPF_regs structure to save the calling C program's registers (R0-R5) to protect its environment from all possible calling sequences. Also, before returning control to the calling C program, the contents of registers 0-7 are stored in the same location (the TPF_regs structure) so that the C program has access to any return values from the assembler program.