From 5972c4a4113e2a4de5edf519faf15296ae1eb3ed Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Mon, 18 Apr 2016 05:19:13 +0000 Subject: add mips n32 port (ILP32 ABI for mips64) based on patch submitted by Jaydeep Patil, with minor changes. --- src/fenv/mipsn32/fenv-sf.c | 3 ++ src/fenv/mipsn32/fenv.S | 70 ++++++++++++++++++++++++++++++++++++++++ src/internal/mipsn32/syscall.s | 19 +++++++++++ src/ldso/mipsn32/dlsym.s | 17 ++++++++++ src/setjmp/mipsn32/longjmp.S | 36 +++++++++++++++++++++ src/setjmp/mipsn32/setjmp.S | 34 +++++++++++++++++++ src/signal/mipsn32/restore.s | 9 ++++++ src/signal/mipsn32/sigsetjmp.s | 38 ++++++++++++++++++++++ src/thread/mipsn32/__unmapself.s | 9 ++++++ src/thread/mipsn32/clone.s | 30 +++++++++++++++++ src/thread/mipsn32/syscall_cp.s | 51 +++++++++++++++++++++++++++++ src/unistd/mipsn32/pipe.s | 19 +++++++++++ 12 files changed, 335 insertions(+) create mode 100644 src/fenv/mipsn32/fenv-sf.c create mode 100644 src/fenv/mipsn32/fenv.S create mode 100644 src/internal/mipsn32/syscall.s create mode 100644 src/ldso/mipsn32/dlsym.s create mode 100644 src/setjmp/mipsn32/longjmp.S create mode 100644 src/setjmp/mipsn32/setjmp.S create mode 100644 src/signal/mipsn32/restore.s create mode 100644 src/signal/mipsn32/sigsetjmp.s create mode 100644 src/thread/mipsn32/__unmapself.s create mode 100644 src/thread/mipsn32/clone.s create mode 100644 src/thread/mipsn32/syscall_cp.s create mode 100644 src/unistd/mipsn32/pipe.s (limited to 'src') diff --git a/src/fenv/mipsn32/fenv-sf.c b/src/fenv/mipsn32/fenv-sf.c new file mode 100644 index 00000000..4aa3dbf1 --- /dev/null +++ b/src/fenv/mipsn32/fenv-sf.c @@ -0,0 +1,3 @@ +#ifdef __mips_soft_float +#include "../fenv.c" +#endif diff --git a/src/fenv/mipsn32/fenv.S b/src/fenv/mipsn32/fenv.S new file mode 100644 index 00000000..cce6436b --- /dev/null +++ b/src/fenv/mipsn32/fenv.S @@ -0,0 +1,70 @@ +#ifndef __mips_soft_float + +.set noreorder +.global feclearexcept +.type feclearexcept,@function +feclearexcept: + and $4, $4, 0x7c + cfc1 $5, $31 + or $5, $5, $4 + xor $5, $5, $4 + ctc1 $5, $31 + jr $ra + li $2, 0 + +.global feraiseexcept +.type feraiseexcept,@function +feraiseexcept: + and $4, $4, 0x7c + cfc1 $5, $31 + or $5, $5, $4 + ctc1 $5, $31 + jr $ra + li $2, 0 + +.global fetestexcept +.type fetestexcept,@function +fetestexcept: + and $4, $4, 0x7c + cfc1 $2, $31 + jr $ra + and $2, $2, $4 + +.global fegetround +.type fegetround,@function +fegetround: + cfc1 $2, $31 + jr $ra + andi $2, $2, 3 + +.global __fesetround +.type __fesetround,@function +__fesetround: + cfc1 $5, $31 + li $6, -4 + and $5, $5, $6 + or $5, $5, $4 + ctc1 $5, $31 + jr $ra + li $2, 0 + +.global fegetenv +.type fegetenv,@function +fegetenv: + cfc1 $5, $31 + sw $5, 0($4) + jr $ra + li $2, 0 + +.global fesetenv +.type fesetenv,@function +fesetenv: + addiu $5, $4, 1 + beq $5, $0, 1f + nop + lw $5, 0($4) +1: ctc1 $5, $31 + jr $ra + li $2, 0 + +#endif diff --git a/src/internal/mipsn32/syscall.s b/src/internal/mipsn32/syscall.s new file mode 100644 index 00000000..510a6fa4 --- /dev/null +++ b/src/internal/mipsn32/syscall.s @@ -0,0 +1,19 @@ +.set noreorder +.global __syscall +.hidden __syscall +.type __syscall,@function +__syscall: + move $2, $4 + move $4, $5 + move $5, $6 + move $6, $7 + move $7, $8 + move $8, $9 + move $9, $10 + move $10, $11 + syscall + beq $7, $0, 1f + nop + subu $2, $0, $2 +1: jr $ra + nop diff --git a/src/ldso/mipsn32/dlsym.s b/src/ldso/mipsn32/dlsym.s new file mode 100644 index 00000000..1c82da30 --- /dev/null +++ b/src/ldso/mipsn32/dlsym.s @@ -0,0 +1,17 @@ +.set noreorder +.global dlsym +.hidden __dlsym +.type dlsym,@function +dlsym: + lui $3, %hi(%neg(%gp_rel(dlsym))) + addiu $3, $3, %lo(%neg(%gp_rel(dlsym))) + addu $3, $3, $25 + move $6, $ra + lw $25, %got_disp(__dlsym)($3) + addiu $sp, $sp, -32 + sd $ra, 16($sp) + jalr $25 + nop + ld $ra, 16($sp) + jr $ra + addiu $sp, $sp, 32 diff --git a/src/setjmp/mipsn32/longjmp.S b/src/setjmp/mipsn32/longjmp.S new file mode 100644 index 00000000..30c3ee0b --- /dev/null +++ b/src/setjmp/mipsn32/longjmp.S @@ -0,0 +1,36 @@ +.set noreorder +.global _longjmp +.global longjmp +.type _longjmp,@function +.type longjmp,@function +_longjmp: +longjmp: + move $2, $5 + bne $2, $0, 1f + nop + addu $2, $2, 1 +1: +#ifndef __mips_soft_float + ldc1 $24, 96($4) + ldc1 $25, 104($4) + ldc1 $26, 112($4) + ldc1 $27, 120($4) + ldc1 $28, 128($4) + ldc1 $29, 136($4) + ldc1 $30, 144($4) + ldc1 $31, 152($4) +#endif + ld $ra, 0($4) + ld $sp, 8($4) + ld $gp, 16($4) + ld $16, 24($4) + ld $17, 32($4) + ld $18, 40($4) + ld $19, 48($4) + ld $20, 56($4) + ld $21, 64($4) + ld $22, 72($4) + ld $23, 80($4) + ld $30, 88($4) + jr $ra + nop diff --git a/src/setjmp/mipsn32/setjmp.S b/src/setjmp/mipsn32/setjmp.S new file mode 100644 index 00000000..b9646c2a --- /dev/null +++ b/src/setjmp/mipsn32/setjmp.S @@ -0,0 +1,34 @@ +.set noreorder +.global __setjmp +.global _setjmp +.global setjmp +.type __setjmp,@function +.type _setjmp,@function +.type setjmp,@function +__setjmp: +_setjmp: +setjmp: + sd $ra, 0($4) + sd $sp, 8($4) + sd $gp, 16($4) + sd $16, 24($4) + sd $17, 32($4) + sd $18, 40($4) + sd $19, 48($4) + sd $20, 56($4) + sd $21, 64($4) + sd $22, 72($4) + sd $23, 80($4) + sd $30, 88($4) +#ifndef __mips_soft_float + sdc1 $24, 96($4) + sdc1 $25, 104($4) + sdc1 $26, 112($4) + sdc1 $27, 120($4) + sdc1 $28, 128($4) + sdc1 $29, 136($4) + sdc1 $30, 144($4) + sdc1 $31, 152($4) +#endif + jr $ra + li $2, 0 diff --git a/src/signal/mipsn32/restore.s b/src/signal/mipsn32/restore.s new file mode 100644 index 00000000..0d1c1c5e --- /dev/null +++ b/src/signal/mipsn32/restore.s @@ -0,0 +1,9 @@ +.set noreorder +.global __restore_rt +.global __restore +.type __restore_rt,@function +.type __restore,@function +__restore_rt: +__restore: + li $2,6211 + syscall diff --git a/src/signal/mipsn32/sigsetjmp.s b/src/signal/mipsn32/sigsetjmp.s new file mode 100644 index 00000000..c0c6961f --- /dev/null +++ b/src/signal/mipsn32/sigsetjmp.s @@ -0,0 +1,38 @@ +.set noreorder +.global sigsetjmp +.global __sigsetjmp +.type sigsetjmp,@function +.type __sigsetjmp,@function +sigsetjmp: +__sigsetjmp: + lui $3, %hi(%neg(%gp_rel(sigsetjmp))) + addiu $3, $3, %lo(%neg(%gp_rel(sigsetjmp))) + + # comparing save mask with 0, if equals to 0 then + # sigsetjmp is equal to setjmp. + beq $5, $0, 1f + addu $3, $3, $25 + sd $ra, 160($4) + sd $16, 168($4) + + # save base of got so that we can use it later + # once we return from 'longjmp' + sd $3, 176($4) + lw $25, %got_disp(setjmp)($3) + jalr $25 + move $16, $4 + + move $5, $2 # Return from 'setjmp' or 'longjmp' + move $4, $16 # Restore the pointer-to-sigjmp_buf + ld $ra, 160($4) # Restore ra of sigsetjmp + ld $16, 168($4) # Restore $16 of sigsetjmp + ld $3, 176($4) # Restore base of got + +.hidden __sigsetjmp_tail + lw $25, %got_disp(__sigsetjmp_tail)($3) + jr $25 + nop +1: + lw $25, %got_disp(setjmp)($3) + jr $25 + nop diff --git a/src/thread/mipsn32/__unmapself.s b/src/thread/mipsn32/__unmapself.s new file mode 100644 index 00000000..4b032e5e --- /dev/null +++ b/src/thread/mipsn32/__unmapself.s @@ -0,0 +1,9 @@ +.set noreorder +.global __unmapself +.type __unmapself,@function +__unmapself: + li $2, 6011 + syscall + li $4, 0 + li $2, 6058 + syscall diff --git a/src/thread/mipsn32/clone.s b/src/thread/mipsn32/clone.s new file mode 100644 index 00000000..51035852 --- /dev/null +++ b/src/thread/mipsn32/clone.s @@ -0,0 +1,30 @@ +.set noreorder +.global __clone +.type __clone,@function +__clone: + # Save function pointer and argument pointer on new thread stack + and $5, $5, -16 # aligning stack to double word + subu $5, $5, 16 + sw $4, 0($5) # save function pointer + sw $7, 4($5) # save argument pointer + + # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid) + # sys_clone(u64 flags, u64 ustack_base, u64 parent_tidptr, u64 child_tidptr, u64 tls) + move $4, $6 + move $6, $8 + move $7, $9 + move $8, $10 + li $2, 6055 + syscall + beq $7, $0, 1f + nop + jr $ra + subu $2, $0, $2 +1: beq $2, $0, 1f + nop + jr $ra + nop +1: lw $25, 0($sp) # function pointer + lw $4, 4($sp) # argument pointer + jr $25 # call the user's function + nop diff --git a/src/thread/mipsn32/syscall_cp.s b/src/thread/mipsn32/syscall_cp.s new file mode 100644 index 00000000..e85615bc --- /dev/null +++ b/src/thread/mipsn32/syscall_cp.s @@ -0,0 +1,51 @@ +.set noreorder +.global __cp_begin +.hidden __cp_begin +.type __cp_begin,@function +.global __cp_end +.hidden __cp_end +.type __cp_end,@function +.global __cp_cancel +.hidden __cp_cancel +.type __cp_cancel,@function +.global __cp_cancel_data +.hidden __cp_cancel_data +.type __cp_cancel_data,@function +.hidden __cancel +.global __syscall_cp_asm +.hidden __syscall_cp_asm +.type __syscall_cp_asm,@function +__syscall_cp_asm: +__cp_begin: + lw $4, 0($4) + bne $4, $0, __cp_cancel + move $2, $5 + move $4, $6 + move $5, $7 + move $6, $8 + move $7, $9 + move $8, $10 + move $9, $11 + lw $10, 0($sp) + syscall +__cp_end: + beq $7, $0, 1f + nop + subu $2, $0, $2 +1: jr $ra + nop + + # if cancellation flag is 1 then call __cancel +__cp_cancel: + move $2, $ra + bal 1f + nop +__cp_cancel_data: + .gpword __cp_cancel_data + .gpword __cancel +1: lw $3, 0($ra) + subu $3, $ra, $3 + lw $25, 4($ra) + addu $25, $25, $3 + jr $25 + move $ra, $2 diff --git a/src/unistd/mipsn32/pipe.s b/src/unistd/mipsn32/pipe.s new file mode 100644 index 00000000..80f882e2 --- /dev/null +++ b/src/unistd/mipsn32/pipe.s @@ -0,0 +1,19 @@ +.set noreorder +.global pipe +.type pipe,@function +pipe: + lui $3, %hi(%neg(%gp_rel(pipe))) + addiu $3, $3, %lo(%neg(%gp_rel(pipe))) + addu $3, $3, $25 + li $2, 6021 + syscall + beq $7, $0, 1f + nop + lw $25, %got_disp(__syscall_ret)($3) + jr $25 + subu $4, $0, $2 +1: sw $2, 0($4) + sw $3, 4($4) + move $2, $0 + jr $ra + nop -- cgit 1.4.1