/* 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