From 76fed5426ceaea6cd08be0d22da57062d4ae29a9 Mon Sep 17 00:00:00 2001
From: Russ Cox <rsc@golang.org>
Date: Thu, 29 Jan 2015 16:16:24 -0500
Subject: [PATCH] liblink: the zero Prog is now valid and ready for use
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Use AXXX instead of AGOK (neither is a valid instruction but AXXX is zero)
for the initial setting of Prog.as, and now there are no non-zero default
field settings.

Remove the arch-specific zprog/zprg in favor of a single global zprog.
Remove the arch-specific prg constructor in favor of emallocz(sizeof(Prog)).

Change-Id: Ia73078726768333d7cdba296f548170c1bea9498
Reviewed-on: https://go-review.googlesource.com/3575
Reviewed-by: Aram H膬v膬rneanu <aram@mgk.ro>
Reviewed-by: Austin Clements <austin@google.com>
---
 include/link.h      |  3 ++-
 src/cmd/5g/galign.c |  5 -----
 src/cmd/5g/gg.h     |  1 -
 src/cmd/5g/gsubr.c  |  2 +-
 src/cmd/5g/peep.c   |  1 -
 src/cmd/5l/5.out.h  |  1 -
 src/cmd/6g/galign.c |  9 ---------
 src/cmd/6g/gg.h     |  1 -
 src/cmd/6g/gsubr.c  |  2 +-
 src/cmd/6l/6.out.h  |  1 -
 src/cmd/8g/galign.c |  9 ---------
 src/cmd/8g/gg.h     |  1 -
 src/cmd/8g/gsubr.c  |  4 ++--
 src/cmd/8l/8.out.h  |  1 -
 src/cmd/9a/lex.c    |  4 ++--
 src/cmd/9g/galign.c |  4 ----
 src/cmd/9g/gg.h     |  1 -
 src/cmd/9g/gsubr.c  |  2 +-
 src/cmd/9l/9.out.h  |  1 -
 src/cmd/gc/go.h     |  1 -
 src/cmd/gc/popt.c   |  2 +-
 src/liblink/asm5.c  | 33 ++++++++++++++-------------------
 src/liblink/asm6.c  |  1 -
 src/liblink/asm8.c  |  1 -
 src/liblink/asm9.c  |  4 ++--
 src/liblink/go.c    |  1 +
 src/liblink/ld.c    |  6 ++++--
 src/liblink/obj5.c  | 28 ++++++----------------------
 src/liblink/obj6.c  | 28 ++--------------------------
 src/liblink/obj8.c  | 27 ++-------------------------
 src/liblink/obj9.c  | 34 +++++++++-------------------------
 31 files changed, 50 insertions(+), 169 deletions(-)

diff --git a/include/link.h b/include/link.h
index a72c66d17e..78de54b2fb 100644
--- a/include/link.h
+++ b/include/link.h
@@ -247,6 +247,8 @@ struct	Prog
 	char	mode;	/* 16, 32, or 64 in 6l, 8l; internal use in 5g, 6g, 8g */
 };
 
+extern Prog zprog; // zeroed Prog
+
 // prevent incompatible type signatures between liblink and 8l on Plan 9
 #pragma incomplete struct Section
 
@@ -600,7 +602,6 @@ struct LinkArch
 	void	(*follow)(Link*, LSym*);
 	int	(*iscall)(Prog*);
 	int	(*isdata)(Prog*);
-	Prog*	(*prg)(void);
 	void	(*progedit)(Link*, Prog*);
 
 	int	minlc;
diff --git a/src/cmd/5g/galign.c b/src/cmd/5g/galign.c
index c2940f3b51..f2cba77eb6 100644
--- a/src/cmd/5g/galign.c
+++ b/src/cmd/5g/galign.c
@@ -36,10 +36,6 @@ betypeinit(void)
 	widthint = 4;
 	widthreg = 4;
 
-	zprog.as = AGOK;
-	zprog.scond = C_SCOND_NONE;
-	arch.zprog = zprog;
-
 	listinit5();
 }
 
@@ -50,7 +46,6 @@ main(int argc, char **argv)
 	arch.thestring = thestring;
 	arch.thelinkarch = thelinkarch;
 	arch.typedefs = typedefs;
-	arch.zprog = zprog;
 	arch.ACALL = ABL;
 	arch.ACHECKNIL = ACHECKNIL;
 	arch.ADATA = ADATA;
diff --git a/src/cmd/5g/gg.h b/src/cmd/5g/gg.h
index 6ee7008574..8a75311d73 100644
--- a/src/cmd/5g/gg.h
+++ b/src/cmd/5g/gg.h
@@ -21,7 +21,6 @@ EXTERN	int32	dynloc;
 EXTERN	uchar	reg[REGALLOC_FMAX+1];
 EXTERN	int32	pcloc;		// instruction counter
 EXTERN	Strlit	emptystring;
-EXTERN	Prog	zprog;
 extern	long	unmappedzero;
 
 /*
diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c
index 66acdedbd5..194d590d2c 100644
--- a/src/cmd/5g/gsubr.c
+++ b/src/cmd/5g/gsubr.c
@@ -1414,7 +1414,7 @@ optoas(int op, Type *t)
 	if(t == T)
 		fatal("optoas: t is nil");
 
-	a = AGOK;
+	a = AXXX;
 	switch(CASE(op, simtype[t->etype])) {
 	default:
 		fatal("optoas: no entry %O-%T etype %T simtype %T", op, t, types[t->etype], types[simtype[t->etype]]);
diff --git a/src/cmd/5g/peep.c b/src/cmd/5g/peep.c
index 46c7046ca3..a96d1f93dc 100644
--- a/src/cmd/5g/peep.c
+++ b/src/cmd/5g/peep.c
@@ -1385,7 +1385,6 @@ predicable(Prog *p)
 	case AXXX:
 	case ADATA:
 	case AGLOBL:
-	case AGOK:
 	case AHISTORY:
 	case ANAME:
 	case ASIGNAME:
diff --git a/src/cmd/5l/5.out.h b/src/cmd/5l/5.out.h
index bc31b5e298..2dcb0ec2b7 100644
--- a/src/cmd/5l/5.out.h
+++ b/src/cmd/5l/5.out.h
@@ -253,7 +253,6 @@ enum
 
 	ADATA,
 	AGLOBL,
-	AGOK,
 	AHISTORY,
 	ANAME,
 	ARET,
diff --git a/src/cmd/6g/galign.c b/src/cmd/6g/galign.c
index c81cd7d0f2..fc97d62d9b 100644
--- a/src/cmd/6g/galign.c
+++ b/src/cmd/6g/galign.c
@@ -59,14 +59,6 @@ betypeinit(void)
 		
 	}
 
-	zprog.link = P;
-	zprog.as = AGOK;
-	zprog.from.type = TYPE_NONE;
-	zprog.from.index = TYPE_NONE;
-	zprog.from.scale = 0;
-	zprog.to = zprog.from;
-	arch.zprog = zprog;
-
 	listinit6();
 }
 
@@ -77,7 +69,6 @@ main(int argc, char **argv)
 	arch.thestring = thestring;
 	arch.thelinkarch = thelinkarch;
 	arch.typedefs = typedefs;
-	arch.zprog = zprog;
 	arch.ACALL = ACALL;
 	arch.ACHECKNIL = ACHECKNIL;
 	arch.ADATA = ADATA;
diff --git a/src/cmd/6g/gg.h b/src/cmd/6g/gg.h
index 7a7b824da1..7a09f673ef 100644
--- a/src/cmd/6g/gg.h
+++ b/src/cmd/6g/gg.h
@@ -13,7 +13,6 @@ EXTERN	int32	dynloc;
 EXTERN	uchar	reg[MAXREG];
 EXTERN	int32	pcloc;		// instruction counter
 EXTERN	Strlit	emptystring;
-EXTERN	Prog	zprog;
 EXTERN	Node*	panicdiv;
 extern	vlong	unmappedzero;
 extern	int	addptr;
diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c
index 6c7cc89025..697016c6f3 100644
--- a/src/cmd/6g/gsubr.c
+++ b/src/cmd/6g/gsubr.c
@@ -1329,7 +1329,7 @@ optoas(int op, Type *t)
 	if(t == T)
 		fatal("optoas: t is nil");
 
-	a = AGOK;
+	a = AXXX;
 	switch(CASE(op, simtype[t->etype])) {
 	default:
 		fatal("optoas: no entry %O-%T", op, t);
diff --git a/src/cmd/6l/6.out.h b/src/cmd/6l/6.out.h
index ccefe97ae1..b40c6b994b 100644
--- a/src/cmd/6l/6.out.h
+++ b/src/cmd/6l/6.out.h
@@ -93,7 +93,6 @@ enum
 	ADIVW,
 	AENTER,
 	AGLOBL,
-	AGOK,
 	AHISTORY,
 	AHLT,
 	AIDIVB,
diff --git a/src/cmd/8g/galign.c b/src/cmd/8g/galign.c
index f5a99121d0..0fdf19dfe8 100644
--- a/src/cmd/8g/galign.c
+++ b/src/cmd/8g/galign.c
@@ -36,14 +36,6 @@ betypeinit(void)
 	widthint = 4;
 	widthreg = 4;
 
-	zprog.link = P;
-	zprog.as = AGOK;
-	zprog.from.type = TYPE_NONE;
-	zprog.from.index = TYPE_NONE;
-	zprog.from.scale = 0;
-	zprog.to = zprog.from;
-	arch.zprog = zprog;
-
 	listinit8();
 }
 
@@ -54,7 +46,6 @@ main(int argc, char **argv)
 	arch.thestring = thestring;
 	arch.thelinkarch = thelinkarch;
 	arch.typedefs = typedefs;
-	arch.zprog = zprog;
 	arch.ACALL = ACALL;
 	arch.ACHECKNIL = ACHECKNIL;
 	arch.ADATA = ADATA;
diff --git a/src/cmd/8g/gg.h b/src/cmd/8g/gg.h
index d9cc2e562f..b2b1178a52 100644
--- a/src/cmd/8g/gg.h
+++ b/src/cmd/8g/gg.h
@@ -21,7 +21,6 @@ EXTERN	int32	dynloc;
 EXTERN	uchar	reg[MAXREG];
 EXTERN	int32	pcloc;		// instruction counter
 EXTERN	Strlit	emptystring;
-EXTERN	Prog	zprog;
 EXTERN	Node*	panicdiv;
 extern	uint32	unmappedzero;
 
diff --git a/src/cmd/8g/gsubr.c b/src/cmd/8g/gsubr.c
index 6f3a2c6906..dd75e9f092 100644
--- a/src/cmd/8g/gsubr.c
+++ b/src/cmd/8g/gsubr.c
@@ -271,7 +271,7 @@ optoas(int op, Type *t)
 	if(t == T)
 		fatal("optoas: t is nil");
 
-	a = AGOK;
+	a = AXXX;
 	switch(CASE(op, simtype[t->etype])) {
 	default:
 		fatal("optoas: no entry %O-%T", op, t);
@@ -690,7 +690,7 @@ foptoas(int op, Type *t, int flg)
 {
 	int et, a;
 
-	a = AGOK;
+	a = AXXX;
 	et = simtype[t->etype];
 
 	if(use_sse)
diff --git a/src/cmd/8l/8.out.h b/src/cmd/8l/8.out.h
index f796d05e0e..f88b48259c 100644
--- a/src/cmd/8l/8.out.h
+++ b/src/cmd/8l/8.out.h
@@ -88,7 +88,6 @@ enum
 	ADIVW,
 	AENTER,
 	AGLOBL,
-	AGOK,
 	AHISTORY,
 	AHLT,
 	AIDIVB,
diff --git a/src/cmd/9a/lex.c b/src/cmd/9a/lex.c
index 9b343f0d69..942791247e 100644
--- a/src/cmd/9a/lex.c
+++ b/src/cmd/9a/lex.c
@@ -670,7 +670,7 @@ outcode(int a, Addr *g1, int reg, Addr *g2)
 		reg = g2->scale;
 	}
 
-	p = ctxt->arch->prg();
+	p = emallocz(sizeof(Prog));
 	p->as = a;
 	p->lineno = lineno;
 	if(nosched)
@@ -700,7 +700,7 @@ outgcode(int a, Addr *g1, int reg, Addr *g2, Addr *g3)
 	if(pass == 1)
 		goto out;
 
-	p = ctxt->arch->prg();
+	p = emallocz(sizeof(Prog));
 	p->as = a;
 	p->lineno = lineno;
 	if(nosched)
diff --git a/src/cmd/9g/galign.c b/src/cmd/9g/galign.c
index 5559e03a53..86509dcc50 100644
--- a/src/cmd/9g/galign.c
+++ b/src/cmd/9g/galign.c
@@ -43,9 +43,6 @@ betypeinit(void)
 	widthint = 8;
 	widthreg = 8;
 
-	zprog.as = AGOK;
-	arch.zprog = zprog;
-
 	listinit9();
 }
 
@@ -56,7 +53,6 @@ main(int argc, char **argv)
 	arch.thestring = thestring;
 	arch.thelinkarch = thelinkarch;
 	arch.typedefs = typedefs;
-	arch.zprog = zprog;
 	arch.ACALL = ABL;
 	arch.ACHECKNIL = ACHECKNIL;
 	arch.ADATA = ADATA;
diff --git a/src/cmd/9g/gg.h b/src/cmd/9g/gg.h
index 983a22a270..367a858e86 100644
--- a/src/cmd/9g/gg.h
+++ b/src/cmd/9g/gg.h
@@ -16,7 +16,6 @@ EXTERN	int32	dynloc;
 EXTERN	uchar	reg[NREG+NFREG];
 EXTERN	int32	pcloc;		// instruction counter
 EXTERN	Strlit	emptystring;
-EXTERN	Prog	zprog;
 EXTERN	Node*	panicdiv;
 extern	vlong	unmappedzero;
 
diff --git a/src/cmd/9g/gsubr.c b/src/cmd/9g/gsubr.c
index 5e8e21a9c7..e58f58c704 100644
--- a/src/cmd/9g/gsubr.c
+++ b/src/cmd/9g/gsubr.c
@@ -1302,7 +1302,7 @@ optoas(int op, Type *t)
 	if(t == T)
 		fatal("optoas: t is nil");
 
-	a = AGOK;
+	a = AXXX;
 	switch(CASE(op, simtype[t->etype])) {
 	default:
 		fatal("optoas: no entry for op=%O type=%T", op, t);
diff --git a/src/cmd/9l/9.out.h b/src/cmd/9l/9.out.h
index 66ee8c43cb..a9748b719f 100644
--- a/src/cmd/9l/9.out.h
+++ b/src/cmd/9l/9.out.h
@@ -513,7 +513,6 @@ enum
 	ASYSCALL,
 	ADATA,
 	AGLOBL,
-	AGOK,
 	AHISTORY,
 	ANAME,
 	ANOP,
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index 526cb5d8a0..fe74f3484d 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -1657,7 +1657,6 @@ struct Arch
 	char *thestring;
 	LinkArch *thelinkarch;
 	Typedef *typedefs;
-	Prog zprog;
 	
 	int ACALL;
 	int ACHECKNIL;
diff --git a/src/cmd/gc/popt.c b/src/cmd/gc/popt.c
index fba57ac16c..a86d3dfa15 100644
--- a/src/cmd/gc/popt.c
+++ b/src/cmd/gc/popt.c
@@ -621,7 +621,7 @@ mergetemp(Prog *firstp)
 			arch.proginfo(&info, p);
 			if(p->to.node == v->node && (info.flags & RightWrite) && !(info.flags & RightRead)) {
 				p->as = arch.ANOP;
-				p->to = arch.zprog.to;
+				p->to = zprog.to;
 				v->removed = 1;
 				if(Debug)
 					print("drop write-only %S\n", v->node->sym);
diff --git a/src/liblink/asm5.c b/src/liblink/asm5.c
index eee6093cfc..9ae041eeb8 100644
--- a/src/liblink/asm5.c
+++ b/src/liblink/asm5.c
@@ -351,11 +351,6 @@ static uint32	opbra(Link*, int, int);
 static	Oprang	oprange[ALAST];
 static	uchar	xcmp[C_GOK+1][C_GOK+1];
 
-static Prog zprg = {
-	.as = AGOK,
-	.scond = C_SCOND_NONE,
-};
-
 static LSym *deferreturn;
 
 static void
@@ -515,7 +510,7 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
 			// split it into two instructions:
 			// 	ADD $-100004, R13
 			// 	MOVW R14, 0(R13)
-			q = ctxt->arch->prg();
+			q = emallocz(sizeof(Prog));
 			p->scond &= ~C_WBIT;
 			*q = *p;
 			a = &p->to;
@@ -534,12 +529,12 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
 			p->from = *a;
 			p->from.reg = 0;
 			p->from.type = TYPE_CONST;
-			p->to = zprg.to;
+			p->to = zprog.to;
 			p->to.type = TYPE_REG;
 			p->to.reg = REG_R13;
 			// make q into p but load/store from 0(R13)
 			q->spadj = 0;
-			*a2 = zprg.from;
+			*a2 = zprog.from;
 			a2->type = TYPE_MEM;
 			a2->reg = REG_R13;
 			a2->sym = nil;
@@ -578,7 +573,7 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
 				// This won't handle .W/.P, so we should reject such code.
 				if(p->scond & (C_PBIT|C_WBIT))
 					ctxt->diag("unsupported instruction (.P/.W): %P", p);
-				q = ctxt->arch->prg();
+				q = emallocz(sizeof(Prog));
 				*q = *p;
 				if(p->to.type == TYPE_MEM)
 					a2 = &q->to;
@@ -594,11 +589,11 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
 				p->as = AMOVW;
 				p->from = *a;
 				p->from.type = TYPE_CONST;
-				p->to = zprg.to;
+				p->to = zprog.to;
 				p->to.type = TYPE_REG;
 				p->to.reg = REG_R11;
 				// make q into p but load/store from 0(R11)
-				*a2 = zprg.from;
+				*a2 = zprog.from;
 				a2->type = TYPE_MEM;
 				a2->reg = REG_R11;
 				a2->sym = nil;
@@ -731,14 +726,14 @@ span5(Link *ctxt, LSym *cursym)
 				if(otxt < 0)
 					otxt = -otxt;
 				if(otxt >= (1L<<17) - 10) {
-					q = ctxt->arch->prg();
+					q = emallocz(sizeof(Prog));
 					q->link = p->link;
 					p->link = q;
 					q->as = AB;
 					q->to.type = TYPE_BRANCH;
 					q->pcond = p->pcond;
 					p->pcond = q;
-					q = ctxt->arch->prg();
+					q = emallocz(sizeof(Prog));
 					q->link = p->link;
 					p->link = q;
 					q->as = AB;
@@ -856,7 +851,7 @@ flushpool(Link *ctxt, Prog *p, int skip, int force)
 	if(ctxt->blitrl) {
 		if(skip){
 			if(0 && skip==1)print("note: flush literal pool at %llux: len=%ud ref=%ux\n", p->pc+4, pool.size, pool.start);
-			q = ctxt->arch->prg();
+			q = emallocz(sizeof(Prog));
 			q->as = AB;
 			q->to.type = TYPE_BRANCH;
 			q->pcond = p->link;
@@ -868,7 +863,7 @@ flushpool(Link *ctxt, Prog *p, int skip, int force)
 			return 0;
 		if(ctxt->headtype == Hnacl && pool.size % 16 != 0) {
 			// if pool is not multiple of 16 bytes, add an alignment marker
-			q = ctxt->arch->prg();
+			q = emallocz(sizeof(Prog));
 			q->as = ADATABUNDLEEND;
 			ctxt->elitrl->link = q;
 			ctxt->elitrl = q;
@@ -900,7 +895,7 @@ addpool(Link *ctxt, Prog *p, Addr *a)
 
 	c = aclass(ctxt, a);
 
-	t = zprg;
+	t = zprog;
 	t.as = AWORD;
 
 	switch(c) {
@@ -939,8 +934,8 @@ addpool(Link *ctxt, Prog *p, Addr *a)
 
 	if(ctxt->headtype == Hnacl && pool.size%16 == 0) {
 		// start a new data bundle
-		q = ctxt->arch->prg();
-		*q = zprg;
+		q = emallocz(sizeof(Prog));
+		*q = zprog;
 		q->as = ADATABUNDLE;
 		q->pc = pool.size;
 		pool.size += 4;
@@ -953,7 +948,7 @@ addpool(Link *ctxt, Prog *p, Addr *a)
 		ctxt->elitrl = q;
 	}
 
-	q = ctxt->arch->prg();
+	q = emallocz(sizeof(Prog));
 	*q = t;
 	q->pc = pool.size;
 
diff --git a/src/liblink/asm6.c b/src/liblink/asm6.c
index 71d24821e0..b3a19dc9fb 100644
--- a/src/liblink/asm6.c
+++ b/src/liblink/asm6.c
@@ -990,7 +990,6 @@ static Optab optab[] =
 	{ AFXRSTOR64,	ysvrs,	Pw, {0x0f,0xae,(01),0x0f,0xae,(01)} },
 	{ AFXSAVE64,	ysvrs,	Pw, {0x0f,0xae,(00),0x0f,0xae,(00)} },
 	{ AGLOBL },
-	{ AGOK },
 	{ AHISTORY },
 	{ AHLT,		ynone,	Px, {0xf4} },
 	{ AIDIVB,	ydivb,	Pb, {0xf6,(07)} },
diff --git a/src/liblink/asm8.c b/src/liblink/asm8.c
index e8508eb07a..c982ca98b7 100644
--- a/src/liblink/asm8.c
+++ b/src/liblink/asm8.c
@@ -675,7 +675,6 @@ static Optab optab[] =
 	{ ADIVW,	ydivl,	Pe, {0xf7,(06)} },
 	{ AENTER },				/* botch */
 	{ AGLOBL },
-	{ AGOK },
 	{ AHISTORY },
 	{ AHLT,		ynone,	Px, {0xf4} },
 	{ AIDIVB,	ydivb,	Pb, {0xf6,(07)} },
diff --git a/src/liblink/asm9.c b/src/liblink/asm9.c
index bc3174d08f..f1c7625747 100644
--- a/src/liblink/asm9.c
+++ b/src/liblink/asm9.c
@@ -535,14 +535,14 @@ span9(Link *ctxt, LSym *cursym)
 			if((o->type == 16 || o->type == 17) && p->pcond) {
 				otxt = p->pcond->pc - c;
 				if(otxt < -(1L<<15)+10 || otxt >= (1L<<15)-10) {
-					q = ctxt->arch->prg();
+					q = emallocz(sizeof(Prog));
 					q->link = p->link;
 					p->link = q;
 					q->as = ABR;
 					q->to.type = TYPE_BRANCH;
 					q->pcond = p->pcond;
 					p->pcond = q;
-					q = ctxt->arch->prg();
+					q = emallocz(sizeof(Prog));
 					q->link = p->link;
 					p->link = q;
 					q->as = ABR;
diff --git a/src/liblink/go.c b/src/liblink/go.c
index 3bc780b852..754a7cc15e 100644
--- a/src/liblink/go.c
+++ b/src/liblink/go.c
@@ -11,6 +11,7 @@
 
 int framepointer_enabled;
 int fieldtrack_enabled;
+Prog zprog;
 
 // Toolchain experiments.
 // These are controlled by the GOEXPERIMENT environment
diff --git a/src/liblink/ld.c b/src/liblink/ld.c
index 6d0fe4a2a4..e055829142 100644
--- a/src/liblink/ld.c
+++ b/src/liblink/ld.c
@@ -217,7 +217,8 @@ copyp(Link *ctxt, Prog *q)
 {
 	Prog *p;
 
-	p = ctxt->arch->prg();
+	USED(ctxt);
+	p = emallocz(sizeof(Prog));
 	*p = *q;
 	return p;
 }
@@ -227,7 +228,8 @@ appendp(Link *ctxt, Prog *q)
 {
 	Prog *p;
 
-	p = ctxt->arch->prg();
+	USED(ctxt);
+	p = emallocz(sizeof(Prog));
 	p->link = q->link;
 	q->link = p;
 	p->lineno = q->lineno;
diff --git a/src/liblink/obj5.c b/src/liblink/obj5.c
index 8d20173912..fd3d4071c5 100644
--- a/src/liblink/obj5.c
+++ b/src/liblink/obj5.c
@@ -35,11 +35,6 @@
 #include "../cmd/5l/5.out.h"
 #include "../runtime/stack.h"
 
-static Prog zprg5 = {
-	.as = AGOK,
-	.scond = C_SCOND_NONE,
-};
-
 static int
 isdata(Prog *p)
 {
@@ -181,16 +176,6 @@ progedit(Link *ctxt, Prog *p)
 	}
 }
 
-static Prog*
-prg(void)
-{
-	Prog *p;
-
-	p = emallocz(sizeof(*p));
-	*p = zprg5;
-	return p;
-}
-
 static	Prog*	stacksplit(Link*, Prog*, int32, int);
 static	void		initdiv(Link*);
 static	void	softfloat(Link*, LSym*);
@@ -515,7 +500,7 @@ preprocess(Link *ctxt, LSym *cursym)
 			if(cursym->text->mark & LEAF) {
 				if(!autosize) {
 					p->as = AB;
-					p->from = zprg5.from;
+					p->from = zprog.from;
 					if(p->to.sym) { // retjmp
 						p->to.type = TYPE_BRANCH;
 					} else {
@@ -731,11 +716,11 @@ softfloat(Link *ctxt, LSym *cursym)
 
 	soft:
 		if (!wasfloat || (p->mark&LABEL)) {
-			next = ctxt->arch->prg();
+			next = emallocz(sizeof(Prog));
 			*next = *p;
 
 			// BL _sfloat(SB)
-			*p = zprg5;
+			*p = zprog;
 			p->link = next;
 			p->as = ABL;
  				p->to.type = TYPE_BRANCH;
@@ -889,7 +874,7 @@ follow(Link *ctxt, LSym *s)
 
 	ctxt->cursym = s;
 
-	firstp = ctxt->arch->prg();
+	firstp = emallocz(sizeof(Prog));
 	lastp = firstp;
 	xfol(ctxt, s->text, &lastp);
 	lastp->link = nil;
@@ -957,7 +942,7 @@ loop:
 				continue;
 		copy:
 			for(;;) {
-				r = ctxt->arch->prg();
+				r = emallocz(sizeof(Prog));
 				*r = *p;
 				if(!(r->mark&FOLL))
 					print("can't happen 1\n");
@@ -985,7 +970,7 @@ loop:
 			}
 		}
 		a = AB;
-		q = ctxt->arch->prg();
+		q = emallocz(sizeof(Prog));
 		q->as = a;
 		q->lineno = p->lineno;
 		q->to.type = TYPE_BRANCH;
@@ -1034,7 +1019,6 @@ LinkArch linkarm = {
 	.follow = follow,
 	.iscall = iscall,
 	.isdata = isdata,
-	.prg = prg,
 	.progedit = progedit,
 
 	.minlc = 4,
diff --git a/src/liblink/obj6.c b/src/liblink/obj6.c
index 15dd9e99a7..c567eeb051 100644
--- a/src/liblink/obj6.c
+++ b/src/liblink/obj6.c
@@ -35,18 +35,6 @@
 #include "../cmd/6l/6.out.h"
 #include "../runtime/stack.h"
 
-static Prog zprg = {
-	.as = AGOK,
-	.from = {
-		.type = TYPE_NONE,
-		.index = TYPE_NONE,
-	},
-	.to = {
-		.type = TYPE_NONE,
-		.index = TYPE_NONE,
-	},
-};
-
 static void
 nopout(Prog *p)
 {
@@ -865,7 +853,7 @@ follow(Link *ctxt, LSym *s)
 
 	ctxt->cursym = s;
 
-	firstp = ctxt->arch->prg();
+	firstp = emallocz(sizeof(Prog));
 	lastp = firstp;
 	xfol(ctxt, s->text, &lastp);
 	lastp->link = nil;
@@ -999,7 +987,7 @@ loop:
 				goto loop;
 			}
 		} /* */
-		q = ctxt->arch->prg();
+		q = emallocz(sizeof(Prog));
 		q->as = AJMP;
 		q->lineno = p->lineno;
 		q->to.type = TYPE_BRANCH;
@@ -1057,16 +1045,6 @@ loop:
 	goto loop;
 }
 
-static Prog*
-prg(void)
-{
-	Prog *p;
-
-	p = emallocz(sizeof(*p));
-	*p = zprg;
-	return p;
-}
-
 LinkArch linkamd64 = {
 	.name = "amd64",
 	.thechar = '6',
@@ -1078,7 +1056,6 @@ LinkArch linkamd64 = {
 	.follow = follow,
 	.iscall = iscall,
 	.isdata = isdata,
-	.prg = prg,
 	.progedit = progedit,
 
 	.minlc = 1,
@@ -1110,7 +1087,6 @@ LinkArch linkamd64p32 = {
 	.follow = follow,
 	.iscall = iscall,
 	.isdata = isdata,
-	.prg = prg,
 	.progedit = progedit,
 
 	.minlc = 1,
diff --git a/src/liblink/obj8.c b/src/liblink/obj8.c
index 37ef8a490e..7ce21ec6cd 100644
--- a/src/liblink/obj8.c
+++ b/src/liblink/obj8.c
@@ -35,18 +35,6 @@
 #include "../cmd/8l/8.out.h"
 #include "../runtime/stack.h"
 
-static Prog zprg = {
-	.as = AGOK,
-	.from = {
-		.type = TYPE_NONE,
-		.index = REG_NONE,
-	},
-	.to = {
-		.type = TYPE_NONE,
-		.index = REG_NONE,
-	},
-};
-
 static int
 isdata(Prog *p)
 {
@@ -244,16 +232,6 @@ progedit(Link *ctxt, Prog *p)
 	}
 }
 
-static Prog*
-prg(void)
-{
-	Prog *p;
-
-	p = emallocz(sizeof(*p));
-	*p = zprg;
-	return p;
-}
-
 static Prog*	load_g_cx(Link*, Prog*);
 static Prog*	stacksplit(Link*, Prog*, int32, int, Prog**);
 
@@ -681,7 +659,7 @@ follow(Link *ctxt, LSym *s)
 
 	ctxt->cursym = s;
 
-	firstp = ctxt->arch->prg();
+	firstp = emallocz(sizeof(Prog));
 	lastp = firstp;
 	xfol(ctxt, s->text, &lastp);
 	lastp->link = nil;
@@ -808,7 +786,7 @@ loop:
 				goto loop;
 			}
 		} /* */
-		q = ctxt->arch->prg();
+		q = emallocz(sizeof(Prog));
 		q->as = AJMP;
 		q->lineno = p->lineno;
 		q->to.type = TYPE_BRANCH;
@@ -877,7 +855,6 @@ LinkArch link386 = {
 	.follow = follow,
 	.iscall = iscall,
 	.isdata = isdata,
-	.prg = prg,
 	.progedit = progedit,
 
 	.minlc = 1,
diff --git a/src/liblink/obj9.c b/src/liblink/obj9.c
index 60fa1d66e1..f1de223172 100644
--- a/src/liblink/obj9.c
+++ b/src/liblink/obj9.c
@@ -35,10 +35,6 @@
 #include "../runtime/stack.h"
 #include "../runtime/funcdata.h"
 
-static Prog zprg = {
-	.as = AGOK,
-};
-
 static int
 isdata(Prog *p)
 {
@@ -512,7 +508,7 @@ preprocess(Link *ctxt, LSym *cursym)
 			if(cursym->text->mark & LEAF) {
 				if(!autosize) {
 					p->as = ABR;
-					p->from = zprg.from;
+					p->from = zprog.from;
 					p->to.type = TYPE_REG;
 					p->to.reg = REG_LR;
 					p->mark |= BRANCH;
@@ -526,7 +522,7 @@ preprocess(Link *ctxt, LSym *cursym)
 				p->to.reg = REGSP;
 				p->spadj = -autosize;
 
-				q = ctxt->arch->prg();
+				q = emallocz(sizeof(Prog));
 				q->as = ABR;
 				q->lineno = p->lineno;
 				q->to.type = TYPE_REG;
@@ -546,7 +542,7 @@ preprocess(Link *ctxt, LSym *cursym)
 			p->to.type = TYPE_REG;
 			p->to.reg = REGTMP;
 
-			q = ctxt->arch->prg();
+			q = emallocz(sizeof(Prog));
 			q->as = AMOVD;
 			q->lineno = p->lineno;
 			q->from.type = TYPE_REG;
@@ -560,7 +556,7 @@ preprocess(Link *ctxt, LSym *cursym)
 
 			if(0) {
 				// Debug bad returns
-				q = ctxt->arch->prg();
+				q = emallocz(sizeof(Prog));
 				q->as = AMOVD;
 				q->lineno = p->lineno;
 				q->from.type = TYPE_MEM;
@@ -575,7 +571,7 @@ preprocess(Link *ctxt, LSym *cursym)
 			}
 
 			if(autosize) {
-				q = ctxt->arch->prg();
+				q = emallocz(sizeof(Prog));
 				q->as = AADD;
 				q->lineno = p->lineno;
 				q->from.type = TYPE_CONST;
@@ -588,7 +584,7 @@ preprocess(Link *ctxt, LSym *cursym)
 				p->link = q;
 			}
 
-			q1 = ctxt->arch->prg();
+			q1 = emallocz(sizeof(Prog));
 			q1->as = ABR;
 			q1->lineno = p->lineno;
 			q1->to.type = TYPE_REG;
@@ -802,7 +798,7 @@ follow(Link *ctxt, LSym *s)
 
 	ctxt->cursym = s;
 
-	firstp = ctxt->arch->prg();
+	firstp = emallocz(sizeof(Prog));
 	lastp = firstp;
 	xfol(ctxt, s->text, &lastp);
 	lastp->link = nil;
@@ -878,7 +874,7 @@ loop:
 				continue;
 		copy:
 			for(;;) {
-				r = ctxt->arch->prg();
+				r = emallocz(sizeof(Prog));
 				*r = *p;
 				if(!(r->mark&FOLL))
 					print("cant happen 1\n");
@@ -905,7 +901,7 @@ loop:
 		}
 
 		a = ABR;
-		q = ctxt->arch->prg();
+		q = emallocz(sizeof(Prog));
 		q->as = a;
 		q->lineno = p->lineno;
 		q->to.type = TYPE_BRANCH;
@@ -935,16 +931,6 @@ loop:
 	goto loop;
 }
 
-static Prog*
-prg(void)
-{
-	Prog *p;
-
-	p = emallocz(sizeof(*p));
-	*p = zprg;
-	return p;
-}
-
 LinkArch linkppc64 = {
 	.name = "ppc64",
 	.thechar = '9',
@@ -956,7 +942,6 @@ LinkArch linkppc64 = {
 	.follow = follow,
 	.iscall = iscall,
 	.isdata = isdata,
-	.prg = prg,
 	.progedit = progedit,
 
 	.minlc = 4,
@@ -988,7 +973,6 @@ LinkArch linkppc64le = {
 	.follow = follow,
 	.iscall = iscall,
 	.isdata = isdata,
-	.prg = prg,
 	.progedit = progedit,
 
 	.minlc = 4,
-- 
2.30.9