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