;****************************** ;* * ;* call a PL/I routine from C * ;* * ;****************************** .title callpli .psect .globl plifp ; ; For documentation on how to use it, refer to CPLI.DOC. ; ; Calling sequence is callpli(&routine, n, a1, a2, ...), ; where n is the number of arguments passed to the routine, ; and a1, a2, etc are pointers to the arguments. ; ; Refer to plient source for description of PL/I and C calling sequences. ; ; ; Algorithm: ; ; C compiles code following a call to pop the argument list: ; for no args: nothing (0 words) ; for 1 arg: TST (sp)+ (1 word) ; for 2 args: CMP (sp)+,(sp)+ (1 word) ; for >2 args: ADD ,sp (2 words) ; Since our call always includes the routine address and number of logical ; arguments, our actual number of arguments is 2 more than the number of ; logical arguments going to the PL/I callee, and we only need worry about ; the cases of 2 or >2 args. We check to see which it is, and skip over the ; appropriate number of words of code. ; .iif ndf c$r4 .error CDEFS.MAC must be included in command line callpli:: mov (sp)+,r0 ;return addr tst 2(sp) ;# logical args beq 1$ tst (r0)+ ;skip 2 words if #logical args>0 (actual>2) 1$: tst (r0)+ ;skip 1 word if =0 (2) mov r4,r1 ;save r4 (must preserve all but r0,r1) jsr pc,plifp ;get PL/I frame pointer (from plient) jsr r5,@(sp)+ ;call the routine mov r1,r4 ;restore caller's r4 jmp (r0) ;return, skipping arg list pop code .end