1#include <exports.h>
2
3#ifndef GCC_VERSION
4#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
5#endif /* GCC_VERSION */
6
7/*
8 * k0 ($26) holds the pointer to the global_data; t9 ($25) is a call-
9 * clobbered register that is also used to set gp ($26). Note that the
10 * jr instruction also executes the instruction immediately following
11 * it; however, GCC/mips generates an additional `nop' after each asm
12 * statement
13 */
14#define EXPORT_FUNC(x) \
15	asm volatile (			\
16"	.globl " #x "\n"		\
17#x ":\n"				\
18"	lw	$25, %0($26)\n"		\
19"	lw	$25, %1($25)\n"		\
20"	jr	$25\n"			\
21	: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "t9");
22
23/* This function is necessary to prevent the compiler from
24 * generating prologue/epilogue, preparing stack frame etc.
25 * The stub functions are special, they do not use the stack
26 * frame passed to them, but pass it intact to the actual
27 * implementation. On the other hand, asm() statements with
28 * arguments can be used only inside the functions (gcc limitation)
29 */
30#if GCC_VERSION < 3004
31static
32#endif /* GCC_VERSION */
33void __attribute__((unused)) dummy(void)
34{
35#include <_exports.h>
36}
37
38#if 0
39extern unsigned long __bss_start, _end;
40
41void app_startup(char **argv)
42{
43	unsigned long * cp = &__bss_start;
44
45	/* Zero out BSS */
46	while (cp < &_end) {
47		*cp++ = 0;
48	}
49}
50#endif
51
52#undef EXPORT_FUNC
53