/* StartTrapImpl.c */ /* * The following table describes the Mimosa calling convention. * * unitsOut <= 4 & unitsIn <= 64 => The return value is passed back "normally" * (in a register) The arguments are passed "normally" (as C arguments) The * hidden argument (static link) is after the arguments unitsOut > 4 & * unitsIn <= 64 => The pointer to the return record is the first C argument * The "real" arguments are passed as C arguments following the first one The * hidden argument (static link) is after the arguments unitsOut <= 4 & * unitsIn > 64 => The return value is passed back "normally" (in a register) * The first C argument is a pointer to the argument record The hidden * argument (static link) is the second C argument unitsOut > 4 & unitsIn > * 64 => The pointer to the return record is the first C argument The second * C argument is a pointer to the argument record The hidden argument (static * link) is the third C argument * * In addition, the the underlying conventions for argument passing differ on * Sun-3 and Sun-4. When passing a structure (which is what C2C uses for * anything larger than a word), the Sun-3 passes the value on the stack, and * the Sun-4 passes the address of the argument. This is surprising, since * the C language specifies that the value be passed by value (the Sun-4 does * not violate this semantics, but does make copies of structure arguments). * The conditional compilation in the GetStartTrapHandler procedure * compensates for this difference. * * The comment regarding the Sun-4 passing the address of the argument is not * quite correct. The Sun-4 C compiler builds a copy of the structure in the * stack and then passes the address of this structure. It doesn't pass a * pointer to the structure itself as implied by the above comment. * -- mna, July 18, 1991 * */ typedef struct { void* (*code)(); void* descriptor; } MesaProcDesc; typedef struct { /* MACHINE DEPENDENT */ MesaProcDesc shadowed; /* the mesa procedure descriptor whose */ /* call is being trapped */ int exporter; /* the program exporting it */ } TrapItem; typedef struct { void* (*self)(); TrapItem* descriptor; } TrapProcDescriptor; static void* StartTrap00(trapProc) TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(trapProc) ); } static void* StartTrap04(arg0, trapProc) int *arg0; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, trapProc) ); } static void* StartTrap08(arg0, arg1, trapProc) int *arg0, *arg1; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, trapProc) ); } static void* StartTrap12(arg0, arg1, arg2, trapProc) int *arg0, *arg1, *arg2; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, trapProc) ); } static void* StartTrap16(arg0, arg1, arg2, arg3, trapProc) int *arg0, *arg1, *arg2, *arg3; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, arg3, trapProc) ); } static void* StartTrap20(arg0, arg1, arg2, arg3, arg4, trapProc) int *arg0, *arg1, *arg2, *arg3, *arg4; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, arg3, arg4, trapProc) ); } static void* StartTrap24(arg0, arg1, arg2, arg3, arg4, arg5, trapProc) int *arg0, *arg1, *arg2, *arg3, *arg4, *arg5; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, arg3, arg4, arg5, trapProc) ); } static void* StartTrap28(arg0, arg1, arg2, arg3, arg4, arg5, arg6, trapProc) int *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, arg3, arg4, arg5, arg6, trapProc) ); } static void* StartTrap32(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, trapProc) int *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; int *arg7; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, trapProc) ); } static void* StartTrap36(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, trapProc) int *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; int *arg7, *arg8; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, trapProc) ); } static void* StartTrap40(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, trapProc) int *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; int *arg7, *arg8, *arg9; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, trapProc) ); } static void* StartTrap44(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, trapProc) int *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; int *arg7, *arg8, *arg9, *arg10; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, trapProc) ); } static void* StartTrap48(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, trapProc) int *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; int *arg7, *arg8, *arg9, *arg10, *arg11; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, trapProc) ); } static void* StartTrap52(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, trapProc) int *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; int *arg7, *arg8, *arg9, *arg10, *arg11, arg12; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, trapProc) ); } static void* StartTrap56(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, trapProc) int *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; int *arg7, *arg8, *arg9, *arg10, *arg11, *arg12, *arg13; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, trapProc) ); } static void* StartTrap60(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, trapProc) int *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; int *arg7, *arg8, *arg9, *arg10, *arg11, *arg12, *arg13; int *arg14; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, trapProc) ); } static void* StartTrap64(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, trapProc) int *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; int *arg7, *arg8, *arg9, *arg10, *arg11, *arg12, *arg13; int *arg14, *arg15; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, trapProc) ); } static void* StartTrap68(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, trapProc) int *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; int *arg7, *arg8, *arg9, *arg10, *arg11, *arg12, *arg13; int *arg14, *arg15, *arg16; TrapProcDescriptor *trapProc; { XR_StartProgram(trapProc->descriptor->exporter); return( ((MesaProcDesc *) trapProc)->code(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, trapProc) ); } static void* (*(Handlers[])) () = { StartTrap00, StartTrap04, StartTrap08, StartTrap12, StartTrap16, StartTrap20, StartTrap24, StartTrap28, StartTrap32, StartTrap36, StartTrap40, StartTrap44, StartTrap48, StartTrap52, StartTrap56, StartTrap60, StartTrap64, StartTrap68 }; #if defined(mc68020) || defined(_IBMR2) /* * RS6000 C convention for passing structure arguments is * like the 68020 (and not the sparc). A function with * 3 incoming args (of 1 word each) uses the same regs as a * function of a 2-word struct and a 1-word arg. This is in * contrast to the sparc where the 2-word struct is passed in * a register as its address rather than as the words of the * structure themselves. -- mna July 18, 1991 */ void* (*( XR_GetStartTrap(unitsOut, unitsIn, argsIn))) () int unitsOut, unitsIn, argsIn; { int index; if (unitsIn <= 64) { if (unitsOut <= 4) index = unitsIn / 4; else index = unitsIn / 4 + 1; } else { if (unitsOut <= 4) index = 1; else index = 2; }; return (Handlers[index]); } #endif #if defined(sparc) void* (*( XR_GetStartTrap(unitsOut, unitsIn, argsIn))) () int unitsOut, unitsIn, argsIn; { int index; if (unitsIn <= 64) { if (unitsOut <= 4) index = argsIn; else index = argsIn + 1; } else { if (unitsOut <= 4) index = 1; else index = 2; }; return (Handlers[index]); } #endif #if !defined(mc68020) && !defined(sparc) && !defined(_IBMR2) -->fix it < -- #endif