about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--mk/rt.mk3
-rw-r--r--src/rt/arch/i386/ccall.S14
-rw-r--r--src/rt/arch/i386/context.h1
-rw-r--r--src/rt/rustrt.def.in1
4 files changed, 18 insertions, 1 deletions
diff --git a/mk/rt.mk b/mk/rt.mk
index 41fa5eb9880..decbd1bc175 100644
--- a/mk/rt.mk
+++ b/mk/rt.mk
@@ -37,7 +37,8 @@ RUNTIME_CS := rt/sync/timer.cpp \
 
 RUNTIME_LL :=
 
-RUNTIME_S := rt/arch/i386/_context.S
+RUNTIME_S := rt/arch/i386/_context.S \
+             rt/arch/i386/ccall.S
 
 RUNTIME_HDR := rt/globals.h \
                rt/rust.h \
diff --git a/src/rt/arch/i386/ccall.S b/src/rt/arch/i386/ccall.S
new file mode 100644
index 00000000000..7adecc4c5d2
--- /dev/null
+++ b/src/rt/arch/i386/ccall.S
@@ -0,0 +1,14 @@
+    .text
+
+// upcall_call_c_stack(void (*fn)(), void *new_esp)
+.globl _upcall_call_c_stack
+_upcall_call_c_stack:
+    movl %esp,%ecx          // grab esp
+    movl 8(%esp),%eax       // save fn
+    movl 12(%esp),%esp      // switch stack
+    pushl %ecx              // save esp on stack
+    calll *%eax
+    popl %esp               // restore esp
+    ret
+
+
diff --git a/src/rt/arch/i386/context.h b/src/rt/arch/i386/context.h
index a31b4c48d14..9a225b79606 100644
--- a/src/rt/arch/i386/context.h
+++ b/src/rt/arch/i386/context.h
@@ -37,6 +37,7 @@ public:
 
   void swap(context &out);
   void call(void *f, void *arg, void *sp);
+  void call(void *f, void *sp);
 
   // Note that this doesn't actually adjust esp. Instead, we adjust esp when
   // we actually do the call. This is needed for exception safety -- if the
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index f5f75d61c94..d7caebe41a1 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -66,6 +66,7 @@ task_yield
 task_join
 unsupervise
 upcall_alloc_c_stack
+upcall_call_c_stack
 upcall_cmp_type
 upcall_dynastack_alloc
 upcall_dynastack_alloc_2