AR-mode programming support
With the METAL option, an AR-mode function can access data stored in data spaces by using the hardware access registers. For more information about AR-mode, see z/OS MVS Programming: Assembler Services Guide. A non-AR-mode function is said to be in primary mode.
The following sections describe the compiler options, language constructs, and built-in functions that support AR-mode programming.
AR-mode function declaration
armode attribute. The
syntax is: void armode_func() __attribute__((armode)); You
can also use the ARMODE compiler option to declare that all functions
in the source program to be AR-mode functions. If you use the ARMODE
compiler option and you want to single out the functions in the source
program to be primary mode functions you can declare the function
with the noarmode attribute. The syntax is: void nonarmode_func() __attribute__((noarmode)); Far pointer declaration, reference, and dereference
__far qualifier.
The syntax is int * __far my_far_pointer;- It can be passed as a parameter.
- It can be received as a function return value.
- It can be compared with another pointer.
- It can be cast as another pointer type.
- It can be used in pointer arithmetic expressions.
- Under AMODE 31, a far pointer occupies eight bytes.
- The ALET occupies the first four bytes.
- The offset occupies the last four bytes.
- Under AMODE 64, a far pointer occupies 16 bytes.
- The first four bytes are unused.
- The ALET occupies the second four bytes.
- The offset occupies the last eight bytes.

C language constructs and far pointers
| Language Construct | Effect |
|---|---|
| Implicit or explicit cast from normal to far pointer | Because the normal pointer is assumed to point to primary address space, the ALET of the far pointer is set to 0. |
| Explicit cast from far pointer to normal pointer | The offset of the far pointer is extracted and used to form the normal pointer. Unless the ALET of the far pointer was 0, the normal pointer is likely to be invalid. |
| Operators !=, == | If either operand is a far pointer, the other operand is implicitly cast to a far pointer before the operands are compared. The comparison is performed on both the ALET and offset components of a far pointer. |
| Operators <, <=, >, >= | Only the offset of the far pointer is used in the comparison. Unless the ALETs of the far pointers were the same, the result might be meaningless. |
| Compare to NULL | Because of the implicit cast of NULL to a far pointer, the != and == operators compare both the ALET and the offset to zero. A test of !(p>NULL) is not sufficient to ensure that the ALET is also 0. |
| Pointer arithmetic | The effects of pointer arithmetic are applied to the offset component of a far pointer only. The ALET component remains unchanged. |
| Address of Operator, operand of & | The result is a normal pointer, except in the
following cases:
|
Implicit ALET association
In addition to explicitly specifying ALETs that use far pointers to access data in data spaces, the compiler must associate those ALETs with all the memory references contained in the AR-mode function.
| Variable type | Implied ALET |
|---|---|
| File-scope variable | ALET 0 (primary data space) |
| Stack variables (function local variable) | The ALET that is in AR 13 at the time of function entry. This points to the stack frame. |
| Parameters (function formal parameters) | The ALET that is in AR 1 at the time of function entry. This points to the parameter list. |
| Data pointed to by regular pointers | ALET 0 (primary data space). |
| Data pointed by far pointer | ALET contained in far pointer. |
Far pointer construction
The Metal C Runtime Library does not provide functions for allocating or deallocating alternative data spaces. You can use the DSPSERV and ALESERV HLASM macros to allocate space and obtain a valid ALET and offset. For an example, see Figure 5. For more information, see z/OS MVS Programming: Assembler Services Guide.
Built-in functions that manage far-pointer components
- Define the macro _MI.BUILTN to "1".
- Include the header file builtins.h.
void * __far __set_far_ALET_offset(unsigned int alet, void * offset);
void * __far __set_far_ALET(unsigned int alet, void * __far offset); 1
void * __far __set_far_offset(void * __far alet, void * offset); 2
- The
__set_far_ALETfunction does not modify the far-pointer parameter offset. It simply uses it to provide the offset component of the far pointer being constructed. Its return value is the constructed far pointer. - Similarly, the
__set_far_offsetfunction that uses the far-pointer parameter ALET is not modified; it simply provides the ALET for the far pointer being constructed.
unsigned int __get_far_ALET(void * __far p);
void * __get_far_offset(void * __far p);
For information about ARMODE built-in functions, see Using hardware built-in functions in z/OS XL C/C++ Programming Guide.
Library functions that manipulate data stored in data spaces
The XL C compiler provides far versions of some of the standard C string and memory library functions. The far versions can be called by either AR-mode or primary-mode functions. If these functions are called by an AR mode function, the compiler will generate inline code for them.
- Define the macro _MI.BUILTN to "1".
- Include the header file
builtins.h.
The semantics of these functions, listed in Figure 4, are identical to the standard version.
void * __far __far_memcpy(void * __far s1, const void * __far s2, size_t n);
int __far_memcmp(const void * __far s1, const void * __far s2, size_t n);
void * __far __far_memset(void * __far s, int c, size_t n);
void * __far __far_memchr(const void * __far s, int c, size_t n);
char * __far __far_strcpy(char * __far s1, const char * __far s2); See Note
char * __far __far_strncpy(char * __far s1, const char * __far s2, size_t n);
int __far_strcmp(const char * __far s1, const char * __far s2);
int __far_strncmp(const char *__far s1, const char * __far s2, size_t n);
char * __far __far_strcat(char * __far s1, const char * __far s2);
char * __far __far_strncat(char * __far s1, const char * __far s2, size_t n);
char * __far __far_strchr(const char * __far s, int c);
char * __far __far_strrchr(const char * __far s, int c);
size_t __far_strlen(const char * __far s);
AR-mode function linkage conventions
- Any function that calls an AR-mode function must supply the 54-word F7SA save area for saving the access registers.
- The AR-mode function must preserve the calling function’s access registers.
- The AR-mode function is responsible for switching into AR mode
on entry and switching back to calling function’s ASC mode on
exit. Note: A primary-mode function does not switch the ASC mode when calling an AR-mode function.
- An AR-mode function must switch to primary mode before calling a primary mode function.
- A far pointer is passed and returned as a
structthat is based on the layout for the calling function’s AMODE.
Default prolog and epilog code for AR-mode functions
If the calling function is in non-AR mode, the DSA and parameter areas are assumed to be located in the primary address space.
- Save the calling function’s access registers in the F7SA save area.
- Save the ASC mode of the calling function in the F7SA save area.
- Switch to AR mode.
- Prime AR 1 and AR 13 with LAE instructions.
- Restore the calling function’s access registers.
- Restore the ASC mode of the calling function.
Data space allocation and deallocation
Figure 5 provides examples of routines for allocating and deallocating data space.
|
|
|
Copying a string pointer to a far pointer
Figure 6 provides an example of using a built-in function to copy a C string pointer to a far pointer.
/*****************************************************/
/* __far_strcpy example */
/*****************************************************/
char *__far far_strcpy_example() __attribute__((armode));
char *__far far_strcpy_example()
{
char *__far far_string;
char * near_string;
near_string = "Hello World!\n";
far_string = allocate_far(1024);
__far_strcpy(far_string,near_string);
return far_string; /* Assume caller will free allocated data space */
}
Far pointer dereference
The Metal C Runtime Library does not provide functions for allocating or deallocating alternative data spaces. Figure 7 provides an example of code that dereferences a far pointer.
/*****************************************************/
/* Simple dereference example */
/*****************************************************/
char get_ith_character(char *__far s, int i) __attribute__((armode));
char get_ith_character(char *__far s, int i)
{
return s[i];
}
int main()
{
char c;
char *__far far_string;
far_string = far_strcpy_example();
c = get_ith_character(far_string,1);
free_far(far_string);
return c;
}