gtpa2m2b | Application Programming |
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:
In ISO-C the linkage type is automatically defined by the linkage editor or online service.
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")
|
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)
|
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.
There are no special considerations for parameter passing between C functions or programs in TPF systems, except for the passing of structures.
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.
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).
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)
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. |