libc: initial arm64 support
This commit is contained in:
parent
59ff04ddb1
commit
9920ecc04b
16 changed files with 407 additions and 0 deletions
77
arm64/include/u.h
Normal file
77
arm64/include/u.h
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#define nil ((void*)0)
|
||||||
|
|
||||||
|
typedef unsigned short ushort;
|
||||||
|
typedef unsigned char uchar;
|
||||||
|
typedef unsigned long ulong;
|
||||||
|
typedef unsigned int uint;
|
||||||
|
typedef signed char schar;
|
||||||
|
typedef long long vlong;
|
||||||
|
typedef unsigned long long uvlong;
|
||||||
|
typedef vlong intptr;
|
||||||
|
typedef uvlong uintptr;
|
||||||
|
typedef unsigned long usize;
|
||||||
|
typedef uint Rune;
|
||||||
|
typedef union FPdbleword FPdbleword;
|
||||||
|
typedef uintptr jmp_buf[2];
|
||||||
|
#define JMPBUFSP 0
|
||||||
|
#define JMPBUFPC 1
|
||||||
|
#define JMPBUFDPC 0
|
||||||
|
typedef unsigned int mpdigit; /* for /sys/include/mp.h */
|
||||||
|
typedef unsigned char u8int;
|
||||||
|
typedef unsigned short u16int;
|
||||||
|
typedef unsigned int u32int;
|
||||||
|
typedef unsigned long long u64int;
|
||||||
|
typedef signed char s8int;
|
||||||
|
typedef signed short s16int;
|
||||||
|
typedef signed int s32int;
|
||||||
|
typedef signed long long s64int;
|
||||||
|
|
||||||
|
/* FPCR (control) */
|
||||||
|
#define FPINEX (1<<12)
|
||||||
|
#define FPUNFL (1<<11)
|
||||||
|
#define FPOVFL (1<<10)
|
||||||
|
#define FPZDIV (1<<9)
|
||||||
|
#define FPINVAL (1<<8)
|
||||||
|
|
||||||
|
#define FPRNR (0<<22)
|
||||||
|
#define FPRPINF (1<<22)
|
||||||
|
#define FPRNINF (2<<22)
|
||||||
|
#define FPRZ (3<<22)
|
||||||
|
|
||||||
|
#define FPRMASK (3<<22)
|
||||||
|
|
||||||
|
/* FPSR (status) */
|
||||||
|
#define FPPEXT 0
|
||||||
|
#define FPPSGL 0
|
||||||
|
#define FPPDBL 0
|
||||||
|
#define FPPMASK 0
|
||||||
|
#define FPAINEX (1<<4)
|
||||||
|
#define FPAUNFL (1<<3)
|
||||||
|
#define FPAOVFL (1<<2)
|
||||||
|
#define FPAZDIV (1<<1)
|
||||||
|
#define FPAINVAL (1<<0)
|
||||||
|
|
||||||
|
union FPdbleword
|
||||||
|
{
|
||||||
|
double x;
|
||||||
|
struct { /* little endian */
|
||||||
|
ulong lo;
|
||||||
|
ulong hi;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef char* va_list;
|
||||||
|
#define va_start(list, start) list =\
|
||||||
|
(sizeof(start) < 8?\
|
||||||
|
(char*)((vlong*)&(start)+1):\
|
||||||
|
(char*)(&(start)+1))
|
||||||
|
#define va_end(list)\
|
||||||
|
USED(list)
|
||||||
|
#define va_arg(list, mode)\
|
||||||
|
((sizeof(mode) == 1)?\
|
||||||
|
((list += 8), (mode*)list)[-8]:\
|
||||||
|
(sizeof(mode) == 2)?\
|
||||||
|
((list += 8), (mode*)list)[-4]:\
|
||||||
|
(sizeof(mode) == 4)?\
|
||||||
|
((list += 8), (mode*)list)[-2]:\
|
||||||
|
((list += sizeof(mode)), (mode*)list)[-1])
|
40
arm64/include/ureg.h
Normal file
40
arm64/include/ureg.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
typedef struct Ureg {
|
||||||
|
u64int r0;
|
||||||
|
u64int r1;
|
||||||
|
u64int r2;
|
||||||
|
u64int r3;
|
||||||
|
u64int r4;
|
||||||
|
u64int r5;
|
||||||
|
u64int r6;
|
||||||
|
u64int r7;
|
||||||
|
u64int r8;
|
||||||
|
u64int r9;
|
||||||
|
u64int r10;
|
||||||
|
u64int r11;
|
||||||
|
u64int r12;
|
||||||
|
u64int r13;
|
||||||
|
u64int r14;
|
||||||
|
u64int r15;
|
||||||
|
u64int r16;
|
||||||
|
u64int r17;
|
||||||
|
u64int r18;
|
||||||
|
u64int r19;
|
||||||
|
u64int r20;
|
||||||
|
u64int r21;
|
||||||
|
u64int r22;
|
||||||
|
u64int r23;
|
||||||
|
u64int r24;
|
||||||
|
u64int r25;
|
||||||
|
u64int r26;
|
||||||
|
u64int r27;
|
||||||
|
u64int r28; /* sb */
|
||||||
|
u64int r29;
|
||||||
|
union {
|
||||||
|
u64int r30;
|
||||||
|
u64int link;
|
||||||
|
};
|
||||||
|
u64int sp;
|
||||||
|
u64int pc; /* interrupted addr */
|
||||||
|
u64int psr;
|
||||||
|
u64int type; /* of exception */
|
||||||
|
} Ureg;
|
|
@ -107,6 +107,14 @@ install:V:
|
||||||
MOVW R0,4(R1)'
|
MOVW R0,4(R1)'
|
||||||
}
|
}
|
||||||
echo RET
|
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
|
case power
|
||||||
echo TEXT $i'(SB)', 1, '$0'
|
echo TEXT $i'(SB)', 1, '$0'
|
||||||
echo MOVW R3, '0(FP)'
|
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…
Reference in a new issue