Add support for the MicroBlaze architecture

* configure.ac: Recognize MicroBlaze.
* linux/microblaze/syscallent.h: New file.
* Makefile.am (EXTRA_DIST): Add linux/microblaze/syscallent.h
* process.c (change_syscall, struct_user_offsets): Add MicroBlaze
support.
* signal.c (sys_sigreturn): Likewise.
* syscall.c (internal_syscall, get_scno, syscall_fixup, get_error,
syscall_enter): Likewise.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Signed-off-by: Michal Simek <monstr@monstr.eu>
diff --git a/syscall.c b/syscall.c
index f33ae4c..38f628b 100644
--- a/syscall.c
+++ b/syscall.c
@@ -760,6 +760,8 @@
 	static long rax;
 #elif defined(CRISV10) || defined(CRISV32)
 	static long r10;
+#elif defined(MICROBLAZE)
+	static long r3;
 #endif
 #endif /* LINUX */
 #ifdef FREEBSD
@@ -1315,6 +1317,9 @@
 			return 0;
 		}
 	}
+# elif defined(MICROBLAZE)
+	if (upeek(tcp, 0, &scno) < 0)
+		return -1;
 # endif
 #endif /* LINUX */
 
@@ -1527,6 +1532,14 @@
 			fprintf(stderr, "stray syscall exit: r10 = %ld\n", r10);
 		return 0;
 	}
+#elif defined(MICROBLAZE)
+	if (upeek(tcp, 3 * 4, &r3) < 0)
+		return -1;
+	if (r3 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
+		if (debug)
+			fprintf(stderr, "stray syscall exit: r3 = %ld\n", r3);
+		return 0;
+	}
 #endif
 #endif /* LINUX */
 	return 1;
@@ -1733,6 +1746,16 @@
 			tcp->u_rval = rval;
 			u_error = 0;
 		}
+# elif defined(MICROBLAZE)
+		/* interpret result as return value or error number */
+		if (is_negated_errno(r3)) {
+			tcp->u_rval = -1;
+			u_error = -r3;
+		}
+		else {
+			tcp->u_rval = r3;
+			u_error = 0;
+		}
 # endif
 #endif /* LINUX */
 #ifdef SUNOS4
@@ -2243,6 +2266,18 @@
 				return -1;
 		}
 	}
+#elif defined(MICROBLAZE)
+	{
+		int i;
+		if (tcp->scno >= 0 && tcp->scno < nsyscalls)
+			tcp->u_nargs = sysent[tcp->scno].nargs;
+		else
+			tcp->u_nargs = 0;
+		for (i = 0; i < tcp->u_nargs; i++) {
+			if (upeek(tcp, (5 + i) * 4, &tcp->u_arg[i]) < 0)
+				return -1;
+		}
+	}
 #elif defined(CRISV10) || defined(CRISV32)
 	{
 		int i;