summary refs log tree commit diff stats
path: root/tinyc/lib/armflush.c
blob: eae32605f24190f78da2989ec383b6040bd2b122 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/* armflush.c - flush the instruction cache

   __clear_cache is used in tccrun.c,  It is a built-in
   intrinsic with gcc.  However tcc in order to compile
   itself needs this function */

#ifdef __TINYC__

/* syscall wrapper */
unsigned syscall(unsigned syscall_nr, ...);

/* arm-tcc supports only fake asm currently */
__asm__(
    ".global syscall\n"
    "syscall:\n"
    ".int 0xe92d4080\n"  // push    {r7, lr}
    ".int 0xe1a07000\n"  // mov     r7, r0
    ".int 0xe1a00001\n"  // mov     r0, r1
    ".int 0xe1a01002\n"  // mov     r1, r2
    ".int 0xe1a02003\n"  // mov     r2, r3
    ".int 0xef000000\n"  // svc     0x00000000
    ".int 0xe8bd8080\n"  // pop     {r7, pc}
    );

/* from unistd.h: */
#if defined(__thumb__) || defined(__ARM_EABI__)
# define __NR_SYSCALL_BASE      0x0
#else
# define __NR_SYSCALL_BASE      0x900000
#endif
#define __ARM_NR_BASE           (__NR_SYSCALL_BASE+0x0f0000)
#define __ARM_NR_cacheflush     (__ARM_NR_BASE+2)

#else

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>

#endif

/* Flushing for tccrun */
void __clear_cache(void *beginning, void *end)
{
/* __ARM_NR_cacheflush is kernel private and should not be used in user space.
 * However, there is no ARM asm parser in tcc so we use it for now */
#if 1
    syscall(__ARM_NR_cacheflush, beginning, end, 0);
#else
    __asm__ ("push {r7}\n\t"
             "mov r7, #0xf0002\n\t"
             "mov r2, #0\n\t"
             "swi 0\n\t"
             "pop {r7}\n\t"
             "ret");
#endif
}
m">/* Current size of *data */ char * data; /* Pointer to malloced area or 0 */ } HTChunk; #ifdef SHORT_NAMES #define HTChunkClear HTChClea #define HTChunkPutc HTChPutc #define HTChunkPuts HTChPuts #define HTChunkCreate HTChCrea #define HTChunkTerminate HTChTerm #define HTChunkEnsure HtChEnsu #endif /* Create new chunk ON ENTRY, growby The number of bytes to allocate at a time when the chunk is later extended. Arbitrary but normally a trade-off time vs. memory ON EXIT, returns A chunk pointer to the new chunk, */ extern HTChunk * HTChunkCreate PARAMS((int growby)); /* * Like HTChunkCreate but with initial allocation - kw * */ extern HTChunk * HTChunkCreate2 PARAMS((int growby, size_t needed)); /* Free a chunk ON ENTRY, ch A valid chunk pointer made by HTChunkCreate() ON EXIT, ch is invalid and may not be used. */ extern void HTChunkFree PARAMS((HTChunk * ch)); /* Clear a chunk ON ENTRY, ch A valid chunk pointer made by HTChunkCreate() ON EXIT, *ch The size of the chunk is zero. */ extern void HTChunkClear PARAMS((HTChunk * ch)); /* Ensure a chunk has a certain space in ON ENTRY, ch A valid chunk pointer made by HTChunkCreate() s The size required ON EXIT, *ch Has size at least s */ extern void HTChunkEnsure PARAMS((HTChunk * ch, int s)); /* Append a character to a chunk ON ENTRY, ch A valid chunk pointer made by HTChunkCreate() c The character to be appended ON EXIT, *ch Is one character bigger */ extern void HTChunkPutc PARAMS((HTChunk * ch, char c)); extern void HTChunkPutb PARAMS((HTChunk * ch, CONST char *b, int l)); extern void HTChunkPutUtf8Char PARAMS((HTChunk * ch, UCode_t code)); /* Append a string to a chunk ON ENTRY, ch A valid chunk pointer made by HTChunkCreate() str Tpoints to a zero-terminated string to be appended ON EXIT, *ch Is bigger by strlen(str) */ extern void HTChunkPuts PARAMS((HTChunk * ch, const char *str)); /* Append a zero character to a chunk */ /* ON ENTRY, ch A valid chunk pointer made by HTChunkCreate() ON EXIT, *ch Is one character bigger */ extern void HTChunkTerminate PARAMS((HTChunk * ch)); /* end */