aboutsummaryrefslogtreecommitdiff
path: root/tinycc/lib/armflush.c
diff options
context:
space:
mode:
Diffstat (limited to 'tinycc/lib/armflush.c')
-rw-r--r--tinycc/lib/armflush.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/tinycc/lib/armflush.c b/tinycc/lib/armflush.c
new file mode 100644
index 0000000..c379e43
--- /dev/null
+++ b/tinycc/lib/armflush.c
@@ -0,0 +1,51 @@
+/* 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 _tccsyscall(unsigned syscall_nr, ...);
+
+/* arm-tcc supports only fake asm currently */
+__asm__(
+ ".global _tccsyscall\n"
+ "_tccsyscall:\n"
+ "push {r7, lr}\n\t"
+ "mov r7, r0\n\t"
+ "mov r0, r1\n\t"
+ "mov r1, r2\n\t"
+ "mov r2, r3\n\t"
+ "svc #0\n\t"
+ "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)
+
+#define syscall _tccsyscall
+
+#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 */
+ syscall(__ARM_NR_cacheflush, beginning, end, 0);
+}