about summary refs log tree commit diff
path: root/src/rt/arch/mips
diff options
context:
space:
mode:
authorJyun-Yan You <jyyou@cs.nctu.edu.tw>2013-05-07 18:03:32 +0800
committerJyun-Yan You <jyyou@cs.nctu.edu.tw>2013-05-09 16:51:42 +0800
commitc2bf9bf9fed8de0c399125feba8252ad263a71fc (patch)
tree7b4795d84124bcf8eb6de69be5b908f7029f93c4 /src/rt/arch/mips
parentfda176b07046c25c67af978c20c3d4eda2068079 (diff)
downloadrust-c2bf9bf9fed8de0c399125feba8252ad263a71fc.tar.gz
rust-c2bf9bf9fed8de0c399125feba8252ad263a71fc.zip
improve MIPS backend and implement segmented stacks
Diffstat (limited to 'src/rt/arch/mips')
-rw-r--r--src/rt/arch/mips/ccall.S1
-rw-r--r--src/rt/arch/mips/morestack.S97
-rw-r--r--src/rt/arch/mips/record_sp.S8
3 files changed, 101 insertions, 5 deletions
diff --git a/src/rt/arch/mips/ccall.S b/src/rt/arch/mips/ccall.S
index abbbad164fd..cdcdc07db55 100644
--- a/src/rt/arch/mips/ccall.S
+++ b/src/rt/arch/mips/ccall.S
@@ -8,7 +8,6 @@
 .align 2
 .globl __morestack
 .hidden __morestack
-.cfi_sections .eh_frame_entry
 .cfi_startproc
 .set nomips16
 .ent __morestack
diff --git a/src/rt/arch/mips/morestack.S b/src/rt/arch/mips/morestack.S
new file mode 100644
index 00000000000..e534ac05913
--- /dev/null
+++ b/src/rt/arch/mips/morestack.S
@@ -0,0 +1,97 @@
+// Mark stack as non-executable
+#if defined(__linux__) && defined(__ELF__)
+.section        .note.GNU-stack, "", @progbits
+#endif
+
+.text
+
+.globl upcall_new_stack
+.globl upcall_del_stack
+.globl __morestack
+
+.hidden __morestack
+
+.cfi_startproc
+.set nomips16
+.ent __morestack
+__morestack:
+        .set noreorder
+        .set nomacro
+
+        addiu $29, $29, -12
+        sw $31, 8($29)
+        sw $30, 4($29)
+        sw $23, 0($29)
+
+        // 24 = 12 (current) + 12 (previous)
+        .cfi_def_cfa_offset 24
+        .cfi_offset 31, -4
+        .cfi_offset 30, -20
+        .cfi_offset 23, -24
+
+        move $23, $28
+        move $30, $29
+        .cfi_def_cfa_register 30
+
+        // Save argument registers of the original function
+        addiu $29, $29, -32
+        sw $4, 16($29)
+        sw $5, 20($29)
+        sw $6, 24($29)
+        sw $7, 28($29)
+
+        move $4, $14     // Size of stack arguments
+        addu $5, $30, 24 // Address of stack arguments
+        move $6, $15     // The amount of stack needed
+
+        move $28, $23
+        lw $25, %call16(upcall_new_stack)($23)
+        jalr $25
+        nop
+
+        // Pop the saved arguments
+        lw $4, 16($29)
+        lw $5, 20($29)
+        lw $6, 24($29)
+        lw $7, 28($29)
+        addiu $29, $29, 32
+
+        lw $24, 8($30)     // Grab the return pointer.
+        addiu $24, $24, 12 // Skip past the `lw`, `jr`, `addiu` in our parent frame
+        move $29, $2       // Switch to the new stack.
+
+        // for PIC
+        lw $2, 12($30)
+        lw $25, 16($30)
+
+        move $28, $23
+        jalr $24           // Reenter the caller function
+        nop
+
+        // Switch back to the rust stack
+        move $29, $30
+
+        // Save the return value
+        addiu $29, $29, -24
+        sw $2, 16($29)
+        sw $3, 20($29)
+
+        move $28, $23
+        lw $25, %call16(upcall_del_stack)($23)
+        jalr $25
+        nop
+
+        // Restore the return value
+        lw $2, 16($29)
+        lw $3, 20($29)
+        addiu $29, $29, 24
+
+        lw $31, 8($29)
+        lw $30, 4($29)
+        lw $23, 0($29)
+        addiu $29, $29, 12
+
+        jr $31
+        nop
+.end __morestack
+.cfi_endproc
diff --git a/src/rt/arch/mips/record_sp.S b/src/rt/arch/mips/record_sp.S
index dd4d2f39375..a88fefead04 100644
--- a/src/rt/arch/mips/record_sp.S
+++ b/src/rt/arch/mips/record_sp.S
@@ -16,8 +16,8 @@ record_sp_limit:
         .set mips32r2
         rdhwr $3, $29
         .set pop
-        addiu $3, $3, -0x7008
-        sw $4, 4($3)
+        addiu $3, $3, -0x7004
+        sw $4, 0($3)
         jr $31
         nop
 .end record_sp_limit
@@ -33,8 +33,8 @@ get_sp_limit:
         .set mips32r2
         rdhwr $3, $29
         .set pop
-        addiu $3, $3, -0x7008
-        lw $2, 4($3)
+        addiu $3, $3, -0x7004
+        lw $2, 0($3)
         jr $31
         nop
 .end get_sp_limit