--- /dev/null +++ /amd64/include/ape/_apetypes.h Sun Jun 28 00:00:00 2026 @@ -0,0 +1,3 @@ +#ifndef _BITS64 +#define _BITS64 +#endif --- /dev/null +++ /power64/include/ape/_apetypes.h Sun Jun 28 00:00:00 2026 @@ -0,0 +1,3 @@ +#ifndef _BITS64 +#define _BITS64 +#endif --- /n/sources/plan9/sys/include/ape/bsd.h Sat Jan 10 10:00:05 2015 +++ /sys/include/ape/bsd.h Sun Jun 28 00:00:00 2026 @@ -15,10 +15,16 @@ extern "C" { #endif +#include "_apetypes.h" + #ifndef _SIZE_T #define _SIZE_T +#ifdef _BITS64 +typedef unsigned long long size_t; +#else typedef unsigned long size_t; #endif +#endif /* ifndefs because X11 stuff (ugh) */ #ifndef bcopy @@ -34,9 +40,13 @@ extern int ffs(unsigned int); extern void bhappy(void*); extern int rresvport(int*); extern int rcmd(char**, int, char*, char*, char*, int*); +extern char* strdup(char*); extern int strcasecmp(char*, char*); extern int putenv(char*); extern int strncasecmp(char*, char*,int); +extern void* memccpy(void*, void*, int, size_t); +extern int fsync(int); +extern int ftruncate(int, off_t); extern int getopt(int, char**, char*); extern int opterr; --- /dev/null +++ /sys/include/ape/f2c.h Sun Jun 28 00:00:00 2026 @@ -0,0 +1,214 @@ +/* f2c.h -- Standard Fortran to C header file */ + +/** barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed." + + - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */ + +#ifndef F2C_INCLUDE +#define F2C_INCLUDE + +typedef long int integer; +typedef char *address; +typedef short int shortint; +typedef float real; +typedef double doublereal; +typedef struct { real r, i; } complex; +typedef struct { doublereal r, i; } doublecomplex; +typedef long int logical; +typedef short int shortlogical; +typedef char logical1; +typedef char integer1; +/* typedef long long longint; */ /* system-dependent */ + +#define TRUE_ (1) +#define FALSE_ (0) + +/* Extern is for use with -E */ +#ifndef Extern +#define Extern extern +#endif + +/* I/O stuff */ + +#ifdef f2c_i2 +/* for -i2 */ +typedef short flag; +typedef short ftnlen; +typedef short ftnint; +#else +typedef long flag; +typedef long ftnlen; +typedef long ftnint; +#endif + +/*external read, write*/ +typedef struct +{ flag cierr; + ftnint ciunit; + flag ciend; + char *cifmt; + ftnint cirec; +} cilist; + +/*internal read, write*/ +typedef struct +{ flag icierr; + char *iciunit; + flag iciend; + char *icifmt; + ftnint icirlen; + ftnint icirnum; +} icilist; + +/*open*/ +typedef struct +{ flag oerr; + ftnint ounit; + char *ofnm; + ftnlen ofnmlen; + char *osta; + char *oacc; + char *ofm; + ftnint orl; + char *oblnk; +} olist; + +/*close*/ +typedef struct +{ flag cerr; + ftnint cunit; + char *csta; +} cllist; + +/*rewind, backspace, endfile*/ +typedef struct +{ flag aerr; + ftnint aunit; +} alist; + +/* inquire */ +typedef struct +{ flag inerr; + ftnint inunit; + char *infile; + ftnlen infilen; + ftnint *inex; /*parameters in standard's order*/ + ftnint *inopen; + ftnint *innum; + ftnint *innamed; + char *inname; + ftnlen innamlen; + char *inacc; + ftnlen inacclen; + char *inseq; + ftnlen inseqlen; + char *indir; + ftnlen indirlen; + char *infmt; + ftnlen infmtlen; + char *inform; + ftnint informlen; + char *inunf; + ftnlen inunflen; + ftnint *inrecl; + ftnint *innrec; + char *inblank; + ftnlen inblanklen; +} inlist; + +#define VOID void + +union Multitype { /* for multiple entry points */ + integer1 g; + shortint h; + integer i; + /* longint j; */ + real r; + doublereal d; + complex c; + doublecomplex z; + }; + +typedef union Multitype Multitype; + +typedef long Long; /* No longer used; formerly in Namelist */ + +struct Vardesc { /* for Namelist */ + char *name; + char *addr; + ftnlen *dims; + int type; + }; +typedef struct Vardesc Vardesc; + +struct Namelist { + char *name; + Vardesc **vars; + int nvars; + }; +typedef struct Namelist Namelist; + +#define abs(x) ((x) >= 0 ? (x) : -(x)) +#define dabs(x) (doublereal)abs(x) +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#define max(a,b) ((a) >= (b) ? (a) : (b)) +#define dmin(a,b) (doublereal)min(a,b) +#define dmax(a,b) (doublereal)max(a,b) + +/* procedure parameter types for -A and -C++ */ + +#define F2C_proc_par_types 1 +#ifdef __cplusplus +typedef int /* Unknown procedure type */ (*U_fp)(...); +typedef shortint (*J_fp)(...); +typedef integer (*I_fp)(...); +typedef real (*R_fp)(...); +typedef doublereal (*D_fp)(...), (*E_fp)(...); +typedef /* Complex */ VOID (*C_fp)(...); +typedef /* Double Complex */ VOID (*Z_fp)(...); +typedef logical (*L_fp)(...); +typedef shortlogical (*K_fp)(...); +typedef /* Character */ VOID (*H_fp)(...); +typedef /* Subroutine */ int (*S_fp)(...); +#else +typedef int /* Unknown procedure type */ (*U_fp)(); +typedef shortint (*J_fp)(); +typedef integer (*I_fp)(); +typedef real (*R_fp)(); +typedef doublereal (*D_fp)(), (*E_fp)(); +typedef /* Complex */ VOID (*C_fp)(); +typedef /* Double Complex */ VOID (*Z_fp)(); +typedef logical (*L_fp)(); +typedef shortlogical (*K_fp)(); +typedef /* Character */ VOID (*H_fp)(); +typedef /* Subroutine */ int (*S_fp)(); +#endif +/* E_fp is for real functions when -R is not specified */ +typedef VOID C_f; /* complex function */ +typedef VOID H_f; /* character function */ +typedef VOID Z_f; /* double complex function */ +typedef doublereal E_f; /* real function with -R not specified */ + +/* undef any lower-case symbols that your C compiler predefines, e.g.: */ + +#ifndef Skip_f2c_Undefs +#undef cray +#undef gcos +#undef mc68010 +#undef mc68020 +#undef mips +#undef pdp11 +#undef sgi +#undef sparc +#undef sun +#undef sun2 +#undef sun3 +#undef sun4 +#undef u370 +#undef u3b +#undef u3b2 +#undef u3b5 +#undef unix +#undef vax +#endif +#endif --- /n/sources/plan9/sys/include/ape/inttypes.h Sat Jan 10 10:00:05 2015 +++ /sys/include/ape/inttypes.h Sun Jun 28 00:00:00 2026 @@ -5,9 +5,15 @@ #ifndef _INTTYPES_H_ #define _INTTYPES_H_ 1 +#include "_apetypes.h" + +#ifdef _BITS64 +typedef long long _intptr_t; +typedef unsigned long long _uintptr_t; +#else typedef int _intptr_t; typedef unsigned int _uintptr_t; - +#endif typedef char int8_t; typedef short int16_t; --- /n/sources/plan9/sys/include/ape/lib9.h Sat Jan 10 10:00:05 2015 +++ /sys/include/ape/lib9.h Sun Jun 28 00:00:00 2026 @@ -64,12 +64,12 @@ extern int bind(char*, char*, int); extern int mount(int, int, char*, int, char*); extern int unmount(char*, char*); extern int rfork(int); -extern int segattach(int, char*, void*, unsigned long); -extern int segbrk(void*, void*); +extern void* segattach(int, char*, void*, unsigned long); +extern void* segbrk(void*, void*); extern int segdetach(void*); extern int segflush(void*, unsigned long); extern int segfree(void*, unsigned long); -extern unsigned long rendezvous(unsigned long, unsigned long); +extern void* rendezvous(void *, void *); extern unsigned long getfcr(void); extern unsigned long getfsr(void); extern void setfcr(unsigned long); --- /n/sources/plan9/sys/include/ape/setjmp.h Sat Jan 10 10:00:05 2015 +++ /sys/include/ape/setjmp.h Sun Jun 28 00:00:00 2026 @@ -2,9 +2,13 @@ #define __SETJMP_H #pragma lib "/$M/lib/ape/libap.a" -typedef int jmp_buf[10]; +#undef _SUSV2_SOURCE +#define _SUSV2_SOURCE +#include + +typedef uintptr_t jmp_buf[4]; /* need 2 pointers on riscv64 */ #ifdef _POSIX_SOURCE -typedef int sigjmp_buf[10]; +typedef uintptr_t sigjmp_buf[4]; /* need 3 pointers for sigsetjmp on riscv64 */ #endif #ifdef __cplusplus --- /n/sources/plan9/sys/include/ape/stddef.h Sat Jan 10 10:00:05 2015 +++ /sys/include/ape/stddef.h Sun Jun 28 00:00:00 2026 @@ -12,14 +12,26 @@ #define offsetof(ty,mem) ((size_t) &(((ty *)0)->mem)) #endif +#include "_apetypes.h" + +#ifdef _BITS64 +typedef long long ptrdiff_t; +#else typedef long ptrdiff_t; +#endif + #ifndef _SIZE_T #define _SIZE_T +#ifdef _BITS64 +typedef unsigned long long size_t; +#else typedef unsigned long size_t; #endif +#endif + #ifndef _WCHAR_T #define _WCHAR_T -typedef unsigned short wchar_t; +typedef unsigned long wchar_t; #endif #endif /* __STDDEF_H */ --- /dev/null +++ /sys/include/ape/stdint.h Sun Jun 28 00:00:00 2026 @@ -0,0 +1 @@ +#include --- /dev/null +++ /sys/include/ape/sys/signal.h Sun Jun 28 00:00:00 2026 @@ -0,0 +1,95 @@ +#ifndef __SIGNAL_H +#define __SIGNAL_H +#pragma lib "/$M/lib/ape/libap.a" + +typedef int sig_atomic_t; + +/* + * We don't give arg types for signal handlers, in spite of ANSI requirement + * that it be 'int' (the signal number), because some programs need an + * additional context argument. So the real type of signal handlers is + * void handler(int sig, char *, struct Ureg *) + * where the char * is the Plan 9 message and Ureg is defined in + */ +#define SIG_DFL ((void (*)())0) +#define SIG_ERR ((void (*)())-1) +#define SIG_IGN ((void (*)())1) + +#define SIGHUP 1 /* hangup */ +#define SIGINT 2 /* interrupt */ +#define SIGQUIT 3 /* quit */ +#define SIGILL 4 /* illegal instruction (not reset when caught)*/ +#define SIGABRT 5 /* used by abort */ +#define SIGFPE 6 /* floating point exception */ +#define SIGKILL 7 /* kill (cannot be caught or ignored) */ +#define SIGSEGV 8 /* segmentation violation */ +#define SIGPIPE 9 /* write on a pipe with no one to read it */ +#define SIGALRM 10 /* alarm clock */ +#define SIGTERM 11 /* software termination signal from kill */ +#define SIGUSR1 12 /* user defined signal 1 */ +#define SIGUSR2 13 /* user defined signal 2 */ +#define SIGBUS 14 /* bus error */ + +/* The following symbols must be defined, but the signals needn't be supported */ +#define SIGCHLD 15 /* child process terminated or stopped */ +#define SIGCONT 16 /* continue if stopped */ +#define SIGSTOP 17 /* stop */ +#define SIGTSTP 18 /* interactive stop */ +#define SIGTTIN 19 /* read from ctl tty by member of background */ +#define SIGTTOU 20 /* write to ctl tty by member of background */ + +#ifdef _BSD_EXTENSION +#define NSIG 21 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +extern void (*signal(int, void (*)()))(); +extern int raise(int); + +#ifdef __cplusplus +} +#endif + +#ifdef _POSIX_SOURCE + +typedef long sigset_t; +struct sigaction { + void (*sa_handler)(); + sigset_t sa_mask; + int sa_flags; +}; +/* values for sa_flags */ +#define SA_NOCLDSTOP 1 + +/* first argument to sigprocmask */ +#define SIG_BLOCK 1 +#define SIG_UNBLOCK 2 +#define SIG_SETMASK 3 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __TYPES_H +extern int kill(pid_t, int); +#endif +extern int sigemptyset(sigset_t *); +extern int sigfillset(sigset_t *); +extern int sigaddset(sigset_t *, int); +extern int sigdelset(sigset_t *, int); +extern int sigismember(const sigset_t *, int); +extern int sigaction(int, const struct sigaction *, struct sigaction *); +extern int sigprocmask(int, sigset_t *, sigset_t *); +extern int sigpending(sigset_t *); +extern int sigsuspend(const sigset_t *); + +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_SOURCE */ + +#endif /* __SIGNAL_H */ --- /n/sources/plan9/sys/include/ape/sys/types.h Sat Jan 10 10:00:05 2015 +++ /sys/include/ape/sys/types.h Sun Jun 28 00:00:00 2026 @@ -11,18 +11,29 @@ typedef short gid_t; typedef short nlink_t; typedef int pid_t; +#include "_apetypes.h" + #ifndef _SIZE_T #define _SIZE_T +#ifdef _BITS64 +typedef unsigned long long size_t; +#else typedef unsigned long size_t; #endif +#endif + #ifndef _SSIZE_T #define _SSIZE_T +#ifdef _BITS64 +typedef long long ssize_t; +#else typedef long ssize_t; #endif +#endif #ifndef _TIME_T #define _TIME_T -typedef long time_t; +typedef long time_t; /* should be ulong */ #endif #ifdef _BSD_EXTENSION --- /n/sources/plan9/sys/include/ape/u.h Sat Jan 10 10:00:05 2015 +++ /sys/include/ape/u.h Sun Jun 28 00:00:00 2026 @@ -4,11 +4,13 @@ This header file is an extension to ANSI/POSIX #endif +#include "_apetypes.h" + #define nil ((void*)0) typedef unsigned short ushort; typedef unsigned char uchar; typedef unsigned long ulong; -typedef unsigned int uint; +typedef unsigned uint; typedef signed char schar; typedef long long vlong; typedef unsigned long long uvlong; --- /n/sources/plan9/sys/include/ape/unistd.h Sat Jan 10 10:00:05 2015 +++ /sys/include/ape/unistd.h Sun Jun 28 00:00:00 2026 @@ -13,14 +13,26 @@ #define _POSIX_SYNC_IO -1 #define _POSIX_VDISABLE -1 +#include "_apetypes.h" + #ifndef _SIZE_T #define _SIZE_T +#ifdef _BITS64 +typedef unsigned long long size_t; +#else typedef unsigned long size_t; #endif +#endif + #ifndef _SSIZE_T #define _SSIZE_T +#ifdef _BITS64 +typedef long long ssize_t; +#else typedef long ssize_t; #endif +#endif + #ifndef NULL #ifndef NULL #ifdef __cplusplus --- /n/sources/plan9/sys/src/ape/lib/9/arm64/getcallerpc.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/9/arm64/getcallerpc.s Sun Jun 28 00:00:00 2026 @@ -1,3 +1,3 @@ -TEXT getcallerpc(SB), $0 - MOV 0(SP), R0 +TEXT getcallerpc(SB), 1, $-4 + MOVW 0(RSP), RARG RETURN --- /n/sources/plan9/sys/src/ape/lib/9/arm64/getfcr.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/9/arm64/getfcr.s Sun Jun 28 00:00:00 2026 @@ -1,21 +1,16 @@ -#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 +TEXT setfcr(SB), $0 + MOV RARG, FPCR RETURN -TEXT getfcr(SB), 1, $-4 - MRS FPCR, R0 +TEXT getfcr(SB), $0 + MOV FPCR, R0 RETURN -TEXT getfsr(SB), 1, $-4 - MRS FPSR, R0 +TEXT getfsr(SB), $0 + MOV FPSR, R0 RETURN -TEXT setfsr(SB), 1, $-4 - MSR R0, FPSR +TEXT setfsr(SB), $0 + MOV RARG, FPSR RETURN --- /n/sources/plan9/sys/src/ape/lib/9/libc.h Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/9/libc.h Sun Jun 28 00:00:00 2026 @@ -14,7 +14,14 @@ #include #include #include -#include +// #include +#ifndef _SUSV2_SOURCE +#define _SUSV2_SOURCE +#include +#undef _SUSV2_SOURCE +#else +#include +#endif #define nelem(x) (sizeof(x)/sizeof((x)[0])) @@ -64,6 +71,37 @@ struct Waitmsg char *msg; } Waitmsg; +/* + * Time-of-day + */ + +typedef +struct Tm +{ + int sec; + int min; + int hour; + int mday; + int mon; + int year; + int wday; + int yday; + char zone[4]; + int tzoff; +} Tm; + +extern Tm* gmtime(long); +extern Tm* localtime(long); +extern char* asctime(Tm*); +extern char* ctime(long); +extern double cputime(void); +extern long times(long*); +extern long tm2sec(Tm*); +extern vlong nsec(void); + +extern void cycles(uvlong*); /* 64-bit value of the cycle counter if there is one, 0 if there isn't */ + +extern long time(long*); extern int _AWAIT(char*, int); extern int _ALARM(unsigned long); @@ -89,10 +127,10 @@ extern long _PREAD(int, void*, long, long long); extern long _PWRITE(int, void*, long, long long); extern long _READ(int, void*, long); extern int _REMOVE(const char*); -extern int _RENDEZVOUS(unsigned long, unsigned long); +extern void* _RENDEZVOUS(void *, void *); extern int _RFORK(int); -extern int _SEGATTACH(int, char*, void*, unsigned long); -extern int _SEGBRK(void*, void*); +extern void* _SEGATTACH(int, char*, void*, unsigned long); +extern void* _SEGBRK(void*, void*); extern int _SEGDETACH(void*); extern int _SEGFLUSH(void*, unsigned long); extern int _SEGFREE(void*, unsigned long); @@ -102,7 +140,7 @@ extern int _STAT(const char*, unsigned char*, int); extern Waitmsg* _WAIT(void); extern long _WRITE(int, const void*, long); extern int _WSTAT(const char*, unsigned char*, int); -extern void *_MALLOCZ(int, int); +extern void *_MALLOCZ(size_t, int); extern int _WERRSTR(char*, ...); extern long _READN(int, void*, long); extern int _IOUNIT(int); @@ -125,7 +163,7 @@ extern int _IOUNIT(int); #define read _READ #define write _WRITE #define _exits(s) _exit(s && *(char*)s ? 1 : 0) -#define exits(s) exit(s && *(char*)s ? 1 : 0) +#define exits(s) exit(s && *(char*)s ? 1 : 0) #define create _CREATE #define pread _PREAD #define readn _READN @@ -139,7 +177,7 @@ extern int _IOUNIT(int); #define ERRMAX 128 extern void setmalloctag(void*, ulong); -extern ulong getcallerpc(void*); +extern uintptr_t getcallerpc(void*); /* Used in libsec.h and not picked up in earlier type definitions */ typedef unsigned int u32int; @@ -152,9 +190,54 @@ int enc32(char *, int, uchar *, int); int dec64(uchar *, int, char *, int); int enc64(char *, int, uchar *, int); -extern vlong nsec(void); - extern void sysfatal(char*, ...); extern ulong truerand(void); /* uses /dev/random */ extern int getfields(char*, char**, int, int, char*); + +#pragma varargck type "lld" vlong +#pragma varargck type "llo" vlong +#pragma varargck type "llx" vlong +#pragma varargck type "llb" vlong +#pragma varargck type "lld" uvlong +#pragma varargck type "llo" uvlong +#pragma varargck type "llx" uvlong +#pragma varargck type "llb" uvlong +#pragma varargck type "ld" long +#pragma varargck type "lo" long +#pragma varargck type "lx" long +#pragma varargck type "lb" long +#pragma varargck type "ld" ulong +#pragma varargck type "lo" ulong +#pragma varargck type "lx" ulong +#pragma varargck type "lb" ulong +#pragma varargck type "d" int +#pragma varargck type "o" int +#pragma varargck type "x" int +#pragma varargck type "c" int +#pragma varargck type "C" int +#pragma varargck type "b" int +#pragma varargck type "d" uint +#pragma varargck type "x" uint +#pragma varargck type "c" uint +#pragma varargck type "C" uint +#pragma varargck type "b" uint +#pragma varargck type "f" double +#pragma varargck type "e" double +#pragma varargck type "g" double +#pragma varargck type "s" char* +#pragma varargck type "q" char* +#pragma varargck type "S" Rune* +#pragma varargck type "Q" Rune* +#pragma varargck type "r" void +#pragma varargck type "%" void +#pragma varargck type "n" int* +#pragma varargck type "p" ulong /* uintptr */ +#pragma varargck type "p" void* +#pragma varargck flag ',' +#pragma varargck flag ' ' +#pragma varargck flag 'h' +#pragma varargck type "<" void* +#pragma varargck type "[" void* +#pragma varargck type "H" void* +#pragma varargck type "lH" void* --- /n/sources/plan9/sys/src/ape/lib/9/rendezvous.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/9/rendezvous.c Sun Jun 28 00:00:00 2026 @@ -1,9 +1,9 @@ #include -extern unsigned long _RENDEZVOUS(unsigned long, unsigned long); +extern void* _RENDEZVOUS(void *, void *); -unsigned long -rendezvous(unsigned long tag, unsigned long value) +void* +rendezvous(void * tag, void * value) { return _RENDEZVOUS(tag, value); } --- /n/sources/plan9/sys/src/ape/lib/9/riscv/getcallerpc.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/9/riscv/getcallerpc.s Sun Jun 28 00:00:00 2026 @@ -1,4 +1,6 @@ +#define RARG R8 + TEXT getcallerpc(SB), $0 - MOVW 0(SP), R8 + MOVW 0(SP), RARG RET --- /n/sources/plan9/sys/src/ape/lib/9/riscv/getfcr.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/9/riscv/getfcr.s Sun Jun 28 00:00:00 2026 @@ -1,5 +1,3 @@ -#define LINK R1 -#define SP R2 #define ARG 8 #define FFLAGS 1 --- /n/sources/plan9/sys/src/ape/lib/9/riscv64/getcallerpc.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/9/riscv64/getcallerpc.s Sun Jun 28 00:00:00 2026 @@ -1,4 +1,6 @@ -TEXT getcallerpc(SB), $0 - MOV 0(SP), R8 +#define RARG R8 + +TEXT getcallerpc(SB), 1, $0 + MOV 0(SP), RARG RET --- /n/sources/plan9/sys/src/ape/lib/9/segattach.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/9/segattach.c Sun Jun 28 00:00:00 2026 @@ -1,8 +1,8 @@ #include -extern int _SEGATTACH(int, char*, void*, unsigned long); +extern void *_SEGATTACH(int, char*, void*, unsigned long); -int +void * segattach(int attr, char *class, void *va, unsigned long len) { return _SEGATTACH(attr, class, va, len); --- /n/sources/plan9/sys/src/ape/lib/ap/amd64/atom.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/amd64/atom.s Sun Jun 28 00:00:00 2026 @@ -1,4 +1,4 @@ -TEXT ainc(SB), 1, $0 /* long ainc(long *); */ +TEXT ainc(SB), 1, $8 /* long ainc(long *); */ ainclp: MOVL (RARG), AX /* exp */ MOVL AX, BX @@ -8,7 +8,7 @@ ainclp: MOVL BX, AX RET -TEXT adec(SB), 1, $0 /* long adec(long*); */ +TEXT adec(SB), 1, $8 /* long adec(long*); */ adeclp: MOVL (RARG), AX MOVL AX, BX @@ -18,49 +18,47 @@ adeclp: MOVL BX, AX RET +TEXT _xinc(SB),$8 /* void _xinc(long *); */ + LOCK; INCL 0(RARG) + RET + +TEXT _xdec(SB),$8 /* long _xdec(long *); */ + MOVL $0, AX + MOVL $1, BX + LOCK; DECL 0(RARG) + CMOVLNE BX, AX + RET + /* - * int cas32(u32int *p, u32int ov, u32int nv); * int cas(uint *p, int ov, int nv); - * int casul(ulong *p, ulong ov, ulong nv); */ -TEXT cas32(SB), 1, $0 TEXT cas(SB), 1, $0 -TEXT casul(SB), 1, $0 -TEXT casl(SB), 1, $0 /* back compat */ MOVL exp+8(FP), AX MOVL new+16(FP), BX LOCK; CMPXCHGL BX, (RARG) MOVL $1, AX /* use CMOVLEQ etc. here? */ - JNZ _cas32r0 -_cas32r1: + JNZ _casr0 +_casr1: RET -_cas32r0: +_casr0: DECL AX RET /* - * int cas64(u64int *p, u64int ov, u64int nv); + * int casv(u64int *p, u64int ov, u64int nv); * int casp(void **p, void *ov, void *nv); */ -TEXT cas64(SB), 1, $0 +TEXT casv(SB), 1, $0 TEXT casp(SB), 1, $0 MOVQ exp+8(FP), AX MOVQ new+16(FP), BX LOCK; CMPXCHGQ BX, (RARG) MOVL $1, AX /* use CMOVLEQ etc. here? */ - JNZ _cas64r0 -_cas64r1: + JNZ _casvr0 +_casvr1: RET -_cas64r0: +_casvr0: DECL AX RET - -/* - * void mfence(void); - */ -TEXT mfence(SB),0,$0 - MFENCE - RET - --- /n/sources/plan9/sys/src/ape/lib/ap/amd64/main9.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/amd64/main9.s Sun Jun 28 00:00:00 2026 @@ -1,12 +1,14 @@ TEXT _main(SB), 1, $(3*8) CALL _envsetup(SB) + MOVL inargc-8(FP), RARG LEAQ inargv+0(FP), AX MOVQ AX, 8(SP) MOVQ environ(SB), AX MOVQ AX, 16(SP) CALL main(SB) + MOVQ AX, RARG CALL exit(SB) RET --- /n/sources/plan9/sys/src/ape/lib/ap/amd64/notetramp.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/amd64/notetramp.c Sun Jun 28 00:00:00 2026 @@ -1,3 +1,4 @@ +/* must match setjmp.s */ #include "../plan9/lib.h" #include "../plan9/sys9.h" #include @@ -5,6 +6,7 @@ /* A stack to hold pcs when signals nest */ #define MAXSIGSTACK 20 + typedef struct Pcstack Pcstack; static struct Pcstack { int sig; @@ -55,7 +57,7 @@ extern sigset_t _psigblocked; typedef struct { sigset_t set; sigset_t blocked; - unsigned long long jmpbuf[2]; + jmp_buf jmpbuf; /* APE version: 4 uintptrs */ } sigjmp_buf_amd64; void @@ -65,16 +67,13 @@ siglongjmp(sigjmp_buf j, int ret) sigjmp_buf_amd64 *jb; jb = (sigjmp_buf_amd64*)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->ax = ret; - if(ret == 0) - u->ax = 1; + u->ax = ret == 0? 1: ret; u->ip = jb->jmpbuf[JMPBUFPC]; u->sp = jb->jmpbuf[JMPBUFSP] + 8; _NOTED(3); /* NRSTR */ --- /n/sources/plan9/sys/src/ape/lib/ap/amd64/setjmp.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/amd64/setjmp.s Sun Jun 28 00:00:00 2026 @@ -1,4 +1,5 @@ -TEXT longjmp(SB), $0 +/* amd64 APE version; must match notetramp.c */ +TEXT longjmp(SB), $0 /* void longjmp(jmp_buf env, int val) */ MOVL r+8(FP), AX CMPL AX, $0 JNE ok /* ansi: "longjmp(0) => longjmp(1)" */ @@ -9,16 +10,22 @@ ok: MOVQ BX, 0(SP) RET -TEXT setjmp(SB), $0 +TEXT setjmp(SB), $0 /* int setjmp(jmp_buf env) */ MOVQ SP, 0(RARG) /* store sp */ MOVQ 0(SP), BX /* store return pc */ MOVQ BX, 8(RARG) MOVL $0, AX /* return 0 */ RET -TEXT sigsetjmp(SB), $0 - MOVL savemask+8(FP), BX +TEXT sigsetjmp(SB), $0 /* sigsetjmp(sigjmp_buf, int mask) */ + MOVL savemask+8(FP), BX /* store signal stuff */ MOVL BX, 0(RARG) + /* + * TODO: this seemed wrong (MOVL $_psig...): surely + * MOVL _psigblocked(SB), ...? + * current code matches all other archs' impl'ns, + * but they could all be wrong, this is not heavily used. + */ MOVL $_psigblocked(SB), 4(RARG) MOVQ SP, 8(RARG) /* store sp */ MOVQ 0(SP), BX /* store return pc */ --- /n/sources/plan9/sys/src/ape/lib/ap/arm/atom.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/arm/atom.s Sun Jun 28 00:00:00 2026 @@ -1,9 +1,16 @@ -#define DMB MCR 15, 0, R0, C7, C10, 5 +#define DMB WORD $0xf57ff05f /* data mem. barrier; last f = SY */ + #define CLREX WORD $0xf57ff01f #define LDREX(a,r) WORD $(0xe<<28|0x01900f9f | (a)<<16 | (r)<<12) /* `The order of operands is from left to right in dataflow order' - asm man */ #define STREX(v,a,r) WORD $(0xe<<28|0x01800f90 | (a)<<16 | (r)<<12 | (v)<<0) +/* + * erratum 754327: no automatic store buffer drain; in cortex-a9 prior to r2p0. + * stores can linger in the store buffer. a dmb will flush them so that other + * processors or peripherals (`external agents') can see them. + */ + /* * int cas(ulong *p, ulong ov, ulong nv); */ @@ -12,57 +19,46 @@ TEXT cas+0(SB),0,$0 /* r0 holds p */ TEXT casp+0(SB),0,$0 /* r0 holds p */ MOVW ov+4(FP), R1 MOVW nv+8(FP), R2 + DMB spincas: - LDREX(0,3) /* LDREX 0(R0),R3 */ + LDREX(0,3) /* LDREX 0(R0),R3 */ CMP.S R3, R1 BNE fail - STREX(2,0,4) /* STREX 0(R0),R2,R4 */ + STREX(2,0,4) /* STREX 0(R0),R2,R4 */ CMP.S $0, R4 BNE spincas - MOVW $0, R0 - DMB + DMB /* required by erratum 754327 */ MOVW $1, R0 RET fail: CLREX MOVW $0, R0 - DMB RET -TEXT _xinc(SB), $0 /* void _xinc(long *); */ -TEXT ainc(SB), $0 /* long ainc(long *); */ +TEXT adec(SB), $0 /* long adec(long *); */ + MOVW $-1, R5 + B start +TEXT ainc(SB), $0 /* long ainc(long *); */ + MOVW $1, R5 +start: + DMB spinainc: - LDREX(0,3) /* LDREX 0(R0),R3 */ - ADD $1,R3 - STREX(3,0,4) /* STREX 0(R0),R3,R4 */ + LDREX(0,3) /* LDREX 0(R0),R3 */ + ADD R5, R3 /* inc or dec */ + STREX(3,0,4) /* STREX 0(R0),R3,R4 */ CMP.S $0, R4 BNE spinainc - MOVW $0, R0 - DMB + DMB /* required by erratum 754327 */ MOVW R3, R0 RET -TEXT _xdec(SB), $0 /* long _xdec(long *); */ -TEXT adec(SB), $0 /* long adec(long *); */ -spinadec: - LDREX(0,3) /* LDREX 0(R0),R3 */ - SUB $1,R3 - STREX(3,0,4) /* STREX 0(R0),R3,R4 */ - CMP.S $0, R4 - BNE spinadec - MOVW $0, R0 - DMB - MOVW R3, R0 +TEXT loadlinked(SB), $0 /* long loadlinked(long *); */ + LDREX(0,0) /* LDREX 0(R0),R0 */ RET -TEXT loadlinked(SB), $0 /* long loadlinked(long *); */ - LDREX(0,0) /* LDREX 0(R0),R0 */ - RET - -TEXT storecond(SB), $0 /* int storecond(long *, long); */ +TEXT storecond(SB), $0 /* int storecond(long *, long); */ MOVW ov+4(FP), R3 - STREX(3,0,4) /* STREX 0(R0),R3,R4 */ - MOVW $0, R0 - DMB - RSB $1, R4, R0 + STREX(3,0,0) /* STREX 0(R0),R3,R0 */ + DMB /* required by erratum 754327 */ + RSB $1, R0 RET --- /n/sources/plan9/sys/src/ape/lib/ap/arm/setjmp.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/arm/setjmp.s Sun Jun 28 00:00:00 2026 @@ -1,29 +1,28 @@ arg=0 link=14 -sp=13 TEXT setjmp(SB), 1, $-4 - MOVW R(sp), (R(arg+0)) - MOVW R(link), 4(R(arg+0)) - MOVW $0, R0 + MOVW SP, (R(arg)) + MOVW R(link), 4(R(arg)) + MOVW $0, R(arg) RET TEXT sigsetjmp(SB), 1, $-4 - MOVW savemask+4(FP), R(arg+2) - MOVW R(arg+2), 0(R(arg+0)) - MOVW $_psigblocked(SB), R(arg+2) - MOVW R2, 4(R(arg+0)) - MOVW R(sp), 8(R(arg+0)) - MOVW R(link), 12(R(arg+0)) - MOVW $0, R(arg+0) + MOVW savemask+4(FP), R2 + MOVW R2, 0(R(arg)) + MOVW $_psigblocked(SB), R2 + MOVW R2, 4(R(arg)) + MOVW SP, 8(R(arg)) + MOVW R(link), 12(R(arg)) + MOVW $0, R(arg) RET TEXT longjmp(SB), 1, $-4 - MOVW r+4(FP), R(arg+2) - CMP $0, R(arg+2) + MOVW r+4(FP), R2 + CMP $0, R2 BNE ok /* ansi: "longjmp(0) => longjmp(1)" */ - MOVW $1, R(arg+2) /* bless their pointed heads */ -ok: MOVW (R(arg+0)), R(sp) - MOVW 4(R(arg+0)), R(link) - MOVW R(arg+2), R(arg+0) + MOVW $1, R2 /* bless their pointed heads */ +ok: MOVW (R(arg)), SP + MOVW 4(R(arg)), R(link) + MOVW R2, R(arg) RET --- /n/sources/plan9/sys/src/ape/lib/ap/arm64/_seek.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/arm64/_seek.c Sun Jun 28 00:00:00 2026 @@ -1,13 +1,11 @@ -typedef long long vlong; +extern long __SEEK(long long*, int, long long, int); -extern int __SEEK(vlong*, int, vlong, int); - -vlong -_SEEK(int fd, vlong o, int p) +long long +_SEEK(int fd, long long o, int p) { - vlong l; + long long l; if(__SEEK(&l, fd, o, p) < 0) - l = -1LL; + l = -1; return l; } --- /n/sources/plan9/sys/src/ape/lib/ap/arm64/atom.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/arm64/atom.s Sun Jun 28 00:00:00 2026 @@ -1,66 +1,48 @@ -#define ISH (2<<2 | 3) - /* - * int casl(ulong *p, ulong ov, ulong nv); - * int cas32(u32int*, u32int, u32int); + * int cas(ulong *p, ulong ov, ulong nv); */ -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 +TEXT cas+0(SB),0,$0 /* r0 holds p */ +TEXT casp+0(SB),0,$0 /* r0 holds p */ + MOV ov+8(FP), R1 + MOV nv+16(FP), R2 spincas: - LDXRW 0(R0), R3 + LDXR 0(RARG), R3 CMP R3, R1 BNE fail - STXRW R2, 0(R0), R4 + STXR R2,0(RARG),R4 CBNZ R4, spincas - MOVW $1, R0 - DMB $ISH + MOV $1, R0 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 + MOV $0, R0 RETURN -TEXT _xinc(SB), $0 /* void _xinc(long *); */ -TEXT ainc(SB), $0 /* long ainc(long *); */ - DMB $ISH +TEXT ainc(SB), $0 /* long ainc(long *); */ spinainc: - LDXRW 0(R0), R3 + LDXR 0(RARG), R3 ADD $1,R3 - STXRW R3, 0(R0), R4 + STXR R3,0(RARG),R4 CBNZ R4, spinainc - MOVW R3, R0 - DMB $ISH + MOV R3, R0 RETURN -TEXT _xdec(SB), $0 /* long _xdec(long *); */ -TEXT adec(SB), $0 /* long adec(long *); */ - DMB $ISH +TEXT adec(SB), $0 /* long adec(long *); */ spinadec: - LDXRW 0(R0), R3 + LDXR 0(RARG), R3 SUB $1,R3 - STXRW R3, 0(R0), R4 + STXR R3,0(RARG),R4 CBNZ R4, spinadec - MOVW R3, R0 - DMB $ISH + MOV R3, R0 + RETURN + +TEXT loadlinked(SB), $0 /* long loadlinked(long *); */ + LDXR 0(RARG), R0 + RETURN + +TEXT storecond(SB), $0 /* int storecond(long *, long); */ + MOV ov+8(FP), R3 + STXR R3,0(RARG),R0 + SUB $1, R0 RETURN --- /n/sources/plan9/sys/src/ape/lib/ap/arm64/getfcr.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/arm64/getfcr.s Sun Jun 28 00:00:00 2026 @@ -1,21 +1,16 @@ -#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 +TEXT setfcr(SB), $0 + MOV RARG, FPCR RETURN -TEXT getfcr(SB), 1, $-4 - MRS FPCR, R0 +TEXT getfcr(SB), $0 + MOV FPCR, R0 RETURN -TEXT getfsr(SB), 1, $-4 - MRS FPSR, R0 +TEXT getfsr(SB), $0 + MOV FPSR, R0 RETURN -TEXT setfsr(SB), 1, $-4 - MSR R0, FPSR +TEXT setfsr(SB), $0 + MOV RARG, FPSR RETURN --- /n/sources/plan9/sys/src/ape/lib/ap/arm64/main9.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/arm64/main9.s Sun Jun 28 00:00:00 2026 @@ -1,9 +1,23 @@ -TEXT _main(SB), 1,$24 +#define NPRIVATES 16 + +TEXT _main(SB), 1, $(2*8 + NPRIVATES*8) MOV $setSB(SB), R28 + /* _tos = arg */ + MOVW RARG, _tos(SB) BL _envsetup(SB) - MOV $inargv+0(FP), R0 - MOV R0, 16(RSP) - MOV inargc-8(FP), R0 + + MOV $p-(NPRIVATES*8)(SP), R1 + MOV R1, _privates(SB) + MOVW $NPRIVATES, R1 + MOVW R1, _nprivates(SB) + + MOV $inargv+0(FP), RARG + MOV RARG, 16(RSP) + MOVW inargc-8(FP), RARG + MOVW RARG, 8(RSP) BL main(SB) +loop: + MOVW RARG, 4(RSP) BL exit(SB) - B -1(PC) +// BL _div(SB) + B loop --- /n/sources/plan9/sys/src/ape/lib/ap/arm64/main9p.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/arm64/main9p.s Sun Jun 28 00:00:00 2026 @@ -1,38 +1,49 @@ #define NPRIVATES 16 -arg=0 -sb=28 +GLOBL _tos(SB), $8 +GLOBL _privates(SB), $8 +GLOBL _nprivates(SB), $4 -TEXT _mainp(SB), 1, $(16 + NPRIVATES*8) - MOV $setSB(SB), R(sb) - MOV R(arg), _tos(SB) +TEXT _mainp(SB), 1, $(3*8+NPRIVATES*8) - MOV $p-(NPRIVATES*8)(SP), R1 + MOV $setSB(SB), R28 + + /* _tos = arg */ + MOVW RARG, _tos(SB) + + MOV $private+8(SP), R1 MOV R1, _privates(SB) - MOV $NPRIVATES, R1 - MOV R1, _nprivates(SB) + MOVW $NPRIVATES, R1 + MOVW R1, _nprivates(SB) + /* _profmain(); */ 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) + /* _tos->prof.pp = _tos->prof.next; */ + MOV _tos+0(SB),R1 + MOV 8(R1), R2 + MOV R2, 0(R1) + + BL _envsetup(SB) + + /* main(argc, argv, environ); */ + MOV $inargv+0(FP), RARG + MOV RARG, 16(RSP) + MOVW inargc-8(FP), RARG + MOVW RARG, 4(RSP) + MOV environ(SB), RARG + MOV RARG, 8(RSP) BL main(SB) loop: - MOV $_exitstr<>(SB), R(arg) - BL exits(SB) + MOVW RARG, 4(RSP) + BL exit(SB) +// MOV $_div(SB), RARG /* force loading of div */ + MOV $_profin(SB), RARG /* force loading of profile */ B loop TEXT _savearg(SB), 1, $0 RETURN TEXT _callpc(SB), 1, $0 - MOV 0(SP), R0 + MOV argp-8(FP), RARG RETURN - -DATA _exitstr<>+0(SB)/4, $"main" -GLOBL _exitstr<>+0(SB), $5 --- /n/sources/plan9/sys/src/ape/lib/ap/arm64/notetramp.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/arm64/notetramp.c Sun Jun 28 00:00:00 2026 @@ -52,30 +52,21 @@ notecont(Ureg *u, char *s) 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); + if(j[0]) + _psigblocked = j[1]; + if(nstack == 0 || pcstack[nstack-1].u->sp > j[2+JMPBUFSP]) + longjmp(j+2, 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; + u->pc = j[2+JMPBUFPC]; + u->sp = j[2+JMPBUFSP]; _NOTED(3); /* NRSTR */ } --- /n/sources/plan9/sys/src/ape/lib/ap/arm64/setjmp.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/arm64/setjmp.s Sun Jun 28 00:00:00 2026 @@ -1,29 +1,27 @@ -arg=0 -link=30 - TEXT setjmp(SB), 1, $-4 MOV SP, R2 - MOVP R2, R(link), 0(R(arg)) - MOV $0, R(arg) + MOV R2, (RARG) + MOV LR, 8(RARG) + MOV $0, RARG RETURN TEXT sigsetjmp(SB), 1, $-4 MOV savemask+8(FP), R2 - MOV R2, 0(R(arg)) + MOV R2, 0(RARG) MOV $_psigblocked(SB), R2 - MOV R2, 8(R(arg)) + MOV R2, 8(RARG) MOV SP, R2 - MOVP R2, R(link), 16(R(arg)) - MOV $0, R(arg) + MOV R2, 16(RARG) + MOV LR, 24(RARG) + MOV $0, RARG 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) + MOV r+8(FP), R1 + CBNZ R1, ok + MOV $1, R1 +ok: MOV (RARG), R2 + MOV 8(RARG), LR + MOV R2, SP + MOV R1, RARG RETURN --- /n/sources/plan9/sys/src/ape/lib/ap/arm64/tas.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/arm64/tas.s Sun Jun 28 00:00:00 2026 @@ -1,11 +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 +TEXT _tas(SB), 1, $-4 + MOV RARG, R2 + MOV $0xdead, R3 +tas1: + LDXR (R2), R0 + CBNZ R0, tas0 + STXR R3, (R2), R4 + CBNZ R4, tas1 +tas0: + CLREX RETURN --- /n/sources/plan9/sys/src/ape/lib/ap/gen/memchr.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/gen/memchr.c Sun Jun 28 00:00:00 2026 @@ -5,7 +5,7 @@ memchr(const void *ap, int c, size_t n) { unsigned char *sp; - sp = ap; + sp = (unsigned char *)ap; c &= 0xFF; while(n > 0) { if(*sp++ == c) --- /n/sources/plan9/sys/src/ape/lib/ap/gen/memcmp.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/gen/memcmp.c Sun Jun 28 00:00:00 2026 @@ -6,8 +6,8 @@ memcmp(const void *a1, const void *a2, size_t n) char *s1, *s2; unsigned c1, c2; - s1 = a1; - s2 = a2; + s1 = (char *)a1; + s2 = (char *)a2; while(n > 0) { c1 = *s1++; c2 = *s2++; --- /n/sources/plan9/sys/src/ape/lib/ap/gen/memmove.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/gen/memmove.c Sun Jun 28 00:00:00 2026 @@ -1,4 +1,5 @@ #include +#include void* memmove(void *a1, const void *a2, size_t n) @@ -6,12 +7,12 @@ memmove(void *a1, const void *a2, size_t n) char *s1, *s2; extern void abort(void); - if((long)n < 0) + if((intptr_t)n < 0) abort(); + s1 = (char *)a1; + s2 = (char *)a2; if(a1 > a2) goto back; - s1 = a1; - s2 = a2; while(n > 0) { *s1++ = *s2++; n--; @@ -19,8 +20,8 @@ memmove(void *a1, const void *a2, size_t n) return a1; back: - s1 = (char*)a1 + n; - s2 = (char*)a2 + n; + s1 += n; + s2 += n; while(n > 0) { *--s1 = *--s2; n--; --- /n/sources/plan9/sys/src/ape/lib/ap/gen/mkfile Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/gen/mkfile Sun Jun 28 00:00:00 2026 @@ -61,4 +61,4 @@ OFILES= `{rc ./reduce $O $objtype $ALLOFILES} +#include #define SWAPINIT(a, es) swaptype = \ - (a - (char*) 0) % sizeof(long) || es % sizeof(long) ? 2 : \ - es == sizeof(long) ? 0 : 1; + (uintptr_t)(a) % sizeof(size_t) || es % sizeof(size_t) ? 2 : \ + es == sizeof(size_t) ? 0 : 1; #define swapcode(TYPE, parmi, parmj, n) { \ - long i = (n) / (int) sizeof(TYPE); \ + size_t i = (n) / (int) sizeof(TYPE); \ register TYPE *pi = (TYPE *) (parmi); \ register TYPE *pj = (TYPE *) (parmj); \ do { \ @@ -14,22 +15,29 @@ *pj++ = t; \ } while (--i > 0); \ } -static void swapfunc(char *a, char *b, int n, int swaptype) -{ if (swaptype <= 1) swapcode(long, a, b, n) - else swapcode(char, a, b, n) + +static void +swapfunc(char *a, char *b, int n, int swaptype) +{ + if (swaptype <= 1) + swapcode(size_t, a, b, n) + else + swapcode(char, a, b, n) } #define swap(a, b) { \ if (swaptype == 0) { \ - long t = * (long *) (a); \ - * (long *) (a) = * (long *) (b); \ - * (long *) (b) = t; \ + size_t t = * (size_t *) (a); \ + * (size_t *) (a) = * (size_t *) (b); \ + * (size_t *) (b) = t; \ } else \ swapfunc(a, b, es, swaptype); \ } #define vecswap(a, b, n) { if (n > 0) swapfunc(a, b, n*es, swaptype); } -static char *med3func(char *a, char *b, char *c, int (*cmp)(const void *, const void *)) -{ return cmp(a, b) < 0 ? +static char * +med3func(char *a, char *b, char *c, int (*cmp)(const void *, const void *)) +{ + return cmp(a, b) < 0 ? (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ) ) : (cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ) ); } @@ -38,7 +46,7 @@ static char *med3func(char *a, char *b, char *c, int (*cmp)(const void *, const void qsort(void *va, size_t n, size_t es, int (*cmp)(const void *, const void *)) { char *a, *pa, *pb, *pc, *pd, *pl, *pm, *pn; - int r, swaptype, na, nb, nc, nd, d; + int r, swaptype, na, nb, nc, nd, d; a = va; SWAPINIT(a, es); --- /n/sources/plan9/sys/src/ape/lib/ap/gen/strchr.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/gen/strchr.c Sun Jun 28 00:00:00 2026 @@ -8,11 +8,11 @@ strchr(const char *s, int c) if(c == 0) { while(*s++) ; - return s-1; + return (char *)s-1; } while(c1 = *s++) if(c1 == c) - return s-1; + return (char *)s-1; return 0; } --- /n/sources/plan9/sys/src/ape/lib/ap/gen/strncpy.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/gen/strncpy.c Sun Jun 28 00:00:00 2026 @@ -1,3 +1,4 @@ +#include #include char* --- /n/sources/plan9/sys/src/ape/lib/ap/mips/atom.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/mips/atom.s Sun Jun 28 00:00:00 2026 @@ -7,7 +7,6 @@ #define NOOP WORD $0x27 TEXT ainc(SB), 1, $-4 /* long ainc(long *); */ -TEXT _xinc(SB), 1, $-4 /* void _xinc(long *); */ MOVW R1, R2 /* address of counter */ loop: MOVW $1, R3 LL(2, 1) @@ -20,7 +19,6 @@ loop: MOVW $1, R3 RET TEXT adec(SB), 1, $-4 /* long adec(long*); */ -TEXT _xdec(SB), 1, $-4 /* long _xdec(long *); */ MOVW R1, R2 /* address of counter */ loop1: MOVW $-1, R3 LL(2, 1) --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/9mallocz.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/9mallocz.c Sun Jun 28 00:00:00 2026 @@ -2,7 +2,7 @@ #include void* -_MALLOCZ(int n, int clr) +_MALLOCZ(size_t n, int clr) { void *v; --- /dev/null +++ /sys/src/ape/lib/ap/plan9/README Sun Jun 28 00:00:00 2026 @@ -0,0 +1,6 @@ +Note that select() is only used by links, python, tcpostio and +drawterm. links and python aren't really vital to Plan 9, and +drawterm won't run on APE due to absence of X11 and it only uses +select for microsecond resolution timing. + +this layer also provides setting and clearing close-on-exec via fcntl. --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/_buf.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/_buf.c Sun Jun 28 00:00:00 2026 @@ -1,3 +1,4 @@ +/* buffering for APE's emulated file descriptors, mainly for select */ #define _BSDTIME_EXTENSION #define _LOCK_EXTENSION #include "lib.h" @@ -10,7 +11,7 @@ #include #include #include -#include +#include #include "sys9.h" typedef struct Muxseg { @@ -23,7 +24,6 @@ typedef struct Muxseg { Muxbuf bufs[INITBUFS]; /* can grow, via segbrk() */ } Muxseg; -#define MUXADDR ((void*)0x6000000) static Muxseg *mux = 0; /* shared memory segment */ /* _muxsid and _killmuxsid are known in libbsd's listen.c */ @@ -57,22 +57,25 @@ _startbuf(int fd) if(mux == 0){ _RFORK(RFREND); - mux = (Muxseg*)_SEGATTACH(0, "shared", MUXADDR, sizeof(Muxseg)); - if((long)mux == -1){ + mux = (Muxseg*)_SEGATTACH(0, "shared", 0, sizeof(Muxseg)); + if((intptr_t)mux == -1){ _syserrno(); return -1; } /* segattach has returned zeroed memory */ atexit(_killmuxsid); } + if((intptr_t)mux == -1){ + _syserrno(); + return -1; + } if(fd == -1) return 0; - lock(&mux->lock); slot = mux->curfds++; if(mux->curfds > INITBUFS) { - if(_SEGBRK(mux, mux->bufs+mux->curfds) < 0){ + if(_SEGBRK(mux, mux->bufs+mux->curfds) == (void *)-1){ _syserrno(); unlock(&mux->lock); return -1; @@ -99,7 +102,7 @@ _startbuf(int fd) for(i=0; ibuf = b; f->flags |= FD_BUFFERED; unlock(&mux->lock); - _muxsid = _RENDEZVOUS(0, 0); + _muxsid = (int)(unsigned long long)_RENDEZVOUS(0, 0); /* leave fd open in parent so system doesn't reuse it */ return 0; } @@ -152,7 +155,7 @@ _copyproc(int fd, Muxbuf *b) /* sleep until there's room */ b->roomwait = 1; unlock(&mux->lock); - _RENDEZVOUS((unsigned long)&b->roomwait, 0); + _RENDEZVOUS(&b->roomwait, 0); } } else unlock(&mux->lock); @@ -174,15 +177,15 @@ _copyproc(int fd, Muxbuf *b) if(mux->selwait && FD_ISSET(fd, &mux->ewant)) { mux->selwait = 0; unlock(&mux->lock); - _RENDEZVOUS((unsigned long)&mux->selwait, fd); + _RENDEZVOUS(&mux->selwait, (void *)fd); } else if(b->datawait) { b->datawait = 0; unlock(&mux->lock); - _RENDEZVOUS((unsigned long)&b->datawait, 0); + _RENDEZVOUS(&b->datawait, 0); } else if(mux->selwait && FD_ISSET(fd, &mux->rwant)) { mux->selwait = 0; unlock(&mux->lock); - _RENDEZVOUS((unsigned long)&mux->selwait, fd); + _RENDEZVOUS(&mux->selwait, (void *)fd); } else unlock(&mux->lock); _exit(0); @@ -195,12 +198,12 @@ _copyproc(int fd, Muxbuf *b) b->datawait = 0; unlock(&mux->lock); /* wake up _bufreading process */ - _RENDEZVOUS((unsigned long)&b->datawait, 0); + _RENDEZVOUS(&b->datawait, 0); } else if(mux->selwait && FD_ISSET(fd, &mux->rwant)) { mux->selwait = 0; unlock(&mux->lock); /* wake up selecting process */ - _RENDEZVOUS((unsigned long)&mux->selwait, fd); + _RENDEZVOUS(&mux->selwait, (void *)fd); } else unlock(&mux->lock); } else @@ -237,7 +240,7 @@ goteof: /* sleep until there's data */ b->datawait = 1; unlock(&mux->lock); - _RENDEZVOUS((unsigned long)&b->datawait, 0); + _RENDEZVOUS(&b->datawait, 0); lock(&mux->lock); ngot = b->putnext - b->getnext; } @@ -255,7 +258,7 @@ goteof: b->roomwait = 0; unlock(&mux->lock); /* wake up copy process */ - _RENDEZVOUS((unsigned long)&b->roomwait, 0); + _RENDEZVOUS(&b->roomwait, 0); } else unlock(&mux->lock); return ngot; @@ -273,7 +276,7 @@ select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeo else t = -1; if(!((rfds && FD_ANYSET(rfds)) || (wfds && FD_ANYSET(wfds)) - || (efds && FD_ANYSET(efds)))) { + || (efds && FD_ANYSET(efds)))) { /* no requested fds */ if(t > 0) _SLEEP(t); @@ -348,7 +351,7 @@ select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeo } mux->selwait = 1; unlock(&mux->lock); - fd = _RENDEZVOUS((unsigned long)&mux->selwait, 0); + fd = (int)(unsigned long long)_RENDEZVOUS(&mux->selwait, 0); if(fd >= 0) { b = _fdinfo[fd].buf; if(FD_ISSET(fd, &mux->rwant)) { @@ -394,7 +397,7 @@ _timerproc(void) signal(SIGALRM, alarmed); for(i=0; iwaittime); if(timerreset) { @@ -405,7 +408,7 @@ _timerproc(void) mux->selwait = 0; mux->waittime = LONGWAIT; unlock(&mux->lock); - _RENDEZVOUS((unsigned long)&mux->selwait, -2); + _RENDEZVOUS(&mux->selwait, (void *)-2); } else { mux->waittime = LONGWAIT; unlock(&mux->lock); @@ -415,7 +418,7 @@ _timerproc(void) } atexit(_killtimerproc); /* parent process continues */ - _RENDEZVOUS(1, 0); + _RENDEZVOUS((void *)1, 0); } static void --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/_envsetup.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/_envsetup.c Sun Jun 28 00:00:00 2026 @@ -96,6 +96,8 @@ _envsetup(void) free(d9a); if(!fdinited) _fdinit(0, 0); + + /* copy environment into a new allocation */ pp = malloc((1+cnt)*sizeof(char *)); if (pp == 0) return; @@ -109,6 +111,7 @@ _envsetup(void) p++; } *pp = 0; + if(!nohandle) _NOTIFY(_notehandler); } --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/access.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/access.c Sun Jun 28 00:00:00 2026 @@ -26,6 +26,10 @@ access(const char *name, int mode) }; char tname[1024]; + if (name == 0) { + errno = EINVAL; + return -1; + } if(mode == 0){ db = _dirstat(name); if(db == nil){ --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/acid.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/acid.c Sun Jun 28 00:00:00 2026 @@ -2,9 +2,16 @@ cpp -I/sys/include/ape -I/$objtype/include/ape -I./include acid.c > t.c vc -a t.c > acidlib */ +#undef _POSIX_SOURCE +#undef _SUSV2_SOURCE +#undef _PLAN9_SOURCE #define _POSIX_SOURCE 1 +#define _SUSV2_SOURCE +#define _PLAN9_SOURCE #define _BSD_EXTENSION 1 #define _LOCK_EXTENSION + +#include #include #include #include @@ -15,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -24,8 +30,9 @@ #include #include #include + /* #include "lib.h" buf.c below */ /* #include "sys9.h" buf.c below */ #include "_buf.c" #include "dir.h" -#include "fcall.h" +/* #include "fcall.h" */ --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/brk.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/brk.c Sun Jun 28 00:00:00 2026 @@ -1,4 +1,6 @@ #include "lib.h" +#include +#include #include #include "sys9.h" @@ -6,27 +8,28 @@ char end[]; static char *bloc = { end }; extern int _BRK_(void*); -char * +int brk(char *p) { - unsigned long n; + uintptr_t n; - n = (unsigned long)p; - n += 3; - n &= ~3; + n = (uintptr_t)p + sizeof(uintptr_t) - 1; + n &= ~((uintptr_t)sizeof(uintptr_t) - 1); if(_BRK_((void*)n) < 0){ errno = ENOMEM; - return (char *)-1; + return -1; } bloc = (char *)n; return 0; } void * -sbrk(unsigned long n) +sbrk(uintptr_t n) { - n += 3; - n &= ~3; + if ((intptr_t)n < 0) + abort(); + n += sizeof(uintptr_t) - 1; + n &= ~((uintptr_t)sizeof(uintptr_t) - 1); if(_BRK_((void *)(bloc+n)) < 0){ errno = ENOMEM; return (void *)-1; --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/ctime.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/ctime.c Sun Jun 28 00:00:00 2026 @@ -195,7 +195,7 @@ asctime_r(const struct tm *t, char *buf) ct_numb(buf+17, t->tm_sec+100); if(t->tm_year >= 100) { buf[20] = '2'; - buf[21] = t->tm_year >= 200? '1': '0'; + buf[21] = '0'; } ct_numb(buf+22, t->tm_year+100); return buf; --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/dir.h Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/dir.h Sun Jun 28 00:00:00 2026 @@ -1,8 +1,8 @@ typedef long long vlong; typedef unsigned long long uvlong; -typedef unsigned char uchar; +typedef unsigned char uchar; typedef unsigned short ushort; -typedef unsigned int uint; +typedef unsigned uint; typedef unsigned long ulong; #define GBIT8(p) ((p)[0]) --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/execve.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/execve.c Sun Jun 28 00:00:00 2026 @@ -30,6 +30,10 @@ execve(const char *name, const char *argv[], const char *envp[]) fi = &_fdinfo[n]; flags = fi->flags; if(flags&FD_CLOEXEC){ + /* + * bug: if _EXEC fails, this fd should still be open. + * probably hard to arrange. + */ _CLOSE(n); fi->flags = 0; fi->oflags = 0; --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/lib.h Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/lib.h Sun Jun 28 00:00:00 2026 @@ -2,6 +2,7 @@ #include #include #include +#include "_apetypes.h" typedef struct Ureg Ureg; @@ -9,7 +10,7 @@ typedef struct Ureg Ureg; enum { READMAX = 8192, /* read at most this much with _READ */ PERFDMAX = 2*READMAX, /* stop _READing an fd when it has this much */ - INITBUFS = 4, /* allow enough room for this many PERFDMAX */ + INITBUFS = 8, /* allow enough room for this many PERFDMAX */ }; typedef struct Muxbuf { --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/malloc.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/malloc.c Sun Jun 28 00:00:00 2026 @@ -2,52 +2,74 @@ #include #include -typedef unsigned int uint; +#define HOWMANY(x, y) (((x)+((y)-1)) / (y)) +#define ROUNDUP(x, y) (HOWMANY((x), (y)) * (y)) enum { MAGIC = 0xbada110c, - MAX2SIZE = 32, + MAX2SIZE = 8*sizeof(void *), CUTOFF = 12, }; typedef struct Bucket Bucket; struct Bucket { - int size; + int size; /* lg2(actual size) */ int magic; - Bucket *next; - int pad; + union { + Bucket *next; + long long pad; /* force data[] to vlong alignment */ + }; char data[1]; }; typedef struct Arena Arena; struct Arena { - Bucket *btab[MAX2SIZE]; + Bucket *btab[MAX2SIZE]; }; static Arena arena; -#define datoff ((int)((Bucket*)0)->data) +#define datoff ((uintptr_t)((Bucket*)0)->data) #define nil ((void*)0) -extern void *sbrk(unsigned long); +extern void *sbrk(uintptr_t); + +static unsigned long long +nextpow2(unsigned long long n) +{ + int pow; + + for(pow = 1; pow < MAX2SIZE; pow++) + if(n <= (1ULL << pow)) + break; + return pow; +} void* malloc(size_t size) { - uint next; int pow, n; Bucket *bp, *nbp; - - for(pow = 1; pow < MAX2SIZE; pow++) { - if(size <= (1<next; @@ -56,38 +78,31 @@ good: abort(); bp->magic = MAGIC; - return bp->data; + return bp->data; } - size = sizeof(Bucket)+(1<next = (Bucket*)next; + nbp = (Bucket*)((uintptr_t)bp + size); + arena.btab[pow] = nbp; /* list skips first quantum (bp) */ + for(n--; --n > 0; ) { nbp->size = pow; - nbp = nbp->next; + nbp = nbp->next = (Bucket*)((uintptr_t)nbp + size); } nbp->size = pow; - } - else { + } else { bp = sbrk(size); - if((intptr_t)bp == -1) + if(bp == (void *)-1) return nil; } - bp->size = pow; bp->magic = MAGIC; - return bp->data; } @@ -100,7 +115,7 @@ free(void *ptr) return; /* Find the start of the structure */ - bp = (Bucket*)((uint)ptr - datoff); + bp = (Bucket*)((uintptr_t)ptr - datoff); if(bp->magic != MAGIC) abort(); @@ -115,20 +130,20 @@ void* realloc(void *ptr, size_t n) { void *new; - uint osize; + uintptr_t osize; Bucket *bp; if(ptr == nil) return malloc(n); /* Find the start of the structure */ - bp = (Bucket*)((uint)ptr - datoff); + bp = (Bucket*)((uintptr_t)ptr - datoff); if(bp->magic != MAGIC) abort(); - /* enough space in this bucket */ - osize = 1<size; + /* enough space in this bucket? */ + osize = 1ULL << bp->size; if(osize >= n) return ptr; --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/nan.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/nan.c Sun Jun 28 00:00:00 2026 @@ -10,7 +10,7 @@ NaN(void) { FPdbleword a; - a.hi = NANEXP; + a.hi = NANEXP; /* no NANQUIET, so signalling NaN */ a.lo = 1; return a.x; } --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/open.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/open.c Sun Jun 28 00:00:00 2026 @@ -19,6 +19,10 @@ open(const char *path, int flags, ...) Fdinfo *fi; va_list va; + if (path == 0) { + errno = EINVAL; + return -1; + } f = flags&O_ACCMODE; if(flags&O_CREAT){ if(access(path, 0) >= 0){ --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/profile.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/profile.c Sun Jun 28 00:00:00 2026 @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -21,10 +22,10 @@ typedef unsigned long long uvlong; #include "/sys/include/tos.h" -extern void* sbrk(ulong); +extern void* sbrk(uintptr_t); extern long _callpc(void**); extern long _savearg(void); -extern void _cycles(uvlong*); /* 64-bit value of the cycle counter if there is one, 0 if there isn't */ +extern void _cycles(uvlong*); /* uvlong cycle counter if present, else 0 */ static ulong khz; static ulong perr; --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/qlock.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/qlock.c Sun Jun 28 00:00:00 2026 @@ -3,6 +3,7 @@ #define _RESEARCH_SOURCE #include #include +#include #include #include #include "sys9.h" @@ -73,7 +74,7 @@ qlock(QLock *q) unlock(&q->lock); /* wait */ - while((*_rendezvousp)((ulong)mp, 1) == ~0) + while((uintptr_t)(*_rendezvousp)(mp, (void *)1) == ~(uintptr_t)0) ; mp->inuse = 0; } @@ -91,7 +92,8 @@ qunlock(QLock *q) if(q->head == nil) q->tail = nil; unlock(&q->lock); - while((*_rendezvousp)((ulong)p, 0x12345) == ~0) + while((uintptr_t)(*_rendezvousp)(p, (void *)0x12345) == + ~(uintptr_t)0) ; return; } --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/read.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/read.c Sun Jun 28 00:00:00 2026 @@ -26,16 +26,10 @@ read(int d, void *buf, size_t nbytes) noblock = f->oflags&O_NONBLOCK; isbuf = f->flags&(FD_BUFFERED|FD_BUFFEREDX); if(noblock || isbuf){ - if(f->flags&FD_BUFFEREDX) { + if(f->flags&FD_BUFFEREDX || !isbuf && _startbuf(d) != 0) { errno = EIO; return -1; } - if(!isbuf) { - if(_startbuf(d) != 0) { - errno = EIO; - return -1; - } - } n = _readbuf(d, buf, nbytes, noblock); }else{ n = _READ(d, buf, nbytes); --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/signal.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/signal.c Sun Jun 28 00:00:00 2026 @@ -7,6 +7,8 @@ extern sigset_t _psigblocked; +typedef void (*Handler)(int, char *, Ureg *); + static struct { char *msg; /* just check prefix */ int num; @@ -93,7 +95,7 @@ int _notehandler(void *u, char *msg) { int i; - void(*f)(int, char*, Ureg*); + void (*f)(int, char*, Ureg*); extern void _doatexits(void); /* in stdio/exit.c */ if(_finishing) --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/sys9.h Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/sys9.h Sun Jun 28 00:00:00 2026 @@ -1,3 +1,4 @@ +#include "_apetypes.h" typedef struct Waitmsg { @@ -32,7 +33,7 @@ struct Waitmsg #define AWRITE 2 /* write access */ #define AREAD 4 /* read access */ -/* Segattch */ +/* Segattach */ #define SG_RONLY 0040 /* read only */ #define SG_CEXEC 0100 /* detach on exec */ @@ -92,16 +93,17 @@ extern int _FWSTAT(int, unsigned char*, int); extern int _MOUNT(int, int, const char*, int, const char*); extern int _NOTED(int); extern int _NOTIFY(int(*)(void*, char*)); +extern long long _NSEC(void); extern int _OPEN(const char*, int); extern int _PIPE(int*); extern long _PREAD(int, void*, long, long long); extern long _PWRITE(int, void*, long, long long); extern long _READ(int, void*, long); extern int _REMOVE(const char*); -extern int _RENDEZVOUS(unsigned long, unsigned long); +extern void* _RENDEZVOUS(void *, void *); extern int _RFORK(int); -extern int _SEGATTACH(int, char*, void*, unsigned long); -extern int _SEGBRK(void*, void*); +extern void* _SEGATTACH(int, char*, void*, unsigned long); +extern void* _SEGBRK(void*, void*); extern int _SEGDETACH(void*); extern int _SEGFLUSH(void*, unsigned long); extern int _SEGFREE(void*, unsigned long); --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/system.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/system.c Sun Jun 28 00:00:00 2026 @@ -26,12 +26,8 @@ system(const char *s) _syserrno(); return -1; } - for(;;) { - w = wait(&status); - if(w == -1 || w == pid) - break; - } - + while((w = wait(&status)) != -1 && w != pid) + ; if(w == -1){ _syserrno(); return w; --- /n/sources/plan9/sys/src/ape/lib/ap/plan9/ttyname.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/plan9/ttyname.c Sun Jun 28 00:00:00 2026 @@ -4,8 +4,8 @@ char * ttyname(int fd) { - static char buf[100]; + static char buf[16]; - sprintf(buf, "/fd/%d", fd); + snprintf(buf, sizeof buf, "/fd/%d", fd); return buf; } --- /n/sources/plan9/sys/src/ape/lib/ap/power/atom.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/power/atom.s Sun Jun 28 00:00:00 2026 @@ -1,34 +1,30 @@ -TEXT _xinc(SB),$0 /* void _xinc(long *); */ -TEXT ainc(SB),$0 /* long ainc(long *); */ +TEXT ainc(SB),$0 /* long ainc(long *); */ MOVW R3, R4 xincloop: LWAR (R4), R3 ADD $1, R3 - DCBT (R4) /* fix 405 errata cpu_210 */ + DCBT (R4) /* fix 405 errata cpu_210 */ STWCCC R3, (R4) BNE xincloop RETURN -TEXT _xdec(SB),$0 /* long _xdec(long *); */ -TEXT adec(SB),$0 /* long adec(long *); */ +TEXT adec(SB),$0 /* long adec(long *); */ MOVW R3, R4 xdecloop: LWAR (R4), R3 ADD $-1, R3 - DCBT (R4) /* fix 405 errata cpu_210 */ + DCBT (R4) /* fix 405 errata cpu_210 */ STWCCC R3, (R4) BNE xdecloop RETURN TEXT loadlink(SB), $0 - LWAR (R3), R3 RETURN TEXT storecond(SB), $0 - MOVW val+4(FP), R4 - DCBT (R3) /* fix 405 errata cpu_210 */ + DCBT (R3) /* fix 405 errata cpu_210 */ STWCCC R4, (R3) BNE storecondfail MOVW $1, R3 @@ -49,14 +45,14 @@ TEXT casp+0(SB),0,$0 LWAR (R3),R5 CMP R5,R4 BNE fail - DCBT (R3) /* fix 405 errata cpu_210 */ + DCBT (R3) /* fix 405 errata cpu_210 */ STWCCC R8,(R3) BNE fail1 MOVW $1,R3 RETURN fail: - DCBT (R3) /* fix 405 errata cpu_210 */ - STWCCC R5,(R3) /* give up exclusive access */ + DCBT (R3) /* fix 405 errata cpu_210 */ + STWCCC R5,(R3) /* give up exclusive access */ fail1: MOVW R0,R3 RETURN --- /n/sources/plan9/sys/src/ape/lib/ap/power64/atom.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/power64/atom.s Sun Jun 28 00:00:00 2026 @@ -1,33 +1,16 @@ +/* stubs */ TEXT ainc(SB), 1, $-4 /* long ainc(long *); */ - BR _trap - RET - TEXT adec(SB), 1, $-4 /* long adec(long*); */ - BR _trap - RET - -TEXT _xinc(SB), 1, $-4 /* void _xinc(long *); */ - BR _trap - RET - -TEXT _xdec(SB), 1, $-4 /* long _xdec(long *); */ - BR _trap - RET - /* * int cas(uint* p, int ov, int nv); */ TEXT cas(SB), 1, $-4 - BR _trap - RET - /* * int casv(u64int* p, u64int ov, u64int nv); */ TEXT casv(SB), 1, $-4 BR _trap RET - _trap: MOVD $0, R0 MOVD 0(R0), R0 --- /n/sources/plan9/sys/src/ape/lib/ap/power64/mkfile Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/power64/mkfile Sun Jun 28 00:00:00 2026 @@ -2,7 +2,6 @@ APE=/sys/src/ape <$APE/config LIB=/$objtype/lib/ape/libap.a OFILES=\ - _seek.$O\ prof.pp = _tos->prof.next; */ + MOV _tos+0(SB), R10 + MOV XLEN(R10), R9 + MOV R9, (R10) + + JAL R1, _envsetup(SB) + + /* main(argc, argv, environ); */ + MOVW inargc-XLEN(FP), R8 + MOV $inargv+0(FP), R9 + MOV R8, 0(SP) + MOV R9, XLEN(SP) + MOV environ(SB), R9 + MOV R9, (2*XLEN)(SP) + JAL R1, main(SB) +loop: + /* exit(main(argc, argv)) */ + MOV R8, 0(SP) + JAL R1, exit(SB) + MOV $_profin(SB), R0 /* force loading of profile */ + MOV R0, R8 + JMP loop + +TEXT _savearg(SB), 1, $0 +TEXT _saveret(SB), 1, $0 + RET + +TEXT _callpc(SB), 1, $0 + MOV argp+0(FP), R8 + MOV XLEN(R8), R8 + RET --- /n/sources/plan9/sys/src/ape/lib/ap/riscv/mkfile Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/riscv/mkfile Sun Jun 28 00:00:00 2026 @@ -4,17 +4,18 @@ LIB=/$objtype/lib/ape/libap.a OFILES=\ atom.$O\ # cycles.$O\ - getfcr.$O\ +# div.$O\ +# getfcr.$O\ lock.$O\ main9.$O\ -# main9p.$O\ - memmove.$O\ - memset.$O\ + main9p.$O\ +# memmove.$O\ +# memset.$O\ notetramp.$O\ setjmp.$O\ - strchr.$O\ - strcmp.$O\ - strcpy.$O\ +# strchr.$O\ +# strcmp.$O\ +# strcpy.$O\ tas.$O\ vlop.$O\ vlrt.$O\ --- /dev/null +++ /sys/src/ape/lib/ap/riscv/notejmp.c Sun Jun 28 00:00:00 2026 @@ -0,0 +1,16 @@ +#include +#include +#include + +void +notejmp(void *vr, jmp_buf j, int ret) +{ + struct Ureg *r = vr; + + r->ret = ret; + if(ret == 0) + r->ret = 1; + r->pc = j[JMPBUFPC]; + r->sp = j[JMPBUFSP]; + noted(NCONT); +} --- /n/sources/plan9/sys/src/ape/lib/ap/riscv/notetramp.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/riscv/notetramp.c Sun Jun 28 00:00:00 2026 @@ -5,6 +5,7 @@ /* A stack to hold pcs when signals nest */ #define MAXSIGSTACK 20 + typedef struct Pcstack Pcstack; static struct Pcstack { int sig; --- /n/sources/plan9/sys/src/ape/lib/ap/riscv/setjmp.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/riscv/setjmp.s Sun Jun 28 00:00:00 2026 @@ -5,7 +5,7 @@ sp=2 TEXT setjmp(SB), 1, $-4 MOVW R(sp), (R(arg+0)) MOVW R(link), 4(R(arg+0)) - MOVW $0, R(arg) + MOVW R0, R(arg) RET TEXT sigsetjmp(SB), 1, $-4 @@ -15,7 +15,7 @@ TEXT sigsetjmp(SB), 1, $-4 MOVW R2, 4(R(arg+0)) MOVW R(sp), 8(R(arg+0)) MOVW R(link), 12(R(arg+0)) - MOVW $0, R(arg+0) + MOVW R0, R(arg+0) RET TEXT longjmp(SB), 1, $-4 --- /dev/null +++ /sys/src/ape/lib/ap/riscv/setsb.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,3 @@ +TEXT setsb(SB), $-4 + MOVW $setSB(SB), R3 + RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv/unused/memccpy.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,20 @@ + TEXT memccpy(SB), $0 +MOVW R8, 0(FP) + MOVW n+12(FP), R8 + BEQ R8, ret + MOVW s1+0(FP), R10 + MOVW s2+4(FP), R9 + MOVBU c+11(FP), R11 + ADD R8, R9, R12 + +l1: MOVBU (R9), R13 + ADD $1, R9 + MOVB R13, (R10) + ADD $1, R10 + BEQ R11, R13, eq + BNE R9, R12, l1 + MOVW $0, R8 + RET + +eq: MOVW R10, R8 +ret: RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv/unused/memchr.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,39 @@ + TEXT memchr(SB), $0 +MOVW R8, 0(FP) + + MOVW n+8(FP), R8 + MOVW s1+0(FP), R9 + MOVBU c+7(FP), R10 + ADD R8, R9, R13 + + AND $(~1), R8, R12 + ADD R9, R12 + BEQ R9, R12, lt2 + +l1: + MOVBU 0(R9), R11 + MOVBU 1(R9), R14 + BEQ R10, R11, eq0 + ADD $2, R9 + BEQ R10, R14, eq + BNE R9, R12, l1 + +lt2: + BEQ R9, R13, zret + +l2: + MOVBU (R9), R11 + ADD $1, R9 + BEQ R10, R11, eq + BNE R9, R13, l2 +zret: + MOVW R0, R8 + RET + +eq0: + MOVW R9, R8 + RET + +eq: + SUB $1,R9, R8 + RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv/unused/memcmp.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,114 @@ + TEXT memcmp(SB), $0 + MOVW R8, s1+0(FP) + MOVW n+8(FP), R15 /* R15 is count */ + MOVW s1+0(FP), R9 /* R9 is pointer1 */ + MOVW s2+4(FP), R10 /* R10 is pointer2 */ + ADD R15,R9, R11 /* R11 is end pointer1 */ + +/* + * if not at least 4 chars, + * dont even mess around. + * 3 chars to guarantee any + * rounding up to a word + * boundary and 4 characters + * to get at least maybe one + * full word cmp. + */ + SLT $4,R15, R8 + BNE R8, out + +/* + * test if both pointers + * are similarly word aligned + */ + XOR R9,R10, R8 + AND $3, R8 + BNE R8, out + +/* + * byte at a time to word align + */ +l1: + AND $3,R9, R8 + BEQ R8, l2 + MOVBU 0(R9), R14 + MOVBU 0(R10), R15 + ADD $1, R9 + BNE R14,R15, ne + ADD $1, R10 + JMP l1 + +/* + * turn R15 into end pointer1-15 + * cmp 16 at a time while theres room + */ +l2: + ADD $-15,R11, R15 +l3: + SLTU R15,R9, R8 + BEQ R8, l4 + MOVW 0(R9), R12 + MOVW 0(R10), R13 + BNE R12,R13, ne1 + MOVW 4(R9), R12 + MOVW 4(R10), R13 + BNE R12,R13, ne1 + MOVW 8(R9), R12 + MOVW 8(R10), R13 + BNE R12,R13, ne1 + MOVW 12(R9), R12 + MOVW 12(R10), R13 + BNE R12,R13, ne1 + ADD $16, R9 + ADD $16, R10 + JMP l3 + +/* + * turn R15 into end pointer1-3 + * cmp 4 at a time while theres room + */ +l4: + ADD $-3,R11, R15 +l5: + SLTU R15,R9, R8 + BEQ R8, out + MOVW 0(R9), R12 + MOVW 0(R10), R13 + ADD $4, R9 + BNE R12,R13, ne1 + ADD $4, R10 + JMP l5 + +/* + * last loop, cmp byte at a time + */ +out: + SLTU R11,R9, R8 + BEQ R8, ret + MOVBU 0(R9), R14 + MOVBU 0(R10), R15 + ADD $1, R9 + BNE R14,R15, ne + ADD $1, R10 + JMP out + +/* + * compare bytes in R12 and R13, lsb first + */ +ne1: + MOVW $0xff, R8 +ne1x: + AND R8, R12, R14 + AND R8, R13, R15 + BNE R14, R15, ne + SLL $8, R8 + BNE R8, ne1x + JMP ret + +ne: + SLTU R14,R15, R8 + BNE R8, ret + MOVW $-1,R8 +ret: + RET + END --- /dev/null +++ /sys/src/ape/lib/ap/riscv/unused/memmove.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,141 @@ + TEXT memcpy(SB), $-4 + TEXT memmove(SB), $-4 + MOVW R8, s1+0(FP) + + MOVW n+8(FP), R9 /* count */ + BEQ R9, return + BGT R9, ok + MOVW $0, R9 +ok: + MOVW s1+0(FP), R11 /* dest pointer */ + MOVW s2+4(FP), R10 /* source pointer */ + + BLTU R10, R11, back + +/* + * byte-at-a-time forward copy to + * get source (R10) aligned. + */ +f1: + AND $3, R10, R8 + BEQ R8, f2 + SUB $1, R9 + BLT R9, return + MOVB (R10), R8 + MOVB R8, (R11) + ADD $1, R10 + ADD $1, R11 + JMP f1 + +/* + * check that dest is aligned + * if not, just go byte-at-a-time + */ +f2: + AND $3, R11, R8 + BEQ R8, f3 + SUB $1, R9 + BLT R9, return + JMP f5 +/* + * quad-long-at-a-time forward copy + */ +f3: + SUB $16, R9 + BLT R9, f4 + MOVW 0(R10), R12 + MOVW 4(R10), R13 + MOVW 8(R10), R14 + MOVW 12(R10), R15 + MOVW R12, 0(R11) + MOVW R13, 4(R11) + MOVW R14, 8(R11) + MOVW R15, 12(R11) + ADD $16, R10 + ADD $16, R11 + JMP f3 + +/* + * cleanup byte-at-a-time + */ +f4: + ADD $15, R9 + BLT R9, return +f5: + MOVB (R10), R8 + MOVB R8, (R11) + ADD $1, R10 + ADD $1, R11 + SUB $1, R9 + BGE R9, f5 + JMP return + +return: + MOVW s1+0(FP),R0 + RET + +/* + * everything the same, but + * copy backwards + */ +back: + ADD R9, R10 + ADD R9, R11 + +/* + * byte-at-a-time backward copy to + * get source (R10) aligned. + */ +b1: + AND $3, R10, R8 + BEQ R8, b2 + SUB $1, R9 + BLT R9, return + SUB $1, R10 + SUB $1, R11 + MOVB (R10), R8 + MOVB R8, (R11) + JMP b1 + +/* + * check that dest is aligned + * if not, just go byte-at-a-time + */ +b2: + AND $3, R11, R8 + BEQ R8, b3 + SUB $1, R9 + BLT R9, return + JMP b5 +/* + * quad-long-at-a-time backward copy + */ +b3: + SUB $16, R9 + BLT R9, b4 + SUB $16, R10 + SUB $16, R11 + MOVW 0(R10), R12 + MOVW 4(R10), R13 + MOVW 8(R10), R14 + MOVW 12(R10), R15 + MOVW R12, 0(R11) + MOVW R13, 4(R11) + MOVW R14, 8(R11) + MOVW R15, 12(R11) + JMP b3 + +/* + * cleanup byte-at-a-time backward + */ +b4: + ADD $15, R9 + BLT R9, return +b5: + SUB $1, R10 + SUB $1, R11 + MOVB (R10), R8 + MOVB R8, (R11) + SUB $1, R9 + BGE R9, b5 + JMP return --- /dev/null +++ /sys/src/ape/lib/ap/riscv/unused/memset.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,83 @@ + TEXT memset(SB),$12 +MOVW R8, s1+0(FP) + + MOVW n+8(FP), R10 /* R10 is count */ + MOVW p+0(FP), R11 /* R11 is pointer */ + MOVW c+4(FP), R12 /* R12 is char */ + ADD R10,R11, R13 /* R13 is end pointer */ + +/* + * if not at least 4 chars, + * dont even mess around. + * 3 chars to guarantee any + * rounding up to a word + * boundary and 4 characters + * to get at least maybe one + * full word store. + */ + SLT $4,R10, R8 + BNE R8, out + +/* + * turn R12 into a word of characters + */ + AND $0xff, R12 + SLL $8,R12, R8 + OR R8, R12 + SLL $16,R12, R8 + OR R8, R12 + +/* + * store one byte at a time until pointer + * is aligned on a word boundary + */ +l1: + AND $3,R11, R8 + BEQ R8, l2 + MOVB R12, 0(R11) + ADD $1, R11 + JMP l1 + +/* + * turn R10 into end pointer-15 + * store 16 at a time while theres room + */ +l2: + ADD $-15,R13, R10 +l3: + SLTU R10,R11, R8 + BEQ R8, l4 + MOVW R12, 0(R11) + MOVW R12, 4(R11) + ADD $16, R11 + MOVW R12, -8(R11) + MOVW R12, -4(R11) + JMP l3 + +/* + * turn R10 into end pointer-3 + * store 4 at a time while theres room + */ +l4: + ADD $-3,R13, R10 +l5: + SLTU R10,R11, R8 + BEQ R8, out + MOVW R12, 0(R11) + ADD $4, R11 + JMP l5 + +/* + * last loop, store byte at a time + */ +out: + SLTU R13,R11 ,R8 + BEQ R8, ret + MOVB R12, 0(R11) + ADD $1, R11 + JMP out + +ret: + MOVW s1+0(FP), R8 + RET + END --- /dev/null +++ /sys/src/ape/lib/ap/riscv/unused/strchr.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,63 @@ + TEXT strchr(SB), $0 + MOVBU c+4(FP), R11 + MOVW R8, R10 + + BEQ R11, l2 + +/* + * char is not null + */ +l1: + MOVBU (R10), R8 + ADD $1, R10 + BEQ R8, ret + BNE R8,R11, l1 + JMP rm1 + +/* + * char is null + * align to word + */ +l2: + AND $3,R10, R8 + BEQ R8, l3 + MOVBU (R10), R8 + ADD $1, R10 + BNE R8, l2 + JMP rm1 + +l3: + MOVW $0xff000000, R13 + MOVW $0x00ff0000, R14 + MOVW $0x0000ff00, R15 + +l4: + MOVW (R10), R12 + ADD $4, R10 + AND $0xff, R12, R8 + BEQ R8, b0 + AND R15, R12, R8 + BEQ R8, b1 + AND R14, R12, R8 + BEQ R8, b2 + AND R13, R12, R8 + BNE R8, l4 + +rm1: + ADD $-1,R10, R8 + JMP ret + +b2: + ADD $-2,R10, R8 + JMP ret + +b1: + ADD $-3,R10, R8 + JMP ret + +b0: + ADD $-4,R10, R8 + JMP ret + +ret: + RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv/unused/strcmp.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,21 @@ +TEXT strcmp(SB), $0 + + MOVW s2+4(FP), R9 + +l1: + MOVBU (R9), R10 + MOVBU (R8), R11 + ADD $1, R8 + BEQ R10, end + ADD $1, R9 + BEQ R10, R11, l1 + + SLTU R11, R10, R8 + BNE R8, ret + MOVW $-1, R8 + RET + +end: + SLTU R11, R10, R8 +ret: + RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv/unused/strcpy.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,92 @@ +TEXT strcpy(SB), $0 + + MOVW s2+4(FP),R9 /* R9 is from pointer */ + MOVW R8, R10 /* R10 is to pointer */ + +/* + * align 'from' pointer + */ +l1: + AND $3, R9, R12 + ADD $1, R9 + BEQ R12, l2 + MOVB -1(R9), R12 + ADD $1, R10 + MOVB R12, -1(R10) + BNE R12, l1 + RET + +/* + * test if 'to' is also aligned + */ +l2: + AND $3,R10, R12 + BEQ R12, l4 + +/* + * copy 4 at a time, 'to' not aligned + */ +l3: + MOVW -1(R9), R11 + ADD $4, R9 + ADD $4, R10 + MOVB R11, -4(R10) + AND $0xff, R11, R12 + BEQ R12, out + + SRL $8, R11 + MOVB R11, -3(R10) + AND $0xff, R11, R12 + BEQ R12, out + + SRL $8, R11 + MOVB R11, -2(R10) + AND $0xff, R11, R12 + BEQ R12, out + + SRL $8, R11 + MOVB R11, -1(R10) + BNE R11, l3 + +out: + RET + +/* + * word at a time both aligned + */ +l4: + MOVW $0xff000000, R14 + MOVW $0x00ff0000, R15 + MOVW $0x0000ff00, R13 + +l5: + ADD $4, R10 + MOVW -1(R9), R11 /* fetch */ + ADD $4, R9 + + AND $0xff, R11, R12 /* is it byte 0 */ + BEQ R12, b0 + AND R13, R11, R12 /* is it byte 1 */ + BEQ R12, b1 + AND R15, R11, R12 /* is it byte 2 */ + BEQ R12, b2 + MOVW R11, -4(R10) /* store */ + AND R14, R11, R12 /* is it byte 3 */ + BNE R12, l5 + JMP out + +b0: + MOVB R0, -4(R10) + JMP out + +b1: + MOVB R11, -4(R10) + MOVB R0, -3(R10) + JMP out + +b2: + MOVB R11, -4(R10) + SRL $8, R11 + MOVB R11, -3(R10) + MOVB R0, -2(R10) + JMP out --- /n/sources/plan9/sys/src/ape/lib/ap/riscv/vlop.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/riscv/vlop.s Sun Jun 28 00:00:00 2026 @@ -1,3 +1,4 @@ +/* _mulv(&result, x.lo, x.hi, y.lo, y.hi) */ TEXT _mulv(SB), $0 MOVW 4(FP), R9 // x.lo MOVW 8(FP), R10 // x.hi --- /n/sources/plan9/sys/src/ape/lib/ap/riscv/vlrt.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/riscv/vlrt.c Sun Jun 28 00:00:00 2026 @@ -9,7 +9,7 @@ typedef signed char schar; typedef struct Vlong Vlong; struct Vlong { - ulong lo; + ulong lo; /* little endian */ ulong hi; }; --- /n/sources/plan9/sys/src/ape/lib/ap/riscv64/_seek.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/riscv64/_seek.c Sun Jun 28 00:00:00 2026 @@ -1,4 +1,4 @@ -extern long __SEEK(long long*, int, long long, int); +extern long __SEEK(long long*, int, long long, int); long long _SEEK(int fd, long long o, int p) @@ -9,4 +9,3 @@ _SEEK(int fd, long long o, int p) l = -1; return l; } - --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/argv0.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,4 @@ +GLOBL argv0(SB), $XLEN +GLOBL _tos(SB), $XLEN +GLOBL _privates(SB), $XLEN +GLOBL _nprivates(SB), $4 --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/cycles.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,8 @@ +#define RARG R8 + +/* user-accessible CSRs */ +#define CYCLO 0xc00 + +TEXT cycles(SB), 1, $0 /* cycles since power up */ + MOV CSR(CYCLO), RARG + RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/getcallerpc.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,6 @@ +#define RARG R8 + +TEXT getcallerpc(SB), 1, $0 + MOV 0(SP), RARG + RET + --- /n/sources/plan9/sys/src/ape/lib/ap/riscv64/getfcr.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/riscv64/getfcr.s Sun Jun 28 00:00:00 2026 @@ -1,5 +1,3 @@ -#define LINK R1 -#define SP R2 #define ARG 8 #define FFLAGS 1 --- /n/sources/plan9/sys/src/ape/lib/ap/riscv64/lock.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/riscv64/lock.c Sun Jun 28 00:00:00 2026 @@ -31,6 +31,10 @@ canlock(Lock *l) /* Undo increment (but don't miss wakeup) */ if(adec(&l->key) == 0) return 0; /* changed from 1 -> 0: no contention */ + /* + * another proc raced with us and is waiting in semacquire in lock, + * so wake it up. + */ _SEMRELEASE(&l->sem, 1); return 0; } --- /n/sources/plan9/sys/src/ape/lib/ap/riscv64/main9.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/riscv64/main9.s Sun Jun 28 00:00:00 2026 @@ -1,16 +1,42 @@ - TEXT _main(SB), 1, $(3*XLEN) +/* APE startup following exec. assume vlong alignment of SP */ +#define NPRIVATES 16 +#define FCSR 3 +GLOBL _tos(SB), $XLEN +GLOBL _privates(SB), $XLEN +GLOBL _nprivates(SB), $4 +GLOBL _savedargc(SB), $4 +GLOBL _savedargv(SB), $XLEN + +TEXT _main(SB), 1, $(4*XLEN + NPRIVATES*XLEN) MOV $setSB(SB), R3 - JAL R1, _envsetup(SB) + MOV R0, CSR(FCSR) - MOVW inargc-XLEN(FP), R8 - MOV R8, XLEN(R2) - MOV $inargv+0(FP), R9 - MOV R9, (2*XLEN)(R2) - MOV environ(SB), R9 - MOV R9, (3*XLEN)(R2) - JAL R1, main(SB) + /* _tos = arg */ + MOV R8, _tos(SB) + + MOV $p-(NPRIVATES*XLEN)(SP), R9 + MOV R9, _privates(SB) + MOV $NPRIVATES, R9 + MOVW R9, _nprivates(SB) + /* save argc & argv before envsetup */ + MOVW inargc-XLEN(FP), R9 + MOVW R9, _savedargc(SB) + MOV $inargv+0(FP), R9 + MOV R9, _savedargv(SB) + MOV R0, environ(SB) /* TODO debug */ + JAL R1, _envsetup(SB) /* may trash any non-stable register */ + + /* exit(main(argc, argv, environ)); */ +//#define R2 SP + MOVW _savedargc(SB), R8 /* argc */ MOVW R8, XLEN(R2) + MOV _savedargv(SB), R9 + MOV R9, (2*XLEN)(R2) /* argv */ + MOV environ(SB), R9 + MOV R9, (3*XLEN)(R2) /* environ */ + JAL R1, main(SB) + JAL R1, exit(SB) RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/main9p.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,55 @@ +/* _mainp - APE startup with profiling _main */ + +#define NPRIVATES 16 +#define FCSR 3 + +GLOBL _tos(SB), $XLEN +GLOBL _privates(SB), $XLEN +GLOBL _nprivates(SB), $4 + +TEXT _mainp(SB), 1, $(4*XLEN + NPRIVATES*XLEN) + MOV $setSB(SB), R3 + MOV R0, CSR(FCSR) + + /* _tos = arg */ + MOV R8, _tos(SB) + + MOV $p-(NPRIVATES*XLEN)(SP), R9 + MOV R9, _privates(SB) + MOV $NPRIVATES, R9 + MOVW R9, _nprivates(SB) + + /* _profmain(); */ + JAL R1, _profmain(SB) + + /* _tos->prof.pp = _tos->prof.next; */ + MOV _tos+0(SB), R10 + MOV XLEN(R10), R9 + MOV R9, (R10) + + JAL R1, _envsetup(SB) /* may trash any non-stable register */ + + /* main(argc, argv, environ); */ + MOVW inargc-XLEN(FP), R8 /* argc */ + MOV $inargv+0(FP), R9 +// AND $~(XLEN-1), R2 /* vlong alignment */ + MOV R9, (2*XLEN)(R2) /* argv */ + MOV environ(SB), R9 + MOV R9, (3*XLEN)(R2) /* environ */ + JAL R1, main(SB) +loop: + /* exit(main(argc, argv, environ)) */ + JAL R1, exit(SB) + + MOV $_profin(SB), R0 /* force loading of profile */ + MOV R0, R8 + JMP loop + +TEXT _savearg(SB), 1, $0 +TEXT _saveret(SB), 1, $0 + RET + +TEXT _callpc(SB), 1, $0 + MOV argp+0(FP), R8 + MOV XLEN(R8), R8 + RET --- /n/sources/plan9/sys/src/ape/lib/ap/riscv64/malloc.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/riscv64/malloc.c Sun Jun 28 00:00:00 2026 @@ -1,143 +1,253 @@ -#include -#include -#include "../plan9/sys9.h" -#include +/* + * V7 unix malloc, adapted to the modern world + */ + +/* + * C storage allocator + * circular first-fit strategy + * works with noncontiguous, but monotonically linked, arena + * each block is preceded by a ptr to the (pointer of) + * the next following block + * blocks are exact number of words long + * aligned to the data type requirements of ALIGN + * pointers to blocks must have BUSY bit 0 + * bit in ptr is 1 for busy, 0 for idle + * gaps in arena are merely noted as busy blocks + * last block of arena (pointed to by alloct) is empty and + * has a pointer to first + * idle blocks are coalesced during space search + * + * a different implementation may need to redefine + * ALIGN, NALIGN, BLOCK, BUSY, INT + * where INT is integer type to which a pointer can be cast + */ + +#include +#include + +#ifdef debug +#define ASSERT(p) if(!(p))botch("p");else -typedef unsigned long long intptr_t; - -enum -{ - MAGIC = 0xbada110c, - MAX2SIZE = 32, - CUTOFF = 12, -}; - -typedef struct Bucket Bucket; -struct Bucket -{ - int size; - int magic; - Bucket *next; - char data[1]; -}; - -typedef struct Arena Arena; -struct Arena +void +botch(char *s) { - Bucket *btab[MAX2SIZE]; + unlock(&malloclck); + print("assertion botched: %s\n", s); + abort(); +} +#else +#define ASSERT(p) +#endif + +#define INT uintptr +#define ALIGN vlong +#define NALIGN 1 +#define WORD sizeof(union store) +#define BLOCK 1024 /* a multiple of WORD */ + +#define BUSY 1 +#define NULL 0 + +#define testbusy(p) ((INT)(p)&BUSY) +#define setbusy(p) (union store *)((INT)(p)|BUSY) +#define clearbusy(p) (union store *)((INT)(p)&~BUSY) + +typedef union store Store; +union store { + Store *ptr; + ALIGN dummy[NALIGN]; + int calloc; /*calloc clears an array of integers*/ }; -static Arena arena; -#define datoff ((int)((Bucket*)0)->data) -#define nil ((void*)0) +static Store allocs[2]; /*initial arena*/ +static Store *allocp; /*search ptr*/ +static Store *alloct; /*arena top*/ +static Store *allocx; /*for benefit of realloc*/ +static Lock malloclck; -extern void *sbrk(unsigned long); - -void* -malloc(size_t size) +void * +malloc(uintptr nbytes) { - intptr_t next; - int pow, n; - Bucket *bp, *nbp; - - for(pow = 1; pow < MAX2SIZE; pow++) { - if(size <= (1<next; - - if(bp->magic != 0) - abort(); - - bp->magic = MAGIC; - return bp->data; + uintptr nw, temp; + Store *p, *q; + + lock(&malloclck); + if (allocs[0].ptr == 0) { /* first time */ + allocs[0].ptr = setbusy(&allocs[1]); + allocs[1].ptr = setbusy(&allocs[0]); + alloct = &allocs[1]; + allocp = &allocs[0]; } - size = sizeof(Bucket)+(1<next = (Bucket*)next; - nbp->size = pow; - nbp = nbp->next; + nw = (nbytes + WORD + WORD - 1) / WORD; + ASSERT(allocp >= allocs && allocp <= alloct); + ASSERT(allock()); + for (p = allocp; ; ) { + for (temp = 0; ; ) { + if (!testbusy(p->ptr)) { + while (!testbusy((q = p->ptr)->ptr)) { + ASSERT(q > p && q < alloct); + p->ptr = q->ptr; + } + if (q >= p + nw && p + nw >= p) + goto found; + } + q = p; + p = clearbusy(p->ptr); + if (p > q) { + ASSERT(p <= alloct); + } else if (q != alloct || p != allocs) { + ASSERT(q == alloct && p == allocs); + unlock(&malloclck); + return NULL; + } else if (++temp > 1) + break; } - nbp->size = pow; + temp = ((nw + BLOCK/WORD) / (BLOCK/WORD)) * (BLOCK/WORD); + q = (Store *)sbrk(0); + if (q + temp < q) { + unlock(&malloclck); + return NULL; + } + q = (Store *)sbrk(temp * WORD); + if ((INT)q == -1) { + unlock(&malloclck); + return NULL; + } + ASSERT(q > alloct); + alloct->ptr = q; + if (q != alloct + 1) + alloct->ptr = setbusy(alloct->ptr); + alloct = q->ptr = q + temp - 1; + alloct->ptr = setbusy(allocs); } - else { - bp = sbrk(size); - if((intptr_t)bp == -1) - return nil; +found: + allocp = p + nw; + ASSERT(allocp <= alloct); + if (q > allocp) { + allocx = allocp->ptr; + allocp->ptr = p->ptr; } - - bp->size = pow; - bp->magic = MAGIC; + p->ptr = setbusy(allocp); + unlock(&malloclck); + return p + 1; +} + +void * +mallocz(uintptr size, int clr) +{ + void *p; - return bp->data; + p = malloc(size); + if (p && clr) + memset(p, 0, size); + return p; } +/* + * freeing strategy tuned for LIFO allocation + */ void -free(void *ptr) +free(void *ap) { - Bucket *bp, **l; + Store *p = (Store *)ap; - if(ptr == nil) + if (p == 0) return; + lock(&malloclck); + ASSERT(p > clearbusy(allocs[1].ptr) && p <= alloct); + ASSERT(allock()); + allocp = --p; + ASSERT(testbusy(p->ptr)); + p->ptr = clearbusy(p->ptr); + ASSERT(p->ptr > allocp && p->ptr <= alloct); + unlock(&malloclck); +} - /* Find the start of the structure */ - bp = (Bucket*)((intptr_t)ptr - datoff); +/* realloc(p, nbytes) reallocates a block obtained from malloc() + * and freed since last call of malloc() + * to have new size nbytes, and old content + * returns new location, or 0 on failure + */ - if(bp->magic != MAGIC) - abort(); +void * +realloc(void *ap, uintptr nbytes) +{ + Store *p, *q; + uintptr nw, onw; - bp->magic = 0; - l = &arena.btab[bp->size]; - bp->next = *l; - *l = bp; + p = ap; + if (nbytes == 0) { + free(p); + return nil; + } + if (p == nil) + return malloc(nbytes); + + if (testbusy(p[-1].ptr)) + free(p); + + onw = p[-1].ptr - p; + q = (Store *)malloc(nbytes); + if (q == NULL || q == p) + return q; + + lock(&malloclck); + memmove(q, p, nbytes); + nw = (nbytes + WORD - 1) / WORD; + if (q < p && q + nw >= p) + (q + (q + nw - p))->ptr = allocx; + unlock(&malloclck); + return q; } -void* -realloc(void *ptr, size_t n) +#ifdef debug +void +allock(void) { - void *new; - size_t osize; - Bucket *bp; - - if(ptr == nil) - return malloc(n); +#ifdef longdebug + Store *p; + int x; + + x = 0; + for (p = &allocs[0]; clearbusy(p->ptr) > p; p = clearbusy(p->ptr)) + if (p == allocp) + x++; + ASSERT(p == alloct); + return x == 1 | p == allocp; +#else + return 1; +#endif +} +#endif - /* Find the start of the structure */ - bp = (Bucket*)((intptr_t)ptr - datoff); +void* +calloc(uintptr n, uintptr szelem) +{ + void *v; - if(bp->magic != MAGIC) - abort(); + if (v = mallocz(n * szelem, 1)) + setmalloctag(v, getcallerpc(&n)); + return v; +} - /* enough space in this bucket */ - osize = 1<size; - if(osize >= n) - return ptr; +void +setmalloctag(void *, uintptr) +{ +} - new = malloc(n); - if(new == nil) - return nil; +void +setrealloctag(void *, uintptr) +{ +} - memmove(new, ptr, osize); - free(ptr); +uintptr +getmalloctag(void *) +{ + return ~0; +} - return new; +uintptr +getrealloctag(void *) +{ + return ~0; } --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/memset.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,83 @@ +/* memset(char *p, int c, size_t n) - ulong version */ + TEXT memset(SB),$(3*XLEN) + MOV R8, p+0(FP) + MOV n+(2*XLEN)(FP), R10 /* R10 is count */ + MOV p+0(FP), R11 /* R11 is pointer */ + MOVW c+XLEN(FP), R12 /* R12 is char */ + ADD R10,R11, R13 /* R13 is end pointer */ + +/* + * if not at least 4 chars, + * dont even mess around. + * 3 chars to guarantee any + * rounding up to a word + * boundary and 4 characters + * to get at least maybe one + * full word store. + */ + SLT $4,R10, R8 + BNE R8, out + +/* + * turn R12 into a word of characters + */ + AND $0xff, R12 + SLL $8,R12, R8 + OR R8, R12 + SLL $16,R12, R8 + OR R8, R12 + +/* + * store one byte at a time until pointer + * is aligned on a word boundary + */ +l1: + AND $3,R11, R8 + BEQ R8, l2 + MOVB R12, 0(R11) + ADD $1, R11 + JMP l1 + +/* + * turn R10 into end pointer-15 + * store 16 at a time while theres room + */ +l2: + ADD $-15,R13, R10 +l3: + SLTU R10,R11, R8 + BEQ R8, l4 + MOVW R12, 0(R11) + MOVW R12, 4(R11) + ADD $16, R11 + MOVW R12, -8(R11) + MOVW R12, -4(R11) + JMP l3 + +/* + * turn R10 into end pointer-3 + * store 4 at a time while theres room + */ +l4: + ADD $-3,R13, R10 +l5: + SLTU R10,R11, R8 + BEQ R8, out + MOVW R12, 0(R11) + ADD $4, R11 + JMP l5 + +/* + * last loop, store byte at a time + */ +out: + SLTU R13,R11 ,R8 + BEQ R8, ret + MOVB R12, 0(R11) + ADD $1, R11 + JMP out + +ret: + MOV s1+0(FP), R8 + RET + END --- /n/sources/plan9/sys/src/ape/lib/ap/riscv64/mkfile Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/riscv64/mkfile Sun Jun 28 00:00:00 2026 @@ -1,20 +1,27 @@ APE=/sys/src/ape <$APE/config LIB=/$objtype/lib/ape/libap.a + OFILES=\ - _seek.$O\ + argv0.$O\ atom.$O\ - brk.$O\ -# cycles.$O\ + cycles.$O\ + getcallerpc.$O\ getfcr.$O\ lock.$O\ main9.$O\ -# main9p.$O\ - malloc.$O\ + main9p.$O\ +# malloc.$O\ +# memccpy.$O\ +# memchr.$O\ +# memcmp.$O\ # memmove.$O\ -# memset.$O\ + memset.$O\ notetramp.$O\ + _seek.$O\ setjmp.$O\ + setsb.$O\ +# sqrt.$O\ # strchr.$O\ # strcmp.$O\ # strcpy.$O\ @@ -23,4 +30,3 @@ OFILES=\ +#include +#include + +void +notejmp(void *vr, jmp_buf j, int ret) +{ + struct Ureg *r = vr; + + r->ret = ret; + if(ret == 0) + r->ret = 1; + r->pc = j[JMPBUFPC]; + r->sp = j[JMPBUFSP]; + noted(NCONT); +} --- /n/sources/plan9/sys/src/ape/lib/ap/riscv64/notetramp.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/riscv64/notetramp.c Sun Jun 28 00:00:00 2026 @@ -1,10 +1,13 @@ +/* must match setjmp.s */ #include "../plan9/lib.h" #include "../plan9/sys9.h" #include #include +#include /* A stack to hold pcs when signals nest */ #define MAXSIGSTACK 20 + typedef struct Pcstack Pcstack; static struct Pcstack { int sig; @@ -39,6 +42,7 @@ notecont(Ureg *u, char *s) Pcstack *p; void(*f)(int, char*, Ureg*); + assert(nstack >= 1); p = &pcstack[nstack-1]; f = p->hdlr; u->pc = p->restorepc; @@ -52,23 +56,28 @@ notecont(Ureg *u, char *s) extern sigset_t _psigblocked; +typedef struct { + sigset_t set; + sigset_t blocked; + jmp_buf jmpbuf; /* APE version: 4 uintptrs */ +} sigjmp_buf_riscv64; + void -siglongjmp(sigjmp_buf _j, int ret) +siglongjmp(sigjmp_buf j, int ret) { struct Ureg *u; - unsigned long long *j; + sigjmp_buf_riscv64 *jb; - j = (uvlong*)_j; - if(j[0]) - _psigblocked = j[1]; - if(nstack == 0 || pcstack[nstack-1].u->sp > j[2+JMPBUFSP]) - longjmp((int*)(j+2), ret); + jb = (sigjmp_buf_riscv64 *)j; + if(jb->set) + _psigblocked = jb->blocked; + if(nstack == 0 || pcstack[nstack-1].u->sp > jb->jmpbuf[JMPBUFSP]) + longjmp((void*)jb->jmpbuf, ret); + assert(nstack >= 1); u = pcstack[nstack-1].u; nstack--; - u->ret = ret; - if(ret == 0) - u->ret = 1; - u->pc = j[2+JMPBUFPC]; - u->sp = j[2+JMPBUFSP]; + u->ret = ret == 0? 1: ret; + u->pc = jb->jmpbuf[JMPBUFPC]; + u->sp = jb->jmpbuf[JMPBUFSP]; /* amd64 adds 8; why? */ _NOTED(3); /* NRSTR */ } --- /n/sources/plan9/sys/src/ape/lib/ap/riscv64/setjmp.s Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/riscv64/setjmp.s Sun Jun 28 00:00:00 2026 @@ -1,24 +1,29 @@ -TEXT setjmp(SB), 1, $-4 - MOV R2, 0(R8) - MOV R1, XLEN(R8) - MOV $0, R8 +/* riscv64 APE version; must match notetramp.c */ +arg=8 +link=1 +sp=2 + +TEXT setjmp(SB), 1, $-4 /* int setjmp(jmp_buf env) */ + MOV R(sp), (R(arg)) + MOV R(link), XLEN(R(arg)) + MOV R0, R(arg) RET -TEXT sigsetjmp(SB), 1, $-4 - MOVW savemask+XLEN(FP), R10 - MOV R10, 0(R8) - MOVW $_psigblocked(SB), R10 - MOV R10, XLEN(R8) - MOV R2, (2*XLEN)(R8) - MOV R1, (3*XLEN)(R8) - MOV $0, R8 +TEXT sigsetjmp(SB), 1, $-4 /* sigsetjmp(sigjmp_buf, int mask) */ + MOVW savemask+8(FP), R(arg+2) /* save signal stuff */ + MOVW R(arg+2), 0(R(arg)) + MOVW _psigblocked(SB), R(arg+2) + MOVW R(arg+2), 4(R(arg)) /* save _psigblocked */ + MOV R(sp), 8(R(arg)) /* save sp */ + MOV R(link), 16(R(arg)) /* save return pc */ + MOV R0, R(arg) RET -TEXT longjmp(SB), 1, $-4 - MOVW r+XLEN(FP), R10 - BNE R10, ok /* ansi: "longjmp(0) => longjmp(1)" */ - MOV $1, R10 /* bless their pointed heads */ -ok: MOV 0(R8), R2 - MOV XLEN(R8), R1 - MOV R10, R8 +TEXT longjmp(SB), 1, $-4 /* void longjmp(jmp_buf env, int val) */ + MOVW r+XLEN(FP), R(arg+2) + BNE R(arg+2), ok /* ansi: "longjmp(0) => longjmp(1)" */ + MOV $1, R(arg+2) /* bless their pointed heads */ +ok: MOV (R(arg)), R(sp) + MOV XLEN(R(arg)), R(link) + MOV R(arg+2), R(arg) RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/setsb.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,3 @@ +TEXT setsb(SB), $-4 + MOV $setSB(SB), R3 + RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/unused/memccpy.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,20 @@ + TEXT memccpy(SB), $0 + MOV R8, 0(FP) + MOVW n+(3*XLEN)(FP), R8 + BEQ R8, ret + MOV s1+0(FP), R10 + MOV s2+XLEN(FP), R9 + MOVBU c+(2*XLEN)(FP), R11 + ADD R8, R9, R12 + +l1: MOVBU (R9), R13 + ADD $1, R9 + MOVB R13, (R10) + ADD $1, R10 + BEQ R11, R13, eq + BNE R9, R12, l1 + MOV R0, R8 + RET + +eq: MOV R10, R8 +ret: RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/unused/memchr.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,38 @@ + TEXT memchr(SB), $0 + MOV R8, 0(FP) + MOVW n+(2*XLEN)(FP), R8 + MOV s1+0(FP), R9 + MOVBU c+XLEN(FP), R10 + ADD R8, R9, R13 + + AND $(~1), R8, R12 + ADD R9, R12 + BEQ R9, R12, lt2 + +l1: + MOVBU 0(R9), R11 + MOVBU 1(R9), R14 + BEQ R10, R11, eq0 + ADD $2, R9 + BEQ R10, R14, eq + BNE R9, R12, l1 + +lt2: + BEQ R9, R13, zret + +l2: + MOVBU (R9), R11 + ADD $1, R9 + BEQ R10, R11, eq + BNE R9, R13, l2 +zret: + MOV R0, R8 + RET + +eq0: + MOV R9, R8 + RET + +eq: + SUB $1, R9, R8 + RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/unused/memcmp.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,114 @@ + TEXT memcmp(SB), $0 + MOV R8, s1+0(FP) + MOVW n+(2*XLEN)(FP), R15 /* R15 is count */ + MOV s1+0(FP), R9 /* R9 is pointer1 */ + MOV s2+XLEN(FP), R10 /* R10 is pointer2 */ + ADD R15, R9, R11 /* R11 is end pointer1 */ + +/* + * if not at least 4 chars, + * dont even mess around. + * 3 chars to guarantee any + * rounding up to a word + * boundary and 4 characters + * to get at least maybe one + * full word cmp. + */ + SLT $4,R15, R8 + BNE R8, out + +/* + * test if both pointers + * are similarly word aligned + */ + XOR R9,R10, R8 + AND $3, R8 + BNE R8, out + +/* + * byte at a time to word align + */ +l1: + AND $3,R9, R8 + BEQ R8, l2 + MOVBU 0(R9), R14 + MOVBU 0(R10), R15 + ADD $1, R9 + BNE R14,R15, ne + ADD $1, R10 + JMP l1 + +/* + * turn R15 into end pointer1-15 + * cmp 16 at a time while theres room + */ +l2: + ADD $-15,R11, R15 +l3: + SLTU R15,R9, R8 + BEQ R8, l4 + MOVW 0(R9), R12 + MOVW 0(R10), R13 + BNE R12,R13, ne1 + MOVW 4(R9), R12 + MOVW 4(R10), R13 + BNE R12,R13, ne1 + MOVW 8(R9), R12 + MOVW 8(R10), R13 + BNE R12,R13, ne1 + MOVW 12(R9), R12 + MOVW 12(R10), R13 + BNE R12,R13, ne1 + ADD $16, R9 + ADD $16, R10 + JMP l3 + +/* + * turn R15 into end pointer1-3 + * cmp 4 at a time while theres room + */ +l4: + ADD $-3,R11, R15 +l5: + SLTU R15,R9, R8 + BEQ R8, out + MOVW 0(R9), R12 + MOVW 0(R10), R13 + ADD $4, R9 + BNE R12,R13, ne1 + ADD $4, R10 + JMP l5 + +/* + * last loop, cmp byte at a time + */ +out: + SLTU R11,R9, R8 + BEQ R8, ret + MOVBU 0(R9), R14 + MOVBU 0(R10), R15 + ADD $1, R9 + BNE R14,R15, ne + ADD $1, R10 + JMP out + +/* + * compare bytes in R12 and R13, lsb first + */ +ne1: + MOVW $0xff, R8 +ne1x: + AND R8, R12, R14 + AND R8, R13, R15 + BNE R14, R15, ne + SLL $8, R8 + BNE R8, ne1x + JMP ret + +ne: + SLTU R14,R15, R8 + BNE R8, ret + MOV $-1, R8 +ret: + RET + END --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/unused/memmove.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,141 @@ + TEXT memcpy(SB), $-4 + TEXT memmove(SB), $-4 + MOV R8, s1+0(FP) + + MOVW n+(2*XLEN)(FP), R9 /* count */ + BEQ R9, return + BGT R9, ok + MOV R0, R9 +ok: + MOV s1+0(FP), R11 /* dest pointer */ + MOV s2+XLEN(FP), R10 /* source pointer */ + + BLTU R11, R10, back + +/* + * byte-at-a-time forward copy to + * get source (R10) aligned. + */ +f1: + AND $3, R10, R8 + BEQ R8, f2 + SUB $1, R9 + BLT R9, return + MOVB (R10), R8 + MOVB R8, (R11) + ADD $1, R10 + ADD $1, R11 + JMP f1 + +/* + * check that dest is aligned + * if not, just go byte-at-a-time + */ +f2: + AND $3, R11, R8 + BEQ R8, f3 + SUB $1, R9 + BLT R9, return + JMP f5 +/* + * quad-long-at-a-time forward copy + */ +f3: + SUB $16, R9 + BLT R9, f4 + MOVW 0(R10), R12 + MOVW 4(R10), R13 + MOVW 8(R10), R14 + MOVW 12(R10), R15 + MOVW R12, 0(R11) + MOVW R13, 4(R11) + MOVW R14, 8(R11) + MOVW R15, 12(R11) + ADD $16, R10 + ADD $16, R11 + JMP f3 + +/* + * cleanup byte-at-a-time + */ +f4: + ADD $15, R9 + BLT R9, return +f5: + MOVB (R10), R8 + MOVB R8, (R11) + ADD $1, R10 + ADD $1, R11 + SUB $1, R9 + BGE R9, f5 + JMP return + +return: + MOV s1+0(FP), R8 + RET + +/* + * everything the same, but + * copy backwards + */ +back: + ADD R9, R10 + ADD R9, R11 + +/* + * byte-at-a-time backward copy to + * get source (R10) aligned. + */ +b1: + AND $3, R10, R8 + BEQ R8, b2 + SUB $1, R9 + BLT R9, return + SUB $1, R10 + SUB $1, R11 + MOVB (R10), R8 + MOVB R8, (R11) + JMP b1 + +/* + * check that dest is aligned + * if not, just go byte-at-a-time + */ +b2: + AND $3, R11, R8 + BEQ R8, b3 + SUB $1, R9 + BLT R9, return + JMP b5 +/* + * quad-long-at-a-time backward copy + */ +b3: + SUB $16, R9 + BLT R9, b4 + SUB $16, R10 + SUB $16, R11 + MOVW 0(R10), R12 + MOVW 4(R10), R13 + MOVW 8(R10), R14 + MOVW 12(R10), R15 + MOVW R12, 0(R11) + MOVW R13, 4(R11) + MOVW R14, 8(R11) + MOVW R15, 12(R11) + JMP b3 + +/* + * cleanup byte-at-a-time backward + */ +b4: + ADD $15, R9 + BLT R9, return +b5: + SUB $1, R10 + SUB $1, R11 + MOVB (R10), R8 + MOVB R8, (R11) + SUB $1, R9 + BGE R9, b5 + JMP return --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/unused/seek.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,21 @@ +/* + * to enable 32- and 64-bit kernels to use a single seek implementation, + * we need to insert the address of the return value, on the stack + * before the existing arguments (fd, where, whence) and after return + * address at SP. the trick is that we point the return address on the + * stack at itself. + */ +TEXT seek(SB), 1, $-4 + SUB $XLEN, R2 /* make room for &ret */ + MOVW R8, (2*XLEN)(SP) /* write fd to stack */ + MOV $XLEN(SP), R8 /* address of ret */ + MOV R8, XLEN(SP) /* write &ret to stack */ + MOV R1, 0(SP) /* write return address to stack */ + MOV $SYSCALL, R8 + ECALL + BLT R8, ret + MOV XLEN(SP), R8 /* okay: copy ret into RARG */ +ret: + MOV 0(SP), R1 /* restore return address */ + ADD $XLEN, R2 /* pop return addr */ + RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/unused/strchr.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,62 @@ + TEXT strchr(SB), $0 + MOV R8, R10 + MOVBU c+XLEN(FP), R11 + BEQ R11, l2 + +/* + * char is not null + */ +l1: + MOVBU (R10), R8 + ADD $1, R10 + BEQ R8, ret + BNE R8,R11, l1 + JMP rm1 + +/* + * char is null + * align to word + */ +l2: + AND $3,R10, R8 + BEQ R8, l3 + MOVBU (R10), R8 + ADD $1, R10 + BNE R8, l2 + JMP rm1 + +l3: + MOVW $0xff000000, R13 + MOVW $0x00ff0000, R14 + MOVW $0x0000ff00, R15 + +l4: + MOVW (R10), R12 + ADD $4, R10 + AND $0xff, R12, R8 + BEQ R8, b0 + AND R15, R12, R8 + BEQ R8, b1 + AND R14, R12, R8 + BEQ R8, b2 + AND R13, R12, R8 + BNE R8, l4 + +rm1: + ADD $-1,R10, R8 + JMP ret + +b2: + ADD $-2,R10, R8 + JMP ret + +b1: + ADD $-3,R10, R8 + JMP ret + +b0: + ADD $-4,R10, R8 + JMP ret + +ret: + RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/unused/strcmp.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,20 @@ +TEXT strcmp(SB), $0 + MOV s2+XLEN(FP), R9 + +l1: + MOVBU (R9), R10 + MOVBU (R8), R11 + ADD $1, R8 + BEQ R10, end + ADD $1, R9 + BEQ R10, R11, l1 + + SLTU R11, R10, R8 + BNE R8, ret + MOV $-1, R8 + RET + +end: + SLTU R11, R10, R8 +ret: + RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/unused/strcpy.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,91 @@ +TEXT strcpy(SB), $0 + MOV s2+XLEN(FP), R9 /* R9 is from pointer */ + MOV R8, R10 /* R10 is to pointer */ + +/* + * align 'from' pointer + */ +l1: + AND $3, R9, R12 + ADD $1, R9 + BEQ R12, l2 + MOVB -1(R9), R12 + ADD $1, R10 + MOVB R12, -1(R10) + BNE R12, l1 + RET + +/* + * test if 'to' is also aligned + */ +l2: + AND $3,R10, R12 + BEQ R12, l4 + +/* + * copy 4 at a time, 'to' not aligned + */ +l3: + MOVW -1(R9), R11 + ADD $4, R9 + ADD $4, R10 + MOVB R11, -4(R10) + AND $0xff, R11, R12 + BEQ R12, out + + SRL $8, R11 + MOVB R11, -3(R10) + AND $0xff, R11, R12 + BEQ R12, out + + SRL $8, R11 + MOVB R11, -2(R10) + AND $0xff, R11, R12 + BEQ R12, out + + SRL $8, R11 + MOVB R11, -1(R10) + BNE R11, l3 + +out: + RET + +/* + * word at a time both aligned + */ +l4: + MOVW $0xff000000, R14 + MOVW $0x00ff0000, R15 + MOVW $0x0000ff00, R13 + +l5: + ADD $4, R10 + MOVW -1(R9), R11 /* fetch */ + ADD $4, R9 + + AND $0xff, R11, R12 /* is it byte 0 */ + BEQ R12, b0 + AND R13, R11, R12 /* is it byte 1 */ + BEQ R12, b1 + AND R15, R11, R12 /* is it byte 2 */ + BEQ R12, b2 + MOVW R11, -4(R10) /* store */ + AND R14, R11, R12 /* is it byte 3 */ + BNE R12, l5 + JMP out + +b0: + MOVB R0, -4(R10) + JMP out + +b1: + MOVB R11, -4(R10) + MOVB R0, -3(R10) + JMP out + +b2: + MOVB R11, -4(R10) + SRL $8, R11 + MOVB R11, -3(R10) + MOVB R0, -2(R10) + JMP out --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/unused/vlop.s Sun Jun 28 00:00:00 2026 @@ -0,0 +1,17 @@ +#undef XLEN +#define XLEN 4 + +TEXT _mulv(SB), $0 /* TODO: revisit; needed on rv64? */ + MOVW XLEN(FP), R9 // x.lo + MOVW (2*XLEN)(FP), R10 // x.hi + MOVW (3*XLEN)(FP), R11 // y.lo + MOVW (4*XLEN)(FP), R12 // y.hi + MULHU R11, R9, R14 // (x.lo*y.lo).hi + MUL R11, R9, R13 // (x.lo*y.lo).lo + MUL R10, R11, R15 // (x.hi*y.lo).lo + ADD R15, R14 + MUL R9, R12, R15 // (x.lo*y.hi).lo + ADD R15, R14 + MOVW R13, 0(R8) + MOVW R14, XLEN(R8) + RET --- /dev/null +++ /sys/src/ape/lib/ap/riscv64/unused/vlrt.c Sun Jun 28 00:00:00 2026 @@ -0,0 +1,711 @@ +typedef unsigned long ulong; +typedef unsigned int uint; +typedef unsigned short ushort; +typedef unsigned char uchar; +typedef signed char schar; + +#define SIGN(n) (1UL<<(n-1)) + +typedef struct Vlong Vlong; +struct Vlong +{ + ulong lo; /* little endian */ + ulong hi; +}; + +void abort(void); + +/* needed by profiler; can't be profiled */ +#pragma profile off + +void +_addv(Vlong *r, Vlong a, Vlong b) +{ + ulong lo, hi; + + lo = a.lo + b.lo; + hi = a.hi + b.hi; + if(lo < a.lo) + hi++; + r->lo = lo; + r->hi = hi; +} + +void +_subv(Vlong *r, Vlong a, Vlong b) +{ + ulong lo, hi; + + lo = a.lo - b.lo; + hi = a.hi - b.hi; + if(lo > a.lo) + hi--; + r->lo = lo; + r->hi = hi; +} + +#pragma profile on + +void +_d2v(Vlong *y, double d) +{ + union { double d; struct Vlong; } x; + ulong xhi, xlo, ylo, yhi; + int sh; + + x.d = d; + + xhi = (x.hi & 0xfffff) | 0x100000; + xlo = x.lo; + sh = 1075 - ((x.hi >> 20) & 0x7ff); + + ylo = 0; + yhi = 0; + if(sh >= 0) { + /* v = (hi||lo) >> sh */ + if(sh < 32) { + if(sh == 0) { + ylo = xlo; + yhi = xhi; + } else { + ylo = (xlo >> sh) | (xhi << (32-sh)); + yhi = xhi >> sh; + } + } else { + if(sh == 32) { + ylo = xhi; + } else + if(sh < 64) { + ylo = xhi >> (sh-32); + } + } + } else { + /* v = (hi||lo) << -sh */ + sh = -sh; + if(sh <= 10) { + ylo = xlo << sh; + yhi = (xhi << sh) | (xlo >> (32-sh)); + } else { + /* overflow */ + yhi = d; /* causes something awful */ + } + } + if(x.hi & SIGN(32)) { + if(ylo != 0) { + ylo = -ylo; + yhi = ~yhi; + } else + yhi = -yhi; + } + + y->hi = yhi; + y->lo = ylo; +} + +void +_f2v(Vlong *y, float f) +{ + _d2v(y, f); +} + +// double +_v2d(Vlong x) +{ + if(x.hi & SIGN(32)) { + if(x.lo) { + x.lo = -x.lo; + x.hi = ~x.hi; + } else + x.hi = -x.hi; + return -((long)x.hi*4294967296. + x.lo); + } + return (long)x.hi*4294967296. + x.lo; +} + +float +_v2f(Vlong x) +{ + return _v2d(x); +} + +/* too many of these are also needed by profiler; leave them out */ +#pragma profile off + +static void +dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r) +{ + ulong numlo, numhi, denhi, denlo, quohi, quolo, t; + int i; + + numhi = num.hi; + numlo = num.lo; + denhi = den.hi; + denlo = den.lo; + /* + * get a divide by zero + */ + if(denlo==0 && denhi==0) { + numlo = numlo / denlo; + } + + /* + * set up the divisor and find the number of iterations needed + */ + if(numhi >= SIGN(32)) { + quohi = SIGN(32); + quolo = 0; + } else { + quohi = numhi; + quolo = numlo; + } + i = 0; + while(denhi < quohi || (denhi == quohi && denlo < quolo)) { + denhi = (denhi<<1) | (denlo>>31); + denlo <<= 1; + i++; + } + + quohi = 0; + quolo = 0; + for(; i >= 0; i--) { + quohi = (quohi<<1) | (quolo>>31); + quolo <<= 1; + if(numhi > denhi || (numhi == denhi && numlo >= denlo)) { + t = numlo; + numlo -= denlo; + if(numlo > t) + numhi--; + numhi -= denhi; + quolo |= 1; + } + denlo = (denlo>>1) | (denhi<<31); + denhi >>= 1; + } + + if(q) { + q->lo = quolo; + q->hi = quohi; + } + if(r) { + r->lo = numlo; + r->hi = numhi; + } +} + +void +_divvu(Vlong *q, Vlong n, Vlong d) +{ + if(n.hi == 0 && d.hi == 0) { + q->hi = 0; + q->lo = n.lo / d.lo; + return; + } + dodiv(n, d, q, 0); +} + +void +_modvu(Vlong *r, Vlong n, Vlong d) +{ + + if(n.hi == 0 && d.hi == 0) { + r->hi = 0; + r->lo = n.lo % d.lo; + return; + } + dodiv(n, d, 0, r); +} + +static void +vneg(Vlong *v) +{ + + if(v->lo == 0) { + v->hi = -v->hi; + return; + } + v->lo = -v->lo; + v->hi = ~v->hi; +} + +void +_divv(Vlong *q, Vlong n, Vlong d) +{ + long nneg, dneg; + + if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) { + q->lo = (long)n.lo / (long)d.lo; + q->hi = ((long)q->lo) >> 31; + return; + } + nneg = n.hi >> 31; + if(nneg) + vneg(&n); + dneg = d.hi >> 31; + if(dneg) + vneg(&d); + dodiv(n, d, q, 0); + if(nneg != dneg) + vneg(q); +} + +void +_modv(Vlong *r, Vlong n, Vlong d) +{ + long nneg, dneg; + + if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) { + r->lo = (long)n.lo % (long)d.lo; + r->hi = ((long)r->lo) >> 31; + return; + } + nneg = n.hi >> 31; + if(nneg) + vneg(&n); + dneg = d.hi >> 31; + if(dneg) + vneg(&d); + dodiv(n, d, 0, r); + if(nneg) + vneg(r); +} + +void +_rshav(Vlong *r, Vlong a, int b) +{ + long t; + + t = a.hi; + if(b >= 32) { + r->hi = t>>31; + if(b >= 64) { + /* this is illegal re C standard */ + r->lo = t>>31; + return; + } + r->lo = t >> (b-32); + return; + } + if(b <= 0) { + r->hi = t; + r->lo = a.lo; + return; + } + r->hi = t >> b; + r->lo = (t << (32-b)) | (a.lo >> b); +} + +void +_rshlv(Vlong *r, Vlong a, int b) +{ + ulong t; + + t = a.hi; + if(b >= 32) { + r->hi = 0; + if(b >= 64) { + /* this is illegal re C standard */ + r->lo = 0; + return; + } + r->lo = t >> (b-32); + return; + } + if(b <= 0) { + r->hi = t; + r->lo = a.lo; + return; + } + r->hi = t >> b; + r->lo = (t << (32-b)) | (a.lo >> b); +} + +void +_lshv(Vlong *r, Vlong a, int b) +{ + ulong t; + + t = a.lo; + if(b >= 32) { + r->lo = 0; + if(b >= 64) { + /* this is illegal re C standard */ + r->hi = 0; + return; + } + r->hi = t << (b-32); + return; + } + if(b <= 0) { + r->lo = t; + r->hi = a.hi; + return; + } + r->lo = t << b; + r->hi = (t >> (32-b)) | (a.hi << b); +} + +void +_andv(Vlong *r, Vlong a, Vlong b) +{ + r->hi = a.hi & b.hi; + r->lo = a.lo & b.lo; +} + +void +_orv(Vlong *r, Vlong a, Vlong b) +{ + r->hi = a.hi | b.hi; + r->lo = a.lo | b.lo; +} + +void +_xorv(Vlong *r, Vlong a, Vlong b) +{ + r->hi = a.hi ^ b.hi; + r->lo = a.lo ^ b.lo; +} + +void +_vpp(Vlong *l, Vlong *r) +{ + + l->hi = r->hi; + l->lo = r->lo; + r->lo++; + if(r->lo == 0) + r->hi++; +} + +void +_vmm(Vlong *l, Vlong *r) +{ + + l->hi = r->hi; + l->lo = r->lo; + if(r->lo == 0) + r->hi--; + r->lo--; +} + +void +_ppv(Vlong *l, Vlong *r) +{ + + r->lo++; + if(r->lo == 0) + r->hi++; + l->hi = r->hi; + l->lo = r->lo; +} + +void +_mmv(Vlong *l, Vlong *r) +{ + + if(r->lo == 0) + r->hi--; + r->lo--; + l->hi = r->hi; + l->lo = r->lo; +} + +void +_vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv) +{ + Vlong t, u; + + u = *ret; + switch(type) { + default: + abort(); + break; + + case 1: /* schar */ + t.lo = *(schar*)lv; + t.hi = t.lo >> 31; + fn(&u, t, rv); + *(schar*)lv = u.lo; + break; + + case 2: /* uchar */ + t.lo = *(uchar*)lv; + t.hi = 0; + fn(&u, t, rv); + *(uchar*)lv = u.lo; + break; + + case 3: /* short */ + t.lo = *(short*)lv; + t.hi = t.lo >> 31; + fn(&u, t, rv); + *(short*)lv = u.lo; + break; + + case 4: /* ushort */ + t.lo = *(ushort*)lv; + t.hi = 0; + fn(&u, t, rv); + *(ushort*)lv = u.lo; + break; + + case 9: /* int */ + t.lo = *(int*)lv; + t.hi = t.lo >> 31; + fn(&u, t, rv); + *(int*)lv = u.lo; + break; + + case 10: /* uint */ + t.lo = *(uint*)lv; + t.hi = 0; + fn(&u, t, rv); + *(uint*)lv = u.lo; + break; + + case 5: /* long */ + t.lo = *(long*)lv; + t.hi = t.lo >> 31; + fn(&u, t, rv); + *(long*)lv = u.lo; + break; + + case 6: /* ulong */ + t.lo = *(ulong*)lv; + t.hi = 0; + fn(&u, t, rv); + *(ulong*)lv = u.lo; + break; + + case 7: /* vlong */ + case 8: /* uvlong */ + fn(&u, *(Vlong*)lv, rv); + *(Vlong*)lv = u; + break; + } + *ret = u; +} + +void +_p2v(Vlong *ret, void *p) +{ + long t; + + t = (ulong)p; + ret->lo = t; + ret->hi = 0; +} + +void +_sl2v(Vlong *ret, long sl) +{ + long t; + + t = sl; + ret->lo = t; + ret->hi = t >> 31; +} + + +void +_ul2v(Vlong *ret, ulong ul) +{ + long t; + + t = ul; + ret->lo = t; + ret->hi = 0; +} + +void +_si2v(Vlong *ret, int si) +{ + long t; + + t = si; + ret->lo = t; + ret->hi = t >> 31; +} + +void +_ui2v(Vlong *ret, uint ui) +{ + long t; + + t = ui; + ret->lo = t; + ret->hi = 0; +} + +void +_sh2v(Vlong *ret, long sh) +{ + long t; + + t = (sh << 16) >> 16; + ret->lo = t; + ret->hi = t >> 31; +} + +void +_uh2v(Vlong *ret, ulong ul) +{ + long t; + + t = ul & 0xffff; + ret->lo = t; + ret->hi = 0; +} + +void +_sc2v(Vlong *ret, long uc) +{ + long t; + + t = (uc << 24) >> 24; + ret->lo = t; + ret->hi = t >> 31; +} + +void +_uc2v(Vlong *ret, ulong ul) +{ + long t; + + t = ul & 0xff; + ret->lo = t; + ret->hi = 0; +} + +long +_v2sc(Vlong rv) +{ + long t; + + t = rv.lo & 0xff; + return (t << 24) >> 24; +} + +long +_v2uc(Vlong rv) +{ + + return rv.lo & 0xff; +} + +long +_v2sh(Vlong rv) +{ + long t; + + t = rv.lo & 0xffff; + return (t << 16) >> 16; +} + +long +_v2uh(Vlong rv) +{ + + return rv.lo & 0xffff; +} + +long +_v2sl(Vlong rv) +{ + + return rv.lo; +} + +long +_v2ul(Vlong rv) +{ + + return rv.lo; +} + +long +_v2si(Vlong rv) +{ + + return rv.lo; +} + +long +_v2ui(Vlong rv) +{ + + return rv.lo; +} + +int +_testv(Vlong rv) +{ + return rv.lo || rv.hi; +} + +int +_eqv(Vlong lv, Vlong rv) +{ + return lv.lo == rv.lo && lv.hi == rv.hi; +} + +int +_nev(Vlong lv, Vlong rv) +{ + return lv.lo != rv.lo || lv.hi != rv.hi; +} + +int +_ltv(Vlong lv, Vlong rv) +{ + return (long)lv.hi < (long)rv.hi || + (lv.hi == rv.hi && lv.lo < rv.lo); +} + +int +_lev(Vlong lv, Vlong rv) +{ + return (long)lv.hi < (long)rv.hi || + (lv.hi == rv.hi && lv.lo <= rv.lo); +} + +int +_gtv(Vlong lv, Vlong rv) +{ + return (long)lv.hi > (long)rv.hi || + (lv.hi == rv.hi && lv.lo > rv.lo); +} + +int +_gev(Vlong lv, Vlong rv) +{ + return (long)lv.hi > (long)rv.hi || + (lv.hi == rv.hi && lv.lo >= rv.lo); +} + +int +_lov(Vlong lv, Vlong rv) +{ + return lv.hi < rv.hi || + (lv.hi == rv.hi && lv.lo < rv.lo); +} + +int +_lsv(Vlong lv, Vlong rv) +{ + return lv.hi < rv.hi || + (lv.hi == rv.hi && lv.lo <= rv.lo); +} + +int +_hiv(Vlong lv, Vlong rv) +{ + return lv.hi > rv.hi || + (lv.hi == rv.hi && lv.lo > rv.lo); +} + +int +_hsv(Vlong lv, Vlong rv) +{ + return lv.hi > rv.hi || + (lv.hi == rv.hi && lv.lo >= rv.lo); +} --- /n/sources/plan9/sys/src/ape/lib/ap/stdio/_IO_putc.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/stdio/_IO_putc.c Sun Jun 28 00:00:00 2026 @@ -3,18 +3,27 @@ */ #include "iolib.h" -void _IO_cleanup(void){ +void +_IO_cleanup(void) +{ fflush(NULL); } + /* * Look this over for simplification */ -int _IO_putc(int c, FILE *f){ +int +_IO_putc(int c, FILE *f) +{ int cnt; - static int first=1; - switch(f->state){ + static int first = 1; + + if (f == 0) + return EOF; + switch (f->state) { case RD: - f->state=ERR; + f->state = ERR; + /* fall through */ case ERR: case CLOSED: return EOF; @@ -23,84 +32,84 @@ int _IO_putc(int c, FILE *f){ /* fall through */ case RDWR: case END: - f->rp=f->buf+f->bufl; - if(f->flags&LINEBUF){ - f->wp=f->rp; - f->lp=f->buf; - } - else - f->wp=f->buf; + f->rp = f->buf + f->bufl; + if (f->flags & LINEBUF) { + f->wp = f->rp; + f->lp = f->buf; + } else + f->wp = f->buf; break; } - if(first){ + if (first) { atexit(_IO_cleanup); - first=0; + first = 0; } - if(f->flags&STRING){ - f->rp=f->buf+f->bufl; - if(f->wp==f->rp){ - if(f->flags&BALLOC) - f->buf=realloc(f->buf, f->bufl+BUFSIZ); - else{ - f->state=ERR; + if (f->flags & STRING) { + f->rp = f->buf + f->bufl; + if (f->wp == f->rp) { + if (f->flags & BALLOC) + f->buf = realloc(f->buf, f->bufl + BUFSIZ); + else { + f->state = ERR; return EOF; } - if(f->buf==NULL){ - f->state=ERR; + if (f->buf == NULL) { + f->state = ERR; return EOF; } - f->rp=f->buf+f->bufl; - f->bufl+=BUFSIZ; + f->rp = f->buf + f->bufl; + f->bufl += BUFSIZ; } - *f->wp++=c; - } - else if(f->flags&LINEBUF){ - if(f->lp==f->rp){ - cnt=f->lp-f->buf; - if(f->flags&APPEND) lseek(f->fd, 0, SEEK_END); - if(cnt!=0 && write(f->fd, f->buf, cnt)!=cnt){ - f->state=ERR; + *f->wp++ = c; + } else if (f->flags & LINEBUF) { + if (f->lp == f->rp) { + cnt = f->lp - f->buf; + if (f->flags & APPEND) + lseek(f->fd, 0, SEEK_END); + if (cnt != 0 && write(f->fd, f->buf, cnt) != cnt) { + f->state = ERR; return EOF; } - f->lp=f->buf; + f->lp = f->buf; } - *f->lp++=c; - if(c=='\n'){ - cnt=f->lp-f->buf; - if(f->flags&APPEND) lseek(f->fd, 0, SEEK_END); - if(cnt!=0 && write(f->fd, f->buf, cnt)!=cnt){ - f->state=ERR; + *f->lp++ = c; + if (c == '\n') { + cnt = f->lp - f->buf; + if (f->flags & APPEND) + lseek(f->fd, 0, SEEK_END); + if (cnt != 0 && write(f->fd, f->buf, cnt) != cnt) { + f->state = ERR; return EOF; } - f->lp=f->buf; + f->lp = f->buf; } - } - else if(f->buf==f->unbuf){ - f->unbuf[0]=c; - if(f->flags&APPEND) lseek(f->fd, 0, SEEK_END); - if(write(f->fd, f->buf, 1)!=1){ - f->state=ERR; + } else if (f->buf == f->unbuf) { + f->unbuf[0] = c; + if (f->flags & APPEND) + lseek(f->fd, 0, SEEK_END); + if (write(f->fd, f->buf, 1) != 1) { + f->state = ERR; return EOF; } - } - else{ - if(f->wp==f->rp){ - cnt=f->wp-f->buf; - if(f->flags&APPEND) lseek(f->fd, 0, SEEK_END); - if(cnt!=0 && write(f->fd, f->buf, cnt)!=cnt){ - f->state=ERR; + } else { + if (f->wp == f->rp) { + cnt = f->wp - f->buf; + if (f->flags & APPEND) + lseek(f->fd, 0, SEEK_END); + if (cnt != 0 && write(f->fd, f->buf, cnt) != cnt) { + f->state = ERR; return EOF; } - f->wp=f->buf; - f->rp=f->buf+f->bufl; + f->wp = f->buf; + f->rp = f->buf + f->bufl; } - *f->wp++=c; + *f->wp++ = c; } - f->state=WR; + f->state = WR; /* * Make sure EOF looks different from putc(-1) * Should be able to cast to unsigned char, but * there's a vc bug preventing that from working */ - return c&0xff; + return c & 0xff; } --- /n/sources/plan9/sys/src/ape/lib/ap/stdio/_dtoa.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/stdio/_dtoa.c Sun Jun 28 00:00:00 2026 @@ -1,4 +1,6 @@ #include "fconv.h" +#include +#include static int quorem(Bigint *, Bigint *); @@ -91,6 +93,8 @@ _dtoa(double darg, int mode, int ndigits, int *decpt, int *sign, char **rve) mlo = 0; d.d = darg; + if (rve) + *rve = 0; if (result) { result->k = result_k; result->maxwds = 1 << result_k; @@ -108,7 +112,8 @@ _dtoa(double darg, int mode, int ndigits, int *decpt, int *sign, char **rve) #if defined(IEEE_Arith) + defined(VAX) #ifdef IEEE_Arith - if ((word0(d) & Exp_mask) == Exp_mask) +// if ((word0(d) & Exp_mask) == Exp_mask) + if (isNaN(darg) || isInf(darg, 0)) #else if (word0(d) == 0x8000) #endif @@ -117,9 +122,9 @@ _dtoa(double darg, int mode, int ndigits, int *decpt, int *sign, char **rve) *decpt = 9999; s = #ifdef IEEE_Arith - !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" : +// !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" : "NaN"; + isNaN(darg)? "NaN": "Infinity"; #endif - "NaN"; if (rve) *rve = #ifdef IEEE_Arith @@ -324,6 +329,9 @@ _dtoa(double darg, int mode, int ndigits, int *decpt, int *sign, char **rve) for(i = 0;;) { L = floor(d.d); d.d -= L; + if(L < 0 || L > 9) + printf("_dtoa: next digit is %d\n", L); + assert(L >= 0 && L <= 9); *s++ = '0' + (int)L; if (d.d < eps.d) goto ret1; @@ -342,6 +350,9 @@ _dtoa(double darg, int mode, int ndigits, int *decpt, int *sign, char **rve) for(i = 1;; i++, d.d *= 10.) { L = floor(d.d); d.d -= L; + if(L < 0 || L > 9) + printf("_dtoa: next digit is %d\n", L); + assert(L >= 0 && L <= 9); *s++ = '0' + (int)L; if (i == ilim) { if (d.d > 0.5 + eps.d) @@ -385,6 +396,9 @@ _dtoa(double darg, int mode, int ndigits, int *decpt, int *sign, char **rve) d.d += ds; } #endif + if(L < 0 || L > 9) + printf("_dtoa: next digit is %d\n", L); + assert(L >= 0 && L <= 9); *s++ = '0' + (int)L; if (i == ilim) { d.d += d.d; --- /n/sources/plan9/sys/src/ape/lib/ap/stdio/_fconv.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/stdio/_fconv.c Sun Jun 28 00:00:00 2026 @@ -218,6 +218,8 @@ _mult(Bigint *a, Bigint *b) #ifdef Pack_32 for(; xb < xbe; xb++, xc0++) { if (y = *xb & 0xffff) { + int lim = 10000; + x = xa; xc = xc0; carry = 0; @@ -228,10 +230,12 @@ _mult(Bigint *a, Bigint *b) carry = z2 >> 16; Storeinc(xc, z2, z); } - while(x < xae); + while(x < xae && --lim > 0); /* TODO: sanity */ *xc = carry; } if (y = *xb >> 16) { + int lim = 10000; + x = xa; xc = xc0; carry = 0; @@ -243,7 +247,7 @@ _mult(Bigint *a, Bigint *b) z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; carry = z2 >> 16; } - while(x < xae); + while(x < xae && --lim > 0); /* TODO: sanity */ *xc = z2; } } @@ -274,7 +278,7 @@ _mult(Bigint *a, Bigint *b) _pow5mult(Bigint *b, int k) { Bigint *b1, *p5, *p51; - int i; + int i, lim = 10000; static int p05[3] = { 5, 25, 125 }; if (i = k & 3) @@ -288,6 +292,8 @@ _pow5mult(Bigint *b, int k) p5->next = 0; } for(;;) { + if (--lim <= 0) + break; /* TODO: sanity */ if (k & 1) { b1 = mult(b, p5); Bfree(b); --- /n/sources/plan9/sys/src/ape/lib/ap/stdio/freopen.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/stdio/freopen.c Sun Jun 28 00:00:00 2026 @@ -22,7 +22,7 @@ FILE *freopen(const char *name, const char *mode, FILE *f){ } m = *mode++; - if(m == 0) + if(m == 0 || name == 0) return NULL; if(*mode == 'b') mode++; --- /n/sources/plan9/sys/src/ape/lib/ap/stdio/iolib.h Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/stdio/iolib.h Sun Jun 28 00:00:00 2026 @@ -14,9 +14,6 @@ * fseek fsetpos ftell rewind clearerr * feof ferror perror */ -#ifndef _SUSV2_SOURCE -#define _SUSV2_SOURCE /* for *intptr_t types */ -#endif #include #include --- /n/sources/plan9/sys/src/ape/lib/ap/stdio/mkfile Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/stdio/mkfile Sun Jun 28 00:00:00 2026 @@ -65,4 +65,4 @@ OFILES=\ state!=OPEN){ f->state=ERR; return -1; --- /n/sources/plan9/sys/src/ape/lib/ap/stdio/vfprintf.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/stdio/vfprintf.c Sun Jun 28 00:00:00 2026 @@ -2,9 +2,11 @@ * pANS stdio -- vfprintf */ #include "iolib.h" +#include #include #include #include +#include /* * Leading flags */ @@ -22,7 +24,7 @@ #define PTR 256 /* convert a void * (%p) */ #define VLONG 512 /* 'll' convert a long long integer */ -static int lflag[] = { /* leading flags */ +static short lflag[] = { /* leading flags */ 0, 0, 0, 0, 0, 0, 0, 0, /* ^@ ^A ^B ^C ^D ^E ^F ^G */ 0, 0, 0, 0, 0, 0, 0, 0, /* ^H ^I ^J ^K ^L ^M ^N ^O */ 0, 0, 0, 0, 0, 0, 0, 0, /* ^P ^Q ^R ^S ^T ^U ^V ^W */ @@ -58,7 +60,7 @@ ZPAD, 0, 0, 0, 0, 0, 0, 0, /* 0 1 2 3 4 5 6 7 */ 0, 0, 0, 0, 0, 0, 0, 0, }; -static int tflag[] = { /* trailing flags */ +static short tflag[] = { /* trailing flags */ 0, 0, 0, 0, 0, 0, 0, 0, /* ^@ ^A ^B ^C ^D ^E ^F ^G */ 0, 0, 0, 0, 0, 0, 0, 0, /* ^H ^I ^J ^K ^L ^M ^N ^O */ 0, 0, 0, 0, 0, 0, 0, 0, /* ^P ^Q ^R ^S ^T ^U ^V ^W */ @@ -153,6 +155,8 @@ vfprintf(FILE *f, const char *as, va_list args) int tfl, flags, width, precision; unsigned char *s; + if (f == 0) + return -1; nprint = 0; s = (unsigned char *)as; while(*s){ @@ -319,6 +323,7 @@ ocvt_fixed(FILE *f, va_list *args, int flags, int width, int precision, else num = va_arg(*args, unsigned int); } if(num == 0) prefix = ""; + if(radix <= 1) radix = 10; /* don't loop forever */ dp = digits; do{ *dp++ = alphabet[num%radix]; @@ -356,7 +361,10 @@ ocvt_fixed(FILE *f, va_list *args, int flags, int width, int precision, putc('0', f); --nlzero; } - while(dp!=digits) putc(*--dp, f); + while(dp > digits) { + --dp; + putc(*dp, f); + } } else{ fputs(sign, f); @@ -365,13 +373,16 @@ ocvt_fixed(FILE *f, va_list *args, int flags, int width, int precision, putc('0', f); --nlzero; } - while(dp != digits) putc(*--dp, f); + while(dp > digits) { + --dp; + putc(*dp, f); + } while(npad){ putc(' ', f); --npad; } } - return nout; + return nout; } static int @@ -448,22 +459,30 @@ ocvt_flt(FILE *f, va_list *args, int flags, int width, int precision, char afmt) { extern char *_dtoa(double, int, int, int*, int*, char **); int echr; - char *digits, *edigits; int exponent; char fmt; int sign; int ndig; int nout, i; - char ebuf[20]; /* no sensible machine will overflow this */ + char ebuf[300]; /* no sensible machine will overflow this */ + char *digits, *edigits; char *eptr; double d; - digits = eptr = 0; + if (f == 0) + return 0; + digits = edigits = 0; + exponent = sign = 0; echr = 'e'; fmt = afmt; d = va_arg(*args, double); - if(precision < 0) precision = 6; - switch(fmt){ + if (width >= 256) /* TODO: sanity check */ + width = 256; + if (precision < 0) + precision = 6; + if (precision >= 256) /* TODO: sanity check */ + precision = 256; + switch (fmt) { case 'f': digits = _dtoa(d, 3, precision, &exponent, &sign, &edigits); break; @@ -472,7 +491,7 @@ ocvt_flt(FILE *f, va_list *args, int flags, int width, int precision, char afmt) fmt = 'e'; /* fall through */ case 'e': - digits = _dtoa(d, 2, 1+precision, &exponent, &sign, &edigits); + digits = _dtoa(d, 2, 1 + precision, &exponent, &sign, &edigits); break; case 'G': echr = 'E'; @@ -485,11 +504,11 @@ ocvt_flt(FILE *f, va_list *args, int flags, int width, int precision, char afmt) precision = edigits - digits; if (exponent > precision && exponent <= precision + 4) precision = exponent; - } - if(exponent >= -3 && exponent <= precision){ + } + if (exponent >= -3 && exponent <= precision) { fmt = 'f'; precision -= exponent; - }else{ + } else { fmt = 'e'; --precision; } @@ -500,67 +519,95 @@ ocvt_flt(FILE *f, va_list *args, int flags, int width, int precision, char afmt) precision = 0; exponent = edigits - digits; fmt = 'f'; - } - ndig = edigits-digits; - if(ndig == 0) { + } else if (exponent >= 1024) /* TODO: sanity check */ + exponent = 1024; + ndig = edigits - digits; + if (ndig == 0) { ndig = 1; digits = "0"; } - if((afmt=='g' || afmt=='G') && !(flags&ALT)){ /* knock off trailing zeros */ - if(fmt == 'f'){ - if(precision+exponent > ndig) { + assert(ndig > 0); + if ((afmt == 'g' || afmt == 'G') && !(flags & ALT)) { /* knock off trailing zeros */ + if (fmt == 'f') { + if (precision + exponent > ndig) { precision = ndig - exponent; - if(precision < 0) + if (precision < 0) precision = 0; } - } - else{ - if(precision > ndig-1) precision = ndig-1; + } else { + if (precision > ndig - 1) + precision = ndig - 1; } } - nout = precision; /* digits after decimal point */ - if(precision!=0 || flags&ALT) nout++; /* decimal point */ - if(fmt=='f' && exponent>0) nout += exponent; /* digits before decimal point */ - else nout++; /* there's always at least one */ - if(sign || flags&(SPACE|SIGN)) nout++; /* sign */ - if(fmt != 'f'){ /* exponent */ - eptr = ebuf; - for(i=exponent<=0?1-exponent:exponent-1; i; i/=10) + nout = precision; /* digits after decimal point */ + if (precision != 0 || flags & ALT) + nout++; /* decimal point */ + if (fmt == 'f' && exponent > 0) + nout += exponent; /* digits before decimal point */ + else + nout++; /* there's always at least one */ + if (sign || flags & (SPACE | SIGN)) + nout++; /* sign */ + eptr = ebuf; + if (fmt != 'f') { /* exponent */ + for (i = exponent <= 0? 1 - exponent: exponent - 1; + i && eptr < ebuf + sizeof ebuf - 10; i /= 10) *eptr++ = '0' + i%10; - while(eptr0 || flags&ALT) putc('.', f); - for(i=0; i!=precision; i++) - putc(0<=i+exponent && i+exponent= 256) /* TODO: sanity check */ + precision = 256; + if (fmt == 'f') { + for (i = 0; i < exponent; i++) + putc(i < ndig? digits[i]: '0', f); + if (i == 0) + putc('0', f); + if (precision > 0 || flags & ALT) + putc('.', f); + for (i = 0; i < precision; i++) + putc(0 <= i + exponent && i + exponent < ndig? + digits[i+exponent]: '0', f); + } else { putc(digits[0], f); - if(precision>0 || flags&ALT) putc('.', f); - for(i=0; i!=precision; i++) putc(i 0 || flags & ALT) + putc('.', f); + for (i = 0; i < precision; i++) + putc(i < ndig - 1? digits[i+1]: '0', f); + putc(echr, f); - putc(exponent<=0?'-':'+', f); - while(eptr>ebuf) putc(*--eptr, f); + putc(exponent <= 0? '-': '+', f); + while (eptr > ebuf) { + --eptr; + putc(*eptr, f); + } } - while(nout < width){ + while (nout < width) { putc(' ', f); nout++; } --- /dev/null +++ /sys/src/ape/lib/ap/syscall/gencall.manual Sun Jun 28 00:00:00 2026 @@ -0,0 +1,174 @@ +#!/bin/rc +# derived from /sys/src/libc/9syscall/mkfile; see its comments too +niladic = (_NSEC) + + {switch($objtype){ + case mips + echo TEXT $i'(SB)', 1, '$0' + echo MOVW R1, '0(FP)' + echo MOVW '$'$n, R1 + echo SYSCALL + if(~ $i _SEEK || ~ $i _NSEC) { + echo 'MOVW $-1,R5 + BNE R1,R5,4(PC) + MOVW a+0(FP),R5 + MOVW R1,0(R5) + MOVW R1,4(R5)' + } + echo RET + case mips2 + echo TEXT $i'(SB)', 1, '$0' + echo MOVW R1, '0(FP)' + echo MOVW '$'$n, R1 + echo ADD '$4',R29 + echo SYSCALL + echo ADD '$-4',R29 + echo RET + case spim + echo TEXT $i'(SB)', 1, '$0' + echo MOVW R1, '0(FP)' + echo MOVW '$'$n, R1 + echo ADD '$4',R29 + echo SYSCALL + echo ADD '$-4',R29 + if(~ $i _SEEK || ~ $i _NSEC) { + echo 'MOVW $-1,R5 + BNE R1,R5,4(PC) + MOVW a+0(FP),R5 + MOVW R1,0(R5) + MOVW R1,4(R5)' + } + echo RET + case 386 + echo TEXT $i'(SB)', 1, '$0' + echo MOVL '$'$n, AX + echo INT '$'64 + if(~ $i _SEEK || ~ $i _NSEC) { + echo 'CMPL AX,$-1 + JNE 4(PC) + MOVL a+0(FP),CX + MOVL AX,0(CX) + MOVL AX,4(CX)' + } + echo RET + case amd64 + if(~ $i _SEEK) + echo TEXT __SEEK'(SB)', 1, '$0' + if not + echo TEXT $i'(SB)', 1, '$0' + # + # For architectures which pass the first argument + # in a register, if the system call takes no arguments + # there will be no 'a0+0(FP)' reserved on the stack. + # + if(! ~ $i $niladic) + echo MOVQ RARG, 'a0+0(FP)' + echo MOVQ '$'$n, RARG + echo SYSCALL + echo RET + case sparc + echo TEXT $i'(SB)', 1, '$0' + echo MOVW R7, '0(FP)' + echo MOVW '$'$n, R7 + echo TA R0 + if(~ $i _SEEK || ~ $i _NSEC) { + echo 'CMP R7,$-1 + BNE 4(PC) + MOVW a+0(FP),R8 + MOVW R7,0(R8) + MOVW R7,4(R8)' + } + echo RETURN + case arm + echo TEXT $i'(SB)', 1, '$0' + echo MOVW R0, '0(FP)' + echo MOVW '$'$n, R0 + echo SWI 0 + if(~ $i _SEEK || ~ $i _NSEC) { + echo 'CMP $-1,R0 + BNE 4(PC) + MOVW a+0(FP),R1 + MOVW R0,0(R1) + MOVW R0,4(R1)' + } + echo RET + case arm64 + if(~ $i _SEEK) + echo TEXT __SEEK'(SB)', 1, '$0' + if not + echo TEXT $i'(SB)', 1, '$0' + if(! ~ $i $niladic) + echo MOV R0, 'a0+0(FP)' + echo SVC '$'$n + echo RETURN + case power + echo TEXT $i'(SB)', 1, '$0' + echo MOVW R3, '0(FP)' + echo MOVW '$'$n, R3 + echo SYSCALL + if(~ $i _SEEK || ~ $i _NSEC) { + echo 'CMP R3,$-1 + BNE 4(PC) + MOVW a+0(FP),R8 + MOVW R3,0(R8) + MOVW R3,4(R8)' + } + echo RETURN + case power64 + if(~ $i _SEEK) + echo TEXT __SEEK'(SB)', 1, '$0' + if not + echo TEXT $i'(SB)', 1, '$0' + if(! ~ $i $niladic) + echo MOVD R3, '0(FP)' + echo MOVW '$'$n, R3 + echo SYSCALL + echo RETURN + case riscv + echo TEXT $i'(SB)', 1, '$0' + echo MOVW R8, '0(FP)' + echo MOVW '$'$n, R8 + echo ECALL + if(~ $i _SEEK) { + echo 'MOVW $-1, R9 + BNE R8, R9, 4(PC) + MOVW a+0(FP),R9 + MOVW R8,0(R9) + MOVW R8,4(R9)' + } + if(~ $i _NSEC) { + echo 'MOVW a+0(FP),R10 + MOVW R8,0(R10) + MOVW R9,4(R10)' + } + echo RET + case riscv64 + if(~ $i _SEEK) + echo TEXT __SEEK'(SB)', 1, '$0' + if not + echo TEXT $i'(SB)', 1, '$0' + # + # For architectures which pass the first argument + # in a register, if the system call takes no arguments + # there will be no 'a0+0(FP)' reserved on the stack. + # + # jc doesn't widen longs to vlongs when pushing them. + # so we have to be careful here to only push longs + # for first arguments, where appropriate. + # + switch ($i) { + case _NSEC + ; + case _BIND _CHDIR _EXEC _EXITS __EXITS _SEGBRK _OPEN _CREATE \ + _BRK_ _REMOVE _NOTIFY _PIPE _SEEK _SEGDETACH _SEGFREE \ + _SEGFLUSH _RENDEZVOUS _UNMOUNT _SEMACQUIRE \ + _SEMRELEASE _ERRSTR _STAT _WSTAT _AWAIT _TSEMACQUIRE + echo MOV R8, '0(FP)' + case * + echo MOVW R8, '0(FP)' + } + echo MOV '$'$n, R8 + echo ECALL + echo RET + }} > $i.s + $AS $i.s --- /n/sources/plan9/sys/src/ape/lib/ap/syscall/mkfile Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/ap/syscall/mkfile Sun Jun 28 00:00:00 2026 @@ -6,16 +6,18 @@ all:V: install install:V: genall gencall genall -# ugh. sources's build process can't hack absolute path names. -# we're in /sys/src/ape/lib/ap/syscall. -SRC=../../../../libc/9syscall # /sys/src/libc/9syscall -gencall:D: $SRC/mkfile $SRC/sys.h - { - sed '/^#define._X[123]/d' $SRC/sys.h - echo '#!/bin/rc' - sed -n -e '/switch/,/\$AS /p' $SRC/mkfile - } | awk -f upper.awk >$target - chmod +x $target +## ugh. sources's build process can't hack absolute path names. +## we're in /sys/src/ape/lib/ap/syscall. +#gencall:D: ../../../../libc/9syscall/mkfile # /sys/src/libc/9syscall/mkfile +# { +# echo '#!/bin/rc' +# sed -n -e 's/seek/_SEEK/g' -e '/switch/,/\$AS /p' $prereq +# } >$target +# chmod +x $target + +# risv64 has complicated 9syscall/mkfile +gencall:D: gencall.manual + cp -x gencall.manual $target nuke clean:V: rm -f *.[$OS] *.s gencall --- /n/sources/plan9/sys/src/ape/lib/bsd/listen.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/bsd/listen.c Sun Jun 28 00:00:00 2026 @@ -81,11 +81,11 @@ listenproc(Rock *r, int fd) _muxsid = getpgrp(); } else setpgid(getpid(), _muxsid); - _RENDEZVOUS(2, _muxsid); + _RENDEZVOUS((void *)2, (void *)_muxsid); break; default: atexit(_killmuxsid); - _muxsid = _RENDEZVOUS(2, 0); + _muxsid = (int)(unsigned long long)_RENDEZVOUS((void *)2, 0); close(pfd[1]); close(nfd); return 0; --- /dev/null +++ /sys/src/ape/lib/bsd/strdup.c Sun Jun 28 00:00:00 2026 @@ -0,0 +1,16 @@ +#include +#include +#include + +char* +strdup(char *p) +{ + int n; + char *np; + + n = strlen(p)+1; + np = malloc(n); + if(np) + memmove(np, p, n); + return np; +} --- /n/sources/plan9/sys/src/ape/lib/draw/libc.h Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/draw/libc.h Sun Jun 28 00:00:00 2026 @@ -1,138 +1 @@ -#define _LOCK_EXTENSION -#define _QLOCK_EXTENSION -#define _BSD_EXTENSION -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef -struct Qid -{ - uvlong path; - ulong vers; - uchar type; -} Qid; - -typedef -struct Dir { - /* system-modified data */ - ushort type; /* server type */ - uint dev; /* server subtype */ - /* file data */ - Qid qid; /* unique id from server */ - ulong mode; /* permissions */ - ulong atime; /* last read time */ - ulong mtime; /* last write time */ - vlong length; /* file length: see */ - char *name; /* last element of path */ - char *uid; /* owner name */ - char *gid; /* group name */ - char *muid; /* last modifier name */ -} Dir; - -uint _convM2D(uchar*, uint, Dir*, char*); -uint _convD2M(Dir*, uchar*, uint); -Dir *_dirstat(char*); -int _dirwstat(char*, Dir*); -Dir *_dirfstat(int); -int _dirfwstat(int, Dir*); -long _dirread(int, Dir**); -long _dirreadall(int, Dir**); -void _nulldir(Dir*); -uint _sizeD2M(Dir*); - -typedef -struct Waitmsg -{ - int pid; /* of loved one */ - unsigned long time[3]; /* of loved one & descendants */ - char *msg; -} Waitmsg; - - -extern int _AWAIT(char*, int); -extern int _ALARM(unsigned long); -extern int _BIND(const char*, const char*, int); -extern int _CHDIR(const char*); -extern int _CLOSE(int); -extern int _CREATE(char*, int, unsigned long); -extern int _DUP(int, int); -extern int _ERRSTR(char*, unsigned int); -extern int _EXEC(char*, char*[]); -extern void _EXITS(char *); -extern int _FD2PATH(int, char*, int); -extern int _FAUTH(int, char*); -extern int _FSESSION(int, char*, int); -extern int _FSTAT(int, unsigned char*, int); -extern int _FWSTAT(int, unsigned char*, int); -extern int _MOUNT(int, int, const char*, int, const char*); -extern int _NOTED(int); -extern int _NOTIFY(int(*)(void*, char*)); -extern int _OPEN(const char*, int); -extern int _PIPE(int*); -extern long _PREAD(int, void*, long, long long); -extern long _PWRITE(int, void*, long, long long); -extern long _READ(int, void*, long); -extern int _REMOVE(const char*); -extern int _RENDEZVOUS(unsigned long, unsigned long); -extern int _RFORK(int); -extern int _SEGATTACH(int, char*, void*, unsigned long); -extern int _SEGBRK(void*, void*); -extern int _SEGDETACH(void*); -extern int _SEGFLUSH(void*, unsigned long); -extern int _SEGFREE(void*, unsigned long); -extern long long _SEEK(int, long long, int); -extern int _SLEEP(long); -extern int _STAT(const char*, unsigned char*, int); -extern Waitmsg* _WAIT(void); -extern long _WRITE(int, const void*, long); -extern int _WSTAT(const char*, unsigned char*, int); -extern void *_MALLOCZ(int, int); -extern int _WERRSTR(char*, ...); -extern long _READN(int, void*, long); -extern int _IOUNIT(int); - -#define dirstat _dirstat -#define dirfstat _dirfstat - -#define OREAD 0 -#define OWRITE 1 -#define ORDWR 2 -#define OCEXEC 32 - -#define AREAD 4 -#define AWRITE 2 -#define AEXEC 1 -#define AEXIST 0 - -#define open _OPEN -#define close _CLOSE -#define read _READ -#define write _WRITE -#define _exits(s) _exit(s && *(char*)s ? 1 : 0) -#define exits(s) exit(s && *(char*)s ? 1 : 0) -#define create _CREATE -#define pread _PREAD -#define readn _READN -#define mallocz _MALLOCZ -#define iounit _IOUNIT -#define bind _BIND - -/* assume being called as in event.c */ -#define postnote(x, pid, msg) kill(pid, SIGTERM) -#define atnotify(x, y) signal(SIGTERM, ekill) - -#define ERRMAX 128 - -extern void setmalloctag(void*, ulong); -extern ulong getcallerpc(void*); +#include "/sys/src/ape/lib/9/libc.h" --- /dev/null +++ /sys/src/ape/lib/draw/libc.old.h Sun Jun 28 00:00:00 2026 @@ -0,0 +1,144 @@ +#define _LOCK_EXTENSION +#define _QLOCK_EXTENSION +#define _BSD_EXTENSION +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef _SUSV2_SOURCE +#define _SUSV2_SOURCE +#include +#undef _SUSV2_SOURCE +#else +#include +#endif + +typedef +struct Qid +{ + uvlong path; + ulong vers; + uchar type; +} Qid; + +typedef +struct Dir { + /* system-modified data */ + ushort type; /* server type */ + uint dev; /* server subtype */ + /* file data */ + Qid qid; /* unique id from server */ + ulong mode; /* permissions */ + ulong atime; /* last read time */ + ulong mtime; /* last write time */ + vlong length; /* file length: see */ + char *name; /* last element of path */ + char *uid; /* owner name */ + char *gid; /* group name */ + char *muid; /* last modifier name */ +} Dir; + +uint _convM2D(uchar*, uint, Dir*, char*); +uint _convD2M(Dir*, uchar*, uint); +Dir *_dirstat(char*); +int _dirwstat(char*, Dir*); +Dir *_dirfstat(int); +int _dirfwstat(int, Dir*); +long _dirread(int, Dir**); +long _dirreadall(int, Dir**); +void _nulldir(Dir*); +uint _sizeD2M(Dir*); + +typedef +struct Waitmsg +{ + int pid; /* of loved one */ + unsigned long time[3]; /* of loved one & descendants */ + char *msg; +} Waitmsg; + + +extern int _AWAIT(char*, int); +extern int _ALARM(unsigned long); +extern int _BIND(const char*, const char*, int); +extern int _CHDIR(const char*); +extern int _CLOSE(int); +extern int _CREATE(char*, int, unsigned long); +extern int _DUP(int, int); +extern int _ERRSTR(char*, unsigned int); +extern int _EXEC(char*, char*[]); +extern void _EXITS(char *); +extern int _FD2PATH(int, char*, int); +extern int _FAUTH(int, char*); +extern int _FSESSION(int, char*, int); +extern int _FSTAT(int, unsigned char*, int); +extern int _FWSTAT(int, unsigned char*, int); +extern int _MOUNT(int, int, const char*, int, const char*); +extern int _NOTED(int); +extern int _NOTIFY(int(*)(void*, char*)); +extern int _OPEN(const char*, int); +extern int _PIPE(int*); +extern long _PREAD(int, void*, long, long long); +extern long _PWRITE(int, void*, long, long long); +extern long _READ(int, void*, long); +extern int _REMOVE(const char*); +extern void* _RENDEZVOUS(void *, void *); +extern int _RFORK(int); +extern int _SEGATTACH(int, char*, void*, unsigned long); +extern int _SEGBRK(void*, void*); +extern int _SEGDETACH(void*); +extern int _SEGFLUSH(void*, unsigned long); +extern int _SEGFREE(void*, unsigned long); +extern long long _SEEK(int, long long, int); +extern int _SLEEP(long); +extern int _STAT(const char*, unsigned char*, int); +extern Waitmsg* _WAIT(void); +extern long _WRITE(int, const void*, long); +extern int _WSTAT(const char*, unsigned char*, int); +extern void *_MALLOCZ(size_t, int); +extern int _WERRSTR(char*, ...); +extern long _READN(int, void*, long); +extern int _IOUNIT(int); + +#define dirstat _dirstat +#define dirfstat _dirfstat + +#define OREAD 0 +#define OWRITE 1 +#define ORDWR 2 +#define OCEXEC 32 + +#define AREAD 4 +#define AWRITE 2 +#define AEXEC 1 +#define AEXIST 0 + +#define open _OPEN +#define close _CLOSE +#define read _READ +#define write _WRITE +#define _exits(s) _exit(s && *(char*)s ? 1 : 0) +#define exits(s) exit(s && *(char*)s ? 1 : 0) +#define create _CREATE +#define pread _PREAD +#define readn _READN +#define mallocz _MALLOCZ +#define iounit _IOUNIT + +/* assume being called as in event.c */ +#define postnote(x, pid, msg) kill(pid, SIGTERM) +#define atnotify(x, y) signal(SIGTERM, ekill) + +#define ERRMAX 128 + +extern void setmalloctag(void*, ulong); +extern uintptr_t getcallerpc(void*); --- /n/sources/plan9/sys/src/ape/lib/fmt/dofmt.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/fmt/dofmt.c Sun Jun 28 00:00:00 2026 @@ -13,6 +13,7 @@ */ #include #include +#include #include "utf.h" #include "fmt.h" #include "fmtdef.h" @@ -22,9 +23,8 @@ int dofmt(Fmt *f, char *fmt) { Rune rune, *rt, *rs; - int r; char *t, *s; - int n, nfmt; + int r, n, nfmt; nfmt = f->nfmt; for(;;){ @@ -348,7 +348,7 @@ __ifmt(Fmt *f) break; } if(f->r == 'p'){ - u = (ulong)va_arg(f->args, void*); + u = (uintptr_t)va_arg(f->args, void*); f->r = 'x'; fl |= FmtUnsigned; }else if(fl & FmtVLong){ --- /n/sources/plan9/sys/src/ape/lib/fmt/fmtfdflush.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/fmt/fmtfdflush.c Sun Jun 28 00:00:00 2026 @@ -12,6 +12,7 @@ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */ #include +#include #include #include "fmt.h" #include "fmtdef.h" @@ -26,7 +27,7 @@ __fmtFdFlush(Fmt *f) int n; n = (char*)f->to - (char*)f->start; - if(n && write((int)f->farg, f->start, n) != n) + if(n && write((int)(uintptr_t)f->farg, f->start, n) != n) return 0; f->to = f->start; return 1; --- /n/sources/plan9/sys/src/ape/lib/fmt/fmtstr.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/fmt/fmtstr.c Sun Jun 28 00:00:00 2026 @@ -14,6 +14,7 @@ #include #include #include +#include #include "utf.h" #include "fmt.h" #include "fmtdef.h" @@ -22,9 +23,9 @@ static int fmtStrFlush(Fmt *f) { char *s; - int n; + uintptr_t n; - n = (int)f->farg; + n = (uintptr_t)f->farg; n += 256; f->farg = (void*)n; s = (char*)f->start; --- /n/sources/plan9/sys/src/ape/lib/fmt/mkfile Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/fmt/mkfile Sun Jun 28 00:00:00 2026 @@ -56,4 +56,4 @@ test: $LIB test.$O $CC -o test test.$O $LIB -L$PLAN9/lib -lutf -CFLAGS=$CFLAGS -c -D_POSIX_SOURCE -D_PLAN9_SOURCE -D_BSD_EXTENSION +CFLAGS=$CFLAGS -c -D_POSIX_SOURCE -D_PLAN9_SOURCE -D_BSD_EXTENSION -D_SUSV2_SOURCE --- /n/sources/plan9/sys/src/ape/lib/fmt/runefmtstr.c Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/fmt/runefmtstr.c Sun Jun 28 00:00:00 2026 @@ -14,6 +14,7 @@ #include #include #include +#include #include "utf.h" #include "fmt.h" #include "fmtdef.h" @@ -22,9 +23,9 @@ static int runeFmtStrFlush(Fmt *f) { Rune *s; - int n; + uintptr_t n; - n = (int)f->farg; + n = (uintptr_t)f->farg; n += 256; f->farg = (void*)n; s = (Rune*)f->start; --- /dev/null +++ /386/include/ape/_apetypes.h Sun Jun 28 00:00:00 2026 @@ -0,0 +1 @@ +/* 32-bit ABI: leave _BITS64 undefined */ --- /dev/null +++ /arm/include/ape/_apetypes.h Sun Jun 28 00:00:00 2026 @@ -0,0 +1 @@ +/* 32-bit ABI: leave _BITS64 undefined */ --- /dev/null +++ /mips/include/ape/_apetypes.h Sun Jun 28 00:00:00 2026 @@ -0,0 +1 @@ +/* 32-bit ABI: leave _BITS64 undefined */ --- /dev/null +++ /power/include/ape/_apetypes.h Sun Jun 28 00:00:00 2026 @@ -0,0 +1 @@ +/* 32-bit ABI: leave _BITS64 undefined */ --- /n/sources/plan9/sys/src/ape/lib/mp/port/libc.h Sat Jan 10 10:00:05 2015 +++ /sys/src/ape/lib/mp/port/libc.h Sun Jun 28 00:00:00 2026 @@ -5,14 +5,21 @@ #include #include #include +#ifndef _SUSV2_SOURCE +#define _SUSV2_SOURCE +#include +#undef _SUSV2_SOURCE +#else +#include +#endif typedef unsigned int u32int; typedef unsigned long long u64int; #define nelem(x) (sizeof(x)/sizeof((x)[0])) -extern ulong getcallerpc(void*); -extern void* mallocz(ulong, int); +extern uintptr_t getcallerpc(void*); +extern void* mallocz(size_t, int); extern void setmalloctag(void*, ulong); extern int dec16(uchar *, int, char *, int);