diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-05-03 20:57:30 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-05-03 20:57:30 +0200 |
commit | 9920ecc04b87cab3968f7f0c286b264bd31e132f (patch) | |
tree | e38cf67b782df089075d9c34269cc88d313fea2b /sys/src/libc | |
parent | 59ff04ddb1b845bfd8542c886bb42c5cb3112a0b (diff) |
libc: initial arm64 support
Diffstat (limited to 'sys/src/libc')
-rw-r--r-- | sys/src/libc/9syscall/mkfile | 8 | ||||
-rw-r--r-- | sys/src/libc/arm64/_seek.c | 14 | ||||
-rw-r--r-- | sys/src/libc/arm64/argv0.s | 4 | ||||
-rw-r--r-- | sys/src/libc/arm64/atom.s | 54 | ||||
-rw-r--r-- | sys/src/libc/arm64/cycles.s | 7 | ||||
-rw-r--r-- | sys/src/libc/arm64/getcallerpc.s | 3 | ||||
-rw-r--r-- | sys/src/libc/arm64/getfcr.s | 21 | ||||
-rw-r--r-- | sys/src/libc/arm64/lock.c | 41 | ||||
-rw-r--r-- | sys/src/libc/arm64/main9.s | 25 | ||||
-rw-r--r-- | sys/src/libc/arm64/main9p.s | 38 | ||||
-rw-r--r-- | sys/src/libc/arm64/mkfile | 31 | ||||
-rw-r--r-- | sys/src/libc/arm64/notejmp.c | 16 | ||||
-rw-r--r-- | sys/src/libc/arm64/setjmp.s | 17 | ||||
-rw-r--r-- | sys/src/libc/arm64/tas.s | 11 |
14 files changed, 290 insertions, 0 deletions
diff --git a/sys/src/libc/9syscall/mkfile b/sys/src/libc/9syscall/mkfile index f8df482bc..48417e271 100644 --- a/sys/src/libc/9syscall/mkfile +++ b/sys/src/libc/9syscall/mkfile @@ -107,6 +107,14 @@ install:V: MOVW R0,4(R1)' } echo RET + case arm64 + j=$i + if(~ $i seek) j=_seek + echo TEXT $j'(SB)', 1, '$0' + echo MOV R0, '0(FP)' + echo MOV '$'$n, R0 + echo SVC + echo RETURN case power echo TEXT $i'(SB)', 1, '$0' echo MOVW R3, '0(FP)' diff --git a/sys/src/libc/arm64/_seek.c b/sys/src/libc/arm64/_seek.c new file mode 100644 index 000000000..d44420db2 --- /dev/null +++ b/sys/src/libc/arm64/_seek.c @@ -0,0 +1,14 @@ +#include <u.h> +#include <libc.h> + +extern int _seek(vlong*, int, vlong, int); + +vlong +seek(int fd, vlong o, int p) +{ + vlong l; + + if(_seek(&l, fd, o, p) < 0) + l = -1LL; + return l; +} diff --git a/sys/src/libc/arm64/argv0.s b/sys/src/libc/arm64/argv0.s new file mode 100644 index 000000000..fe4eb4c85 --- /dev/null +++ b/sys/src/libc/arm64/argv0.s @@ -0,0 +1,4 @@ +GLOBL argv0(SB), $8 +GLOBL _tos(SB), $8 +GLOBL _privates(SB), $8 +GLOBL _nprivates(SB), $4 diff --git a/sys/src/libc/arm64/atom.s b/sys/src/libc/arm64/atom.s new file mode 100644 index 000000000..f1fbc522a --- /dev/null +++ b/sys/src/libc/arm64/atom.s @@ -0,0 +1,54 @@ +/* + * int cas32(u32int *p, u32int ov, u32int nv); + * int cas(uint *p, int ov, int nv); + * int casl(ulong *p, ulong ov, ulong nv); + */ +TEXT cas32(SB), 1, $-4 +TEXT cas(SB), 1, $-4 +TEXT casl(SB), 1, $-4 + MOVWU ov+8(FP), R1 + MOVWU nv+16(FP), R2 +_cas1: + LDXRW (R0), R3 + CMP R3, R1 + BNE _cas0 + STXRW R2, (R0), R4 + CBNZ R4, _cas1 + MOVW $1, R0 + B _barrier(SB) +_cas0: + CLREX + MOVW $0, R0 + RETURN + +TEXT casp(SB), 1, $-4 + MOV ov+8(FP), R1 + MOV nv+16(FP), R2 +_casp1: + LDXR (R0), R3 + CMP R3, R1 + BNE _cas0 + STXR R2, (R0), R4 + CBNZ R4, _casp1 + MOVW $1, R0 + B _barrier(SB) + +TEXT _xinc(SB), 1, $-4 /* void _xinc(long *); */ +TEXT ainc(SB), 1, $-4 /* long ainc(long *); */ +spinainc: + LDXRW (R0), R3 + ADDW $1,R3 + STXRW R3, (R0), R4 + CBNZ R4, spinainc + MOVW R3, R0 + B _barrier(SB) + +TEXT _xdec(SB), 1, $-4 /* long _xdec(long *); */ +TEXT adec(SB), 1, $-4 /* long adec(long *); */ +spinadec: + LDXRW (R0), R3 + SUBW $1,R3 + STXRW R3, (R0), R4 + CBNZ R4, spinadec + MOVW R3, R0 + B _barrier(SB) diff --git a/sys/src/libc/arm64/cycles.s b/sys/src/libc/arm64/cycles.s new file mode 100644 index 000000000..389ea201f --- /dev/null +++ b/sys/src/libc/arm64/cycles.s @@ -0,0 +1,7 @@ +#define SYSREG(op0,op1,Cn,Cm,op2) SPR(((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5)) +#define PMCCNTR_EL0 SYSREG(3,3,9,13,0) + +TEXT cycles(SB), 1, $-4 + MRS PMCCNTR_EL0, R1 + MOV R1, (R0) + RETURN diff --git a/sys/src/libc/arm64/getcallerpc.s b/sys/src/libc/arm64/getcallerpc.s new file mode 100644 index 000000000..7ca9a3e8c --- /dev/null +++ b/sys/src/libc/arm64/getcallerpc.s @@ -0,0 +1,3 @@ +TEXT getcallerpc(SB), $0 + MOV 0(SP), R0 + RETURN diff --git a/sys/src/libc/arm64/getfcr.s b/sys/src/libc/arm64/getfcr.s new file mode 100644 index 000000000..c5c90de90 --- /dev/null +++ b/sys/src/libc/arm64/getfcr.s @@ -0,0 +1,21 @@ +#define SYSARG5(op0,op1,Cn,Cm,op2) ((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5) + +#define FPCR SPR(SYSARG5(3,3,4,4,0)) +#define FPSR SPR(SYSARG5(3,3,4,4,1)) + +TEXT setfcr(SB), 1, $-4 + MSR R0, FPCR + RETURN + +TEXT getfcr(SB), 1, $-4 + MRS FPCR, R0 + RETURN + +TEXT getfsr(SB), 1, $-4 + MRS FPSR, R0 + RETURN + +TEXT setfsr(SB), 1, $-4 + MSR R0, FPSR + RETURN + diff --git a/sys/src/libc/arm64/lock.c b/sys/src/libc/arm64/lock.c new file mode 100644 index 000000000..307c4b7d6 --- /dev/null +++ b/sys/src/libc/arm64/lock.c @@ -0,0 +1,41 @@ +#include <u.h> +#include <libc.h> + +extern uintptr _barrier(uintptr); + +void +lock(Lock *lk) +{ + int i; + + /* once fast */ + if(!_tas(&lk->val)) + return; + /* a thousand times pretty fast */ + for(i=0; i<1000; i++){ + if(!_tas(&lk->val)) + return; + sleep(0); + } + /* now nice and slow */ + for(i=0; i<1000; i++){ + if(!_tas(&lk->val)) + return; + sleep(100); + } + /* take your time */ + while(_tas(&lk->val)) + sleep(1000); +} + +int +canlock(Lock *lk) +{ + return _tas(&lk->val) == 0; +} + +void +unlock(Lock *lk) +{ + lk->val = _barrier(0); +} diff --git a/sys/src/libc/arm64/main9.s b/sys/src/libc/arm64/main9.s new file mode 100644 index 000000000..36cf953cc --- /dev/null +++ b/sys/src/libc/arm64/main9.s @@ -0,0 +1,25 @@ +#define NPRIVATES 16 + +TEXT _main(SB), 1, $(16 + NPRIVATES*8) + MOV $setSB(SB), R28 + MOV R0, _tos(SB) + + ADD $32, RSP, R1 + MOV R1, _privates(SB) + MOVW $NPRIVATES, R2 + MOVW R2, _nprivates(SB) + + MOV $inargv+0(FP), R1 + MOV R1, 16(RSP) + + MOVW inargc-8(FP), R0 + MOV R0, 8(RSP) + + BL main(SB) +loop: + MOV $_exitstr<>(SB), R0 + BL exits(SB) + B loop + +DATA _exitstr<>+0(SB)/4, $"main" +GLOBL _exitstr<>+0(SB), $5 diff --git a/sys/src/libc/arm64/main9p.s b/sys/src/libc/arm64/main9p.s new file mode 100644 index 000000000..0255f3a82 --- /dev/null +++ b/sys/src/libc/arm64/main9p.s @@ -0,0 +1,38 @@ +#define NPRIVATES 16 + +TEXT _mainp(SB), 1, $(16 + NPRIVATES*8) + MOV $setSB(SB), R28 + MOV R0, _tos(SB) + + ADD $32, RSP, R1 + MOV R1, _privates(SB) + MOVW $NPRIVATES, R2 + MOVW R2, _nprivates(SB) + + BL _profmain(SB) + + MOV _tos(SB), R0 /* _tos->prof.pp = _tos->prof.next; */ + MOV 8(R0), R1 + MOV R1, 0(R0) + + MOV $inargv+0(FP), R1 + MOV R1, 16(RSP) + + MOVW inargc-8(FP), R0 + MOV R0, 8(RSP) + + BL main(SB) +loop: + MOV $_exitstr<>(SB), R0 + BL exits(SB) + MOV $_profin(SB), R0 + B loop + +TEXT _callpc(SB), 1, $-4 + MOV 0(SP), R0 +TEXT _saveret(SB), 1, $-4 +TEXT _savearg(SB), 1, $-4 + RETURN + +DATA _exitstr<>+0(SB)/4, $"main" +GLOBL _exitstr<>+0(SB), $5 diff --git a/sys/src/libc/arm64/mkfile b/sys/src/libc/arm64/mkfile new file mode 100644 index 000000000..b0c7abe06 --- /dev/null +++ b/sys/src/libc/arm64/mkfile @@ -0,0 +1,31 @@ +objtype=arm64 +</$objtype/mkfile +OS=7 + +LIB=/$objtype/lib/libc.a +SFILES=\ + argv0.s\ + atom.s\ + cycles.s\ + getcallerpc.s\ + getfcr.s\ + main9.s\ + main9p.s\ + setjmp.s\ + tas.s\ + +CFILES=\ + lock.c\ + notejmp.c\ + _seek.c\ + +HFILES=/sys/include/libc.h + +OFILES=${CFILES:%.c=%.$O} ${SFILES:%.s=%.$O} + +UPDATE=mkfile\ + $HFILES\ + $CFILES\ + $SFILES\ + +</sys/src/cmd/mksyslib diff --git a/sys/src/libc/arm64/notejmp.c b/sys/src/libc/arm64/notejmp.c new file mode 100644 index 000000000..dff612bce --- /dev/null +++ b/sys/src/libc/arm64/notejmp.c @@ -0,0 +1,16 @@ +#include <u.h> +#include <libc.h> +#include <ureg.h> + +void +notejmp(void *vr, jmp_buf j, int ret) +{ + struct Ureg *r = vr; + + r->r0 = ret; + if(ret == 0) + r->r0 = 1; + r->pc = j[JMPBUFPC]; + r->sp = j[JMPBUFSP]; + noted(NCONT); +} diff --git a/sys/src/libc/arm64/setjmp.s b/sys/src/libc/arm64/setjmp.s new file mode 100644 index 000000000..741a52a04 --- /dev/null +++ b/sys/src/libc/arm64/setjmp.s @@ -0,0 +1,17 @@ +TEXT setjmp(SB), 1, $-4 + MOV LR, 8(R0) + MOV SP, R1 + MOV R1, 0(R0) + MOV $0, R0 + RETURN + +TEXT longjmp(SB), 1, $-4 + MOV 8(R0), LR + MOV 0(R0), R1 + MOVW arg+8(FP), R0 + MOV R1, SP + CBZ R0, _one + RETURN +_one: + MOV $1, R0 + RETURN diff --git a/sys/src/libc/arm64/tas.s b/sys/src/libc/arm64/tas.s new file mode 100644 index 000000000..090037c81 --- /dev/null +++ b/sys/src/libc/arm64/tas.s @@ -0,0 +1,11 @@ +TEXT _tas(SB), 1, $-4 + MOVW $1, R2 +_tas1: + LDXRW (R0), R1 + STXRW R2, (R0), R3 + CBNZ R3, _tas1 + MOVW R1, R0 + +TEXT _barrier(SB), 1, $-4 + DMB $0xB // ISH + RETURN |