I am a long time assembler programmer, moving into the world of Metal C. I am very much a C novice, so my terminology may reflect the stuff that I know vs. the stuff that I am learning. It will certainly color how I understand things.
I am trying to insert new Metal C code into some old components that don't necessarily follow standard entry linkage conventions.
For example, a service routine takes, as input in R1, the address of a control block to process. I've looked at the Metal C User's Guide at the discussion about parameter passing and the #pragma linkage discussion in the language reference and there doesn't seem to be a means to cause the compiler to do this.
In essence, I want to declare a routine that is invoked by the following assembler:
L R1,MyParm@ Put pointer to Parm into R1
L R15,Routine@ Get address of service routine
BASR R14,R15 Branch to service routine
I realize that I can take the above, parameterize it and put it into an __asm() block, but I would like to keep the program as "clean" as possible.
Thanks, Scott
Addendum - 26 September 2019
To respond to Mark Hiscock's answer below, such an __asm() block would look like:
#define CallwithR1(ParmPtr,RoutinePtr,RC,Rsn) \
__asm( \
" L R1,%2 Get ParmPtr into R1 \n" \
" L R15,%3 Get RoutinePtr into R15 \n" \
" BALR R14,R15 Call the routine \n" \
" ST R15,%0 Save the return code \n" \
" ST R0,%1 Save the reason code \n" \
/* Output variables */ \
: "=m"(RC) /* %0, output only, in-memory */ \
,"=m"(Rsn) /* %1, output only, in memory */ \
/* Input variables */ \
: "m"(ParmPtr) /* %2, input, in-memory */ \
,"m"(RoutinePtr) /* %3, input, in-memory */ \
/* Register clobber list */ \
: "r0" /* R0 clobbered by reason code */ \
,"r1" /* R1 clobbered by linkage code */ \
,"r14" /* R14 clobbered by return addr */ \
,"r15" /* R15 clobbered by return code */ \
);
and would be far simpler to deal with (fewer instructions, no bind time issues). I'm really looking for something that allows the compiler to "do the right thing."
Scott
You could try something like this in the C program:
And then call the function like this:
Then the assembler would look like this:
This is a 64bit example and MYHLASM would have to be available at the bind time of the C program.
Hope this helps,
Mark