diff options
| author | Charles.Forsyth <devnull@localhost> | 2009-04-01 22:54:06 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2009-04-01 22:54:06 +0000 |
| commit | 4eb166cf184c1f102fb79e31b1465ea3e2021c39 (patch) | |
| tree | 0e1bd8c059324d5cb99d625a67398e48a9ffce95 | |
| parent | a9b1d9c7f57ec21ff8be147f5c949966b966e519 (diff) | |
20090401-2350
| -rw-r--r-- | Inferno/spim/include/lib9.h | 8 | ||||
| -rw-r--r-- | Inferno/spim/include/u.h | 56 | ||||
| -rw-r--r-- | Linux/spim/include/fpuctl.h | 65 | ||||
| -rw-r--r-- | Linux/spim/include/lib9.h | 494 | ||||
| -rw-r--r-- | emu/Linux/asm-spim.S | 70 | ||||
| -rw-r--r-- | lib9/getcallerpc-Linux-spim.S | 10 | ||||
| -rw-r--r-- | libdynld/dynld-spim.c | 22 | ||||
| -rw-r--r-- | libinterp/comp-mips.c | 95 | ||||
| -rw-r--r-- | libinterp/comp-spim.c | 1 | ||||
| -rw-r--r-- | libkern/frexp-mips.c | 3 | ||||
| -rw-r--r-- | libkern/frexp-spim.c | 79 | ||||
| -rw-r--r-- | libkern/getfcr-spim.s | 1 | ||||
| -rw-r--r-- | libkern/memmove-spim.s | 1 | ||||
| -rw-r--r-- | libkern/memset-spim.s | 1 | ||||
| -rw-r--r-- | libkern/nan-mips.c | 3 | ||||
| -rw-r--r-- | libkern/nan-spim.c | 69 | ||||
| -rw-r--r-- | libkern/strchr-spim.c | 18 | ||||
| -rw-r--r-- | libkern/strchr-spim.s | 1 | ||||
| -rw-r--r-- | libkern/vlop-spim.s | 17 | ||||
| -rw-r--r-- | libkern/vlrt-mips.c | 7 | ||||
| -rw-r--r-- | libkern/vlrt-spim.c | 711 | ||||
| -rw-r--r-- | mkfiles/mkfile-Linux-spim | 29 |
22 files changed, 1706 insertions, 55 deletions
diff --git a/Inferno/spim/include/lib9.h b/Inferno/spim/include/lib9.h new file mode 100644 index 00000000..649829be --- /dev/null +++ b/Inferno/spim/include/lib9.h @@ -0,0 +1,8 @@ +#include <u.h> +#include <kern.h> + +/* + * Extensions for Inferno to basic libc.h + */ + +#define __LITTLE_ENDIAN /* math/dtoa.c; longs in MIPS doubles are little-endian in LE mode */ diff --git a/Inferno/spim/include/u.h b/Inferno/spim/include/u.h new file mode 100644 index 00000000..8a57b3a2 --- /dev/null +++ b/Inferno/spim/include/u.h @@ -0,0 +1,56 @@ +#define nil ((void*)0) +typedef unsigned short ushort; +typedef unsigned char uchar; +typedef unsigned long ulong; +typedef unsigned int uint; +typedef signed char schar; +typedef long long vlong; +typedef unsigned long long uvlong; +typedef ushort Rune; +typedef union FPdbleword FPdbleword; +typedef long jmp_buf[2]; +#define JMPBUFSP 0 +#define JMPBUFPC 1 +#define JMPBUFDPC 0 +typedef unsigned int mpdigit; /* for /sys/include/mp.h */ +typedef unsigned int u32int; /* for /sys/include/libsec.h */ +typedef unsigned char u8int; +typedef unsigned short u16int; +typedef unsigned long uintptr; + +/* FCR */ +#define FPINEX (1<<7) +#define FPUNFL (1<<8) +#define FPOVFL (1<<9) +#define FPZDIV (1<<10) +#define FPINVAL (1<<11) +#define FPRNR (0<<0) +#define FPRZ (1<<0) +#define FPRPINF (2<<0) +#define FPRNINF (3<<0) +#define FPRMASK (3<<0) +#define FPPEXT 0 +#define FPPSGL 0 +#define FPPDBL 0 +#define FPPMASK 0 +/* FSR */ +#define FPAINEX (1<<2) +#define FPAOVFL (1<<4) +#define FPAUNFL (1<<3) +#define FPAZDIV (1<<5) +#define FPAINVAL (1<<6) +union FPdbleword +{ + double x; + struct { /* little endian */ + ulong lo; + ulong hi; + }; +}; + +/* stdarg */ +typedef char *va_list; +#define va_start(list, start) list = (sizeof(start)<4 ? (char *)((int *)&(start)+1) : \ +(char *)(&(start)+1)) +#define va_arg(list, mode) ((mode*)(list += sizeof(mode)))[-1] +#define va_end(list) diff --git a/Linux/spim/include/fpuctl.h b/Linux/spim/include/fpuctl.h new file mode 100644 index 00000000..ad5dcba7 --- /dev/null +++ b/Linux/spim/include/fpuctl.h @@ -0,0 +1,65 @@ +/* FCR */ +#define FCRBITS 0x00000F83 +#define FPINEX (1<<7) +#define FPUNFL (1<<8) +#define FPOVFL (1<<9) +#define FPZDIV (1<<10) +#define FPINVAL (1<<11) +#define FPRNR (0<<0) +#define FPRZ (1<<0) +#define FPRPINF (2<<0) +#define FPRNINF (3<<0) +#define FPRMASK (3<<0) +#define FPPEXT 0 +#define FPPSGL 0 +#define FPPDBL 0 +#define FPPMASK 0 +/* FSR */ +#define FSRBITS 0x0003F07C +#define FPAINEX (1<<2) +#define FPAOVFL (1<<4) +#define FPAUNFL (1<<3) +#define FPAZDIV (1<<5) +#define FPAINVAL (1<<6) + +/* + * Linux mips fpu support + * Mimic Plan9 floating point support + */ + +static void +setfcr(ulong fcr) +{ + __asm__("ctc1 %0,$31\n" + : :"r" (fcr) + ); +} + +static ulong +getfcr(void) +{ + ulong fcr = 0; + __asm__("cfc1 %0,$31\n" + : "=r" (fcr) + ); + fcr &= FCRBITS; + return fcr; +} + +static ulong +getfsr(void) +{ + ulong fsr = 0; + __asm__("cfc1 %0,$31\n" + : "=r" (fsr) + ); + fsr &= FSRBITS; + return fsr; +} + +static void +setfsr(ulong fsr) +{ + fsr |= getfcr(); + setfcr(getfcr()|fsr); +} diff --git a/Linux/spim/include/lib9.h b/Linux/spim/include/lib9.h new file mode 100644 index 00000000..06b7a2be --- /dev/null +++ b/Linux/spim/include/lib9.h @@ -0,0 +1,494 @@ +/* define _BSD_SOURCE to use ISO C, POSIX, and 4.3BSD things. */ +#ifndef _BSD_SOURCE +#define _BSD_SOURCE +#endif +#define _LARGEFILE_SOURCE 1 +#define _LARGEFILE64_SOURCE 1 +#define _FILE_OFFSET_BITS 64 +#include <features.h> +#include <sys/types.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> +#include <endian.h> + +#define getwd infgetwd + +#ifndef EMU +typedef struct Proc Proc; +#endif + +/* + * math module dtoa + * #define __LITTLE_ENDIAN according to target under linux + */ + +#ifdef __MIPSEB__ +#undef __LITTLE_ENDIAN +#else +#define __LITTLE_ENDIAN 1234 +#endif + +#define nil ((void*)0) + +typedef unsigned char uchar; +typedef signed char schar; +typedef unsigned short Rune; +typedef long long int vlong; +typedef unsigned long long int uvlong; +typedef unsigned int u32int; +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 = 3, /* maximum bytes per rune */ + Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ + Runeself = 0x80, /* rune and UTF sequences are the same (<) */ + Runeerror = 0x80 /* decoding error in UTF */ +}; + +/* + * 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 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 ulong 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); +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 { + ulong val; + int pid; +} Lock; + +extern ulong _tas(ulong*); + +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() + +/* + * Extensions for emu kernel emulation + */ +#ifdef EMU + +/* + * This structure must agree with FPsave and FPrestore asm routines + */ +typedef struct FPU FPU; +struct FPU +{ + uchar env[28]; +}; + +/* + * Later versions of Linux seemed to need large stack for gethostbyname() + * so we had this at 128k, which is excessive. More recently, we've + * reduced it again after testing stack usage by gethostbyname. + */ +#define KSTACK (16 * 1024) + +static __inline Proc *getup(void) { + Proc *p; + __asm__( "move %0, $29\n\t" + : "=r" (p) + ); + return *(Proc **)((unsigned long)p & ~(KSTACK - 1)); +}; + +#define up (getup()) + +typedef sigjmp_buf osjmpbuf; +#define ossetjmp(buf) sigsetjmp(buf, 1) + +#endif diff --git a/emu/Linux/asm-spim.S b/emu/Linux/asm-spim.S new file mode 100644 index 00000000..5e281187 --- /dev/null +++ b/emu/Linux/asm-spim.S @@ -0,0 +1,70 @@ +#include "syscall.h" +#include <sys/asm.h> +#include <sys/regdef.h> +#include <asm/cachectl.h> + +/* + * executeonnewstack(void *tos, void (*tramp)(void *arg), void *arg) + */ + +LEAF(executeonnewstack) + and a0,a0,~7 + addu sp,a0,-16 + move a0,a2 + move t9,a1 + jalr t9 + + li v0,SYS_exit + li a0,0 + syscall + + END(executeonnewstack) + +/* + * unlockandexit(int *key) + */ + +LEAF(unlockandexit) + lw a1,0(a0) + li v0,SYS_exit + li a0,0 + sw a0,0(a1) + syscall + END(unlockandexit) + +LEAF(FPsave) + cfc1 t0, $31 + sw t0, 0(a0) /* a0 is argument */ + j $31 + END(FPsave) + +LEAF(FPrestore) + lw t0, 0(a0) /* a0 is argument */ + ctc1 t0, $31 + j $31 + END(FPrestore) + +LEAF(_tas) + .set noreorder +1: + ll v0,0(a0) /* a0 is argument */ + or t1, v0, 1 + sc t1,0(a0) + beq t1,zero,1b + nop + j $31 /* lock held */ + nop + .set reorder + END(_tas) + +/* + * int segflush(void *p, ulong len) + */ + +LEAF(segflush) + li a2,BCACHE + li v0,SYS_cacheflush + syscall + li v0,0 + j $31 + END(segflush) diff --git a/lib9/getcallerpc-Linux-spim.S b/lib9/getcallerpc-Linux-spim.S new file mode 100644 index 00000000..f3109864 --- /dev/null +++ b/lib9/getcallerpc-Linux-spim.S @@ -0,0 +1,10 @@ +#include <sys/regdef.h> +#include <sys/asm.h> + +LEAF(getcallerpc) + .set noreorder + addiu t0,a0,-4 + j ra + lw v0,0(t0) + .set reorder + END(getcallerpc) diff --git a/libdynld/dynld-spim.c b/libdynld/dynld-spim.c new file mode 100644 index 00000000..491080c0 --- /dev/null +++ b/libdynld/dynld-spim.c @@ -0,0 +1,22 @@ +#include "lib9.h" +#include <a.out.h> +#include <dynld.h> + +#define CHK(i,ntab) if((unsigned)(i)>=(ntab))return "bad relocation index" + +long +dynmagic(void) +{ + return DYN_MAGIC | N_MAGIC; +} + +char* +dynreloc(uchar *b, ulong p, int m, Dynsym **tab, int ntab) +{ + USED(b); + USED(p); + USED(m); + USED(tab); + USED(ntab); + return "mips-le (spim) unimplemented"; +} diff --git a/libinterp/comp-mips.c b/libinterp/comp-mips.c index ef812500..cd15c727 100644 --- a/libinterp/comp-mips.c +++ b/libinterp/comp-mips.c @@ -15,6 +15,10 @@ #define JR(op,r) gen((op)|((r)<<21)) #define J(op,c) gen((op)|(((ulong)(c)>>2)&0x3FFFFFFUL)) +#ifndef HIOFFSET +#define HIOFFSET 0 /* big endian */ +#endif + enum { Rzero = 0, @@ -112,6 +116,9 @@ enum REV1 = 1<<4, REV2 = 1<<5, + Bhi = HIOFFSET, + Blo = Bhi ^ 4, + MacRET = 0, MacFRP, MacINDX, @@ -620,9 +627,9 @@ cbral(Inst *i, int op, int mode) cp = 0; op1(i, Olea, Ri, 0); op2(i, Olea, Rj, 0); - IRR(Olw, 0,Ri, Ro1); - IRR(Olw, 0,Rj, Ro2); - IRR(Olw, 4,Ri, Ri); + IRR(Olw, Bhi,Ri, Ro1); + IRR(Olw, Bhi,Rj, Ro2); + IRR(Olw, Blo,Ri, Ri); switch(mode & OMASK) { case ANDAND: @@ -633,7 +640,7 @@ cbral(Inst *i, int op, int mode) case OROR: BRRI(Obne, Ro2,Ro1, branch(i)); b1: - IRR(Olw, 4,Rj, Rj); + IRR(Olw, Blo,Rj, Rj); delay(); BRRI(op, Rj,Ri, branch(i)); break; @@ -644,7 +651,7 @@ cbral(Inst *i, int op, int mode) else RRR(Oslt, Ro1,Ro2, Ro3); BRI(Obne, Ro3, branch(i)); - IRR(Olw, 4,Rj, Rj); + IRR(Olw, Blo,Rj, Rj); cp = code; BRRI(Obne, Ro2,Ro1, 0); if(mode & REV2) @@ -697,24 +704,24 @@ shrl(Inst *i) } c = i->s.imm; op2(i, Olea, Ro3, 1); - IRR(Olw, 0,Ro3, Ro1); + IRR(Olw, Bhi,Ro3, Ro1); if(c >= 32) { if((i->add&ARM) != AXNON) op3(i, Olea, Ro3, 0); else delay(); SRR(Osra, 31, Ro1, Ro2); - IRR(Osw, 0,Ro3, Ro2); + IRR(Osw, Bhi,Ro3, Ro2); if(c >= 64) { - IRR(Osw, 4,Ro3, Ro2); + IRR(Osw, Blo,Ro3, Ro2); return; } if(c > 32) SRR(Osra, c-32, Ro1, Ro1); - IRR(Osw, 4,Ro3, Ro1); + IRR(Osw, Blo,Ro3, Ro1); return; } - IRR(Olw, 4,Ro3, Ro2); + IRR(Olw, Blo,Ro3, Ro2); if((i->add&ARM) != AXNON) op3(i, Olea, Ro3, !c); if(c != 0) { @@ -723,8 +730,8 @@ shrl(Inst *i) SRR(Osrl, c, Ro2, Ro2); RRR(Oor, Ri, Ro2, Ro2); } - IRR(Osw, 4,Ro3, Ro2); - IRR(Osw, 0,Ro3, Ro1); + IRR(Osw, Blo,Ro3, Ro2); + IRR(Osw, Bhi,Ro3, Ro1); } static void @@ -739,23 +746,23 @@ shll(Inst *i) c = i->s.imm; if(c >= 64) { op3(i, Olea, Ro3, 1); - IRR(Osw, 0,Ro3, Rzero); - IRR(Osw, 4,Ro3, Rzero); + IRR(Osw, Bhi,Ro3, Rzero); + IRR(Osw, Blo,Ro3, Rzero); return; } op2(i, Olea, Ro3, 1); if(c >= 32) { - IRR(Olw, 4,Ro3, Ro1); + IRR(Olw, Blo,Ro3, Ro1); if((i->add&ARM) != AXNON) op3(i, Olea, Ro3, 1); - IRR(Osw, 4,Ro3, Rzero); + IRR(Osw, Blo,Ro3, Rzero); if(c > 32) SRR(Osll, c-32, Ro1, Ro1); - IRR(Osw, 0,Ro3, Ro1); + IRR(Osw, Bhi,Ro3, Ro1); return; } - IRR(Olw, 4,Ro3, Ro2); - IRR(Olw, 0,Ro3, Ro1); + IRR(Olw, Blo,Ro3, Ro2); + IRR(Olw, Bhi,Ro3, Ro1); if((i->add&ARM) != AXNON) op3(i, Olea, Ro3, !c); if(c != 0) { @@ -764,8 +771,8 @@ shll(Inst *i) SRR(Osll, c, Ro1, Ro1); RRR(Oor, Ri, Ro1, Ro1); } - IRR(Osw, 4,Ro3, Ro2); - IRR(Osw, 0,Ro3, Ro1); + IRR(Osw, Blo,Ro3, Ro2); + IRR(Osw, Bhi,Ro3, Ro1); } static void @@ -913,7 +920,7 @@ comp(Inst *i) break; case ICVTLW: op1(i, Olea, Ro1, 1); - IRR(Olw, 4,Ro1, Ro1); + IRR(Olw, Blo,Ro1, Ro1); delay(); op3(i, Osw, Ro1, 0); break; @@ -921,8 +928,8 @@ comp(Inst *i) op1(i, Olw, Ro1, 0); op3(i, Olea, Ro2, 0); SRR(Osra, 31, Ro1, Ro3); - IRR(Osw, 4,Ro2, Ro1); - IRR(Osw, 0,Ro2, Ro3); + IRR(Osw, Blo,Ro2, Ro1); + IRR(Osw, Bhi,Ro2, Ro3); break; case IHEADM: op1(i, Olw, Ro1, 1); @@ -1030,8 +1037,8 @@ comp(Inst *i) break; case ICVTFW: op1(i, Olea, Ro1, 1); - IRR(Olf, 0,Ro1, Rf2+1); - IRR(Olf, 4,Ro1, Rf2); + IRR(Olf, Bhi,Ro1, Rf2+1); + IRR(Olf, Blo,Ro1, Rf2); delay(); FRRR(Ocvtfw, 0, Rf2, Rf2); op3(i, Olea, Ro2, 1); @@ -1043,17 +1050,17 @@ comp(Inst *i) delay(); FRRR(Ocvtwf, 0, Rf2, Rf2); op3(i, Olea, Ro2, 1); - IRR(Osf, 0,Ro2, Rf2+1); - IRR(Osf, 4,Ro2, Rf2); + IRR(Osf, Bhi,Ro2, Rf2+1); + IRR(Osf, Blo,Ro2, Rf2); break; case INEGF: op1(i, Olea, Ro1, 1); - IRR(Olf, 0,Ro1, Rf1+1); - IRR(Olf, 4,Ro1, Rf1); + IRR(Olf, Bhi,Ro1, Rf1+1); + IRR(Olf, Blo,Ro1, Rf1); op3(i, Olea, Ro2, 1); FRRR(Onegf, 0, Rf1,Rf2); - IRR(Osf, 0,Ro2, Rf2+1); - IRR(Osf, 4,Ro2, Rf2); + IRR(Osf, Bhi,Ro2, Rf2+1); + IRR(Osf, Blo,Ro2, Rf2); break; case IXORL: case IORL: @@ -1063,10 +1070,10 @@ comp(Inst *i) op1(i, Olea, Ro1, 0); op2(i, Olea, Ro3, 0); - IRR(Olw, 4,Ro1, Rj); /* ls */ - IRR(Olw, 4,Ro3, Ro2); - IRR(Olw, 0,Ro1, Ri); /* ms */ - IRR(Olw, 0,Ro3, Ro1); + IRR(Olw, Blo,Ro1, Rj); /* ls */ + IRR(Olw, Blo,Ro3, Ro2); + IRR(Olw, Bhi,Ro1, Ri); /* ms */ + IRR(Olw, Bhi,Ro3, Ro1); switch(i->op) { case IXORL: @@ -1096,8 +1103,8 @@ comp(Inst *i) } if((i->add&ARM) != AXNON) op3(i, Olea, Ro3, 1); - IRR(Osw, 0,Ro3, Ro1); - IRR(Osw, 4,Ro3, Ro2); + IRR(Osw, Bhi,Ro3, Ro1); + IRR(Osw, Blo,Ro3, Ro2); break; case ISHLL: shll(i); @@ -1117,10 +1124,10 @@ comp(Inst *i) case IBNEF: op1(i, Olea, Ro1, 0); op2(i, Olea, Ro2, 0); - IRR(Olf, 0,Ro1, Rf1+1); - IRR(Olf, 4,Ro1, Rf1); - IRR(Olf, 0,Ro2, Rf2+1); - IRR(Olf, 4,Ro2, Rf2); + IRR(Olf, Bhi,Ro1, Rf1+1); + IRR(Olf, Blo,Ro1, Rf1); + IRR(Olf, Bhi,Ro2, Rf2+1); + IRR(Olf, Blo,Ro2, Rf2); switch(i->op) { case IADDF: o = Oaddf; goto f1; case ISUBF: o = Osubf; goto f1; @@ -1135,8 +1142,8 @@ comp(Inst *i) f1: op3(i, Olea, Ro1, 0); FRRR(o, Rf1,Rf2, Rf2); - IRR(Osf, 0,Ro1, Rf2+1); - IRR(Osf, 4,Ro1, Rf2); + IRR(Osf, Bhi,Ro1, Rf2+1); + IRR(Osf, Blo,Ro1, Rf2); break; f2: delay(); diff --git a/libinterp/comp-spim.c b/libinterp/comp-spim.c index f8c34c33..0ffb0f1f 100644 --- a/libinterp/comp-spim.c +++ b/libinterp/comp-spim.c @@ -1 +1,2 @@ +#define HIOFFSET 4 /* byte offset of high-order word in little-endian vlongs */ #include "comp-mips.c" diff --git a/libkern/frexp-mips.c b/libkern/frexp-mips.c index ac22e037..b13bbead 100644 --- a/libkern/frexp-mips.c +++ b/libkern/frexp-mips.c @@ -1,5 +1,4 @@ -#include <u.h> -#include <libc.h> +#include <lib9.h> #define MASK 0x7ffL #define SHIFT 20 diff --git a/libkern/frexp-spim.c b/libkern/frexp-spim.c new file mode 100644 index 00000000..8973a14d --- /dev/null +++ b/libkern/frexp-spim.c @@ -0,0 +1,79 @@ +#include <lib9.h> + +#define MASK 0x7ffL +#define SHIFT 20 +#define BIAS 1022L + +typedef union +{ + double d; + struct + { + long ls; + long ms; + }; +} Cheat; + +double +frexp(double d, int *ep) +{ + Cheat x; + + if(d == 0) { + *ep = 0; + return 0; + } + x.d = d; + *ep = ((x.ms >> SHIFT) & MASK) - BIAS; + x.ms &= ~(MASK << SHIFT); + x.ms |= BIAS << SHIFT; + return x.d; +} + +double +ldexp(double d, int e) +{ + Cheat x; + + if(d == 0) + return 0; + x.d = d; + e += (x.ms >> SHIFT) & MASK; + if(e <= 0) + return 0; /* underflow */ + if(e >= MASK){ /* overflow */ + if(d < 0) + return Inf(-1); + return Inf(1); + } + x.ms &= ~(MASK << SHIFT); + x.ms |= (long)e << SHIFT; + return x.d; +} + +double +modf(double d, double *ip) +{ + Cheat x; + int e; + + if(d < 1) { + if(d < 0) { + x.d = modf(-d, ip); + *ip = -*ip; + return -x.d; + } + *ip = 0; + return d; + } + x.d = d; + e = ((x.ms >> SHIFT) & MASK) - BIAS; + if(e <= SHIFT+1) { + x.ms &= ~(0x1fffffL >> e); + x.ls = 0; + } else + if(e <= SHIFT+33) + x.ls &= ~(0x7fffffffL >> (e-SHIFT-2)); + *ip = x.d; + return d - x.d; +} diff --git a/libkern/getfcr-spim.s b/libkern/getfcr-spim.s new file mode 100644 index 00000000..a2b07152 --- /dev/null +++ b/libkern/getfcr-spim.s @@ -0,0 +1 @@ +#include "getfcr-mips.s" diff --git a/libkern/memmove-spim.s b/libkern/memmove-spim.s new file mode 100644 index 00000000..af74643c --- /dev/null +++ b/libkern/memmove-spim.s @@ -0,0 +1 @@ +#include "memmove-mips.s" diff --git a/libkern/memset-spim.s b/libkern/memset-spim.s new file mode 100644 index 00000000..eca40b6b --- /dev/null +++ b/libkern/memset-spim.s @@ -0,0 +1 @@ +#include "memset-mips.s" diff --git a/libkern/nan-mips.c b/libkern/nan-mips.c index e1b3db36..f1cfa0b0 100644 --- a/libkern/nan-mips.c +++ b/libkern/nan-mips.c @@ -1,5 +1,4 @@ -#include <u.h> -#include <libc.h> +#include <lib9.h> #define NANEXP (2047<<20) #define NANMASK (2047<<20) diff --git a/libkern/nan-spim.c b/libkern/nan-spim.c new file mode 100644 index 00000000..2152925a --- /dev/null +++ b/libkern/nan-spim.c @@ -0,0 +1,69 @@ +#include <lib9.h> + +#define NANEXP (2047<<20) +#define NANMASK (2047<<20) +#define NANSIGN (1<<31) + +double +NaN(void) +{ + union + { + double d; + long x[2]; + } a; + + a.x[1] = NANEXP; + a.x[0] = 1; + return a.d; +} + +int +isNaN(double d) +{ + union + { + double d; + long x[2]; + } a; + + a.d = d; + if((a.x[1] & NANMASK) != NANEXP) + return 0; + return !isInf(d, 0); +} + +double +Inf(int sign) +{ + union + { + double d; + long x[2]; + } a; + + a.x[1] = NANEXP; + a.x[0] = 0; + if(sign < 0) + a.x[1] |= NANSIGN; + return a.d; +} + +int +isInf(double d, int sign) +{ + union + { + double d; + long x[2]; + } a; + + a.d = d; + if(a.x[0] != 0) + return 0; + if(a.x[1] == NANEXP) + return sign >= 0; + if(a.x[1] == (NANEXP|NANSIGN)) + return sign <= 0; + return 0; +} diff --git a/libkern/strchr-spim.c b/libkern/strchr-spim.c new file mode 100644 index 00000000..1d4d425c --- /dev/null +++ b/libkern/strchr-spim.c @@ -0,0 +1,18 @@ +#include <lib9.h> + +char* +strchr(char *s, int c) +{ + char c1; + + if(c == 0) { + while(*s++) + ; + return s-1; + } + + while(c1 = *s++) + if(c1 == c) + return s-1; + return 0; +} diff --git a/libkern/strchr-spim.s b/libkern/strchr-spim.s new file mode 100644 index 00000000..355d32a9 --- /dev/null +++ b/libkern/strchr-spim.s @@ -0,0 +1 @@ +#include "strchr-mips.s" diff --git a/libkern/vlop-spim.s b/libkern/vlop-spim.s new file mode 100644 index 00000000..10c97d9e --- /dev/null +++ b/libkern/vlop-spim.s @@ -0,0 +1,17 @@ +TEXT _mulv(SB), $0 + MOVW 4(FP), R2 + MOVW 8(FP), R3 + MOVW 12(FP), R4 + MOVW 16(FP), R5 + MULU R4, R2 + MOVW LO, R6 + MOVW HI, R7 + MULU R3, R4 + MOVW LO, R8 + ADDU R8, R7 + MULU R2, R5 + MOVW LO, R8 + ADDU R8, R7 + MOVW R6, 0(R1) + MOVW R7, 4(R1) + RET diff --git a/libkern/vlrt-mips.c b/libkern/vlrt-mips.c index 96456277..f15372eb 100644 --- a/libkern/vlrt-mips.c +++ b/libkern/vlrt-mips.c @@ -16,13 +16,6 @@ struct Vlong ulong hi; ulong lo; }; - struct - { - ushort hims; - ushort hils; - ushort loms; - ushort lols; - }; }; }; diff --git a/libkern/vlrt-spim.c b/libkern/vlrt-spim.c new file mode 100644 index 00000000..e4ef727a --- /dev/null +++ b/libkern/vlrt-spim.c @@ -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 +{ + union + { + struct + { + ulong lo; + ulong hi; + }; + }; +}; + +void abort(void); + +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; +} + + +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); +} + +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); +} diff --git a/mkfiles/mkfile-Linux-spim b/mkfiles/mkfile-Linux-spim new file mode 100644 index 00000000..c68c798b --- /dev/null +++ b/mkfiles/mkfile-Linux-spim @@ -0,0 +1,29 @@ +TARGMODEL= Posix +TARGSHTYPE= sh +CPUS= spim + +O= o +OS= o + +AR= mipsel-linux-uclibc-ar +ARFLAGS= crvs + +AS= mipsel-linux-uclibc-gcc -c -mips32 +ASFLAGS= + +CC= mipsel-linux-uclibc-gcc -c -mips32 +CFLAGS= -g\ + -Os\ + -I$ROOT/Linux/spim/include\ + -I$ROOT/include\ + -I/usr/X11R6/include + +ANSICPP= +LD= mipsel-linux-uclibc-gcc +LDFLAGS= -L/usr/openwin/lib\ + -L/usr/X11R6/lib\ + +SYSLIBS= + +YACC= iyacc +YFLAGS= -d |
