#include "jit-config.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifndef JIT_WIN32_PLATFORM
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#else
#include <windows.h>
#include <io.h>
#endif
#if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MMAP) && defined(HAVE_MUNMAP)
#ifndef MAP_ANONYMOUS
#ifdef MAP_ANON
#define MAP_ANONYMOUS MAP_ANON
#endif
#endif
#ifdef MAP_ANONYMOUS
#define JIT_USE_MMAP
#endif
#endif
void *
_jit_malloc_exec(unsigned int size)
{
#if defined(JIT_WIN32_PLATFORM)
return VirtualAlloc(NULL, size,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
#elif defined(JIT_USE_MMAP)
void *ptr = mmap(0, size,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if(ptr == (void *)-1)
{
return (void *)0;
}
return ptr;
#else
return malloc(size);
#endif
}
void
_jit_free_exec(void *ptr, unsigned int size)
{
if(ptr)
{
#if defined(JIT_WIN32_PLATFORM)
VirtualFree(ptr, 0, MEM_RELEASE);
#elif defined(JIT_USE_MMAP)
munmap(ptr, size);
#else
free(ptr);
#endif
}
}
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
register unsigned char *p;
register unsigned char *end;
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");
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
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)
__asm __volatile ("mov r0, %0\n"
"mov r1, %1\n"
"mov r2, %2\n"
"swi 0x9f0002 @ sys_cacheflush"
:
: "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
}