/****************************************************************************** * * l i b s t a c k . h * * Copyright © 1997 Erick Gallesio - I3S-CNRS/ESSI * * * Permission to use, copy, and/or distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that both the above copyright notice and this permission notice appear in * all copies and derived works. Fees for distribution or use of this * software or derived works may only be charged with express written * permission of the copyright holder. * This software is provided ``as is'' without express or implied warranty. * * This software is a derivative work of other copyrighted softwares; the * copyright notices of these softwares are placed in the file COPYRIGHTS * * * Author: Erick Gallesio [eg@unice.fr] * Creation date: 28-Sep-1997 17:30 * Last file update: 7-Oct-1997 12:07 * ******************************************************************************/ /* This code has been tested on the following architectures/systems I386 Linux 2.0 (ELF) sun4x SunOS 4.1.x & SunOS 5.5.x Alpha OSF1 V4.0 HP HP-UX B.10.20 MIPS32 IRIX 6.2 */ #define @ARCH@ #define PROCESSOR "@ARCH@" #define MAX_EXTERNAL_PARAM 16 /* cannot be changed !!! */ typedef union { double d; float f[2]; int i[2]; long l; } fake_type; extern fake_type stk_argv[MAX_EXTERNAL_PARAM]; extern int stk_argc; /* Macros for pushing arguments */ #define init_ext_call() stk_argc=0; #define push_char push_int #define push_short push_int #define push_string push_ptr #define push_int(x) ((stk_argc < MAX_EXTERNAL_PARAM)? \ (stk_argv[stk_argc++].i[0]=(int) (x),\ 0) : \ -1) #define push_long(x) ((stk_argc < MAX_EXTERNAL_PARAM)? \ (stk_argv[stk_argc++].l=(long) (x), \ 0) : \ -1) #if defined(SUN) || defined(I386) # define push_float(x) ((stk_argc < MAX_EXTERNAL_PARAM)? \ (stk_argv[stk_argc++].f[0]=(float)(x),\ 0) : \ -1) # define push_double(x) ((stk_argc < MAX_EXTERNAL_PARAM-1)? \ (stk_argv[stk_argc].d =(double)(x), \ stk_argv[stk_argc+1].i[0]= \ stk_argv[stk_argc].i[1], \ stk_argc +=2, \ 0) : \ -1) # define push_ptr push_int #endif #if defined(HP) # define push_float(x) ((stk_argc < MAX_EXTERNAL_PARAM)? \ (stk_argv[stk_argc++].f[0]=(float)(x),\ 0) : \ -1) # define push_double stk_push_double # define push_ptr push_int #endif #if defined(ALPHA) # define push_float stk_push_float # define push_double(x) ((stk_argc < MAX_EXTERNAL_PARAM)? \ (stk_argv[stk_argc++].d=(double) (x),\ 0) : \ -1) # define push_ptr push_long #endif #if defined(MIPS32) # define push_float stk_push_float # define push_double stk_push_double # define push_ptr push_long #endif /* Macros for calling functions */ #define call_ext_void call_ext_int #define call_ext_char call_ext_int #define call_ext_short call_ext_int #define call_ext_int call_ext_long #define call_ext_long(fct) stk_call_long(fct) #if defined(I386) # define call_ext_float call_ext_double #endif #if defined(SUN)||defined(ALPHA)||defined(HP)|| defined(MIPS32) # define call_ext_float(fct) stk_call_float(fct) #endif #define call_ext_double(fct) stk_call_double(fct) #if defined(ALPHA) # define call_ext_ptr(x) ((void*) call_ext_long(x)) #else # define call_ext_ptr(x) ((void*) call_ext_int(x)) #endif #define call_ext_bool call_ext_char #define call_ext_string call_ext_ptr #ifdef MIPS32 # define get_argv(x) stk_argv[x].i[0] #else # define get_argv(x) stk_argv[x].l #endif /* Prototypes of stack functions. Some of them could be inexistent for a * particular machine */ extern long stk_call_long (void *fct); extern float stk_call_float (void *fct); extern double stk_call_double(void *fct); extern int stk_push_float(float f); extern int stk_push_double(double d); /* Utility macro */ #define big_switch \ switch (stk_argc) { \ case 0: return f(); \ case 1: return f(get_argv(0)); \ case 2: return f(get_argv(0), get_argv(1)); \ case 3: return f(get_argv(0), get_argv(1), get_argv(2)); \ case 4: return f(get_argv(0), get_argv(1), get_argv(2), get_argv(3)); \ case 5: return f(get_argv(0), get_argv(1), get_argv(2), get_argv(3), \ get_argv(4)); \ case 6: return f(get_argv(0), get_argv(1), get_argv(2), get_argv(3), \ get_argv(4), get_argv(5)); \ case 7: return f(get_argv(0), get_argv(1), get_argv(2), get_argv(3), \ get_argv(4), get_argv(5), get_argv(6)); \ case 8: return f(get_argv(0), get_argv(1), get_argv(2), get_argv(3), \ get_argv(4), get_argv(5), get_argv(6), get_argv(7)); \ case 9: return f(get_argv(0), get_argv(1), get_argv(2), get_argv(3), \ get_argv(4), get_argv(5), get_argv(6), get_argv(7), \ get_argv(8)); \ case 10: return f(get_argv(0), get_argv(1), get_argv(2), get_argv(3), \ get_argv(4), get_argv(5), get_argv(6), get_argv(7), \ get_argv(8), get_argv(9)); \ case 11: return f(get_argv(0), get_argv(1), get_argv(2), get_argv(3), \ get_argv(4), get_argv(5), get_argv(6), get_argv(7), \ get_argv(8), get_argv(9), get_argv(10)); \ case 12: return f(get_argv(0), get_argv(1), get_argv(2), get_argv(3), \ get_argv(4), get_argv(5), get_argv(6), get_argv(7), \ get_argv(8), get_argv(9), get_argv(10), get_argv(11)); \ case 13: return f(get_argv(0), get_argv(1), get_argv(2), get_argv(3), \ get_argv(4), get_argv(5), get_argv(6), get_argv(7), \ get_argv(8), get_argv(9), get_argv(10), get_argv(11), \ get_argv(12)); \ case 14: return f(get_argv(0), get_argv(1), get_argv(2), get_argv(3), \ get_argv(4), get_argv(5), get_argv(6), get_argv(7), \ get_argv(8), get_argv(9), get_argv(10), get_argv(11), \ get_argv(12), get_argv(13)); \ case 15: return f(get_argv(0), get_argv(1), get_argv(2), get_argv(3), \ get_argv(4), get_argv(5), get_argv(6), get_argv(7), \ get_argv(8), get_argv(9), get_argv(10), get_argv(11), \ get_argv(12), get_argv(13), get_argv(14)); \ case 16: return f(get_argv(0), get_argv(1), get_argv(2), get_argv(3), \ get_argv(4), get_argv(5), get_argv(6), get_argv(7), \ get_argv(8), get_argv(9), get_argv(10), get_argv(11), \ get_argv(12), get_argv(13), get_argv(14), get_argv(15)); \ }