Browse Source

Plan 9 from Bell Labs 2012-09-22

David du Colombier 11 years ago
parent
commit
1eca2f907b

+ 9 - 11
sys/include/mach.h

@@ -11,12 +11,10 @@
  *		i386,
  *		amd64,
  *		sparc,
- *		sparc64,
  *		mips2 (R4000)
  *		arm
  *		powerpc,
  *		powerpc64
- *		alpha
  *		arm64
  */
 enum
@@ -32,9 +30,9 @@ enum
 	M29000,			/* retired */
 	MARM,
 	MPOWER,
-	MALPHA,
+	MALPHA,			/* retired */
 	NMIPS,
-	MSPARC64,
+	MSPARC64,		/* retired */
 	MAMD64,
 	MPOWER64,
 	MARM64,
@@ -59,10 +57,10 @@ enum
 	FPOWER,			/* q.out */
 	FPOWERB,		/* power pc bootable */
 	FMIPS2LE,		/* 0.out */
-	FALPHA,			/* 7.out */
-	FALPHAB,		/* DEC Alpha bootable */
+	FALPHA,			/* retired */
+	FALPHAB,		/* retired DEC Alpha bootable */
 	FMIPSLE,		/* 3k little endian */
-	FSPARC64,		/* u.out */
+	FSPARC64,		/* retired */
 	FAMD64,			/* 6.out */
 	FAMD64B,		/* 6.out bootable */
 	FPOWER64,		/* 9.out */
@@ -82,8 +80,8 @@ enum
 	A29000,			/* retired */
 	AARM,
 	APOWER,
-	AALPHA,
-	ASPARC64,
+	AALPHA,			/* retired */
+	ASPARC64,		/* retired */
 	AAMD64,
 	APOWER64,
 	AARM64,
@@ -99,8 +97,8 @@ enum
 	ObjArm,			/* .5 */
 	ObjPower,		/* .q */
 	ObjMips2le,		/* .0 */
-	ObjAlpha,		/* .7 */
-	ObjSparc64,		/* .u */
+	ObjAlpha,		/* retired */
+	ObjSparc64,		/* retired */
 	ObjAmd64,		/* .6 */
 	ObjSpim,		/* .0 */
 	ObjPower64,		/* .9 */

+ 114 - 0
sys/src/libmach/7.c

@@ -0,0 +1,114 @@
+/*
+ * alpha definition
+ */
+#include <u.h>
+#include <bio.h>
+#include "7c/ureg.h"
+#include <mach.h>
+
+#define	REGOFF(x)	(ulong)(&((struct Ureg *) 0)->x)
+
+#define	REGSIZE		sizeof(struct Ureg)
+#define	FPREGSIZE	(8*33)
+
+#define	SP		REGOFF(sp)
+#define	PC		REGOFF(pc)
+#define	FP_REG(x)	(REGSIZE+8*(x))
+
+Reglist alphareglist[] = {
+	{"STATUS",	REGOFF(status),	RINT|RRDONLY, 'W'},
+	{"TYPE",	REGOFF(type),	RINT|RRDONLY, 'W'},
+	{"A0",	REGOFF(a0),	RINT|RRDONLY, 'W'},
+	{"A1",	REGOFF(a1),	RINT|RRDONLY, 'W'},
+	{"A2",		REGOFF(a2),	RINT|RRDONLY, 'W'},
+	{"PC",		PC,	RINT, 'X'},
+	{"SP",		SP,	RINT, 'X'},
+	{"R29",		REGOFF(r29),	RINT, 'W'},
+	{"R28",		REGOFF(r28),	RINT, 'W'},
+	{"R27",		REGOFF(r27),	RINT, 'W'},
+	{"R26",		REGOFF(r26),	RINT, 'W'},
+	{"R25",		REGOFF(r25),	RINT, 'W'},
+	{"R24",		REGOFF(r24),	RINT, 'W'},
+	{"R23",		REGOFF(r23),	RINT, 'W'},
+	{"R22",		REGOFF(r22),	RINT, 'W'},
+	{"R21",		REGOFF(r21),	RINT, 'W'},
+	{"R20",		REGOFF(r20),	RINT, 'W'},
+	{"R19",		REGOFF(r19),	RINT, 'W'},
+	{"R18",		REGOFF(r18),	RINT, 'W'},
+	{"R17",		REGOFF(r17),	RINT, 'W'},
+	{"R16",		REGOFF(r16),	RINT, 'W'},
+	{"R15",		REGOFF(r15),	RINT, 'W'},
+	{"R14",		REGOFF(r14),	RINT, 'W'},
+	{"R13",		REGOFF(r13),	RINT, 'W'},
+	{"R12",		REGOFF(r12),	RINT, 'W'},
+	{"R11",		REGOFF(r11),	RINT, 'W'},
+	{"R10",		REGOFF(r10),	RINT, 'W'},
+	{"R9",		REGOFF(r9),	RINT, 'W'},
+	{"R8",		REGOFF(r8),	RINT, 'W'},
+	{"R7",		REGOFF(r7),	RINT, 'W'},
+	{"R6",		REGOFF(r6),	RINT, 'W'},
+	{"R5",		REGOFF(r5),	RINT, 'W'},
+	{"R4",		REGOFF(r4),	RINT, 'W'},
+	{"R3",		REGOFF(r3),	RINT, 'W'},
+	{"R2",		REGOFF(r2),	RINT, 'W'},
+	{"R1",		REGOFF(r1),	RINT, 'W'},
+	{"R0",		REGOFF(r0),	RINT, 'W'},
+	{"F0",		FP_REG(0),	RFLT, 'F'},
+	{"F1",		FP_REG(1),	RFLT, 'F'},
+	{"F2",		FP_REG(2),	RFLT, 'F'},
+	{"F3",		FP_REG(3),	RFLT, 'F'},
+	{"F4",		FP_REG(4),	RFLT, 'F'},
+	{"F5",		FP_REG(5),	RFLT, 'F'},
+	{"F6",		FP_REG(6),	RFLT, 'F'},
+	{"F7",		FP_REG(7),	RFLT, 'F'},
+	{"F8",		FP_REG(8),	RFLT, 'F'},
+	{"F9",		FP_REG(9),	RFLT, 'F'},
+	{"F10",		FP_REG(10),	RFLT, 'F'},
+	{"F11",		FP_REG(11),	RFLT, 'F'},
+	{"F12",		FP_REG(12),	RFLT, 'F'},
+	{"F13",		FP_REG(13),	RFLT, 'F'},
+	{"F14",		FP_REG(14),	RFLT, 'F'},
+	{"F15",		FP_REG(15),	RFLT, 'F'},
+	{"F16",		FP_REG(16),	RFLT, 'F'},
+	{"F17",		FP_REG(17),	RFLT, 'F'},
+	{"F18",		FP_REG(18),	RFLT, 'F'},
+	{"F19",		FP_REG(19),	RFLT, 'F'},
+	{"F20",		FP_REG(20),	RFLT, 'F'},
+	{"F21",		FP_REG(21),	RFLT, 'F'},
+	{"F22",		FP_REG(22),	RFLT, 'F'},
+	{"F23",		FP_REG(23),	RFLT, 'F'},
+	{"F24",		FP_REG(24),	RFLT, 'F'},
+	{"F25",		FP_REG(25),	RFLT, 'F'},
+	{"F26",		FP_REG(26),	RFLT, 'F'},
+	{"F27",		FP_REG(27),	RFLT, 'F'},
+	{"F28",		FP_REG(28),	RFLT, 'F'},
+	{"F29",		FP_REG(29),	RFLT, 'F'},
+	{"F30",		FP_REG(30),	RFLT, 'F'},
+	{"F31",		FP_REG(31),	RFLT, 'F'},
+	{"FPCR",		FP_REG(32),	RFLT, 'W'},
+	{  0 }
+};
+
+	/* the machine description */
+Mach malpha =
+{
+	"alpha",
+	MALPHA,		/* machine type */
+	alphareglist,	/* register set */
+	REGSIZE,	/* number of bytes in reg set */
+	FPREGSIZE,	/* number of bytes in fp reg set */
+	"PC",
+	"SP",
+	"R29",
+	"setSB",	/* static base register name */
+	0,		/* static base register value */
+	0x2000,		/* page size */
+	0x80000000ULL,	/* kernel base */
+	0xF0000000ULL,	/* kernel text mask */
+	0x7FFFFFFFULL,	/* user stack top */
+	4,		/* quantization of pc */
+	4,		/* szaddr */
+	8,		/* szreg (not used?) */
+	4,		/* szfloat */
+	8,		/* szdouble */
+};

+ 265 - 0
sys/src/libmach/7c/7.out.h

@@ -0,0 +1,265 @@
+#define	NSNAME	8
+#define	NSYM	50
+#define	NREG	32
+#define NOPROF	(1<<0)
+#define DUPOK	(1<<1)
+
+enum
+{
+	REGRET		= 0,	/* return register and first temp, grows++ */
+	REGARG		= 0,	/* first arg passed in */
+	REGEXT		= 15,	/* first external register, grows-- */
+
+	REGLINK		= 26,	/* subroutine linkage */
+	REGTMP		= 27,	/* used by the loader */
+	REGTMP2		= 28,	/* used by the loader */
+	REGSB		= 29,	/* static pointer */
+	REGSP		= 30,	/* stack pointer */
+	REGZERO		= 31,	/* always zero */
+
+	FREGRET		= 0,
+	FREGEXT		= 27,	/* first external register */
+	FREGHALF	= 28,	/* double */
+	FREGONE		= 29,	/* double */
+	FREGTWO		= 30,	/* double */
+	FREGZERO	= 31,	/* both float and double */
+};
+
+enum	as
+{
+	AXXX,
+	AGOK,
+	ATEXT,
+	ADATA,
+	AGLOBL,
+	AHISTORY,
+	ANAME,
+	AWORD,
+
+	ANOP,
+
+	AMOVL,
+	AMOVLU,
+	AMOVQ,
+	AMOVQU,
+	AMOVS,
+	AMOVT,
+
+	AMOVB,
+	AMOVBU,
+	AMOVW,
+	AMOVWU,
+
+	AMOVA,
+	AMOVAH,
+
+	AMOVLL,
+	AMOVQL,
+	AMOVLC,
+	AMOVQC,
+
+	AMOVQP,
+	AMOVLP,
+
+	AADDL,
+	AADDLV,
+	AADDQ,
+	AADDQV,
+	AS4ADDL,
+	AS4ADDQ,
+	AS8ADDL,
+	AS8ADDQ,
+	AS4SUBL,
+	AS4SUBQ,
+	AS8SUBL,
+	AS8SUBQ,
+	ASUBL,
+	ASUBLV,
+	ASUBQ,
+	ASUBQV,
+
+	ACMPEQ,
+	ACMPGT,
+	ACMPGE,
+	ACMPUGT,
+	ACMPUGE,
+	ACMPBLE,
+
+	AAND,
+	AANDNOT,
+	AOR,
+	AORNOT,
+	AXOR,
+	AXORNOT,
+
+	ACMOVEQ,
+	ACMOVNE,
+	ACMOVLT,
+	ACMOVGE,
+	ACMOVLE,
+	ACMOVGT,
+	ACMOVLBC,
+	ACMOVLBS,
+
+	AMULL,
+	AMULQ,
+	AMULLV,
+	AMULQV,
+	AUMULH,
+	ADIVQ,
+	AMODQ,
+	ADIVQU,
+	AMODQU,
+	ADIVL,
+	AMODL,
+	ADIVLU,
+	AMODLU,
+
+	ASLLQ,
+	ASRLQ,
+	ASRAQ,
+	ASLLL,
+	ASRLL,
+	ASRAL,
+
+	AEXTBL,
+	AEXTWL,
+	AEXTLL,
+	AEXTQL,
+	AEXTWH,
+	AEXTLH,
+	AEXTQH,
+
+	AINSBL,
+	AINSWL,
+	AINSLL,
+	AINSQL,
+	AINSWH,
+	AINSLH,
+	AINSQH,
+
+	AMSKBL,
+	AMSKWL,
+	AMSKLL,
+	AMSKQL,
+	AMSKWH,
+	AMSKLH,
+	AMSKQH,
+
+	AZAP,
+	AZAPNOT,
+
+	AJMP,
+	AJSR,
+	ARET,
+
+	ABR,
+	ABSR,
+
+	ABEQ,
+	ABNE,
+	ABLT,
+	ABGE,
+	ABLE,
+	ABGT,
+	ABLBC,
+	ABLBS,
+
+	AFBEQ,
+	AFBNE,
+	AFBLT,
+	AFBGE,
+	AFBLE,
+	AFBGT,
+
+	ATRAPB,
+	AMB,
+	AFETCH,
+	AFETCHM,
+	ARPCC,
+
+	ACPYS,
+	ACPYSN,
+	ACPYSE,
+	ACVTLQ,
+	ACVTQL,
+	AFCMOVEQ,
+	AFCMOVNE,
+	AFCMOVLT,
+	AFCMOVGE,
+	AFCMOVLE,
+	AFCMOVGT,
+
+	AADDS,
+	AADDT,
+	ACMPTEQ,
+	ACMPTGT,
+	ACMPTGE,
+	ACMPTUN,
+	ACVTQS,
+	ACVTQT,
+	ACVTTS,
+	ACVTTQ,
+	ADIVS,
+	ADIVT,
+	AMULS,
+	AMULT,
+	ASUBS,
+	ASUBT,
+
+	ACALL_PAL,
+	AREI,
+
+	AEND,
+
+	ADYNT,
+	AINIT,
+
+	ASIGNAME,
+
+	ALAST,
+};
+
+/* type/name */
+enum
+{
+	D_GOK	= 0,
+	D_NONE,
+
+/* name */
+	D_EXTERN,
+	D_STATIC,
+	D_AUTO,
+	D_PARAM,
+
+/* type */
+	D_BRANCH,
+	D_OREG,
+	D_CONST,
+	D_FCONST,
+	D_SCONST,
+	D_REG,
+	D_FREG,
+	D_FCREG,
+	D_PREG,
+	D_PCC,
+	D_FILE,
+	D_FILE1,
+};
+
+/*
+ * this is the ranlib header
+ */
+#define	SYMDEF	"__.SYMDEF"
+
+/*
+ * this is the simulated IEEE floating point
+ */
+typedef	struct	ieee	Ieee;
+struct	ieee
+{
+	long	l;	/* contains ls-man	0xffffffff */
+	long	h;	/* contains sign	0x80000000
+				    exp		0x7ff00000
+				    ms-man	0x000fffff */
+};

+ 49 - 0
sys/src/libmach/7c/ureg.h

@@ -0,0 +1,49 @@
+struct Ureg
+{
+	/* l.s saves 31 64-bit values: */
+	uvlong	type;
+	uvlong	a0;
+	uvlong	a1;
+	uvlong	a2;
+
+	uvlong	r0;
+	uvlong	r1;
+	uvlong	r2;
+	uvlong	r3;
+	uvlong	r4;
+	uvlong	r5;
+	uvlong	r6;
+	uvlong	r7;
+	uvlong	r8;
+	uvlong	r9;
+	uvlong	r10;
+	uvlong	r11;
+	uvlong	r12;
+	uvlong	r13;
+	uvlong	r14;
+	uvlong	r15;
+
+	uvlong	r19;
+	uvlong	r20;
+	uvlong	r21;
+	uvlong	r22;
+	uvlong	r23;
+	uvlong	r24;
+	uvlong	r25;
+	uvlong	r26;
+	uvlong	r27;
+	uvlong	r28;
+	union {
+		uvlong	r30;
+		uvlong	usp;
+		uvlong	sp;
+	};
+
+	/* OSF/1 PALcode frame: */
+	uvlong	status;	/* PS */
+	uvlong	pc;
+	uvlong	r29;		/* GP */
+	uvlong	r16;		/* a0 */
+	uvlong	r17;		/* a1 */
+	uvlong	r18;		/* a2 */
+};

+ 925 - 0
sys/src/libmach/7db.c

@@ -0,0 +1,925 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <mach.h>
+/*
+ * Alpha-specific debugger interface
+ */
+
+static 	char	*alphaexcep(Map*, Rgetter);
+static	int	alphafoll(Map*, uvlong, Rgetter, uvlong*);
+static	int	alphainst(Map*, uvlong, char, char*, int);
+static	int	alphadas(Map*, uvlong, char*, int);
+static	int	alphainstlen(Map*, uvlong);
+/*
+ *	Debugger interface
+ */
+Machdata alphamach =
+{
+	{0x80, 0, 0, 0},		/* break point */
+	4,			/* break point size */
+
+	leswab,			/* short to local byte order */
+	leswal,			/* long to local byte order */
+	leswav,			/* vlong to local byte order */
+	risctrace,		/* C traceback */
+	riscframe,		/* Frame finder */
+	alphaexcep,		/* print exception */
+	0,			/* breakpoint fixup */
+	leieeesftos,		/* single precision float printer */
+	leieeedftos,		/* double precisioin float printer */
+	alphafoll,		/* following addresses */
+	alphainst,		/* print instruction */
+	alphadas,		/* dissembler */
+	alphainstlen,		/* instruction size */
+};
+
+static char *illegaltype[] = {
+	"breakpoint",
+	"bugchk",
+	"gentrap",
+	"fen",
+	"illegal instruction",
+};
+
+static char *
+alphaexcep(Map *map, Rgetter rget)
+{
+	ulong type, a0, a1;
+	static char buf[256];
+
+	type = (*rget)(map, "TYPE");
+	a0 = (*rget)(map, "A0");
+	a1 = (*rget)(map, "A1");
+/*	a2 = (*rget)(map, "A2"); */
+
+	switch (type) {
+	case 1:	/* arith */
+		sprint(buf, "trap: arithmetic trap 0x%lux", a0);
+		break;
+	case 2:	/* bad instr or FEN */
+		if (a0 <= 4)
+			return illegaltype[a0];
+		else
+			sprint(buf, "illegal instr trap, unknown type %lud", a0);
+		break;
+	case 3:	/* intr */
+		sprint(buf, "interrupt type %lud", a0);
+		break;
+	case 4:	/* memory fault */
+		sprint(buf, "fault %s addr=0x%lux", (a1&1)?"write":"read", a0);
+		break;
+	case 5:	/* syscall() */
+		return "system call";
+	case 6:	/* alignment fault */
+		sprint(buf, "unaligned op 0x%lux addr 0x%lux", a1, a0);
+		break;
+	default:	/* cannot happen */
+		sprint(buf, "unknown exception type %lud", type);
+		break;
+	}
+	return buf;
+}
+
+	/* alpha disassembler and related functions */
+
+static	char FRAMENAME[] = ".frame";
+
+typedef struct {
+	uvlong addr;
+	uchar op;			/* bits 31-26 */
+	uchar ra;			/* bits 25-21 */
+	uchar rb;			/* bits 20-16 */
+	uchar rc;			/* bits 4-0 */
+	long mem;			/* bits 15-0 */
+	long branch;			/* bits 20-0 */
+	uchar function;			/* bits 11-5 */
+	uchar literal;			/* bits 20-13 */
+	uchar islit;			/* bit 12 */
+	uchar fpfn;			/* bits 10-5 */
+	uchar fpmode;			/* bits 15-11 */
+	long w0;
+	long w1;
+	int size;			/* instruction size */
+	char *curr;			/* fill point in buffer */
+	char *end;			/* end of buffer */
+	char *err;			/* error message */
+} Instr;
+
+static Map *mymap;
+
+static int
+decode(uvlong pc, Instr *i)
+{
+	ulong w;
+
+	if (get4(mymap, pc, &w) < 0) {
+		werrstr("can't read instruction: %r");
+		return -1;
+	}
+	i->addr = pc;
+	i->size = 1;
+	i->op = (w >> 26) & 0x3F;
+	i->ra = (w >> 21) & 0x1F;
+	i->rb = (w >> 16) & 0x1F;
+	i->rc = w & 0x1F;
+	i->function = (w >> 5) & 0x7F;
+	i->mem = w & 0xFFFF;
+	if (i->mem & 0x8000)
+		i->mem -= 0x10000;
+	i->branch = w & 0x1FFFFF;
+	if (i->branch & 0x100000)
+		i->branch -= 0x200000;
+	i->function = (w >> 5) & 0x7F;
+	i->literal = (w >> 13) & 0xFF;
+	i->islit = (w >> 12) & 0x01;
+	i->fpfn = (w >> 5) & 0x3F;
+	i->fpmode = (w >> 11) & 0x1F;
+	i->w0 = w;
+	return 1;
+}
+
+static int
+mkinstr(uvlong pc, Instr *i)
+{
+/*	Instr x; */
+
+	if (decode(pc, i) < 0)
+		return -1;
+
+#ifdef	frommips
+/* we probably want to do something like this for alpha... */
+	/*
+	 * if it's a LUI followed by an ORI,
+	 * it's an immediate load of a large constant.
+	 * fix the LUI immediate in any case.
+	 */
+	if (i->op == 0x0F) {
+		if (decode(pc+4, &x) < 0)
+			return 0;
+		i->immediate <<= 16;
+		if (x.op == 0x0D && x.rs == x.rt && x.rt == i->rt) {
+			i->immediate |= (x.immediate & 0xFFFF);
+			i->w1 = x.w0;
+			i->size++;
+			return 1;
+		}
+	}
+#endif
+	return 1;
+}
+
+#pragma	varargck	argpos	bprint		2
+
+static void
+bprint(Instr *i, char *fmt, ...)
+{
+	va_list arg;
+
+	va_start(arg, fmt);
+	i->curr = vseprint(i->curr, i->end, fmt, arg);
+	va_end(arg);
+}
+
+typedef struct Opcode Opcode;
+
+struct Opcode {
+	char *mnemonic;
+	void (*f)(Opcode *, Instr *);
+	char *ken;
+};
+
+static void format(char *, Instr *, char *);
+
+static int
+plocal(Instr *i, char *m, char r, int store)
+{
+	int offset;
+	char *reg;
+	Symbol s;
+
+	if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s))
+		return 0;
+	if (s.value > i->mem) {
+		if(!getauto(&s, s.value-i->mem, CAUTO, &s))
+			return 0;
+		reg = "(SP)";
+		offset = i->mem;
+	} else {
+		offset = i->mem-s.value-8;
+		if (!getauto(&s, offset, CPARAM, &s))
+			return 0;
+		reg = "(FP)";
+	}
+	if (store)
+		bprint(i, "%s\t%c%d,%s+%d%s", m, r, i->ra, s.name, offset, reg);
+	else
+		bprint(i, "%s\t%s+%d%s,%c%d", m, s.name, offset, reg, r, i->ra);
+	return 1;
+}
+
+static void
+_load(Opcode *o, Instr *i, char r)
+{
+	char *m;
+
+	m = o->mnemonic;
+	if (i->rb == 30 && plocal(i, m, r, 0))
+		return;
+	if (i->rb == 29 && mach->sb) {
+		bprint(i, "%s\t", m);
+		i->curr += symoff(i->curr, i->end-i->curr, i->mem+mach->sb, CANY);
+		bprint(i, "(SB),%c%d", r, i->ra);
+		return;
+	}
+	format(m, i, o->ken);
+}
+
+static void
+load(Opcode *o, Instr *i)
+{
+	_load(o, i, 'R');
+}
+
+static void
+loadf(Opcode *o, Instr *i)
+{
+	_load(o, i, 'F');
+}
+
+static void
+_store(Opcode *o, Instr *i, char r)
+{
+	char *m;
+
+	m = o->mnemonic;
+	if (i->rb == 30 && plocal(i, m, r, 1))
+		return;
+	if (i->rb == 29 && mach->sb) {
+		bprint(i, "%s\t%c%d,", m, r, i->ra);
+		i->curr += symoff(i->curr, i->end-i->curr, i->mem+mach->sb, CANY);
+		bprint(i, "(SB)");
+		return;
+	}
+	format(o->mnemonic, i, o->ken);
+}
+
+static void
+store(Opcode *o, Instr *i)
+{
+	_store(o, i, 'R');
+}
+
+static void
+storef(Opcode *o, Instr *i)
+{
+	_store(o, i, 'F');
+}
+
+static void
+misc(Opcode *o, Instr *i)
+{
+	char *f;
+
+	USED(o);
+	switch (i->mem&0xFFFF) {
+	case 0x0000:
+		f = "TRAPB";
+		break;
+	case 0x4000:
+		f = "MB";
+		break;
+	case 0x8000:
+		f = "FETCH\t0(R%b)";
+		break;
+	case 0xA000:
+		f = "FETCH_M\t0(R%b)";
+		break;
+	case 0xC000:
+		f = "RPCC\tR%a";
+		break;
+	case 0xE000:
+		f = "RC\tR%a";
+		break;
+	case 0xF000:
+		f = "RS\tR%a";
+		break;
+	default:
+		f = "%w";
+	}
+	format(0, i, f);
+}
+
+static char	*jmpcode[4] = { "JMP", "JSR", "RET", "JSR_COROUTINE" };
+
+static void
+jmp(Opcode *o, Instr *i)
+{
+	int hint;
+	char *m;
+
+	USED(o);
+	hint = (i->mem >> 14) & 3;
+	m = jmpcode[hint];
+	if (i->ra == 31) {
+		if (hint == 2 && i->rb == 29)
+			bprint(i, m);
+		else
+			format(m, i, "(R%b)");
+	}
+	else
+		format(m, i, "R%a,(R%b)");
+}
+
+static void
+br(Opcode *o, Instr *i)
+{
+	if (i->ra == 31)
+		format(o->mnemonic, i, "%B");
+	else
+		format(o->mnemonic, i, o->ken);
+}
+
+static void
+bsr(Opcode *o, Instr *i)
+{
+	if (i->ra == 26)
+		format(o->mnemonic, i, "%B");
+	else
+		format(o->mnemonic, i, o->ken);
+}
+
+static void
+mult(Opcode *o, Instr *i)
+{
+	char *m;
+
+	switch (i->function) {
+	case 0x00:
+		m = "MULL";
+		break;
+	case 0x20:
+		m = "MULQ";
+		break;
+	case 0x40:
+		m = "MULL/V";
+		break;
+	case 0x60:
+		m = "MULQ/V";
+		break;
+	case 0x30:
+		m = "UMULH";
+		break;
+	default:
+		format("???", i, "%w");
+		return;
+	}
+	format(m, i, o->ken);
+}
+
+static char	alphaload[] = "%l,R%a";
+static char	alphafload[] = "%l,F%a";
+static char	alphastore[] = "R%a,%l";
+static char	alphafstore[] = "F%a,%l";
+static char	alphabranch[] = "R%a,%B";
+static char	alphafbranch[] = "F%a,%B";
+static char	alphaint[] = "%v,R%a,R%c";
+static char	alphafp[] = "F%b,F%a,F%c";
+static char	alphafp2[] = "F%b,F%c";
+static char	alphaxxx[] = "%w";
+
+static Opcode opcodes[64] = {
+	"PAL",		0,	alphaxxx,
+	"OPC01",	0,	alphaxxx,
+	"OPC02",	0,	alphaxxx,
+	"OPC03",	0,	alphaxxx,
+	"OPC04",	0,	alphaxxx,
+	"OPC05",	0,	alphaxxx,
+	"OPC06",	0,	alphaxxx,
+	"OPC07",	0,	alphaxxx,
+	"MOVQA",	load,	alphaload,
+	"MOVQAH",	load,	alphaload,
+	"MOVBU",	load,	alphaload,		/* v 3 */
+	"MOVQU",	load,	alphaload,
+	"MOVWU",	load,	alphaload,		/* v 3 */
+	"MOVWU",	store,	alphastore,		/* v 3 */
+	"MOVBU",	store,	alphastore,		/* v 3 */
+	"MOVQU",	store,	alphastore,
+	0,		0,	0,			/* int arith */
+	0,		0,	0,			/* logical */
+	0,		0,	0,			/* shift */
+	0,		mult,	alphaint,
+	"OPC14",	0,	alphaxxx,
+	"vax",		0,	alphafp,		/* vax */
+	0,		0,	0,			/* ieee */
+	0,		0,	0,			/* fp */
+	0,		misc,	alphaxxx,
+	"PAL19 [HW_MFPR]",0,	alphaxxx,
+	"JSR",		jmp,	0,
+	"PAL1B [HW_LD]",0,	alphaxxx,
+	"OPC1C",	0,	alphaxxx,
+	"PAL1D [HW_MTPR]",0,	alphaxxx,
+	"PAL1E [HW_REI]",0,	alphaxxx,
+	"PAL1F [HW_ST]",0,	alphaxxx,
+	"MOVF",		loadf,	alphafload,
+	"MOVG",		loadf,	alphafload,
+	"MOVS",		loadf,	alphafload,
+	"MOVT",		loadf,	alphafload,
+	"MOVF",		storef,	alphafstore,
+	"MOVG",		storef,	alphafstore,
+	"MOVS",		storef,	alphafstore,
+	"MOVT",		storef,	alphafstore,
+	"MOVL",		load,	alphaload,
+	"MOVQ",		load,	alphaload,
+	"MOVLL",	load,	alphaload,
+	"MOVQL",	load,	alphaload,
+	"MOVL",		store,	alphastore,
+	"MOVQ",		store,	alphastore,
+	"MOVLC",	store,	alphastore,
+	"MOVQC",	store,	alphastore,
+	"JMP",		br,	alphabranch,
+	"FBEQ",		0,	alphafbranch,
+	"FBLT",		0,	alphafbranch,
+	"FBLE",		0,	alphafbranch,
+	"JSR",		bsr,	alphabranch,
+	"FBNE",		0,	alphafbranch,
+	"FBGE",		0,	alphafbranch,
+	"FBGT",		0,	alphafbranch,
+	"BLBC",		0,	alphafbranch,
+	"BEQ",		0,	alphabranch,
+	"BLT",		0,	alphabranch,
+	"BLE",		0,	alphabranch,
+	"BLBS",		0,	alphabranch,
+	"BNE",		0,	alphabranch,
+	"BGE",		0,	alphabranch,
+	"BGT",		0,	alphabranch,
+};
+
+static Opcode fpopcodes[64] = {
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+
+	"CVTLQ",	0,	alphafp2,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+
+	"CPYS",		0,	alphafp,
+	"CPYSN",	0,	alphafp,
+	"CPYSE",	0,	alphafp,
+	"???",		0,	alphaxxx,
+	"MOVT",		0,	"FPCR,F%a",
+	"MOVT",		0,	"F%a,FPCR",
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"FCMOVEQ",	0,	alphafp,
+	"FCMOVNE",	0,	alphafp,
+	"FCMOVLT",	0,	alphafp,
+	"FCMOVGE",	0,	alphafp,
+	"FCMOVLE",	0,	alphafp,
+	"FCMOVGT",	0,	alphafp,
+
+	"CVTQL",	0,	alphafp2,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+};
+
+static Opcode ieeeopcodes[64] = {
+	"ADDS",		0,	alphafp,
+	"SUBS",		0,	alphafp,
+	"MULS",		0,	alphafp,
+	"DIVS",		0,	alphafp,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+
+	"ADDT",		0,	alphafp,
+	"SUBT",		0,	alphafp,
+	"MULT",		0,	alphafp,
+	"DIVT",		0,	alphafp,
+	"CMPTUN",	0,	alphafp,
+	"CMPTEQ",	0,	alphafp,
+	"CMPTLT",	0,	alphafp,
+	"CMPTLE",	0,	alphafp,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"CVTTS",	0,	alphafp2,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"CVTTQ",	0,	alphafp2,
+
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"???",		0,	alphaxxx,
+	"CVTQS",	0,	alphafp2,
+	"???",		0,	alphaxxx,
+	"CVTQT",	0,	alphafp2,
+	"???",		0,	alphaxxx,
+};
+
+static uchar	amap[128] = {
+	[0x00]	1,
+	[0x40]	2,
+	[0x20]	3,
+	[0x60]	4,
+	[0x09]	5,
+	[0x49]	6,
+	[0x29]	7,
+	[0x69]	8,
+	[0x2D]	9,
+	[0x4D]	10,
+	[0x6D]	11,
+	[0x1D]	12,	
+	[0x3D]	13,	
+	[0x0F]	14,	
+	[0x02]	15,	
+	[0x0B]	16,	
+	[0x12]	17,	
+	[0x1B]	18,
+	[0x22]	19,	
+	[0x2B]	20,	
+	[0x32]	21,	
+	[0x3B]	22,
+};
+
+static Opcode arithopcodes[64] = {
+	"???",		0,	alphaxxx,
+	"ADDL",		0,	alphaint,
+	"ADDL/V",	0,	alphaint,
+	"ADDQ",		0,	alphaint,
+	"ADDQ/V",	0,	alphaint,
+	"SUBL",		0,	alphaint,
+	"SUBL/V",	0,	alphaint,
+	"SUBQ",		0,	alphaint,
+	"SUBQ/V",	0,	alphaint,
+	"CMPEQ",	0,	alphaint,
+	"CMPLT",	0,	alphaint,
+	"CMPLE",	0,	alphaint,
+	"CMPULT",	0,	alphaint,
+	"CMPULE",	0,	alphaint,
+	"CMPBGE",	0,	alphaint,
+	"S4ADDL",	0,	alphaint,
+	"S4SUBL",	0,	alphaint,
+	"S8ADDL",	0,	alphaint,
+	"S8SUBL",	0,	alphaint,
+	"S4ADDQ",	0,	alphaint,
+	"S4SUBQ",	0,	alphaint,
+	"S8ADDQ",	0,	alphaint,
+	"S8SUBQ",	0,	alphaint,
+};
+
+static uchar	lmap[128] = {
+	[0x00]	1,
+	[0x20]	2,
+	[0x40]	3,
+	[0x08]	4,
+	[0x28]	5,
+	[0x48]	6,
+	[0x24]	7,
+	[0x44]	8,
+	[0x64]	9,
+	[0x26]	7,
+	[0x46]	8,
+	[0x66]	9,
+	[0x14]	10,
+	[0x16]	11,
+};
+
+static Opcode logicalopcodes[64] = {
+	"???",		0,	alphaxxx,
+	"AND",		0,	alphaint,
+	"OR",		0,	alphaint,
+	"XOR",		0,	alphaint,
+	"ANDNOT",	0,	alphaint,
+	"ORNOT",	0,	alphaint,
+	"XORNOT",	0,	alphaint,
+	"CMOVEQ",	0,	alphaint,
+	"CMOVLT",	0,	alphaint,
+	"CMOVLE",	0,	alphaint,
+	"CMOVNE",	0,	alphaint,
+	"CMOVGE",	0,	alphaint,
+	"CMOVGT",	0,	alphaint,
+	"CMOVLBS",	0,	alphaint,
+	"CMOVLBC",	0,	alphaint,
+};
+
+static uchar	smap[128] = {
+	[0x39]	1,
+	[0x3C]	2,
+	[0x34]	3,
+	[0x06]	4,
+	[0x16]	5,
+	[0x26]	6,
+	[0x36]	7,
+	[0x5A]	8,
+	[0x6A]	9,
+	[0x7A]	10,
+	[0x0B]	11,
+	[0x1B]	12,
+	[0x2B]	13,
+	[0x3B]	14,
+	[0x57]	15,
+	[0x67]	16,
+	[0x77]	17,
+	[0x02]	18,
+	[0x12]	19,
+	[0x22]	20,
+	[0x32]	21,
+	[0x52]	22,
+	[0x62]	23,
+	[0x72]	24,
+	[0x30]	25,
+	[0x31]	26,
+};
+
+static Opcode shiftopcodes[64] = {
+	"???",		0,	alphaxxx,
+	"SLLQ",		0,	alphaint,
+	"SRAQ",		0,	alphaint,
+	"SRLQ",		0,	alphaint,
+	"EXTBL",	0,	alphaint,
+	"EXTWL",	0,	alphaint,
+	"EXTLL",	0,	alphaint,
+	"EXTQL",	0,	alphaint,
+	"EXTWH",	0,	alphaint,
+	"EXTLH",	0,	alphaint,
+	"EXTQH",	0,	alphaint,
+	"INSBL",	0,	alphaint,
+	"INSWL",	0,	alphaint,
+	"INSLL",	0,	alphaint,
+	"INSQL",	0,	alphaint,
+	"INSWH",	0,	alphaint,
+	"INSLH",	0,	alphaint,
+	"INSQH",	0,	alphaint,
+	"MSKBL",	0,	alphaint,
+	"MSKWL",	0,	alphaint,
+	"MSKLL",	0,	alphaint,
+	"MSKQL",	0,	alphaint,
+	"MSKWH",	0,	alphaint,
+	"MSKLH",	0,	alphaint,
+	"MSKQH",	0,	alphaint,
+	"ZAP",		0,	alphaint,
+	"ZAPNOT",	0,	alphaint,
+};
+
+static void
+format(char *mnemonic, Instr *i, char *f)
+{
+	if (mnemonic)
+		format(0, i, mnemonic);
+	if (f == 0)
+		return;
+	if (mnemonic)
+		if (i->curr < i->end)
+			*i->curr++ = '\t';
+	for ( ; *f && i->curr < i->end; f++) {
+		if (*f != '%') {
+			*i->curr++ = *f;
+			continue;
+		}
+		switch (*++f) {
+
+		case 'a':
+			bprint(i, "%d", i->ra);
+			break;
+
+		case 'b':
+			bprint(i, "%d", i->rb);
+			break;
+
+		case 'c':
+			bprint(i, "%d", i->rc);
+			break;
+
+		case 'v':
+			if (i->islit)
+				bprint(i, "$%ux", i->literal);
+			else
+				bprint(i, "R%d", i->rb);
+			break;
+
+		case 'l':
+			bprint(i, "%lx(R%d)", i->mem, i->rb);
+			break;
+
+		case 'i':
+			bprint(i, "$%lx", i->mem);
+			break;
+
+		case 'B':
+			i->curr += symoff(i->curr, i->end-i->curr,
+				(i->branch<<2)+i->addr+4, CANY);
+			break;
+
+		case 'w':
+			bprint(i, "[%lux]", i->w0);
+			break;
+
+		case '\0':
+			*i->curr++ = '%';
+			return;
+
+		default:
+			bprint(i, "%%%c", *f);
+			break;
+		}
+	}
+	*i->curr = 0;
+}
+
+static int
+printins(Map *map, uvlong pc, char *buf, int n)
+{
+	Instr i;
+	Opcode *o;
+	uchar op;
+
+	i.curr = buf;
+	i.end = buf+n-1;
+	mymap = map;
+	if (mkinstr(pc, &i) < 0)
+		return -1;
+	switch (i.op) {
+
+	case 0x10:					/* INTA */
+		o = arithopcodes;
+		op = amap[i.function];
+		break;
+
+	case 0x11:					/* INTL */
+		o = logicalopcodes;
+		op = lmap[i.function];
+		break;
+
+	case 0x12:					/* INTS */
+		o = shiftopcodes;
+		op = smap[i.function];
+		break;
+
+	case 0x16:					/* FLTI */
+		o = ieeeopcodes;
+		op = i.fpfn;
+		break;
+
+	case 0x17:					/* FLTL */
+		o = fpopcodes;
+		op = i.fpfn;
+		break;
+
+	default:
+		o = opcodes;
+		op = i.op;
+		break;
+	}
+	if (o[op].f)
+		(*o[op].f)(&o[op], &i);
+	else
+		format(o[op].mnemonic, &i, o[op].ken);
+	return i.size*4;
+}
+
+static int
+alphainst(Map *map, uvlong pc, char modifier, char *buf, int n)
+{
+	USED(modifier);
+	return printins(map, pc, buf, n);
+}
+
+static int
+alphadas(Map *map, uvlong pc, char *buf, int n)
+{
+	Instr i;
+
+	i.curr = buf;
+	i.end = buf+n;
+	mymap = map;
+	if (mkinstr(pc, &i) < 0)
+		return -1;
+	if (i.end-i.curr > 8)
+		i.curr = _hexify(buf, i.w0, 7);
+	if (i.size == 2 && i.end-i.curr > 9) {
+		*i.curr++ = ' ';
+		i.curr = _hexify(i.curr, i.w1, 7);
+	}
+	*i.curr = 0;
+	return i.size*4;
+}
+
+static int
+alphainstlen(Map *map, uvlong pc)
+{
+	Instr i;
+
+	mymap = map;
+	if (mkinstr(pc, &i) < 0)
+		return -1;
+	return i.size*4;
+}
+
+static int
+alphafoll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
+{
+	char buf[8];
+	Instr i;
+
+	mymap = map;
+	if (mkinstr(pc, &i) < 0)
+		return -1;
+
+	switch(i.op) {
+	case 0x1A:				/* JMP/JSR/RET */
+		sprint(buf, "R%d", i.rb);
+		foll[0] = (*rget)(map, buf);
+		return 1;
+	case 0x30:				/* BR */
+	case 0x34:				/* BSR */
+		foll[0] = pc+4 + (i.branch<<2);
+		return 1;
+	default:
+		if (i.op > 0x30) {		/* cond */
+			foll[0] = pc+4;
+			foll[1] = pc+4 + (i.branch<<2);
+			return 2;
+		}
+		foll[0] = pc+i.size*4;
+		return 1;
+	}
+}

+ 138 - 0
sys/src/libmach/7obj.c

@@ -0,0 +1,138 @@
+/*
+ * 7obj.c - identify and parse an alpha object file
+ */
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <mach.h>
+#include "7c/7.out.h"
+#include "obj.h"
+
+typedef struct Addr	Addr;
+struct Addr
+{
+	char	type;
+	char	sym;
+	char	name;
+};
+static Addr addr(Biobuf*);
+static char type2char(int);
+static void skip(Biobuf*, int);
+
+int
+_is7(char *s)
+{
+	return  s[0] == ANAME				/* ANAME */
+		&& s[1] == D_FILE			/* type */
+		&& s[2] == 1				/* sym */
+		&& s[3] == '<';				/* name of file */
+}
+
+int
+_read7(Biobuf *bp, Prog *p)
+{
+	int as, n;
+	Addr a;
+
+	as = Bgetc(bp);			/* as */
+	if(as < 0)
+		return 0;
+	p->kind = aNone;
+	p->sig = 0;
+	if(as == ANAME || as == ASIGNAME){
+		if(as == ASIGNAME){
+			Bread(bp, &p->sig, 4);
+			p->sig = leswal(p->sig);
+		}
+		p->kind = aName;
+		p->type = type2char(Bgetc(bp));		/* type */
+		p->sym = Bgetc(bp);			/* sym */
+		n = 0;
+		for(;;) {
+			as = Bgetc(bp);
+			if(as < 0)
+				return 0;
+			n++;
+			if(as == 0)
+				break;
+		}
+		p->id = malloc(n);
+		if(p->id == 0)
+			return 0;
+		Bseek(bp, -n, 1);
+		if(Bread(bp, p->id, n) != n)
+			return 0;
+		return 1;
+	}
+	if(as == ATEXT)
+		p->kind = aText;
+	else if(as == AGLOBL)
+		p->kind = aData;
+	skip(bp, 5);		/* reg(1), lineno(4) */
+	a = addr(bp);
+	addr(bp);
+	if(a.type != D_OREG || a.name != D_STATIC && a.name != D_EXTERN)
+		p->kind = aNone;
+	p->sym = a.sym;
+	return 1;
+}
+
+static Addr
+addr(Biobuf *bp)
+{
+	Addr a;
+	vlong off;
+
+	a.type = Bgetc(bp);	/* a.type */
+	skip(bp,1);		/* reg */
+	a.sym = Bgetc(bp);	/* sym index */
+	a.name = Bgetc(bp);	/* sym type */
+	switch(a.type){
+	default:
+	case D_NONE: case D_REG: case D_FREG: case D_PREG:
+	case D_FCREG: case D_PCC:
+		break;
+	case D_OREG:
+	case D_CONST:
+	case D_BRANCH:
+		off = (uvlong)Bgetc(bp);
+		off |= (uvlong)Bgetc(bp) << 8;
+		off |= (uvlong)Bgetc(bp) << 16;
+		off |= (uvlong)Bgetc(bp) << 24;
+		off |= (uvlong)Bgetc(bp) << 32;
+		off |= (uvlong)Bgetc(bp) << 40;
+		off |= (uvlong)Bgetc(bp) << 48;
+		off |= (uvlong)Bgetc(bp) << 56;
+		if(off < 0)
+			off = -off;
+		if(a.sym && (a.name==D_PARAM || a.name==D_AUTO))
+			_offset(a.sym, off);
+		break;
+	case D_SCONST:
+		skip(bp, NSNAME);
+		break;
+	case D_FCONST:
+		skip(bp, 8);
+		break;
+	}
+	return a;
+}
+
+static char
+type2char(int t)
+{
+	switch(t){
+	case D_EXTERN:		return 'U';
+	case D_STATIC:		return 'b';
+	case D_AUTO:		return 'a';
+	case D_PARAM:		return 'p';
+	default:		return UNKNOWN;
+	}
+}
+
+static void
+skip(Biobuf *bp, int n)
+{
+	while (n-- > 0)
+		Bgetc(bp);
+}

+ 25 - 0
sys/src/libmach/executable.c

@@ -68,6 +68,7 @@ extern	Mach	mamd64;
 extern	Mach	marm;
 extern	Mach	mpower;
 extern	Mach	mpower64;
+extern	Mach	malpha;
 
 ExecTable exectab[] =
 {
@@ -233,6 +234,24 @@ ExecTable exectab[] =
 		sizeof(Exec),
 		leswal,
 		armdotout },
+	{ L_MAGIC,			/* alpha 7.out */
+		"alpha plan 9 executable",
+		"alpha plan 9 dlm",
+		FALPHA,
+		1,
+		&malpha,
+		sizeof(Exec),
+		beswal,
+		common },
+	{ 0x0700e0c3,			/* alpha boot image */
+		"alpha plan 9 boot image",
+		nil,
+		FALPHA,
+		0,
+		&malpha,
+		sizeof(Exec),
+		beswal,
+		common },
 	{ 0 },
 };
 
@@ -375,6 +394,12 @@ commonboot(Fhdr *fp)
 		fp->name = "ARM plan 9 boot image";
 		fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
 		return;
+	case FALPHA:
+		fp->type = FALPHAB;
+		fp->txtaddr = (u32int)fp->entry;
+		fp->name = "alpha plan 9 boot image";
+		fp->dataddr = fp->txtaddr+fp->txtsz;
+		break;
 	case FPOWER:
 		fp->type = FPOWERB;
 		fp->txtaddr = (u32int)fp->entry;

+ 5 - 0
sys/src/libmach/mkfile

@@ -18,6 +18,7 @@ FILES=\
 	2\
 	5\
 	6\
+	7\
 	8\
 	9\
 	vdb\
@@ -26,6 +27,7 @@ FILES=\
 	qdb\
 	2db\
 	5db\
+	7db\
 	8db\
 	vobj\
 	kobj\
@@ -33,6 +35,7 @@ FILES=\
 	2obj\
 	5obj\
 	6obj\
+	7obj\
 	8obj\
 	9obj\
 	qobj\
@@ -61,5 +64,7 @@ kobj.$O: /sys/src/cmd/kc/k.out.h
 qobj.$O: /sys/src/cmd/qc/q.out.h
 vobj.$O: /sys/src/cmd/vc/v.out.h
 
+7obj.$O: 7c/7.out.h
+
 # 9obj.$O: /sys/src/cmd/9c/9.out.h
 # uobj.$O: uc/u.out.h

+ 1 - 0
sys/src/libmach/obj.c

@@ -56,6 +56,7 @@ static Obj	obj[] =
 	[Obj68020]	"68020 .2",	_is2, _read2,
 	[ObjAmd64]	"amd64 .6",	_is6, _read6,
 	[ObjArm]	"arm .5",	_is5, _read5,
+	[ObjAlpha]	"alpha .7",	_is7, _read7,
 	[Obj386]	"386 .8",	_is8, _read8,
 	[ObjSparc]	"sparc .k",	_isk, _readk,
 	[ObjPower]	"power .q",	_isq, _readq,

+ 8 - 2
sys/src/libmach/setmach.c

@@ -17,9 +17,9 @@ struct machtab
 };
 
 extern	Mach		mmips, msparc, m68020, mi386, mamd64,
-			marm, mmips2be, mmips2le, mpower, mpower64, msparc64;
+			marm, mmips2be, mmips2le, mpower, mpower64, malpha, msparc64;
 extern	Machdata	mipsmach, mipsmachle, sparcmach, m68020mach, i386mach,
-			armmach, mipsmach2le, powermach, sparc64mach;
+			armmach, mipsmach2le, powermach, alphamach, sparc64mach;
 
 /*
  *	machine selection table.  machines with native disassemblers should
@@ -118,6 +118,12 @@ Machtab	machines[] =
 		APOWER64,
 		&mpower64,
 		&powermach,	},
+	{	"alpha",			/*Alpha*/
+		FALPHA,
+		FALPHAB,
+		AALPHA,
+		&malpha,
+		&alphamach,	},
 	{	"sparc64",			/*plan 9 sparc64 */
 		FSPARC64,
 		FSPARCB,			/* XXX? */

+ 1 - 1
sys/src/libmach/u.c

@@ -3,7 +3,7 @@
  */
 #include <u.h>
 #include <bio.h>
-#include "/sparc64/include/ureg.h"
+#include "uc/ureg.h"
 #include <mach.h>
 
 #define	REGOFF(x)	(ulong)(&((struct Ureg *) 0)->x)

+ 51 - 0
sys/src/libmach/uc/ureg.h

@@ -0,0 +1,51 @@
+
+/*
+ * sparc64 registers.
+ * Currently just 32-bit registers (also somewhat compatible with
+ * the sparc32 ureg).
+ */
+struct Ureg
+{
+	ulong	r0;			/* unnecessary; just for symmetry */
+	union{
+		ulong	sp;		/* r1 */
+		ulong	usp;		/* r1 */
+		ulong	r1;
+	};
+	ulong	r2;
+	ulong	r3;
+	ulong	r4;
+	ulong	r5;
+	ulong	r6;
+	ulong	r7;
+	ulong	r8;
+	ulong	r9;
+	ulong	r10;
+	ulong	r11;
+	ulong	r12;
+	ulong	r13;
+	ulong	r14;
+	ulong	r15;
+	ulong	r16;
+	ulong	r17;
+	ulong	r18;
+	ulong	r19;
+	ulong	r20;
+	ulong	r21;
+	ulong	r22;
+	ulong	r23;
+	ulong	r24;
+	ulong	r25;
+	ulong	r26;
+	ulong	r27;
+	ulong	r28;
+	ulong	r29;
+	ulong	r30;
+	ulong	r31;
+	ulong	y;
+	ulong	tt;
+	ulong	pstate;
+	ulong	npc;
+	ulong	pc;
+	ulong	pad;	/* so structure is double word aligned */
+};