about summary refs log tree commit diff
path: root/src/rt
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2011-11-08 17:07:11 -0800
committerNiko Matsakis <niko@alum.mit.edu>2011-11-08 21:14:09 -0800
commitff5b319ce551e6b9b79ce8f127e25d26d0f4d085 (patch)
treebc4c8e307509232e0f599d7e39bb3b8815c77de7 /src/rt
parent2edd3135adcf4a3812487df75c503a95fbbc1a38 (diff)
downloadrust-ff5b319ce551e6b9b79ce8f127e25d26d0f4d085.tar.gz
rust-ff5b319ce551e6b9b79ce8f127e25d26d0f4d085.zip
correct stack alignment
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/arch/i386/regs.h2
-rw-r--r--src/rt/arch/x86_64/_context.S86
-rw-r--r--src/rt/arch/x86_64/context.cpp3
-rw-r--r--src/rt/arch/x86_64/context.h4
-rw-r--r--src/rt/arch/x86_64/regs.h (renamed from src/rt/arch/x86_64/x86_64_regs.h)24
5 files changed, 60 insertions, 59 deletions
diff --git a/src/rt/arch/i386/regs.h b/src/rt/arch/i386/regs.h
new file mode 100644
index 00000000000..80eacd80178
--- /dev/null
+++ b/src/rt/arch/i386/regs.h
@@ -0,0 +1,2 @@
+// This file is not used by i386, but we keep it here so all
+// architectures have the same set of header files.
diff --git a/src/rt/arch/x86_64/_context.S b/src/rt/arch/x86_64/_context.S
index 39df5b6610b..7fdc6114b0a 100644
--- a/src/rt/arch/x86_64/_context.S
+++ b/src/rt/arch/x86_64/_context.S
@@ -1,5 +1,7 @@
-#include "x86_64_regs.h"
-
+#include "regs.h"
+#define ARG0 RUSTRT_ARG0_S
+#define ARG1 RUSTRT_ARG1_S
+        
         .text
 
 /*
@@ -41,7 +43,10 @@ First four arguments:
 /*
         Stores current registers into arg0/RCX and restores
         registers found in arg1/RDX. This is used by our
-	    implementation of getcontext.
+	    implementation of getcontext.  Only saves/restores nonvolatile
+        registers and the register used for the first argument.
+        Volatile registers in general ought to be saved by the caller
+        anyhow.
 */	
 
 // swap_registers(registers_t *oregs, registers_t *regs)
@@ -56,60 +61,53 @@ swap_registers:
         // return address. We can therefore just return normally to
         // jump back into the old code.
 
-#       if defined(RUSTRT_ARG0_S)
-        mov RUSTRT_ARG0_S, %rdi
-        mov RUSTRT_ARG1_S, %rsi
-#       endif
-        
         // Save instruction pointer:
         pop %rax
-        mov %rax, (RUSTRT_IP*8)(%rdi)
+        mov %rax, (RUSTRT_IP*8)(RUSTRT_ARG0_S)
 
         // Save non-volatile integer registers:
         //   (including RSP)
-        mov %rbx, (RUSTRT_RBX*8)(%rdi)
-        mov %rsp, (RUSTRT_RSP*8)(%rdi)
-        mov %rbp, (RUSTRT_RBP*8)(%rdi)
-        mov %r12, (RUSTRT_R12*8)(%rdi)
-        mov %r13, (RUSTRT_R13*8)(%rdi)
-        mov %r14, (RUSTRT_R14*8)(%rdi)
-        mov %r15, (RUSTRT_R15*8)(%rdi)
-
-        // Save relevant argument registers:
-        mov %rcx, (RUSTRT_RCX*8)(%rdi)
-        mov %rdi, (RUSTRT_RDI*8)(%rdi)
+        mov %rbx, (RUSTRT_RBX*8)(ARG0)
+        mov %rsp, (RUSTRT_RSP*8)(ARG0)
+        mov %rbp, (RUSTRT_RBP*8)(ARG0)
+        mov %r12, (RUSTRT_R12*8)(ARG0)
+        mov %r13, (RUSTRT_R13*8)(ARG0)
+        mov %r14, (RUSTRT_R14*8)(ARG0)
+        mov %r15, (RUSTRT_R15*8)(ARG0)
+
+        // Save 0th argument register:
+        mov ARG0, (RUSTRT_ARG0*8)(ARG0)
 
         // Save non-volatile XMM registers:
-        movapd %xmm0, (RUSTRT_XMM0*8)(%rdi)
-        movapd %xmm1, (RUSTRT_XMM1*8)(%rdi)
-        movapd %xmm2, (RUSTRT_XMM2*8)(%rdi)
-        movapd %xmm3, (RUSTRT_XMM3*8)(%rdi)
-        movapd %xmm4, (RUSTRT_XMM4*8)(%rdi)
-        movapd %xmm5, (RUSTRT_XMM5*8)(%rdi)
+        movapd %xmm0, (RUSTRT_XMM0*8)(ARG0)
+        movapd %xmm1, (RUSTRT_XMM1*8)(ARG0)
+        movapd %xmm2, (RUSTRT_XMM2*8)(ARG0)
+        movapd %xmm3, (RUSTRT_XMM3*8)(ARG0)
+        movapd %xmm4, (RUSTRT_XMM4*8)(ARG0)
+        movapd %xmm5, (RUSTRT_XMM5*8)(ARG0)
 
         // Restore non-volatile integer registers:
         //   (including RSP)
-        mov (RUSTRT_RBX*8)(%rsi), %rbx
-        mov (RUSTRT_RSP*8)(%rsi), %rsp
-        mov (RUSTRT_RBP*8)(%rsi), %rbp
-        mov (RUSTRT_R12*8)(%rsi), %r12
-        mov (RUSTRT_R13*8)(%rsi), %r13
-        mov (RUSTRT_R14*8)(%rsi), %r14
-        mov (RUSTRT_R15*8)(%rsi), %r15
-
-        // Restore relevant argument registers:
-        mov (RUSTRT_RCX*8)(%rsi), %rcx
-        mov (RUSTRT_RDI*8)(%rsi), %rdi
+        mov (RUSTRT_RBX*8)(ARG1), %rbx
+        mov (RUSTRT_RSP*8)(ARG1), %rsp
+        mov (RUSTRT_RBP*8)(ARG1), %rbp
+        mov (RUSTRT_R12*8)(ARG1), %r12
+        mov (RUSTRT_R13*8)(ARG1), %r13
+        mov (RUSTRT_R14*8)(ARG1), %r14
+        mov (RUSTRT_R15*8)(ARG1), %r15
+
+        // Restore 0th argument register:
+        mov (RUSTRT_ARG0*8)(ARG1), ARG0
 
         // Restore non-volatile XMM registers:
-        movapd (RUSTRT_XMM0*8)(%rsi), %xmm0
-        movapd (RUSTRT_XMM1*8)(%rsi), %xmm1
-        movapd (RUSTRT_XMM2*8)(%rsi), %xmm2
-        movapd (RUSTRT_XMM3*8)(%rsi), %xmm3
-        movapd (RUSTRT_XMM4*8)(%rsi), %xmm4
-        movapd (RUSTRT_XMM5*8)(%rsi), %xmm5
+        movapd (RUSTRT_XMM0*8)(ARG1), %xmm0
+        movapd (RUSTRT_XMM1*8)(ARG1), %xmm1
+        movapd (RUSTRT_XMM2*8)(ARG1), %xmm2
+        movapd (RUSTRT_XMM3*8)(ARG1), %xmm3
+        movapd (RUSTRT_XMM4*8)(ARG1), %xmm4
+        movapd (RUSTRT_XMM5*8)(ARG1), %xmm5
 
         // Jump to the instruction pointer
         // found in regs:
-        jmp *(RUSTRT_IP*8)(%rsi)
+        jmp *(RUSTRT_IP*8)(ARG1)
 
diff --git a/src/rt/arch/x86_64/context.cpp b/src/rt/arch/x86_64/context.cpp
index 09577dbd151..d9070c6385a 100644
--- a/src/rt/arch/x86_64/context.cpp
+++ b/src/rt/arch/x86_64/context.cpp
@@ -26,8 +26,9 @@ void context::call(void *f, void *arg, void *stack) {
   swap(*this);
 
   // set up the stack
-  uint32_t *sp = (uint32_t *)stack;
+  uint64_t *sp = (uint64_t *)stack;
   sp = align_down(sp);
+  *--sp = 0xdeadbeef; // takes place of ret. addr.
 
   regs.data[RUSTRT_ARG0] = (uint64_t)arg;
   regs.data[RUSTRT_RSP] = (uint64_t)sp;
diff --git a/src/rt/arch/x86_64/context.h b/src/rt/arch/x86_64/context.h
index 5d764cfdb0a..3f01a4479d7 100644
--- a/src/rt/arch/x86_64/context.h
+++ b/src/rt/arch/x86_64/context.h
@@ -23,8 +23,8 @@ T align_down(T sp)
 // The struct in which we store the saved data.  This is mostly the
 // volatile registers and instruction pointer, but it also includes
 // RCX/RDI which are used to pass arguments.  The indices for each
-// register are found in <x86_64_regs.h>:
-#include "x86_64_regs.h"
+// register are found in "regs.h":
+#include "regs.h"
 struct registers_t {
     uint64_t data[RUSTRT_MAX];
 };
diff --git a/src/rt/arch/x86_64/x86_64_regs.h b/src/rt/arch/x86_64/regs.h
index 084ab03fdc4..7d090ff5b27 100644
--- a/src/rt/arch/x86_64/x86_64_regs.h
+++ b/src/rt/arch/x86_64/regs.h
@@ -1,13 +1,13 @@
-#define RUSTRT_RBX  0
-#define RUSTRT_RSP  1
-#define RUSTRT_RBP  2
-#define RUSTRT_RDI  3
-#define RUSTRT_RCX  4
-#define RUSTRT_R12  5
-#define RUSTRT_R13  6
-#define RUSTRT_R14  7
-#define RUSTRT_R15  8
-#define RUSTRT_IP   9
+#define RUSTRT_RBX   0
+#define RUSTRT_RSP   1
+#define RUSTRT_RBP   2
+#define RUSTRT_ARG0  3 // RCX on Windows, RDI elsewhere
+#define RUSTRT_R12   4
+#define RUSTRT_R13   5
+#define RUSTRT_R14   6
+#define RUSTRT_R15   7
+#define RUSTRT_IP    8
+#define RUSTRT_XXX   9 // Not used, just padding
 #define RUSTRT_XMM0 10
 #define RUSTRT_XMM1 12
 #define RUSTRT_XMM2 14
@@ -19,11 +19,11 @@
 // ARG0 is the register in which the first argument goes.
 // Naturally this depends on your operating system.
 #if defined(__MINGW32__) || defined(_WINDOWS)
-#   define RUSTRT_ARG0 RUSTRT_RCX  
 #   define RUSTRT_ARG0_S %rcx
 #   define RUSTRT_ARG1_S %rdx
 #else
-#   define RUSTRT_ARG0 RUSTRT_RDI  
+#   define RUSTRT_ARG0_S %rdi
+#   define RUSTRT_ARG1_S %rsi
 #endif