#ifndef AROS_MACHINE_H
#define AROS_MACHINE_H
/*
    (C) 1995-96 AROS - The Amiga Replacement OS
    $Id: machine.h,v 1.4 1997/05/07 15:26:27 aros Exp $

    NOTE: This file must compile *without* any other header !

    Desc: machine.h include file for Linux/m68k (and others?)
    Lang: english
*/

/* We want register args, and LVOs */
#define UseRegisterArgs 1
#define EnableSetFunction 1

/* Linux/m68k gcc has no register args capabilities */
#define AROS_COMPILER_NO_REGARGS

/* Information generated by machine.c */
#define AROS_STACK_GROWS_DOWNWARDS 1 /* Stack direction */
#define AROS_BIG_ENDIAN            1 /* Big or little endian */
#define AROS_SIZEOFULONG           4 /* Size of an ULONG */
#define AROS_WORDALIGN             2 /* Alignment for WORD */
#define AROS_LONGALIGN             2 /* Alignment for LONG */
#define AROS_PTRALIGN              2 /* Alignment for PTR */
#define AROS_IPTRALIGN             2 /* Alignment for IPTR */
#define AROS_DOUBLEALIGN           2 /* Alignment for double */
#define AROS_WORSTALIGN            8 /* Worst case alignment */

/*
    How much do I have to add to sp to get the address of the first
    byte on the stack?
*/
#define SP_OFFSET 0

/*
    Retain binary compatibility with AmigaOS.
    Comment this out if you want APTRs.
*/
#define AROS_BSTR_TYPE	long
#define AROS_BPTR_TYPE	long
#define MKBADDR(a)	(((LONG)(a)) >> 2)
#define BADDR(a)	((APTR)((ULONG)(a) << 2))

/*
    One entry in a libraries' jumptable. For assembler compatibility, the
    field jmp should contain the code for an absolute jmp to a 32bit
    address. There are also a couple of macros which you should use to
    access the vector table from C.
*/
struct JumpVec
{
    unsigned short jmp;
    unsigned char vec[4];
};

/* Internal macros */
#define __AROS_ASMJMP			0x4EF9
#define __AROS_SET_VEC(v,a)             (*(ULONG*)(v)->vec=(ULONG)(a))
#define __AROS_GET_VEC(v)               ((APTR)(*(ULONG*)(v)->vec))

/* Use these to acces a vector table */
#define LIB_VECTSIZE			(sizeof (struct JumpVec))
#define __AROS_GETJUMPVEC(lib,n)        ((struct JumpVec *)(((UBYTE *)lib)-(n*LIB_VECTSIZE)))
#define __AROS_GETVECADDR(lib,n)        (__AROS_GET_VEC(__AROS_GETJUMPVEC(lib,n)))
#define __AROS_SETVECADDR(lib,n,addr)   (__AROS_SET_VEC(__AROS_GETJUMPVEC(lib,n),(APTR)(addr)))
#define __AROS_INITVEC(lib,n)           __AROS_GETJUMPVEC(lib,n)->jmp = __AROS_ASMJMP, \
					__AROS_SETVECADDR(lib,n,_aros_not_implemented)

/*
    Find the next valid alignment for a structure if the next x bytes must
    be skipped.
*/
#define AROS_ALIGN(x)        (((x)+AROS_WORSTALIGN-1)&-AROS_WORSTALIGN)

/* Prototypes */
extern void _aros_not_implemented (void);

/* How much stack do we need ? Lots :-) */
#define AROS_STACKSIZE	100000

/* How to map function arguments to CPU registers */

/* The registers */
#define D0 "%d0"
#define D1 "%d1"
#define D2 "%d2"
#define D3 "%d3"
#define D4 "%d4"
#define D5 "%d5"
#define D6 "%d6"
#define D7 "%d7"
#define A0 "%a0"
#define A1 "%a1"
#define A2 "%a2"
#define A3 "%a3"
#define A4 "%a4"
#define A5 "%a5"
#define A6 "%a6"	/* This will only work with m68k-linux-gcc when
			   compiling with -O0 and -fomit-frame-pointer */

/* RawDoFmt hook */
#if UseRegisterArgs
#define RDFCALL(hook,data,dptr) \
({\
        long __data = (long)(data);\
        long __dptr = (long)(dptr);\
        {\
            register long ___data __asm__(D0) = __data;\
            register long ___dptr __asm__(A3) = __dptr;\
            __asm__ __volatile__("jsr (%0)"\
                : /* no output */\
                :"a"(hook),"r"(___data),"r"(___dptr)\
                :A0,A1,D0,D1,"memory","cc");\
        }\
})
#else
#define RDFCALL(hook,data,dptr) ((void(*)(UBYTE,APTR))(hook))(data,dptr);
#endif

/* What to do with the library base in header, prototype and call */
#define __AROS_LH_BASE(basetype,basename)   basetype basename
#define __AROS_LP_BASE(basetype,basename)   void *
#define __AROS_LC_BASE(basetype,basename)   basename

/* How to transform an argument in header, prototype and call */
#define __AROS_LHA(type,name,reg)     type name
#define __AROS_LPA(type,name,reg)     type
#define __AROS_LCA(type,name,reg)     name
#define __AROS_UFHA(type,name,reg)    type name
#define __AROS_UFPA(type,name,reg)    type
#define __AROS_UFCA(type,name,reg)    name

/* Prefix for library function in header, prototype and call */
#define __AROS_LH_PREFIX    /* eps */
#define __AROS_LP_PREFIX    /* eps */
#define __AROS_LC_PREFIX    /* eps */
#define __AROS_UFH_PREFIX   /* eps */
#define __AROS_UFP_PREFIX   /* eps */
#define __AROS_UFC_PREFIX   /* eps */

/* if this is defined, all AROS_LP*-macros will expand to nothing. */
#define __AROS_USE_MACROS_FOR_LIBCALL

#if UseRegisterArgs
/* We need to redefine all the macros for use with Linux/m68k gcc */

#define AROS_SLIB_ENTRY_S(n,s) #s "_" #n

#define __ASM_PREFIX(name,system) \
    __asm__(".text\n\t.balign 16\n\t"\
	".globl "## AROS_SLIB_ENTRY_S(name,system) ##"\n\t"\
	".type "## AROS_SLIB_ENTRY_S(name,system) ##",@function\n"\
	AROS_SLIB_ENTRY_S(name,system) ##":\n\t"\
	"move.l %a6,-(%sp)\n\t"

#define __ASM_PREFIXI(name,system) \
    __asm__(".text\n\t.balign 16\n\t"\
	".globl "## AROS_SLIB_ENTRY_S(name,system) ##"\n\t"\
	".type "## AROS_SLIB_ENTRY_S(name,system) ##",@function\n"\
	AROS_SLIB_ENTRY_S(name,system) ##":\n\t"

#define __ASM_ARG(type, name, reg) \
	"move.l "## reg ##",-(%sp)\n\t"

#define __ASM_POSTFIX(type,name,system,argc) \
	"jsr _"## AROS_SLIB_ENTRY_S(name,system) ##"\n\t"\
	"add.w #4*" #argc "+4,%sp\n\t"\
	"rts\n\t"\
	".size "## AROS_SLIB_ENTRY_S(name,system) ##",.-"\
	## AROS_SLIB_ENTRY_S(name,system) );\
    __AROS_LH_PREFIX type AROS_SLIB_ENTRY(name,_##system)(

#define __ASM_POSTFIXI(type,name,system,argc) \
	"jsr _"## AROS_SLIB_ENTRY_S(name,system) ##"\n\t"\
	"add.w #4*" #argc ",%sp\n\t"\
	"rts\n\t"\
	".size "## AROS_SLIB_ENTRY_S(name,system) ##",.-"\
	## AROS_SLIB_ENTRY_S(name,system) );\
    __AROS_LH_PREFIX type AROS_SLIB_ENTRY(name,_##system)(

#define AROS_LH0(t,n,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_POSTFIX(t,n,s,0)\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH1(t,n,a1,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,1)\
    __AROS_LHA(a1),\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH2(t,n,a1,a2,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,2)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH3(t,n,a1,a2,a3,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,3)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH4(t,n,a1,a2,a3,a4,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,4)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH5(t,n,a1,a2,a3,a4,a5,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,5)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH6(t,n,a1,a2,a3,a4,a5,a6,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,6)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH7(t,n,a1,a2,a3,a4,a5,a6,a7,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,7)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH8(t,n,a1,a2,a3,a4,a5,a6,a7,a8,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,8)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH9(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a9)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,9)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LHA(a9),\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH10(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a10)\
    __ASM_ARG(a9)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,10)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LHA(a9),\
    __AROS_LHA(a10),\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH11(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a11)\
    __ASM_ARG(a10)\
    __ASM_ARG(a9)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,11)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LHA(a9),\
    __AROS_LHA(a10),\
    __AROS_LHA(a11),\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH12(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a12)\
    __ASM_ARG(a11)\
    __ASM_ARG(a10)\
    __ASM_ARG(a9)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,12)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LHA(a9),\
    __AROS_LHA(a10),\
    __AROS_LHA(a11),\
    __AROS_LHA(a12),\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH13(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a13)\
    __ASM_ARG(a12)\
    __ASM_ARG(a11)\
    __ASM_ARG(a10)\
    __ASM_ARG(a9)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,13)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LHA(a9),\
    __AROS_LHA(a10),\
    __AROS_LHA(a11),\
    __AROS_LHA(a12),\
    __AROS_LHA(a13),\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH14(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a14)\
    __ASM_ARG(a13)\
    __ASM_ARG(a12)\
    __ASM_ARG(a11)\
    __ASM_ARG(a10)\
    __ASM_ARG(a9)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,14)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LHA(a9),\
    __AROS_LHA(a10),\
    __AROS_LHA(a11),\
    __AROS_LHA(a12),\
    __AROS_LHA(a13),\
    __AROS_LHA(a14),\
    __AROS_LH_BASE(bt,bn))

#define AROS_LH15(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,bt,bn,o,s) \
    __ASM_PREFIX(n,s)\
    __ASM_ARG(a15)\
    __ASM_ARG(a14)\
    __ASM_ARG(a13)\
    __ASM_ARG(a12)\
    __ASM_ARG(a11)\
    __ASM_ARG(a10)\
    __ASM_ARG(a9)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX(t,n,s,15)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LHA(a9),\
    __AROS_LHA(a10),\
    __AROS_LHA(a11),\
    __AROS_LHA(a12),\
    __AROS_LHA(a13),\
    __AROS_LHA(a14),\
    __AROS_LHA(a15),\
    __AROS_LH_BASE(bt,bn))

/* Library functions which don't need the libbase */
#define AROS_LH0I(t,n,bt,bn,o,s) \
    __AROS_LH_PREFIX t AROS_SLIB_ENTRY(n,s)(void)

#define AROS_LH1I(t,n,a1,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,1)\
    __AROS_LHA(a1))

#define AROS_LH2I(t,n,a1,a2,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,2)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2))

#define AROS_LH3I(t,n,a1,a2,a3,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,3)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3))

#define AROS_LH4I(t,n,a1,a2,a3,a4,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,4)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4))

#define AROS_LH5I(t,n,a1,a2,a3,a4,a5,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,5)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5))

#define AROS_LH6I(t,n,a1,a2,a3,a4,a5,a6,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,6)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6))

#define AROS_LH7I(t,n,a1,a2,a3,a4,a5,a6,a7,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,7)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7))

#define AROS_LH8I(t,n,a1,a2,a3,a4,a5,a6,a7,a8,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,8)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8))

#define AROS_LH9I(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a9)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,9)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LHA(a9))

#define AROS_LH10I(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a10)\
    __ASM_ARG(a9)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,10)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LHA(a9),\
    __AROS_LHA(a10))

#define AROS_LH11I(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a11)\
    __ASM_ARG(a10)\
    __ASM_ARG(a9)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,11)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LHA(a9),\
    __AROS_LHA(a10),\
    __AROS_LHA(a11))

#define AROS_LH12I(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a12)\
    __ASM_ARG(a11)\
    __ASM_ARG(a10)\
    __ASM_ARG(a9)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,12)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LHA(a9),\
    __AROS_LHA(a10),\
    __AROS_LHA(a11),\
    __AROS_LHA(a12))

#define AROS_LH13I(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a13)\
    __ASM_ARG(a12)\
    __ASM_ARG(a11)\
    __ASM_ARG(a10)\
    __ASM_ARG(a9)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,13)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LHA(a9),\
    __AROS_LHA(a10),\
    __AROS_LHA(a11),\
    __AROS_LHA(a12),\
    __AROS_LHA(a13))

#define AROS_LH14I(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a14)\
    __ASM_ARG(a13)\
    __ASM_ARG(a12)\
    __ASM_ARG(a11)\
    __ASM_ARG(a10)\
    __ASM_ARG(a9)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,14)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LHA(a9),\
    __AROS_LHA(a10),\
    __AROS_LHA(a11),\
    __AROS_LHA(a12),\
    __AROS_LHA(a13),\
    __AROS_LHA(a14))

#define AROS_LH15I(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,bt,bn,o,s) \
    __ASM_PREFIXI(n,s)\
    __ASM_ARG(a15)\
    __ASM_ARG(a14)\
    __ASM_ARG(a13)\
    __ASM_ARG(a12)\
    __ASM_ARG(a11)\
    __ASM_ARG(a10)\
    __ASM_ARG(a9)\
    __ASM_ARG(a8)\
    __ASM_ARG(a7)\
    __ASM_ARG(a6)\
    __ASM_ARG(a5)\
    __ASM_ARG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIXI(t,n,s,15)\
    __AROS_LHA(a1),\
    __AROS_LHA(a2),\
    __AROS_LHA(a3),\
    __AROS_LHA(a4),\
    __AROS_LHA(a5),\
    __AROS_LHA(a6),\
    __AROS_LHA(a7),\
    __AROS_LHA(a8),\
    __AROS_LHA(a9),\
    __AROS_LHA(a10),\
    __AROS_LHA(a11),\
    __AROS_LHA(a12),\
    __AROS_LHA(a13),\
    __AROS_LHA(a14),\
    __AROS_LHA(a15))

/*
    Taken from an old version of AROS:
    This is one way to call a function with registerized parameters and gcc:
    I build a define that defines normal function calls into one of those
    LC0()-Makros for expansion directly into the source code.

    They work as follows:
    First I copy the arguments of the function into normal variables.
    Second I copy those variables into the appropriate registers.
    (I cannot write them directly into those registers because this locks
     the register and one of the arguments may be a function call that needs it.)
    Third I call the assembler function with registers as arguments.
    Fourth I return the result. (The casting of the long is necessary to make
    void work).

    Prototype stylish Macros are also possible (using __inline functions instead
    of defines) but they need more system ressources to compile, more complicated
    Makefiles (gcc cannot inline without optimization) and cannot use local
    library bases.
*/
#define __LC0(type,name,basetype,basename,offset,system)  \
({                                                  \
   {						    \
	register long __d0 __asm(D0);               \
	__asm __volatile("move.l %%a6,-(%%sp)\n\t"  \
	    "move.l %1,%%a6\n\t"		    \
	    "jsr %%a6@(-6*"#offset":W)\n\t"	    \
	    "move.l (%%sp)+,%%a6"		    \
	    :"=r"(__d0)                             \
	    :"r"(basename)			    \
	    :D0,D1,A0,A1,"memory","cc");            \
	(type)__d0;				    \
    }						    \
})

#define __LC1(t,n,t1,n1,r1,bt,bn,o,s)                 \
({                                                  \
    t1 __n1 = (n1);                                 \
    {						    \
	register long __d0 __asm(D0);               \
	register long ___n1 __asm(r1) = (long)__n1; \
	__asm __volatile("move.l %%a6,-(%%sp)\n\t"  \
	    "move.l %2,%%a6\n\t"		    \
	    "jsr %%a6@(-6*"#o":W)\n\t"		    \
	    "move.l (%%sp)+,%%a6"		    \
	    :"=r"(__d0)                             \
	    :"r"(___n1),"r"(bn)			    \
	    :A0,A1,D0,D1,"memory","cc");            \
	(t)__d0;				    \
    }						    \
})

#define __LC2(t,n,t1,n1,r1,t2,n2,r2,bt,bn,o,s)      \
({                                                  \
    t1 __n1 = (n1);                                 \
    t2 __n2 = (n2);                                 \
    {						    \
	register long __d0 __asm(D0);               \
	register long ___n1 __asm(r1) = (long)__n1; \
	register long ___n2 __asm(r2) = (long)__n2; \
	__asm __volatile("move.l %%a6,-(%%sp)\n\t"  \
	    "move.l %1,%%a6\n\t"		    \
	    "jsr %%a6@(-6*"#o":W)\n\t"		    \
	    "move.l (%%sp)+,%%a6"		    \
	    :"=r"(__d0)                             \
	    :"r"(bn),"r"(___n1),"r"(___n2)	    \
	    :D0,D1,A0,A1,"memory","cc");            \
        (t)__d0;                                    \
    }						    \
})

#define __LC3(t,n,t1,n1,r1,t2,n2,r2,t3,n3,r3,bt,bn,o,s) \
({                                                  \
    t1 __n1 = (n1);                                 \
    t2 __n2 = (n2);                                 \
    t3 __n3 = (n3);                                 \
    {						    \
	register long __d0 __asm(D0);               \
	register long ___n1 __asm(r1) = (long)__n1; \
	register long ___n2 __asm(r2) = (long)__n2; \
	register long ___n3 __asm(r3) = (long)__n3; \
	__asm __volatile("move.l %%a6,-(%%sp)\n\t"  \
	    "move.l %4,%%a6\n\t"		    \
	    "jsr %%a6@(-6*"#o":W)\n\t"		    \
	    "move.l (%%sp)+,%%a6"		    \
	    :"=r"(__d0)                             \
	    :"r"(___n1),"r"(___n2),"r"(___n3),      \
	     "r"(bn)				    \
	    :A0,A1,D0,D1,"memory","cc");            \
	(t)__d0;				    \
    }						    \
})

#define __LC4(t,n,t1,n1,r1,t2,n2,r2,t3,n3,r3,t4,n4,r4,bt,bn,o,s) \
({                                                  \
    t1 __n1 = (n1);                                 \
    t2 __n2 = (n2);                                 \
    t3 __n3 = (n3);                                 \
    t4 __n4 = (n4);                                 \
    {						    \
	register long __d0 __asm(D0);		    \
	register long ___n1 __asm(r1) = (long)__n1; \
	register long ___n2 __asm(r2) = (long)__n2; \
	register long ___n3 __asm(r3) = (long)__n3; \
	register long ___n4 __asm(r4) = (long)__n4; \
	__asm __volatile("move.l %%a6,-(%%sp)\n\t"  \
	    "move.l %5,%%a6\n\t"		    \
	    "jsr %%a6@(-6*"#o":W)\n\t"		    \
	    "move.l (%%sp)+,%%a6"		    \
	    :"=r"(__d0)                             \
	    :"r"(___n1),"r"(___n2),"r"(___n3),      \
	     "r"(___n4),"r"(bn)			    \
	    :A0,A1,D0,D1,"memory","cc");            \
	(t)__d0;				    \
    }						    \
})

#define __LC5(t,n,t1,n1,r1,t2,n2,r2,t3,n3,r3,t4,n4,r4,t5,n5,r5,bt,bn,o,s) \
({                                                  \
    t1 __n1 = (n1);                                 \
    t2 __n2 = (n2);                                 \
    t3 __n3 = (n3);                                 \
    t4 __n4 = (n4);                                 \
    t5 __n5 = (n5);                                 \
    {						    \
	register long __d0 __asm(D0);               \
	register long ___n1 __asm(r1) = (long)__n1; \
	register long ___n2 __asm(r2) = (long)__n2; \
	register long ___n3 __asm(r3) = (long)__n3; \
	register long ___n4 __asm(r4) = (long)__n4; \
	register long ___n5 __asm(r5) = (long)__n5; \
	__asm __volatile("move.l %%a6,-(%%sp)\n\t"  \
	    "move.l %6,%%a6\n\t"		    \
	    "jsr %%a6@(-6*"#o":W)\n\t"		    \
	    "move.l (%%sp)+,%%a6"		    \
	    :"=r"(__d0)                             \
	    :"r"(___n1),"r"(___n2),"r"(___n3),      \
	     "r"(___n4),"r"(___n5),"r"(bn)	    \
	    :A0,A1,D0,D1,"memory","cc");            \
	(t)__d0;				    \
    }						    \
})

#define __LC6(t,n,t1,n1,r1,t2,n2,r2,t3,n3,r3,t4,n4,r4,t5,n5,r5,t6,n6,r6,bt,bn,o,s) \
({                                                  \
    t1 __n1 = (n1);                                 \
    t2 __n2 = (n2);                                 \
    t3 __n3 = (n3);                                 \
    t4 __n4 = (n4);                                 \
    t5 __n5 = (n5);                                 \
    t6 __n6 = (n6);				    \
    {                                               \
        register long __d0 __asm(D0);               \
        register long ___n1 __asm(r1) = (long)__n1; \
        register long ___n2 __asm(r2) = (long)__n2; \
        register long ___n3 __asm(r3) = (long)__n3; \
        register long ___n4 __asm(r4) = (long)__n4; \
        register long ___n5 __asm(r5) = (long)__n5; \
        register long ___n6 __asm(r6) = (long)__n6; \
        __asm __volatile("move.l %%a6,-(%%sp)\n\t"  \
	    "move.l %7,%%a6\n\t"		    \
	    "jsr %%a6@(-6*"#o":W)\n\t"		    \
	    "move.l (%%sp)+,%%a6"		    \
            :"=r"(__d0)                             \
            :"r"(___n1),"r"(___n2),"r"(___n3),      \
             "r"(___n4),"r"(___n5),"r"(___n6),      \
             "r"(bn)				    \
            :A0,A1,D0,D1,"memory","cc");            \
        (t)__d0;                                    \
    }                                               \
})

#define __LC9(t,n,t1,n1,r1,t2,n2,r2,t3,n3,r3,t4,n4,r4,t5,n5,r5,t6,n6,r6,t7,n7,r7,t8,n8,r8,t9,n9,r9,bt,bn,o,s) \
({                                                  \
    t1 __n1 = (n1);                                 \
    t2 __n2 = (n2);                                 \
    t3 __n3 = (n3);                                 \
    t4 __n4 = (n4);                                 \
    t5 __n5 = (n5);                                 \
    t6 __n6 = (n6);                                 \
    t7 __n7 = (n7);                                 \
    t8 __n8 = (n8);                                 \
    t9 __n9 = (n9);                                 \
    {                                               \
	register long __d0 __asm(D0);               \
        register long ___n1 __asm(r1) = (long)__n1; \
        register long ___n2 __asm(r2) = (long)__n2; \
        register long ___n3 __asm(r3) = (long)__n3; \
        register long ___n4 __asm(r4) = (long)__n4; \
        register long ___n5 __asm(r5) = (long)__n5; \
        register long ___n6 __asm(r6) = (long)__n6; \
        register long ___n7 __asm(r7) = (long)__n7; \
        register long ___n8 __asm(r8) = (long)__n8; \
        register long ___n9 __asm(r9) = (long)__n9; \
        __asm __volatile("move.l %%a6,-(%%sp)\n\t"  \
	    "move.l %9,%%a6\n\t"		    \
	    "jsr %%a6@(-6*"#o":W)\n\t"		    \
	    "move.l (%%sp)+,%%a6"		    \
            : /* no output */                       \
            :"r"(___n1),"r"(___n2),"r"(___n3),      \
             "r"(___n4),"r"(___n5),"r"(___n6),      \
             "r"(___n7),"r"(___n8),"r"(___n9),      \
             "r"(bn)				    \
            :A0,A1,D0,D1,"memory","cc");            \
	(t)__d0;				    \
    }                                               \
})

#define AROS_LC0(t,n,bt,bn,o,s)                 __LC0(t,n,bt,bn,o,s)
#define AROS_LC0I(t,n,bt,bn,o,s)                __LC0(t,n,bt,bn,o,s)
#define AROS_LC1(t,n,a1,bt,bn,o,s)              __LC1(t,n,a1,bt,bn,o,s)
#define AROS_LC1I(t,n,a1,bt,bn,o,s)             __LC1(t,n,a1,bt,bn,o,s)
#define AROS_LC2(t,n,a1,a2,bt,bn,o,s)           __LC2(t,n,a1,a2,bt,bn,o,s)
#define AROS_LC2I(t,n,a1,a2,bt,bn,o,s)          __LC2(t,n,a1,a2,bt,bn,o,s)
#define AROS_LC3(t,n,a1,a2,a3,bt,bn,o,s)        __LC3(t,n,a1,a2,a3,bt,bn,o,s)
#define AROS_LC3I(t,n,a1,a2,a3,bt,bn,o,s)       __LC3(t,n,a1,a2,a3,bt,bn,o,s)
#define AROS_LC4(t,n,a1,a2,a3,a4,bt,bn,o,s)     __LC4(t,n,a1,a2,a3,a4,bt,bn,o,s)
#define AROS_LC4I(t,n,a1,a2,a3,a4,bt,bn,o,s)    __LC4(t,n,a1,a2,a3,a4,bt,bn,o,s)
#define AROS_LC5(t,n,a1,a2,a3,a4,a5,bt,bn,o,s)  __LC5(t,n,a1,a2,a3,a4,a5,bt,bn,o,s)
#define AROS_LC5I(t,n,a1,a2,a3,a4,a5,bt,bn,o,s) __LC5(t,n,a1,a2,a3,a4,a5,bt,bn,o,s)
#define AROS_LC6(t,n,a1,a2,a3,a4,a5,a6,bt,bn,o,s) \
	__LC6(t,n,a1,a2,a3,a4,a5,a6,bt,bn,o,s)
#define AROS_LC6I(t,n,a1,a2,a3,a4,a5,a6,bt,bn,o,s) \
	__LC6(t,n,a1,a2,a3,a4,a5,a6,bt,bn,o,s)
#define AROS_LC8(t,n,a1,a2,a3,a4,a5,a6,a7,a8,bt,bn,o,s) \
	__LC8(t,n,a1,a2,a3,a4,a5,a6,a7,a8,bt,bn,o,s)
#define AROS_LC8I(t,n,a1,a2,a3,a4,a5,a6,a7,a8,bt,bn,o,s) \
	__LC8(t,n,a1,a2,a3,a4,a5,a6,a7,a8,bt,bn,o,s)
#define AROS_LC9(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,bt,bn,o,s) \
	__LC9(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,bt,bn,o,s)
#define AROS_LC9I(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,bt,bn,o,s) \
	__LC9(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,bt,bn,o,s)

#define AROS_LVO_CALL0(returntype,basetype,basename,offset,system) \
__LC0(returntype,,basetype,basename,offset,system)

#define AROS_LVO_CALL1(t,a1,bt,bn,o,s) \
__LC1(t,,a1,bt,bn,o,s)

#define AROS_LVO_CALL1NR(a1,bt,bn,o,s) \
__LC1(void,,a1,bt,bn,o,s)

#define AROS_LVO_CALL2(t,a1,a2,bt,bn,o,s) \
__LC2(t,,a1,a2,bt,bn,o,s)

#define AROS_LVO_CALL3(t,a1,a2,a3,bt,bn,o,s) \
__LC3(t,,a1,a2,a3,bt,bn,o,s)

#define AROS_LVO_CALL3NR(a1,a2,a3,bt,bn,o,s) \
__LC3(void,,a1,a2,a3,bt,bn,o,s)

#define AROS_LVO_CALL4(t,a1,a2,a3,a4,bt,bn,o,s) \
__LC4(t,,a1,a2,a3,a4,bt,bn,o,s)

/* Macros for user functions */

#define __ASM_PREFIX_U(name) \
    __asm__(".text\n\t.balign 16\n"\
	".globl " #name "\n\t"\
	".type " #name ",@function\n"\
	#name ":\n\t"\

#define __ASM_POSTFIX_U(type,name,argc) \
	"jsr _" #name "\n\t"\
	"add.w #4*" #argc ",%sp\n\t"\
	"rts\n\t"\
	".size " #name ",.-" #name);\
    __AROS_UFH_PREFIX type _##name (

/* Function headers for user functions */
#define AROS_UFH0(t,n) \
    t n (void)

#define AROS_UFH1(t,n,a1) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,1)\
    __AROS_UFHA(a1))

#define AROS_UFH2(t,n,a1,a2) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,2)\
    __AROS_UFHA(a1),\
    __AROS_UFHA(a2))

#define AROS_UFH3(t,n,a1,a2,a3) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,3)\
    __AROS_UFHA(a1),\
    __AROS_UFHA(a2),\
    __AROS_UFHA(a3))

#define AROS_UFH4(t,n,a1,a2,a3,a4) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_REG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,4)\
    __AROS_UFHA(a1),\
    __AROS_UFHA(a2),\
    __AROS_UFHA(a3),\
    __AROS_UFHA(a4))

#define AROS_UFH5(t,n,a1,a2,a3,a4,a5) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_REG(a5)\
    __ASM_REG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,5)\
    __AROS_UFHA(a1),\
    __AROS_UFHA(a2),\
    __AROS_UFHA(a3),\
    __AROS_UFHA(a4),\
    __AROS_UFHA(a5))

#define AROS_UFH6(t,n,a1,a2,a3,a4,a5,a6) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_REG(a6)\
    __ASM_REG(a5)\
    __ASM_REG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,6)\
    __AROS_UFHA(a1),\
    __AROS_UFHA(a2),\
    __AROS_UFHA(a3),\
    __AROS_UFHA(a4),\
    __AROS_UFHA(a5),\
    __AROS_UFHA(a6))

#define AROS_UFH7(t,n,a1,a2,a3,a4,a5,a6,a7) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_REG(a7)\
    __ASM_REG(a6)\
    __ASM_REG(a5)\
    __ASM_REG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,7)\
    __AROS_UFHA(a1),\
    __AROS_UFHA(a2),\
    __AROS_UFHA(a3),\
    __AROS_UFHA(a4),\
    __AROS_UFHA(a5),\
    __AROS_UFHA(a6),\
    __AROS_UFHA(a7))

#define AROS_UFH8(t,n,a1,a2,a3,a4,a5,a6,a7,a8) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_REG(a8)\
    __ASM_REG(a7)\
    __ASM_REG(a6)\
    __ASM_REG(a5)\
    __ASM_REG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,8)\
    __AROS_UFHA(a1),\
    __AROS_UFHA(a2),\
    __AROS_UFHA(a3),\
    __AROS_UFHA(a4),\
    __AROS_UFHA(a5),\
    __AROS_UFHA(a6),\
    __AROS_UFHA(a7),\
    __AROS_UFHA(a8))

#define AROS_UFH9(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_REG(a9)\
    __ASM_REG(a8)\
    __ASM_REG(a7)\
    __ASM_REG(a6)\
    __ASM_REG(a5)\
    __ASM_REG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,9)\
    __AROS_UFHA(a1),\
    __AROS_UFHA(a2),\
    __AROS_UFHA(a3),\
    __AROS_UFHA(a4),\
    __AROS_UFHA(a5),\
    __AROS_UFHA(a6),\
    __AROS_UFHA(a7),\
    __AROS_UFHA(a8),\
    __AROS_UFHA(a9))

#define AROS_UFH10(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_REG(a10)\
    __ASM_REG(a9)\
    __ASM_REG(a8)\
    __ASM_REG(a7)\
    __ASM_REG(a6)\
    __ASM_REG(a5)\
    __ASM_REG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,10)\
    __AROS_UFHA(a1),\
    __AROS_UFHA(a2),\
    __AROS_UFHA(a3),\
    __AROS_UFHA(a4),\
    __AROS_UFHA(a5),\
    __AROS_UFHA(a6),\
    __AROS_UFHA(a7),\
    __AROS_UFHA(a8),\
    __AROS_UFHA(a9),\
    __AROS_UFHA(a10))

#define AROS_UFH11(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_REG(a11)\
    __ASM_REG(a10)\
    __ASM_REG(a9)\
    __ASM_REG(a8)\
    __ASM_REG(a7)\
    __ASM_REG(a6)\
    __ASM_REG(a5)\
    __ASM_REG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,11)\
    __AROS_UFHA(a1),\
    __AROS_UFHA(a2),\
    __AROS_UFHA(a3),\
    __AROS_UFHA(a4),\
    __AROS_UFHA(a5),\
    __AROS_UFHA(a6),\
    __AROS_UFHA(a7),\
    __AROS_UFHA(a8),\
    __AROS_UFHA(a9),\
    __AROS_UFHA(a10),\
    __AROS_UFHA(a11))

#define AROS_UFH12(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_REG(a12)\
    __ASM_REG(a11)\
    __ASM_REG(a10)\
    __ASM_REG(a9)\
    __ASM_REG(a8)\
    __ASM_REG(a7)\
    __ASM_REG(a6)\
    __ASM_REG(a5)\
    __ASM_REG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,12)\
    __AROS_UFHA(a1),\
    __AROS_UFHA(a2),\
    __AROS_UFHA(a3),\
    __AROS_UFHA(a4),\
    __AROS_UFHA(a5),\
    __AROS_UFHA(a6),\
    __AROS_UFHA(a7),\
    __AROS_UFHA(a8),\
    __AROS_UFHA(a9),\
    __AROS_UFHA(a10),\
    __AROS_UFHA(a11),\
    __AROS_UFHA(a12))

#define AROS_UFH13(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_REG(a13)\
    __ASM_REG(a12)\
    __ASM_REG(a11)\
    __ASM_REG(a10)\
    __ASM_REG(a9)\
    __ASM_REG(a8)\
    __ASM_REG(a7)\
    __ASM_REG(a6)\
    __ASM_REG(a5)\
    __ASM_REG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,13)\
    __AROS_UFHA(a1),\
    __AROS_UFHA(a2),\
    __AROS_UFHA(a3),\
    __AROS_UFHA(a4),\
    __AROS_UFHA(a5),\
    __AROS_UFHA(a6),\
    __AROS_UFHA(a7),\
    __AROS_UFHA(a8),\
    __AROS_UFHA(a9),\
    __AROS_UFHA(a10),\
    __AROS_UFHA(a11),\
    __AROS_UFHA(a12),\
    __AROS_UFHA(a13))

#define AROS_UFH14(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_REG(a14)\
    __ASM_REG(a13)\
    __ASM_REG(a12)\
    __ASM_REG(a11)\
    __ASM_REG(a10)\
    __ASM_REG(a9)\
    __ASM_REG(a8)\
    __ASM_REG(a7)\
    __ASM_REG(a6)\
    __ASM_REG(a5)\
    __ASM_REG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,14)\
    __AROS_UFHA(a1),\
    __AROS_UFHA(a2),\
    __AROS_UFHA(a3),\
    __AROS_UFHA(a4),\
    __AROS_UFHA(a5),\
    __AROS_UFHA(a6),\
    __AROS_UFHA(a7),\
    __AROS_UFHA(a8),\
    __AROS_UFHA(a9),\
    __AROS_UFHA(a10),\
    __AROS_UFHA(a11),\
    __AROS_UFHA(a12),\
    __AROS_UFHA(a13),\
    __AROS_UFHA(a14))

#define AROS_UFH15(t,n,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) \
    t n ();\
    __ASM_PREFIX_U(n)\
    __ASM_REG(a15)\
    __ASM_REG(a14)\
    __ASM_REG(a13)\
    __ASM_REG(a12)\
    __ASM_REG(a11)\
    __ASM_REG(a10)\
    __ASM_REG(a9)\
    __ASM_REG(a8)\
    __ASM_REG(a7)\
    __ASM_REG(a6)\
    __ASM_REG(a5)\
    __ASM_REG(a4)\
    __ASM_ARG(a3)\
    __ASM_ARG(a2)\
    __ASM_ARG(a1)\
    __ASM_POSTFIX_U(t,n,15)\
    __AROS_UFHA(a1),\
    __AROS_UFHA(a2),\
    __AROS_UFHA(a3),\
    __AROS_UFHA(a4),\
    __AROS_UFHA(a5),\
    __AROS_UFHA(a6),\
    __AROS_UFHA(a7),\
    __AROS_UFHA(a8),\
    __AROS_UFHA(a9),\
    __AROS_UFHA(a10),\
    __AROS_UFHA(a11),\
    __AROS_UFHA(a12),\
    __AROS_UFHA(a13),\
    __AROS_UFHA(a14),\
    __AROS_UFHA(a15))

/* Call a user function */
#define AROS_UFC0(t,n) \
    (((__AROS_UFC_PREFIX t(*)(void))n)())
#define __UFC1(t,n,t1,n1,r1) \
({\
    t1 __n1 = (n1);\
    {\
        register long __d0 __asm__(D0);\
	register t1 ___n1 __asm__(r1) = __n1;\
        __asm__ __volatile__("jsr (%1)"\
            :"=r"(__d0)\
            :"a"(n),"r"(___n1)\
            :A0,A1,D0,D1,"cc","memory");\
        (t)__d0;\
    }\
})
#define AROS_UFC1(t,n,a1)       __UFC1(t,n,a1)
#define __UFC2(t,n,t1,n1,r1,t2,n2,r2) \
({\
    t1 __n1 = (n1);\
    t2 __n2 = (n2);\
    {\
        register long __d0 __asm__(D0);\
	register t1 ___n1 __asm__(r1) = __n1;\
	register t2 ___n2 __asm__(r2) = __n2;\
        __asm__ __volatile__("jsr (%1)"\
            :"=r"(__d0)\
            :"a"(n),"r"(___n1),"r"(___n2)\
            :A0,A1,D0,D1,"cc","memory");\
        (t)__d0;\
    }\
})
#define AROS_UFC2(t,n,a1,a2)    __UFC2(t,n,a1,a2)
#define __UFC3(t,n,t1,n1,r1,t2,n2,r2,t3,n3,r3) \
({\
    t1 __n1 = (n1);\
    t2 __n2 = (n2);\
    t3 __n3 = (n3);\
    {\
        register long __d0 __asm__(D0);\
	register t1 ___n1 __asm__(r1) = __n1;\
	register t2 ___n2 __asm__(r2) = __n2;\
	register t3 ___n3 __asm__(r3) = __n3;\
        __asm__ __volatile__("jsr (%1)"\
            :"=r"(__d0)\
            :"a"(n),"r"(___n1),"r"(___n2),"r"(___n3)\
            :A0,A1,D0,D1,"cc","memory");\
        (t)__d0;\
    }\
})
#define AROS_UFC3(t,n,a1,a2,a3) __UFC3(t,n,a1,a2,a3)

/* Special versions which use %a6, so it needs to be saved on the stack
   first. */
#define __UFC1S(t,n,t1,n1,r1) \
({\
    {\
	register long __d0 __asm__(D0);\
	__asm__ __volatile("move.l %%a6,-(%%sp)\n\t"\
	    "move.l %2,%%a6\n\t"\
	    "jsr (%1)\n\t"\
	    "move.l (%%sp)+,%%a6"\
	    :"=r"(__d0)\
	    :"a"(n),"r"(n1)\
	    :A0,A1,D0,D1,"cc","memory");\
	(t)__d0;\
    }\
})
#define AROS_UFC1S(t,n,a1) __UFC1S(t,n,a1)
#define __UFC2S(t,n,t1,n1,r1,t2,n2,r2) \
({\
    t1 __n1 = (n1);\
    {\
	register long __d0 __asm__(D0);\
	register t1 ___n1 __asm__(r1) = __n1;\
	__asm__ __volatile__("move.l %%a6,-(%%sp)\n\t"\
	    "move.l %3,%%a6\n\t"\
	    "jsr (%1)\n\t"\
	    "move.l (%%sp)+,%%a6"\
	    :"=r"(__d0)\
	    :"a"(n),"r"(___n1),"r"(n2)\
	    :A0,A1,D0,D1,"cc","memory");\
	(t)__d0;\
    }\
})
#define AROS_UFC2S(t,n,a1,a2) __UFC2S(t,n,a1,a2)
#define __UFC3S(t,n,t1,n1,r1,t2,n2,r2,t3,n3,r3) \
({\
    t1 __n1 = (n1);\
    t2 __n2 = (n2);\
    {\
	register long __d0 __asm__(D0);\
	register t1 ___n1 __asm__(r1) = __n1;\
	register t2 ___n2 __asm__(r2) = __n2;\
	__asm__ __volatile__("move.l %%a6,-(%%sp)\n\t"\
	    "move.l %4,%%a6\n\t"\
	    "jsr (%1)\n\t"\
	    "move.l (%%sp)+,%%a6"\
	    :"=r"(__d0)\
	    :"a"(n),"r"(___n1),"r"(___n2),"r"(n3)\
	    :A0,A1,D0,D1,"cc","memory");\
	(t)__d0;\
    }\
})
#define AROS_UFC3S(t,n,a1,a2,a3) __UFC3S(t,n,a1,a2,a3)

#endif /* UseRegisterArgs */

#endif /* AROS_MACHINE_H */
