add powerpc64 port

This commit is contained in:
Bobby Bingham
2016-04-30 19:18:17 -05:00
committed by Rich Felker
parent 6bc7d9c411
commit c0ede9e404
42 changed files with 2342 additions and 1 deletions

68
src/fenv/powerpc64/fenv.c Normal file
View 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;
}

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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