changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: libc: initial arm64 support

changeset 7185: fb00248097c0
parent 7184: 681e7449529d
child 7186: 4dd5e2428c1d
author: cinap_lenrek@felloff.net
date: Fri, 03 May 2019 20:57:30 +0200
files: arm64/include/u.h arm64/include/ureg.h sys/src/libc/9syscall/mkfile sys/src/libc/arm64/_seek.c sys/src/libc/arm64/argv0.s sys/src/libc/arm64/atom.s sys/src/libc/arm64/cycles.s sys/src/libc/arm64/getcallerpc.s sys/src/libc/arm64/getfcr.s sys/src/libc/arm64/lock.c sys/src/libc/arm64/main9.s sys/src/libc/arm64/main9p.s sys/src/libc/arm64/mkfile sys/src/libc/arm64/notejmp.c sys/src/libc/arm64/setjmp.s sys/src/libc/arm64/tas.s
description: libc: initial arm64 support
     1.1new file mode 100644
     1.2--- /dev/null
     1.3+++ b/arm64/include/u.h
     1.4@@ -0,0 +1,77 @@
     1.5+#define nil		((void*)0)
     1.6+
     1.7+typedef	unsigned short	ushort;
     1.8+typedef	unsigned char	uchar;
     1.9+typedef	unsigned long	ulong;
    1.10+typedef	unsigned int	uint;
    1.11+typedef	signed char	schar;
    1.12+typedef	long long	vlong;
    1.13+typedef	unsigned long long uvlong;
    1.14+typedef vlong	intptr;
    1.15+typedef uvlong	uintptr;
    1.16+typedef unsigned long	usize;
    1.17+typedef	uint		Rune;
    1.18+typedef union FPdbleword FPdbleword;
    1.19+typedef uintptr	jmp_buf[2];
    1.20+#define	JMPBUFSP	0
    1.21+#define	JMPBUFPC	1
    1.22+#define	JMPBUFDPC	0
    1.23+typedef unsigned int	mpdigit;	/* for /sys/include/mp.h */
    1.24+typedef unsigned char u8int;
    1.25+typedef unsigned short u16int;
    1.26+typedef unsigned int	u32int;
    1.27+typedef unsigned long long u64int;
    1.28+typedef signed char s8int;
    1.29+typedef signed short s16int;
    1.30+typedef signed int s32int;
    1.31+typedef signed long long s64int;
    1.32+
    1.33+/* FPCR (control) */
    1.34+#define	FPINEX		(1<<12)
    1.35+#define	FPUNFL		(1<<11)
    1.36+#define	FPOVFL		(1<<10)
    1.37+#define	FPZDIV		(1<<9)
    1.38+#define	FPINVAL		(1<<8)
    1.39+
    1.40+#define	FPRNR		(0<<22)
    1.41+#define	FPRPINF		(1<<22)
    1.42+#define	FPRNINF		(2<<22)
    1.43+#define	FPRZ		(3<<22)
    1.44+
    1.45+#define	FPRMASK		(3<<22)
    1.46+
    1.47+/* FPSR (status) */
    1.48+#define	FPPEXT	0
    1.49+#define	FPPSGL	0
    1.50+#define	FPPDBL	0
    1.51+#define	FPPMASK	0
    1.52+#define	FPAINEX		(1<<4)
    1.53+#define	FPAUNFL		(1<<3)
    1.54+#define	FPAOVFL		(1<<2)
    1.55+#define	FPAZDIV		(1<<1)
    1.56+#define	FPAINVAL	(1<<0)
    1.57+
    1.58+union FPdbleword
    1.59+{
    1.60+	double	x;
    1.61+	struct {	/* little endian */
    1.62+		ulong lo;
    1.63+		ulong hi;
    1.64+	};
    1.65+};
    1.66+
    1.67+typedef	char*	va_list;
    1.68+#define va_start(list, start) list =\
    1.69+	(sizeof(start) < 8?\
    1.70+		(char*)((vlong*)&(start)+1):\
    1.71+		(char*)(&(start)+1))
    1.72+#define va_end(list)\
    1.73+	USED(list)
    1.74+#define va_arg(list, mode)\
    1.75+	((sizeof(mode) == 1)?\
    1.76+		((list += 8), (mode*)list)[-8]:\
    1.77+	(sizeof(mode) == 2)?\
    1.78+		((list += 8), (mode*)list)[-4]:\
    1.79+	(sizeof(mode) == 4)?\
    1.80+		((list += 8), (mode*)list)[-2]:\
    1.81+		((list += sizeof(mode)), (mode*)list)[-1])
     2.1new file mode 100644
     2.2--- /dev/null
     2.3+++ b/arm64/include/ureg.h
     2.4@@ -0,0 +1,40 @@
     2.5+typedef struct Ureg {
     2.6+	u64int	r0;
     2.7+	u64int	r1;
     2.8+	u64int	r2;
     2.9+	u64int	r3;
    2.10+	u64int	r4;
    2.11+	u64int	r5;
    2.12+	u64int	r6;
    2.13+	u64int	r7;
    2.14+	u64int	r8;
    2.15+	u64int	r9;
    2.16+	u64int	r10;
    2.17+	u64int	r11;
    2.18+	u64int	r12;
    2.19+	u64int	r13;
    2.20+	u64int	r14;
    2.21+	u64int	r15;
    2.22+	u64int	r16;
    2.23+	u64int	r17;
    2.24+	u64int	r18;
    2.25+	u64int	r19;
    2.26+	u64int	r20;
    2.27+	u64int	r21;
    2.28+	u64int	r22;
    2.29+	u64int	r23;
    2.30+	u64int	r24;
    2.31+	u64int	r25;
    2.32+	u64int	r26;
    2.33+	u64int	r27;
    2.34+	u64int	r28;	/* sb */
    2.35+	u64int	r29;
    2.36+	union {
    2.37+		u64int	r30;
    2.38+		u64int	link;
    2.39+	};
    2.40+	u64int	sp;
    2.41+	u64int	pc;	/* interrupted addr */
    2.42+	u64int	psr;
    2.43+	u64int	type;	/* of exception */
    2.44+} Ureg;
     3.1--- a/sys/src/libc/9syscall/mkfile
     3.2+++ b/sys/src/libc/9syscall/mkfile
     3.3@@ -107,6 +107,14 @@ install:V:
     3.4 				MOVW R0,4(R1)'
     3.5 			}
     3.6 			echo RET
     3.7+		case arm64
     3.8+			j=$i
     3.9+			if(~ $i seek) j=_seek
    3.10+			echo TEXT $j'(SB)', 1, '$0'
    3.11+			echo MOV R0, '0(FP)'
    3.12+			echo MOV '$'$n, R0
    3.13+			echo SVC
    3.14+			echo RETURN
    3.15 		case power
    3.16 			echo TEXT $i'(SB)', 1, '$0'
    3.17 			echo MOVW R3, '0(FP)'
     4.1new file mode 100644
     4.2--- /dev/null
     4.3+++ b/sys/src/libc/arm64/_seek.c
     4.4@@ -0,0 +1,14 @@
     4.5+#include <u.h>
     4.6+#include <libc.h>
     4.7+
     4.8+extern int _seek(vlong*, int, vlong, int);
     4.9+
    4.10+vlong
    4.11+seek(int fd, vlong o, int p)
    4.12+{
    4.13+	vlong l;
    4.14+
    4.15+	if(_seek(&l, fd, o, p) < 0)
    4.16+		l = -1LL;
    4.17+	return l;
    4.18+}
     5.1new file mode 100644
     5.2--- /dev/null
     5.3+++ b/sys/src/libc/arm64/argv0.s
     5.4@@ -0,0 +1,4 @@
     5.5+GLOBL	argv0(SB), $8
     5.6+GLOBL	_tos(SB), $8
     5.7+GLOBL	_privates(SB), $8
     5.8+GLOBL	_nprivates(SB), $4
     6.1new file mode 100644
     6.2--- /dev/null
     6.3+++ b/sys/src/libc/arm64/atom.s
     6.4@@ -0,0 +1,54 @@
     6.5+/*
     6.6+ * int cas32(u32int *p, u32int ov, u32int nv);
     6.7+ * int cas(uint *p, int ov, int nv);
     6.8+ * int casl(ulong *p, ulong ov, ulong nv);
     6.9+ */
    6.10+TEXT cas32(SB), 1, $-4
    6.11+TEXT cas(SB), 1, $-4
    6.12+TEXT casl(SB), 1, $-4
    6.13+	MOVWU	ov+8(FP), R1
    6.14+	MOVWU	nv+16(FP), R2
    6.15+_cas1:
    6.16+	LDXRW	(R0), R3
    6.17+	CMP	R3, R1
    6.18+	BNE	_cas0
    6.19+	STXRW	R2, (R0), R4
    6.20+	CBNZ	R4, _cas1
    6.21+	MOVW	$1, R0
    6.22+	B	_barrier(SB)
    6.23+_cas0:
    6.24+	CLREX
    6.25+	MOVW	$0, R0
    6.26+	RETURN
    6.27+
    6.28+TEXT casp(SB), 1, $-4
    6.29+	MOV	ov+8(FP), R1
    6.30+	MOV	nv+16(FP), R2
    6.31+_casp1:
    6.32+	LDXR	(R0), R3
    6.33+	CMP	R3, R1
    6.34+	BNE	_cas0
    6.35+	STXR	R2, (R0), R4
    6.36+	CBNZ	R4, _casp1
    6.37+	MOVW	$1, R0
    6.38+	B	_barrier(SB)
    6.39+
    6.40+TEXT _xinc(SB), 1, $-4	/* void	_xinc(long *); */
    6.41+TEXT ainc(SB), 1, $-4	/* long ainc(long *); */
    6.42+spinainc:
    6.43+	LDXRW	(R0), R3
    6.44+	ADDW	$1,R3
    6.45+	STXRW	R3, (R0), R4
    6.46+	CBNZ	R4, spinainc
    6.47+	MOVW	R3, R0
    6.48+	B	_barrier(SB)
    6.49+
    6.50+TEXT _xdec(SB), 1, $-4	/* long _xdec(long *); */
    6.51+TEXT adec(SB), 1, $-4	/* long adec(long *); */
    6.52+spinadec:
    6.53+	LDXRW	(R0), R3
    6.54+	SUBW	$1,R3
    6.55+	STXRW	R3, (R0), R4
    6.56+	CBNZ	R4, spinadec
    6.57+	MOVW	R3, R0
    6.58+	B	_barrier(SB)
     7.1new file mode 100644
     7.2--- /dev/null
     7.3+++ b/sys/src/libc/arm64/cycles.s
     7.4@@ -0,0 +1,7 @@
     7.5+#define	SYSREG(op0,op1,Cn,Cm,op2)	SPR(((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5))
     7.6+#define PMCCNTR_EL0			SYSREG(3,3,9,13,0)
     7.7+
     7.8+TEXT cycles(SB), 1, $-4
     7.9+	MRS	PMCCNTR_EL0, R1
    7.10+	MOV	R1, (R0)
    7.11+	RETURN
     8.1new file mode 100644
     8.2--- /dev/null
     8.3+++ b/sys/src/libc/arm64/getcallerpc.s
     8.4@@ -0,0 +1,3 @@
     8.5+TEXT getcallerpc(SB), $0
     8.6+	MOV	0(SP), R0
     8.7+	RETURN
     9.1new file mode 100644
     9.2--- /dev/null
     9.3+++ b/sys/src/libc/arm64/getfcr.s
     9.4@@ -0,0 +1,21 @@
     9.5+#define	SYSARG5(op0,op1,Cn,Cm,op2)	((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5)
     9.6+
     9.7+#define	FPCR		SPR(SYSARG5(3,3,4,4,0))
     9.8+#define	FPSR		SPR(SYSARG5(3,3,4,4,1))
     9.9+
    9.10+TEXT	setfcr(SB), 1, $-4
    9.11+	MSR	R0, FPCR
    9.12+	RETURN
    9.13+
    9.14+TEXT	getfcr(SB), 1, $-4
    9.15+	MRS	FPCR, R0
    9.16+	RETURN
    9.17+
    9.18+TEXT	getfsr(SB), 1, $-4
    9.19+	MRS	FPSR, R0
    9.20+	RETURN
    9.21+
    9.22+TEXT	setfsr(SB), 1, $-4
    9.23+	MSR	R0, FPSR
    9.24+	RETURN
    9.25+
    10.1new file mode 100644
    10.2--- /dev/null
    10.3+++ b/sys/src/libc/arm64/lock.c
    10.4@@ -0,0 +1,41 @@
    10.5+#include <u.h>
    10.6+#include <libc.h>
    10.7+
    10.8+extern uintptr _barrier(uintptr);
    10.9+
   10.10+void
   10.11+lock(Lock *lk)
   10.12+{
   10.13+	int i;
   10.14+
   10.15+	/* once fast */
   10.16+	if(!_tas(&lk->val))
   10.17+		return;
   10.18+	/* a thousand times pretty fast */
   10.19+	for(i=0; i<1000; i++){
   10.20+		if(!_tas(&lk->val))
   10.21+			return;
   10.22+		sleep(0);
   10.23+	}
   10.24+	/* now nice and slow */
   10.25+	for(i=0; i<1000; i++){
   10.26+		if(!_tas(&lk->val))
   10.27+			return;
   10.28+		sleep(100);
   10.29+	}
   10.30+	/* take your time */
   10.31+	while(_tas(&lk->val))
   10.32+		sleep(1000);
   10.33+}
   10.34+
   10.35+int
   10.36+canlock(Lock *lk)
   10.37+{
   10.38+	return _tas(&lk->val) == 0;
   10.39+}
   10.40+
   10.41+void
   10.42+unlock(Lock *lk)
   10.43+{
   10.44+	lk->val = _barrier(0);
   10.45+}
    11.1new file mode 100644
    11.2--- /dev/null
    11.3+++ b/sys/src/libc/arm64/main9.s
    11.4@@ -0,0 +1,25 @@
    11.5+#define NPRIVATES	16
    11.6+
    11.7+TEXT	_main(SB), 1, $(16 + NPRIVATES*8)
    11.8+	MOV	$setSB(SB), R28
    11.9+	MOV	R0, _tos(SB)
   11.10+
   11.11+	ADD	$32, RSP, R1
   11.12+	MOV	R1, _privates(SB)
   11.13+	MOVW	$NPRIVATES, R2
   11.14+	MOVW	R2, _nprivates(SB)
   11.15+
   11.16+	MOV	$inargv+0(FP), R1
   11.17+	MOV	R1, 16(RSP)
   11.18+
   11.19+	MOVW	inargc-8(FP), R0
   11.20+	MOV	R0, 8(RSP)
   11.21+
   11.22+	BL	main(SB)
   11.23+loop:
   11.24+	MOV	$_exitstr<>(SB), R0
   11.25+	BL	exits(SB)
   11.26+	B	loop
   11.27+
   11.28+DATA	_exitstr<>+0(SB)/4, $"main"
   11.29+GLOBL	_exitstr<>+0(SB), $5
    12.1new file mode 100644
    12.2--- /dev/null
    12.3+++ b/sys/src/libc/arm64/main9p.s
    12.4@@ -0,0 +1,38 @@
    12.5+#define NPRIVATES	16
    12.6+
    12.7+TEXT	_mainp(SB), 1, $(16 + NPRIVATES*8)
    12.8+	MOV	$setSB(SB), R28
    12.9+	MOV	R0, _tos(SB)
   12.10+
   12.11+	ADD	$32, RSP, R1
   12.12+	MOV	R1, _privates(SB)
   12.13+	MOVW	$NPRIVATES, R2
   12.14+	MOVW	R2, _nprivates(SB)
   12.15+
   12.16+	BL	_profmain(SB)
   12.17+
   12.18+	MOV	_tos(SB), R0	/* _tos->prof.pp = _tos->prof.next; */
   12.19+	MOV	8(R0), R1
   12.20+	MOV	R1, 0(R0)
   12.21+
   12.22+	MOV	$inargv+0(FP), R1
   12.23+	MOV	R1, 16(RSP)
   12.24+
   12.25+	MOVW	inargc-8(FP), R0
   12.26+	MOV	R0, 8(RSP)
   12.27+
   12.28+	BL	main(SB)
   12.29+loop:
   12.30+	MOV	$_exitstr<>(SB), R0
   12.31+	BL	exits(SB)
   12.32+	MOV	$_profin(SB), R0
   12.33+	B	loop
   12.34+
   12.35+TEXT	_callpc(SB), 1, $-4
   12.36+	MOV	0(SP), R0
   12.37+TEXT	_saveret(SB), 1, $-4
   12.38+TEXT	_savearg(SB), 1, $-4
   12.39+	RETURN
   12.40+
   12.41+DATA	_exitstr<>+0(SB)/4, $"main"
   12.42+GLOBL	_exitstr<>+0(SB), $5
    13.1new file mode 100644
    13.2--- /dev/null
    13.3+++ b/sys/src/libc/arm64/mkfile
    13.4@@ -0,0 +1,31 @@
    13.5+objtype=arm64
    13.6+</$objtype/mkfile
    13.7+OS=7
    13.8+
    13.9+LIB=/$objtype/lib/libc.a
   13.10+SFILES=\
   13.11+	argv0.s\
   13.12+	atom.s\
   13.13+	cycles.s\
   13.14+	getcallerpc.s\
   13.15+	getfcr.s\
   13.16+	main9.s\
   13.17+	main9p.s\
   13.18+	setjmp.s\
   13.19+	tas.s\
   13.20+
   13.21+CFILES=\
   13.22+	lock.c\
   13.23+	notejmp.c\
   13.24+	_seek.c\
   13.25+
   13.26+HFILES=/sys/include/libc.h
   13.27+
   13.28+OFILES=${CFILES:%.c=%.$O} ${SFILES:%.s=%.$O}
   13.29+
   13.30+UPDATE=mkfile\
   13.31+	$HFILES\
   13.32+	$CFILES\
   13.33+	$SFILES\
   13.34+
   13.35+</sys/src/cmd/mksyslib
    14.1new file mode 100644
    14.2--- /dev/null
    14.3+++ b/sys/src/libc/arm64/notejmp.c
    14.4@@ -0,0 +1,16 @@
    14.5+#include <u.h>
    14.6+#include <libc.h>
    14.7+#include <ureg.h>
    14.8+
    14.9+void
   14.10+notejmp(void *vr, jmp_buf j, int ret)
   14.11+{
   14.12+	struct Ureg *r = vr;
   14.13+
   14.14+	r->r0 = ret;
   14.15+	if(ret == 0)
   14.16+		r->r0 = 1;
   14.17+	r->pc = j[JMPBUFPC];
   14.18+	r->sp = j[JMPBUFSP];
   14.19+	noted(NCONT);
   14.20+}
    15.1new file mode 100644
    15.2--- /dev/null
    15.3+++ b/sys/src/libc/arm64/setjmp.s
    15.4@@ -0,0 +1,17 @@
    15.5+TEXT setjmp(SB), 1, $-4
    15.6+	MOV	LR, 8(R0)
    15.7+	MOV	SP, R1
    15.8+	MOV	R1, 0(R0)
    15.9+	MOV	$0, R0
   15.10+	RETURN
   15.11+
   15.12+TEXT longjmp(SB), 1, $-4
   15.13+	MOV	8(R0), LR
   15.14+	MOV	0(R0), R1
   15.15+	MOVW	arg+8(FP), R0
   15.16+	MOV	R1, SP
   15.17+	CBZ	R0, _one
   15.18+	RETURN
   15.19+_one:
   15.20+	MOV	$1, R0
   15.21+	RETURN
    16.1new file mode 100644
    16.2--- /dev/null
    16.3+++ b/sys/src/libc/arm64/tas.s
    16.4@@ -0,0 +1,11 @@
    16.5+TEXT	_tas(SB), 1, $-4
    16.6+	MOVW	$1, R2
    16.7+_tas1:
    16.8+	LDXRW	(R0), R1
    16.9+	STXRW	R2, (R0), R3
   16.10+	CBNZ	R3, _tas1
   16.11+	MOVW	R1, R0
   16.12+
   16.13+TEXT	_barrier(SB), 1, $-4
   16.14+	DMB	$0xB	// ISH
   16.15+	RETURN