pdp11: add syscall generator code
authorAlan Cox <alan@linux.intel.com>
Sat, 17 Feb 2018 22:36:57 +0000 (22:36 +0000)
committerAlan Cox <alan@linux.intel.com>
Sat, 17 Feb 2018 22:36:57 +0000 (22:36 +0000)
Library/Makefile
Library/tools/syscall_pdp11.c [new file with mode: 0644]

index bed22d8..ba54c5d 100644 (file)
@@ -29,6 +29,9 @@ tools/syscall_6809: tools/syscall_6809.c ../Kernel/include/syscall_name.h
 tools/syscall-scc6809: tools/syscall-scc6809.c ../Kernel/include/syscall_name.h
        $(CC) $(CFLAGS) -o $@ $<
 
+tools/syscall_pdp11: tools/syscall_pdp11.c ../Kernel/include/syscall_name.h
+       $(CC) $(CFLAGS) -o $@ $<
+
 tools/binman: tools/binman.c
        $(CC) $(CFLAGS) -o $@ $<
 
@@ -55,4 +58,4 @@ endif
 ifeq ($(USERCPU),6502)
        install -m 0644 ../Kernel/include/userstructs.h include/sys/
        install -m 0644 ../Kernel/include/drivewire.h include/sys/
-endif
\ No newline at end of file
+endif
diff --git a/Library/tools/syscall_pdp11.c b/Library/tools/syscall_pdp11.c
new file mode 100644 (file)
index 0000000..00d621d
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ *     Generate the syscall functions
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "syscall_name.h"
+
+static char namebuf[128];
+
+static void write_call(int n)
+{
+  int args;
+  FILE *fp;
+  snprintf(namebuf, 128, "fuzixpdp11/syscall_%s.s", syscall_name[n]);
+  fp = fopen(namebuf, "w");
+  if (fp == NULL) {
+    perror(namebuf);
+    exit(1);
+  }
+  fprintf(fp, "\t.text\n\t.even\n\n"
+             "\t.globl _%1$s\n\n"
+             "_%1$s:\n", syscall_name[n]);
+  /* All current varargs max at 3 */
+  if (syscall_args[n] == VARARGS)
+    args = 3;
+  else
+    args = syscall_args[n];
+
+  /* FIXME: save r2/r3 if needed */
+  switch(n) {
+    case 2:
+      fprintf(fp, "\tmov 4(sp),r1\n");
+    case 1:
+      fprintf(fp, "\tmov 2(sp),r0\n");
+    case 0:
+      break;
+    case 3:
+      fprintf(fp, "\tmov r2,-(sp)\n\tmov 4(sp),r0\n"
+                  "\tmov 6(sp),r1\n\tmov 8(sp),r2\n");
+      break;
+    case 4:
+      fprintf(fp, "\tmov r2,-(sp)\n\tmov r3,-(sp)\n"
+                  "\tmov 6(sp),r0\n\tmov 8(sp),r1\n"
+                  "\tmov 10(sp),r0\n\tmov 12(sp),r1\n");
+      break;
+  }
+  fprintf(fp, "\ttrap $%d\n", n);
+  fprintf(fp, "\ttst r1\n\tbeq noerr\n");
+  fprintf(fp, "\tmov r1,_errno\n");
+  fprintf(fp, "\tnoerr:\n");
+  switch(n) {
+    case 3:
+      fprintf(fp, "\tmov (sp)+, r3\n");
+    case 2:
+      fprintf(fp, "\tmov (sp)+, r2\n");
+  }
+  fprintf(fp, "\trts pc\n");   /* And restore R2/R3 if needed */
+  fclose(fp);
+}
+
+static void write_call_table(void)
+{
+  int i;
+  for (i = 0; i < NR_SYSCALL; i++)
+    write_call(i);
+}
+
+static void write_makefile(void)
+{
+  int i;
+  FILE *fp = fopen("fuzixpdp11/Makefile", "w");
+  if (fp == NULL) {
+    perror("Makefile");
+    exit(1);
+  }
+  fprintf(fp, "# Autogenerated by tools/syscall_pdp11\n");
+  fprintf(fp, "CROSS_AS=pdp11-aout-as\nCROSS_LD=pdp11-aout-ld\nCROSS_AR=pdp11-aout-ar\n");
+  fprintf(fp, "ASOPTS=\n\n");
+  fprintf(fp, "ASRCS = syscall_%s.s\n", syscall_name[0]);
+  for (i = 1; i < NR_SYSCALL; i++)
+    fprintf(fp, "ASRCS += syscall_%s.s\n", syscall_name[i]);
+  fprintf(fp, "\n\nASRCALL = $(ASRCS)\n");
+  fprintf(fp, "\nAOBJS = $(ASRCALL:.s=.o)\n\n");
+  fprintf(fp, "syslib.lib: $(AOBJS)\n");
+  fprintf(fp, "\techo $(AOBJS) >syslib.l\n");
+  fprintf(fp, "\t$(CROSS_AR) rc syslib.lib $(AOBJS)\n\n");
+  fprintf(fp, "$(AOBJS): %%.o: %%.s\n");
+  fprintf(fp, "\t$(CROSS_AS) $(ASOPTS) -o $*.o $<\n\n");
+  fprintf(fp, "clean:\n");
+  fprintf(fp, "\trm -f $(AOBJS) $(ASRCS) syslib.lib syslib.l *~\n\n");
+  fclose(fp);
+}
+
+int main(int argc, char *argv[])
+{
+  write_makefile();
+  write_call_table();
+  exit(0);
+}