about summary refs log tree commit diff
path: root/src/rt
diff options
context:
space:
mode:
authorklutzy <klutzytheklutzy@gmail.com>2013-08-26 22:01:55 +0900
committerklutzy <klutzytheklutzy@gmail.com>2013-08-26 22:16:54 +0900
commit442f4a5f2ca6f7f4082c09968e0fd83601a50d2a (patch)
tree9ad67e23fcc2987c6500414796a36b4c454e7499 /src/rt
parent63e53b8af2f37f9eb8eda0087b02f8deba252c2f (diff)
Support Win64 context switching
This patch saves and restores win64's nonvolatile registers.
This patch also saves stack information of thread environment
block (TEB), which is at %gs:0x08 and %gs:0x10.
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/arch/x86_64/_context.S48
-rw-r--r--src/rt/arch/x86_64/regs.h36
2 files changed, 75 insertions, 9 deletions
diff --git a/src/rt/arch/x86_64/_context.S b/src/rt/arch/x86_64/_context.S
index a8af27e3e4f..857fe91c914 100644
--- a/src/rt/arch/x86_64/_context.S
+++ b/src/rt/arch/x86_64/_context.S
@@ -86,16 +86,40 @@ SWAP_REGISTERS:
         mov %r14, (RUSTRT_R14*8)(ARG0)
         mov %r15, (RUSTRT_R15*8)(ARG0)
 
+#if defined(__MINGW32__) || defined(_WINDOWS)
+        mov %rdi, (RUSTRT_RDI*8)(ARG0)
+        mov %rsi, (RUSTRT_RSI*8)(ARG0)
+
+        // Save stack range
+        mov %gs:0x08, %r8
+        mov %r8, (RUSTRT_ST1*8)(ARG0)
+        mov %gs:0x10, %r9
+        mov %r9, (RUSTRT_ST2*8)(ARG0)
+#endif
+
         // Save 0th argument register:
         mov ARG0, (RUSTRT_ARG0*8)(ARG0)
 
         // Save non-volatile XMM registers:
+#if defined(__MINGW32__) || defined(_WINDOWS)
+        movapd %xmm6, (RUSTRT_XMM6*8)(ARG0)
+        movapd %xmm7, (RUSTRT_XMM7*8)(ARG0)
+        movapd %xmm8, (RUSTRT_XMM8*8)(ARG0)
+        movapd %xmm9, (RUSTRT_XMM9*8)(ARG0)
+        movapd %xmm10, (RUSTRT_XMM10*8)(ARG0)
+        movapd %xmm11, (RUSTRT_XMM11*8)(ARG0)
+        movapd %xmm12, (RUSTRT_XMM12*8)(ARG0)
+        movapd %xmm13, (RUSTRT_XMM13*8)(ARG0)
+        movapd %xmm14, (RUSTRT_XMM14*8)(ARG0)
+        movapd %xmm15, (RUSTRT_XMM15*8)(ARG0)
+#else
         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)
+#endif
 
         // Restore non-volatile integer registers:
         //   (including RSP)
@@ -107,16 +131,40 @@ SWAP_REGISTERS:
         mov (RUSTRT_R14*8)(ARG1), %r14
         mov (RUSTRT_R15*8)(ARG1), %r15
 
+#if defined(__MINGW32__) || defined(_WINDOWS)
+        mov (RUSTRT_RDI*8)(ARG1), %rdi
+        mov (RUSTRT_RSI*8)(ARG1), %rsi
+
+        // Restore stack range
+        mov (RUSTRT_ST1*8)(ARG1), %r8
+        mov %r8, %gs:0x08
+        mov (RUSTRT_ST2*8)(ARG1), %r9
+        mov %r9, %gs:0x10
+#endif
+
         // Restore 0th argument register:
         mov (RUSTRT_ARG0*8)(ARG1), ARG0
 
         // Restore non-volatile XMM registers:
+#if defined(__MINGW32__) || defined(_WINDOWS)
+        movapd (RUSTRT_XMM6*8)(ARG1), %xmm6
+        movapd (RUSTRT_XMM7*8)(ARG1), %xmm7
+        movapd (RUSTRT_XMM8*8)(ARG1), %xmm8
+        movapd (RUSTRT_XMM9*8)(ARG1), %xmm9
+        movapd (RUSTRT_XMM10*8)(ARG1), %xmm10
+        movapd (RUSTRT_XMM11*8)(ARG1), %xmm11
+        movapd (RUSTRT_XMM12*8)(ARG1), %xmm12
+        movapd (RUSTRT_XMM13*8)(ARG1), %xmm13
+        movapd (RUSTRT_XMM14*8)(ARG1), %xmm14
+        movapd (RUSTRT_XMM15*8)(ARG1), %xmm15
+#else
         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
+#endif
 
         // Jump to the instruction pointer
         // found in regs:
diff --git a/src/rt/arch/x86_64/regs.h b/src/rt/arch/x86_64/regs.h
index 1aca452df10..cff47ac378a 100644
--- a/src/rt/arch/x86_64/regs.h
+++ b/src/rt/arch/x86_64/regs.h
@@ -18,15 +18,33 @@
 #define RUSTRT_R14   6
 #define RUSTRT_R15   7
 #define RUSTRT_IP    8
-// Not used, just padding
-#define RUSTRT_XXX   9
-#define RUSTRT_XMM0 10
-#define RUSTRT_XMM1 12
-#define RUSTRT_XMM2 14
-#define RUSTRT_XMM3 16
-#define RUSTRT_XMM4 18
-#define RUSTRT_XMM5 20
-#define RUSTRT_MAX  22
+#if defined(__MINGW32__) || defined(_WINDOWS)
+    #define RUSTRT_RDI   9
+    #define RUSTRT_RSI   10
+    #define RUSTRT_ST1   11
+    #define RUSTRT_ST2   12
+    #define RUSTRT_XMM6  14
+    #define RUSTRT_XMM7  16
+    #define RUSTRT_XMM8  18
+    #define RUSTRT_XMM9  20
+    #define RUSTRT_XMM10 22
+    #define RUSTRT_XMM11 24
+    #define RUSTRT_XMM12 26
+    #define RUSTRT_XMM13 28
+    #define RUSTRT_XMM14 30
+    #define RUSTRT_XMM15 32
+    #define RUSTRT_MAX   34
+#else
+    // Not used, just padding
+    #define RUSTRT_XXX   9
+    #define RUSTRT_XMM0 10
+    #define RUSTRT_XMM1 12
+    #define RUSTRT_XMM2 14
+    #define RUSTRT_XMM3 16
+    #define RUSTRT_XMM4 18
+    #define RUSTRT_XMM5 20
+    #define RUSTRT_MAX  22
+#endif
 
 // ARG0 is the register in which the first argument goes.
 // Naturally this depends on your operating system.