add m68k port
three ABIs are supported: the default with 68881 80-bit fpu format and results returned in floating point registers, softfloat-only with the same format, and coldfire fpu with IEEE single/double only. only the first is tested at all, and only under qemu which has fpu emulation bugs. basic functionality smoke tests have been performed for the most common arch-specific breakage via libc-test and qemu user-level emulation. some sysvipc failures remain, but are shared with other big endian archs and will be fixed separately.
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
#include <fenv.h>
|
||||
|
||||
#if __HAVE_68881__ || __mcffpu__
|
||||
|
||||
static unsigned getsr()
|
||||
{
|
||||
unsigned v;
|
||||
__asm__ __volatile__ ("fmove.l %%fpsr,%0" : "=dm"(v));
|
||||
return v;
|
||||
}
|
||||
|
||||
static void setsr(unsigned v)
|
||||
{
|
||||
__asm__ __volatile__ ("fmove.l %0,%%fpsr" : : "dm"(v));
|
||||
}
|
||||
|
||||
static unsigned getcr()
|
||||
{
|
||||
unsigned v;
|
||||
__asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=dm"(v));
|
||||
return v;
|
||||
}
|
||||
|
||||
static void setcr(unsigned v)
|
||||
{
|
||||
__asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "dm"(v));
|
||||
}
|
||||
|
||||
int feclearexcept(int mask)
|
||||
{
|
||||
if (mask & ~FE_ALL_EXCEPT) return -1;
|
||||
setsr(getsr() & ~mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int feraiseexcept(int mask)
|
||||
{
|
||||
if (mask & ~FE_ALL_EXCEPT) return -1;
|
||||
setsr(getsr() | mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fetestexcept(int mask)
|
||||
{
|
||||
return getsr() & mask;
|
||||
}
|
||||
|
||||
int fegetround(void)
|
||||
{
|
||||
return getcr() & FE_UPWARD;
|
||||
}
|
||||
|
||||
int __fesetround(int r)
|
||||
{
|
||||
setcr((getcr() & ~FE_UPWARD) | r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fegetenv(fenv_t *envp)
|
||||
{
|
||||
envp->__control_register = getcr();
|
||||
envp->__status_register = getsr();
|
||||
__asm__ __volatile__ ("fmove.l %%fpiar,%0"
|
||||
: "=dm"(envp->__instruction_address));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fesetenv(const fenv_t *envp)
|
||||
{
|
||||
static const fenv_t default_env = { 0 };
|
||||
if (envp == FE_DFL_ENV)
|
||||
envp = &default_env;
|
||||
setcr(envp->__control_register);
|
||||
setsr(envp->__status_register);
|
||||
__asm__ __volatile__ ("fmove.l %0,%%fpiar"
|
||||
: : "dm"(envp->__instruction_address));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "../fenv.c"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
.global __syscall
|
||||
.hidden __syscall
|
||||
.type __syscall,%function
|
||||
__syscall:
|
||||
movem.l %d2-%d5,-(%sp)
|
||||
movem.l 20(%sp),%d0-%d5/%a0
|
||||
trap #0
|
||||
movem.l (%sp)+,%d2-%d5
|
||||
rts
|
||||
@@ -0,0 +1,12 @@
|
||||
.text
|
||||
.global dlsym
|
||||
.hidden __dlsym
|
||||
.type dlsym,@function
|
||||
dlsym:
|
||||
move.l (%sp),-(%sp)
|
||||
move.l 12(%sp),-(%sp)
|
||||
move.l 12(%sp),-(%sp)
|
||||
lea __dlsym-.-8,%a1
|
||||
jsr (%pc,%a1)
|
||||
add.l #12,%sp
|
||||
rts
|
||||
@@ -0,0 +1,14 @@
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,@function
|
||||
.type longjmp,@function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
movea.l 4(%sp),%a0
|
||||
move.l 8(%sp),%d0
|
||||
bne 1f
|
||||
move.l #1,%d0
|
||||
1: movem.l (%a0),%d2-%d7/%a2-%a7
|
||||
fmovem.x 52(%a0),%fp2-%fp7
|
||||
move.l 48(%a0),(%sp)
|
||||
rts
|
||||
@@ -0,0 +1,18 @@
|
||||
.global ___setjmp
|
||||
.hidden ___setjmp
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
___setjmp:
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
movea.l 4(%sp),%a0
|
||||
movem.l %d2-%d7/%a2-%a7,(%a0)
|
||||
move.l (%sp),48(%a0)
|
||||
fmovem.x %fp2-%fp7,52(%a0)
|
||||
clr.l %d0
|
||||
rts
|
||||
@@ -0,0 +1,29 @@
|
||||
.global sigsetjmp
|
||||
.global __sigsetjmp
|
||||
.type sigsetjmp,@function
|
||||
.type __sigsetjmp,@function
|
||||
sigsetjmp:
|
||||
__sigsetjmp:
|
||||
move.l 8(%sp),%d0
|
||||
beq 1f
|
||||
|
||||
movea.l 4(%sp),%a1
|
||||
move.l (%sp)+,156(%a1)
|
||||
move.l %a2,156+4+8(%a1)
|
||||
movea.l %a1,%a2
|
||||
|
||||
.hidden ___setjmp
|
||||
lea ___setjmp-.-8,%a1
|
||||
jsr (%pc,%a1)
|
||||
|
||||
move.l 156(%a2),-(%sp)
|
||||
move.l %a2,4(%sp)
|
||||
move.l %d0,8(%sp)
|
||||
movea.l 156+4+8(%a2),%a2
|
||||
|
||||
.hidden __sigsetjmp_tail
|
||||
lea __sigsetjmp_tail-.-8,%a1
|
||||
jmp (%pc,%a1)
|
||||
|
||||
1: lea ___setjmp-.-8,%a1
|
||||
jmp (%pc,%a1)
|
||||
@@ -0,0 +1,8 @@
|
||||
.text
|
||||
.global __m68k_read_tp
|
||||
.type __m68k_read_tp,@function
|
||||
__m68k_read_tp:
|
||||
move.l #333,%d0
|
||||
trap #0
|
||||
move.l %d0,%a0
|
||||
rts
|
||||
@@ -0,0 +1,24 @@
|
||||
.text
|
||||
.global __clone
|
||||
.type __clone,@function
|
||||
__clone:
|
||||
movem.l %d2-%d5,-(%sp)
|
||||
move.l #120,%d0
|
||||
move.l 28(%sp),%d1
|
||||
move.l 24(%sp),%d2
|
||||
and.l #-16,%d2
|
||||
move.l 36(%sp),%d3
|
||||
move.l 44(%sp),%d4
|
||||
move.l 40(%sp),%d5
|
||||
move.l 20(%sp),%a0
|
||||
move.l 32(%sp),%a1
|
||||
trap #0
|
||||
tst.l %d0
|
||||
beq 1f
|
||||
movem.l (%sp)+,%d2-%d5
|
||||
rts
|
||||
1: move.l %a1,-(%sp)
|
||||
jsr (%a0)
|
||||
move.l #1,%d0
|
||||
trap #0
|
||||
clr.b 0
|
||||
@@ -0,0 +1,26 @@
|
||||
.text
|
||||
.global __cp_begin
|
||||
.hidden __cp_begin
|
||||
.global __cp_end
|
||||
.hidden __cp_end
|
||||
.global __cp_cancel
|
||||
.hidden __cp_cancel
|
||||
.hidden __cancel
|
||||
.global __syscall_cp_asm
|
||||
.hidden __syscall_cp_asm
|
||||
.type __syscall_cp_asm,@function
|
||||
__syscall_cp_asm:
|
||||
movem.l %d2-%d5,-(%sp)
|
||||
movea.l 20(%sp),%a0
|
||||
__cp_begin:
|
||||
move.l (%a0),%d0
|
||||
bne __cp_cancel
|
||||
movem.l 24(%sp),%d0-%d5/%a0
|
||||
trap #0
|
||||
__cp_end:
|
||||
movem.l (%sp)+,%d2-%d5
|
||||
rts
|
||||
__cp_cancel:
|
||||
movem.l (%sp)+,%d2-%d5
|
||||
move.l __cancel-.-8,%a1
|
||||
jmp (%pc,%a1)
|
||||
Reference in New Issue
Block a user