more 386 runtime:
	remove use of _subv in vlrt.c
	darwin/386/signal.c
	darwin/386/*
	linux/386/* (forgotten before)

can run empty program on darwin/386 now.

R=r
DELTA=1140  (1021 added, 114 deleted, 5 changed)
OCL=26942
CL=26968
diff --git a/src/runtime/386/vlrt.c b/src/runtime/386/vlrt.c
index 254eb3e..9f205b9 100755
--- a/src/runtime/386/vlrt.c
+++ b/src/runtime/386/vlrt.c
@@ -43,6 +43,7 @@
 {
 	union
 	{
+		long long	v;
 		struct
 		{
 			ulong	lo;
@@ -60,8 +61,6 @@
 
 void	abort(void);
 
-void _subv(Vlong*, Vlong, Vlong);
-
 void
 _d2v(Vlong *y, double d)
 {
@@ -236,7 +235,7 @@
 			slowdodiv(num, den, &q, &r);
 		else {
 			q.lo = n;
-			_subv(&r, num, x);
+			r.v = num.v - x.v;
 		}
 	} else {
 		if(num.hi >= den.lo){
diff --git a/src/runtime/darwin/386/defs.h b/src/runtime/darwin/386/defs.h
new file mode 100644
index 0000000..b66a5d8
--- /dev/null
+++ b/src/runtime/darwin/386/defs.h
@@ -0,0 +1,229 @@
+// godefs -f -m32 defs.c
+
+// MACHINE GENERATED - DO NOT EDIT.
+
+// Constants
+enum {
+	PROT_NONE = 0,
+	PROT_READ = 0x1,
+	PROT_WRITE = 0x2,
+	PROT_EXEC = 0x4,
+	MAP_ANON = 0x1000,
+	MAP_PRIVATE = 0x2,
+	MACH_MSG_TYPE_MOVE_RECEIVE = 0x10,
+	MACH_MSG_TYPE_MOVE_SEND = 0x11,
+	MACH_MSG_TYPE_MOVE_SEND_ONCE = 0x12,
+	MACH_MSG_TYPE_COPY_SEND = 0x13,
+	MACH_MSG_TYPE_MAKE_SEND = 0x14,
+	MACH_MSG_TYPE_MAKE_SEND_ONCE = 0x15,
+	MACH_MSG_TYPE_COPY_RECEIVE = 0x16,
+	MACH_MSG_PORT_DESCRIPTOR = 0,
+	MACH_MSG_OOL_DESCRIPTOR = 0x1,
+	MACH_MSG_OOL_PORTS_DESCRIPTOR = 0x2,
+	MACH_MSG_OOL_VOLATILE_DESCRIPTOR = 0x3,
+	MACH_MSGH_BITS_COMPLEX = 0x80000000,
+	MACH_SEND_MSG = 0x1,
+	MACH_RCV_MSG = 0x2,
+	MACH_RCV_LARGE = 0x4,
+	MACH_SEND_TIMEOUT = 0x10,
+	MACH_SEND_INTERRUPT = 0x40,
+	MACH_SEND_CANCEL = 0x80,
+	MACH_SEND_ALWAYS = 0x10000,
+	MACH_SEND_TRAILER = 0x20000,
+	MACH_RCV_TIMEOUT = 0x100,
+	MACH_RCV_NOTIFY = 0x200,
+	MACH_RCV_INTERRUPT = 0x400,
+	MACH_RCV_OVERWRITE = 0x1000,
+	NDR_PROTOCOL_2_0 = 0,
+	NDR_INT_BIG_ENDIAN = 0,
+	NDR_INT_LITTLE_ENDIAN = 0x1,
+	NDR_FLOAT_IEEE = 0,
+	NDR_CHAR_ASCII = 0,
+	SA_SIGINFO = 0x40,
+	SA_RESTART = 0x2,
+	SA_ONSTACK = 0x1,
+	SA_USERTRAMP = 0x100,
+	SA_64REGSET = 0x200,
+};
+
+// Types
+#pragma pack on
+
+typedef struct MachBody MachBody;
+struct MachBody {
+	uint32 msgh_descriptor_count;
+};
+
+typedef struct MachHeader MachHeader;
+struct MachHeader {
+	uint32 msgh_bits;
+	uint32 msgh_size;
+	uint32 msgh_remote_port;
+	uint32 msgh_local_port;
+	uint32 msgh_reserved;
+	int32 msgh_id;
+};
+
+typedef struct MachNDR MachNDR;
+struct MachNDR {
+	uint8 mig_vers;
+	uint8 if_vers;
+	uint8 reserved1;
+	uint8 mig_encoding;
+	uint8 int_rep;
+	uint8 char_rep;
+	uint8 float_rep;
+	uint8 reserved2;
+};
+
+typedef struct MachPort MachPort;
+struct MachPort {
+	uint32 name;
+	uint32 pad1;
+	uint16 pad2;
+	uint8 disposition;
+	uint8 type;
+};
+
+typedef struct StackT StackT;
+struct StackT {
+	void *ss_sp;
+	uint32 ss_size;
+	int32 ss_flags;
+};
+
+typedef union Sighandler Sighandler;
+union Sighandler {
+	void *__sa_handler;
+	void *__sa_sigaction;
+};
+
+typedef struct Sigaction Sigaction;
+struct Sigaction {
+	Sighandler __sigaction_u;
+	void *sa_tramp;
+	uint32 sa_mask;
+	int32 sa_flags;
+};
+
+typedef union Sigval Sigval;
+union Sigval {
+	int32 sival_int;
+	void *sival_ptr;
+};
+
+typedef struct Siginfo Siginfo;
+struct Siginfo {
+	int32 si_signo;
+	int32 si_errno;
+	int32 si_code;
+	int32 si_pid;
+	uint32 si_uid;
+	int32 si_status;
+	void *si_addr;
+	Sigval si_value;
+	int32 si_band;
+	uint32 __pad[7];
+};
+
+typedef struct FPControl FPControl;
+struct FPControl {
+	byte pad0[2];
+};
+
+typedef struct FPStatus FPStatus;
+struct FPStatus {
+	byte pad0[2];
+};
+
+typedef struct RegMMST RegMMST;
+struct RegMMST {
+	int8 mmst_reg[10];
+	int8 mmst_rsrv[6];
+};
+
+typedef struct RegXMM RegXMM;
+struct RegXMM {
+	int8 xmm_reg[16];
+};
+
+typedef struct Regs Regs;
+struct Regs {
+	uint32 eax;
+	uint32 ebx;
+	uint32 ecx;
+	uint32 edx;
+	uint32 edi;
+	uint32 esi;
+	uint32 ebp;
+	uint32 esp;
+	uint32 ss;
+	uint32 eflags;
+	uint32 eip;
+	uint32 cs;
+	uint32 ds;
+	uint32 es;
+	uint32 fs;
+	uint32 gs;
+};
+
+typedef struct FloatState FloatState;
+struct FloatState {
+	int32 fpu_reserved[2];
+	FPControl fpu_fcw;
+	FPStatus fpu_fsw;
+	uint8 fpu_ftw;
+	uint8 fpu_rsrv1;
+	uint16 fpu_fop;
+	uint32 fpu_ip;
+	uint16 fpu_cs;
+	uint16 fpu_rsrv2;
+	uint32 fpu_dp;
+	uint16 fpu_ds;
+	uint16 fpu_rsrv3;
+	uint32 fpu_mxcsr;
+	uint32 fpu_mxcsrmask;
+	RegMMST fpu_stmm0;
+	RegMMST fpu_stmm1;
+	RegMMST fpu_stmm2;
+	RegMMST fpu_stmm3;
+	RegMMST fpu_stmm4;
+	RegMMST fpu_stmm5;
+	RegMMST fpu_stmm6;
+	RegMMST fpu_stmm7;
+	RegXMM fpu_xmm0;
+	RegXMM fpu_xmm1;
+	RegXMM fpu_xmm2;
+	RegXMM fpu_xmm3;
+	RegXMM fpu_xmm4;
+	RegXMM fpu_xmm5;
+	RegXMM fpu_xmm6;
+	RegXMM fpu_xmm7;
+	int8 fpu_rsrv4[224];
+	int32 fpu_reserved1;
+};
+
+typedef struct ExceptionState ExceptionState;
+struct ExceptionState {
+	uint32 trapno;
+	uint32 err;
+	uint32 faultvaddr;
+};
+
+typedef struct Mcontext Mcontext;
+struct Mcontext {
+	ExceptionState es;
+	Regs ss;
+	FloatState fs;
+};
+
+typedef struct Ucontext Ucontext;
+struct Ucontext {
+	int32 uc_onstack;
+	uint32 uc_sigmask;
+	StackT uc_stack;
+	Ucontext *uc_link;
+	uint32 uc_mcsize;
+	Mcontext *uc_mcontext;
+};
+#pragma pack off
diff --git a/src/runtime/darwin/386/rt0.s b/src/runtime/darwin/386/rt0.s
new file mode 100755
index 0000000..5b52e91
--- /dev/null
+++ b/src/runtime/darwin/386/rt0.s
@@ -0,0 +1,8 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Darwin and Linux use the same linkage to main
+
+TEXT	_rt0_386_darwin(SB),7,$0
+	JMP	_rt0_386(SB)
diff --git a/src/runtime/darwin/386/signal.c b/src/runtime/darwin/386/signal.c
new file mode 100644
index 0000000..a6c7822
--- /dev/null
+++ b/src/runtime/darwin/386/signal.c
@@ -0,0 +1,103 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs.h"
+#include "os.h"
+#include "signals.h"
+
+void
+dumpregs(Regs *r)
+{
+	printf("eax     %x\n", r->eax);
+	printf("ebx     %x\n", r->ebx);
+	printf("ecx     %x\n", r->ecx);
+	printf("edx     %x\n", r->edx);
+	printf("edi     %x\n", r->edi);
+	printf("esi     %x\n", r->esi);
+	printf("ebp     %x\n", r->ebp);
+	printf("esp     %x\n", r->esp);
+	printf("eip     %x\n", r->eip);
+	printf("eflags  %x\n", r->eflags);
+	printf("cs      %x\n", r->cs);
+	printf("fs      %x\n", r->fs);
+	printf("gs      %x\n", r->gs);
+}
+
+void
+sighandler(int32 sig, Siginfo *info, void *context)
+{
+	Ucontext *uc;
+	Mcontext *mc;
+	Regs *r;
+
+	if(panicking)	// traceback already printed
+		sys_Exit(2);
+	panicking = 1;
+
+	if(sig < 0 || sig >= NSIG){
+		printf("Signal %d\n", sig);
+	}else{
+		printf("%s\n", sigtab[sig].name);
+	}
+
+	uc = context;
+	mc = uc->uc_mcontext;
+	r = &mc->ss;
+
+	printf("Faulting address: %p\n", info->si_addr);
+	printf("pc: %x\n", r->eip);
+	printf("\n");
+
+	if(gotraceback()){
+		traceback((void*)r->eip, (void*)r->esp, m->curg);
+		tracebackothers(m->curg);
+		dumpregs(r);
+	}
+
+	sys·Breakpoint();
+	sys_Exit(2);
+}
+
+void
+sigignore(int32, Siginfo*, void*)
+{
+}
+
+void
+signalstack(byte *p, int32 n)
+{
+	StackT st;
+
+	st.ss_sp = p;
+	st.ss_size = n;
+	st.ss_flags = 0;
+	sigaltstack(&st, nil);
+}
+
+void
+initsig(void)
+{
+	int32 i;
+	static Sigaction sa;
+
+	sa.sa_flags |= SA_SIGINFO|SA_ONSTACK;
+	sa.sa_mask = 0; // 0xFFFFFFFFU;
+	sa.sa_tramp = sigtramp;	// sigtramp's job is to call into real handler
+	for(i = 0; i<NSIG; i++) {
+		if(sigtab[i].flags) {
+			if(sigtab[i].flags & SigCatch) {
+				sa.__sigaction_u.__sa_sigaction = sighandler;
+			} else {
+				sa.__sigaction_u.__sa_sigaction = sigignore;
+			}
+			if(sigtab[i].flags & SigRestart)
+				sa.sa_flags |= SA_RESTART;
+			else
+				sa.sa_flags &= ~SA_RESTART;
+			sigaction(i, &sa, nil);
+		}
+	}
+}
+
diff --git a/src/runtime/darwin/386/sys.s b/src/runtime/darwin/386/sys.s
new file mode 100644
index 0000000..1f9f82f
--- /dev/null
+++ b/src/runtime/darwin/386/sys.s
@@ -0,0 +1,223 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// System calls and other sys.stuff for 386, Darwin
+// See http://fxr.watson.org/fxr/source/bsd/kern/syscalls.c?v=xnu-1228
+// or /usr/include/sys/syscall.h (on a Mac) for system call numbers.
+
+TEXT notok(SB),7,$0
+	MOVL	$0xf1, 0xf1
+	RET
+
+// Exit the entire program (like C exit)
+TEXT sys·Exit(SB),7,$0
+	MOVL	$1, AX
+	INT	$0x80
+	CALL	notok(SB)
+	RET
+
+// Exit this OS thread (like pthread_exit, which eventually
+// calls __bsdthread_terminate).
+TEXT exit1(SB),7,$0
+	MOVL	$361, AX
+	INT	$0x80
+	JAE 2(PC)
+	CALL	notok(SB)
+	RET
+
+TEXT sys·write(SB),7,$0
+	MOVL	$4, AX
+	INT	$0x80
+	JAE	2(PC)
+	CALL	notok(SB)
+	RET
+
+TEXT sys·mmap(SB),7,$0
+	MOVL	$197, AX
+	INT	$0x80
+	JAE	2(PC)
+	CALL	notok(SB)
+	RET
+
+TEXT sigaction(SB),7,$0
+	MOVL	$46, AX
+	INT	$0x80
+	JAE	2(PC)
+	CALL	notok(SB)
+	RET
+
+// Sigtramp's job is to call the actual signal handler.
+// It is called with the following arguments on the stack:
+//	0(FP)	"return address" - ignored
+//	4(FP)	actual handler
+//	8(FP)	siginfo style - ignored
+//	12(FP)	signal number
+//	16(FP)	siginfo
+//	20(FP)	context
+TEXT sigtramp(SB),7,$40
+	MOVL	4(FS), BP	// m
+	MOVL	28(BP), BP	// m->gsignal
+	MOVL	BP, 0(FS)	// g = m->gsignal
+
+	MOVL	handler+4(FP), DI
+	MOVL	signo+12(FP), AX
+	MOVL	siginfo+16(FP), BX
+	MOVL	context+20(FP), CX
+
+	MOVL	AX, 0(SP)
+	MOVL	BX, 4(SP)
+	MOVL	CX, 8(SP)
+	CALL	DI
+
+	MOVL	context+20(FP), CX
+	MOVL	style+8(FP), BX
+
+	MOVL	$0, 0(SP)	// "caller PC" - ignored
+	MOVL	CX, 4(SP)
+	MOVL	BX, 8(SP)
+	MOVL	$184, AX	// sigreturn(ucontext, infostyle)
+	INT	$0x80
+	CALL	notok(SB)
+	RET
+
+TEXT sigaltstack(SB),7,$0
+	MOVL	$53, AX
+	INT	$0x80
+	JAE	2(PC)
+	CALL	notok(SB)
+	RET
+
+TEXT bsdthread_create(SB),7,$0
+	MOVL	$360, AX
+	INT	$0x80
+	JAE	2(PC)
+	CALL	notok(SB)
+	RET
+
+TEXT bsdthread_register(SB),7,$40
+	MOVL	$366, AX
+	MOVL	$bsdthread_start(SB), 0(SP)	// threadstart
+	MOVL	$0, 4(SP)	// wqthread, not used by us
+	MOVL	$0, 8(SP)	// pthsize, not used by us
+	MOVL	$0, 12(SP)	// paranoia
+	MOVL	$0, 16(SP)
+	MOVL	$0, 20(SP)
+	INT	$0x80
+	JAE	2(PC)
+	CALL	notok(SB)
+	RET
+
+// Invoke Mach system call.
+// Assumes system call number in AX,
+// caller PC on stack, caller's caller PC next,
+// and then the system call arguments.
+//
+// Can be used for BSD too, but we don't,
+// because if you use this interface the BSD
+// system call numbers need an extra field
+// in the high 16 bits that seems to be the
+// argument count in bytes but is not always.
+// INT $0x80 works fine for those.
+TEXT sysenter(SB),7,$0
+	POPL	DX
+	MOVL	SP, CX
+	BYTE $0x0F; BYTE $0x34;  // SYSENTER
+	// returns to DX with SP set to CX
+
+TEXT mach_msg_trap(SB),7,$0
+	MOVL	$-31, AX
+	CALL	sysenter(SB)
+	RET
+
+TEXT mach_reply_port(SB),7,$0
+	MOVL	$-26, AX
+	CALL	sysenter(SB)
+	RET
+
+TEXT mach_task_self(SB),7,$0
+	MOVL	$-28, AX
+	CALL	sysenter(SB)
+	RET
+
+// Mach provides trap versions of the semaphore ops,
+// instead of requiring the use of RPC.
+
+// uint32 mach_semaphore_wait(uint32)
+TEXT mach_semaphore_wait(SB),7,$0
+	MOVL	$-36, AX
+	CALL	sysenter(SB)
+	RET
+
+// uint32 mach_semaphore_timedwait(uint32, uint32, uint32)
+TEXT mach_semaphore_timedwait(SB),7,$0
+	MOVL	$-38, AX
+	CALL	sysenter(SB)
+	RET
+
+// uint32 mach_semaphore_signal(uint32)
+TEXT mach_semaphore_signal(SB),7,$0
+	MOVL	$-33, AX
+	CALL	sysenter(SB)
+	RET
+
+// uint32 mach_semaphore_signal_all(uint32)
+TEXT mach_semaphore_signal_all(SB),7,$0
+	MOVL	$-34, AX
+	CALL	sysenter(SB)
+	RET
+
+/*
+descriptor entry format for system call
+is the native machine format, ugly as it is:
+
+	2-byte limit
+	3-byte base
+	1-byte: 0x80=present, 0x60=dpl<<5, 0x1F=type
+	1-byte: 0x80=limit is *4k, 0x40=32-bit operand size,
+		0x0F=4 more bits of limit
+	1 byte: 8 more bits of base
+
+int i386_get_ldt(int, union ldt_entry *, int);
+int i386_set_ldt(int, const union ldt_entry *, int);
+
+*/
+
+// setldt(int entry, int address, int limit)
+TEXT setldt(SB),7,$32
+	// set up data_desc
+	LEAL	16(SP), AX	// struct data_desc
+	MOVL	$0, 0(AX)
+	MOVL	$0, 4(AX)
+
+	MOVL	address+4(FP), BX	// aka base
+	MOVW	BX, 2(AX)
+	SHRL	$16, BX
+	MOVB	BX, 4(AX)
+	SHRL	$8, BX
+	MOVB	BX, 7(AX)
+
+	MOVL	limit+8(FP), BX
+	MOVW	BX, 0(AX)
+	SHRL	$16, BX
+	ANDL	$0x0F, BX
+	ORL	$0x40, BX		// 32-bit operand size
+	MOVB	BX, 6(AX)
+
+	MOVL	$0xF2, 5(AX)	// r/w data descriptor, dpl=3, present
+
+	// call i386_set_ldt(entry, desc, 1)
+	MOVL	entry+0(FP), BX
+	MOVL	BX, 0(SP)
+	MOVL	AX, 4(SP)
+	MOVL	$1, 8(SP)
+	CALL	i386_set_ldt(SB)
+	RET
+
+TEXT i386_set_ldt(SB),7,$0
+	MOVL	$5, AX
+	INT	$0x82	// sic
+	JAE	2(PC)
+	CALL	notok(SB)
+	RET
+
diff --git a/src/runtime/darwin/signal.c b/src/runtime/darwin/amd64/signal.c
similarity index 100%
rename from src/runtime/darwin/signal.c
rename to src/runtime/darwin/amd64/signal.c
diff --git a/src/runtime/darwin/thread.c b/src/runtime/darwin/thread.c
index 0d54177..c780e16 100644
--- a/src/runtime/darwin/thread.c
+++ b/src/runtime/darwin/thread.c
@@ -169,11 +169,7 @@
 static void
 macherror(int32 r, int8 *fn)
 {
-	prints("mach error ");
-	prints(fn);
-	prints(": ");
-	sys·printint(r);
-	prints("\n");
+	printf("mach error %s: %d\n", fn, r);
 	throw("mach error");
 }
 
diff --git a/src/runtime/linux/386/defs.h b/src/runtime/linux/386/defs.h
new file mode 100755
index 0000000..112fc7b
--- /dev/null
+++ b/src/runtime/linux/386/defs.h
@@ -0,0 +1,136 @@
+// godefs -f -m32 -f -I/home/rsc/pub/linux-2.6/arch/x86/include -f -I/home/rsc/pub/linux-2.6/include defs2.c
+
+// MACHINE GENERATED - DO NOT EDIT.
+
+// Constants
+enum {
+	PROT_NONE = 0,
+	PROT_READ = 0x1,
+	PROT_WRITE = 0x2,
+	PROT_EXEC = 0x4,
+	MAP_ANON = 0x20,
+	MAP_PRIVATE = 0x2,
+	SA_RESTART = 0x10000000,
+	SA_ONSTACK = 0x8000000,
+	SA_RESTORER = 0x4000000,
+	SA_SIGINFO = 0x4,
+};
+
+// Types
+#pragma pack on
+
+typedef struct Fpreg Fpreg;
+struct Fpreg {
+	uint16 significand[4];
+	uint16 exponent;
+};
+
+typedef struct Fpxreg Fpxreg;
+struct Fpxreg {
+	uint16 significand[4];
+	uint16 exponent;
+	uint16 padding[3];
+};
+
+typedef struct Xmmreg Xmmreg;
+struct Xmmreg {
+	uint32 element[4];
+};
+
+typedef struct Fpstate Fpstate;
+struct Fpstate {
+	uint32 cw;
+	uint32 sw;
+	uint32 tag;
+	uint32 ipoff;
+	uint32 cssel;
+	uint32 dataoff;
+	uint32 datasel;
+	Fpreg _st[8];
+	uint16 status;
+	uint16 magic;
+	uint32 _fxsr_env[6];
+	uint32 mxcsr;
+	uint32 reserved;
+	Fpxreg _fxsr_st[8];
+	Xmmreg _xmm[8];
+	uint32 padding1[44];
+	byte _anon_[48];
+};
+
+typedef struct Timespec Timespec;
+struct Timespec {
+	int32 tv_sec;
+	int32 tv_nsec;
+};
+
+typedef struct Timeval Timeval;
+struct Timeval {
+	int32 tv_sec;
+	int32 tv_usec;
+};
+
+typedef struct Sigaction Sigaction;
+struct Sigaction {
+	byte _u[4];
+	uint32 sa_mask;
+	uint32 sa_flags;
+	void *sa_restorer;
+};
+
+typedef struct Siginfo Siginfo;
+struct Siginfo {
+	int32 si_signo;
+	int32 si_errno;
+	int32 si_code;
+	byte _sifields[116];
+};
+
+typedef struct Sigaltstack Sigaltstack;
+struct Sigaltstack {
+	void *ss_sp;
+	int32 ss_flags;
+	uint32 ss_size;
+};
+
+typedef struct Sigcontext Sigcontext;
+struct Sigcontext {
+	uint16 gs;
+	uint16 __gsh;
+	uint16 fs;
+	uint16 __fsh;
+	uint16 es;
+	uint16 __esh;
+	uint16 ds;
+	uint16 __dsh;
+	uint32 edi;
+	uint32 esi;
+	uint32 ebp;
+	uint32 esp;
+	uint32 ebx;
+	uint32 edx;
+	uint32 ecx;
+	uint32 eax;
+	uint32 trapno;
+	uint32 err;
+	uint32 eip;
+	uint16 cs;
+	uint16 __csh;
+	uint32 eflags;
+	uint32 esp_at_signal;
+	uint16 ss;
+	uint16 __ssh;
+	Fpstate *fpstate;
+	uint32 oldmask;
+	uint32 cr2;
+};
+
+typedef struct Ucontext Ucontext;
+struct Ucontext {
+	uint32 uc_flags;
+	Ucontext *uc_link;
+	Sigaltstack uc_stack;
+	Sigcontext uc_mcontext;
+	uint32 uc_sigmask;
+};
+#pragma pack off
diff --git a/src/runtime/linux/386/rt0.s b/src/runtime/linux/386/rt0.s
new file mode 100755
index 0000000..7717c37
--- /dev/null
+++ b/src/runtime/linux/386/rt0.s
@@ -0,0 +1,8 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Darwin and Linux use the same linkage to main
+
+TEXT	_rt0_386_linux(SB),7,$0
+	JMP	_rt0_386(SB)
diff --git a/src/runtime/linux/386/sys.s b/src/runtime/linux/386/sys.s
new file mode 100755
index 0000000..379d153
--- /dev/null
+++ b/src/runtime/linux/386/sys.s
@@ -0,0 +1,222 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//
+// System calls and other sys.stuff for 386, Linux
+//
+
+TEXT syscall(SB),7,$0
+	MOVL 4(SP), AX	// syscall number
+	MOVL 8(SP), BX	// arg1
+	MOVL 12(SP), CX	// arg2
+	MOVL 16(SP), DX	// arg3
+	MOVL 20(SP), SI	// arg4
+	MOVL 24(SP), DI	// arg5
+	MOVL 28(SP), BP	// arg6
+	INT $0x80
+	CMPL AX, $0xfffff001
+	JLS 2(PC)
+	INT $3	// not reached
+	RET
+
+TEXT sys·Exit(SB),7,$0
+	MOVL	$252, AX	// syscall number
+	MOVL	4(SP), BX
+	INT	$0x80
+	INT $3	// not reached
+	RET
+
+TEXT exit1(SB),7,$0
+	MOVL	$1, AX	// exit - exit the current os thread
+	MOVL	4(SP), BX
+	INT	$0x80
+	INT $3	// not reached
+	RET
+
+TEXT write(SB),7,$0
+	MOVL	$4, AX		// syscall - write
+	MOVL	4(SP),  BX
+	MOVL	8(SP), CX
+	MOVL	12(SP), DX
+	INT	$0x80
+	RET
+
+TEXT getpid(SB),7,$0
+	MOVL	$20, AX
+	INT	$0x80
+	RET
+
+TEXT kill(SB),7,$0
+	MOVL	$37, AX
+	MOVL	4(SP), BX
+	MOVL	8(SP), CX
+	INT	$0x80
+	RET
+
+TEXT sys·write(SB),7,$0
+	MOVL	$4, AX		// syscall - write
+	MOVL	4(SP), BX
+	MOVL	8(SP), CX
+	MOVL	12(SP), DX
+	INT	$0x80
+	RET
+
+TEXT rt_sigaction(SB),7,$0
+	MOVL	$174, AX		// syscall - rt_sigaction
+	MOVL	4(SP), BX
+	MOVL	8(SP), CX
+	MOVL	12(SP), DX
+	MOVL	16(SP), SI
+	INT	$0x80
+	RET
+
+TEXT sigtramp(SB),7,$0
+	MOVL	4(FS), BP	// m
+	MOVL	20(BP), AX	// m->gsignal
+	MOVL	AX, 0(FS)	// g = m->gsignal
+	JMP	sighandler(SB)
+
+TEXT sigignore(SB),7,$0
+	RET
+
+TEXT sigreturn(SB),7,$0
+	MOVL	4(FS), BP	// m
+	MOVL	32(BP), BP	// m->curg
+	MOVL	BP, 0(FS)	// g = m->curg
+	MOVL	$173, AX	// rt_sigreturn
+	INT $0x80
+	INT $3	// not reached
+	RET
+
+TEXT sys·mmap(SB),7,$0
+	MOVL	$192, AX	// mmap2
+	MOVL	4(SP), BX
+	MOVL	8(SP), CX
+	MOVL	12(SP), DX
+	MOVL	16(SP), SI
+	MOVL	20(SP), DI
+	MOVL	24(SP), BP
+	SHRL	$12, BP
+	INT	$0x80
+	CMPL	AX, $0xfffff001
+	JLS	2(PC)
+	INT	$3
+	RET
+
+// int64 futex(int32 *uaddr, int32 op, int32 val,
+//	struct timespec *timeout, int32 *uaddr2, int32 val2);
+TEXT futex(SB),7,$0
+	MOVL	$240, AX	// futex
+	MOVL	4(SP), BX
+	MOVL	8(SP), CX
+	MOVL	12(SP), DX
+	MOVL	16(SP), SI
+	MOVL	20(SP), DI
+	MOVL	24(SP), BP
+	INT	$0x80
+	RET
+
+// int64 clone(int32 flags, void *stack, M *m, G *g, void (*fn)(void));
+TEXT clone(SB),7,$0
+	MOVL	$120, AX	// clone
+	MOVL	flags+4(SP), BX
+	MOVL	stack+8(SP), CX
+
+	// Copy m, g, fn off parent stack for use by child.
+	SUBL	$12, CX
+	MOVL	m+12(SP), DX
+	MOVL	DX, 0(CX)
+	MOVL	g+16(SP), DX
+	MOVL	DX, 4(CX)
+	MOVL	fn+20(SP), DX
+	MOVL	DX, 8(CX)
+
+	MOVL	$120, AX
+	INT	$0x80
+
+	// In parent, return.
+	CMPL	AX, $0
+	JEQ	2(PC)
+	RET
+
+	// In child, set up new stack, etc.
+	MOVL	0(CX), BX	// m
+	MOVL	12(AX), AX	// fs (= m->cret)
+	MOVW	AX, FS
+	MOVL	8(CX), DX	// fn
+	ADDL	$12, CX
+	MOVL	CX, SP
+
+	// fn is now on top of stack.
+
+	// initialize m->procid to Linux tid
+	MOVL	$224, AX
+	INT	$0x80
+	MOVL	AX, 20(BX)
+
+	// call fn
+	CALL	DX
+
+	// It shouldn't return; if it does, exit.
+	MOVL	$111, DI
+	MOVL	$1, AX
+	INT	$0x80
+	JMP	-3(PC)	// keep exiting
+
+TEXT sigaltstack(SB),7,$-8
+	MOVL	$186, AX	// sigaltstack
+	MOVL	new+4(SP), BX
+	MOVL	old+8(SP), CX
+	INT	$0x80
+	CMPL	AX, $0xfffff001
+	JLS	2(PC)
+	INT	$3
+	RET
+
+//	// fake the per-goroutine and per-mach registers
+//	LEAL	m0(SB),
+
+// TODO(rsc): move to linux.s
+// <asm-i386/ldt.h>
+// struct user_desc {
+// 	unsigned int  entry_number;
+// 	unsigned long base_addr;
+// 	unsigned int  limit;
+// 	unsigned int  seg_32bit:1;
+// 	unsigned int  contents:2;
+// 	unsigned int  read_exec_only:1;
+// 	unsigned int  limit_in_pages:1;
+// 	unsigned int  seg_not_present:1;
+// 	unsigned int  useable:1;
+// };
+#define SEG_32BIT 0x01
+// contents are the 2 bits 0x02 and 0x04.
+#define CONTENTS_DATA 0x00
+#define CONTENTS_STACK 0x02
+#define CONTENTS_CODE 0x04
+#define READ_EXEC_ONLY 0x08
+#define LIMIT_IN_PAGES 0x10
+#define SEG_NOT_PRESENT 0x20
+#define USEABLE 0x40
+
+// setldt(int entry, int address, int limit)
+TEXT setldt(SB),7,$32
+	// set up user_desc
+	LEAL	16(SP), AX	// struct user_desc
+	MOVL	entry+0(FP), BX	// entry
+	MOVL	BX, 0(AX)
+	MOVL	address+4(FP), BX	// base address
+	MOVL	BX, 4(AX)
+	MOVL	limit+8(FP), BX	// limit
+	MOVL	BX, 8(AX)
+	MOVL	$(SEG_32BIT|USEABLE|CONTENTS_DATA), 12(AX)	// flag bits
+
+	// call modify_ldt
+	MOVL	$123, 0(SP)	// syscall - modify_ldt
+	MOVL	$1, 4(SP)	// func = 1 (write)
+	MOVL	AX, 8(SP)	// user_desc
+	MOVL	$16, 12(SP)	// sizeof(user_desc)
+	CALL	syscall(SB)
+	RET
+
diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c
index 8a740f8..25e2568 100644
--- a/src/runtime/runtime.c
+++ b/src/runtime/runtime.c
@@ -23,15 +23,18 @@
 {
 	uint8 *sp;
 
-	prints("\npanic ");
-	sys·printpc(&lno);
-	prints("\n");
+	if(panicking) {
+		printf("double panic\n");
+		sys_Exit(3);
+	}
+	panicking++;
+
+	printf("\npanic PC=%X [%d]\n", (uint64)(uintptr)&lno, panicking);
 	sp = (uint8*)&lno;
 	if(gotraceback()){
 		traceback(sys·getcallerpc(&lno), sp, g);
 		tracebackothers(g);
 	}
-	panicking = 1;
 	sys·Breakpoint();  // so we can grab it in a debugger
 	sys_Exit(2);
 }