C/C++

C/C++

C/C++

Your one-stop destination to learn and collaborate about the latest innovations in IBM C/C++ for z/OS compilers to develop high-performing C/C++ applications and system programs on z/OS while maximizing hardware use and improving application performance.

 View Only
  • 1.  Parameter Passing - Non-standard Linkage

    Posted Wed September 25, 2019 05:07 PM

    Hello,

    I am a long time assembler and PL/X 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.

      

    I remember from my PL/X days that you could declare an entry and the parameter could be specified as something like "ptr(31) inreg(1)" and the follow-up call would be "call theroutine(addr(mycontrolblock));".  The compiler would dutifully obtain the address of mycontrolblock, put it in R1 and BASR to the routine.  Is there something like this in Metal C?

     

    Thanks,

    Scott Fagen

    21st Century Software

    Scott Fagen


  • 2.  Re: Parameter Passing - Non-standard Linkage

    Posted Tue October 01, 2019 06:42 PM

    Hi Scott,

    Sorry for the delay. There's no way to do this with the compiler. Instead, you can create a customized prolog (for example #pragma prolog(myfunction, "MYPROLOG")) to set up R1 to point to a parameter list that could contain the address of that control block as it's first (only) parameter.

    Hope that helps!

    Thanks,

    Nicole

    Nicole Trudeau


  • 3.  Re: Parameter Passing - Non-standard Linkage

    Posted Tue October 01, 2019 07:09 PM

    Hmm…I think you get the gist of my question, but are answering the reverse problem…I'm not being called with my parm in R1.  I would like to make a call and have the parameter placed into R1 (rather than a pointer to a standard parameter list).  Is there a way to do that?

     

    I've cobbled together this __asm which probably does the right thing (also gobbles up R15 as the Return Code and R0 as the Reason Code):

     

    #define CallwithR1(ParmPtr,RoutinePtr,RC,Rsn)                                 \

    __asm(                                                                        \

    "         L     R1,%2                     Get ParmPtr into R1 \n"             \

    "         L     R15,%3                    Get RoutinePtr into R15 \n"         \

    "         BASR  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     */ \

     

    Then I could "CallwithR1(&myparm,&myroutine,RetCode,RsnCode)"

     

    I was just hoping that I'd not have to go down this route…

     

    Thanks!
    Scott

    Scott Fagen


  • 4.  Re: Parameter Passing - Non-standard Linkage

    Posted Tue October 01, 2019 07:34 PM

    I know you've been communicating with us over email and got our answer already, but I'll post the latest response for future readers' benefit:

    What you've got is probably the best way to do it right now from a performance perspective, though from a type safety perspective, use a wrapper function to type check the arguments. If you turn on optimization it may come down to the same performance due to inlining while still giving you better type safety.

    Thanks,

    Nicole

    Nicole Trudeau