diff options
| author | Jyun-Yan You <jyyou@cs.nctu.edu.tw> | 2013-05-07 18:03:32 +0800 |
|---|---|---|
| committer | Jyun-Yan You <jyyou@cs.nctu.edu.tw> | 2013-05-09 16:51:42 +0800 |
| commit | c2bf9bf9fed8de0c399125feba8252ad263a71fc (patch) | |
| tree | 7b4795d84124bcf8eb6de69be5b908f7029f93c4 /src/rt/arch/mips | |
| parent | fda176b07046c25c67af978c20c3d4eda2068079 (diff) | |
| download | rust-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.S | 1 | ||||
| -rw-r--r-- | src/rt/arch/mips/morestack.S | 97 | ||||
| -rw-r--r-- | src/rt/arch/mips/record_sp.S | 8 |
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 |
