about summary refs log tree commit diff
path: root/src/rt/arch/arm/morestack.S
diff options
context:
space:
mode:
authorILyoan <ilyoan@gmail.com>2013-02-22 15:17:54 +0900
committerBrian Anderson <banderson@mozilla.com>2013-04-10 18:49:50 -0700
commit3d0d144283959bf62368f6965aae14ce95ee286b (patch)
tree19a9f762bc6d0c04922d3a7314c865e1f3a8521f /src/rt/arch/arm/morestack.S
parent4b4f48283bdd71fa106f1e2ce80c6d2a0d2aff36 (diff)
downloadrust-3d0d144283959bf62368f6965aae14ce95ee286b.tar.gz
rust-3d0d144283959bf62368f6965aae14ce95ee286b.zip
rust morestack assembly for arm
Conflicts:
	src/rt/arch/arm/morestack.S
Diffstat (limited to 'src/rt/arch/arm/morestack.S')
-rw-r--r--src/rt/arch/arm/morestack.S55
1 files changed, 54 insertions, 1 deletions
diff --git a/src/rt/arch/arm/morestack.S b/src/rt/arch/arm/morestack.S
index 1afce5bd848..3af8e898cdb 100644
--- a/src/rt/arch/arm/morestack.S
+++ b/src/rt/arch/arm/morestack.S
@@ -8,6 +8,59 @@
 .arm
 .align
 
-.globl __morestack
+.global upcall_new_stack
+.global upcall_del_stack
+.global __morestack
 .hidden __morestack
+
+// r4 and r5 are scratch registers for __morestack due to llvm
+// ARMFrameLowering::adjustForSegmentedStacks() implementation.
+    .align 2
+    .type __morestack,%function
 __morestack:
+
+    // Save frame pointer and return address
+    push {fp, lr}
+    
+    mov fp, sp
+
+    // Save argument registers of the original function
+    push {r0, r1, r2, r3, lr}
+
+    mov r0, r4         // The amount of stack needed
+    add r1, fp, #20    // Address of stack arguments
+    mov r2, r5         // Size of stack arguments
+    
+    // Create new stack
+    bl upcall_new_stack@plt
+
+    // Hold new stack pointer
+    mov r5, r0
+
+    // Pop the saved arguments
+    pop {r0, r1, r2, r3, lr}
+
+    // Grab the return pointer
+    add r4, lr, #16    // Skip past the return
+    mov sp, r5         // Swich to the new stack
+    mov lr, pc
+    mov pc, r4         // Call the original function
+
+    // Switch back to rust stack
+    mov sp, fp
+
+    // Save return value
+    push {r0, r1}
+
+    // Remove the new allocated stack
+    bl upcall_del_stack@plt
+
+    // Restore return value
+    pop {r0, r1}
+
+    // Return
+    pop {fp, lr}
+    mov pc, lr
+.endofmorestack:
+    .size   __morestack, .endofmorestack-__morestack
+