mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-03 21:48:15 +00:00 
			
		
		
		
	R29 was an unlucky choice as with recent toolchains (gcc-4.2.x) gcc will refuse to use load/store multiple insns; instead, it issues a list of simple load/store instructions upon function entry and exit, resulting in bigger code size, which in turn makes the build for a few boards fail. Use r2 instead. Signed-off-by: Wolfgang Denk <wd@denx.de>
		
			
				
	
	
		
			88 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <stddef.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
void *func[8], **pfunc;
 | 
						|
 | 
						|
typedef struct xxx xxx_t;
 | 
						|
struct xxx {
 | 
						|
	int dummy;
 | 
						|
	void **pfunc;
 | 
						|
} q;
 | 
						|
 | 
						|
#define XF_strcpy 3
 | 
						|
#define XF_printf 4
 | 
						|
 | 
						|
#define LABEL(x)					\
 | 
						|
asm volatile (						\
 | 
						|
 | 
						|
#if defined(__i386__)
 | 
						|
#define EXPORT_FUNC(x)					\
 | 
						|
asm volatile (						\
 | 
						|
"	.globl mon_" #x "\n"				\
 | 
						|
"mon_" #x ":\n"						\
 | 
						|
"	movl	%0, %%eax\n"				\
 | 
						|
"	movl	pfunc, %%ecx\n"				\
 | 
						|
"	jmp	*(%%ecx,%%eax)\n"			\
 | 
						|
	: : "i"(XF_ ## x * sizeof(void *)) : "eax", "ecx");
 | 
						|
#elif defined(__powerpc__)
 | 
						|
#define EXPORT_FUNC(x)					\
 | 
						|
asm volatile (						\
 | 
						|
"	.globl mon_" #x "\n"				\
 | 
						|
"mon_" #x ":\n"						\
 | 
						|
"	lwz	%%r11, %0(%%r2)\n"			\
 | 
						|
"	lwz	%%r11, %1(%%r11)\n"			\
 | 
						|
"	mtctr	%%r11\n"				\
 | 
						|
"	bctr\n"					\
 | 
						|
	: : "i"(offsetof(xxx_t, pfunc)), "i"(XF_ ## x * sizeof(void *)) : "r11", "r2");
 | 
						|
#elif defined(__arm__)
 | 
						|
#define EXPORT_FUNC(x)					\
 | 
						|
asm volatile (						\
 | 
						|
"	.globl mon_" #x "\n"				\
 | 
						|
"mon_" #x ":\n"						\
 | 
						|
"	ldr	ip, [r8, %0]\n"				\
 | 
						|
"	ldr	pc, [ip, %1]\n"				\
 | 
						|
	: : "i"(offsetof(xxx_t, pfunc)), "i"(XF_ ## x * sizeof(void *)) : "ip");
 | 
						|
#elif defined(__mips__)
 | 
						|
#define EXPORT_FUNC(x)					\
 | 
						|
asm volatile (						\
 | 
						|
"	.globl mon_" #x "\n"				\
 | 
						|
"mon_" #x ":\n"						\
 | 
						|
"	lw	$25, %0($26)\n"				\
 | 
						|
"	lw	$25, %1($25)\n"				\
 | 
						|
"	jr	$25\n"					\
 | 
						|
	: : "i"(offsetof(xxx_t, pfunc)), "i"(XF_ ## x * sizeof(void *)) : "t9");
 | 
						|
#else
 | 
						|
#error [No stub code for this arch]
 | 
						|
#endif
 | 
						|
 | 
						|
void dummy(void)
 | 
						|
{
 | 
						|
EXPORT_FUNC(printf)
 | 
						|
EXPORT_FUNC(strcpy)
 | 
						|
}
 | 
						|
 | 
						|
int main(void)
 | 
						|
{
 | 
						|
#if defined(__i386__)
 | 
						|
	xxx_t *pq;
 | 
						|
#elif defined(__powerpc__)
 | 
						|
	register volatile xxx_t *pq asm("r2");
 | 
						|
#elif defined(__arm__)
 | 
						|
	register volatile xxx_t *pq asm("r8");
 | 
						|
#elif defined(__mips__)
 | 
						|
	register volatile xxx_t *pq asm("k0");
 | 
						|
#endif
 | 
						|
	char buf[32];
 | 
						|
 | 
						|
	func[XF_strcpy] = strcpy;
 | 
						|
	func[XF_printf] = printf;
 | 
						|
	pq = &q;
 | 
						|
	pq->pfunc = pfunc = func;
 | 
						|
 | 
						|
	mon_strcpy(buf, "test");
 | 
						|
	mon_printf("hi %s %d z\n", buf, 444);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 |