John,
Thanks for asking the question. I used your testcases and added the requirements, according to the z/OS Metal C Programming Guide - Chapter 3, below. This program runs successfully to completion. One needs to initialize the MetalC run-time environment, and assign the address of that block R12. Therefore R12 should not be re-used for the entire life of application. Also, the metal_function should be identified as OS linkage to/in the caller only.
/*metalCallee.c*/
#pragma prolog(metal_function,main)
#pragma epilog(metal_function,main)
#include <stdlib.h>
#include <metal.h>
#include <string.h>
register void * env_tkn __asm("r12");
void metal_function(int* a, int* b, int* c, int* d) {
struct __csysenv_s metal_env;
int* stg31;
memset(&metal_env, 0, sizeof(metal_env));
metal_env.__cseversion = __CSE_VERSION_1;
env_tkn = (void*) __cinit(&metal_env);
/*The 31-bit address allocated on heap is local this function and fred
upon return to the caller*/
stg31 = (int*) __malloc31(4);
c = stg31;
*stg31 = 5;
__asm(" AR %0,%1\n":"+r"(*a):"r"(*c));
__cterm((__csysenv_t) env_tkn);
}
/*xplinkCaller.c*/
#include <stdio.h>
#pragma linkage(metal_function,OS)
void metal_function(int*, int*, int*, int*);
int main() {
int a, b, c, d;
a = b = c = d = 1;
metal_function(&a, &b, &c, &d);
/*Expect to see
Sum = 6 c = 1;
*/
printf("Sum = %d c = %d\n", a, c);
return 0;
}
xlc -qMETAL -S -q64 -qlongname -qnosearch -I/usr/include/metal -o metalCallee.s metalCallee.c //-qnosearch to clear the default include path
xlc -c -q64 -qlongname xplinkCaller.c
as -mgoff -I CBC.SCCNSAM metalCallee.s //Include SCCNSAM if you are using the sample PROLOG/EPILOG macros
xlc -q64 -o a.out xplinkCaller.o metalCallee.o
a.out
Visda