--- /dev/null Thu Mar 12 09:23:01 2026 +++ /arm64/include/ape/_apetypes.h Thu Mar 5 20:40:32 2026 @@ -0,0 +1,3 @@ +#ifndef _BITS64 +#define _BITS64 +#endif --- /dev/null Thu Mar 12 09:23:01 2026 +++ /arm64/include/ape/float.h Thu Mar 5 20:40:32 2026 @@ -0,0 +1,73 @@ +#ifndef __FLOAT +#define __FLOAT +/* IEEE, default rounding */ + +#define FLT_ROUNDS 1 +#define FLT_RADIX 2 + +#define FLT_DIG 6 +#define FLT_EPSILON 1.19209290e-07 +#define FLT_MANT_DIG 24 +#define FLT_MAX 3.40282347e+38 +#define FLT_MAX_10_EXP 38 +#define FLT_MAX_EXP 128 +#define FLT_MIN 1.17549435e-38 +#define FLT_MIN_10_EXP -37 +#define FLT_MIN_EXP -125 + +#define DBL_DIG 15 +#define DBL_EPSILON 2.2204460492503131e-16 +#define DBL_MANT_DIG 53 +#define DBL_MAX 1.797693134862315708145e+308 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define DBL_MIN 2.225073858507201383090233e-308 +#define DBL_MIN_10_EXP -307 +#define DBL_MIN_EXP -1021 +#define LDBL_MANT_DIG DBL_MANT_DIG +#define LDBL_EPSILON DBL_EPSILON +#define LDBL_DIG DBL_DIG +#define LDBL_MIN_EXP DBL_MIN_EXP +#define LDBL_MIN DBL_MIN +#define LDBL_MIN_10_EXP DBL_MIN_10_EXP +#define LDBL_MAX_EXP DBL_MAX_EXP +#define LDBL_MAX DBL_MAX +#define LDBL_MAX_10_EXP DBL_MAX_10_EXP + +typedef union FPdbleword FPdbleword; +union FPdbleword +{ + double x; + struct { /* little endian */ + long lo; + long hi; + }; +}; + +#ifdef _RESEARCH_SOURCE +/* define stuff needed for floating conversion */ +#define IEEE_8087 1 +#define Sudden_Underflow 1 +#endif +#ifdef _PLAN9_SOURCE +/* FCR */ +#define FPINEX (1<<5) +#define FPOVFL (1<<3) +#define FPUNFL ((1<<4)|(1<<1)) +#define FPZDIV (1<<2) +#define FPRNR (0<<10) +#define FPRZ (3<<10) +#define FPRPINF (2<<10) +#define FPRNINF (1<<10) +#define FPRMASK (3<<10) +#define FPPEXT (3<<8) +#define FPPSGL (0<<8) +#define FPPDBL (2<<8) +#define FPPMASK (3<<8) +/* FSR */ +#define FPAINEX FPINEX +#define FPAOVFL FPOVFL +#define FPAUNFL FPUNFL +#define FPAZDIV FPZDIV +#endif +#endif /* __FLOAT */ --- /dev/null Thu Mar 12 09:23:01 2026 +++ /arm64/include/ape/math.h Thu Mar 5 20:40:32 2026 @@ -0,0 +1,74 @@ +#ifndef __MATH +#define __MATH +#pragma lib "/$M/lib/ape/libap.a" + +/* a HUGE_VAL appropriate for IEEE double-precision */ +/* the correct value, 1.797693134862316e+308, causes a ken overflow */ +#define HUGE_VAL 1.79769313486231e+308 + +#ifdef __cplusplus +extern "C" { +#endif + +extern double acos(double); +extern double asin(double); +extern double atan(double); +extern double atan2(double, double); +extern double cos(double); +extern double sin(double); +extern double tan(double); +extern double cosh(double); +extern double sinh(double); +extern double tanh(double); +extern double exp(double); +extern double frexp(double, int *); +extern double ldexp(double, int); +extern double log(double); +extern double log10(double); +extern double modf(double, double *); +extern double pow(double, double); +extern double sqrt(double); +extern double ceil(double); +extern double fabs(double); +extern double floor(double); +extern double fmod(double, double); +extern double NaN(void); +extern int isNaN(double); +extern double Inf(int); +extern int isInf(double, int); + +#ifdef _RESEARCH_SOURCE +/* does >> treat left operand as unsigned ? */ +#define Unsigned_Shifts 1 +#define M_E 2.7182818284590452354 /* e */ +#define M_LOG2E 1.4426950408889634074 /* log 2e */ +#define M_LOG10E 0.43429448190325182765 /* log 10e */ +#define M_LN2 0.69314718055994530942 /* log e2 */ +#define M_LN10 2.30258509299404568402 /* log e10 */ +#define M_PI 3.14159265358979323846 /* pi */ +#define M_PI_2 1.57079632679489661923 /* pi/2 */ +#define M_PI_4 0.78539816339744830962 /* pi/4 */ +#define M_1_PI 0.31830988618379067154 /* 1/pi */ +#define M_2_PI 0.63661977236758134308 /* 2/pi */ +#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ + +extern double hypot(double, double); +extern double erf(double); +extern double erfc(double); +extern double j0(double); +extern double y0(double); +extern double j1(double); +extern double y1(double); +extern double jn(int, double); +extern double yn(int, double); + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* __MATH */ --- /dev/null Thu Mar 12 09:23:01 2026 +++ /arm64/include/ape/stdarg.h Thu Mar 5 20:40:32 2026 @@ -0,0 +1,18 @@ +#ifndef __STDARG +#define __STDARG + +typedef char *va_list; + +#define va_start(list, start) list = (sizeof(start)<8 ? (char *)((long long *)&(start)+1) : \ +(char *)(&(start)+1)) +#define va_end(list) +#define va_arg(list, mode)\ + ((sizeof(mode) == 1)?\ + ((mode*)(list += 8))[-8]:\ + (sizeof(mode) == 2)?\ + ((mode*)(list += 8))[-4]:\ + (sizeof(mode) == 4)?\ + ((mode*)(list += 8))[-2]:\ + ((mode*)(list += sizeof(mode)))[-1]) + +#endif /* __STDARG */ --- /dev/null Thu Mar 12 09:23:01 2026 +++ /arm64/include/ape/ureg.h Thu Mar 5 20:40:32 2026 @@ -0,0 +1,44 @@ +#ifndef __UREG_H +#define __UREG_H +#if !defined(_PLAN9_SOURCE) + This header file is an extension to ANSI/POSIX +#endif +typedef struct Ureg { + unsigned long long r0; + unsigned long long r1; + unsigned long long r2; + unsigned long long r3; + unsigned long long r4; + unsigned long long r5; + unsigned long long r6; + unsigned long long r7; + unsigned long long r8; + unsigned long long r9; + unsigned long long r10; + unsigned long long r11; + unsigned long long r12; + unsigned long long r13; + unsigned long long r14; + unsigned long long r15; + unsigned long long r16; + unsigned long long r17; + unsigned long long r18; + unsigned long long r19; + unsigned long long r20; + unsigned long long r21; + unsigned long long r22; + unsigned long long r23; + unsigned long long r24; + unsigned long long r25; + unsigned long long r26; + unsigned long long r27; + unsigned long long r28; + unsigned long long r29; + unsigned long long r30; + unsigned long long sp; + unsigned long long link; + unsigned long long pc; /* interrupted addr */ + unsigned long type; /* of exception */ + unsigned long psr; +} Ureg; +#endif --- /dev/null Thu Mar 12 09:23:01 2026 +++ /arm64/include/u.h Thu Mar 5 20:40:17 2026 @@ -0,0 +1,70 @@ +#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 long long intptr; +typedef unsigned long long 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; + +/* VFP FCR */ +#define FPINEX (1<<12) /* trap enables for exceptions */ +#define FPUNFL (1<<11) +#define FPOVFL (1<<10) +#define FPZDIV (1<<9) +#define FPINVAL (1<<8) +#define FPRNR (0<<22) +#define FPRZ (1<<22) +#define FPRPINF (2<<22) +#define FPRNINF (3<<22) +#define FPRMASK (3<<22) +#define FPPEXT 0 +#define FPPSGL 0 +#define FPPDBL 0 +#define FPPMASK 0 +/* FSR */ +#define FPAINEX (1<<4) /* accrued exceptions */ +#define FPAUNFL (1<<3) +#define FPAOVFL (1<<2) +#define FPAZDIV (1<<1) +#define FPAINVAL (1<<0) +union FPdbleword +{ + double x; + struct { /* little endian */ + uint lo; + uint 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]) + +#define _BITS64 /* for pool allocator & ape */ --- /dev/null Thu Mar 12 09:23:01 2026 +++ /arm64/include/ureg.h Thu Mar 5 20:40:17 2026 @@ -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; --- /dev/null Thu Mar 12 09:23:01 2026 +++ /arm64/mkfile Thu Mar 5 20:39:56 2026 @@ -0,0 +1,6 @@ + +//#include + +void +lock(Lock *l) +{ + if(ainc(&l->key) == 1) + return; /* changed from 0 -> 1: we hold lock */ + /* otherwise wait in kernel */ + while(_SEMACQUIRE(&l->sem, 1) < 0){ + /* interrupted; try again */ + } +} + +void +unlock(Lock *l) +{ + if(adec(&l->key) == 0) + return; /* changed from 1 -> 0: no contention */ + _SEMRELEASE(&l->sem, 1); +} + +int +canlock(Lock *l) +{ + if(ainc(&l->key) == 1) + return 1; /* changed from 0 -> 1: success */ + /* Undo increment (but don't miss wakeup) */ + if(adec(&l->key) == 0) + return 0; /* changed from 1 -> 0: no contention */ + _SEMRELEASE(&l->sem, 1); + return 0; +} --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/ape/lib/ap/arm64/main9.s Fri Mar 6 17:08:27 2026 @@ -0,0 +1,9 @@ +TEXT _main(SB), 1,$24 + MOV $setSB(SB), R28 + BL _envsetup(SB) + MOV $inargv+0(FP), R0 + MOV R0, 16(RSP) + MOV inargc-8(FP), R0 + BL main(SB) + BL exit(SB) + B -1(PC) --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/ape/lib/ap/arm64/main9p.s Fri Mar 6 16:11:32 2026 @@ -0,0 +1,38 @@ +#define NPRIVATES 16 + +arg=0 +sb=28 + +TEXT _mainp(SB), 1, $(16 + NPRIVATES*8) + MOV $setSB(SB), R(sb) + MOV R(arg), _tos(SB) + + MOV $p-(NPRIVATES*8)(SP), R1 + MOV R1, _privates(SB) + MOV $NPRIVATES, R1 + MOV R1, _nprivates(SB) + + BL _profmain(SB) + /* _tos->prof.pp = _tos->prof.next; */ + MOV _tos(SB), R1 + MOV 8(R1), R0 + MOV R0, 0(R1) + + MOV $inargv+0(FP), R(arg) + MOV R(arg), argv-(8*NPRIVATES+16)(SP) + MOV inargc-8(FP), R(arg) + BL main(SB) +loop: + MOV $_exitstr<>(SB), R(arg) + BL exits(SB) + B loop + +TEXT _savearg(SB), 1, $0 + RETURN + +TEXT _callpc(SB), 1, $0 + MOV 0(SP), R0 + RETURN + +DATA _exitstr<>+0(SB)/4, $"main" +GLOBL _exitstr<>+0(SB), $5 --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/ape/lib/ap/arm64/memmove.s Fri Mar 6 16:11:32 2026 @@ -0,0 +1,114 @@ +TEXT memcpy(SB), $-20 +TEXT memmove(SB), $-20 + MOV R0, s1+0(FP) + + MOVWU n+16(FP), R9 /* count */ + CBZ R9, return + MOV R0, R11 /* dest pointer */ + MOV s2+8(FP), R10 /* source pointer */ + CMP R11, R10 + BEQ return + BLO back + +/* + * byte-at-a-time forward copy to + * get source (R10) vlong aligned. + */ +f1: + ANDS $7, R10, R8 + BEQ f2 + SUBS $1, R9 + BLT return + MOVB (R10)1!, R8 + MOVB R8, (R11)1! + B f1 + +/* + * check that dest is vlong aligned + * if not, just go byte-at-a-time + */ +f2: + ANDS $7, R11, R8 + BEQ f3 + SUBS $1, R9 + BLT return + B f5 +/* + * two-vlongs-at-a-time forward copy + */ +f3: + SUBS $16, R9 + BLT f4 + MOVP (R10)16!, R12, R13 + MOVP R12, R13, (R11)16! + B f3 + +/* + * cleanup byte-at-a-time + */ +f4: + ADDS $15, R9 + BLT return +f5: + MOVB (R10)1!, R8 + MOVB R8, (R11)1! + SUBS $1, R9 + BGE f5 + +return: + MOVW s1+0(FP),R0 + RETURN + +/* + * everything the same, but + * copy backwards + */ +back: + ADD R9, R10 + ADD R9, R11 + +/* + * byte-at-a-time backward copy to + * get source (R10) vlong aligned. + */ +b1: + ANDS $7, R10, R8 + BEQ b2 + SUBS $1, R9 + BLT return + MOVB -1(R10)!, R8 + MOVB R8, -1(R11)! + B b1 + +/* + * check that dest is aligned + * if not, just go byte-at-a-time + */ +b2: + ANDS $7, R11, R8 + BEQ b3 + SUBS $1, R9 + BLT return + B b5 +/* + * two-vlongs-at-a-time backward copy + */ +b3: + SUBS $16, R9 + BLT b4 + MOVP -16(R10)!, R12, R13 + MOVP R12, R13, -16(R11)! + B b3 + +/* + * cleanup byte-at-a-time backward + */ +b4: + ADDS $15, R9 + BLT return +b5: + MOVB -1(R10)!, R8 + MOVB R8, -1(R11)! + SUBS $1, R9 + BGE b5 + B return --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/ape/lib/ap/arm64/memset.s Fri Mar 6 16:11:32 2026 @@ -0,0 +1,38 @@ +TEXT memset(SB), $0 + MOV R0, R11 + MOVBU c+8(FP), R10 + MOVWU n+16(FP), R9 + + /* align dst to 8 bytes */ +f0: + ANDS $15, R11, R8 + BEQ f1 + SUBS $1, R9 + BLT done + MOVB R10, (R11)1! + B f0 +f1: + /* need at least 16 for 2-register store */ + SUBS $16, R9 + BLT tail + /* duplicate low byte 8 times */ + ORR R10<<8, R10 + ORR R10<<16, R10 + ORR R10<<32, R10 +f2: + /* store 16 bytes at a time */ + MOVP R10, R10, (R11)16! + SUBS $16, R9 + BGE f2 + + /* remaining bytes */ +tail: + ADDS $15, R9 + BLT done +f3: + MOVB R10, (R11)1! + SUBS $1, R9 + BGE f3 + +done: + RETURN --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/ape/lib/ap/arm64/mkfile Fri Mar 6 17:30:57 2026 @@ -0,0 +1,21 @@ +APE=/sys/src/ape +<$APE/config +LIB=/$objtype/lib/ape/libap.a +OFILES=\ + _seek.$O\ + atom.$O\ + cycles.$O\ + getfcr.$O\ + lock.$O\ + main9.$O\ + main9p.$O\ + memmove.$O\ + memset.$O\ + notetramp.$O\ + setjmp.$O\ + tas.$O\ + + +#include + +/* A stack to hold pcs when signals nest */ +#define MAXSIGSTACK 20 +typedef struct Pcstack Pcstack; +static struct Pcstack { + int sig; + void (*hdlr)(int, char*, Ureg*); + unsigned long long restorepc; + Ureg *u; +} pcstack[MAXSIGSTACK]; +static int nstack = 0; + +static void notecont(Ureg*, char*); + +void +_notetramp(int sig, void (*hdlr)(int, char*, Ureg*), Ureg *u) +{ + Pcstack *p; + + if(nstack >= MAXSIGSTACK) + _NOTED(1); /* nesting too deep; just do system default */ + p = &pcstack[nstack]; + p->restorepc = u->pc; + p->sig = sig; + p->hdlr = hdlr; + p->u = u; + nstack++; + u->pc = (unsigned long long) notecont; + _NOTED(2); /* NSAVE: clear note but hold state */ +} + +static void +notecont(Ureg *u, char *s) +{ + Pcstack *p; + void(*f)(int, char*, Ureg*); + + p = &pcstack[nstack-1]; + f = p->hdlr; + u->pc = p->restorepc; + nstack--; + (*f)(p->sig, s, u); + _NOTED(3); /* NRSTR */ +} + +#define JMPBUFPC 1 +#define JMPBUFSP 0 + +extern sigset_t _psigblocked; + +typedef struct { + sigset_t set; + sigset_t blocked; + unsigned long long jmpbuf[2]; +} sigjmp_buf_arm64; + +void +siglongjmp(sigjmp_buf j, int ret) +{ + struct Ureg *u; + sigjmp_buf_arm64 *jb; + + jb = (sigjmp_buf_arm64*)j; + + if(jb->set) + _psigblocked = jb->blocked; + if(nstack == 0 || pcstack[nstack-1].u->sp > jb->jmpbuf[JMPBUFSP]) + longjmp((void*)jb->jmpbuf, ret); + u = pcstack[nstack-1].u; + nstack--; + u->r0 = ret; + if(ret == 0) + u->r0 = 1; + u->pc = jb->jmpbuf[JMPBUFPC]; + u->sp = jb->jmpbuf[JMPBUFSP] + 8; + _NOTED(3); /* NRSTR */ +} --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/ape/lib/ap/arm64/setjmp.s Fri Mar 6 19:19:09 2026 @@ -0,0 +1,29 @@ +arg=0 +link=30 + +TEXT setjmp(SB), 1, $-4 + MOV SP, R2 + MOVP R2, R(link), 0(R(arg)) + MOV $0, R(arg) + RETURN + +TEXT sigsetjmp(SB), 1, $-4 + MOV savemask+8(FP), R2 + MOV R2, 0(R(arg)) + MOV $_psigblocked(SB), R2 + MOV R2, 8(R(arg)) + MOV SP, R2 + MOVP R2, R(link), 16(R(arg)) + MOV $0, R(arg) + RETURN + +TEXT longjmp(SB), 1, $-4 + MOVP 0(R(arg)), R2, R(link) + MOV R2, SP + MOV r+8(FP), R(arg) + CBZ R(arg), ret1 + RETURN +ret1: + /* ansi: "longjmp(0) => longjmp(1)" */ + MOVW $1, R(arg) + RETURN --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/ape/lib/ap/arm64/tas.s Fri Mar 6 16:20:15 2026 @@ -0,0 +1,11 @@ +#define ISH (2<<2 | 3) + +TEXT tas(SB), 1, $-4 + MOVW $1, R2 +_tas1: + LDXRW (R0), R1 + STXRW R2, (R0), R3 + CBNZ R3, _tas1 + MOVW R1, R0 + DMB $ISH + RETURN --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/ape/lib/mp/arm64/mkfile Fri Mar 6 16:03:20 2026 @@ -0,0 +1,13 @@ +objtype=arm + +#include + +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; +} --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/libc/arm64/argv0.s Thu Mar 5 17:27:40 2026 @@ -0,0 +1,4 @@ +GLOBL argv0(SB), $8 +GLOBL _tos(SB), $8 +GLOBL _privates(SB), $8 +GLOBL _nprivates(SB), $8 --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/libc/arm64/atom.s Thu Mar 5 17:27:40 2026 @@ -0,0 +1,66 @@ +#define ISH (2<<2 | 3) + +/* + * int casl(ulong *p, ulong ov, ulong nv); + * int cas32(u32int*, u32int, u32int); + */ + +TEXT casl+0(SB),0,$0 /* r0 holds p */ +TEXT cas32+0(SB),0,$0 /* r0 holds p */ + MOVWU ov+8(FP), R1 + MOVWU nv+16(FP), R2 +spincas: + LDXRW 0(R0), R3 + CMP R3, R1 + BNE fail + STXRW R2, 0(R0), R4 + CBNZ R4, spincas + MOVW $1, R0 + DMB $ISH + RETURN +fail: + CLREX + MOVW $0, R0 + DMB $ISH + RETURN + +/* + * int casp(void**, void*, void*); + */ + +TEXT casp+0(SB),0,$0 /* r0 holds p */ + MOV ov+8(FP), R1 + MOV nv+16(FP), R2 +spincasp: + LDXR 0(R0), R3 + CMP R3, R1 + BNE fail + STXR R2, 0(R0), R4 + CBNZ R4, spincasp + MOVW $1, R0 + DMB $ISH + RETURN + +TEXT _xinc(SB), $0 /* void _xinc(long *); */ +TEXT ainc(SB), $0 /* long ainc(long *); */ + DMB $ISH +spinainc: + LDXRW 0(R0), R3 + ADD $1,R3 + STXRW R3, 0(R0), R4 + CBNZ R4, spinainc + MOVW R3, R0 + DMB $ISH + RETURN + +TEXT _xdec(SB), $0 /* long _xdec(long *); */ +TEXT adec(SB), $0 /* long adec(long *); */ + DMB $ISH +spinadec: + LDXRW 0(R0), R3 + SUB $1,R3 + STXRW R3, 0(R0), R4 + CBNZ R4, spinadec + MOVW R3, R0 + DMB $ISH + RETURN --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/libc/arm64/cycles.c Thu Mar 5 17:27:40 2026 @@ -0,0 +1,10 @@ +#include +#include + +#pragma profile off + +void +cycles(uvlong*u) +{ + *u = 0LL; +} --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/libc/arm64/getcallerpc.s Thu Mar 5 17:27:40 2026 @@ -0,0 +1,3 @@ +TEXT getcallerpc(SB), $0 + MOV 0(SP), R0 + RETURN --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/libc/arm64/getfcr.s Thu Mar 5 17:27:40 2026 @@ -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 + --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/libc/arm64/main9.s Thu Mar 5 17:27:40 2026 @@ -0,0 +1,25 @@ +#define NPRIVATES 16 + +arg=0 +sb=28 + +TEXT _main(SB), 1, $(16 + NPRIVATES*8) + MOV $setSB(SB), R(sb) + MOV R(arg), _tos(SB) + + MOV $p-(NPRIVATES*8)(SP), R1 + MOV R1, _privates(SB) + MOV $NPRIVATES, R1 + MOV R1, _nprivates(SB) + + MOV $inargv+0(FP), R(arg) + MOV R(arg), argv-(8*NPRIVATES+16)(SP) + MOV inargc-8(FP), R(arg) + BL main(SB) +loop: + MOV $_exitstr<>(SB), R(arg) + BL exits(SB) + B loop + +DATA _exitstr<>+0(SB)/4, $"main" +GLOBL _exitstr<>+0(SB), $5 --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/libc/arm64/main9p.s Thu Mar 5 17:27:40 2026 @@ -0,0 +1,38 @@ +#define NPRIVATES 16 + +arg=0 +sb=28 + +TEXT _mainp(SB), 1, $(16 + NPRIVATES*8) + MOV $setSB(SB), R(sb) + MOV R(arg), _tos(SB) + + MOV $p-(NPRIVATES*8)(SP), R1 + MOV R1, _privates(SB) + MOV $NPRIVATES, R1 + MOV R1, _nprivates(SB) + + BL _profmain(SB) + /* _tos->prof.pp = _tos->prof.next; */ + MOV _tos(SB), R1 + MOV 8(R1), R0 + MOV R0, 0(R1) + + MOV $inargv+0(FP), R(arg) + MOV R(arg), argv-(8*NPRIVATES+16)(SP) + MOV inargc-8(FP), R(arg) + BL main(SB) +loop: + MOV $_exitstr<>(SB), R(arg) + BL exits(SB) + B loop + +TEXT _savearg(SB), 1, $0 + RETURN + +TEXT _callpc(SB), 1, $0 + MOV 0(SP), R0 + RETURN + +DATA _exitstr<>+0(SB)/4, $"main" +GLOBL _exitstr<>+0(SB), $5 --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/libc/arm64/memmove.s Thu Mar 5 17:27:40 2026 @@ -0,0 +1,114 @@ +TEXT memcpy(SB), $-20 +TEXT memmove(SB), $-20 + MOV R0, s1+0(FP) + + MOVWU n+16(FP), R9 /* count */ + CBZ R9, return + MOV R0, R11 /* dest pointer */ + MOV s2+8(FP), R10 /* source pointer */ + CMP R11, R10 + BEQ return + BLO back + +/* + * byte-at-a-time forward copy to + * get source (R10) vlong aligned. + */ +f1: + ANDS $7, R10, R8 + BEQ f2 + SUBS $1, R9 + BLT return + MOVB (R10)1!, R8 + MOVB R8, (R11)1! + B f1 + +/* + * check that dest is vlong aligned + * if not, just go byte-at-a-time + */ +f2: + ANDS $7, R11, R8 + BEQ f3 + SUBS $1, R9 + BLT return + B f5 +/* + * two-vlongs-at-a-time forward copy + */ +f3: + SUBS $16, R9 + BLT f4 + MOVP (R10)16!, R12, R13 + MOVP R12, R13, (R11)16! + B f3 + +/* + * cleanup byte-at-a-time + */ +f4: + ADDS $15, R9 + BLT return +f5: + MOVB (R10)1!, R8 + MOVB R8, (R11)1! + SUBS $1, R9 + BGE f5 + +return: + MOVW s1+0(FP),R0 + RETURN + +/* + * everything the same, but + * copy backwards + */ +back: + ADD R9, R10 + ADD R9, R11 + +/* + * byte-at-a-time backward copy to + * get source (R10) vlong aligned. + */ +b1: + ANDS $7, R10, R8 + BEQ b2 + SUBS $1, R9 + BLT return + MOVB -1(R10)!, R8 + MOVB R8, -1(R11)! + B b1 + +/* + * check that dest is aligned + * if not, just go byte-at-a-time + */ +b2: + ANDS $7, R11, R8 + BEQ b3 + SUBS $1, R9 + BLT return + B b5 +/* + * two-vlongs-at-a-time backward copy + */ +b3: + SUBS $16, R9 + BLT b4 + MOVP -16(R10)!, R12, R13 + MOVP R12, R13, -16(R11)! + B b3 + +/* + * cleanup byte-at-a-time backward + */ +b4: + ADDS $15, R9 + BLT return +b5: + MOVB -1(R10)!, R8 + MOVB R8, -1(R11)! + SUBS $1, R9 + BGE b5 + B return --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/libc/arm64/memset.s Thu Mar 5 17:27:40 2026 @@ -0,0 +1,38 @@ +TEXT memset(SB), $0 + MOV R0, R11 + MOVBU c+8(FP), R10 + MOVWU n+16(FP), R9 + + /* align dst to 8 bytes */ +f0: + ANDS $15, R11, R8 + BEQ f1 + SUBS $1, R9 + BLT done + MOVB R10, (R11)1! + B f0 +f1: + /* need at least 16 for 2-register store */ + SUBS $16, R9 + BLT tail + /* duplicate low byte 8 times */ + ORR R10<<8, R10 + ORR R10<<16, R10 + ORR R10<<32, R10 +f2: + /* store 16 bytes at a time */ + MOVP R10, R10, (R11)16! + SUBS $16, R9 + BGE f2 + + /* remaining bytes */ +tail: + ADDS $15, R9 + BLT done +f3: + MOVB R10, (R11)1! + SUBS $1, R9 + BGE f3 + +done: + RETURN --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/libc/arm64/mkfile Thu Mar 5 17:27:40 2026 @@ -0,0 +1,27 @@ +objtype=arm64 + +#include +#include + +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); +} --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/libc/arm64/setjmp.s Thu Mar 5 17:27:40 2026 @@ -0,0 +1,19 @@ +arg=0 +link=30 + +TEXT setjmp(SB), 1, $-4 + MOV SP, R2 + MOVP R2, R(link), 0(R(arg)) + MOV $0, R(arg) + RETURN + +TEXT longjmp(SB), 1, $-4 + MOVP 0(R(arg)), R2, R(link) + MOV R2, SP + MOV r+8(FP), R(arg) + CBZ R(arg), ret1 + RETURN +ret1: + /* ansi: "longjmp(0) => longjmp(1)" */ + MOVW $1, R(arg) + RETURN --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/libc/arm64/sqrt.s Thu Mar 5 17:27:40 2026 @@ -0,0 +1,4 @@ +TEXT sqrt(SB), $0 + FMOVD a+0(FP), F0 + FSQRTD F0, F0 + RETURN --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/libc/arm64/tas.s Thu Mar 5 17:27:40 2026 @@ -0,0 +1,11 @@ +#define ISH (2<<2 | 3) + +TEXT _tas(SB), 1, $-4 + MOVW $1, R2 +_tas1: + LDXRW (R0), R1 + STXRW R2, (R0), R3 + CBNZ R3, _tas1 + MOVW R1, R0 + DMB $ISH + RETURN --- /dev/null Thu Mar 12 09:30:04 2026 +++ /sys/src/libmp/arm64/mkfile Thu Mar 5 17:29:00 2026 @@ -0,0 +1,13 @@ +objtype=arm + +#include +#include +#include "threadimpl.h" + +/* first argument goes in a register; simplest just to ignore it */ +static void +launcherarm64(int, void (*f)(void *arg), void *arg) +{ + if (f == nil) + sysfatal("launcherarm64: nil f passed: arg %#p", arg); + (*f)(arg); + threadexits(nil); +} + +void +_threadinitstack(Thread *t, void (*f)(void*), void *arg) +{ + uintptr *tos; + + tos = (uintptr *)&t->stk[t->stksize&~7]; + *--tos = (uintptr)arg; + *--tos = (uintptr)f; + t->sched[JMPBUFPC] = (uintptr)launcherarm64+JMPBUFDPC; + t->sched[JMPBUFSP] = (uintptr)tos - 2*sizeof(uintptr); /* 1st arg, return PC */ +} --- /sys/src/libthread/mkfile Wed Sep 19 22:18:52 2012 +++ /sys/src/libthread/mkfile Thu Mar 5 19:10:38 2026 @@ -33,6 +33,7 @@ 386.c\ amd64.c\ arm.c\ + arm64.c\ channel.c\ chanprint.c\ create.c\ --- /sys/src/mkfile.proto Fri Jan 30 09:43:35 2026 +++ /sys/src/mkfile.proto Thu Mar 5 18:45:13 2026 @@ -2,8 +2,8 @@ # common mkfile parameters shared by all architectures # -OS=568ijqv -CPUS=arm amd64 386 riscv riscv64 power mips +OS=5678ijqv +CPUS=arm arm64 amd64 386 riscv riscv64 power mips CFLAGS=-FTVw LEX=lex YACC=yacc