Alien-LibJIT

 view release on metacpan or  search on metacpan

libjit/jit/jit-alloc.c  view on Meta::CPAN

 * Flush the contents of the block at @var{ptr} from the CPU's
 * data and instruction caches.  This must be used after the code is
 * written to an executable code segment, but before the code is
 * executed, to prepare it for execution.
 * @end deftypefun
@*/
void
_jit_flush_exec(void *ptr, unsigned int size)
{

#define ROUND_BEG_PTR(p) \
	((void *)((((jit_nuint)(p)) / CLSIZE) * CLSIZE))
#define ROUND_END_PTR(p,s) \
	((void *)(((((jit_nuint)(p)) + (s) + CLSIZE - 1)/CLSIZE)*CLSIZE))

#if defined(__GNUC__)
#if defined(PPC)

#define CLSIZE 4
	/* Flush the CPU cache on PPC platforms */
	register unsigned char *p;
	register unsigned char *end;

	/* Flush the data out of the data cache */
	p   = ROUND_BEG_PTR (ptr);
	end = ROUND_END_PTR (p, size);
	while (p < end)
	{
		__asm__ __volatile__ ("dcbst 0,%0" :: "r"(p));
		p += CLSIZE;
	}
	__asm__ __volatile__ ("sync");

	/* Invalidate the cache lines in the instruction cache */
	p = ROUND_BEG_PTR (ptr);
	while (p < end)
	{
		__asm__ __volatile__ ("icbi 0,%0; isync" :: "r"(p));
		p += CLSIZE;
	}
	__asm__ __volatile__ ("isync");

#elif defined(__sparc)

#define CLSIZE 4

	/* Flush the CPU cache on sparc platforms */
	register unsigned char *p   = ROUND_BEG_PTR (ptr);
	register unsigned char *end = ROUND_END_PTR (p, size);
	__asm__ __volatile__ ("stbar");
	while (p < end)
	{
		__asm__ __volatile__ ("flush %0" :: "r"(p));
		p += CLSIZE;
	}
	__asm__ __volatile__ ("nop; nop; nop; nop; nop");

#elif (defined(__arm__) || defined(__arm)) && defined(linux)

	/* ARM Linux has a "cacheflush" system call */
	/* R0 = start of range, R1 = end of range, R3 = flags */
	/* flags = 0 indicates data cache, flags = 1 indicates both caches */
	__asm __volatile ("mov r0, %0\n"
	                  "mov r1, %1\n"
					  "mov r2, %2\n"
					  "swi 0x9f0002       @ sys_cacheflush"
					  : /* no outputs */
					  : "r" (ptr),
					    "r" (((int)ptr) + (int)size),
						"r" (0)
					  : "r0", "r1", "r3" );

#elif (defined(__ia64) || defined(__ia64__)) && defined(linux)
#define CLSIZE 32
	register unsigned char *p   = ROUND_BEG_PTR (ptr);
	register unsigned char *end = ROUND_END_PTR (p, size);
	while(p < end)
	{
		asm volatile("fc %0" :: "r"(p));
		p += CLSIZE;
	}
	asm volatile(";;sync.i;;srlz.i;;");
#endif
#endif	/* __GNUC__ */
}



( run in 1.451 second using v1.01-cache-2.11-cpan-796a6f069b2 )