libmach
diff --git a/src/libmach/regs.c b/src/libmach/regs.c
new file mode 100644
index 0000000..43c0478
--- /dev/null
+++ b/src/libmach/regs.c
@@ -0,0 +1,59 @@
+#include <u.h>
+#include <libc.h>
+#include <mach.h>
+
+int
+rput(Regs *regs, char *name, ulong u)
+{
+	if(regs == nil){
+		werrstr("registers not mapped");
+		return -1;
+	}
+	return regs->rw(regs, name, &u, 0);
+}
+
+int
+rget(Regs *regs, char *name, ulong *u)
+{
+	if(regs == nil){
+		*u = ~(ulong)0;
+		werrstr("registers not mapped");
+		return -1;
+	}
+	return regs->rw(regs, name, u, 1);
+}
+
+int
+_uregrw(Regs *regs, char *name, ulong *u, int isr)
+{
+	Regdesc *r;
+	uchar *ureg;
+
+	if(!isr){
+		werrstr("cannot write registers");
+		return -1;
+	}
+
+	if((r = regdesc(name)) == nil)
+		return -1;
+	ureg = ((UregRegs*)regs)->ureg + r->offset;
+
+	switch(r->format){
+	default:
+	case 'X':
+		*u = mach->swap4(*(u32int*)ureg);
+		return 0;
+	}
+}
+
+Regdesc*
+regdesc(char *name)
+{
+	Regdesc *r;
+
+	for(r=mach->reglist; r->name; r++)
+		if(strcmp(r->name, name) == 0)
+			return r;
+	return nil;
+}
+