libc: initial arm64 support
This commit is contained in:
parent
59ff04ddb1
commit
9920ecc04b
16 changed files with 407 additions and 0 deletions
|
@ -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)'
|
||||
|
|
14
sys/src/libc/arm64/_seek.c
Normal file
14
sys/src/libc/arm64/_seek.c
Normal file
|
@ -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;
|
||||
}
|
4
sys/src/libc/arm64/argv0.s
Normal file
4
sys/src/libc/arm64/argv0.s
Normal file
|
@ -0,0 +1,4 @@
|
|||
GLOBL argv0(SB), $8
|
||||
GLOBL _tos(SB), $8
|
||||
GLOBL _privates(SB), $8
|
||||
GLOBL _nprivates(SB), $4
|
54
sys/src/libc/arm64/atom.s
Normal file
54
sys/src/libc/arm64/atom.s
Normal file
|
@ -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)
|
7
sys/src/libc/arm64/cycles.s
Normal file
7
sys/src/libc/arm64/cycles.s
Normal file
|
@ -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
|
3
sys/src/libc/arm64/getcallerpc.s
Normal file
3
sys/src/libc/arm64/getcallerpc.s
Normal file
|
@ -0,0 +1,3 @@
|
|||
TEXT getcallerpc(SB), $0
|
||||
MOV 0(SP), R0
|
||||
RETURN
|
21
sys/src/libc/arm64/getfcr.s
Normal file
21
sys/src/libc/arm64/getfcr.s
Normal file
|
@ -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
|
||||
|
41
sys/src/libc/arm64/lock.c
Normal file
41
sys/src/libc/arm64/lock.c
Normal file
|
@ -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);
|
||||
}
|
25
sys/src/libc/arm64/main9.s
Normal file
25
sys/src/libc/arm64/main9.s
Normal file
|
@ -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
|
38
sys/src/libc/arm64/main9p.s
Normal file
38
sys/src/libc/arm64/main9p.s
Normal file
|
@ -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
|
31
sys/src/libc/arm64/mkfile
Normal file
31
sys/src/libc/arm64/mkfile
Normal file
|
@ -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
|
16
sys/src/libc/arm64/notejmp.c
Normal file
16
sys/src/libc/arm64/notejmp.c
Normal file
|
@ -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);
|
||||
}
|
17
sys/src/libc/arm64/setjmp.s
Normal file
17
sys/src/libc/arm64/setjmp.s
Normal file
|
@ -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
|
11
sys/src/libc/arm64/tas.s
Normal file
11
sys/src/libc/arm64/tas.s
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue