mirror of
https://github.com/fluencelabs/musl
synced 2025-06-25 20:51:53 +00:00
add powerpc64 port
This commit is contained in:
committed by
Rich Felker
parent
6bc7d9c411
commit
c0ede9e404
68
src/fenv/powerpc64/fenv.c
Normal file
68
src/fenv/powerpc64/fenv.c
Normal file
@ -0,0 +1,68 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <fenv.h>
|
||||
|
||||
static inline double get_fpscr_f(void)
|
||||
{
|
||||
double d;
|
||||
__asm__ __volatile__("mffs %0" : "=d"(d));
|
||||
return d;
|
||||
}
|
||||
|
||||
static inline long get_fpscr(void)
|
||||
{
|
||||
return (union {double f; long i;}) {get_fpscr_f()}.i;
|
||||
}
|
||||
|
||||
static inline void set_fpscr_f(double fpscr)
|
||||
{
|
||||
__asm__ __volatile__("mtfsf 255, %0" : : "d"(fpscr));
|
||||
}
|
||||
|
||||
static void set_fpscr(long fpscr)
|
||||
{
|
||||
set_fpscr_f((union {long i; double f;}) {fpscr}.f);
|
||||
}
|
||||
|
||||
int feclearexcept(int mask)
|
||||
{
|
||||
mask &= FE_ALL_EXCEPT;
|
||||
if (mask & FE_INVALID) mask |= FE_ALL_INVALID;
|
||||
set_fpscr(get_fpscr() & ~mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int feraiseexcept(int mask)
|
||||
{
|
||||
mask &= FE_ALL_EXCEPT;
|
||||
if (mask & FE_INVALID) mask |= FE_INVALID_SOFTWARE;
|
||||
set_fpscr(get_fpscr() | mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fetestexcept(int mask)
|
||||
{
|
||||
return get_fpscr() & mask & FE_ALL_EXCEPT;
|
||||
}
|
||||
|
||||
int fegetround(void)
|
||||
{
|
||||
return get_fpscr() & 3;
|
||||
}
|
||||
|
||||
int __fesetround(int r)
|
||||
{
|
||||
set_fpscr(get_fpscr() & ~3L | r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fegetenv(fenv_t *envp)
|
||||
{
|
||||
*envp = get_fpscr_f();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fesetenv(const fenv_t *envp)
|
||||
{
|
||||
set_fpscr_f(envp != FE_DFL_ENV ? *envp : 0);
|
||||
return 0;
|
||||
}
|
17
src/internal/powerpc64/syscall.s
Normal file
17
src/internal/powerpc64/syscall.s
Normal file
@ -0,0 +1,17 @@
|
||||
.global __syscall
|
||||
.hidden __syscall
|
||||
.type __syscall,@function
|
||||
__syscall:
|
||||
mr 0, 3 # Save the system call number
|
||||
mr 3, 4 # Shift the arguments: arg1
|
||||
mr 4, 5 # arg2
|
||||
mr 5, 6 # arg3
|
||||
mr 6, 7 # arg4
|
||||
mr 7, 8 # arg5
|
||||
mr 8, 9 # arg6
|
||||
sc
|
||||
bnslr+ # return if not summary overflow
|
||||
neg 3, 3 # otherwise error: return negated value.
|
||||
blr
|
||||
.end __syscall
|
||||
.size __syscall, .-__syscall
|
12
src/ldso/powerpc64/dlsym.s
Normal file
12
src/ldso/powerpc64/dlsym.s
Normal file
@ -0,0 +1,12 @@
|
||||
.text
|
||||
.global dlsym
|
||||
.hidden __dlsym
|
||||
.type dlsym,@function
|
||||
dlsym:
|
||||
addis 2, 12, .TOC.-dlsym@ha
|
||||
addi 2, 2, .TOC.-dlsym@l
|
||||
.localentry dlsym,.-dlsym
|
||||
mflr 5 # The return address is arg3.
|
||||
b __dlsym
|
||||
.end dlsym
|
||||
.size dlsym, .-dlsym
|
77
src/setjmp/powerpc64/longjmp.s
Normal file
77
src/setjmp/powerpc64/longjmp.s
Normal file
@ -0,0 +1,77 @@
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,@function
|
||||
.type longjmp,@function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
# 0) move old return address into the link register
|
||||
ld 0, 0*8(3)
|
||||
mtlr 0
|
||||
# 1) restore cr
|
||||
ld 0, 1*8(3)
|
||||
mtcr 0
|
||||
# 2) restore r1-r2 (SP and TOC)
|
||||
ld 1, 2*8(3)
|
||||
ld 2, 3*8(3)
|
||||
# 3) restore r14-r31
|
||||
ld 14, 4*8(3)
|
||||
ld 15, 5*8(3)
|
||||
ld 16, 6*8(3)
|
||||
ld 17, 7*8(3)
|
||||
ld 18, 8*8(3)
|
||||
ld 19, 9*8(3)
|
||||
ld 20, 10*8(3)
|
||||
ld 21, 11*8(3)
|
||||
ld 22, 12*8(3)
|
||||
ld 23, 13*8(3)
|
||||
ld 24, 14*8(3)
|
||||
ld 25, 15*8(3)
|
||||
ld 26, 16*8(3)
|
||||
ld 27, 17*8(3)
|
||||
ld 28, 18*8(3)
|
||||
ld 29, 19*8(3)
|
||||
ld 30, 20*8(3)
|
||||
ld 31, 21*8(3)
|
||||
# 4) restore floating point registers f14-f31
|
||||
lfd 14, 22*8(3)
|
||||
lfd 15, 23*8(3)
|
||||
lfd 16, 24*8(3)
|
||||
lfd 17, 25*8(3)
|
||||
lfd 18, 26*8(3)
|
||||
lfd 19, 27*8(3)
|
||||
lfd 20, 28*8(3)
|
||||
lfd 21, 29*8(3)
|
||||
lfd 22, 30*8(3)
|
||||
lfd 23, 31*8(3)
|
||||
lfd 24, 32*8(3)
|
||||
lfd 25, 33*8(3)
|
||||
lfd 26, 34*8(3)
|
||||
lfd 27, 35*8(3)
|
||||
lfd 28, 36*8(3)
|
||||
lfd 29, 37*8(3)
|
||||
lfd 30, 38*8(3)
|
||||
lfd 31, 39*8(3)
|
||||
|
||||
# 5) restore vector registers v20-v31
|
||||
addi 3, 3, 40*8
|
||||
lvx 20, 0, 3 ; addi 3, 3, 16
|
||||
lvx 21, 0, 3 ; addi 3, 3, 16
|
||||
lvx 22, 0, 3 ; addi 3, 3, 16
|
||||
lvx 23, 0, 3 ; addi 3, 3, 16
|
||||
lvx 24, 0, 3 ; addi 3, 3, 16
|
||||
lvx 25, 0, 3 ; addi 3, 3, 16
|
||||
lvx 26, 0, 3 ; addi 3, 3, 16
|
||||
lvx 27, 0, 3 ; addi 3, 3, 16
|
||||
lvx 28, 0, 3 ; addi 3, 3, 16
|
||||
lvx 29, 0, 3 ; addi 3, 3, 16
|
||||
lvx 30, 0, 3 ; addi 3, 3, 16
|
||||
lvx 31, 0, 3
|
||||
|
||||
# 6) return r4 ? r4 : 1
|
||||
mr 3, 4
|
||||
cmpwi cr7, 4, 0
|
||||
bne cr7, 1f
|
||||
li 3, 1
|
||||
1:
|
||||
blr
|
||||
|
78
src/setjmp/powerpc64/setjmp.s
Normal file
78
src/setjmp/powerpc64/setjmp.s
Normal file
@ -0,0 +1,78 @@
|
||||
.global ___setjmp
|
||||
.hidden ___setjmp
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
___setjmp:
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
# 0) store IP into 0, then into the jmpbuf pointed to by r3 (first arg)
|
||||
mflr 0
|
||||
std 0, 0*8(3)
|
||||
# 1) store cr
|
||||
mfcr 0
|
||||
std 0, 1*8(3)
|
||||
# 2) store r1-r2 (SP and TOC)
|
||||
std 1, 2*8(3)
|
||||
std 2, 3*8(3)
|
||||
# 3) store r14-31
|
||||
std 14, 4*8(3)
|
||||
std 15, 5*8(3)
|
||||
std 16, 6*8(3)
|
||||
std 17, 7*8(3)
|
||||
std 18, 8*8(3)
|
||||
std 19, 9*8(3)
|
||||
std 20, 10*8(3)
|
||||
std 21, 11*8(3)
|
||||
std 22, 12*8(3)
|
||||
std 23, 13*8(3)
|
||||
std 24, 14*8(3)
|
||||
std 25, 15*8(3)
|
||||
std 26, 16*8(3)
|
||||
std 27, 17*8(3)
|
||||
std 28, 18*8(3)
|
||||
std 29, 19*8(3)
|
||||
std 30, 20*8(3)
|
||||
std 31, 21*8(3)
|
||||
# 4) store floating point registers f14-f31
|
||||
stfd 14, 22*8(3)
|
||||
stfd 15, 23*8(3)
|
||||
stfd 16, 24*8(3)
|
||||
stfd 17, 25*8(3)
|
||||
stfd 18, 26*8(3)
|
||||
stfd 19, 27*8(3)
|
||||
stfd 20, 28*8(3)
|
||||
stfd 21, 29*8(3)
|
||||
stfd 22, 30*8(3)
|
||||
stfd 23, 31*8(3)
|
||||
stfd 24, 32*8(3)
|
||||
stfd 25, 33*8(3)
|
||||
stfd 26, 34*8(3)
|
||||
stfd 27, 35*8(3)
|
||||
stfd 28, 36*8(3)
|
||||
stfd 29, 37*8(3)
|
||||
stfd 30, 38*8(3)
|
||||
stfd 31, 39*8(3)
|
||||
|
||||
# 5) store vector registers v20-v31
|
||||
addi 3, 3, 40*8
|
||||
stvx 20, 0, 3 ; addi 3, 3, 16
|
||||
stvx 21, 0, 3 ; addi 3, 3, 16
|
||||
stvx 22, 0, 3 ; addi 3, 3, 16
|
||||
stvx 23, 0, 3 ; addi 3, 3, 16
|
||||
stvx 24, 0, 3 ; addi 3, 3, 16
|
||||
stvx 25, 0, 3 ; addi 3, 3, 16
|
||||
stvx 26, 0, 3 ; addi 3, 3, 16
|
||||
stvx 27, 0, 3 ; addi 3, 3, 16
|
||||
stvx 28, 0, 3 ; addi 3, 3, 16
|
||||
stvx 29, 0, 3 ; addi 3, 3, 16
|
||||
stvx 30, 0, 3 ; addi 3, 3, 16
|
||||
stvx 31, 0, 3
|
||||
|
||||
# 6) return 0
|
||||
li 3, 0
|
||||
blr
|
11
src/signal/powerpc64/restore.s
Normal file
11
src/signal/powerpc64/restore.s
Normal file
@ -0,0 +1,11 @@
|
||||
.global __restore
|
||||
.type __restore,%function
|
||||
__restore:
|
||||
li 0, 119 #__NR_sigreturn
|
||||
sc
|
||||
|
||||
.global __restore_rt
|
||||
.type __restore_rt,%function
|
||||
__restore_rt:
|
||||
li 0, 172 # __NR_rt_sigreturn
|
||||
sc
|
30
src/signal/powerpc64/sigsetjmp.s
Normal file
30
src/signal/powerpc64/sigsetjmp.s
Normal file
@ -0,0 +1,30 @@
|
||||
.global sigsetjmp
|
||||
.global __sigsetjmp
|
||||
.type sigsetjmp,%function
|
||||
.type __sigsetjmp,%function
|
||||
.hidden ___setjmp
|
||||
sigsetjmp:
|
||||
__sigsetjmp:
|
||||
addis 2, 12, .TOC.-__sigsetjmp@ha
|
||||
addi 2, 2, .TOC.-__sigsetjmp@l
|
||||
.localentry sigsetjmp,.-sigsetjmp
|
||||
.localentry __sigsetjmp,.-__sigsetjmp
|
||||
|
||||
cmpwi cr7, 4, 0
|
||||
beq- cr7, ___setjmp
|
||||
|
||||
mflr 5
|
||||
std 5, 512(3)
|
||||
std 16, 512+8+8(3)
|
||||
mr 16, 3
|
||||
|
||||
bl ___setjmp
|
||||
|
||||
mr 4, 3
|
||||
mr 3, 16
|
||||
ld 5, 512(3)
|
||||
mtlr 5
|
||||
ld 16, 512+8+8(3)
|
||||
|
||||
.hidden __sigsetjmp_tail
|
||||
b __sigsetjmp_tail
|
8
src/thread/powerpc64/__set_thread_area.s
Normal file
8
src/thread/powerpc64/__set_thread_area.s
Normal file
@ -0,0 +1,8 @@
|
||||
.text
|
||||
.global __set_thread_area
|
||||
.type __set_thread_area, %function
|
||||
__set_thread_area:
|
||||
mr 13, 3
|
||||
li 3, 0
|
||||
blr
|
||||
|
9
src/thread/powerpc64/__unmapself.s
Normal file
9
src/thread/powerpc64/__unmapself.s
Normal file
@ -0,0 +1,9 @@
|
||||
.text
|
||||
.global __unmapself
|
||||
.type __unmapself,%function
|
||||
__unmapself:
|
||||
li 0, 91 # __NR_munmap
|
||||
sc
|
||||
li 0, 1 #__NR_exit
|
||||
sc
|
||||
blr
|
47
src/thread/powerpc64/clone.s
Normal file
47
src/thread/powerpc64/clone.s
Normal file
@ -0,0 +1,47 @@
|
||||
.text
|
||||
.global __clone
|
||||
.type __clone, %function
|
||||
__clone:
|
||||
# int clone(fn, stack, flags, arg, ptid, tls, ctid)
|
||||
# a b c d e f g
|
||||
# 3 4 5 6 7 8 9
|
||||
# pseudo C code:
|
||||
# tid = syscall(SYS_clone,c,b,e,f,g);
|
||||
# if (!tid) syscall(SYS_exit, a(d));
|
||||
# return tid;
|
||||
|
||||
# create initial stack frame for new thread
|
||||
clrrdi 4, 4, 4
|
||||
li 0, 0
|
||||
stdu 0,-32(4)
|
||||
|
||||
# save fn and arg to child stack
|
||||
std 3, 8(4)
|
||||
std 6, 16(4)
|
||||
|
||||
# shuffle args into correct registers and call SYS_clone
|
||||
mr 3, 5
|
||||
#mr 4, 4
|
||||
mr 5, 7
|
||||
mr 6, 8
|
||||
mr 7, 9
|
||||
li 0, 120 # SYS_clone = 120
|
||||
sc
|
||||
|
||||
# if error, negate return (errno)
|
||||
bns+ 1f
|
||||
neg 3, 3
|
||||
|
||||
1: # if we're the parent, return
|
||||
cmpwi cr7, 3, 0
|
||||
bnelr cr7
|
||||
|
||||
# we're the child. call fn(arg)
|
||||
ld 3, 16(1)
|
||||
ld 12, 8(1)
|
||||
mtctr 12
|
||||
bctrl
|
||||
|
||||
# call SYS_exit. exit code is already in r3 from fn return value
|
||||
li 0, 1 # SYS_exit = 1
|
||||
sc
|
37
src/thread/powerpc64/syscall_cp.s
Normal file
37
src/thread/powerpc64/syscall_cp.s
Normal file
@ -0,0 +1,37 @@
|
||||
.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
|
||||
.text
|
||||
.type __syscall_cp_asm,%function
|
||||
__syscall_cp_asm:
|
||||
# at enter: r3 = pointer to self->cancel, r4: syscall no, r5: first arg, r6: 2nd, r7: 3rd, r8: 4th, r9: 5th, r10: 6th
|
||||
__cp_begin:
|
||||
# if (self->cancel) goto __cp_cancel
|
||||
lwz 0, 0(3)
|
||||
cmpwi cr7, 0, 0
|
||||
bne- cr7, __cp_cancel
|
||||
|
||||
# make syscall
|
||||
mr 0, 4
|
||||
mr 3, 5
|
||||
mr 4, 6
|
||||
mr 5, 7
|
||||
mr 6, 8
|
||||
mr 7, 9
|
||||
mr 8, 10
|
||||
sc
|
||||
|
||||
__cp_end:
|
||||
# return error ? -r3 : r3
|
||||
bnslr+
|
||||
neg 3, 3
|
||||
blr
|
||||
|
||||
__cp_cancel:
|
||||
b __cancel
|
Reference in New Issue
Block a user