204 lines
6.5 KiB
C
204 lines
6.5 KiB
C
/******************************************************************************
|
|
*
|
|
* l i b s t a c k . h
|
|
*
|
|
* Copyright © 1997 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
|
|
*
|
|
*
|
|
* 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)); \
|
|
}
|