summaryrefslogtreecommitdiff
path: root/emu/Linux/asm-386.S
diff options
context:
space:
mode:
Diffstat (limited to 'emu/Linux/asm-386.S')
-rw-r--r--emu/Linux/asm-386.S109
1 files changed, 109 insertions, 0 deletions
diff --git a/emu/Linux/asm-386.S b/emu/Linux/asm-386.S
new file mode 100644
index 00000000..caa1f79a
--- /dev/null
+++ b/emu/Linux/asm-386.S
@@ -0,0 +1,109 @@
+ .file "asm-Linux-386.S"
+#include "syscall.h"
+ .text
+
+/*
+ * executeonnewstack(void *tos, void (*tramp)(void *arg), void *arg)
+ */
+
+ .type executeonnewstack,@function
+ .global executeonnewstack
+executeonnewstack:
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %esi
+
+ movl 8(%ebp), %esi /* get tos */
+ subl $4, %esi
+ movl 16(%ebp), %eax
+ movl %eax, (%esi) /* stash arg on new stack */
+ subl $4, %esi
+ movl 12(%ebp), %eax
+ movl %eax, (%esi) /* stash tramp on new stack */
+ mov %esi, %esp /* swap stacks pronto */
+ popl %eax /* recover the tramp address */
+ subl %ebp, %ebp /* stop stack traceback here */
+ call *%eax /* and jump to it (ho ho) */
+
+ /* if we return here, tramp didn't do its job */
+
+ addl $8, %esp /* clean up for pose value */
+
+ leal SYS_exit, %eax
+ int $0x80
+
+/*
+ * unlockandexit(int *key)
+ *
+ * NB: the return status may be garbaged if the stack is reused
+ * between the unlock and the system call, but this should
+ * not matter since no task is waiting for the result
+ */
+
+ .type unlockandexit,@function
+ .global unlockandexit
+unlockandexit:
+ pushl %ebp
+ movl %esp, %ebp
+
+ movl 8(%ebp), %esi /* get the key address */
+ pushl $0 /* exit status 0 */
+ movl $0, %eax /* unlock the stack allocator */
+ movl %eax, (%esi)
+ leal SYS_exit, %eax /* call exit */
+ int $0x80
+
+/*
+ * umult(ulong m1, ulong m2, ulong *hi)
+ */
+
+ .type umult,@function
+ .global umult
+umult:
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %ebx
+
+ movl 8(%ebp), %eax
+ movl 12(%ebp), %ebx
+ mull %ebx
+ movl 16(%ebp), %ebx
+ movl %edx, (%ebx)
+
+ popl %ebx
+ popl %ebp
+ ret
+
+ .type FPsave,@function
+ .global FPsave
+FPsave:
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax
+ fstenv (%eax)
+ popl %ebp
+ ret
+
+ .type FPrestore,@function
+ .global FPrestore
+FPrestore:
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax
+ fldenv (%eax)
+ popl %ebp
+ ret
+
+ .type getcallerpc,@function
+ .global getcallerpc
+getcallerpc:
+ movl 4(%ebp), %eax
+ ret
+
+ .type _tas,@function
+ .globl _tas
+_tas:
+ movl $1, %eax
+ movl 4(%esp), %ecx
+ xchgl %eax, 0(%ecx)
+ ret