summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Forsyth <charles.forsyth@gmail.com>2018-12-21 15:05:38 +0000
committerCharles Forsyth <charles.forsyth@gmail.com>2018-12-21 15:05:38 +0000
commit0195c4e25fc394097552c7f5ebf3085ec2d201f5 (patch)
treef67d1be5b8f66a11756be790f1e9371340b5be9e
parent9765fcf68d2e5e39e39c100f798b9d00202e0d0a (diff)
parentb743441fb25b17bc7b81d3fb599b4ff5f149368b (diff)
Merged in yk/inferno-os/AIX-power (pull request #17)
AIX-power port Approved-by: Charles Forsyth <charles.forsyth@gmail.com>
-rw-r--r--.hgignore9
-rwxr-xr-xAIX/power/bin/data2cbin0 -> 79583 bytes
-rwxr-xr-xAIX/power/bin/iyaccbin0 -> 198151 bytes
-rwxr-xr-xAIX/power/bin/mkbin0 -> 337445 bytes
-rwxr-xr-xAIX/power/bin/ndatebin0 -> 59026 bytes
-rw-r--r--AIX/power/include/ar.h30
-rw-r--r--AIX/power/include/emu.h25
-rw-r--r--AIX/power/include/lib9.h509
-rw-r--r--README.md2
-rw-r--r--doc/port.ms2
-rw-r--r--emu/AIX/asm-power.s108
-rw-r--r--emu/AIX/cmd.c213
-rw-r--r--emu/AIX/deveia.c40
-rw-r--r--emu/AIX/devfs.c7
-rw-r--r--emu/AIX/emu104
-rw-r--r--emu/AIX/emu-g100
-rw-r--r--emu/AIX/mkfile52
-rw-r--r--emu/AIX/mkfile-power0
-rw-r--r--emu/AIX/os.c300
-rw-r--r--emu/AIX/segflush-power.c33
-rw-r--r--emu/port/devfs-posix.c2
-rw-r--r--emu/port/win-x11a.c2
-rw-r--r--lib/emptydirs1
-rw-r--r--lib9/getcallerpc-AIX-power.c12
-rw-r--r--lib9/setfcr-AIX-power.c39
-rw-r--r--libmath/FPcontrol-AIX.c77
-rw-r--r--libmemdraw/mkfile-AIX1
-rw-r--r--libmemlayer/mkfile-AIX4
-rw-r--r--limbo/lex.c2
-rw-r--r--makemk-AIX.sh78
-rw-r--r--mkconfig4
-rw-r--r--mkfiles/mkfile-AIX-power25
-rw-r--r--mkfiles/mkhost-AIX14
-rw-r--r--utils/mk/archive-AIX.c203
-rw-r--r--utils/mk/mkfile4
35 files changed, 1995 insertions, 7 deletions
diff --git a/.hgignore b/.hgignore
index b933c7d9..bdd6041c 100644
--- a/.hgignore
+++ b/.hgignore
@@ -61,5 +61,14 @@ syntax: regexp
^usr/\.*
^grid/.*
^libinterp/cryptmod.h
+^libinterp/drawmod.h
+^libinterp/freetypemod.h
^libinterp/ipintsmod.h
+^libinterp/keyring.h
^libinterp/keyringif.h
+^libinterp/loadermod.h
+^libinterp/mathmod.h
+^libinterp/runt.h
+^libinterp/sysmod.h
+^libinterp/tkmod.h
+^limbo/runt.h
diff --git a/AIX/power/bin/data2c b/AIX/power/bin/data2c
new file mode 100755
index 00000000..9cdacae0
--- /dev/null
+++ b/AIX/power/bin/data2c
Binary files differ
diff --git a/AIX/power/bin/iyacc b/AIX/power/bin/iyacc
new file mode 100755
index 00000000..c97da6a7
--- /dev/null
+++ b/AIX/power/bin/iyacc
Binary files differ
diff --git a/AIX/power/bin/mk b/AIX/power/bin/mk
new file mode 100755
index 00000000..14d47859
--- /dev/null
+++ b/AIX/power/bin/mk
Binary files differ
diff --git a/AIX/power/bin/ndate b/AIX/power/bin/ndate
new file mode 100755
index 00000000..f5293367
--- /dev/null
+++ b/AIX/power/bin/ndate
Binary files differ
diff --git a/AIX/power/include/ar.h b/AIX/power/include/ar.h
new file mode 100644
index 00000000..f8473172
--- /dev/null
+++ b/AIX/power/include/ar.h
@@ -0,0 +1,30 @@
+#define ARMAG "<bigaf>\n"
+#define SARMAG 8
+
+#define ARFMAG "`\n"
+
+struct fl_hdr /* archive fixed length header - printable ascii */
+{
+ char magic[SARMAG]; /* Archive file magic string */
+ char memoff[20]; /* Offset to member table */
+ char gstoff[20]; /* Offset to 32-bit global sym table */
+ char gst64off[20]; /* Offset to 64-bit global sym table */
+ char fstmoff[20]; /* Offset to first archive member */
+ char lstmoff[20]; /* Offset to last archive member */
+ char freeoff[20]; /* Offset to first mem on free list */
+};
+#define SAR_FLHDR (SARMAG+120)
+
+struct ar_hdr /* archive file member header - printable ascii */
+{
+ char size[20]; /* file member size - decimal */
+ char nxtmem[20]; /* pointer to next member - decimal */
+ char prvmem[20]; /* pointer to previous member - decimal */
+ char date[12]; /* file member date - decimal */
+ char uid[12]; /* file member user id - decimal */
+ char gid[12]; /* file member group id - decimal */
+ char mode[12]; /* file member mode - octal */
+ char namlen[4]; /* file member name length - decimal */
+ /* and variable length name follows*/
+};
+#define SAR_HDR 112
diff --git a/AIX/power/include/emu.h b/AIX/power/include/emu.h
new file mode 100644
index 00000000..94053840
--- /dev/null
+++ b/AIX/power/include/emu.h
@@ -0,0 +1,25 @@
+/*
+ * system- and machine-specific declarations for emu:
+ * floating-point save and restore, signal handling primitive, and
+ * implementation of the current-process variable `up'.
+ */
+
+/*
+ * This structure must agree with FPsave and FPrestore asm routines
+ */
+typedef struct FPU FPU;
+struct FPU
+{
+ uchar env[18*8];
+};
+
+#define KSTACK (32 * 1024)
+
+extern Proc* getup(void);
+
+#define up (getup())
+
+typedef sigjmp_buf osjmpbuf;
+#define ossetjmp(buf) sigsetjmp(buf, 1)
+
+#define pthread_yield sched_yield
diff --git a/AIX/power/include/lib9.h b/AIX/power/include/lib9.h
new file mode 100644
index 00000000..b4f1a11a
--- /dev/null
+++ b/AIX/power/include/lib9.h
@@ -0,0 +1,509 @@
+#define _DEFAULT_SOURCE
+#define _BSD_SOURCE
+#define _LINUX_SOURCE_COMPAT
+#define _XOPEN_SOURCE 500
+#define _LARGEFILE_SOURCE 1
+#define _LARGEFILE64_SOURCE 1
+#define _FILE_OFFSET_BITS 64
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#define sync __os_sync
+#include <unistd.h>
+#undef sync
+#include <errno.h>
+#define __NO_STRING_INLINES
+#include <string.h>
+#include "math.h"
+#include <fcntl.h>
+#include <setjmp.h>
+#include <float.h>
+
+#define getwd infgetwd
+
+#ifndef EMU
+typedef struct Proc Proc;
+#endif
+
+#undef __LITTLE_ENDIAN
+
+#define nil ((void*)0)
+
+typedef unsigned char uchar;
+typedef signed char schar;
+typedef unsigned int Rune;
+typedef long long int vlong;
+typedef unsigned long long int uvlong;
+typedef unsigned int u32int;
+typedef uvlong u64int;
+typedef unsigned long ulong;
+typedef unsigned short ushort;
+typedef unsigned int uint;
+
+typedef unsigned int mpdigit; /* for /sys/include/mp.h */
+typedef unsigned short u16int;
+typedef unsigned char u8int;
+typedef unsigned long uintptr;
+
+#define USED(x) if(x){}else{}
+#define SET(x)
+
+#undef nelem
+#define nelem(x) (sizeof(x)/sizeof((x)[0]))
+#undef offsetof
+#define offsetof(s, m) (ulong)(&(((s*)0)->m))
+#undef assert
+#define assert(x) if(x){}else _assert("x")
+
+/*
+ * most mem and string routines are declared by ANSI/POSIX files above
+ */
+
+extern char* strecpy(char*, char*, char*);
+extern char* strdup(const char*);
+extern int cistrncmp(char*, char*, int);
+extern int cistrcmp(char*, char*);
+extern char* cistrstr(char*, char*);
+extern int tokenize(char*, char**, int);
+
+enum
+{
+ UTFmax = 4, /* maximum bytes per rune */
+ Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */
+ Runeself = 0x80, /* rune and UTF sequences are the same (<) */
+ Runeerror = 0xFFFD, /* decoding error in UTF */
+ Runemax = 0x10FFFF, /* 21-bit rune */
+ Runemask = 0x1FFFFF, /* bits used by runes (see grep) */
+};
+
+/*
+ * rune routines
+ */
+extern int runetochar(char*, Rune*);
+extern int chartorune(Rune*, char*);
+extern int runelen(long);
+extern int runenlen(Rune*, int);
+extern int fullrune(char*, int);
+extern int utflen(char*);
+extern int utfnlen(char*, long);
+extern char* utfrune(char*, long);
+extern char* utfrrune(char*, long);
+extern char* utfutf(char*, char*);
+extern char* utfecpy(char*, char*, char*);
+
+extern Rune* runestrcat(Rune*, Rune*);
+extern Rune* runestrchr(Rune*, Rune);
+extern int runestrcmp(Rune*, Rune*);
+extern Rune* runestrcpy(Rune*, Rune*);
+extern Rune* runestrncpy(Rune*, Rune*, long);
+extern Rune* runestrecpy(Rune*, Rune*, Rune*);
+extern Rune* runestrdup(Rune*);
+extern Rune* runestrncat(Rune*, Rune*, long);
+extern int runestrncmp(Rune*, Rune*, long);
+extern Rune* runestrrchr(Rune*, Rune);
+extern long runestrlen(Rune*);
+extern Rune* runestrstr(Rune*, Rune*);
+
+extern Rune tolowerrune(Rune);
+extern Rune totitlerune(Rune);
+extern Rune toupperrune(Rune);
+extern int isalpharune(Rune);
+extern int islowerrune(Rune);
+extern int isspacerune(Rune);
+extern int istitlerune(Rune);
+extern int isupperrune(Rune);
+
+/*
+ * malloc
+ */
+extern void* malloc(size_t);
+extern void* mallocz(ulong, int);
+extern void free(void*);
+extern ulong msize(void*);
+extern void* calloc(size_t, size_t);
+extern void* realloc(void*, size_t);
+extern void setmalloctag(void*, ulong);
+extern void setrealloctag(void*, ulong);
+extern ulong getmalloctag(void*);
+extern ulong getrealloctag(void*);
+extern void* malloctopoolblock(void*);
+
+/*
+ * print routines
+ */
+typedef struct Fmt Fmt;
+struct Fmt{
+ uchar runes; /* output buffer is runes or chars? */
+ void *start; /* of buffer */
+ void *to; /* current place in the buffer */
+ void *stop; /* end of the buffer; overwritten if flush fails */
+ int (*flush)(Fmt *); /* called when to == stop */
+ void *farg; /* to make flush a closure */
+ int nfmt; /* num chars formatted so far */
+ va_list args; /* args passed to dofmt */
+ int r; /* % format Rune */
+ int width;
+ int prec;
+ ulong flags;
+};
+
+enum{
+ FmtWidth = 1,
+ FmtLeft = FmtWidth << 1,
+ FmtPrec = FmtLeft << 1,
+ FmtSharp = FmtPrec << 1,
+ FmtSpace = FmtSharp << 1,
+ FmtSign = FmtSpace << 1,
+ FmtZero = FmtSign << 1,
+ FmtUnsigned = FmtZero << 1,
+ FmtShort = FmtUnsigned << 1,
+ FmtLong = FmtShort << 1,
+ FmtVLong = FmtLong << 1,
+ FmtComma = FmtVLong << 1,
+ FmtByte = FmtComma << 1,
+
+ FmtFlag = FmtByte << 1
+};
+
+extern int print(char*, ...);
+extern char* seprint(char*, char*, char*, ...);
+extern char* vseprint(char*, char*, char*, va_list);
+extern int snprint(char*, int, char*, ...);
+extern int vsnprint(char*, int, char*, va_list);
+extern char* smprint(char*, ...);
+extern char* vsmprint(char*, va_list);
+extern int sprint(char*, char*, ...);
+extern int fprint(int, char*, ...);
+extern int vfprint(int, char*, va_list);
+
+extern int runesprint(Rune*, char*, ...);
+extern int runesnprint(Rune*, int, char*, ...);
+extern int runevsnprint(Rune*, int, char*, va_list);
+extern Rune* runeseprint(Rune*, Rune*, char*, ...);
+extern Rune* runevseprint(Rune*, Rune*, char*, va_list);
+extern Rune* runesmprint(char*, ...);
+extern Rune* runevsmprint(char*, va_list);
+
+extern int fmtfdinit(Fmt*, int, char*, int);
+extern int fmtfdflush(Fmt*);
+extern int fmtstrinit(Fmt*);
+extern char* fmtstrflush(Fmt*);
+extern int runefmtstrinit(Fmt*);
+extern Rune* runefmtstrflush(Fmt*);
+
+extern int fmtinstall(int, int (*)(Fmt*));
+extern int dofmt(Fmt*, char*);
+extern int dorfmt(Fmt*, Rune*);
+extern int fmtprint(Fmt*, char*, ...);
+extern int fmtvprint(Fmt*, char*, va_list);
+extern int fmtrune(Fmt*, int);
+extern int fmtstrcpy(Fmt*, char*);
+extern int fmtrunestrcpy(Fmt*, Rune*);
+/*
+ * error string for %r
+ * supplied on per os basis, not part of fmt library
+ */
+extern int errfmt(Fmt *f);
+
+/*
+ * quoted strings
+ */
+extern char *unquotestrdup(char*);
+extern Rune *unquoterunestrdup(Rune*);
+extern char *quotestrdup(char*);
+extern Rune *quoterunestrdup(Rune*);
+extern int quotestrfmt(Fmt*);
+extern int quoterunestrfmt(Fmt*);
+extern void quotefmtinstall(void);
+extern int (*doquote)(int);
+
+/*
+ * random number
+ */
+extern ulong truerand(void);
+extern ulong ntruerand(ulong);
+
+/*
+ * math
+ */
+extern int isNaN(double);
+extern double NaN(void);
+extern int isInf(double, int);
+
+/*
+ * Time-of-day
+ */
+
+typedef struct Tm Tm;
+struct Tm {
+ int sec;
+ int min;
+ int hour;
+ int mday;
+ int mon;
+ int year;
+ int wday;
+ int yday;
+ char zone[4];
+ int tzoff;
+};
+extern vlong osnsec(void);
+#define nsec osnsec
+
+/*
+ * one-of-a-kind
+ */
+extern void _assert(char*);
+extern double charstod(int(*)(void*), void*);
+extern char* cleanname(char*);
+extern uintptr getcallerpc(void*);
+extern int getfields(char*, char**, int, int, char*);
+extern char* getuser(void);
+extern char* getwd(char*, int);
+extern double ipow10(int);
+#define pow10 infpow10
+extern double pow10(int);
+extern vlong strtoll(const char*, char**, int);
+#define qsort infqsort
+extern void qsort(void*, long, long, int (*)(void*, void*));
+extern uvlong strtoull(const char*, char**, int);
+extern void sysfatal(char*, ...);
+extern int dec64(uchar*, int, char*, int);
+extern int enc64(char*, int, uchar*, int);
+extern int dec32(uchar*, int, char*, int);
+extern int enc32(char*, int, uchar*, int);
+extern int dec16(uchar*, int, char*, int);
+extern int enc16(char*, int, uchar*, int);
+extern int encodefmt(Fmt*);
+
+/*
+ * synchronization
+ */
+typedef
+struct Lock {
+ int val;
+ int pid;
+} Lock;
+
+extern int _tas(int*);
+
+extern void lock(Lock*);
+extern void unlock(Lock*);
+extern int canlock(Lock*);
+
+typedef struct QLock QLock;
+struct QLock
+{
+ Lock use; /* to access Qlock structure */
+ Proc *head; /* next process waiting for object */
+ Proc *tail; /* last process waiting for object */
+ int locked; /* flag */
+};
+
+extern void qlock(QLock*);
+extern void qunlock(QLock*);
+extern int canqlock(QLock*);
+extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */
+
+typedef
+struct RWLock
+{
+ Lock l; /* Lock modify lock */
+ QLock x; /* Mutual exclusion lock */
+ QLock k; /* Lock for waiting writers */
+ int readers; /* Count of readers in lock */
+} RWLock;
+
+extern int canrlock(RWLock*);
+extern int canwlock(RWLock*);
+extern void rlock(RWLock*);
+extern void runlock(RWLock*);
+extern void wlock(RWLock*);
+extern void wunlock(RWLock*);
+
+/*
+ * network dialing
+ */
+#define NETPATHLEN 40
+
+/*
+ * system calls
+ *
+ */
+#define STATMAX 65535U /* max length of machine-independent stat structure */
+#define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */
+#define ERRMAX 128 /* max length of error string */
+
+#define MORDER 0x0003 /* mask for bits defining order of mounting */
+#define MREPL 0x0000 /* mount replaces object */
+#define MBEFORE 0x0001 /* mount goes before others in union directory */
+#define MAFTER 0x0002 /* mount goes after others in union directory */
+#define MCREATE 0x0004 /* permit creation in mounted directory */
+#define MCACHE 0x0010 /* cache some data */
+#define MMASK 0x0017 /* all bits on */
+
+#define OREAD 0 /* open for read */
+#define OWRITE 1 /* write */
+#define ORDWR 2 /* read and write */
+#define OEXEC 3 /* execute, == read but check execute permission */
+#define OTRUNC 16 /* or'ed in (except for exec), truncate file first */
+#define OCEXEC 32 /* or'ed in, close on exec */
+#define ORCLOSE 64 /* or'ed in, remove on close */
+#define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */
+
+#define AEXIST 0 /* accessible: exists */
+#define AEXEC 1 /* execute access */
+#define AWRITE 2 /* write access */
+#define AREAD 4 /* read access */
+
+/* bits in Qid.type */
+#define QTDIR 0x80 /* type bit for directories */
+#define QTAPPEND 0x40 /* type bit for append only files */
+#define QTEXCL 0x20 /* type bit for exclusive use files */
+#define QTMOUNT 0x10 /* type bit for mounted channel */
+#define QTAUTH 0x08 /* type bit for authentication file */
+#define QTFILE 0x00 /* plain file */
+
+/* bits in Dir.mode */
+#define DMDIR 0x80000000 /* mode bit for directories */
+#define DMAPPEND 0x40000000 /* mode bit for append only files */
+#define DMEXCL 0x20000000 /* mode bit for exclusive use files */
+#define DMMOUNT 0x10000000 /* mode bit for mounted channel */
+#define DMAUTH 0x08000000 /* mode bit for authentication file */
+#define DMREAD 0x4 /* mode bit for read permission */
+#define DMWRITE 0x2 /* mode bit for write permission */
+#define DMEXEC 0x1 /* mode bit for execute permission */
+
+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 */
+ char *name; /* last element of path */
+ char *uid; /* owner name */
+ char *gid; /* group name */
+ char *muid; /* last modifier name */
+} Dir;
+
+extern Dir* dirstat(char*);
+extern Dir* dirfstat(int);
+extern int dirwstat(char*, Dir*);
+extern int dirfwstat(int, Dir*);
+extern long dirread(int, Dir**);
+extern void nulldir(Dir*);
+extern long dirreadall(int, Dir**);
+
+typedef
+struct Waitmsg
+{
+ int pid; /* of loved one */
+ ulong time[3]; /* of loved one & descendants */
+ char *msg;
+} Waitmsg;
+
+extern void _exits(char*);
+
+extern void exits(char*);
+extern int create(char*, int, int);
+extern int errstr(char*, uint);
+
+extern void perror(const char*);
+extern long readn(int, void*, long);
+extern int remove(const char*);
+extern void rerrstr(char*, uint);
+extern vlong seek(int, vlong, int);
+extern int segflush(void*, ulong);
+extern void werrstr(char*, ...);
+
+extern char *argv0;
+#define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\
+ argv[0] && argv[0][0]=='-' && argv[0][1];\
+ argc--, argv++) {\
+ char *_args, *_argt;\
+ Rune _argc;\
+ _args = &argv[0][1];\
+ if(_args[0]=='-' && _args[1]==0){\
+ argc--; argv++; break;\
+ }\
+ _argc = 0;\
+ while(*_args && (_args += chartorune(&_argc, _args)))\
+ switch(_argc)
+#define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc);
+#define ARGF() (_argt=_args, _args="",\
+ (*_argt? _argt: argv[1]? (argc--, *++argv): 0))
+#define EARGF(x) (_argt=_args, _args="",\
+ (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0)))
+
+#define ARGC() _argc
+
+/*
+ * Extensions for Inferno to basic libc.h
+ */
+
+#define setbinmode()
+
+extern void setfcr(ulong);
+extern void setfsr(ulong);
+extern ulong getfcr(void);
+extern ulong getfsr(void);
+
+
+/* FPSCR */
+#define FPSFX (1<<31) /* exception summary (sticky) */
+#define FPSEX (1<<30) /* enabled exception summary */
+#define FPSVX (1<<29) /* invalid operation exception summary */
+#define FPSOX (1<<28) /* overflow exception OX (sticky) */
+#define FPSUX (1<<27) /* underflow exception UX (sticky) */
+#define FPSZX (1<<26) /* zero divide exception ZX (sticky) */
+#define FPSXX (1<<25) /* inexact exception XX (sticky) */
+#define FPSVXSNAN (1<<24) /* invalid operation exception for SNaN (sticky) */
+#define FPSVXISI (1<<23) /* invalid operation exception for ∞-∞ (sticky) */
+#define FPSVXIDI (1<<22) /* invalid operation exception for ∞/∞ (sticky) */
+#define FPSVXZDZ (1<<21) /* invalid operation exception for 0/0 (sticky) */
+#define FPSVXIMZ (1<<20) /* invalid operation exception for ∞*0 (sticky) */
+#define FPSVXVC (1<<19) /* invalid operation exception for invalid compare (sticky) */
+#define FPSFR (1<<18) /* fraction rounded */
+#define FPSFI (1<<17) /* fraction inexact */
+#define FPSFPRF (1<<16) /* floating point result class */
+#define FPSFPCC (0xF<<12) /* <, >, =, unordered */
+#define FPVXCVI (1<<8) /* enable exception for invalid integer convert (sticky) */
+
+/* FCR */
+#define FPVE (1<<7) /* invalid operation exception enable */
+#define FPOVFL (1<<6) /* enable overflow exceptions */
+#define FPUNFL (1<<5) /* enable underflow */
+#define FPZDIV (1<<4) /* enable zero divide */
+#define FPINEX (1<<3) /* enable inexact exceptions */
+#define FPRMASK (3<<0) /* rounding mode */
+#define FPRNR (0<<0)
+#define FPRZ (1<<0)
+#define FPRPINF (2<<0)
+#define FPRNINF (3<<0)
+#define FPPEXT 0
+#define FPPSGL 0
+#define FPPDBL 0
+#define FPPMASK 0
+#define FPINVAL FPVE
+/* FSR */
+#define FPAOVFL FPSOX
+#define FPAINEX FPSXX
+#define FPAUNFL FPSUX
+#define FPAZDIV FPSZX
+#define FPAINVAL FPSVX
+
diff --git a/README.md b/README.md
index 84be1156..4d2949f2 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,6 @@ The use of a high-level language and virtual machine is sensible but mundane. Th
The system can be used to build portable client and server applications. It makes it straightforward to build lean applications that share all manner of resources over a network, without the cruft of much of the 'Grid' software one sees.
-Inferno can run 'native' on various ARM, PowerPC, SPARC and x86 platforms but also 'hosted', under an existing operating system (including FreeBSD, Irix, Linux, MacOS X, Plan 9, and Solaris), again on various processor types.
+Inferno can run 'native' on various ARM, PowerPC, SPARC and x86 platforms but also 'hosted', under an existing operating system (including AIX, FreeBSD, Irix, Linux, MacOS X, Plan 9, and Solaris), again on various processor types.
This Bitbucket project includes source for the basic applications, Inferno itself (hosted and native), all supporting software, including the native compiler suite, essential executables and supporting files.
diff --git a/doc/port.ms b/doc/port.ms
index 21ae2830..cb56ae1e 100644
--- a/doc/port.ms
+++ b/doc/port.ms
@@ -189,6 +189,7 @@ There are currently four main variants of hosted Inferno: Plan 9, Unix (and clon
The source is held in directory
.CW emu ,
with a subdirectory for each hosted platform:
+.CW AIX ,
.CW FreeBSD ,
.CW Irix ,
.CW Linux ,
@@ -246,6 +247,7 @@ threads efficiently.
.PP
There are working emu versions
for
+AIX/power,
FreeBSD/386,
Irix/mips,
Linux/386,
diff --git a/emu/AIX/asm-power.s b/emu/AIX/asm-power.s
new file mode 100644
index 00000000..024c058b
--- /dev/null
+++ b/emu/AIX/asm-power.s
@@ -0,0 +1,108 @@
+.set r0,0; .set SP,1; .set RTOC,2; .set r3,3; .set r4,4
+.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9
+.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14
+.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19
+.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24
+.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29
+.set r30,30; .set r31,31
+.set fp0,0; .set fp1,1; .set fp2,2; .set fp3,3; .set fp4,4
+.set fp5,5; .set fp6,6; .set fp7,7; .set fp8,8; .set fp9,9
+.set fp10,10; .set fp11,11; .set fp12,12; .set fp13,13; .set fp14,14
+.set fp15,15; .set fp16,16; .set fp17,17; .set fp18,18; .set fp19,19
+.set fp20,20; .set fp21,21; .set fp22,22; .set fp23,23; .set fp24,24
+.set fp25,25; .set fp26,26; .set fp27,27; .set fp28,28; .set fp29,29
+.set fp30,30; .set fp31,31
+.set v0,0; .set v1,1; .set v2,2; .set v3,3; .set v4,4
+.set v5,5; .set v6,6; .set v7,7; .set v8,8; .set v9,9
+.set v10,10; .set v11,11; .set v12,12; .set v13,13; .set v14,14
+.set v15,15; .set v16,16; .set v17,17; .set v18,18; .set v19,19
+.set v20,20; .set v21,21; .set v22,22; .set v23,23; .set v24,24
+.set v25,25; .set v26,26; .set v27,27; .set v28,28; .set v29,29
+.set v30,30; .set v31,31
+.set LR,8; .set CTR,9; .set TID,17; .set DSISR,18; .set DAR,19; .set TO_RTCU,20
+
+.machine "ppc"
+
+ .align 2
+ .globl .FPsave
+.FPsave:
+ stfd fp14,0*8(r3)
+ stfd fp15,1*8(r3)
+ stfd fp16,2*8(r3)
+ stfd fp17,3*8(r3)
+ stfd fp18,4*8(r3)
+ stfd fp19,5*8(r3)
+ stfd fp20,6*8(r3)
+ stfd fp21,7*8(r3)
+ stfd fp22,8*8(r3)
+ stfd fp23,9*8(r3)
+ stfd fp24,10*8(r3)
+ stfd fp25,11*8(r3)
+ stfd fp26,12*8(r3)
+ stfd fp27,13*8(r3)
+ stfd fp28,14*8(r3)
+ stfd fp29,15*8(r3)
+ stfd fp30,16*8(r3)
+ stfd fp31,17*8(r3)
+ blr
+
+ .align 2
+ .globl .FPrestore
+.FPrestore:
+ lfd fp14,0*8(r3)
+ lfd fp15,1*8(r3)
+ lfd fp16,2*8(r3)
+ lfd fp17,3*8(r3)
+ lfd fp18,4*8(r3)
+ lfd fp19,5*8(r3)
+ lfd fp20,6*8(r3)
+ lfd fp21,7*8(r3)
+ lfd fp22,8*8(r3)
+ lfd fp23,9*8(r3)
+ lfd fp24,10*8(r3)
+ lfd fp25,11*8(r3)
+ lfd fp26,12*8(r3)
+ lfd fp27,13*8(r3)
+ lfd fp28,14*8(r3)
+ lfd fp29,15*8(r3)
+ lfd fp30,16*8(r3)
+ lfd fp31,17*8(r3)
+ blr
+
+ .align 2
+ .globl ._tas
+._tas:
+ sync
+ mr r4, r3
+ addi r5,0,0x1
+_tas_1:
+ lwarx r3, 0, r4
+ cmpwi r3, 0
+ bne- _tas_2
+ stwcx. r5, 0, r4
+ bne- _tas_1
+_tas_2:
+ sync
+ blr
+
+ .align 2
+ .globl .executeonnewstack
+.executeonnewstack:
+ mr SP,r3 # change stacks
+ stwu LR,-16(SP) # save lr to aid the traceback
+ li r0,0
+ stw r0,20(SP)
+ mr r3,r5
+ mtctr r4
+ bctrl # tramp(arg)
+ br
+
+ .align 2
+ .globl .unlockandexit
+.unlockandexit:
+ li r0,0x0
+ stw r0,0(r3) # unlock
+ li r0,1 # sys exit; 234 is exit group
+ li r3,0 # exit status
+ sc
+ br
diff --git a/emu/AIX/cmd.c b/emu/AIX/cmd.c
new file mode 100644
index 00000000..ed4cabab
--- /dev/null
+++ b/emu/AIX/cmd.c
@@ -0,0 +1,213 @@
+#include <sys/types.h>
+#include <signal.h>
+#include <pwd.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+
+#include "dat.h"
+#include "fns.h"
+#include "error.h"
+
+enum
+{
+ Debug = 0
+};
+
+/*
+ * os-specific devcmd support.
+ * this version should be reasonably portable across Unix systems.
+ */
+typedef struct Targ Targ;
+struct Targ
+{
+ int fd[3]; /* fd[0] is standard input, fd[1] is standard output, fd[2] is standard error */
+ char** args;
+ char* dir;
+ int pid;
+ int wfd; /* child writes errors that occur after the fork or on exec */
+ int uid;
+ int gid;
+};
+
+extern int gidnobody;
+extern int uidnobody;
+
+static int
+childproc(Targ *t)
+{
+ int i, nfd;
+
+ if(Debug)
+ print("devcmd: '%s'", t->args[0]);
+
+ nfd = getdtablesize();
+ for(i = 0; i < nfd; i++)
+ if(i != t->fd[0] && i != t->fd[1] && i != t->fd[2] && i != t->wfd)
+ close(i);
+
+ dup2(t->fd[0], 0);
+ dup2(t->fd[1], 1);
+ dup2(t->fd[2], 2);
+ close(t->fd[0]);
+ close(t->fd[1]);
+ close(t->fd[2]);
+
+ /* should have an auth file to do host-specific authorisation? */
+ if(t->gid != -1){
+ if(setgid(t->gid) < 0 && getegid() == 0){
+ fprint(t->wfd, "can't set gid %d: %s", t->gid, strerror(errno));
+ _exit(1);
+ }
+ }
+
+ if(t->uid != -1){
+ if(setuid(t->uid) < 0 && geteuid() == 0){
+ fprint(t->wfd, "can't set uid %d: %s", t->uid, strerror(errno));
+ _exit(1);
+ }
+ }
+
+ if(t->dir != nil && chdir(t->dir) < 0){
+ fprint(t->wfd, "can't chdir to %s: %s", t->dir, strerror(errno));
+ _exit(1);
+ }
+
+ signal(SIGPIPE, SIG_DFL);
+
+ execvp(t->args[0], t->args);
+ if(Debug)
+ print("execvp: %s\n",strerror(errno));
+ fprint(t->wfd, "exec failed: %s", strerror(errno));
+
+ _exit(1);
+}
+
+void*
+oscmd(char **args, int nice, char *dir, int *fd)
+{
+ Targ *t;
+ int r, fd0[2], fd1[2], fd2[2], wfd[2], n, pid;
+
+ t = mallocz(sizeof(*t), 1);
+ if(t == nil)
+ return nil;
+
+ fd0[0] = fd0[1] = -1;
+ fd1[0] = fd1[1] = -1;
+ fd2[0] = fd2[1] = -1;
+ wfd[0] = wfd[1] = -1;
+ if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(fd2) < 0 || pipe(wfd) < 0)
+ goto Error;
+ if(fcntl(wfd[1], F_SETFD, FD_CLOEXEC) < 0) /* close on exec to give end of file on success */
+ goto Error;
+
+ t->fd[0] = fd0[0];
+ t->fd[1] = fd1[1];
+ t->fd[2] = fd2[1];
+ t->wfd = wfd[1];
+ t->args = args;
+ t->dir = dir;
+ t->gid = up->env->gid;
+ if(t->gid == -1)
+ t->gid = gidnobody;
+ t->uid = up->env->uid;
+ if(t->uid == -1)
+ t->uid = uidnobody;
+
+ signal(SIGCHLD, SIG_DFL);
+ switch(pid = fork()) {
+ case -1:
+ goto Error;
+ case 0:
+ setpgid(0, getpid());
+ if(nice)
+ oslopri();
+ childproc(t);
+ _exit(1);
+ default:
+ t->pid = pid;
+ if(Debug)
+ print("cmd pid %d\n", t->pid);
+ break;
+ }
+
+ close(fd0[0]);
+ close(fd1[1]);
+ close(fd2[1]);
+ close(wfd[1]);
+
+ n = read(wfd[0], up->genbuf, sizeof(up->genbuf)-1);
+ close(wfd[0]);
+ if(n > 0){
+ close(fd0[1]);
+ close(fd1[0]);
+ close(fd2[0]);
+ free(t);
+ up->genbuf[n] = 0;
+ if(Debug)
+ print("oscmd: bad exec: %q\n", up->genbuf);
+ error(up->genbuf);
+ return nil;
+ }
+
+ fd[0] = fd0[1];
+ fd[1] = fd1[0];
+ fd[2] = fd2[0];
+ return t;
+
+Error:
+ r = errno;
+ if(Debug)
+ print("oscmd: %q\n",strerror(r));
+ close(fd0[0]);
+ close(fd0[1]);
+ close(fd1[0]);
+ close(fd1[1]);
+ close(fd2[0]);
+ close(fd2[1]);
+ close(wfd[0]);
+ close(wfd[1]);
+ error(strerror(r));
+ return nil;
+}
+
+int
+oscmdkill(void *a)
+{
+ Targ *t = a;
+
+ if(Debug)
+ print("kill: %d\n", t->pid);
+ return kill(-t->pid, SIGTERM);
+}
+
+int
+oscmdwait(void *a, char *buf, int n)
+{
+ Targ *t = a;
+ int s;
+
+ if(waitpid(t->pid, &s, 0) == -1){
+ if(Debug)
+ print("wait error: %d [in %d] %q\n", t->pid, getpid(), strerror(errno));
+ return -1;
+ }
+ if(WIFEXITED(s)){
+ if(WEXITSTATUS(s) == 0)
+ return snprint(buf, n, "%d 0 0 0 ''", t->pid);
+ return snprint(buf, n, "%d 0 0 0 'exit: %d'", t->pid, WEXITSTATUS(s));
+ }
+ if(WIFSIGNALED(s)){
+ if(WTERMSIG(s) == SIGTERM || WTERMSIG(s) == SIGKILL)
+ return snprint(buf, n, "%d 0 0 0 killed", t->pid);
+ return snprint(buf, n, "%d 0 0 0 'signal: %d'", t->pid, WTERMSIG(s));
+ }
+ return snprint(buf, n, "%d 0 0 0 'odd status: 0x%x'", t->pid, s);
+}
+
+void
+oscmdfree(void *a)
+{
+ free(a);
+}
diff --git a/emu/AIX/deveia.c b/emu/AIX/deveia.c
new file mode 100644
index 00000000..3e00ca3f
--- /dev/null
+++ b/emu/AIX/deveia.c
@@ -0,0 +1,40 @@
+/*
+ * AIX serial port definitions
+ */
+
+static char *sysdev[] = {
+ "/dev/tty0",
+ "/dev/tty1",
+ "/dev/tty2",
+ "/dev/tty3",
+ "/dev/tty4",
+ "/dev/tty5",
+ "/dev/tty6",
+ "/dev/tty7",
+};
+
+#include <sys/ioctl.h>
+#include "deveia-posix.c"
+#include "deveia-bsd.c"
+
+
+static struct tcdef_t bps[] = {
+ {0, B0},
+ {50, B50},
+ {75, B75},
+ {110, B110},
+ {134, B134},
+ {150, B150},
+ {200, B200},
+ {300, B300},
+ {600, B600},
+ {1200, B1200},
+ {1800, B1800},
+ {2400, B2400},
+ {4800, B4800},
+ {9600, B9600},
+ {19200, B19200},
+ {38400, B38400},
+ {-1, -1}
+};
+
diff --git a/emu/AIX/devfs.c b/emu/AIX/devfs.c
new file mode 100644
index 00000000..194c1090
--- /dev/null
+++ b/emu/AIX/devfs.c
@@ -0,0 +1,7 @@
+#include "devfs-posix.c"
+
+static vlong
+osdisksize(int fd)
+{
+ return 0;
+}
diff --git a/emu/AIX/emu b/emu/AIX/emu
new file mode 100644
index 00000000..43f6e128
--- /dev/null
+++ b/emu/AIX/emu
@@ -0,0 +1,104 @@
+dev
+ root
+ cons
+ env
+ mnt
+ pipe
+ prog
+ prof
+ srv
+ dup
+ ssl
+ cap
+ fs
+ cmd cmd
+ indir
+
+ draw win-x11a
+ pointer
+ snarf
+
+ ip ipif6-posix ipaux
+ eia
+ mem
+
+lib
+ interp
+ tk
+ freetype
+ math
+ draw
+
+ memlayer
+ memdraw
+ keyring
+ sec
+ mp
+
+ 9
+
+link
+
+mod
+ sys
+ draw
+
+ tk
+ math
+ srv srv
+ keyring
+ crypt
+ ipints
+ loader
+ freetype
+
+port
+ alloc
+ cache
+ chan
+ dev
+ devtab
+
+ dial
+ dis
+ discall
+ env
+ error
+ errstr
+ exception
+ exportfs
+ inferno
+ latin1
+ main
+ parse
+ pgrp
+ print
+ proc
+ qio
+ random
+ sysfile
+ uqid
+
+code
+
+init
+ emuinit
+
+root
+ /dev /
+ /fd /
+ /prog /
+ /prof /
+ /net /
+ /net.alt /
+ /chan /
+ /nvfs /
+ /env /
+# /dis
+# /n
+# /icons
+# /osinit.dis
+# /dis/emuinit.dis
+# /dis/lib/auth.dis
+# /dis/lib/ssl.dis
+# /n/local /
diff --git a/emu/AIX/emu-g b/emu/AIX/emu-g
new file mode 100644
index 00000000..41831fa9
--- /dev/null
+++ b/emu/AIX/emu-g
@@ -0,0 +1,100 @@
+env
+ X11LIBS=
+dev
+ root
+ cons
+ env
+ mnt
+ pipe
+ prog
+ prof
+ srv
+ dup
+ ssl
+ cap
+ fs
+ cmd cmd
+ indir
+
+ ip ipif6-posix ipaux
+ eia
+ mem
+
+lib
+ interp
+ math
+ keyring
+ sec
+ mp
+
+ 9
+
+link
+
+mod
+ sys
+ math
+ srv srv
+ keyring
+ crypt
+ ipints
+ loader
+
+port
+ alloc
+ cache
+ chan
+ dev
+ devtab
+
+ dial
+ dis
+ discall
+ env
+ error
+ errstr
+ exception
+ exportfs
+ inferno
+ latin1
+ main
+ parse
+ pgrp
+ print
+ proc
+ qio
+ random
+ sysfile
+ uqid
+
+code
+ void setpointer(int x, int y){USED(x); USED(y);}
+ ulong strtochan(char *s){USED(s); return ~0;}
+
+init
+ emuinit
+
+root
+ /dev /
+ /fd /
+ /prog /
+ /prof /
+ /net /
+ /net.alt /
+ /chan /
+ /nvfs /
+ /env /
+# /chan
+# /dev
+# /dis
+# /env
+# /n
+# /net
+# /nvfs /
+# /prog
+# /icons
+# /osinit.dis
+# /dis/emuinit.dis
+# /dis/lib/auth.dis
+# /dis/lib/ssl.dis
+# /n/local /
diff --git a/emu/AIX/mkfile b/emu/AIX/mkfile
new file mode 100644
index 00000000..2089bd28
--- /dev/null
+++ b/emu/AIX/mkfile
@@ -0,0 +1,52 @@
+SYSTARG=AIX
+<../../mkconfig
+SYSTARG=AIX
+
+#Configurable parameters
+
+CONF=emu #default configuration
+CONFLIST=emu
+CLEANCONFLIST=
+
+INSTALLDIR=$ROOT/$SYSTARG/$OBJTYPE/bin #path of directory where kernel is installed
+
+#end configurable parameters
+
+X11LIBS= -lX11 -lXext
+
+<$ROOT/mkfiles/mkfile-$SYSTARG-$OBJTYPE #set vars based on target system
+
+<| $SHELLNAME ../port/mkdevlist $CONF #sets $IP, $DEVS, $PORT, $LIBS
+<mkfile-$OBJTYPE
+
+OBJ=\
+ asm-$OBJTYPE.$O\
+ $ARCHFILES\
+ os.$O\
+ kproc-pthreads.$O\
+ segflush-$OBJTYPE.$O\
+ $CONF.root.$O\
+ lock.$O\
+ $DEVS\
+ $PORT\
+
+LIBNAMES=${LIBS:%=lib%.a}
+
+HFILES=\
+
+CFLAGS='-DROOT="'$ROOT'"' -DEMU -I. -I../port -I$ROOT/$SYSTARG/$OBJTYPE/include -I$ROOT/include -I$ROOT/libinterp $CTHREADFLAGS $CFLAGS $EMUOPTIONS
+SYSLIBS= $X11LIBS -lm -lpthread
+KERNDATE=`{$NDATE}
+
+default:V: $O.$CONF
+
+$O.$CONF: $OBJ $CONF.c $CONF.root.h $LIBNAMES
+ $CC $CFLAGS '-DKERNDATE='$KERNDATE $CONF.c
+ $LD $LDFLAGS -o $target $OBJ $CONF.$O $LIBFILES $SYSLIBS
+
+install:V: $O.$CONF
+ cp $O.$CONF $INSTALLDIR/$CONF
+
+<../port/portmkfile
+
+devfs.$O: ../port/devfs-posix.c
diff --git a/emu/AIX/mkfile-power b/emu/AIX/mkfile-power
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/emu/AIX/mkfile-power
diff --git a/emu/AIX/os.c b/emu/AIX/os.c
new file mode 100644
index 00000000..83bf0901
--- /dev/null
+++ b/emu/AIX/os.c
@@ -0,0 +1,300 @@
+#include <sys/types.h>
+#include <time.h>
+#include <termios.h>
+#include <signal.h>
+#include <pwd.h>
+#include <sched.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+
+#include <stdint.h>
+
+#include "dat.h"
+#include "fns.h"
+#include "error.h"
+
+#include <semaphore.h>
+
+#include <raise.h>
+
+enum
+{
+ DELETE = 0x7f,
+ CTRLC = 'C'-'@',
+ NSTACKSPERALLOC = 16,
+ X11STACK= 256*1024
+};
+char *hosttype = "Linux";
+
+typedef sem_t Sem;
+
+extern int dflag;
+
+int gidnobody = -1;
+int uidnobody = -1;
+static struct termios tinit;
+
+static void
+sysfault(char *what, void *addr)
+{
+ char buf[64];
+
+ snprint(buf, sizeof(buf), "sys: %s%#p", what, addr);
+ disfault(nil, buf);
+}
+
+static void
+trapILL(int signo, siginfo_t *si, void *a)
+{
+ USED(signo);
+ USED(a);
+ sysfault("illegal instruction pc=", si->si_addr);
+}
+
+static int
+isnilref(siginfo_t *si)
+{
+ return si != 0 && (si->si_addr == (void*)~(uintptr_t)0 || (uintptr_t)si->si_addr < 512);
+}
+
+static void
+trapmemref(int signo, siginfo_t *si, void *a)
+{
+ USED(a); /* ucontext_t*, could fetch pc in machine-dependent way */
+ if(isnilref(si))
+ disfault(nil, exNilref);
+ else if(signo == SIGBUS)
+ sysfault("bad address addr=", si->si_addr); /* eg, misaligned */
+ else
+ sysfault("segmentation violation addr=", si->si_addr);
+}
+
+static void
+trapFPE(int signo, siginfo_t *si, void *a)
+{
+ char buf[64];
+
+ USED(signo);
+ USED(a);
+ snprint(buf, sizeof(buf), "sys: fp: exception status=%.4lux pc=%#p", getfsr(), si->si_addr);
+ disfault(nil, buf);
+}
+
+static void
+trapUSR1(int signo)
+{
+ int intwait;
+
+ USED(signo);
+
+ intwait = up->intwait;
+ up->intwait = 0; /* clear it to let proc continue in osleave */
+
+ if(up->type != Interp) /* Used to unblock pending I/O */
+ return;
+
+ if(intwait == 0) /* Not posted so it's a sync error */
+ disfault(nil, Eintr); /* Should never happen */
+}
+
+void
+oslongjmp(void *regs, osjmpbuf env, int val)
+{
+ USED(regs);
+ siglongjmp(env, val);
+}
+
+static void
+termset(void)
+{
+ struct termios t;
+
+ tcgetattr(0, &t);
+ tinit = t;
+ t.c_lflag &= ~(ICANON|ECHO|ISIG);
+ t.c_cc[VMIN] = 1;
+ t.c_cc[VTIME] = 0;
+ tcsetattr(0, TCSANOW, &t);
+}
+
+static void
+termrestore(void)
+{
+ tcsetattr(0, TCSANOW, &tinit);
+}
+
+void
+cleanexit(int x)
+{
+ USED(x);
+
+ if(up->intwait) {
+ up->intwait = 0;
+ return;
+ }
+
+ if(dflag == 0)
+ termrestore();
+
+ kill(0, SIGKILL);
+ exit(0);
+}
+
+void
+osreboot(char *file, char **argv)
+{
+ if(dflag == 0)
+ termrestore();
+ execvp(file, argv);
+ error("reboot failure");
+}
+
+void
+libinit(char *imod)
+{
+ struct sigaction act;
+ struct passwd *pw;
+ Proc *p;
+ char sys[64];
+
+ setsid();
+
+ gethostname(sys, sizeof(sys));
+ kstrdup(&ossysname, sys);
+ pw = getpwnam("nobody");
+ if(pw != nil) {
+ uidnobody = pw->pw_uid;
+ gidnobody = pw->pw_gid;
+ }
+
+ if(dflag == 0)
+ termset();
+
+ memset(&act, 0, sizeof(act));
+ act.sa_handler = trapUSR1;
+ sigaction(SIGUSR1, &act, nil);
+
+ act.sa_handler = SIG_IGN;
+ sigaction(SIGCHLD, &act, nil);
+
+ /*
+ * For the correct functioning of devcmd in the
+ * face of exiting slaves
+ */
+ signal(SIGPIPE, SIG_IGN);
+ if(signal(SIGTERM, SIG_IGN) != SIG_IGN)
+ signal(SIGTERM, cleanexit);
+ if(signal(SIGINT, SIG_IGN) != SIG_IGN)
+ signal(SIGINT, cleanexit);
+
+ if(sflag == 0) {
+ act.sa_flags = SA_SIGINFO;
+ act.sa_sigaction = trapILL;
+ sigaction(SIGILL, &act, nil);
+ act.sa_sigaction = trapFPE;
+ sigaction(SIGFPE, &act, nil);
+ act.sa_sigaction = trapmemref;
+ sigaction(SIGBUS, &act, nil);
+ sigaction(SIGSEGV, &act, nil);
+ act.sa_flags &= ~SA_SIGINFO;
+ }
+
+ p = newproc();
+ kprocinit(p);
+
+ pw = getpwuid(getuid());
+ if(pw != nil)
+ kstrdup(&eve, pw->pw_name);
+ else
+ print("cannot getpwuid\n");
+
+ p->env->uid = getuid();
+ p->env->gid = getgid();
+
+ emuinit(imod);
+}
+
+int
+readkbd(void)
+{
+ int n;
+ char buf[1];
+
+ n = read(0, buf, sizeof(buf));
+ if(n < 0)
+ print("keyboard close (n=%d, %s)\n", n, strerror(errno));
+ if(n <= 0)
+ pexit("keyboard thread", 0);
+
+ switch(buf[0]) {
+ case '\r':
+ buf[0] = '\n';
+ break;
+ case DELETE:
+ buf[0] = 'H' - '@';
+ break;
+ case CTRLC:
+ cleanexit(0);
+ break;
+ }
+ return buf[0];
+}
+
+/*
+ * Return an abitrary millisecond clock time
+ */
+long
+osmillisec(void)
+{
+ static long sec0 = 0, usec0;
+ struct timeval t;
+
+ if(gettimeofday(&t,(struct timezone*)0)<0)
+ return 0;
+
+ if(sec0 == 0) {
+ sec0 = t.tv_sec;
+ usec0 = t.tv_usec;
+ }
+ return (t.tv_sec-sec0)*1000+(t.tv_usec-usec0+500)/1000;
+}
+
+/*
+ * Return the time since the epoch in nanoseconds and microseconds
+ * The epoch is defined at 1 Jan 1970
+ */
+vlong
+osnsec(void)
+{
+ struct timeval t;
+
+ gettimeofday(&t, nil);
+ return (vlong)t.tv_sec*1000000000L + t.tv_usec*1000;
+}
+
+vlong
+osusectime(void)
+{
+ struct timeval t;
+
+ gettimeofday(&t, nil);
+ return (vlong)t.tv_sec * 1000000 + t.tv_usec;
+}
+
+int
+osmillisleep(ulong milsec)
+{
+ struct timespec time;
+
+ time.tv_sec = milsec/1000;
+ time.tv_nsec= (milsec%1000)*1000000;
+ nanosleep(&time, NULL);
+ return 0;
+}
+
+int
+limbosleep(ulong milsec)
+{
+ return osmillisleep(milsec);
+}
diff --git a/emu/AIX/segflush-power.c b/emu/AIX/segflush-power.c
new file mode 100644
index 00000000..5029b0aa
--- /dev/null
+++ b/emu/AIX/segflush-power.c
@@ -0,0 +1,33 @@
+#include <sys/types.h>
+
+#include "dat.h"
+
+
+/*
+ * from geoff collyer's port
+ * invalidate instruction cache and write back data cache from a to a+n-1,
+ * at least.
+ */
+int
+segflush(void *a, ulong n)
+{
+ ulong *p;
+
+ // cache blocks are often eight words (32 bytes) long, sometimes 16 bytes.
+ // need to determine it dynamically?
+ for (p = (ulong *)((ulong)a & ~7UL); (char *)p < (char *)a + n; p++)
+ __asm__("dcbst 0,r0\n\t" // not dcbf, which writes back, then invalidates
+ "icbi 0,r0\n\t"
+ : // no output
+ : "ar" (p)
+ );
+ __asm__("sync\n\t"
+ : // no output
+ :
+ );
+ __asm__("isync\n\t"
+ : // no output
+ :
+ );
+ return 0;
+}
diff --git a/emu/port/devfs-posix.c b/emu/port/devfs-posix.c
index 02c842f4..14cce877 100644
--- a/emu/port/devfs-posix.c
+++ b/emu/port/devfs-posix.c
@@ -9,7 +9,7 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/fcntl.h>
+#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <utime.h>
diff --git a/emu/port/win-x11a.c b/emu/port/win-x11a.c
index 3670b260..569287b6 100644
--- a/emu/port/win-x11a.c
+++ b/emu/port/win-x11a.c
@@ -304,7 +304,7 @@ copy32to32(Rectangle r)
lp = dp + width;
while(dp < lp){
v = *dp++;
- w = infernortox11[(v>>16)&0xff]<<16|infernogtox11[(v>>8)&0xff]<<8|infernobtox11[(v>>0)&0xff]<<0;
+ w = v&(0xff<<24)|infernortox11[(v>>16)&0xff]<<16|infernogtox11[(v>>8)&0xff]<<8|infernobtox11[(v>>0)&0xff]<<0;
*wp++ = w;
}
dp += dx;
diff --git a/lib/emptydirs b/lib/emptydirs
index 9fbf988d..10234dc1 100644
--- a/lib/emptydirs
+++ b/lib/emptydirs
@@ -1,3 +1,4 @@
+AIX/power/lib
FreeBSD/386/lib
Inferno/386/bin
Inferno/386/lib
diff --git a/lib9/getcallerpc-AIX-power.c b/lib9/getcallerpc-AIX-power.c
new file mode 100644
index 00000000..4a4e4fb5
--- /dev/null
+++ b/lib9/getcallerpc-AIX-power.c
@@ -0,0 +1,12 @@
+#include <lib9.h>
+
+ulong
+getcallerpc(void *x)
+{
+ulong *lp;
+
+ lp = x;
+
+ return lp[-1];
+}
+
diff --git a/lib9/setfcr-AIX-power.c b/lib9/setfcr-AIX-power.c
new file mode 100644
index 00000000..60939a27
--- /dev/null
+++ b/lib9/setfcr-AIX-power.c
@@ -0,0 +1,39 @@
+#include "lib9.h"
+
+ulong
+getfcr(void)
+{
+ double fpscr;
+
+ fpscr = __readflm();
+ return ((ulong*)&fpscr)[1];
+}
+
+ulong
+getfsr(void)
+{
+ double fpscr;
+
+ fpscr = __readflm();
+ return ((ulong*)&fpscr)[1];
+}
+
+void
+setfsr(ulong fsr)
+{
+ double fpscr;
+
+ fpscr = __readflm();
+ (((ulong*)&fpscr)[1]) = fsr;
+ __setflm(fpscr);
+}
+
+void
+setfcr(ulong fcr)
+{
+ double fpscr;
+
+ fpscr = __readflm();
+ (((ulong*)&fpscr)[1]) = fcr;
+ __setflm(fpscr);
+}
diff --git a/libmath/FPcontrol-AIX.c b/libmath/FPcontrol-AIX.c
new file mode 100644
index 00000000..180c8bde
--- /dev/null
+++ b/libmath/FPcontrol-AIX.c
@@ -0,0 +1,77 @@
+#include "lib9.h"
+#include "mathi.h"
+
+void
+FPinit(void)
+{
+ setfsr(0); /* Clear pending exceptions */
+ setfcr(FPPDBL|FPRNR|FPINVAL|FPZDIV|FPUNFL|FPOVFL);
+}
+
+ulong
+getFPstatus(void)
+{
+ ulong fsr = 0, fsr9 = getfsr();
+ /* on specific machines, could be table lookup */
+ if(fsr9&FPAINEX) fsr |= INEX;
+ if(fsr9&FPAOVFL) fsr |= OVFL;
+ if(fsr9&FPAUNFL) fsr |= UNFL;
+ if(fsr9&FPAZDIV) fsr |= ZDIV;
+ if(fsr9&FPAINVAL) fsr |= INVAL;
+ return fsr;
+}
+
+ulong
+FPstatus(ulong fsr, ulong mask)
+{
+ ulong fsr9 = 0;
+ ulong old = getFPstatus();
+ fsr = (fsr&mask) | (old&~mask);
+ if(fsr&INEX) fsr9 |= FPAINEX;
+ if(fsr&OVFL) fsr9 |= FPAOVFL;
+ if(fsr&UNFL) fsr9 |= FPAUNFL;
+ if(fsr&ZDIV) fsr9 |= FPAZDIV;
+ if(fsr&INVAL) fsr9 |= FPAINVAL;
+ setfsr(fsr9);
+ return(old&mask);
+}
+
+ulong
+getFPcontrol(void)
+{
+ ulong fcr = 0, fcr9 = getfcr();
+ switch(fcr9&FPRMASK){
+ case FPRNR: fcr = RND_NR; break;
+ case FPRNINF: fcr = RND_NINF; break;
+ case FPRPINF: fcr = RND_PINF; break;
+ case FPRZ: fcr = RND_Z; break;
+ }
+ if(fcr9&FPINEX) fcr |= INEX;
+ if(fcr9&FPOVFL) fcr |= OVFL;
+ if(fcr9&FPUNFL) fcr |= UNFL;
+ if(fcr9&FPZDIV) fcr |= ZDIV;
+ if(fcr9&FPINVAL) fcr |= INVAL;
+ return fcr;
+}
+
+ulong
+FPcontrol(ulong fcr, ulong mask)
+{
+ ulong fcr9 = FPPDBL;
+ ulong old = getFPcontrol();
+ fcr = (fcr&mask) | (old&~mask);
+ if(fcr&INEX) fcr9 |= FPINEX;
+ if(fcr&OVFL) fcr9 |= FPOVFL;
+ if(fcr&UNFL) fcr9 |= FPUNFL;
+ if(fcr&ZDIV) fcr9 |= FPZDIV;
+ if(fcr&INVAL) fcr9 |= FPINVAL;
+ switch(fcr&RND_MASK){
+ case RND_NR: fcr9 |= FPRNR; break;
+ case RND_NINF: fcr9 |= FPRNINF; break;
+ case RND_PINF: fcr9 |= FPRPINF; break;
+ case RND_Z: fcr9 |= FPRZ; break;
+ }
+ setfcr(fcr9);
+ return(old&mask);
+}
+
diff --git a/libmemdraw/mkfile-AIX b/libmemdraw/mkfile-AIX
new file mode 100644
index 00000000..a83c8dfe
--- /dev/null
+++ b/libmemdraw/mkfile-AIX
@@ -0,0 +1 @@
+<mkfile-Inferno
diff --git a/libmemlayer/mkfile-AIX b/libmemlayer/mkfile-AIX
new file mode 100644
index 00000000..d772cd4e
--- /dev/null
+++ b/libmemlayer/mkfile-AIX
@@ -0,0 +1,4 @@
+#
+# System dependent objects for Posix model systems
+#
+SYSFILES=lalloc.$O
diff --git a/limbo/lex.c b/limbo/lex.c
index d75e28f2..c6af1988 100644
--- a/limbo/lex.c
+++ b/limbo/lex.c
@@ -1434,7 +1434,7 @@ allocmem(ulong n)
{
void *p;
- p = malloc(n);
+ p = malloc(n != 0? n: 1);
if(p == nil)
fatal("out of memory");
return p;
diff --git a/makemk-AIX.sh b/makemk-AIX.sh
new file mode 100644
index 00000000..51745b1d
--- /dev/null
+++ b/makemk-AIX.sh
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+# this file is used only to bootstrap mk onto a platform
+# that currently lacks a binary for mk. after that, mk can
+# look after itself.
+
+# support@vitanuova.com
+
+# change these defines as appropriate here or in mkconfig
+# ROOT should be the root of the Inferno tree
+ROOT=/usr/inferno
+SYSTARG=AIX
+OBJTYPE=power
+SYSTYPE=posix
+
+# if you have already changed mkconfig from the distribution, we'll use the definitions from that
+grep -s 'SYSTARG=Plan9' mkconfig || . ./mkconfig
+
+PLAT=$ROOT/$SYSTARG/$OBJTYPE
+
+# you might need to adjust the CC, LD, AR, and RANLIB definitions after this point
+CC="p xlc -g -O -qsuppress=1506-224 -c -I$PLAT/include -I$ROOT/include -I$ROOT/utils/include"
+LD="p xlc"
+AR="p ar crvs"
+RANLIB=":" # some systems still require `ranlib'
+
+error() {
+ echo $* >&2
+ exit 1
+}
+
+ofiles() {
+ echo $* | sed 's/\.c/.o/g'
+}
+
+p() {
+ echo $*
+ "$@"
+}
+
+# make sure we start off clean
+echo removing old libraries and binaries
+rm -f $PLAT/lib/*.a $PLAT/bin/*
+rm -f utils/cc/y.tab.?
+
+# ensure the output directories exist
+mkdir -p $PLAT/lib $PLAT/bin
+
+# libregexp
+cd $ROOT/utils/libregexp || error cannot find libregexp directory
+CFILES="regaux.c regcomp.c regerror.c regexec.c regsub.c rregexec.c rregsub.c"
+$CC $CFILES || error libregexp compilation failed
+$AR $PLAT/lib/libregexp.a `ofiles $CFILES` || error libregexp ar failed
+$RANLIB $PLAT/lib/libregexp.a || error libregexp ranlib failed
+
+# libbio
+cd $ROOT/libbio || error cannot find libbio directory
+$CC *.c || error libbio compilation failed
+$AR $PLAT/lib/libbio.a *.o || error libbio ar failed
+$RANLIB $PLAT/lib/libbio.a || error libbio ranlib failed
+
+# lib9
+cd $ROOT/lib9 || error cannot find lib9 directory
+CFILES="dirstat-$SYSTYPE.c rerrstr.c errstr-$SYSTYPE.c getuser-$SYSTYPE.c" # system specific
+CFILES="$CFILES charstod.c cleanname.c create.c dirwstat.c *print*.c *fmt*.c exits.c getfields.c pow10.c print.c qsort.c rune.c runestrlen.c seek.c strdup.c strtoll.c utflen.c utfrrune.c utfrune.c utf*.c *str*cpy*.c"
+$CC $CFILES || error lib9 compilation failed
+$AR $PLAT/lib/lib9.a `ofiles $CFILES` || error lib9 ar failed
+$RANLIB $PLAT/lib/lib9.a || error lib9 ranlib failed
+
+# mk itself
+cd $ROOT/utils/mk
+CFILES="Posix.c sh.c" # system specific
+CFILES="$CFILES arc.c archive-AIX.c bufblock.c env.c file.c graph.c job.c lex.c main.c match.c mk.c parse.c recipe.c rule.c run.c shprint.c symtab.c var.c varsub.c word.c"
+$CC $CFILES || error mk compilation failed
+$LD -o mk `ofiles $CFILES` $PLAT/lib/libregexp.a $PLAT/lib/libbio.a $PLAT/lib/lib9.a || error mk link failed
+cp mk $PLAT/bin || error mk binary install failed
+
+echo mk binary built successfully!
diff --git a/mkconfig b/mkconfig
index 08fc3a8c..f189dca6 100644
--- a/mkconfig
+++ b/mkconfig
@@ -14,8 +14,8 @@ TKSTYLE=std
#
# Except for building kernels, SYSTARG must always be the same as SYSHOST
#
-SYSHOST=Plan9 # build system OS type (Hp, Inferno, Irix, Linux, MacOSX, Nt, Plan9, Solaris)
-SYSTARG=$SYSHOST # target system OS type (Hp, Inferno, Irix, Linux, Nt, Plan9, Solaris)
+SYSHOST=Plan9 # build system OS type (AIX, Hp, Inferno, Irix, Linux, MacOSX, Nt, Plan9, Solaris)
+SYSTARG=$SYSHOST # target system OS type (AIX, Hp, Inferno, Irix, Linux, Nt, Plan9, Solaris)
#
# specify the architecture of the target system - Plan 9 imports it from the
diff --git a/mkfiles/mkfile-AIX-power b/mkfiles/mkfile-AIX-power
new file mode 100644
index 00000000..3faf4286
--- /dev/null
+++ b/mkfiles/mkfile-AIX-power
@@ -0,0 +1,25 @@
+TARGMODEL= Posix
+TARGSHTYPE= sh
+CPUS= power
+
+O= o
+OS= o
+
+AR= ar
+ARFLAGS= crvs
+
+AS= xlc -c
+ASFLAGS=
+
+CC= xlc_r -c
+CFLAGS= -q32 -g -O -qsuppress=1506-224\
+ -I$ROOT/$SYSTARG/$OBJTYPE/include\
+ -I$ROOT/include\
+
+ANSICPP=
+LD= xlc_r
+LDFLAGS= -bmaxdata:0x80000000
+SYSLIBS= -lm
+
+YACC= iyacc
+YFLAGS= -d
diff --git a/mkfiles/mkhost-AIX b/mkfiles/mkhost-AIX
new file mode 100644
index 00000000..3c1a86c3
--- /dev/null
+++ b/mkfiles/mkhost-AIX
@@ -0,0 +1,14 @@
+
+# Variables for host system type = AIX
+
+SHELLTYPE= sh
+SHELLNAME= /bin/sh
+HOSTMODEL= Posix
+OSTARG= os
+
+DATA2S= data2s
+NDATE= ndate
+KSIZE= ksize
+AWK= awk
+
+MKAR= archive-$SYSTARG
diff --git a/utils/mk/archive-AIX.c b/utils/mk/archive-AIX.c
new file mode 100644
index 00000000..a4327a96
--- /dev/null
+++ b/utils/mk/archive-AIX.c
@@ -0,0 +1,203 @@
+#include "mk.h"
+#include <ar.h>
+
+static int dolong;
+
+static void atimes(char *);
+static char *split(char*, char**);
+
+long
+atimeof(int force, char *name)
+{
+ Symtab *sym;
+ long t;
+ char *archive, *member, buf[512];
+
+ archive = split(name, &member);
+ if(archive == 0)
+ Exit();
+
+ t = mtime(archive);
+ sym = symlook(archive, S_AGG, 0);
+ if(sym){
+ if(force || (t > (long)sym->value)){
+ atimes(archive);
+ sym->value = (void *)t;
+ }
+ }
+ else{
+ atimes(archive);
+ /* mark the aggegate as having been done */
+ symlook(strdup(archive), S_AGG, "")->value = (void *)t;
+ }
+ snprint(buf, sizeof(buf), "%s(%s)", archive, member);
+ sym = symlook(buf, S_TIME, 0);
+ if (sym)
+ return (long)sym->value; /* uggh */
+ return 0;
+}
+
+void
+atouch(char *name)
+{
+ char *archive, *member;
+ int fd, i, namelen;
+ struct fl_hdr g;
+ struct ar_hdr h;
+ long t;
+ char memname[256];
+
+ archive = split(name, &member);
+ if(archive == 0)
+ Exit();
+
+ fd = open(archive, ORDWR);
+ if(fd < 0){
+ fd = create(archive, OWRITE, 0666);
+ if(fd < 0){
+ perror(archive);
+ Exit();
+ }
+ write(fd, ARMAG, SARMAG);
+ for(i = 0; i < 6; i++)
+ fprint(fd, "%-20ld", 0);
+ }
+ if(symlook(name, S_TIME, 0)){
+ /* hoon off and change it in situ */
+ LSEEK(fd, 0, 0);
+ if(read(fd, &g, SAR_FLHDR) != SAR_FLHDR){
+ close(fd);
+ return;
+ }
+ t = atol(g.fstmoff);
+ if(t == 0){
+ close(fd);
+ return;
+ }
+ for(;;){
+ LSEEK(fd, t, 0);
+ if(read(fd, (char *)&h, SAR_HDR) != SAR_HDR)
+ break;
+
+ namelen = atol(h.namlen);
+ if(namelen == 0 || namelen >= sizeof memname){
+ namelen = 0;
+ goto skip;
+ }
+ if(read(fd, memname, namelen) != namelen)
+ break;
+ memname[namelen] = 0;
+
+ if(strcmp(member, memname) == 0){
+ snprint(h.date, sizeof(h.date), "%-12ld", time(0));
+ LSEEK(fd, t, 0);
+ write(fd, (char *)&h, SAR_HDR);
+ break;
+ }
+ skip:
+ t = atol(h.nxtmem);
+ if(t == 0)
+ break;
+ }
+ }
+ close(fd);
+}
+
+static void
+atimes(char *ar)
+{
+ struct fl_hdr g;
+ struct ar_hdr h;
+ long o, t;
+ int fd, i, namelen;
+ char buf[2048], *p, *strings;
+ char name[1024];
+ Symtab *sym;
+
+ strings = nil;
+ fd = open(ar, OREAD);
+ if(fd < 0)
+ return;
+
+ if(read(fd, &g, SAR_FLHDR) != SAR_FLHDR){
+ close(fd);
+ return;
+ }
+ o = atol(g.fstmoff);
+ if(o == 0){
+ close(fd);
+ return;
+ }
+ for(;;){
+ LSEEK(fd, o, 0);
+ if(read(fd, (char *)&h, SAR_HDR) != SAR_HDR)
+ break;
+
+ t = atol(h.date);
+ if(t == 0) /* as it sometimes happens; thanks ken */
+ t = 1;
+
+ namelen = atol(h.namlen);
+ if(namelen == 0 || namelen >= sizeof name){
+ namelen = 0;
+ goto skip;
+ }
+ if(read(fd, name, namelen) != namelen)
+ break;
+ name[namelen] = 0;
+
+ snprint(buf, sizeof buf, "%s(%s)", ar, name);
+ sym = symlook(strdup(buf), S_TIME, (void *)t);
+ sym->value = (void *)t;
+ skip:
+ o = atol(h.nxtmem);
+ if(o == 0)
+ break;
+ }
+ close(fd);
+ free(strings);
+}
+
+static int
+type(char *file)
+{
+ int fd;
+ char buf[SARMAG];
+
+ fd = open(file, OREAD);
+ if(fd < 0){
+ if(symlook(file, S_BITCH, 0) == 0){
+ Bprint(&bout, "%s doesn't exist: assuming it will be an archive\n", file);
+ symlook(file, S_BITCH, (void *)file);
+ }
+ return 1;
+ }
+ if(read(fd, buf, SARMAG) != SARMAG){
+ close(fd);
+ return 0;
+ }
+ close(fd);
+ return strncmp(ARMAG, buf, SARMAG) == 0;
+}
+
+static char*
+split(char *name, char **member)
+{
+ char *p, *q;
+
+ p = strdup(name);
+ q = utfrune(p, '(');
+ if(q){
+ *q++ = 0;
+ if(member)
+ *member = q;
+ q = utfrune(q, ')');
+ if (q)
+ *q = 0;
+ if(type(p))
+ return p;
+ free(p);
+ fprint(2, "mk: '%s' is not an archive\n", name);
+ }
+ return 0;
+}
diff --git a/utils/mk/mkfile b/utils/mk/mkfile
index 9d4deea8..2aecf006 100644
--- a/utils/mk/mkfile
+++ b/utils/mk/mkfile
@@ -1,9 +1,11 @@
+MKAR= archive
+
<../../mkconfig
TARG=mk
OFILES= arc.$O\
- archive.$O\
+ $MKAR.$O\
bufblock.$O\
env.$O\
file.$O\