Merge in a port for mips32-linux, by Petar Jovanovic and Dejan Jevtic,
mips-valgrind@rt-rk.com, Bug 270777.
Valgrind: changes to existing files.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12616 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/include/valgrind.h b/include/valgrind.h
index d10a513..afb4681 100644
--- a/include/valgrind.h
+++ b/include/valgrind.h
@@ -117,6 +117,7 @@
#undef PLAT_ppc64_linux
#undef PLAT_arm_linux
#undef PLAT_s390x_linux
+#undef PLAT_mips32_linux
#if defined(__APPLE__) && defined(__i386__)
@@ -138,6 +139,8 @@
# define PLAT_arm_linux 1
#elif defined(__linux__) && defined(__s390__) && defined(__s390x__)
# define PLAT_s390x_linux 1
+#elif defined(__linux__) && defined(__mips__)
+# define PLAT_mips32_linux 1
#else
/* If we're not compiling for our target platform, don't generate
any inline asms. */
@@ -665,6 +668,70 @@
#endif /* PLAT_s390x_linux */
+/* ------------------------- mips32-linux ---------------- */
+
+#if defined(PLAT_mips32_linux)
+
+typedef
+ struct {
+ unsigned int nraddr; /* where's the code? */
+ }
+ OrigFn;
+
+/* .word 0x342
+ * .word 0x742
+ * .word 0xC2
+ * .word 0x4C2*/
+#define __SPECIAL_INSTRUCTION_PREAMBLE \
+ "srl $0, $0, 13\n\t" \
+ "srl $0, $0, 29\n\t" \
+ "srl $0, $0, 3\n\t" \
+ "srl $0, $0, 19\n\t"
+
+#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
+ _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
+ __extension__ \
+ ({ volatile unsigned int _zzq_args[6]; \
+ volatile unsigned int _zzq_result; \
+ _zzq_args[0] = (unsigned int)(_zzq_request); \
+ _zzq_args[1] = (unsigned int)(_zzq_arg1); \
+ _zzq_args[2] = (unsigned int)(_zzq_arg2); \
+ _zzq_args[3] = (unsigned int)(_zzq_arg3); \
+ _zzq_args[4] = (unsigned int)(_zzq_arg4); \
+ _zzq_args[5] = (unsigned int)(_zzq_arg5); \
+ __asm__ volatile("move $11, %1\n\t" /*default*/ \
+ "move $12, %2\n\t" /*ptr*/ \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* T3 = client_request ( T4 ) */ \
+ "or $13, $13, $13\n\t" \
+ "move %0, $11\n\t" /*result*/ \
+ : "=r" (_zzq_result) \
+ : "r" (_zzq_default), "r" (&_zzq_args[0]) \
+ : "cc","memory", "t3", "t4"); \
+ _zzq_result; \
+ })
+
+#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
+ volatile unsigned int __addr; \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %t9 = guest_NRADDR */ \
+ "or $14, $14, $14\n\t" \
+ "move %0, $11" /*result*/ \
+ : "=r" (__addr) \
+ : \
+ : "cc", "memory" , "t3" \
+ ); \
+ _zzq_orig->nraddr = __addr; \
+ }
+
+#define VALGRIND_CALL_NOREDIR_T9 \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* call-noredir *%t9 */ \
+ "or $15, $15, $15\n\t"
+#endif /* PLAT_mips32_linux */
+
/* Insert assembly code for other platforms here... */
#endif /* NVALGRIND */
@@ -3589,6 +3656,545 @@
#endif /* PLAT_s390x_linux */
+/* ------------------------- mips-linux ------------------------- */
+
+#if defined(PLAT_mips32_linux)
+
+/* These regs are trashed by the hidden call. */
+#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6", \
+"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+"$25", "$31"
+
+/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
+ long) == 4. */
+
+#define CALL_FN_W_v(lval, orig) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[1]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ __asm__ volatile( \
+ "subu $29, $29, 8 \n\t" \
+ "sw $gp, 0($sp) \n\t" \
+ "sw $ra, 4($sp) \n\t" \
+ "subu $29, $29, 16 \n\t" \
+ "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "addu $29, $29, 16\n\t" \
+ "lw $gp, 0($sp) \n\t" \
+ "lw $ra, 4($sp) \n\t" \
+ "addu $29, $29, 8 \n\t" \
+ "move %0, $v0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_W(lval, orig, arg1) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[2]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ __asm__ volatile( \
+ "subu $29, $29, 8 \n\t" \
+ "sw $gp, 0($sp) \n\t" \
+ "sw $ra, 4($sp) \n\t" \
+ "subu $29, $29, 16 \n\t" \
+ "lw $a0, 4(%1) \n\t" /* arg1*/ \
+ "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "addu $29, $29, 16 \n\t" \
+ "lw $gp, 0($sp) \n\t" \
+ "lw $ra, 4($sp) \n\t" \
+ "addu $29, $29, 8 \n\t" \
+ "move %0, $v0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ __asm__ volatile( \
+ "subu $29, $29, 8 \n\t" \
+ "sw $gp, 0($sp) \n\t" \
+ "sw $ra, 4($sp) \n\t" \
+ "subu $29, $29, 16 \n\t" \
+ "lw $a0, 4(%1) \n\t" \
+ "lw $a1, 8(%1) \n\t" \
+ "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "addu $29, $29, 16 \n\t" \
+ "lw $gp, 0($sp) \n\t" \
+ "lw $ra, 4($sp) \n\t" \
+ "addu $29, $29, 8 \n\t" \
+ "move %0, $v0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[4]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ __asm__ volatile( \
+ "subu $29, $29, 8 \n\t" \
+ "sw $gp, 0($sp) \n\t" \
+ "sw $ra, 4($sp) \n\t" \
+ "subu $29, $29, 16 \n\t" \
+ "lw $a0, 4(%1) \n\t" \
+ "lw $a1, 8(%1) \n\t" \
+ "lw $a2, 12(%1) \n\t" \
+ "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "addu $29, $29, 16 \n\t" \
+ "lw $gp, 0($sp) \n\t" \
+ "lw $ra, 4($sp) \n\t" \
+ "addu $29, $29, 8 \n\t" \
+ "move %0, $v0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[5]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ __asm__ volatile( \
+ "subu $29, $29, 8 \n\t" \
+ "sw $gp, 0($sp) \n\t" \
+ "sw $ra, 4($sp) \n\t" \
+ "subu $29, $29, 16 \n\t" \
+ "lw $a0, 4(%1) \n\t" \
+ "lw $a1, 8(%1) \n\t" \
+ "lw $a2, 12(%1) \n\t" \
+ "lw $a3, 16(%1) \n\t" \
+ "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "addu $29, $29, 16 \n\t" \
+ "lw $gp, 0($sp) \n\t" \
+ "lw $ra, 4($sp) \n\t" \
+ "addu $29, $29, 8 \n\t" \
+ "move %0, $v0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[6]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ __asm__ volatile( \
+ "subu $29, $29, 8 \n\t" \
+ "sw $gp, 0($sp) \n\t" \
+ "sw $ra, 4($sp) \n\t" \
+ "lw $a0, 20(%1) \n\t" \
+ "subu $sp, $sp, 24\n\t" \
+ "sw $a0, 16($sp) \n\t" \
+ "lw $a0, 4(%1) \n\t" \
+ "lw $a1, 8(%1) \n\t" \
+ "lw $a2, 12(%1) \n\t" \
+ "lw $a3, 16(%1) \n\t" \
+ "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "addu $29, $29, 24 \n\t" \
+ "lw $gp, 0($sp) \n\t" \
+ "lw $ra, 4($sp) \n\t" \
+ "addu $sp, $sp, 8 \n\t" \
+ "move %0, $v0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[7]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ __asm__ volatile( \
+ "subu $29, $29, 8 \n\t" \
+ "sw $gp, 0($sp) \n\t" \
+ "sw $ra, 4($sp) \n\t" \
+ "lw $a0, 20(%1) \n\t" \
+ "subu $sp, $sp, 32\n\t" \
+ "sw $a0, 16($sp) \n\t" \
+ "lw $a0, 24(%1) \n\t" \
+ "nop\n\t" \
+ "sw $a0, 20($sp) \n\t" \
+ "lw $a0, 4(%1) \n\t" \
+ "lw $a1, 8(%1) \n\t" \
+ "lw $a2, 12(%1) \n\t" \
+ "lw $a3, 16(%1) \n\t" \
+ "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "addu $sp, $sp, 32 \n\t" \
+ "lw $gp, 0($sp) \n\t" \
+ "lw $ra, 4($sp) \n\t" \
+ "addu $sp, $sp, 8 \n\t" \
+ "move %0, $v0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[8]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ __asm__ volatile( \
+ "subu $29, $29, 8 \n\t" \
+ "sw $gp, 0($sp) \n\t" \
+ "sw $ra, 4($sp) \n\t" \
+ "lw $a0, 20(%1) \n\t" \
+ "subu $sp, $sp, 32\n\t" \
+ "sw $a0, 16($sp) \n\t" \
+ "lw $a0, 24(%1) \n\t" \
+ "sw $a0, 20($sp) \n\t" \
+ "lw $a0, 28(%1) \n\t" \
+ "sw $a0, 24($sp) \n\t" \
+ "lw $a0, 4(%1) \n\t" \
+ "lw $a1, 8(%1) \n\t" \
+ "lw $a2, 12(%1) \n\t" \
+ "lw $a3, 16(%1) \n\t" \
+ "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "addu $sp, $sp, 32 \n\t" \
+ "lw $gp, 0($sp) \n\t" \
+ "lw $ra, 4($sp) \n\t" \
+ "addu $sp, $sp, 8 \n\t" \
+ "move %0, $v0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[9]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ __asm__ volatile( \
+ "subu $29, $29, 8 \n\t" \
+ "sw $gp, 0($sp) \n\t" \
+ "sw $ra, 4($sp) \n\t" \
+ "lw $a0, 20(%1) \n\t" \
+ "subu $sp, $sp, 40\n\t" \
+ "sw $a0, 16($sp) \n\t" \
+ "lw $a0, 24(%1) \n\t" \
+ "sw $a0, 20($sp) \n\t" \
+ "lw $a0, 28(%1) \n\t" \
+ "sw $a0, 24($sp) \n\t" \
+ "lw $a0, 32(%1) \n\t" \
+ "sw $a0, 28($sp) \n\t" \
+ "lw $a0, 4(%1) \n\t" \
+ "lw $a1, 8(%1) \n\t" \
+ "lw $a2, 12(%1) \n\t" \
+ "lw $a3, 16(%1) \n\t" \
+ "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "addu $sp, $sp, 40 \n\t" \
+ "lw $gp, 0($sp) \n\t" \
+ "lw $ra, 4($sp) \n\t" \
+ "addu $sp, $sp, 8 \n\t" \
+ "move %0, $v0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[10]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ __asm__ volatile( \
+ "subu $29, $29, 8 \n\t" \
+ "sw $gp, 0($sp) \n\t" \
+ "sw $ra, 4($sp) \n\t" \
+ "lw $a0, 20(%1) \n\t" \
+ "subu $sp, $sp, 40\n\t" \
+ "sw $a0, 16($sp) \n\t" \
+ "lw $a0, 24(%1) \n\t" \
+ "sw $a0, 20($sp) \n\t" \
+ "lw $a0, 28(%1) \n\t" \
+ "sw $a0, 24($sp) \n\t" \
+ "lw $a0, 32(%1) \n\t" \
+ "sw $a0, 28($sp) \n\t" \
+ "lw $a0, 36(%1) \n\t" \
+ "sw $a0, 32($sp) \n\t" \
+ "lw $a0, 4(%1) \n\t" \
+ "lw $a1, 8(%1) \n\t" \
+ "lw $a2, 12(%1) \n\t" \
+ "lw $a3, 16(%1) \n\t" \
+ "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "addu $sp, $sp, 40 \n\t" \
+ "lw $gp, 0($sp) \n\t" \
+ "lw $ra, 4($sp) \n\t" \
+ "addu $sp, $sp, 8 \n\t" \
+ "move %0, $v0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[11]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ __asm__ volatile( \
+ "subu $29, $29, 8 \n\t" \
+ "sw $gp, 0($sp) \n\t" \
+ "sw $ra, 4($sp) \n\t" \
+ "lw $a0, 20(%1) \n\t" \
+ "subu $sp, $sp, 48\n\t" \
+ "sw $a0, 16($sp) \n\t" \
+ "lw $a0, 24(%1) \n\t" \
+ "sw $a0, 20($sp) \n\t" \
+ "lw $a0, 28(%1) \n\t" \
+ "sw $a0, 24($sp) \n\t" \
+ "lw $a0, 32(%1) \n\t" \
+ "sw $a0, 28($sp) \n\t" \
+ "lw $a0, 36(%1) \n\t" \
+ "sw $a0, 32($sp) \n\t" \
+ "lw $a0, 40(%1) \n\t" \
+ "sw $a0, 36($sp) \n\t" \
+ "lw $a0, 4(%1) \n\t" \
+ "lw $a1, 8(%1) \n\t" \
+ "lw $a2, 12(%1) \n\t" \
+ "lw $a3, 16(%1) \n\t" \
+ "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "addu $sp, $sp, 48 \n\t" \
+ "lw $gp, 0($sp) \n\t" \
+ "lw $ra, 4($sp) \n\t" \
+ "addu $sp, $sp, 8 \n\t" \
+ "move %0, $v0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
+ arg6,arg7,arg8,arg9,arg10, \
+ arg11) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[12]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ _argvec[11] = (unsigned long)(arg11); \
+ __asm__ volatile( \
+ "subu $29, $29, 8 \n\t" \
+ "sw $gp, 0($sp) \n\t" \
+ "sw $ra, 4($sp) \n\t" \
+ "lw $a0, 20(%1) \n\t" \
+ "subu $sp, $sp, 48\n\t" \
+ "sw $a0, 16($sp) \n\t" \
+ "lw $a0, 24(%1) \n\t" \
+ "sw $a0, 20($sp) \n\t" \
+ "lw $a0, 28(%1) \n\t" \
+ "sw $a0, 24($sp) \n\t" \
+ "lw $a0, 32(%1) \n\t" \
+ "sw $a0, 28($sp) \n\t" \
+ "lw $a0, 36(%1) \n\t" \
+ "sw $a0, 32($sp) \n\t" \
+ "lw $a0, 40(%1) \n\t" \
+ "sw $a0, 36($sp) \n\t" \
+ "lw $a0, 44(%1) \n\t" \
+ "sw $a0, 40($sp) \n\t" \
+ "lw $a0, 4(%1) \n\t" \
+ "lw $a1, 8(%1) \n\t" \
+ "lw $a2, 12(%1) \n\t" \
+ "lw $a3, 16(%1) \n\t" \
+ "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "addu $sp, $sp, 48 \n\t" \
+ "lw $gp, 0($sp) \n\t" \
+ "lw $ra, 4($sp) \n\t" \
+ "addu $sp, $sp, 8 \n\t" \
+ "move %0, $v0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
+ arg6,arg7,arg8,arg9,arg10, \
+ arg11,arg12) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[13]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ _argvec[11] = (unsigned long)(arg11); \
+ _argvec[12] = (unsigned long)(arg12); \
+ __asm__ volatile( \
+ "subu $29, $29, 8 \n\t" \
+ "sw $gp, 0($sp) \n\t" \
+ "sw $ra, 4($sp) \n\t" \
+ "lw $a0, 20(%1) \n\t" \
+ "subu $sp, $sp, 56\n\t" \
+ "sw $a0, 16($sp) \n\t" \
+ "lw $a0, 24(%1) \n\t" \
+ "sw $a0, 20($sp) \n\t" \
+ "lw $a0, 28(%1) \n\t" \
+ "sw $a0, 24($sp) \n\t" \
+ "lw $a0, 32(%1) \n\t" \
+ "sw $a0, 28($sp) \n\t" \
+ "lw $a0, 36(%1) \n\t" \
+ "sw $a0, 32($sp) \n\t" \
+ "lw $a0, 40(%1) \n\t" \
+ "sw $a0, 36($sp) \n\t" \
+ "lw $a0, 44(%1) \n\t" \
+ "sw $a0, 40($sp) \n\t" \
+ "lw $a0, 48(%1) \n\t" \
+ "sw $a0, 44($sp) \n\t" \
+ "lw $a0, 4(%1) \n\t" \
+ "lw $a1, 8(%1) \n\t" \
+ "lw $a2, 12(%1) \n\t" \
+ "lw $a3, 16(%1) \n\t" \
+ "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "addu $sp, $sp, 56 \n\t" \
+ "lw $gp, 0($sp) \n\t" \
+ "lw $ra, 4($sp) \n\t" \
+ "addu $sp, $sp, 8 \n\t" \
+ "move %0, $v0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#endif /* PLAT_mips32_linux */
+
/* ------------------------------------------------------------------ */
/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */
@@ -4068,5 +4674,6 @@
#undef PLAT_ppc64_linux
#undef PLAT_arm_linux
#undef PLAT_s390x_linux
+#undef PLAT_mips32_linux
#endif /* __VALGRIND_H */