changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: ape: initial support for arm64

changeset 7190: 41fb44a3b2dc
parent 7189: 5f30fb0ada5d
child 7191: 753613b3b8c4
author: cinap_lenrek@felloff.net
date: Fri, 03 May 2019 21:06:46 +0200
files: arm64/include/ape/float.h arm64/include/ape/math.h arm64/include/ape/stdarg.h arm64/include/ape/stdint.h arm64/include/ape/ureg.h sys/src/ape/lib/9/arm64/getcallerpc.s sys/src/ape/lib/9/arm64/getfcr.s sys/src/ape/lib/ap/arm64/_seek.c sys/src/ape/lib/ap/arm64/getfcr.s sys/src/ape/lib/ap/arm64/lock.c sys/src/ape/lib/ap/arm64/main9.s sys/src/ape/lib/ap/arm64/mkfile sys/src/ape/lib/ap/arm64/notetramp.c sys/src/ape/lib/ap/arm64/setjmp.s sys/src/ape/lib/ap/arm64/tas.s sys/src/ape/lib/mp/arm64/mkfile sys/src/ape/lib/sec/arm64/mkfile sys/src/cmd/pcc.c
description: ape: initial support for arm64
     1.1new file mode 100644
     1.2--- /dev/null
     1.3+++ b/arm64/include/ape/float.h
     1.4@@ -0,0 +1,73 @@
     1.5+#ifndef __FLOAT
     1.6+#define __FLOAT
     1.7+/* IEEE, default rounding */
     1.8+
     1.9+#define FLT_ROUNDS	1
    1.10+#define FLT_RADIX	2
    1.11+
    1.12+#define FLT_DIG		6
    1.13+#define FLT_EPSILON	1.19209290e-07
    1.14+#define FLT_MANT_DIG	24
    1.15+#define FLT_MAX		3.40282347e+38
    1.16+#define FLT_MAX_10_EXP	38
    1.17+#define FLT_MAX_EXP	128
    1.18+#define FLT_MIN		1.17549435e-38
    1.19+#define FLT_MIN_10_EXP	-37
    1.20+#define FLT_MIN_EXP	-125
    1.21+
    1.22+#define DBL_DIG		15
    1.23+#define DBL_EPSILON	2.2204460492503131e-16
    1.24+#define DBL_MANT_DIG	53
    1.25+#define DBL_MAX		1.797693134862315708145e+308
    1.26+#define DBL_MAX_10_EXP	308
    1.27+#define DBL_MAX_EXP	1024
    1.28+#define DBL_MIN		2.225073858507201383090233e-308
    1.29+#define DBL_MIN_10_EXP	-307
    1.30+#define DBL_MIN_EXP	-1021
    1.31+#define LDBL_MANT_DIG	DBL_MANT_DIG
    1.32+#define LDBL_EPSILON	DBL_EPSILON
    1.33+#define LDBL_DIG	DBL_DIG
    1.34+#define LDBL_MIN_EXP	DBL_MIN_EXP
    1.35+#define LDBL_MIN	DBL_MIN
    1.36+#define LDBL_MIN_10_EXP	DBL_MIN_10_EXP
    1.37+#define LDBL_MAX_EXP	DBL_MAX_EXP
    1.38+#define LDBL_MAX	DBL_MAX
    1.39+#define LDBL_MAX_10_EXP	DBL_MAX_10_EXP
    1.40+
    1.41+typedef 	union FPdbleword FPdbleword;
    1.42+union FPdbleword
    1.43+{
    1.44+	double	x;
    1.45+	struct {	/* little endian */
    1.46+		long lo;
    1.47+		long hi;
    1.48+	};
    1.49+};
    1.50+
    1.51+#ifdef _RESEARCH_SOURCE
    1.52+/* define stuff needed for floating conversion */
    1.53+#define IEEE_8087	1
    1.54+#define Sudden_Underflow 1
    1.55+#endif
    1.56+#ifdef _PLAN9_SOURCE
    1.57+/* FCR */
    1.58+#define	FPINEX	(1<<5)
    1.59+#define	FPOVFL	(1<<3)
    1.60+#define	FPUNFL	((1<<4)|(1<<1))
    1.61+#define	FPZDIV	(1<<2)
    1.62+#define	FPRNR	(0<<10)
    1.63+#define	FPRZ	(3<<10)
    1.64+#define	FPRPINF	(2<<10)
    1.65+#define	FPRNINF	(1<<10)
    1.66+#define	FPRMASK	(3<<10)
    1.67+#define	FPPEXT	(3<<8)
    1.68+#define	FPPSGL	(0<<8)
    1.69+#define	FPPDBL	(2<<8)
    1.70+#define	FPPMASK	(3<<8)
    1.71+/* FSR */
    1.72+#define	FPAINEX	FPINEX
    1.73+#define	FPAOVFL	FPOVFL
    1.74+#define	FPAUNFL	FPUNFL
    1.75+#define	FPAZDIV	FPZDIV
    1.76+#endif
    1.77+#endif /* __FLOAT */
     2.1new file mode 100644
     2.2--- /dev/null
     2.3+++ b/arm64/include/ape/math.h
     2.4@@ -0,0 +1,79 @@
     2.5+#ifndef __MATH
     2.6+#define __MATH
     2.7+#pragma lib "/$M/lib/ape/libap.a"
     2.8+
     2.9+/* a HUGE_VAL appropriate for IEEE double-precision */
    2.10+/* the correct value, 1.797693134862316e+308, causes a ken overflow */
    2.11+#define HUGE_VAL 1.79769313486231e+308
    2.12+
    2.13+#ifdef __cplusplus
    2.14+extern "C" {
    2.15+#endif
    2.16+
    2.17+extern double acos(double);
    2.18+extern double asin(double);
    2.19+extern double atan(double);
    2.20+extern double atan2(double, double);
    2.21+extern double cos(double);
    2.22+extern double hypot(double, double);
    2.23+extern double sin(double);
    2.24+extern double tan(double);
    2.25+extern double cosh(double);
    2.26+extern double sinh(double);
    2.27+extern double tanh(double);
    2.28+extern double exp(double);
    2.29+extern double frexp(double, int *);
    2.30+extern double ldexp(double, int);
    2.31+extern double log(double);
    2.32+extern double log10(double);
    2.33+extern double modf(double, double *);
    2.34+extern double pow(double, double);
    2.35+extern double sqrt(double);
    2.36+extern double ceil(double);
    2.37+extern double fabs(double);
    2.38+extern double floor(double);
    2.39+extern double fmod(double, double);
    2.40+extern double NaN(void);
    2.41+extern int isNaN(double);
    2.42+extern double Inf(int);
    2.43+extern int isInf(double, int);
    2.44+extern double fmin(double, double);
    2.45+
    2.46+#ifdef _RESEARCH_SOURCE
    2.47+/* does >> treat left operand as unsigned ? */
    2.48+#define Unsigned_Shifts 1
    2.49+#define	M_E		2.7182818284590452354	/* e */
    2.50+#define	M_LOG2E		1.4426950408889634074	/* log 2e */
    2.51+#define	M_LOG10E	0.43429448190325182765	/* log 10e */
    2.52+#define	M_LN2		0.69314718055994530942	/* log e2 */
    2.53+#define	M_LN10		2.30258509299404568402	/* log e10 */
    2.54+#define	M_PI		3.14159265358979323846	/* pi */
    2.55+#define	M_PI_2		1.57079632679489661923	/* pi/2 */
    2.56+#define	M_PI_4		0.78539816339744830962	/* pi/4 */
    2.57+#define	M_1_PI		0.31830988618379067154	/* 1/pi */
    2.58+#define	M_2_PI		0.63661977236758134308	/* 2/pi */
    2.59+#define	M_2_SQRTPI	1.12837916709551257390	/* 2/sqrt(pi) */
    2.60+#define	M_SQRT2		1.41421356237309504880	/* sqrt(2) */
    2.61+#define	M_SQRT1_2	0.70710678118654752440	/* 1/sqrt(2) */
    2.62+
    2.63+extern double hypot(double, double);
    2.64+extern double erf(double);
    2.65+extern double erfc(double);
    2.66+extern double j0(double);
    2.67+extern double y0(double);
    2.68+extern double j1(double);
    2.69+extern double y1(double);
    2.70+extern double jn(int, double);
    2.71+extern double yn(int, double);
    2.72+
    2.73+#endif
    2.74+
    2.75+
    2.76+#ifdef __cplusplus
    2.77+}
    2.78+#endif
    2.79+
    2.80+#define isnan(x) isNaN(x)
    2.81+#define isinf(x) isInf(x)
    2.82+
    2.83+#endif /* __MATH */
     3.1new file mode 100644
     3.2--- /dev/null
     3.3+++ b/arm64/include/ape/stdarg.h
     3.4@@ -0,0 +1,18 @@
     3.5+#ifndef __STDARG
     3.6+#define __STDARG
     3.7+
     3.8+typedef char *va_list;
     3.9+
    3.10+#define va_start(list, start) list = (sizeof(start)<8 ? (char *)((long long *)&(start)+1) : \
    3.11+(char *)(&(start)+1))
    3.12+#define va_end(list)
    3.13+#define va_arg(list, mode)\
    3.14+	((sizeof(mode) == 1)?\
    3.15+		((mode*)(list += 8))[-8]:\
    3.16+	(sizeof(mode) == 2)?\
    3.17+		((mode*)(list += 8))[-4]:\
    3.18+	(sizeof(mode) == 4)?\
    3.19+		((mode*)(list += 8))[-2]:\
    3.20+		((mode*)(list += sizeof(mode)))[-1])
    3.21+
    3.22+#endif /* __STDARG */
     4.1new file mode 100644
     4.2--- /dev/null
     4.3+++ b/arm64/include/ape/stdint.h
     4.4@@ -0,0 +1,31 @@
     4.5+#ifndef _STDINT_H_
     4.6+#define _STDINT_H_ 1
     4.7+
     4.8+typedef char int8_t;
     4.9+typedef short int16_t;
    4.10+typedef int int32_t;
    4.11+typedef long long int64_t;
    4.12+typedef unsigned char uint8_t;
    4.13+typedef unsigned short uint16_t;
    4.14+typedef unsigned int uint32_t;
    4.15+typedef unsigned long long uint64_t;
    4.16+
    4.17+typedef long long intptr_t;
    4.18+typedef unsigned long long uintptr_t;
    4.19+
    4.20+#define INT8_MIN	0x80
    4.21+#define INT16_MIN	0x8000
    4.22+#define INT32_MIN	0x80000000
    4.23+#define INT64_MIN	0x8000000000000000LL
    4.24+
    4.25+#define INT8_MAX	0x7f
    4.26+#define INT16_MAX	0x7fff
    4.27+#define INT32_MAX	0x7fffffff
    4.28+#define INT64_MAX	0x7fffffffffffffffULL
    4.29+
    4.30+#define UINT8_MAX	0xff
    4.31+#define UINT16_MAX	0xffff
    4.32+#define UINT32_MAX	0xffffffffL
    4.33+#define UINT64_MAX	0xffffffffffffffffULL
    4.34+
    4.35+#endif
     5.1new file mode 100644
     5.2--- /dev/null
     5.3+++ b/arm64/include/ape/ureg.h
     5.4@@ -0,0 +1,50 @@
     5.5+#ifndef __UREG_H
     5.6+#define __UREG_H
     5.7+#if !defined(_PLAN9_SOURCE)
     5.8+    This header file is an extension to ANSI/POSIX
     5.9+#endif
    5.10+
    5.11+struct Ureg {
    5.12+	unsigned long long	r0;
    5.13+	unsigned long long	r1;
    5.14+	unsigned long long	r2;
    5.15+	unsigned long long	r3;
    5.16+	unsigned long long	r4;
    5.17+	unsigned long long	r5;
    5.18+	unsigned long long	r6;
    5.19+	unsigned long long	r7;
    5.20+	unsigned long long	r8;
    5.21+	unsigned long long	r9;
    5.22+	unsigned long long	r10;
    5.23+	unsigned long long	r11;
    5.24+	unsigned long long	r12;
    5.25+	unsigned long long	r13;
    5.26+	unsigned long long	r14;
    5.27+	unsigned long long	r15;
    5.28+	unsigned long long	r16;
    5.29+	unsigned long long	r17;
    5.30+	unsigned long long	r18;
    5.31+	unsigned long long	r19;
    5.32+	unsigned long long	r20;
    5.33+	unsigned long long	r21;
    5.34+	unsigned long long	r22;
    5.35+	unsigned long long	r23;
    5.36+	unsigned long long	r24;
    5.37+	unsigned long long	r25;
    5.38+	unsigned long long	r26;
    5.39+	unsigned long long	r27;
    5.40+	unsigned long long	r28;	/* sb */
    5.41+	union {
    5.42+		unsigned long long	r29;
    5.43+		unsigned long long	sp;
    5.44+	};
    5.45+	union {
    5.46+		unsigned long long	r30;
    5.47+		unsigned long long	link;
    5.48+	};
    5.49+	unsigned long long	type;	/* of exception */
    5.50+	unsigned long long	psr;
    5.51+	unsigned long long	pc;	/* interrupted addr */
    5.52+};
    5.53+
    5.54+#endif
     6.1new file mode 100644
     6.2--- /dev/null
     6.3+++ b/sys/src/ape/lib/9/arm64/getcallerpc.s
     6.4@@ -0,0 +1,3 @@
     6.5+TEXT getcallerpc(SB), $0
     6.6+	MOV	0(SP), R0
     6.7+	RETURN
     7.1new file mode 100644
     7.2--- /dev/null
     7.3+++ b/sys/src/ape/lib/9/arm64/getfcr.s
     7.4@@ -0,0 +1,21 @@
     7.5+#define	SYSARG5(op0,op1,Cn,Cm,op2)	((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5)
     7.6+
     7.7+#define	FPCR		SPR(SYSARG5(3,3,4,4,0))
     7.8+#define	FPSR		SPR(SYSARG5(3,3,4,4,1))
     7.9+
    7.10+TEXT	setfcr(SB), $0
    7.11+	MSR	R0, FPCR
    7.12+	RETURN
    7.13+
    7.14+TEXT	getfcr(SB), $0
    7.15+	MRS	FPCR, R0
    7.16+	RETURN
    7.17+
    7.18+TEXT	getfsr(SB), $0
    7.19+	MRS	FPSR, R0
    7.20+	RETURN
    7.21+
    7.22+TEXT	setfsr(SB), $0
    7.23+	MSR	R0, FPSR
    7.24+	RETURN
    7.25+
     8.1new file mode 100644
     8.2--- /dev/null
     8.3+++ b/sys/src/ape/lib/ap/arm64/_seek.c
     8.4@@ -0,0 +1,11 @@
     8.5+extern long __SEEK(long long*, int, long long, int);
     8.6+
     8.7+long long
     8.8+_SEEK(int fd, long long o, int p)
     8.9+{
    8.10+	long long l;
    8.11+
    8.12+	if(__SEEK(&l, fd, o, p) < 0)
    8.13+		l = -1;
    8.14+	return l;
    8.15+}
     9.1new file mode 100644
     9.2--- /dev/null
     9.3+++ b/sys/src/ape/lib/ap/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/ape/lib/ap/arm64/lock.c
    10.4@@ -0,0 +1,43 @@
    10.5+#define _LOCK_EXTENSION
    10.6+#include "../plan9/sys9.h"
    10.7+#include <lock.h>
    10.8+
    10.9+extern int	tas(int*);
   10.10+extern unsigned long long _barrier(unsigned long long);
   10.11+
   10.12+void
   10.13+lock(Lock *lk)
   10.14+{
   10.15+	int i;
   10.16+
   10.17+	/* once fast */
   10.18+	if(!tas(&lk->val))
   10.19+		return;
   10.20+	/* a thousand times pretty fast */
   10.21+	for(i=0; i<1000; i++){
   10.22+		if(!tas(&lk->val))
   10.23+			return;
   10.24+		_SLEEP(0);
   10.25+	}
   10.26+	/* now nice and slow */
   10.27+	for(i=0; i<1000; i++){
   10.28+		if(!tas(&lk->val))
   10.29+			return;
   10.30+		_SLEEP(100);
   10.31+	}
   10.32+	/* take your time */
   10.33+	while(tas(&lk->val))
   10.34+		_SLEEP(1000);
   10.35+}
   10.36+
   10.37+int
   10.38+canlock(Lock *lk)
   10.39+{
   10.40+	return tas(&lk->val) == 0;
   10.41+}
   10.42+
   10.43+void
   10.44+unlock(Lock *lk)
   10.45+{
   10.46+	lk->val = _barrier(0);
   10.47+}
    11.1new file mode 100644
    11.2--- /dev/null
    11.3+++ b/sys/src/ape/lib/ap/arm64/main9.s
    11.4@@ -0,0 +1,39 @@
    11.5+#define NPRIVATES	16
    11.6+
    11.7+GLOBL	_tos(SB), $8
    11.8+GLOBL	_errnoloc(SB), $8
    11.9+GLOBL	_plan9err(SB), $128
   11.10+GLOBL	_privates(SB), $8
   11.11+GLOBL	_nprivates(SB), $4
   11.12+
   11.13+TEXT	_main(SB), 1, $(32 + 8+128 + NPRIVATES*8)
   11.14+	MOV	$setSB(SB), R28
   11.15+	MOV	R0, _tos(SB)
   11.16+
   11.17+	ADD	$32, RSP, R1
   11.18+
   11.19+	MOV	R1, _errnoloc(SB)
   11.20+	ADD	$8, R1
   11.21+
   11.22+	MOV	R1, _plan9err(SB)
   11.23+	ADD	$128, R1
   11.24+
   11.25+	MOV	R1, _privates(SB)
   11.26+	MOVW	$NPRIVATES, R2
   11.27+	MOVW	R2, _nprivates(SB)
   11.28+
   11.29+	BL	_envsetup(SB)
   11.30+
   11.31+	MOV	environ(SB), R2
   11.32+	MOV	R2, 24(RSP)
   11.33+
   11.34+	MOV	$inargv+0(FP), R1
   11.35+	MOV	R1, 16(RSP)
   11.36+
   11.37+	MOVW	inargc-8(FP), R0
   11.38+	MOV	R0, 8(RSP)
   11.39+
   11.40+	BL	main(SB)
   11.41+loop:
   11.42+	BL	exit(SB)
   11.43+	B	loop
    12.1new file mode 100644
    12.2--- /dev/null
    12.3+++ b/sys/src/ape/lib/ap/arm64/mkfile
    12.4@@ -0,0 +1,16 @@
    12.5+APE=/sys/src/ape
    12.6+<$APE/config
    12.7+LIB=/$objtype/lib/ape/libap.a
    12.8+OFILES=\
    12.9+	_seek.$O\
   12.10+	getfcr.$O\
   12.11+	lock.$O\
   12.12+	main9.$O\
   12.13+	notetramp.$O\
   12.14+	setjmp.$O\
   12.15+	tas.$O\
   12.16+
   12.17+</sys/src/cmd/mksyslib
   12.18+
   12.19+CFLAGS=-c -D_POSIX_SOURCE -D_PLAN9_SOURCE
   12.20+
    13.1new file mode 100644
    13.2--- /dev/null
    13.3+++ b/sys/src/ape/lib/ap/arm64/notetramp.c
    13.4@@ -0,0 +1,72 @@
    13.5+#include "../plan9/lib.h"
    13.6+#include "../plan9/sys9.h"
    13.7+#include <signal.h>
    13.8+#include <setjmp.h>
    13.9+
   13.10+/* A stack to hold pcs when signals nest */
   13.11+#define MAXSIGSTACK 20
   13.12+typedef struct Pcstack Pcstack;
   13.13+static struct Pcstack {
   13.14+	int sig;
   13.15+	void (*hdlr)(int, char*, Ureg*);
   13.16+	unsigned long long restorepc;
   13.17+	Ureg *u;
   13.18+} pcstack[MAXSIGSTACK];
   13.19+static int nstack = 0;
   13.20+
   13.21+static void notecont(Ureg*, char*);
   13.22+
   13.23+void
   13.24+_notetramp(int sig, void (*hdlr)(int, char*, Ureg*), Ureg *u)
   13.25+{
   13.26+	Pcstack *p;
   13.27+
   13.28+	if(nstack >= MAXSIGSTACK)
   13.29+		_NOTED(1);	/* nesting too deep; just do system default */
   13.30+	p = &pcstack[nstack];
   13.31+	p->restorepc = u->pc;
   13.32+	p->sig = sig;
   13.33+	p->hdlr = hdlr;
   13.34+	p->u = u;
   13.35+	nstack++;
   13.36+	u->pc = (unsigned long long) notecont;
   13.37+	_NOTED(2);	/* NSAVE: clear note but hold state */
   13.38+}
   13.39+
   13.40+static void
   13.41+notecont(Ureg *u, char *s)
   13.42+{
   13.43+	Pcstack *p;
   13.44+	void(*f)(int, char*, Ureg*);
   13.45+
   13.46+	p = &pcstack[nstack-1];
   13.47+	f = p->hdlr;
   13.48+	u->pc = p->restorepc;
   13.49+	nstack--;
   13.50+	(*f)(p->sig, s, u);
   13.51+	_NOTED(3);	/* NRSTR */
   13.52+}
   13.53+
   13.54+#define JMPBUFPC 1
   13.55+#define JMPBUFSP 0
   13.56+
   13.57+extern sigset_t	_psigblocked;
   13.58+
   13.59+void
   13.60+siglongjmp(sigjmp_buf j, int ret)
   13.61+{
   13.62+	struct Ureg *u;
   13.63+
   13.64+	if(j[0])
   13.65+		_psigblocked = j[1];
   13.66+	if(nstack == 0 || pcstack[nstack-1].u->sp > j[2+JMPBUFSP])
   13.67+		longjmp(j+2, ret);
   13.68+	u = pcstack[nstack-1].u;
   13.69+	nstack--;
   13.70+	u->r0 = ret;
   13.71+	if(ret == 0)
   13.72+		u->r0 = 1;
   13.73+	u->pc = j[2+JMPBUFPC];
   13.74+	u->sp = j[2+JMPBUFSP];
   13.75+	_NOTED(3);	/* NRSTR */
   13.76+}
    14.1new file mode 100644
    14.2--- /dev/null
    14.3+++ b/sys/src/ape/lib/ap/arm64/setjmp.s
    14.4@@ -0,0 +1,26 @@
    14.5+TEXT sigsetjmp(SB), 1, $-4
    14.6+	MOVW	savemask+8(FP), R1
    14.7+	MOVW	_psigblocked(SB), R2
    14.8+	MOVW	R1, 0(R0)
    14.9+	MOVW	R2, 4(R0)
   14.10+	ADD	$8, R0
   14.11+	/* wet floor */
   14.12+
   14.13+TEXT setjmp(SB), 1, $-4
   14.14+	MOV	LR, 8(R0)
   14.15+	MOV	SP, R1
   14.16+	MOV	R1, 0(R0)
   14.17+	MOV	$0, R0
   14.18+	RETURN
   14.19+
   14.20+
   14.21+TEXT longjmp(SB), 1, $-4
   14.22+	MOV	8(R0), LR
   14.23+	MOV	0(R0), R1
   14.24+	MOVW	arg+8(FP), R0
   14.25+	MOV	R1, SP
   14.26+	CBZ	R0, _one
   14.27+	RETURN
   14.28+_one:
   14.29+	MOV	$1, R0
   14.30+	RETURN
    15.1new file mode 100644
    15.2--- /dev/null
    15.3+++ b/sys/src/ape/lib/ap/arm64/tas.s
    15.4@@ -0,0 +1,11 @@
    15.5+TEXT	tas(SB), 1, $-4
    15.6+	MOVW	$1, R2
    15.7+_tas1:
    15.8+	LDXRW	(R0), R1
    15.9+	STXRW	R2, (R0), R3
   15.10+	CBNZ	R3, _tas1
   15.11+	MOVW	R1, R0
   15.12+
   15.13+TEXT	_barrier(SB), 1, $-4
   15.14+	DMB	$0xB	// ISH
   15.15+	RETURN
    16.1new file mode 100644
    16.2--- /dev/null
    16.3+++ b/sys/src/ape/lib/mp/arm64/mkfile
    16.4@@ -0,0 +1,8 @@
    16.5+APE=/sys/src/ape
    16.6+<$APE/config
    16.7+
    16.8+objtype=arm64
    16.9+</$objtype/mkfile
   16.10+
   16.11+install clean all update:V:
   16.12+	
    17.1new file mode 100644
    17.2--- /dev/null
    17.3+++ b/sys/src/ape/lib/sec/arm64/mkfile
    17.4@@ -0,0 +1,8 @@
    17.5+APE=/sys/src/ape
    17.6+<$APE/config
    17.7+
    17.8+objtype=arm64
    17.9+</$objtype/mkfile
   17.10+
   17.11+install clean all update:V:
   17.12+	
    18.1--- a/sys/src/cmd/pcc.c
    18.2+++ b/sys/src/cmd/pcc.c
    18.3@@ -16,6 +16,7 @@ Objtype objtype[] = {
    18.4 	{"68020",	"2c", "2l", "2", "2.out"},
    18.5 	{"arm",		"5c", "5l", "5", "5.out"},
    18.6 	{"amd64",	"6c", "6l", "6", "6.out"},
    18.7+	{"arm64",	"7c", "7l", "7", "7.out"},
    18.8 	{"386",		"8c", "8l", "8", "8.out"},
    18.9 	{"power64",	"9c", "9l", "9", "9.out"},
   18.10 	{"sparc",	"kc", "kl", "k", "k.out"},