shithub: riscv

Download patch

ref: 2346ea488600e7e735c2275e5bcd310bbbf9810c
parent: 5851d6fe391a1169d595721dd33afe77165bd84b
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Apr 7 18:10:40 EDT 2025

kernel: deduplicate the mess that is the 32-bit arm ports

avoid these #include "../omap/*.h" constructs, and
handle it in the mkfile instead.

move most of the 32-bit arm stuff to omap,
except bcm hosts some crazy vfp3 + fpi mixed mode
code which is shared with tegra.

get rid of omap/mouse.c, just define a mousectl()
in screen.c, we'r done.

--- a/sys/src/9/bcm/fpi.c
+++ /dev/null
@@ -1,1 +1,0 @@
-#include "../omap/fpi.c"
--- a/sys/src/9/bcm/fpi.h
+++ /dev/null
@@ -1,1 +1,0 @@
-#include "../omap/fpi.h"
--- a/sys/src/9/bcm/fpiarm.c
+++ b/sys/src/9/bcm/fpiarm.c
@@ -13,7 +13,7 @@
 #include	"ureg.h"
 
 #include	"arm.h"
-#include	"fpi.h"
+#include	"../omap/fpi.h"
 
 /* undef this if correct kernel r13 isn't in Ureg;
  * check calculation in fpiarm below
--- a/sys/src/9/bcm/fpimem.c
+++ /dev/null
@@ -1,1 +1,0 @@
-#include "../omap/fpimem.c"
--- a/sys/src/9/bcm/mkfile
+++ b/sys/src/9/bcm/mkfile
@@ -102,15 +102,23 @@
 <../port/portmkfile
 <|../port/mkbootrules $CONF
 
+fpi.$O fpiarm.$O fpimem.$O: ../omap/fpi.h
+fpi.$O:	../omap/fpi.c
+	$CC $CFLAGS -. ../omap/fpi.c
+fpimem.$O:	../omap/fpimem.c
+	$CC $CFLAGS -. ../omap/fpimem.c
+
+syscall.$O:	../omap/syscall.c
+	$CC $CFLAGS -. ../omap/syscall.c
+
 arch.$O clock.$O fpiarm.$O main.$O mmu.$O screen.$O syscall.$O trap.$O: \
 	/$objtype/include/ureg.h
 arch.$O trap.$O main.$O: /sys/include/tos.h
-fpi.$O fpiarm.$O fpimem.$O: fpi.h
 l.$O lexception.$O lproc.$O mmu.$O: mem.h
 l.$O lexception.$O lproc.$O armv6.$O armv7.$O: arm.s
 armv7.$O: cache.v7.s
 main.$O: errstr.h rebootcode.i
-devmouse.$O mouse.$O screen.$O: screen.h
+devmouse.$O screen.$O: screen.h
 usbdwc.$O: dwcotg.h ../port/usb.h
 i2cbcm.$O i2cgpio.$O: ../port/i2c.h
 emmc.$O ether4330.$O: ../port/sd.h
--- a/sys/src/9/bcm/mouse.c
+++ /dev/null
@@ -1,1 +1,0 @@
-#include "../omap/mouse.c"
--- a/sys/src/9/bcm/pi
+++ b/sys/src/9/bcm/pi
@@ -16,7 +16,7 @@
 	bridge	log
 	ip	arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
 	draw	screen swcursor
-	mouse	mouse
+	mouse
 	uart	gpio
 	gpio	gpio
 	i2c
--- a/sys/src/9/bcm/pi2
+++ b/sys/src/9/bcm/pi2
@@ -16,7 +16,7 @@
 	bridge	log
 	ip	arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
 	draw	screen swcursor
-	mouse	mouse
+	mouse
 	uart	gpio
 	gpio	gpio
 	i2c
--- a/sys/src/9/bcm/screen.c
+++ b/sys/src/9/bcm/screen.c
@@ -56,6 +56,33 @@
 static void screenwin(void);
 
 /* called from devmouse */
+enum
+{
+	CMaccelerated,
+	CMlinear,
+};
+
+static Cmdtab mousectlmsg[] =
+{
+	CMaccelerated,		"accelerated",		0,
+	CMlinear,		"linear",		1,
+};
+
+void
+mousectl(Cmdbuf *cb)
+{
+	Cmdtab *ct;
+
+	ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
+	switch(ct->index){
+	case CMaccelerated:
+		mouseaccelerate(cb->nf == 1? 1: atoi(cb->f[1]));
+		break;
+	case CMlinear:
+		mouseaccelerate(0);
+		break;
+	}
+}
 
 void
 cursoron(void)
--- a/sys/src/9/bcm/syscall.c
+++ /dev/null
@@ -1,1 +1,0 @@
-#include "../kw/syscall.c"
--- a/sys/src/9/bcm64/mkfile
+++ b/sys/src/9/bcm64/mkfile
@@ -114,7 +114,7 @@
 main.$O: rebootcode.i
 pcibcm.$O: ../port/pci.h
 
-devmouse.$O mouse.$O screen.$O: screen.h
+devmouse.$O screen.$O: screen.h
 usbdwc.$O: dwcotg.h ../port/usb.h
 i2cbcm.$O i2cgpio.$O: ../port/i2c.h
 emmc.$O sdhc.$O sdhost.$O ether4330.$O: ../port/sd.h
--- a/sys/src/9/bcm64/pi3
+++ b/sys/src/9/bcm64/pi3
@@ -17,7 +17,7 @@
 	bridge	log
 	ip	arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
 	draw	screen swcursor
-	mouse	mouse
+	mouse
 	uart	gpio
 	gpio	gpio
 	i2c
--- a/sys/src/9/bcm64/pi4
+++ b/sys/src/9/bcm64/pi4
@@ -17,7 +17,7 @@
 	bridge	log
 	ip	arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
 	draw	screen swcursor
-	mouse	mouse
+	mouse
 	uart	gpio
 	gpio	gpio
 	i2c
--- a/sys/src/9/kw/fpi.c
+++ /dev/null
@@ -1,300 +1,0 @@
-/*
- * Floating Point Interpreter.
- * shamelessly stolen from an original by ark.
- */
-#include "fpi.h"
-
-void
-fpiround(Internal *i)
-{
-	unsigned long guard;
-
-	guard = i->l & GuardMask;
-	i->l &= ~GuardMask;
-	if(guard > (LsBit>>1) || (guard == (LsBit>>1) && (i->l & LsBit))){
-		i->l += LsBit;
-		if(i->l & CarryBit){
-			i->l &= ~CarryBit;
-			i->h++;
-			if(i->h & CarryBit){
-				if (i->h & 0x01)
-					i->l |= CarryBit;
-				i->l >>= 1;
-				i->h >>= 1;
-				i->e++;
-			}
-		}
-	}
-}
-
-static void
-matchexponents(Internal *x, Internal *y)
-{
-	int count;
-
-	count = y->e - x->e;
-	x->e = y->e;
-	if(count >= 2*FractBits){
-		x->l = x->l || x->h;
-		x->h = 0;
-		return;
-	}
-	if(count >= FractBits){
-		count -= FractBits;
-		x->l = x->h|(x->l != 0);
-		x->h = 0;
-	}
-	while(count > 0){
-		count--;
-		if(x->h & 0x01)
-			x->l |= CarryBit;
-		if(x->l & 0x01)
-			x->l |= 2;
-		x->l >>= 1;
-		x->h >>= 1;
-	}
-}
-
-static void
-shift(Internal *i)
-{
-	i->e--;
-	i->h <<= 1;
-	i->l <<= 1;
-	if(i->l & CarryBit){
-		i->l &= ~CarryBit;
-		i->h |= 0x01;
-	}
-}
-
-static void
-normalise(Internal *i)
-{
-	while((i->h & HiddenBit) == 0)
-		shift(i);
-}
-
-static void
-renormalise(Internal *i)
-{
-	if(i->e < -2 * FractBits)
-		i->e = -2 * FractBits;
-	while(i->e < 1){
-		i->e++;
-		if(i->h & 0x01)
-			i->l |= CarryBit;
-		i->h >>= 1;
-		i->l = (i->l>>1)|(i->l & 0x01);
-	}
-	if(i->e >= ExpInfinity)
-		SetInfinity(i);
-}
-
-void
-fpinormalise(Internal *x)
-{
-	if(!IsWeird(x) && !IsZero(x))
-		normalise(x);
-}
-
-void
-fpiadd(Internal *x, Internal *y, Internal *i)
-{
-	Internal *t;
-
-	i->s = x->s;
-	if(IsWeird(x) || IsWeird(y)){
-		if(IsNaN(x) || IsNaN(y))
-			SetQNaN(i);
-		else
-			SetInfinity(i);
-		return;
-	}
-	if(x->e > y->e){
-		t = x;
-		x = y;
-		y = t;
-	}
-	matchexponents(x, y);
-	i->e = x->e;
-	i->h = x->h + y->h;
-	i->l = x->l + y->l;
-	if(i->l & CarryBit){
-		i->h++;
-		i->l &= ~CarryBit;
-	}
-	if(i->h & (HiddenBit<<1)){
-		if(i->h & 0x01)
-			i->l |= CarryBit;
-		i->l = (i->l>>1)|(i->l & 0x01);
-		i->h >>= 1;
-		i->e++;
-	}
-	if(IsWeird(i))
-		SetInfinity(i);
-}
-
-void
-fpisub(Internal *x, Internal *y, Internal *i)
-{
-	Internal *t;
-
-	if(y->e < x->e
-	   || (y->e == x->e && (y->h < x->h || (y->h == x->h && y->l < x->l)))){
-		t = x;
-		x = y;
-		y = t;
-	}
-	i->s = y->s;
-	if(IsNaN(y)){
-		SetQNaN(i);
-		return;
-	}
-	if(IsInfinity(y)){
-		if(IsInfinity(x))
-			SetQNaN(i);
-		else
-			SetInfinity(i);
-		return;
-	}
-	matchexponents(x, y);
-	i->e = y->e;
-	i->h = y->h - x->h;
-	i->l = y->l - x->l;
-	if(i->l < 0){
-		i->l += CarryBit;
-		i->h--;
-	}
-	if(i->h == 0 && i->l == 0)
-		SetZero(i);
-	else while(i->e > 1 && (i->h & HiddenBit) == 0)
-		shift(i);
-}
-
-#define	CHUNK		(FractBits/2)
-#define	CMASK		((1<<CHUNK)-1)
-#define	HI(x)		((short)((x)>>CHUNK) & CMASK)
-#define	LO(x)		((short)(x) & CMASK)
-#define	SPILL(x)	((x)>>CHUNK)
-#define	M(x, y)		((long)a[x]*(long)b[y])
-#define	C(h, l)		(((long)((h) & CMASK)<<CHUNK)|((l) & CMASK))
-
-void
-fpimul(Internal *x, Internal *y, Internal *i)
-{
-	long a[4], b[4], c[7], f[4];
-
-	i->s = x->s^y->s;
-	if(IsWeird(x) || IsWeird(y)){
-		if(IsNaN(x) || IsNaN(y) || IsZero(x) || IsZero(y))
-			SetQNaN(i);
-		else
-			SetInfinity(i);
-		return;
-	}
-	else if(IsZero(x) || IsZero(y)){
-		SetZero(i);
-		return;
-	}
-	normalise(x);
-	normalise(y);
-	i->e = x->e + y->e - (ExpBias - 1);
-
-	a[0] = HI(x->h); b[0] = HI(y->h);
-	a[1] = LO(x->h); b[1] = LO(y->h);
-	a[2] = HI(x->l); b[2] = HI(y->l);
-	a[3] = LO(x->l); b[3] = LO(y->l);
-
-	c[6] =                               M(3, 3);
-	c[5] =                     M(2, 3) + M(3, 2) + SPILL(c[6]);
-	c[4] =           M(1, 3) + M(2, 2) + M(3, 1) + SPILL(c[5]);
-	c[3] = M(0, 3) + M(1, 2) + M(2, 1) + M(3, 0) + SPILL(c[4]);
-	c[2] = M(0, 2) + M(1, 1) + M(2, 0)           + SPILL(c[3]);
-	c[1] = M(0, 1) + M(1, 0)                     + SPILL(c[2]);
-	c[0] = M(0, 0)                               + SPILL(c[1]);
-
-	f[0] = c[0];
-	f[1] = C(c[1], c[2]);
-	f[2] = C(c[3], c[4]);
-	f[3] = C(c[5], c[6]);
-
-	if((f[0] & HiddenBit) == 0){
-		f[0] <<= 1;
-		f[1] <<= 1;
-		f[2] <<= 1;
-		f[3] <<= 1;
-		if(f[1] & CarryBit){
-			f[0] |= 1;
-			f[1] &= ~CarryBit;
-		}
-		if(f[2] & CarryBit){
-			f[1] |= 1;
-			f[2] &= ~CarryBit;
-		}
-		if(f[3] & CarryBit){
-			f[2] |= 1;
-			f[3] &= ~CarryBit;
-		}
-		i->e--;
-	}
-	i->h = f[0];
-	i->l = f[1];
-	if(f[2] || f[3])
-		i->l |= 1;
-	renormalise(i);
-}
-
-void
-fpidiv(Internal *x, Internal *y, Internal *i)
-{
-	i->s = x->s^y->s;
-	if(IsNaN(x) || IsNaN(y)
-	   || (IsInfinity(x) && IsInfinity(y)) || (IsZero(x) && IsZero(y))){
-		SetQNaN(i);
-		return;
-	}
-	else if(IsZero(x) || IsInfinity(y)){
-		SetInfinity(i);
-		return;
-	}
-	else if(IsInfinity(x) || IsZero(y)){
-		SetZero(i);
-		return;
-	}
-	normalise(x);
-	normalise(y);
-	i->h = 0;
-	i->l = 0;
-	i->e = y->e - x->e + (ExpBias + 2*FractBits - 1);
-	do{
-		if(y->h > x->h || (y->h == x->h && y->l >= x->l)){
-			i->l |= 0x01;
-			y->h -= x->h;
-			y->l -= x->l;
-			if(y->l < 0){
-				y->l += CarryBit;
-				y->h--;
-			}
-		}
-		shift(y);
-		shift(i);
-	}while ((i->h & HiddenBit) == 0);
-	if(y->h || y->l)
-		i->l |= 0x01;
-	renormalise(i);
-}
-
-int
-fpicmp(Internal *x, Internal *y)
-{
-	if(IsNaN(x) && IsNaN(y))
-		return 0;
-	if(IsInfinity(x) && IsInfinity(y))
-		return y->s - x->s;
-	if(x->e == y->e && x->h == y->h && x->l == y->l)
-		return y->s - x->s;
-	if(x->e < y->e
-	   || (x->e == y->e && (x->h < y->h || (x->h == y->h && x->l < y->l))))
-		return y->s ? 1: -1;
-	return x->s ? -1: 1;
-}
--- a/sys/src/9/kw/fpi.h
+++ /dev/null
@@ -1,61 +1,0 @@
-typedef long Word;
-typedef unsigned long Single;
-typedef struct {
-	unsigned long l;
-	unsigned long h;
-} Double;
-
-enum {
-	FractBits	= 28,
-	CarryBit	= 0x10000000,
-	HiddenBit	= 0x08000000,
-	MsBit		= HiddenBit,
-	NGuardBits	= 3,
-	GuardMask	= 0x07,
-	LsBit		= (1<<NGuardBits),
-
-	SingleExpBias	= 127,
-	SingleExpMax	= 255,
-	DoubleExpBias	= 1023,
-	DoubleExpMax	= 2047,
-
-	ExpBias		= DoubleExpBias,
-	ExpInfinity	= DoubleExpMax,
-};
-
-typedef struct {
-	unsigned char s;
-	short e;
-	long l;				/* 0000FFFFFFFFFFFFFFFFFFFFFFFFFGGG */
-	long h;				/* 0000HFFFFFFFFFFFFFFFFFFFFFFFFFFF */
-} Internal;
-
-#define IsWeird(n)	((n)->e >= ExpInfinity)
-#define	IsInfinity(n)	(IsWeird(n) && (n)->h == HiddenBit && (n)->l == 0)
-#define	SetInfinity(n)	((n)->e = ExpInfinity, (n)->h = HiddenBit, (n)->l = 0)
-#define IsNaN(n)	(IsWeird(n) && (((n)->h & ~HiddenBit) || (n)->l))
-#define	SetQNaN(n)	((n)->s = 0, (n)->e = ExpInfinity, 		\
-			 (n)->h = HiddenBit|(LsBit<<1), (n)->l = 0)
-#define IsZero(n)	((n)->e == 1 && (n)->h == 0 && (n)->l == 0)
-#define SetZero(n)	((n)->e = 1, (n)->h = 0, (n)->l = 0)
-
-/*
- * fpi.c
- */
-extern void fpiround(Internal *);
-extern void fpiadd(Internal *, Internal *, Internal *);
-extern void fpisub(Internal *, Internal *, Internal *);
-extern void fpimul(Internal *, Internal *, Internal *);
-extern void fpidiv(Internal *, Internal *, Internal *);
-extern int fpicmp(Internal *, Internal *);
-extern void fpinormalise(Internal*);
-
-/*
- * fpimem.c
- */
-extern void fpis2i(Internal *, void *);
-extern void fpid2i(Internal *, void *);
-extern void fpiw2i(Internal *, void *);
-extern void fpii2s(void *, Internal *);
-extern void fpii2d(void *, Internal *);
-extern void fpii2w(Word *, Internal *);
--- a/sys/src/9/kw/fpiarm.c
+++ /dev/null
@@ -1,772 +1,0 @@
-/*
- * this doesn't attempt to implement ARM floating-point properties
- * that aren't visible in the Inferno environment.
- * all arithmetic is done in double precision.
- * the FP trap status isn't updated.
- */
-#include	"u.h"
-#include	"../port/lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-
-#include	"ureg.h"
-
-#include	"arm.h"
-#include	"fpi.h"
-
-/* undef this if correct kernel r13 isn't in Ureg;
- * check calculation in fpiarm below
- */
-#define	REG(ur, x) (*(long*)(((char*)(ur))+roff[(x)]))
-#define	FR(ufp, x) (*(Internal*)(ufp)->regs[(x)&(Nfpctlregs - 1)])
-
-typedef struct FP2 FP2;
-typedef struct FP1 FP1;
-
-struct FP2 {
-	char*	name;
-	void	(*f)(Internal, Internal, Internal*);
-};
-
-struct FP1 {
-	char*	name;
-	void	(*f)(Internal*, Internal*);
-};
-
-enum {
-	N = 1<<31,
-	Z = 1<<30,
-	C = 1<<29,
-	V = 1<<28,
-	REGPC = 15,
-};
-
-enum {
-	fpemudebug = 0,
-};
-
-#undef OFR
-#define	OFR(X)	((ulong)&((Ureg*)0)->X)
-
-static	int	roff[] = {
-	OFR(r0), OFR(r1), OFR(r2), OFR(r3),
-	OFR(r4), OFR(r5), OFR(r6), OFR(r7),
-	OFR(r8), OFR(r9), OFR(r10), OFR(r11),
-	OFR(r12), OFR(r13), OFR(r14), OFR(pc),
-};
-
-static Internal fpconst[8] = {		/* indexed by op&7 (ARM 7500 FPA) */
-	/* s, e, l, h */
-	{0, 0x1, 0x00000000, 0x00000000}, /* 0.0 */
-	{0, 0x3FF, 0x00000000, 0x08000000},	/* 1.0 */
-	{0, 0x400, 0x00000000, 0x08000000},	/* 2.0 */
-	{0, 0x400, 0x00000000, 0x0C000000},	/* 3.0 */
-	{0, 0x401, 0x00000000, 0x08000000},	/* 4.0 */
-	{0, 0x401, 0x00000000, 0x0A000000},	/* 5.0 */
-	{0, 0x3FE, 0x00000000, 0x08000000},	/* 0.5 */
-	{0, 0x402, 0x00000000, 0x0A000000},	/* 10.0 */
-};
-
-/*
- * arm binary operations
- */
-
-static void
-fadd(Internal m, Internal n, Internal *d)
-{
-	(m.s == n.s? fpiadd: fpisub)(&m, &n, d);
-}
-
-static void
-fsub(Internal m, Internal n, Internal *d)
-{
-	m.s ^= 1;
-	(m.s == n.s? fpiadd: fpisub)(&m, &n, d);
-}
-
-static void
-fsubr(Internal m, Internal n, Internal *d)
-{
-	n.s ^= 1;
-	(n.s == m.s? fpiadd: fpisub)(&n, &m, d);
-}
-
-static void
-fmul(Internal m, Internal n, Internal *d)
-{
-	fpimul(&m, &n, d);
-}
-
-static void
-fdiv(Internal m, Internal n, Internal *d)
-{
-	fpidiv(&m, &n, d);
-}
-
-static void
-fdivr(Internal m, Internal n, Internal *d)
-{
-	fpidiv(&n, &m, d);
-}
-
-/*
- * arm unary operations
- */
-
-static void
-fmov(Internal *m, Internal *d)
-{
-	*d = *m;
-}
-
-static void
-fmovn(Internal *m, Internal *d)
-{
-	*d = *m;
-	d->s ^= 1;
-}
-
-static void
-fabsf(Internal *m, Internal *d)
-{
-	*d = *m;
-	d->s = 0;
-}
-
-static void
-frnd(Internal *m, Internal *d)
-{
-	short e;
-
-	(m->s? fsub: fadd)(fpconst[6], *m, d);
-	if(IsWeird(d))
-		return;
-	fpiround(d);
-	e = (d->e - ExpBias) + 1;
-	if(e <= 0)
-		SetZero(d);
-	else if(e > FractBits){
-		if(e < 2*FractBits)
-			d->l &= ~((1<<(2*FractBits - e))-1);
-	}else{
-		d->l = 0;
-		if(e < FractBits)
-			d->h &= ~((1<<(FractBits-e))-1);
-	}
-}
-
-/*
- * ARM 7500 FPA opcodes
- */
-
-static	FP1	optab1[16] = {	/* Fd := OP Fm */
-[0]	{"MOVF",	fmov},
-[1]	{"NEGF",	fmovn},
-[2]	{"ABSF",	fabsf},
-[3]	{"RNDF",	frnd},
-[4]	{"SQTF",	/*fsqt*/0},
-/* LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN all `deprecated' */
-/* URD and NRM aren't implemented */
-};
-
-static	FP2	optab2[16] = {	/* Fd := Fn OP Fm */
-[0]	{"ADDF",	fadd},
-[1]	{"MULF",	fmul},
-[2]	{"SUBF",	fsub},
-[3]	{"RSUBF",	fsubr},
-[4]	{"DIVF",	fdiv},
-[5]	{"RDIVF",	fdivr},
-/* POW, RPW deprecated */
-[8]	{"REMF",	/*frem*/0},
-[9]	{"FMF",	fmul},	/* fast multiply */
-[10]	{"FDV",	fdiv},	/* fast divide */
-[11]	{"FRD",	fdivr},	/* fast reverse divide */
-/* POL deprecated */
-};
-
-/*
- * ARM VFP opcodes
- */
-
-static	FP1	voptab1[32] = {	/* Vd := OP Vm */
-[0]	{"MOVF",	fmov},
-[1]	{"ABSF",	fabsf},
-[2]	{"NEGF",	fmovn},
-[15]	{"CVTF",	fmov},
-};
-
-static	FP2	voptab2[16] = {	/* Vd := Vn FOP Fm */
-[4]	{"MULF",	fmul},
-[6]	{"ADDF",	fadd},
-[7]	{"SUBF",	fsub},
-[8]	{"DIVF",	fdiv},
-};
-
-static ulong
-fcmp(Internal *n, Internal *m)
-{
-	int i;
-	Internal rm, rn;
-
-	if(IsWeird(m) || IsWeird(n)){
-		/* BUG: should trap if not masked */
-		return V|C;
-	}
-	rn = *n;
-	rm = *m;
-	fpiround(&rn);
-	fpiround(&rm);
-	i = fpicmp(&rn, &rm);
-	if(i > 0)
-		return C;
-	else if(i == 0)
-		return C|Z;
-	else
-		return N;
-}
-
-static void
-fld(void (*f)(Internal*, void*), int d, ulong ea, int n, FPsave *ufp)
-{
-	void *mem;
-
-	mem = (void*)ea;
-	(*f)(&FR(ufp, d), mem);
-	if(fpemudebug)
-		print("MOV%c #%lux, F%d\n", n==8? 'D': 'F', ea, d);
-}
-
-static void
-fst(void (*f)(void*, Internal*), ulong ea, int s, int n, FPsave *ufp)
-{
-	Internal tmp;
-	void *mem;
-
-	mem = (void*)ea;
-	tmp = FR(ufp, s);
-	if(fpemudebug)
-		print("MOV%c	F%d,#%lux\n", n==8? 'D': 'F', s, ea);
-	(*f)(mem, &tmp);
-}
-
-static int
-condok(int cc, int c)
-{
-	switch(c){
-	case 0:	/* Z set */
-		return cc&Z;
-	case 1:	/* Z clear */
-		return (cc&Z) == 0;
-	case 2:	/* C set */
-		return cc&C;
-	case 3:	/* C clear */
-		return (cc&C) == 0;
-	case 4:	/* N set */
-		return cc&N;
-	case 5:	/* N clear */
-		return (cc&N) == 0;
-	case 6:	/* V set */
-		return cc&V;
-	case 7:	/* V clear */
-		return (cc&V) == 0;
-	case 8:	/* C set and Z clear */
-		return cc&C && (cc&Z) == 0;
-	case 9:	/* C clear or Z set */
-		return (cc&C) == 0 || cc&Z;
-	case 10:	/* N set and V set, or N clear and V clear */
-		return (~cc&(N|V))==0 || (cc&(N|V)) == 0;
-	case 11:	/* N set and V clear, or N clear and V set */
-		return (cc&(N|V))==N || (cc&(N|V))==V;
-	case 12:	/* Z clear, and either N set and V set or N clear and V clear */
-		return (cc&Z) == 0 && ((~cc&(N|V))==0 || (cc&(N|V))==0);
-	case 13:	/* Z set, or N set and V clear or N clear and V set */
-		return (cc&Z) || (cc&(N|V))==N || (cc&(N|V))==V;
-	case 14:	/* always */
-		return 1;
-	case 15:	/* never (reserved) */
-		return 0;
-	}
-	return 0;	/* not reached */
-}
-
-static void
-unimp(ulong pc, ulong op)
-{
-	char buf[60];
-
-	snprint(buf, sizeof(buf), "sys: fp: pc=%lux unimp fp 0x%.8lux", pc, op);
-	if(fpemudebug)
-		print("FPE: %s\n", buf);
-	error(buf);
-	/* no return */
-}
-
-static void
-fpaemu(ulong pc, ulong op, Ureg *ur, FPsave *ufp)
-{
-	int rn, rd, tag, o;
-	long off;
-	ulong ea;
-	Internal tmp, *fm, *fn;
-
-	/* note: would update fault status here if we noted numeric exceptions */
-
-	/*
-	 * LDF, STF; 10.1.1
-	 */
-	if(((op>>25)&7) == 6){
-		if(op & (1<<22))
-			unimp(pc, op);	/* packed or extended */
-		rn = (op>>16)&0xF;
-		off = (op&0xFF)<<2;
-		if((op & (1<<23)) == 0)
-			off = -off;
-		ea = REG(ur, rn);
-		if(rn == REGPC)
-			ea += 8;
-		if(op & (1<<24))
-			ea += off;
-		rd = (op>>12)&7;
-		if(op & (1<<20)){
-			if(op & (1<<15))
-				fld(fpid2i, rd, ea, 8, ufp);
-			else
-				fld(fpis2i, rd, ea, 4, ufp);
-		}else{
-			if(op & (1<<15))
-				fst(fpii2d, ea, rd, 8, ufp);
-			else
-				fst(fpii2s, ea, rd, 4, ufp);
-		}
-		if((op & (1<<24)) == 0)
-			ea += off;
-		if(op & (1<<21))
-			REG(ur, rn) = ea;
-		return;
-	}
-
-	/*
-	 * CPRT/transfer, 10.3
-	 */
-	if(op & (1<<4)){
-		rd = (op>>12) & 0xF;
-
-		/*
-		 * compare, 10.3.1
-		 */
-		if(rd == 15 && op & (1<<20)){
-			rn = (op>>16)&7;
-			fn = &FR(ufp, rn);
-			if(op & (1<<3)){
-				fm = &fpconst[op&7];
-				if(fpemudebug)
-					tag = 'C';
-			}else{
-				fm = &FR(ufp, op&7);
-				if(fpemudebug)
-					tag = 'F';
-			}
-			switch((op>>21)&7){
-			default:
-				unimp(pc, op);
-			case 4:	/* CMF: Fn :: Fm */
-			case 6:	/* CMFE: Fn :: Fm (with exception) */
-				ur->psr &= ~(N|C|Z|V);
-				ur->psr |= fcmp(fn, fm);
-				break;
-			case 5:	/* CNF: Fn :: -Fm */
-			case 7:	/* CNFE: Fn :: -Fm (with exception) */
-				tmp = *fm;
-				tmp.s ^= 1;
-				ur->psr &= ~(N|C|Z|V);
-				ur->psr |= fcmp(fn, &tmp);
-				break;
-			}
-			if(fpemudebug)
-				print("CMPF	%c%d,F%ld =%#lux\n",
-					tag, rn, op&7, ur->psr>>28);
-			return;
-		}
-
-		/*
-		 * other transfer, 10.3
-		 */
-		switch((op>>20)&0xF){
-		default:
-			unimp(pc, op);
-		case 0:	/* FLT */
-			rn = (op>>16) & 7;
-			fpiw2i(&FR(ufp, rn), &REG(ur, rd));
-			if(fpemudebug)
-				print("MOVW[FD]	R%d, F%d\n", rd, rn);
-			break;
-		case 1:	/* FIX */
-			if(op & (1<<3))
-				unimp(pc, op);
-			rn = op & 7;
-			tmp = FR(ufp, rn);
-			fpii2w(&REG(ur, rd), &tmp);
-			if(fpemudebug)
-				print("MOV[FD]W	F%d, R%d =%ld\n", rn, rd, REG(ur, rd));
-			break;
-		case 2:	/* FPSR := Rd */
-			ufp->status = REG(ur, rd);
-			if(fpemudebug)
-				print("MOVW	R%d, FPSR\n", rd);
-			break;
-		case 3:	/* Rd := FPSR */
-			REG(ur, rd) = ufp->status;
-			if(fpemudebug)
-				print("MOVW	FPSR, R%d\n", rd);
-			break;
-		case 4:	/* FPCR := Rd */
-			ufp->control = REG(ur, rd);
-			if(fpemudebug)
-				print("MOVW	R%d, FPCR\n", rd);
-			break;
-		case 5:	/* Rd := FPCR */
-			REG(ur, rd) = ufp->control;
-			if(fpemudebug)
-				print("MOVW	FPCR, R%d\n", rd);
-			break;
-		}
-		return;
-	}
-
-	/*
-	 * arithmetic
-	 */
-
-	if(op & (1<<3)){	/* constant */
-		fm = &fpconst[op&7];
-		if(fpemudebug)
-			tag = 'C';
-	}else{
-		fm = &FR(ufp, op&7);
-		if(fpemudebug)
-			tag = 'F';
-	}
-	rd = (op>>12)&7;
-	o = (op>>20)&0xF;
-	if(op & (1<<15)){	/* monadic */
-		FP1 *fp;
-		fp = &optab1[o];
-		if(fp->f == nil)
-			unimp(pc, op);
-		if(fpemudebug)
-			print("%s	%c%ld,F%d\n", fp->name, tag, op&7, rd);
-		(*fp->f)(fm, &FR(ufp, rd));
-	} else {
-		FP2 *fp;
-		fp = &optab2[o];
-		if(fp->f == nil)
-			unimp(pc, op);
-		rn = (op>>16)&7;
-		if(fpemudebug)
-			print("%s	%c%ld,F%d,F%d\n", fp->name, tag, op&7, rn, rd);
-		(*fp->f)(*fm, FR(ufp, rn), &FR(ufp, rd));
-	}
-}
-
-static void
-vfpoptoi(Internal *fm, uchar o2, uchar o4)
-{
-	fm->s = o2>>3;
-	fm->e = ((o2>>3) | ~(o2 & 4)) - 3 + ExpBias;
-	fm->l = 0;
-	fm->h = o4 << (20+NGuardBits);
-	if(fm->e)
-		fm->h |= HiddenBit;
-	else
-		fm->e++;
-}
-
-static void
-vfpemu(ulong pc, ulong op, Ureg *ur, FPsave *ufp)
-{
-	int sz, vd, o1, o2, o3, o4, o, tag;
-	long off;
-	ulong ea;
-	Word w;
-	
-	Internal *fm, fc;
-
-	/* note: would update fault status here if we noted numeric exceptions */
-
-	sz = op & (1<<8);
-	o1 = (op>>20) & 0xF;
-	o2 = (op>>16) & 0xF;
-	vd = (op>>12) & 0xF;
-
-	switch((op>>24) & 0xF){
-	default:
-		unimp(pc, op);
-	case 0xD:
-		/* 
-		 * Extension Register load/store A7.6 
-		 */
-		off = (op&0xFF)<<2;
-		if((op & (1<<23)) == 0)
-			off = -off;
-		ea = REG(ur, o2) + off;
-		switch(o1&0x7){	/* D(Bit 22) = 0 (5l) */
-		default:
-			unimp(pc, op);
-		case 0:
-			if(sz)
-				fst(fpii2d, ea, vd, sz, ufp);
-			else
-				fst(fpii2s, ea, vd, sz, ufp);
-			break;
-		case 1:
-			if(sz)
-				fld(fpid2i, vd, ea, sz, ufp);
-			else
-				fld(fpis2i, vd, ea, sz, ufp);
-			break;
-		}
-		break;
-	case 0xE:
-		if(op & (1<<4)){
-			/* 
-			 * Register transfer between Core & Extension A7.8
-			 */
-			if(sz)	/* C(Bit 8) != 0 */
-				unimp(pc, op);
-			switch(o1){
-			default:
-				unimp(pc, op);
-			case 0:	/* Fn := Rt */
-				*((Word*)&FR(ufp, o2)) = REG(ur, vd);
-				if(fpemudebug)
-					print("MOVWF	R%d, F%d\n", vd, o2);
-				break;
-			case 1:	/* Rt := Fn */
-				REG(ur, vd) = *((Word*)&FR(ufp, o2));
-				if(fpemudebug)
-					print("MOVFW	F%d, R%d =%ld\n", o2, vd, REG(ur, vd));
-				break;
-			case 0xE:	/* FPSCR := Rt */
-				ufp->status = REG(ur, vd);
-				if(fpemudebug)
-					print("MOVW	R%d, FPSCR\n", vd);
-				break;
-			case 0xF:	/* Rt := FPSCR */
-				if(vd == 0xF){
-					ur->psr = ufp->status;
-					if(fpemudebug)
-						print("MOVW	FPSCR, PSR\n");
-				}else{
-					REG(ur, vd) = ufp->status;
-					if(fpemudebug)
-						print("MOVW	FPSCR, R%d\n", vd);
-				}
-				break;
-			}
-		}
-		else{
-			/*
-			 * VFP data processing instructions A7.5
-			 * Note: As per 5l we ignore (D, N, M) bits
-			 */
-			if(fpemudebug)
-				tag = 'F';
-			o3 = (op>>6) & 0x3;
-			o4 = op & 0xF;
-			fm = &FR(ufp, o4);
-
-			if(o1 == 0xB){	/* A7-17 */
-				if(o3 & 0x1){
-					switch(o2){
-					default:
-						o = (o2<<1) | (o3>>1);
-						break;
-					case 0x8:	/* CVT int -> float/double */
-						w = *((Word*)fm);
-						fpiw2i(&FR(ufp, vd), &w);
-						if(fpemudebug)
-							print("CVTW%c	F%d, F%d\n", sz?'D':'F', o4, vd);
-						return;
-					case 0xD:	/* CVT float/double -> int */
-						fpii2w(&w, fm);
-						*((Word*)&FR(ufp, vd)) = w;
-						if(fpemudebug)
-							print("CVT%cW	F%d, F%d\n", sz?'D':'F', o4, vd);
-						return;
-					case 0x5:	/* CMPF(E) */
-							fm = &fpconst[0];
-							if(fpemudebug)
-								tag = 'C';
-					case 0x4:	/* CMPF(E) */
-						ufp->status &= ~(N|C|Z|V);
-						ufp->status |= fcmp(&FR(ufp, vd), fm);
-						if(fpemudebug)
-							print("CMPF	%c%d,F%d =%#lux\n",
-									tag, (o2&0x1)? 0: o4, vd, ufp->status>>28);
-						return;
-					}
-				}else{	/* VMOV imm (VFPv3 & v4) (5l doesn't generate) */
-					vfpoptoi(&fc, o2, o4);
-					fm = &fc;
-					o = 0;
-					if(fpemudebug)
-						tag = 'C';
-				}
-				FP1 *vfp;
-				vfp = &voptab1[o];
-				if(vfp->f == nil)
-					unimp(pc, op);
-				if(fpemudebug)
-					print("%s	%c%d,F%d\n", vfp->name, tag, o4, vd);
-				(*vfp->f)(fm, &FR(ufp, vd));
-			}
-			else {	/* A7-16 */
-				FP2 *vfp;
-				o = ((o1&0x3)<<1) | (o1&0x8) | (o3&0x1);
-				vfp = &voptab2[o];
-				if(vfp->f == nil)
-					unimp(pc, op);
-				if(fpemudebug)
-					print("%s	F%d,F%d,F%d\n", vfp->name, o4, o2, vd);
-				(*vfp->f)(*fm, FR(ufp, o2), &FR(ufp, vd));
-			}
-		}
-		break;
-	}
-}
-
-void
-casemu(ulong pc, ulong op, Ureg *ur)
-{
-	ulong *rp, ro, rn, *rd;
-
-	USED(pc);
-
-	rp = (ulong*)ur;
-	ro = rp[op>>16 & 0x7];
-	rn = rp[op>>0 & 0x7];
-	rd = rp + (op>>12 & 0x7);
-	rp = (ulong*)*rd;
-	validaddr((uintptr)rp, 4, 1);
-	splhi();
-	if(*rd = (*rp == ro))
-		*rp = rn;
-	spllo();
-}
-
-int ldrexvalid;
-
-void
-ldrex(ulong pc, ulong op, Ureg *ur)
-{
-	ulong *rp, *rd, *addr;
-
-	USED(pc);
-
-	rp = (ulong*)ur;
-	rd = rp + (op>>16 & 0x7);
-	addr = (ulong*)*rd;
-	validaddr((uintptr)addr, 4, 0);
-	ldrexvalid = 1;
-	rp[op>>12 & 0x7] = *addr;
-	if(fpemudebug)
-		print("ldrex, r%ld = [r%ld]@0x%8.8p = 0x%8.8lux",
-			op>>12 & 0x7, op>>16 & 0x7, addr, rp[op>>12 & 0x7]);
-}
-
-void
-strex(ulong pc, ulong op, Ureg *ur)
-{
-	ulong *rp, rn, *rd, *addr;
-
-	USED(pc);
-
-	rp = (ulong*)ur;
-	rd = rp + (op>>16 & 0x7);
-	rn = rp[op>>0 & 0x7];
-	addr = (ulong*)*rd;
-	validaddr((uintptr)addr, 4, 1);
-	splhi();
-	if(ldrexvalid){
-		if(fpemudebug)
-			print("strex valid, [r%ld]@0x%8.8p = r%ld = 0x%8.8lux",
-				op>>16 & 0x7, addr, op>>0 & 0x7, rn);
-		*addr = rn;
-		ldrexvalid = 0;
-		rp[op>>12 & 0x7] = 0;
-	}else{
-		if(fpemudebug)
-			print("strex invalid, r%ld = 1", op>>16 & 0x7);
-		rp[op>>12 & 0x7] = 1;
-	}
-	spllo();
-}
-
-struct {
-	ulong	opc;
-	ulong	mask;
-	void	(*f)(ulong, ulong, Ureg*);
-} specialopc[] = {
-	{ 0x01900f9f, 0x0ff00fff, ldrex },
-	{ 0x01800f90, 0x0ff00ff0, strex },
-	{ 0x0ed00100, 0x0ef08100, casemu },
-	{ 0x00000000, 0x00000000, nil }
-};
-
-/*
- * returns the number of FP instructions emulated
- */
-int
-fpiarm(Ureg *ur)
-{
-	ulong op, o, cp;
-	FPsave *ufp;
-	int i, n;
-
-	if(up == nil)
-		panic("fpiarm not in a process");
-	ufp = up->fpsave;
-	/*
-	 * because all the emulated fp state is in the proc structure,
-	 * it need not be saved/restored
-	 */
-	if(up->fpstate != FPactive){
-//		assert(sizeof(Internal) == sizeof(ufp->regs[0]));
-		up->fpstate = FPactive;
-		ufp->control = 0;
-		ufp->status = (0x01<<28)|(1<<12);	/* software emulation, alternative C flag */
-		for(n = 0; n < Nfpctlregs; n++)
-			FR(ufp, n) = fpconst[0];
-	}
-	for(n=0; ;n++){
-		validaddr(ur->pc, 4, 0);
-		op = *(ulong*)(ur->pc);
-		if(fpemudebug)
-			print("%#lux: %#8.8lux ", ur->pc, op);
-		o = (op>>24) & 0xF;
-		cp = (op>>8) & 0xF;
-		for(i = 0; specialopc[i].f; i++)
-			if((op & specialopc[i].mask) == specialopc[i].opc)
-				break;
-		if(specialopc[i].f){
-			if(condok(ur->psr, op>>28))
-				specialopc[i].f(ur->pc, op, ur);
-		}
-		else if(ISVFPOP(cp, o)){
-			if(condok(ur->psr, op>>28))
-				vfpemu(ur->pc, op, ur, ufp);
-		}
-		else if(ISFPAOP(cp, o)){
-			if(condok(ur->psr, op>>28))
-				fpaemu(ur->pc, op, ur, ufp);
-		}
-		else
-			break;
-
-		ur->pc += 4;		/* pretend cpu executed the instr */
-	}
-	if(fpemudebug)
-		print("\n");
-	return n;
-}
--- a/sys/src/9/kw/fpimem.c
+++ /dev/null
@@ -1,136 +1,0 @@
-#include "fpi.h"
-
-/*
- * the following routines depend on memory format, not the machine
- */
-
-void
-fpis2i(Internal *i, void *v)
-{
-	Single *s = v;
-
-	i->s = (*s & 0x80000000) ? 1: 0;
-	if((*s & ~0x80000000) == 0){
-		SetZero(i);
-		return;
-	}
-	i->e = ((*s>>23) & 0x00FF) - SingleExpBias + ExpBias;
-	i->h = (*s & 0x007FFFFF)<<(1+NGuardBits);
-	i->l = 0;
-	if(i->e)
-		i->h |= HiddenBit;
-	else
-		i->e++;
-}
-
-void
-fpid2i(Internal *i, void *v)
-{
-	Double *d = v;
-
-	i->s = (d->h & 0x80000000) ? 1: 0;
-	i->e = (d->h>>20) & 0x07FF;
-	i->h = ((d->h & 0x000FFFFF)<<(4+NGuardBits))|((d->l>>25) & 0x7F);
-	i->l = (d->l & 0x01FFFFFF)<<NGuardBits;
-	if(i->e)
-		i->h |= HiddenBit;
-	else
-		i->e++;
-}
-
-void
-fpiw2i(Internal *i, void *v)
-{
-	Word w, word = *(Word*)v;
-	short e;
-
-	if(word < 0){
-		i->s = 1;
-		word = -word;
-	}
-	else
-		i->s = 0;
-	if(word == 0){
-		SetZero(i);
-		return;
-	}
-	if(word > 0){
-		for (e = 0, w = word; w; w >>= 1, e++)
-			;
-	} else
-		e = 32;
-	if(e > FractBits){
-		i->h = word>>(e - FractBits);
-		i->l = (word & ((1<<(e - FractBits)) - 1))<<(2*FractBits - e);
-	}
-	else {
-		i->h = word<<(FractBits - e);
-		i->l = 0;
-	}
-	i->e = (e - 1) + ExpBias;
-}
-
-void
-fpii2s(void *v, Internal *i)
-{
-	short e;
-	Single *s = (Single*)v;
-
-	fpiround(i);
-	if(i->h & HiddenBit)
-		i->h &= ~HiddenBit;
-	else
-		i->e--;
-	*s = i->s ? 0x80000000: 0;
-	e = i->e;
-	if(e < ExpBias){
-		if(e <= (ExpBias - SingleExpBias))
-			return;
-		e = SingleExpBias - (ExpBias - e);
-	}
-	else  if(e >= (ExpBias + (SingleExpMax-SingleExpBias))){
-		*s |= SingleExpMax<<23;
-		return;
-	}
-	else
-		e = SingleExpBias + (e - ExpBias);
-	*s |= (e<<23)|(i->h>>(1+NGuardBits));
-}
-
-void
-fpii2d(void *v, Internal *i)
-{
-	Double *d = (Double*)v;
-
-	fpiround(i);
-	if(i->h & HiddenBit)
-		i->h &= ~HiddenBit;
-	else
-		i->e--;
-	i->l = ((i->h & GuardMask)<<25)|(i->l>>NGuardBits);
-	i->h >>= NGuardBits;
-	d->h = i->s ? 0x80000000: 0;
-	d->h |= (i->e<<20)|((i->h & 0x00FFFFFF)>>4);
-	d->l = (i->h<<28)|i->l;
-}
-
-void
-fpii2w(Word *word, Internal *i)
-{
-	Word w;
-	short e;
-
-	fpiround(i);
-	e = (i->e - ExpBias) + 1;
-	if(e <= 0)
-		w = 0;
-	else if(e > 31)
-		w = 0x7FFFFFFF;
-	else if(e > FractBits)
-		w = (i->h<<(e - FractBits))|(i->l>>(2*FractBits - e));
-	else
-		w = i->h>>(FractBits-e);
-	if(i->s)
-		w = -w;
-	*word = w;
-}
--- a/sys/src/9/kw/mkfile
+++ b/sys/src/9/kw/mkfile
@@ -124,7 +124,20 @@
 archkw.$O devether.$O ether1116.$O ethermii.$O: \
 	../port/ethermii.h ../port/etherif.h ../port/netif.h
 archkw.$O devflash.$O flashkw.$O: ../port/flashif.h
-fpi.$O fpiarm.$O fpimem.$O: fpi.h
+
+fpi.$O fpiarm.$O fpimem.$O: ../omap/fpi.h
+fpi.$O:	../omap/fpi.c
+	$CC $CFLAGS -. ../omap/fpi.c
+fpiarm.$O:	../omap/fpiarm.c
+	$CC $CFLAGS -. ../omap/fpiarm.c
+fpimem.$O:	../omap/fpimem.c
+	$CC $CFLAGS -. ../omap/fpimem.c
+
+softfpu.$O:	../omap/softfpu.c
+	$CC $CFLAGS -. ../omap/softfpu.c
+syscall.$O:	../omap/syscall.c
+	$CC $CFLAGS -. ../omap/syscall.c
+
 l.$O lexception.$O lproc.$O mmu.$O rebootcode.$O: arm.s arm.h mem.h
 main.$O:	errstr.h rebootcode.i
 mouse.$O:	screen.h
--- a/sys/src/9/kw/softfpu.c
+++ /dev/null
@@ -1,104 +1,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-
-int
-fpudevprocio(Proc* proc, void* a, long n, uintptr offset, int write)
-{
-	/*
-	 * Called from procdevtab.read and procdevtab.write
-	 * allow user process access to the FPU registers.
-	 * This is the only FPU routine which is called directly
-	 * from the port code; it would be nice to have dynamic
-	 * creation of entries in the device file trees...
-	 */
-	USED(proc, a, n, offset, write);
-
-	return 0;
-}
-
-void
-fpunotify(void)
-{
-	/*
-	 * Called when a note is about to be delivered to a
-	 * user process, usually at the end of a system call.
-	 * Note handlers are not allowed to use the FPU so
-	 * the state is marked (after saving if necessary) and
-	 * checked in the Device Not Available handler.
-	 */
-}
-
-void
-fpunoted(void)
-{
-	/*
-	 * Called from sysnoted() via the machine-dependent
-	 * noted() routine.
-	 * Clear the flag set above in fpunotify().
-	 */
-}
-
-FPsave*
-notefpsave(Proc*)
-{
-	return nil;
-}
-
-void
-fpuprocsave(Proc*)
-{
-	/*
-	 * Called from sched() and sleep() via the machine-dependent
-	 * procsave() routine.
-	 * About to go in to the scheduler.
-	 * If the process wasn't using the FPU
-	 * there's nothing to do.
-	 */
-}
-
-void
-fpuprocrestore(Proc*)
-{
-	/*
-	 * The process has been rescheduled and is about to run.
-	 * Nothing to do here right now. If the process tries to use
-	 * the FPU again it will cause a Device Not Available
-	 * exception and the state will then be restored.
-	 */
-}
-
-void
-fpusysprocsetup(Proc*)
-{
-	/*
-	 * Disable the FPU.
-	 * Called from sysexec() via sysprocsetup() to
-	 * set the FPU for the new process.
-	 */
-}
-
-void
-fpuinit(void)
-{
-}
-
-int
-fpuemu(Ureg* ureg)
-{
-	int nfp;
-
-	if(waserror()){
-		splhi();
-		postnote(up, 1, up->errstr, NDebug);
-		return 1;
-	}
-	spllo();
-	nfp = fpiarm(ureg);
-	splhi();
-	poperror();
-
-	return nfp;
-}
--- a/sys/src/9/kw/syscall.c
+++ /dev/null
@@ -1,293 +1,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "../port/systab.h"
-
-#include <tos.h>
-#include "ureg.h"
-
-#include "arm.h"
-
-typedef struct {
-	uintptr	ip;
-	Ureg*	arg0;
-	char*	arg1;
-	char	msg[ERRMAX];
-	Ureg*	old;
-	Ureg	ureg;
-} NFrame;
-
-/*
- *   Return user to state before notify()
- */
-static void
-noted(Ureg* cur, uintptr arg0)
-{
-	NFrame *nf;
-	Ureg *nur;
-
-	qlock(&up->debug);
-	if(arg0 != NRSTR && !up->notified){
-		qunlock(&up->debug);
-		pprint("call to noted() when not notified\n");
-		pexit("Suicide", 0);
-	}
-	up->notified = 0;
-
-	splhi();
-	fpunoted();
-	spllo();
-
-	nf = up->ureg;
-
-	/* sanity clause */
-	if(!okaddr((uintptr)nf, sizeof(NFrame), 0)){
-		qunlock(&up->debug);
-		pprint("bad ureg in noted %#p\n", nf);
-		pexit("Suicide", 0);
-	}
-
-	/* don't let user change system flags */
-	nur = &nf->ureg;
-	nur->psr &= PsrMask|PsrDfiq|PsrDirq;
-	nur->psr |= (cur->psr & ~(PsrMask|PsrDfiq|PsrDirq));
-
-	memmove(cur, nur, sizeof(Ureg));
-
-	switch((int)arg0){
-	case NCONT:
-	case NRSTR:
-		if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->sp, BY2WD, 0)){
-			qunlock(&up->debug);
-			pprint("suicide: trap in noted\n");
-			pexit("Suicide", 0);
-		}
-		up->ureg = nf->old;
-		qunlock(&up->debug);
-		break;
-	case NSAVE:
-		if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->sp, BY2WD, 0)){
-			qunlock(&up->debug);
-			pprint("suicide: trap in noted\n");
-			pexit("Suicide", 0);
-		}
-		qunlock(&up->debug);
-
-		splhi();
-		nf->arg1 = nf->msg;
-		nf->arg0 = &nf->ureg;
-		nf->ip = 0;
-		cur->sp = (uintptr)nf;
-		cur->r0 = (uintptr)nf->arg0;
-		break;
-	default:
-		up->lastnote->flag = NDebug;
-		/*FALLTHROUGH*/
-	case NDFLT:
-		qunlock(&up->debug);
-		if(up->lastnote->flag == NDebug)
-			pprint("suicide: %s\n", up->lastnote->msg);
-		pexit(up->lastnote->msg, up->lastnote->flag != NDebug);
-	}
-}
-
-/*
- *  Call user, if necessary, with note.
- *  Pass user the Ureg struct and the note on his stack.
- */
-int
-notify(Ureg* ureg)
-{
-	uintptr sp;
-	NFrame *nf;
-	char *msg;
-
-	if(up->procctl)
-		procctl();
-	if(up->nnote == 0)
-		return 0;
-
-	spllo();
-	qlock(&up->debug);
-	msg = popnote(ureg);
-	if(msg == nil){
-		qunlock(&up->debug);
-		splhi();
-		return 0;
-	}
-
-	if(!okaddr((uintptr)up->notify, 1, 0)){
-		qunlock(&up->debug);
-		pprint("suicide: notify function address %#p\n", up->notify);
-		pexit("Suicide", 0);
-	}
-
-	sp = ureg->sp - sizeof(NFrame);
-	if(!okaddr(sp, sizeof(NFrame), 1)){
-		qunlock(&up->debug);
-		pprint("suicide: notify stack address %#p\n", sp);
-		pexit("Suicide", 0);
-	}
-
-	nf = (void*)sp;
-	memmove(&nf->ureg, ureg, sizeof(Ureg));
-	nf->old = up->ureg;
-	up->ureg = nf;
-	memmove(nf->msg, msg, ERRMAX);
-	nf->arg1 = nf->msg;
-	nf->arg0 = &nf->ureg;
-	nf->ip = 0;
-
-	ureg->sp = sp;
-	ureg->pc = (uintptr)up->notify;
-	ureg->r0 = (uintptr)nf->arg0;
-
-	splhi();
-	fpunotify();
-	qunlock(&up->debug);
-
-	return 1;
-}
-
-void
-syscall(Ureg* ureg)
-{
-	char *e;
-	u32int s;
-	ulong sp;
-	long ret;
-	int i, scallnr;
-	vlong startns, stopns;
-
-	if(!kenter(ureg))
-		panic("syscall: from kernel: pc %#lux r14 %#lux psr %#lux",
-			ureg->pc, ureg->r14, ureg->psr);
-
-	m->syscall++;
-	up->insyscall = 1;
-	up->pc = ureg->pc;
-
-	scallnr = ureg->r0;
-	up->scallnr = scallnr;
-	spllo();
-	sp = ureg->sp;
-
-	up->nerrlab = 0;
-	ret = -1;
-	if(!waserror()){
-		if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD))
-			validaddr(sp, sizeof(Sargs)+BY2WD, 0);
-		up->s = *((Sargs*)(sp+BY2WD));
-		if(up->procctl == Proc_tracesyscall){
-			syscallfmt(scallnr, ureg->pc, (va_list)up->s.args);
-			s = splhi();
-			up->procctl = Proc_stopme;
-			procctl();
-			splx(s);
-			todget(nil, &startns);
-		}
-		if(scallnr >= nsyscall || systab[scallnr] == nil){
-			postnote(up, 1, "sys: bad sys call", NDebug);
-			error(Ebadarg);
-		}
-		up->psstate = sysctab[scallnr];
-		ret = systab[scallnr]((va_list)up->s.args);
-		poperror();
-	}else{
-		/* failure: save the error buffer for errstr */
-		e = up->syserrstr;
-		up->syserrstr = up->errstr;
-		up->errstr = e;
-	}
-	if(up->nerrlab){
-		print("bad errstack [%d]: %d extra\n", scallnr, up->nerrlab);
-		for(i = 0; i < NERR; i++)
-			print("sp=%#p pc=%#p\n",
-				up->errlab[i].sp, up->errlab[i].pc);
-		panic("error stack");
-	}
-
-	/*
-	 *  Put return value in frame.  On the x86 the syscall is
-	 *  just another trap and the return value from syscall is
-	 *  ignored.  On other machines the return value is put into
-	 *  the results register by caller of syscall.
-	 */
-	ureg->r0 = ret;
-
-	if(up->procctl == Proc_tracesyscall){
-		todget(nil, &stopns);
-		sysretfmt(scallnr, (va_list)up->s.args, ret, startns, stopns);
-		s = splhi();
-		up->procctl = Proc_stopme;
-		procctl();
-		splx(s);
-	}
-
-	up->insyscall = 0;
-	up->psstate = 0;
-
-	if(scallnr == NOTED)
-		noted(ureg, *((ulong*)up->s.args));
-
-	splhi();
-	if(scallnr != RFORK && (up->procctl || up->nnote))
-		notify(ureg);
-
-	/* if we delayed sched because we held a lock, sched now */
-	if(up->delaysched)
-		sched();
-	kexit(ureg);
-}
-
-uintptr
-execregs(uintptr entry, ulong ssize, ulong nargs)
-{
-	ulong *sp;
-	Ureg *ureg;
-
-	sp = (ulong*)(USTKTOP - ssize);
-	*--sp = nargs;
-
-	ureg = up->dbgreg;
-//	memset(ureg, 0, 15*sizeof(ulong));
-	ureg->r13 = (ulong)sp;
-	ureg->pc = entry;
-//print("%lud: EXECREGS pc %#ux sp %#ux nargs %ld\n", up->pid, ureg->pc, ureg->r13, nargs);
-
-	/*
-	 * return the address of kernel/user shared data
-	 * (e.g. clock stuff)
-	 */
-	return USTKTOP-sizeof(Tos);
-}
-
-void
-sysprocsetup(Proc* p)
-{
-	fpusysprocsetup(p);
-}
-
-/* 
- *  Craft a return frame which will cause the child to pop out of
- *  the scheduler in user mode with the return register zero.  Set
- *  pc to point to a l.s return function.
- */
-void
-forkchild(Proc *p, Ureg *ureg)
-{
-	Ureg *cureg;
-
-//print("%lud setting up for forking child %lud\n", up->pid, p->pid);
-	p->sched.sp = (ulong)p-sizeof(Ureg);
-	p->sched.pc = (ulong)forkret;
-
-	cureg = (Ureg*)(p->sched.sp);
-	memmove(cureg, ureg, sizeof(Ureg));
-
-	/* syscall returns 0 for child */
-	cureg->r0 = 0;
-}
--- a/sys/src/9/omap/beagle
+++ b/sys/src/9/omap/beagle
@@ -59,7 +59,6 @@
 	rdb
 	coproc
 	dma
-	mouse
 #	sdaoe		sdscsi
 	softfpu
 	uarti8250
--- a/sys/src/9/omap/fpi.c
+++ b/sys/src/9/omap/fpi.c
@@ -2,7 +2,7 @@
  * Floating Point Interpreter.
  * shamelessly stolen from an original by ark.
  */
-#include "fpi.h"
+#include "../omap/fpi.h"
 
 void
 fpiround(Internal *i)
--- a/sys/src/9/omap/fpiarm.c
+++ b/sys/src/9/omap/fpiarm.c
@@ -13,7 +13,8 @@
 #include	"ureg.h"
 
 #include	"arm.h"
-#include	"fpi.h"
+
+#include	"../omap/fpi.h"
 
 /* undef this if correct kernel r13 isn't in Ureg;
  * check calculation in fpiarm below
--- a/sys/src/9/omap/fpimem.c
+++ b/sys/src/9/omap/fpimem.c
@@ -1,4 +1,4 @@
-#include "fpi.h"
+#include "../omap/fpi.h"
 
 /*
  * the following routines depend on memory format, not the machine
--- a/sys/src/9/omap/mkfile
+++ b/sys/src/9/omap/mkfile
@@ -33,6 +33,7 @@
 	qio.$O\
 	qlock.$O\
 	segment.$O\
+	syscallfmt.$O\
 	sysfile.$O\
 	sysproc.$O\
 	taslock.$O\
@@ -107,7 +108,7 @@
 l.$O lexception.$O lproc.$O mmu.$O rebootcode.$O: arm.s arm.h mem.h
 l.$O rebootcode.$O: cache.v7.s
 main.$O: errstr.h rebootcode.i
-devdss.$O devmouse.$O mouse.$O screen.$O: screen.h
+devdss.$O devmouse.$O screen.$O: screen.h
 devusb.$O: ../port/usb.h
 usbehci.$O usbohci.$O usbuhci.$O: ../port/usb.h usbehci.h
 
--- a/sys/src/9/omap/mouse.c
+++ /dev/null
@@ -1,66 +1,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "io.h"
-
-#define	Image	IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-static QLock mousectlqlock;
-static int accelerated;
-
-enum
-{
-	CMaccelerated,
-	CMlinear,
-};
-
-static Cmdtab mousectlmsg[] =
-{
-	CMaccelerated,		"accelerated",		0,
-	CMlinear,		"linear",		1,
-};
-
-
-static void
-setaccelerated(int x)
-{
-	accelerated = x;
-	mouseaccelerate(x);
-}
-
-static void
-setlinear(void)
-{
-	accelerated = 0;
-	mouseaccelerate(0);
-}
-
-void
-mousectl(Cmdbuf *cb)
-{
-	Cmdtab *ct;
-
-	qlock(&mousectlqlock);
-	if(waserror()){
-		qunlock(&mousectlqlock);
-		nexterror();
-	}
-	ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
-	switch(ct->index){
-	case CMaccelerated:
-		setaccelerated(cb->nf == 1? 1: atoi(cb->f[1]));
-		break;
-	case CMlinear:
-		setlinear();
-		break;
-	}
-	qunlock(&mousectlqlock);
-	poperror();
-}
--- a/sys/src/9/omap/screen.c
+++ b/sys/src/9/omap/screen.c
@@ -313,6 +313,33 @@
 }
 
 /* called from devmouse */
+enum
+{
+	CMaccelerated,
+	CMlinear,
+};
+
+static Cmdtab mousectlmsg[] =
+{
+	CMaccelerated,		"accelerated",		0,
+	CMlinear,		"linear",		1,
+};
+
+void
+mousectl(Cmdbuf *cb)
+{
+	Cmdtab *ct;
+
+	ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
+	switch(ct->index){
+	case CMaccelerated:
+		mouseaccelerate(cb->nf == 1? 1: atoi(cb->f[1]));
+		break;
+	case CMlinear:
+		mouseaccelerate(0);
+		break;
+	}
+}
 
 void
 cursoron(void)
--- a/sys/src/9/teg2/fns.h
+++ b/sys/src/9/teg2/fns.h
@@ -142,6 +142,7 @@
 
 extern int fpiarm(Ureg*);
 extern int fpudevprocio(Proc*, void*, long, uintptr, int);
+extern FPalloc *fpalloc(void);
 extern void fpuinit(void);
 extern void fpunoted(void);
 extern void fpunotify(void);
--- a/sys/src/9/teg2/fpi.c
+++ /dev/null
@@ -1,300 +1,0 @@
-/*
- * Floating Point Interpreter.
- * shamelessly stolen from an original by ark.
- */
-#include "fpi.h"
-
-void
-fpiround(Internal *i)
-{
-	unsigned long guard;
-
-	guard = i->l & GuardMask;
-	i->l &= ~GuardMask;
-	if(guard > (LsBit>>1) || (guard == (LsBit>>1) && (i->l & LsBit))){
-		i->l += LsBit;
-		if(i->l & CarryBit){
-			i->l &= ~CarryBit;
-			i->h++;
-			if(i->h & CarryBit){
-				if (i->h & 0x01)
-					i->l |= CarryBit;
-				i->l >>= 1;
-				i->h >>= 1;
-				i->e++;
-			}
-		}
-	}
-}
-
-static void
-matchexponents(Internal *x, Internal *y)
-{
-	int count;
-
-	count = y->e - x->e;
-	x->e = y->e;
-	if(count >= 2*FractBits){
-		x->l = x->l || x->h;
-		x->h = 0;
-		return;
-	}
-	if(count >= FractBits){
-		count -= FractBits;
-		x->l = x->h|(x->l != 0);
-		x->h = 0;
-	}
-	while(count > 0){
-		count--;
-		if(x->h & 0x01)
-			x->l |= CarryBit;
-		if(x->l & 0x01)
-			x->l |= 2;
-		x->l >>= 1;
-		x->h >>= 1;
-	}
-}
-
-static void
-shift(Internal *i)
-{
-	i->e--;
-	i->h <<= 1;
-	i->l <<= 1;
-	if(i->l & CarryBit){
-		i->l &= ~CarryBit;
-		i->h |= 0x01;
-	}
-}
-
-static void
-normalise(Internal *i)
-{
-	while((i->h & HiddenBit) == 0)
-		shift(i);
-}
-
-static void
-renormalise(Internal *i)
-{
-	if(i->e < -2 * FractBits)
-		i->e = -2 * FractBits;
-	while(i->e < 1){
-		i->e++;
-		if(i->h & 0x01)
-			i->l |= CarryBit;
-		i->h >>= 1;
-		i->l = (i->l>>1)|(i->l & 0x01);
-	}
-	if(i->e >= ExpInfinity)
-		SetInfinity(i);
-}
-
-void
-fpinormalise(Internal *x)
-{
-	if(!IsWeird(x) && !IsZero(x))
-		normalise(x);
-}
-
-void
-fpiadd(Internal *x, Internal *y, Internal *i)
-{
-	Internal *t;
-
-	i->s = x->s;
-	if(IsWeird(x) || IsWeird(y)){
-		if(IsNaN(x) || IsNaN(y))
-			SetQNaN(i);
-		else
-			SetInfinity(i);
-		return;
-	}
-	if(x->e > y->e){
-		t = x;
-		x = y;
-		y = t;
-	}
-	matchexponents(x, y);
-	i->e = x->e;
-	i->h = x->h + y->h;
-	i->l = x->l + y->l;
-	if(i->l & CarryBit){
-		i->h++;
-		i->l &= ~CarryBit;
-	}
-	if(i->h & (HiddenBit<<1)){
-		if(i->h & 0x01)
-			i->l |= CarryBit;
-		i->l = (i->l>>1)|(i->l & 0x01);
-		i->h >>= 1;
-		i->e++;
-	}
-	if(IsWeird(i))
-		SetInfinity(i);
-}
-
-void
-fpisub(Internal *x, Internal *y, Internal *i)
-{
-	Internal *t;
-
-	if(y->e < x->e
-	   || (y->e == x->e && (y->h < x->h || (y->h == x->h && y->l < x->l)))){
-		t = x;
-		x = y;
-		y = t;
-	}
-	i->s = y->s;
-	if(IsNaN(y)){
-		SetQNaN(i);
-		return;
-	}
-	if(IsInfinity(y)){
-		if(IsInfinity(x))
-			SetQNaN(i);
-		else
-			SetInfinity(i);
-		return;
-	}
-	matchexponents(x, y);
-	i->e = y->e;
-	i->h = y->h - x->h;
-	i->l = y->l - x->l;
-	if(i->l < 0){
-		i->l += CarryBit;
-		i->h--;
-	}
-	if(i->h == 0 && i->l == 0)
-		SetZero(i);
-	else while(i->e > 1 && (i->h & HiddenBit) == 0)
-		shift(i);
-}
-
-#define	CHUNK		(FractBits/2)
-#define	CMASK		((1<<CHUNK)-1)
-#define	HI(x)		((short)((x)>>CHUNK) & CMASK)
-#define	LO(x)		((short)(x) & CMASK)
-#define	SPILL(x)	((x)>>CHUNK)
-#define	M(x, y)		((long)a[x]*(long)b[y])
-#define	C(h, l)		(((long)((h) & CMASK)<<CHUNK)|((l) & CMASK))
-
-void
-fpimul(Internal *x, Internal *y, Internal *i)
-{
-	long a[4], b[4], c[7], f[4];
-
-	i->s = x->s^y->s;
-	if(IsWeird(x) || IsWeird(y)){
-		if(IsNaN(x) || IsNaN(y) || IsZero(x) || IsZero(y))
-			SetQNaN(i);
-		else
-			SetInfinity(i);
-		return;
-	}
-	else if(IsZero(x) || IsZero(y)){
-		SetZero(i);
-		return;
-	}
-	normalise(x);
-	normalise(y);
-	i->e = x->e + y->e - (ExpBias - 1);
-
-	a[0] = HI(x->h); b[0] = HI(y->h);
-	a[1] = LO(x->h); b[1] = LO(y->h);
-	a[2] = HI(x->l); b[2] = HI(y->l);
-	a[3] = LO(x->l); b[3] = LO(y->l);
-
-	c[6] =                               M(3, 3);
-	c[5] =                     M(2, 3) + M(3, 2) + SPILL(c[6]);
-	c[4] =           M(1, 3) + M(2, 2) + M(3, 1) + SPILL(c[5]);
-	c[3] = M(0, 3) + M(1, 2) + M(2, 1) + M(3, 0) + SPILL(c[4]);
-	c[2] = M(0, 2) + M(1, 1) + M(2, 0)           + SPILL(c[3]);
-	c[1] = M(0, 1) + M(1, 0)                     + SPILL(c[2]);
-	c[0] = M(0, 0)                               + SPILL(c[1]);
-
-	f[0] = c[0];
-	f[1] = C(c[1], c[2]);
-	f[2] = C(c[3], c[4]);
-	f[3] = C(c[5], c[6]);
-
-	if((f[0] & HiddenBit) == 0){
-		f[0] <<= 1;
-		f[1] <<= 1;
-		f[2] <<= 1;
-		f[3] <<= 1;
-		if(f[1] & CarryBit){
-			f[0] |= 1;
-			f[1] &= ~CarryBit;
-		}
-		if(f[2] & CarryBit){
-			f[1] |= 1;
-			f[2] &= ~CarryBit;
-		}
-		if(f[3] & CarryBit){
-			f[2] |= 1;
-			f[3] &= ~CarryBit;
-		}
-		i->e--;
-	}
-	i->h = f[0];
-	i->l = f[1];
-	if(f[2] || f[3])
-		i->l |= 1;
-	renormalise(i);
-}
-
-void
-fpidiv(Internal *x, Internal *y, Internal *i)
-{
-	i->s = x->s^y->s;
-	if(IsNaN(x) || IsNaN(y)
-	   || (IsInfinity(x) && IsInfinity(y)) || (IsZero(x) && IsZero(y))){
-		SetQNaN(i);
-		return;
-	}
-	else if(IsZero(x) || IsInfinity(y)){
-		SetInfinity(i);
-		return;
-	}
-	else if(IsInfinity(x) || IsZero(y)){
-		SetZero(i);
-		return;
-	}
-	normalise(x);
-	normalise(y);
-	i->h = 0;
-	i->l = 0;
-	i->e = y->e - x->e + (ExpBias + 2*FractBits - 1);
-	do{
-		if(y->h > x->h || (y->h == x->h && y->l >= x->l)){
-			i->l |= 0x01;
-			y->h -= x->h;
-			y->l -= x->l;
-			if(y->l < 0){
-				y->l += CarryBit;
-				y->h--;
-			}
-		}
-		shift(y);
-		shift(i);
-	}while ((i->h & HiddenBit) == 0);
-	if(y->h || y->l)
-		i->l |= 0x01;
-	renormalise(i);
-}
-
-int
-fpicmp(Internal *x, Internal *y)
-{
-	if(IsNaN(x) && IsNaN(y))
-		return 0;
-	if(IsInfinity(x) && IsInfinity(y))
-		return y->s - x->s;
-	if(x->e == y->e && x->h == y->h && x->l == y->l)
-		return y->s - x->s;
-	if(x->e < y->e
-	   || (x->e == y->e && (x->h < y->h || (x->h == y->h && x->l < y->l))))
-		return y->s ? 1: -1;
-	return x->s ? -1: 1;
-}
--- a/sys/src/9/teg2/fpi.h
+++ /dev/null
@@ -1,61 +1,0 @@
-typedef long Word;
-typedef unsigned long Single;
-typedef struct {
-	unsigned long l;
-	unsigned long h;
-} Double;
-
-enum {
-	FractBits	= 28,
-	CarryBit	= 0x10000000,
-	HiddenBit	= 0x08000000,
-	MsBit		= HiddenBit,
-	NGuardBits	= 3,
-	GuardMask	= 0x07,
-	LsBit		= (1<<NGuardBits),
-
-	SingleExpBias	= 127,
-	SingleExpMax	= 255,
-	DoubleExpBias	= 1023,
-	DoubleExpMax	= 2047,
-
-	ExpBias		= DoubleExpBias,
-	ExpInfinity	= DoubleExpMax,
-};
-
-typedef struct {
-	unsigned char s;
-	short e;
-	long l;				/* 0000FFFFFFFFFFFFFFFFFFFFFFFFFGGG */
-	long h;				/* 0000HFFFFFFFFFFFFFFFFFFFFFFFFFFF */
-} Internal;
-
-#define IsWeird(n)	((n)->e >= ExpInfinity)
-#define	IsInfinity(n)	(IsWeird(n) && (n)->h == HiddenBit && (n)->l == 0)
-#define	SetInfinity(n)	((n)->e = ExpInfinity, (n)->h = HiddenBit, (n)->l = 0)
-#define IsNaN(n)	(IsWeird(n) && (((n)->h & ~HiddenBit) || (n)->l))
-#define	SetQNaN(n)	((n)->s = 0, (n)->e = ExpInfinity, 		\
-			 (n)->h = HiddenBit|(LsBit<<1), (n)->l = 0)
-#define IsZero(n)	((n)->e == 1 && (n)->h == 0 && (n)->l == 0)
-#define SetZero(n)	((n)->e = 1, (n)->h = 0, (n)->l = 0)
-
-/*
- * fpi.c
- */
-extern void fpiround(Internal *);
-extern void fpiadd(Internal *, Internal *, Internal *);
-extern void fpisub(Internal *, Internal *, Internal *);
-extern void fpimul(Internal *, Internal *, Internal *);
-extern void fpidiv(Internal *, Internal *, Internal *);
-extern int fpicmp(Internal *, Internal *);
-extern void fpinormalise(Internal*);
-
-/*
- * fpimem.c
- */
-extern void fpis2i(Internal *, void *);
-extern void fpid2i(Internal *, void *);
-extern void fpiw2i(Internal *, void *);
-extern void fpii2s(void *, Internal *);
-extern void fpii2d(void *, Internal *);
-extern void fpii2w(Word *, Internal *);
--- a/sys/src/9/teg2/fpiarm.c
+++ /dev/null
@@ -1,691 +1,0 @@
-/*
- * this doesn't attempt to implement ARM floating-point properties
- * that aren't visible in the Inferno environment.
- * all arithmetic is done in double precision.
- * the FP trap status isn't updated.
- */
-#include	"u.h"
-#include	"../port/lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-
-#include	"ureg.h"
-
-#include	"arm.h"
-#include	"fpi.h"
-
-/* undef this if correct kernel r13 isn't in Ureg;
- * check calculation in fpiarm below
- */
-#define	REG(ur, x) (*(long*)(((char*)(ur))+roff[(x)]))
-#define	FR(ufp, x) (*(Internal*)(ufp)->regs[(x)&(Nfpctlregs - 1)])
-
-typedef struct FP2 FP2;
-typedef struct FP1 FP1;
-
-struct FP2 {
-	char*	name;
-	void	(*f)(Internal, Internal, Internal*);
-};
-
-struct FP1 {
-	char*	name;
-	void	(*f)(Internal*, Internal*);
-};
-
-enum {
-	N = 1<<31,
-	Z = 1<<30,
-	C = 1<<29,
-	V = 1<<28,
-	REGPC = 15,
-};
-
-enum {
-	fpemudebug = 0,
-};
-
-#undef OFR
-#define	OFR(X)	((ulong)&((Ureg*)0)->X)
-
-static	int	roff[] = {
-	OFR(r0), OFR(r1), OFR(r2), OFR(r3),
-	OFR(r4), OFR(r5), OFR(r6), OFR(r7),
-	OFR(r8), OFR(r9), OFR(r10), OFR(r11),
-	OFR(r12), OFR(r13), OFR(r14), OFR(pc),
-};
-
-static Internal fpconst[8] = {		/* indexed by op&7 (ARM 7500 FPA) */
-	/* s, e, l, h */
-	{0, 0x1, 0x00000000, 0x00000000}, /* 0.0 */
-	{0, 0x3FF, 0x00000000, 0x08000000},	/* 1.0 */
-	{0, 0x400, 0x00000000, 0x08000000},	/* 2.0 */
-	{0, 0x400, 0x00000000, 0x0C000000},	/* 3.0 */
-	{0, 0x401, 0x00000000, 0x08000000},	/* 4.0 */
-	{0, 0x401, 0x00000000, 0x0A000000},	/* 5.0 */
-	{0, 0x3FE, 0x00000000, 0x08000000},	/* 0.5 */
-	{0, 0x402, 0x00000000, 0x0A000000},	/* 10.0 */
-};
-
-/*
- * arm binary operations
- */
-
-static void
-fadd(Internal m, Internal n, Internal *d)
-{
-	(m.s == n.s? fpiadd: fpisub)(&m, &n, d);
-}
-
-static void
-fsub(Internal m, Internal n, Internal *d)
-{
-	m.s ^= 1;
-	(m.s == n.s? fpiadd: fpisub)(&m, &n, d);
-}
-
-static void
-fsubr(Internal m, Internal n, Internal *d)
-{
-	n.s ^= 1;
-	(n.s == m.s? fpiadd: fpisub)(&n, &m, d);
-}
-
-static void
-fmul(Internal m, Internal n, Internal *d)
-{
-	fpimul(&m, &n, d);
-}
-
-static void
-fdiv(Internal m, Internal n, Internal *d)
-{
-	fpidiv(&m, &n, d);
-}
-
-static void
-fdivr(Internal m, Internal n, Internal *d)
-{
-	fpidiv(&n, &m, d);
-}
-
-/*
- * arm unary operations
- */
-
-static void
-fmov(Internal *m, Internal *d)
-{
-	*d = *m;
-}
-
-static void
-fmovn(Internal *m, Internal *d)
-{
-	*d = *m;
-	d->s ^= 1;
-}
-
-static void
-fabsf(Internal *m, Internal *d)
-{
-	*d = *m;
-	d->s = 0;
-}
-
-static void
-frnd(Internal *m, Internal *d)
-{
-	short e;
-
-	(m->s? fsub: fadd)(fpconst[6], *m, d);
-	if(IsWeird(d))
-		return;
-	fpiround(d);
-	e = (d->e - ExpBias) + 1;
-	if(e <= 0)
-		SetZero(d);
-	else if(e > FractBits){
-		if(e < 2*FractBits)
-			d->l &= ~((1<<(2*FractBits - e))-1);
-	}else{
-		d->l = 0;
-		if(e < FractBits)
-			d->h &= ~((1<<(FractBits-e))-1);
-	}
-}
-
-/*
- * ARM 7500 FPA opcodes
- */
-
-static	FP1	optab1[16] = {	/* Fd := OP Fm */
-[0]	{"MOVF",	fmov},
-[1]	{"NEGF",	fmovn},
-[2]	{"ABSF",	fabsf},
-[3]	{"RNDF",	frnd},
-[4]	{"SQTF",	/*fsqt*/0},
-/* LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN all `deprecated' */
-/* URD and NRM aren't implemented */
-};
-
-static	FP2	optab2[16] = {	/* Fd := Fn OP Fm */
-[0]	{"ADDF",	fadd},
-[1]	{"MULF",	fmul},
-[2]	{"SUBF",	fsub},
-[3]	{"RSUBF",	fsubr},
-[4]	{"DIVF",	fdiv},
-[5]	{"RDIVF",	fdivr},
-/* POW, RPW deprecated */
-[8]	{"REMF",	/*frem*/0},
-[9]	{"FMF",	fmul},	/* fast multiply */
-[10]	{"FDV",	fdiv},	/* fast divide */
-[11]	{"FRD",	fdivr},	/* fast reverse divide */
-/* POL deprecated */
-};
-
-/*
- * ARM VFP opcodes
- */
-
-static	FP1	voptab1[32] = {	/* Vd := OP Vm */
-[0]	{"MOVF",	fmov},
-[1]	{"ABSF",	fabsf},
-[2]	{"NEGF",	fmovn},
-[15]	{"CVTF",	fmov},
-};
-
-static	FP2	voptab2[16] = {	/* Vd := Vn FOP Fm */
-[4]	{"MULF",	fmul},
-[6]	{"ADDF",	fadd},
-[7]	{"SUBF",	fsub},
-[8]	{"DIVF",	fdiv},
-};
-
-static ulong
-fcmp(Internal *n, Internal *m)
-{
-	int i;
-	Internal rm, rn;
-
-	if(IsWeird(m) || IsWeird(n)){
-		/* BUG: should trap if not masked */
-		return V|C;
-	}
-	rn = *n;
-	rm = *m;
-	fpiround(&rn);
-	fpiround(&rm);
-	i = fpicmp(&rn, &rm);
-	if(i > 0)
-		return C;
-	else if(i == 0)
-		return C|Z;
-	else
-		return N;
-}
-
-static void
-fld(void (*f)(Internal*, void*), int d, ulong ea, int n, FPsave *ufp)
-{
-	void *mem;
-
-	mem = (void*)ea;
-	(*f)(&FR(ufp, d), mem);
-	if(fpemudebug)
-		print("MOV%c #%lux, F%d\n", n==8? 'D': 'F', ea, d);
-}
-
-static void
-fst(void (*f)(void*, Internal*), ulong ea, int s, int n, FPsave *ufp)
-{
-	Internal tmp;
-	void *mem;
-
-	mem = (void*)ea;
-	tmp = FR(ufp, s);
-	if(fpemudebug)
-		print("MOV%c	F%d,#%lux\n", n==8? 'D': 'F', s, ea);
-	(*f)(mem, &tmp);
-}
-
-static int
-condok(int cc, int c)
-{
-	switch(c){
-	case 0:	/* Z set */
-		return cc&Z;
-	case 1:	/* Z clear */
-		return (cc&Z) == 0;
-	case 2:	/* C set */
-		return cc&C;
-	case 3:	/* C clear */
-		return (cc&C) == 0;
-	case 4:	/* N set */
-		return cc&N;
-	case 5:	/* N clear */
-		return (cc&N) == 0;
-	case 6:	/* V set */
-		return cc&V;
-	case 7:	/* V clear */
-		return (cc&V) == 0;
-	case 8:	/* C set and Z clear */
-		return cc&C && (cc&Z) == 0;
-	case 9:	/* C clear or Z set */
-		return (cc&C) == 0 || cc&Z;
-	case 10:	/* N set and V set, or N clear and V clear */
-		return (~cc&(N|V))==0 || (cc&(N|V)) == 0;
-	case 11:	/* N set and V clear, or N clear and V set */
-		return (cc&(N|V))==N || (cc&(N|V))==V;
-	case 12:	/* Z clear, and either N set and V set or N clear and V clear */
-		return (cc&Z) == 0 && ((~cc&(N|V))==0 || (cc&(N|V))==0);
-	case 13:	/* Z set, or N set and V clear or N clear and V set */
-		return (cc&Z) || (cc&(N|V))==N || (cc&(N|V))==V;
-	case 14:	/* always */
-		return 1;
-	case 15:	/* never (reserved) */
-		return 0;
-	}
-	return 0;	/* not reached */
-}
-
-static void
-unimp(ulong pc, ulong op)
-{
-	char buf[60];
-
-	snprint(buf, sizeof(buf), "sys: fp: pc=%lux unimp fp 0x%.8lux", pc, op);
-	if(fpemudebug)
-		print("FPE: %s\n", buf);
-	error(buf);
-	/* no return */
-}
-
-static void
-fpaemu(ulong pc, ulong op, Ureg *ur, FPsave *ufp)
-{
-	int rn, rd, tag, o;
-	long off;
-	ulong ea;
-	Internal tmp, *fm, *fn;
-
-	/* note: would update fault status here if we noted numeric exceptions */
-
-	/*
-	 * LDF, STF; 10.1.1
-	 */
-	if(((op>>25)&7) == 6){
-		if(op & (1<<22))
-			unimp(pc, op);	/* packed or extended */
-		rn = (op>>16)&0xF;
-		off = (op&0xFF)<<2;
-		if((op & (1<<23)) == 0)
-			off = -off;
-		ea = REG(ur, rn);
-		if(rn == REGPC)
-			ea += 8;
-		if(op & (1<<24))
-			ea += off;
-		rd = (op>>12)&7;
-		if(op & (1<<20)){
-			if(op & (1<<15))
-				fld(fpid2i, rd, ea, 8, ufp);
-			else
-				fld(fpis2i, rd, ea, 4, ufp);
-		}else{
-			if(op & (1<<15))
-				fst(fpii2d, ea, rd, 8, ufp);
-			else
-				fst(fpii2s, ea, rd, 4, ufp);
-		}
-		if((op & (1<<24)) == 0)
-			ea += off;
-		if(op & (1<<21))
-			REG(ur, rn) = ea;
-		return;
-	}
-
-	/*
-	 * CPRT/transfer, 10.3
-	 */
-	if(op & (1<<4)){
-		rd = (op>>12) & 0xF;
-
-		/*
-		 * compare, 10.3.1
-		 */
-		if(rd == 15 && op & (1<<20)){
-			rn = (op>>16)&7;
-			fn = &FR(ufp, rn);
-			if(op & (1<<3)){
-				fm = &fpconst[op&7];
-				if(fpemudebug)
-					tag = 'C';
-			}else{
-				fm = &FR(ufp, op&7);
-				if(fpemudebug)
-					tag = 'F';
-			}
-			switch((op>>21)&7){
-			default:
-				unimp(pc, op);
-			case 4:	/* CMF: Fn :: Fm */
-			case 6:	/* CMFE: Fn :: Fm (with exception) */
-				ur->psr &= ~(N|C|Z|V);
-				ur->psr |= fcmp(fn, fm);
-				break;
-			case 5:	/* CNF: Fn :: -Fm */
-			case 7:	/* CNFE: Fn :: -Fm (with exception) */
-				tmp = *fm;
-				tmp.s ^= 1;
-				ur->psr &= ~(N|C|Z|V);
-				ur->psr |= fcmp(fn, &tmp);
-				break;
-			}
-			if(fpemudebug)
-				print("CMPF	%c%d,F%ld =%#lux\n",
-					tag, rn, op&7, ur->psr>>28);
-			return;
-		}
-
-		/*
-		 * other transfer, 10.3
-		 */
-		switch((op>>20)&0xF){
-		default:
-			unimp(pc, op);
-		case 0:	/* FLT */
-			rn = (op>>16) & 7;
-			fpiw2i(&FR(ufp, rn), &REG(ur, rd));
-			if(fpemudebug)
-				print("MOVW[FD]	R%d, F%d\n", rd, rn);
-			break;
-		case 1:	/* FIX */
-			if(op & (1<<3))
-				unimp(pc, op);
-			rn = op & 7;
-			tmp = FR(ufp, rn);
-			fpii2w(&REG(ur, rd), &tmp);
-			if(fpemudebug)
-				print("MOV[FD]W	F%d, R%d =%ld\n", rn, rd, REG(ur, rd));
-			break;
-		case 2:	/* FPSR := Rd */
-			ufp->status = REG(ur, rd);
-			if(fpemudebug)
-				print("MOVW	R%d, FPSR\n", rd);
-			break;
-		case 3:	/* Rd := FPSR */
-			REG(ur, rd) = ufp->status;
-			if(fpemudebug)
-				print("MOVW	FPSR, R%d\n", rd);
-			break;
-		case 4:	/* FPCR := Rd */
-			ufp->control = REG(ur, rd);
-			if(fpemudebug)
-				print("MOVW	R%d, FPCR\n", rd);
-			break;
-		case 5:	/* Rd := FPCR */
-			REG(ur, rd) = ufp->control;
-			if(fpemudebug)
-				print("MOVW	FPCR, R%d\n", rd);
-			break;
-		}
-		return;
-	}
-
-	/*
-	 * arithmetic
-	 */
-
-	if(op & (1<<3)){	/* constant */
-		fm = &fpconst[op&7];
-		if(fpemudebug)
-			tag = 'C';
-	}else{
-		fm = &FR(ufp, op&7);
-		if(fpemudebug)
-			tag = 'F';
-	}
-	rd = (op>>12)&7;
-	o = (op>>20)&0xF;
-	if(op & (1<<15)){	/* monadic */
-		FP1 *fp;
-		fp = &optab1[o];
-		if(fp->f == nil)
-			unimp(pc, op);
-		if(fpemudebug)
-			print("%s	%c%ld,F%d\n", fp->name, tag, op&7, rd);
-		(*fp->f)(fm, &FR(ufp, rd));
-	} else {
-		FP2 *fp;
-		fp = &optab2[o];
-		if(fp->f == nil)
-			unimp(pc, op);
-		rn = (op>>16)&7;
-		if(fpemudebug)
-			print("%s	%c%ld,F%d,F%d\n", fp->name, tag, op&7, rn, rd);
-		(*fp->f)(*fm, FR(ufp, rn), &FR(ufp, rd));
-	}
-}
-
-static void
-vfpoptoi(Internal *fm, uchar o2, uchar o4)
-{
-	fm->s = o2>>3;
-	fm->e = ((o2>>3) | ~(o2 & 4)) - 3 + ExpBias;
-	fm->l = 0;
-	fm->h = o4 << (20+NGuardBits);
-	if(fm->e)
-		fm->h |= HiddenBit;
-	else
-		fm->e++;
-}
-
-static void
-vfpemu(ulong pc, ulong op, Ureg *ur, FPsave *ufp)
-{
-	int sz, vd, o1, o2, o3, o4, o, tag;
-	long off;
-	ulong ea;
-	Word w;
-	
-	Internal *fm, fc;
-
-	/* note: would update fault status here if we noted numeric exceptions */
-
-	sz = op & (1<<8);
-	o1 = (op>>20) & 0xF;
-	o2 = (op>>16) & 0xF;
-	vd = (op>>12) & 0xF;
-
-	switch((op>>24) & 0xF){
-	default:
-		unimp(pc, op);
-	case 0xD:
-		/* 
-		 * Extension Register load/store A7.6 
-		 */
-		off = (op&0xFF)<<2;
-		if((op & (1<<23)) == 0)
-			off = -off;
-		ea = REG(ur, o2) + off;
-		switch(o1&0x7){	/* D(Bit 22) = 0 (5l) */
-		default:
-			unimp(pc, op);
-		case 0:
-			if(sz)
-				fst(fpii2d, ea, vd, sz, ufp);
-			else
-				fst(fpii2s, ea, vd, sz, ufp);
-			break;
-		case 1:
-			if(sz)
-				fld(fpid2i, vd, ea, sz, ufp);
-			else
-				fld(fpis2i, vd, ea, sz, ufp);
-			break;
-		}
-		break;
-	case 0xE:
-		if(op & (1<<4)){
-			/* 
-			 * Register transfer between Core & Extension A7.8
-			 */
-			if(sz)	/* C(Bit 8) != 0 */
-				unimp(pc, op);
-			switch(o1){
-			default:
-				unimp(pc, op);
-			case 0:	/* Fn := Rt */
-				*((Word*)&FR(ufp, o2)) = REG(ur, vd);
-				if(fpemudebug)
-					print("MOVWF	R%d, F%d\n", vd, o2);
-				break;
-			case 1:	/* Rt := Fn */
-				REG(ur, vd) = *((Word*)&FR(ufp, o2));
-				if(fpemudebug)
-					print("MOVFW	F%d, R%d =%ld\n", o2, vd, REG(ur, vd));
-				break;
-			case 0xE:	/* FPSCR := Rt */
-				ufp->status = REG(ur, vd);
-				if(fpemudebug)
-					print("MOVW	R%d, FPSCR\n", vd);
-				break;
-			case 0xF:	/* Rt := FPSCR */
-				if(vd == 0xF){
-					ur->psr = ufp->status;
-					if(fpemudebug)
-						print("MOVW	FPSCR, PSR\n");
-				}else{
-					REG(ur, vd) = ufp->status;
-					if(fpemudebug)
-						print("MOVW	FPSCR, R%d\n", vd);
-				}
-				break;
-			}
-		}
-		else{
-			/*
-			 * VFP data processing instructions A7.5
-			 * Note: As per 5l we ignore (D, N, M) bits
-			 */
-			if(fpemudebug)
-				tag = 'F';
-			o3 = (op>>6) & 0x3;
-			o4 = op & 0xF;
-			fm = &FR(ufp, o4);
-
-			if(o1 == 0xB){	/* A7-17 */
-				if(o3 & 0x1){
-					switch(o2){
-					default:
-						o = (o2<<1) | (o3>>1);
-						break;
-					case 0x8:	/* CVT int -> float/double */
-						w = *((Word*)fm);
-						fpiw2i(&FR(ufp, vd), &w);
-						if(fpemudebug)
-							print("CVTW%c	F%d, F%d\n", sz?'D':'F', o4, vd);
-						return;
-					case 0xD:	/* CVT float/double -> int */
-						fpii2w(&w, fm);
-						*((Word*)&FR(ufp, vd)) = w;
-						if(fpemudebug)
-							print("CVT%cW	F%d, F%d\n", sz?'D':'F', o4, vd);
-						return;
-					case 0x5:	/* CMPF(E) */
-							fm = &fpconst[0];
-							if(fpemudebug)
-								tag = 'C';
-					case 0x4:	/* CMPF(E) */
-						ufp->status &= ~(N|C|Z|V);
-						ufp->status |= fcmp(&FR(ufp, vd), fm);
-						if(fpemudebug)
-							print("CMPF	%c%d,F%d =%#lux\n",
-									tag, (o2&0x1)? 0: o4, vd, ufp->status>>28);
-						return;
-					}
-				}else{	/* VMOV imm (VFPv3 & v4) (5l doesn't generate) */
-					vfpoptoi(&fc, o2, o4);
-					fm = &fc;
-					o = 0;
-					if(fpemudebug)
-						tag = 'C';
-				}
-				FP1 *vfp;
-				vfp = &voptab1[o];
-				if(vfp->f == nil)
-					unimp(pc, op);
-				if(fpemudebug)
-					print("%s	%c%d,F%d\n", vfp->name, tag, o4, vd);
-				(*vfp->f)(fm, &FR(ufp, vd));
-			}
-			else {	/* A7-16 */
-				FP2 *vfp;
-				o = ((o1&0x3)<<1) | (o1&0x8) | (o3&0x1);
-				vfp = &voptab2[o];
-				if(vfp->f == nil)
-					unimp(pc, op);
-				if(fpemudebug)
-					print("%s	F%d,F%d,F%d\n", vfp->name, o4, o2, vd);
-				(*vfp->f)(*fm, FR(ufp, o2), &FR(ufp, vd));
-			}
-		}
-		break;
-	}
-}
-
-
-/*
- * returns the number of FP instructions emulated
- */
-int
-fpiarm(Ureg *ur)
-{
-	ulong op, o, cp;
-	FPsave *ufp;
-	int n;
-	void (*fpemu)(ulong , ulong , Ureg *, FPsave *);
-
-	if(up == nil)
-		panic("fpiarm not in a process");
-	ufp = up->fpsave;
-	/*
-	 * because all the emulated fp state is in the proc structure,
-	 * it need not be saved/restored
-	 */
-	switch(up->fpstate){
-	case FPactive:
-	case FPinactive:
-		error("illegal instruction: emulated fpu opcode in VFP mode");
-	case FPinit:
-		assert(sizeof(Internal) <= sizeof(ufp->regs[0]));
-		up->fpstate = FPemu;
-		ufp->control = 0;
-		ufp->status = (0x01<<28)|(1<<12); /* sw emulation, alt. C flag */
-		for(n = 0; n < Nfpctlregs; n++)
-			FR(ufp, n) = fpconst[0];
-	}
-	for(n=0; ;n++){
-		validaddr(ur->pc, 4, 0);
-		op = *(ulong*)(ur->pc);
-		if(fpemudebug)
-			print("%#lux: %#8.8lux ", ur->pc, op);
-		o = (op>>24) & 0xF;
-		cp = (op>>8) & 0xF;
-		if(ISFPAOP(cp, o))
-			fpemu = fpaemu;
-		else if(ISVFPOP(cp, o))
-			fpemu = vfpemu;
-		else
-			break;
-		if(condok(ur->psr, op>>28))
-			fpemu(ur->pc, op, ur, ufp);
-		
-		ur->pc += 4;		/* pretend cpu executed the instr */
-	}
-	if(fpemudebug)
-		print("\n");
-	return n;
-}
--- a/sys/src/9/teg2/fpimem.c
+++ /dev/null
@@ -1,136 +1,0 @@
-#include "fpi.h"
-
-/*
- * the following routines depend on memory format, not the machine
- */
-
-void
-fpis2i(Internal *i, void *v)
-{
-	Single *s = v;
-
-	i->s = (*s & 0x80000000) ? 1: 0;
-	if((*s & ~0x80000000) == 0){
-		SetZero(i);
-		return;
-	}
-	i->e = ((*s>>23) & 0x00FF) - SingleExpBias + ExpBias;
-	i->h = (*s & 0x007FFFFF)<<(1+NGuardBits);
-	i->l = 0;
-	if(i->e)
-		i->h |= HiddenBit;
-	else
-		i->e++;
-}
-
-void
-fpid2i(Internal *i, void *v)
-{
-	Double *d = v;
-
-	i->s = (d->h & 0x80000000) ? 1: 0;
-	i->e = (d->h>>20) & 0x07FF;
-	i->h = ((d->h & 0x000FFFFF)<<(4+NGuardBits))|((d->l>>25) & 0x7F);
-	i->l = (d->l & 0x01FFFFFF)<<NGuardBits;
-	if(i->e)
-		i->h |= HiddenBit;
-	else
-		i->e++;
-}
-
-void
-fpiw2i(Internal *i, void *v)
-{
-	Word w, word = *(Word*)v;
-	short e;
-
-	if(word < 0){
-		i->s = 1;
-		word = -word;
-	}
-	else
-		i->s = 0;
-	if(word == 0){
-		SetZero(i);
-		return;
-	}
-	if(word > 0){
-		for (e = 0, w = word; w; w >>= 1, e++)
-			;
-	} else
-		e = 32;
-	if(e > FractBits){
-		i->h = word>>(e - FractBits);
-		i->l = (word & ((1<<(e - FractBits)) - 1))<<(2*FractBits - e);
-	}
-	else {
-		i->h = word<<(FractBits - e);
-		i->l = 0;
-	}
-	i->e = (e - 1) + ExpBias;
-}
-
-void
-fpii2s(void *v, Internal *i)
-{
-	short e;
-	Single *s = (Single*)v;
-
-	fpiround(i);
-	if(i->h & HiddenBit)
-		i->h &= ~HiddenBit;
-	else
-		i->e--;
-	*s = i->s ? 0x80000000: 0;
-	e = i->e;
-	if(e < ExpBias){
-		if(e <= (ExpBias - SingleExpBias))
-			return;
-		e = SingleExpBias - (ExpBias - e);
-	}
-	else  if(e >= (ExpBias + (SingleExpMax-SingleExpBias))){
-		*s |= SingleExpMax<<23;
-		return;
-	}
-	else
-		e = SingleExpBias + (e - ExpBias);
-	*s |= (e<<23)|(i->h>>(1+NGuardBits));
-}
-
-void
-fpii2d(void *v, Internal *i)
-{
-	Double *d = (Double*)v;
-
-	fpiround(i);
-	if(i->h & HiddenBit)
-		i->h &= ~HiddenBit;
-	else
-		i->e--;
-	i->l = ((i->h & GuardMask)<<25)|(i->l>>NGuardBits);
-	i->h >>= NGuardBits;
-	d->h = i->s ? 0x80000000: 0;
-	d->h |= (i->e<<20)|((i->h & 0x00FFFFFF)>>4);
-	d->l = (i->h<<28)|i->l;
-}
-
-void
-fpii2w(Word *word, Internal *i)
-{
-	Word w;
-	short e;
-
-	fpiround(i);
-	e = (i->e - ExpBias) + 1;
-	if(e <= 0)
-		w = 0;
-	else if(e > 31)
-		w = 0x7FFFFFFF;
-	else if(e > FractBits)
-		w = (i->h<<(e - FractBits))|(i->l>>(2*FractBits - e));
-	else
-		w = i->h>>(FractBits-e);
-	if(i->s)
-		w = -w;
-	*word = w;
-}
--- a/sys/src/9/teg2/mkfile
+++ b/sys/src/9/teg2/mkfile
@@ -113,6 +113,22 @@
 
 CFLAGS= -I. -I../port $CFLAGS	# hack to compile private sysproc.c (e.g.)
 
+fpi.$O fpiarm.$O fpimem.$O: ../omap/fpi.h
+fpi.$O:	../omap/fpi.c
+	$CC $CFLAGS -. ../omap/fpi.c
+fpimem.$O:	../omap/fpimem.c
+	$CC $CFLAGS -. ../omap/fpimem.c
+
+fpiarm.$O:	../bcm/fpiarm.c
+	$CC $CFLAGS -. ../bcm/fpiarm.c
+vfp3.$O:	../bcm/vfp3.c
+	$CC $CFLAGS -. ../bcm/vfp3.c
+
+softfpu.$O:	../omap/softfpu.c
+	$CC $CFLAGS -. ../omap/softfpu.c
+syscall.$O:	../omap/syscall.c
+	$CC $CFLAGS -. ../omap/syscall.c
+
 arch.$O clock.$O fpiarm.$O main.$O mmu.$O screen.$O sdscsi.$O syscall.$O \
 	trap.$O: /$objtype/include/ureg.h
 
@@ -119,7 +135,6 @@
 archtegra.$O devether.$0 ether9221.$O: ../port/etherif.h ../port/netif.h
 archtegra.$O devflash.$O flashtegra.$O flashigep.$O: ../port/flashif.h
 ecc.$O flashtegra.$O flashigep.$O: ../port/nandecc.h io.h
-fpi.$O fpiarm.$O fpimem.$O: fpi.h
 l.$O lexception.$O lproc.$O mmu.$O rebootcode.$O: arm.s mem.h
 l.$O rebootcode.$O: cache.v7.s
 main.$O: errstr.h rebootcode.i /sys/include/tos.h
--- a/sys/src/9/teg2/softfpu.c
+++ /dev/null
@@ -1,117 +1,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-
-int
-fpudevprocio(Proc* proc, void* a, long n, uintptr offset, int write)
-{
-	/*
-	 * Called from procdevtab.read and procdevtab.write
-	 * allow user process access to the FPU registers.
-	 * This is the only FPU routine which is called directly
-	 * from the port code; it would be nice to have dynamic
-	 * creation of entries in the device file trees...
-	 */
-	USED(proc, a, n, offset, write);
-
-	return 0;
-}
-
-void
-fpunotify(void)
-{
-	/*
-	 * Called when a note is about to be delivered to a
-	 * user process, usually at the end of a system call.
-	 * Note handlers are not allowed to use the FPU so
-	 * the state is marked (after saving if necessary) and
-	 * checked in the Device Not Available handler.
-	 */
-}
-
-void
-fpunoted(void)
-{
-	/*
-	 * Called from sysnoted() via the machine-dependent
-	 * noted() routine.
-	 * Clear the flag set above in fpunotify().
-	 */
-}
-
-void
-fpuprocrestore(Proc*)
-{
-	/*
-	 * The process has been rescheduled and is about to run.
-	 * Nothing to do here right now. If the process tries to use
-	 * the FPU again it will cause a Device Not Available
-	 * exception and the state will then be restored.
-	 */
-}
-
-void
-fpuprocfork(Proc*)
-{
-	/*
-	 * The current process has been forked, save and copy neccesary
-	 * state to child. Nothing to do here, child proc starts with FPinit.
-	 */
-}
-
-void
-fpuprocsave(Proc*)
-{
-	/*
-	 * Called from sched() and sleep() via the machine-dependent
-	 * procsave() routine.
-	 * About to go in to the scheduler.
-	 * If the process wasn't using the FPU
-	 * there's nothing to do.
-	 */
-}
-
-void
-fpusysprocsetup(Proc*)
-{
-	/*
-	 * Disable the FPU.
-	 * Called from sysexec() via sysprocsetup() to
-	 * set the FPU for the new process.
-	 */
-}
-
-void
-fpuinit(void)
-{
-}
-
-int
-fpuemu(Ureg* ureg)
-{
-	int nfp;
-
-	if(waserror()){
-		splhi();
-		postnote(up, 1, up->errstr, NDebug);
-		return 1;
-	}
-	spllo();
-	nfp = fpiarm(ureg);
-	splhi();
-	poperror();
-
-	return nfp;
-}
-
-void
-fpon(void)
-{
-}
-
-void
-fpoff(void)
-{
-}
--- a/sys/src/9/teg2/syscall.c
+++ /dev/null
@@ -1,316 +1,0 @@
-/* we use l1 and l2 cache ops to help stability. */
-
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "../port/systab.h"
-
-#include <tos.h>
-#include "ureg.h"
-
-#include "arm.h"
-
-enum {
-	Psrsysbits = PsrMask | PsrDfiq | PsrDirq | PsrDasabt | PsrMbz,
-};
-
-typedef struct {
-	uintptr	ip;
-	Ureg*	arg0;
-	char*	arg1;
-	char	msg[ERRMAX];
-	Ureg*	old;
-	Ureg	ureg;
-} NFrame;
-
-/*
- *   Return user to state before notify()
- */
-static void
-noted(Ureg* cur, uintptr arg0)
-{
-	NFrame *nf;
-	Ureg *nur;
-
-	qlock(&up->debug);
-	if(arg0 != NRSTR && !up->notified){
-		qunlock(&up->debug);
-		pprint("call to noted() when not notified\n");
-		pexit("Suicide", 0);
-	}
-	up->notified = 0;
-	fpunoted();
-
-	nf = up->ureg;
-	/* sanity clause */
-	if(!okaddr((uintptr)nf, sizeof(NFrame), 0)){
-		qunlock(&up->debug);
-		pprint("bad ureg in noted %#p\n", nf);
-		pexit("Suicide", 0);
-	}
-
-	/* don't let user change system flags */
-	nur = &nf->ureg;
-	nur->psr &= Psrsysbits;
-	nur->psr |= cur->psr & ~Psrsysbits;
-
-	memmove(cur, nur, sizeof(Ureg));
-
-	switch((int)arg0){
-	case NCONT:
-	case NRSTR:
-		if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->sp, BY2WD, 0)){
-			qunlock(&up->debug);
-			pprint("suicide: trap in noted\n");
-			pexit("Suicide", 0);
-		}
-		up->ureg = nf->old;
-		qunlock(&up->debug);
-		break;
-	case NSAVE:
-		if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->sp, BY2WD, 0)){
-			qunlock(&up->debug);
-			pprint("suicide: trap in noted\n");
-			pexit("Suicide", 0);
-		}
-		qunlock(&up->debug);
-
-		splhi();
-		nf->arg1 = nf->msg;
-		nf->arg0 = &nf->ureg;
-		nf->ip = 0;
-		cur->sp = (uintptr)nf;
-		cur->r0 = (uintptr)nf->arg0;
-		break;
-	default:
-		up->lastnote->flag = NDebug;
-		/*FALLTHROUGH*/
-	case NDFLT:
-		qunlock(&up->debug);
-		if(up->lastnote->flag == NDebug)
-			pprint("suicide: %s\n", up->lastnote->msg);
-		pexit(up->lastnote->msg, up->lastnote->flag != NDebug);
-	}
-}
-
-/*
- *  Call user, if necessary, with note.
- *  Pass user the Ureg struct and the note on his stack.
- */
-int
-notify(Ureg* ureg)
-{
-	uintptr sp;
-	NFrame *nf;
-	char *msg;
-
-	if(up->procctl)
-		procctl();
-	if(up->nnote == 0)
-		return 0;
-
-	spllo();
-	qlock(&up->debug);
-	msg = popnote(ureg);
-	if(msg == nil){
-		qunlock(&up->debug);
-		splhi();
-		return 0;
-	}
-
-	if(!okaddr((uintptr)up->notify, 1, 0)){
-		qunlock(&up->debug);
-		pprint("suicide: notify function address %#p\n", up->notify);
-		pexit("Suicide", 0);
-	}
-
-	sp = ureg->sp - sizeof(NFrame);
-	if(!okaddr(sp, sizeof(NFrame), 1)){
-		qunlock(&up->debug);
-		pprint("suicide: notify stack address %#p\n", sp);
-		pexit("Suicide", 0);
-	}
-
-	nf = (void*)sp;
-	memmove(&nf->ureg, ureg, sizeof(Ureg));
-	nf->old = up->ureg;
-	up->ureg = nf;
-	memmove(nf->msg, msg, ERRMAX);
-	nf->arg1 = nf->msg;
-	nf->arg0 = &nf->ureg;
-	nf->ip = 0;
-
-	ureg->sp = sp;
-	ureg->pc = (uintptr)up->notify;
-	ureg->r0 = (uintptr)nf->arg0;
-
-	splhi();
-	fpunotify();
-	qunlock(&up->debug);
-
-	l1cache->wb();				/* is this needed? */
-	return 1;
-}
-
-void
-syscall(Ureg* ureg)
-{
-	char *e;
-	u32int s;
-	ulong sp;
-	long ret;
-	int i, scallnr;
-	vlong startns, stopns;
-
-	if(!kenter(ureg))
-		panic("syscall: from kernel: pc %#lux r14 %#lux psr %#lux",
-			ureg->pc, ureg->r14, ureg->psr);
-
-	m->syscall++;
-	up->insyscall = 1;
-	up->pc = ureg->pc;
-
-	scallnr = ureg->r0;
-	up->scallnr = scallnr;
-	spllo();
-	sp = ureg->sp;
-
-	if(up->procctl == Proc_tracesyscall){
-		/*
-		 * Redundant validaddr.  Do we care?
-		 * Tracing syscalls is not exactly a fast path...
-		 * Beware, validaddr currently does a pexit rather
-		 * than an error if there's a problem; that might
-		 * change in the future.
-		 */
-		if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD))
-			validaddr(sp, sizeof(Sargs)+BY2WD, 0);
-
-		syscallfmt(scallnr, ureg->pc, (va_list)(sp+BY2WD));
-		up->procctl = Proc_stopme;
-		procctl();
-		if (up->syscalltrace) 
-			free(up->syscalltrace);
-		up->syscalltrace = nil;
-	}
-
-	up->nerrlab = 0;
-	ret = -1;
-	todget(nil, &startns);
-
-	l1cache->wb();			/* system is more stable with this */
-	if(!waserror()){
-		if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD))
-			validaddr(sp, sizeof(Sargs)+BY2WD, 0);
-
-		up->s = *((Sargs*)(sp+BY2WD));
-		if(scallnr >= nsyscall || systab[scallnr] == nil){
-			postnote(up, 1, "sys: bad sys call", NDebug);
-			error(Ebadarg);
-		}
-		up->psstate = sysctab[scallnr];
-		ret = systab[scallnr]((va_list)up->s.args);
-		poperror();
-	}else{
-		/* failure: save the error buffer for errstr */
-		e = up->syserrstr;
-		up->syserrstr = up->errstr;
-		up->errstr = e;
-	}
-	if(up->nerrlab){
-		print("bad errstack [%d]: %d extra\n", scallnr, up->nerrlab);
-		for(i = 0; i < NERR; i++)
-			print("sp=%#p pc=%#p\n",
-				up->errlab[i].sp, up->errlab[i].pc);
-		panic("error stack");
-	}
-
-	/*
-	 *  Put return value in frame.  On the x86 the syscall is
-	 *  just another trap and the return value from syscall is
-	 *  ignored.  On other machines the return value is put into
-	 *  the results register by caller of syscall.
-	 */
-	ureg->r0 = ret;
-
-	if(up->procctl == Proc_tracesyscall){
-		todget(nil, &stopns);
-		sysretfmt(scallnr, (va_list)(sp+BY2WD), ret, startns, stopns);
-		s = splhi();
-		up->procctl = Proc_stopme;
-		procctl();
-		splx(s);
-		if(up->syscalltrace)
-			free(up->syscalltrace);
-		up->syscalltrace = nil;
-	}
-
-	up->insyscall = 0;
-	up->psstate = 0;
-
-	if(scallnr == NOTED)
-		noted(ureg, *(ulong*)(sp+BY2WD));
-
-	splhi();
-	if(scallnr != RFORK && (up->procctl || up->nnote))
-		notify(ureg);
-
-	l1cache->wb();			/* system is more stable with this */
-
-	/* if we delayed sched because we held a lock, sched now */
-	if(up->delaysched)
-		sched();
-	kexit(ureg);
-}
-
-uintptr
-execregs(uintptr entry, ulong ssize, ulong nargs)
-{
-	ulong *sp;
-	Ureg *ureg;
-
-	sp = (ulong*)(USTKTOP - ssize);
-	*--sp = nargs;
-
-	ureg = up->dbgreg;
-//	memset(ureg, 0, 15*sizeof(ulong));
-	ureg->r13 = (ulong)sp;
-	ureg->pc = entry;
-//print("%lud: EXECREGS pc %#ux sp %#ux nargs %ld\n", up->pid, ureg->pc, ureg->r13, nargs);
-	allcache->wbse(ureg, sizeof *ureg);		/* is this needed? */
-
-	/*
-	 * return the address of kernel/user shared data
-	 * (e.g. clock stuff)
-	 */
-	return USTKTOP-sizeof(Tos);
-}
-
-void
-sysprocsetup(Proc* p)
-{
-	fpusysprocsetup(p);
-}
-
-/* 
- *  Craft a return frame which will cause the child to pop out of
- *  the scheduler in user mode with the return register zero.  Set
- *  pc to point to a l.s return function.
- */
-void
-forkchild(Proc *p, Ureg *ureg)
-{
-	Ureg *cureg;
-
-	p->sched.sp = (ulong)p - sizeof(Ureg);
-	p->sched.pc = (ulong)forkret;
-
-	cureg = (Ureg*)(p->sched.sp);
-	memmove(cureg, ureg, sizeof(Ureg));
-
-	/* syscall returns 0 for child */
-	cureg->r0 = 0;
-}
--- a/sys/src/9/teg2/vfp3.c
+++ /dev/null
@@ -1,1 +1,0 @@
-#include "../bcm/vfp3.c"
--