Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Add MIPS (o32 ABI) support
Signed-off-by: Carsten Munk <carsten.munk@gmail.com>
- Loading branch information
Showing
3 changed files
with
287 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,278 @@ | ||
--- glibc-2.13/fedora/tzdata-update.c 2011-12-31 10:29:33.850744001 +0100 | ||
+++ glibc-2.13-tzdata-update-mips/fedora/tzdata-update.c 2011-12-31 11:28:27.686744006 +0100 | ||
@@ -420,6 +420,275 @@ | ||
_r0 = (int)r0; \ | ||
register int _r1 __asm__("r1") = (int)r1; \ | ||
register int _r2 __asm__("r2") = (int)r2; | ||
+#elif defined __mips__ | ||
+/* In order to get __set_errno() definition in INLINE_SYSCALL. */ | ||
+#ifndef __ASSEMBLER__ | ||
+#include <errno.h> | ||
+#endif | ||
+ | ||
+/* For Linux we can use the system call table in the header file | ||
+ /usr/include/asm/unistd.h | ||
+ of the kernel. But these symbols do not follow the SYS_* syntax | ||
+ so we have to redefine the `SYS_ify' macro here. */ | ||
+#undef SYS_ify | ||
+#ifdef __STDC__ | ||
+# define SYS_ify(syscall_name) __NR_##syscall_name | ||
+#else | ||
+# define SYS_ify(syscall_name) __NR_/**/syscall_name | ||
+#endif | ||
+ | ||
+#ifndef __ASSEMBLER__ | ||
+ | ||
+/* Define a macro which expands into the inline wrapper code for a system | ||
+ call. */ | ||
+#undef INLINE_SYSCALL | ||
+#define INLINE_SYSCALL(name, nr, args...) \ | ||
+ ({ INTERNAL_SYSCALL_DECL(err); \ | ||
+ long result_var = INTERNAL_SYSCALL (name, err, nr, args); \ | ||
+ if ( INTERNAL_SYSCALL_ERROR_P (result_var, err) ) \ | ||
+ { \ | ||
+ __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, err)); \ | ||
+ result_var = -1L; \ | ||
+ } \ | ||
+ result_var; }) | ||
+ | ||
+#undef INTERNAL_SYSCALL_DECL | ||
+#define INTERNAL_SYSCALL_DECL(err) long err | ||
+ | ||
+#undef INTERNAL_SYSCALL_ERROR_P | ||
+#define INTERNAL_SYSCALL_ERROR_P(val, err) ((long) (err)) | ||
+ | ||
+#undef INTERNAL_SYSCALL_ERRNO | ||
+#define INTERNAL_SYSCALL_ERRNO(val, err) (val) | ||
+ | ||
+#undef INTERNAL_SYSCALL | ||
+#define INTERNAL_SYSCALL(name, err, nr, args...) \ | ||
+ internal_syscall##nr (, "li\t$2, %2\t\t\t# " #name "\n\t", \ | ||
+ "i" (SYS_ify (name)), err, args) | ||
+ | ||
+#undef INTERNAL_SYSCALL_NCS | ||
+#define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \ | ||
+ internal_syscall##nr (= number, , "r" (__v0), err, args) | ||
+ | ||
+#define internal_syscall0(ncs_init, cs_init, input, err, dummy...) \ | ||
+({ \ | ||
+ long _sys_result; \ | ||
+ \ | ||
+ { \ | ||
+ register long __v0 asm("$2") ncs_init; \ | ||
+ register long __a3 asm("$7"); \ | ||
+ __asm__ volatile ( \ | ||
+ ".set\tnoreorder\n\t" \ | ||
+ cs_init \ | ||
+ "syscall\n\t" \ | ||
+ ".set reorder" \ | ||
+ : "=r" (__v0), "=r" (__a3) \ | ||
+ : input \ | ||
+ : __SYSCALL_CLOBBERS); \ | ||
+ err = __a3; \ | ||
+ _sys_result = __v0; \ | ||
+ } \ | ||
+ _sys_result; \ | ||
+}) | ||
+ | ||
+#define internal_syscall1(ncs_init, cs_init, input, err, arg1) \ | ||
+({ \ | ||
+ long _sys_result; \ | ||
+ \ | ||
+ { \ | ||
+ register long __v0 asm("$2") ncs_init; \ | ||
+ register long __a0 asm("$4") = (long) arg1; \ | ||
+ register long __a3 asm("$7"); \ | ||
+ __asm__ volatile ( \ | ||
+ ".set\tnoreorder\n\t" \ | ||
+ cs_init \ | ||
+ "syscall\n\t" \ | ||
+ ".set reorder" \ | ||
+ : "=r" (__v0), "=r" (__a3) \ | ||
+ : input, "r" (__a0) \ | ||
+ : __SYSCALL_CLOBBERS); \ | ||
+ err = __a3; \ | ||
+ _sys_result = __v0; \ | ||
+ } \ | ||
+ _sys_result; \ | ||
+}) | ||
+ | ||
+#define internal_syscall2(ncs_init, cs_init, input, err, arg1, arg2) \ | ||
+({ \ | ||
+ long _sys_result; \ | ||
+ \ | ||
+ { \ | ||
+ register long __v0 asm("$2") ncs_init; \ | ||
+ register long __a0 asm("$4") = (long) arg1; \ | ||
+ register long __a1 asm("$5") = (long) arg2; \ | ||
+ register long __a3 asm("$7"); \ | ||
+ __asm__ volatile ( \ | ||
+ ".set\tnoreorder\n\t" \ | ||
+ cs_init \ | ||
+ "syscall\n\t" \ | ||
+ ".set\treorder" \ | ||
+ : "=r" (__v0), "=r" (__a3) \ | ||
+ : input, "r" (__a0), "r" (__a1) \ | ||
+ : __SYSCALL_CLOBBERS); \ | ||
+ err = __a3; \ | ||
+ _sys_result = __v0; \ | ||
+ } \ | ||
+ _sys_result; \ | ||
+}) | ||
+ | ||
+#define internal_syscall3(ncs_init, cs_init, input, err, arg1, arg2, arg3)\ | ||
+({ \ | ||
+ long _sys_result; \ | ||
+ \ | ||
+ { \ | ||
+ register long __v0 asm("$2") ncs_init; \ | ||
+ register long __a0 asm("$4") = (long) arg1; \ | ||
+ register long __a1 asm("$5") = (long) arg2; \ | ||
+ register long __a2 asm("$6") = (long) arg3; \ | ||
+ register long __a3 asm("$7"); \ | ||
+ __asm__ volatile ( \ | ||
+ ".set\tnoreorder\n\t" \ | ||
+ cs_init \ | ||
+ "syscall\n\t" \ | ||
+ ".set\treorder" \ | ||
+ : "=r" (__v0), "=r" (__a3) \ | ||
+ : input, "r" (__a0), "r" (__a1), "r" (__a2) \ | ||
+ : __SYSCALL_CLOBBERS); \ | ||
+ err = __a3; \ | ||
+ _sys_result = __v0; \ | ||
+ } \ | ||
+ _sys_result; \ | ||
+}) | ||
+ | ||
+#define internal_syscall4(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4)\ | ||
+({ \ | ||
+ long _sys_result; \ | ||
+ \ | ||
+ { \ | ||
+ register long __v0 asm("$2") ncs_init; \ | ||
+ register long __a0 asm("$4") = (long) arg1; \ | ||
+ register long __a1 asm("$5") = (long) arg2; \ | ||
+ register long __a2 asm("$6") = (long) arg3; \ | ||
+ register long __a3 asm("$7") = (long) arg4; \ | ||
+ __asm__ volatile ( \ | ||
+ ".set\tnoreorder\n\t" \ | ||
+ cs_init \ | ||
+ "syscall\n\t" \ | ||
+ ".set\treorder" \ | ||
+ : "=r" (__v0), "+r" (__a3) \ | ||
+ : input, "r" (__a0), "r" (__a1), "r" (__a2) \ | ||
+ : __SYSCALL_CLOBBERS); \ | ||
+ err = __a3; \ | ||
+ _sys_result = __v0; \ | ||
+ } \ | ||
+ _sys_result; \ | ||
+}) | ||
+ | ||
+/* We need to use a frame pointer for the functions in which we | ||
+ adjust $sp around the syscall, or debug information and unwind | ||
+ information will be $sp relative and thus wrong during the syscall. As | ||
+ of GCC 3.4.3, this is sufficient. */ | ||
+#define FORCE_FRAME_POINTER alloca (4) | ||
+ | ||
+#define internal_syscall5(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5)\ | ||
+({ \ | ||
+ long _sys_result; \ | ||
+ \ | ||
+ FORCE_FRAME_POINTER; \ | ||
+ { \ | ||
+ register long __v0 asm("$2") ncs_init; \ | ||
+ register long __a0 asm("$4") = (long) arg1; \ | ||
+ register long __a1 asm("$5") = (long) arg2; \ | ||
+ register long __a2 asm("$6") = (long) arg3; \ | ||
+ register long __a3 asm("$7") = (long) arg4; \ | ||
+ __asm__ volatile ( \ | ||
+ ".set\tnoreorder\n\t" \ | ||
+ "subu\t$29, 32\n\t" \ | ||
+ "sw\t%6, 16($29)\n\t" \ | ||
+ cs_init \ | ||
+ "syscall\n\t" \ | ||
+ "addiu\t$29, 32\n\t" \ | ||
+ ".set\treorder" \ | ||
+ : "=r" (__v0), "+r" (__a3) \ | ||
+ : input, "r" (__a0), "r" (__a1), "r" (__a2), \ | ||
+ "r" ((long)arg5) \ | ||
+ : __SYSCALL_CLOBBERS); \ | ||
+ err = __a3; \ | ||
+ _sys_result = __v0; \ | ||
+ } \ | ||
+ _sys_result; \ | ||
+}) | ||
+ | ||
+#define internal_syscall6(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6)\ | ||
+({ \ | ||
+ long _sys_result; \ | ||
+ \ | ||
+ FORCE_FRAME_POINTER; \ | ||
+ { \ | ||
+ register long __v0 asm("$2") ncs_init; \ | ||
+ register long __a0 asm("$4") = (long) arg1; \ | ||
+ register long __a1 asm("$5") = (long) arg2; \ | ||
+ register long __a2 asm("$6") = (long) arg3; \ | ||
+ register long __a3 asm("$7") = (long) arg4; \ | ||
+ __asm__ volatile ( \ | ||
+ ".set\tnoreorder\n\t" \ | ||
+ "subu\t$29, 32\n\t" \ | ||
+ "sw\t%6, 16($29)\n\t" \ | ||
+ "sw\t%7, 20($29)\n\t" \ | ||
+ cs_init \ | ||
+ "syscall\n\t" \ | ||
+ "addiu\t$29, 32\n\t" \ | ||
+ ".set\treorder" \ | ||
+ : "=r" (__v0), "+r" (__a3) \ | ||
+ : input, "r" (__a0), "r" (__a1), "r" (__a2), \ | ||
+ "r" ((long)arg5), "r" ((long)arg6) \ | ||
+ : __SYSCALL_CLOBBERS); \ | ||
+ err = __a3; \ | ||
+ _sys_result = __v0; \ | ||
+ } \ | ||
+ _sys_result; \ | ||
+}) | ||
+ | ||
+#define internal_syscall7(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\ | ||
+({ \ | ||
+ long _sys_result; \ | ||
+ \ | ||
+ FORCE_FRAME_POINTER; \ | ||
+ { \ | ||
+ register long __v0 asm("$2") ncs_init; \ | ||
+ register long __a0 asm("$4") = (long) arg1; \ | ||
+ register long __a1 asm("$5") = (long) arg2; \ | ||
+ register long __a2 asm("$6") = (long) arg3; \ | ||
+ register long __a3 asm("$7") = (long) arg4; \ | ||
+ __asm__ volatile ( \ | ||
+ ".set\tnoreorder\n\t" \ | ||
+ "subu\t$29, 32\n\t" \ | ||
+ "sw\t%6, 16($29)\n\t" \ | ||
+ "sw\t%7, 20($29)\n\t" \ | ||
+ "sw\t%8, 24($29)\n\t" \ | ||
+ cs_init \ | ||
+ "syscall\n\t" \ | ||
+ "addiu\t$29, 32\n\t" \ | ||
+ ".set\treorder" \ | ||
+ : "=r" (__v0), "+r" (__a3) \ | ||
+ : input, "r" (__a0), "r" (__a1), "r" (__a2), \ | ||
+ "r" ((long)arg5), "r" ((long)arg6), "r" ((long)arg7) \ | ||
+ : __SYSCALL_CLOBBERS); \ | ||
+ err = __a3; \ | ||
+ _sys_result = __v0; \ | ||
+ } \ | ||
+ _sys_result; \ | ||
+}) | ||
+ | ||
+#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \ | ||
+ "$14", "$15", "$24", "$25", "hi", "lo", "memory" | ||
+ | ||
+#endif /* __ASSEMBLER__ */ | ||
+ | ||
+/* Pointer mangling is not yet supported for MIPS. */ | ||
+#define PTR_MANGLE(var) (void) (var) | ||
+#define PTR_DEMANGLE(var) (void) (var) | ||
+ | ||
#endif | ||
|
||
char buffer[32768], data[32768]; |