Commit 8e0e09ae authored by Russ Cox's avatar Russ Cox

liblink: remove some gotos + other fixes

Rewrite gotos that violate Go's stricter rules.
Use uchar* instead of char* in a few places that aren't strings.
Remove dead opcross code from asm5.c.
Declare regstr (in both list6 and list8) static.

LGTM=minux, dave
R=minux, dave
CC=golang-codereviews
https://golang.org/cl/113230043
parent 34655223
......@@ -105,8 +105,8 @@ struct Prog
int32 spadj;
uchar mark;
uchar back; // 6l, 8l
char ft; /* 6l, 8l oclass cache */
char tt; // 6l, 8l
uchar ft; /* 6l, 8l oclass cache */
uchar tt; // 6l, 8l
uchar optab; // 5l
uchar isize; // 6l, 8l
......
......@@ -394,10 +394,8 @@ static int32 immrot(uint32);
static int32 immaddr(int32);
static int32 opbra(Link*, int, int);
static Opcross opcross[8];
static Oprang oprange[ALAST];
static char xcmp[C_GOK+1][C_GOK+1];
static uchar repop[ALAST];
static uchar xcmp[C_GOK+1][C_GOK+1];
static Prog zprg = {
.as = AGOK,
......@@ -811,8 +809,8 @@ span5(Link *ctxt, LSym *cursym)
if(m % 4 != 0 || p->pc % 4 != 0) {
ctxt->diag("pc invalid: %P size=%d", p, m);
}
if(m > sizeof(out))
ctxt->diag("instruction size too large: %d > %d", m, sizeof(out));
if(m/4 > nelem(out))
ctxt->diag("instruction size too large: %d > %d", m/4, nelem(out));
if(m == 0 && (p->as != AFUNCDATA && p->as != APCDATA && p->as != ADATABUNDLEEND)) {
if(p->as == ATEXT) {
ctxt->autosize = p->to.offset + 4;
......@@ -1068,6 +1066,8 @@ immhalf(int32 v)
return 0;
}
static int aconsize(Link *ctxt);
static int
aclass(Link *ctxt, Addr *a)
{
......@@ -1179,7 +1179,7 @@ aclass(Link *ctxt, Addr *a)
case D_NONE:
ctxt->instoffset = a->offset;
if(a->reg != NREG)
goto aconsize;
return aconsize(ctxt);
t = immrot(ctxt->instoffset);
if(t)
......@@ -1199,15 +1199,11 @@ aclass(Link *ctxt, Addr *a)
case D_AUTO:
ctxt->instoffset = ctxt->autosize + a->offset;
goto aconsize;
return aconsize(ctxt);
case D_PARAM:
ctxt->instoffset = ctxt->autosize + a->offset + 4L;
aconsize:
t = immrot(ctxt->instoffset);
if(t)
return C_RACON;
return C_LACON;
return aconsize(ctxt);
}
return C_GOK;
......@@ -1217,6 +1213,17 @@ aclass(Link *ctxt, Addr *a)
return C_GOK;
}
static int
aconsize(Link *ctxt)
{
int t;
t = immrot(ctxt->instoffset);
if(t)
return C_RACON;
return C_LACON;
}
static void
prasm(Prog *p)
{
......@@ -1227,7 +1234,7 @@ static Optab*
oplook(Link *ctxt, Prog *p)
{
int a1, a2, a3, r;
char *c1, *c3;
uchar *c1, *c3;
Optab *o, *e;
a1 = p->optab;
......@@ -1251,11 +1258,6 @@ oplook(Link *ctxt, Prog *p)
r = p->as;
o = oprange[r].start;
if(o == 0) {
a1 = opcross[repop[r]][a1][a2][a3];
if(a1) {
p->optab = a1+1;
return optab+a1;
}
o = oprange[r].stop; /* just generate an error */
}
if(0 /*debug['O']*/) {
......@@ -1527,6 +1529,8 @@ buildop(Link *ctxt)
}
}
static int32 mov(Link*, Prog*);
static void
asmout(Link *ctxt, Prog *p, Optab *o, int32 *out)
{
......@@ -1584,19 +1588,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
break;
case 3: /* add R<<[IR],[R],R */
mov:
aclass(ctxt, &p->from);
o1 = oprrr(ctxt, p->as, p->scond);
o1 |= p->from.offset;
rt = p->to.reg;
r = p->reg;
if(p->to.type == D_NONE)
rt = 0;
if(p->as == AMOVW || p->as == AMVN)
r = 0;
else if(r == NREG)
r = rt;
o1 |= (r<<16) | (rt<<12);
o1 = mov(ctxt, p);
break;
case 4: /* add $I,[R],R */
......@@ -1869,19 +1861,23 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o1 |= p->from.reg << 0;
break;
case 38: /* movm $con,oreg -> stm */
o1 = (0x4 << 25);
o1 |= p->from.offset & 0xffff;
o1 |= p->to.reg << 16;
aclass(ctxt, &p->to);
goto movm;
case 39: /* movm oreg,$con -> ldm */
o1 = (0x4 << 25) | (1 << 20);
o1 |= p->to.offset & 0xffff;
o1 |= p->from.reg << 16;
aclass(ctxt, &p->from);
movm:
case 38:
case 39:
switch(o->type) {
case 38: /* movm $con,oreg -> stm */
o1 = (0x4 << 25);
o1 |= p->from.offset & 0xffff;
o1 |= p->to.reg << 16;
aclass(ctxt, &p->to);
break;
case 39: /* movm oreg,$con -> ldm */
o1 = (0x4 << 25) | (1 << 20);
o1 |= p->to.offset & 0xffff;
o1 |= p->from.reg << 16;
aclass(ctxt, &p->from);
break;
}
if(ctxt->instoffset != 0)
ctxt->diag("offset must be zero in MOVM; %P", p);
o1 |= (p->scond & C_SCOND) << 28;
......@@ -1989,7 +1985,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(p->from.reg == NREG) {
if(p->as != AMOVW)
ctxt->diag("byte MOV from shifter operand");
goto mov;
o1 = mov(ctxt, p);
break;
}
if(p->from.offset&(1<<4))
ctxt->diag("bad shift in LDR");
......@@ -2001,7 +1998,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 60: /* movb R(R),R -> ldrsb indexed */
if(p->from.reg == NREG) {
ctxt->diag("byte MOV from shifter operand");
goto mov;
o1 = mov(ctxt, p);
break;
}
if(p->from.offset&(~0xf))
ctxt->diag("bad shift in LDRSB");
......@@ -2358,6 +2356,27 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
return;
}
static int32
mov(Link *ctxt, Prog *p)
{
int32 o1;
int rt, r;
aclass(ctxt, &p->from);
o1 = oprrr(ctxt, p->as, p->scond);
o1 |= p->from.offset;
rt = p->to.reg;
r = p->reg;
if(p->to.type == D_NONE)
rt = 0;
if(p->as == AMOVW || p->as == AMVN)
r = 0;
else if(r == NREG)
r = rt;
o1 |= (r<<16) | (rt<<12);
return o1;
}
static int32
oprrr(Link *ctxt, int a, int sc)
{
......
......@@ -60,8 +60,6 @@ enum
FuncAlign = 16
};
extern char *anames6[];
typedef struct Optab Optab;
typedef struct Movtab Movtab;
......@@ -187,7 +185,7 @@ enum
Maxand = 10, /* in -a output width of the byte codes */
};
static char ycover[Ymax*Ymax];
static uchar ycover[Ymax*Ymax];
static int reg[D_NONE];
static int regrex[D_NONE+1];
static void asmins(Link *ctxt, Prog *p);
......@@ -2484,7 +2482,7 @@ asmando(Link *ctxt, Addr *a, int o)
}
static void
bytereg(Addr *a, char *t)
bytereg(Addr *a, uint8 *t)
{
if(a->index == D_NONE && (a->type >= D_AX && a->type <= D_R15)) {
a->type = D_AL + (a->type-D_AX);
......@@ -2688,7 +2686,7 @@ mediaop(Link *ctxt, Optab *o, int op, int osize, int z)
break;
}
default:
if(ctxt->andptr == ctxt->and || ctxt->andptr[-1] != Pm)
if(ctxt->andptr == ctxt->and || ctxt->and[ctxt->andptr - ctxt->and - 1] != Pm)
*ctxt->andptr++ = Pm;
break;
}
......@@ -2904,8 +2902,13 @@ found:
asmando(ctxt, &p->to, o->op[z+1]);
break;
case Zcallindreg:
r = addrel(ctxt->cursym);
r->off = p->pc;
r->type = R_CALLIND;
r->siz = 0;
// fallthrough
case Zo_m64:
case_Zo_m64:
*ctxt->andptr++ = op;
asmandsz(ctxt, &p->to, o->op[z+1], 0, 1);
break;
......@@ -3082,13 +3085,6 @@ found:
put4(ctxt, 0);
break;
case Zcallindreg:
r = addrel(ctxt->cursym);
r->off = p->pc;
r->type = R_CALLIND;
r->siz = 0;
goto case_Zo_m64;
case Zbr:
case Zjmp:
case Zloop:
......@@ -3450,7 +3446,7 @@ nacltrunc(Link *ctxt, int reg)
static void
asmins(Link *ctxt, Prog *p)
{
int n, np, c;
int i, n, np, c;
uchar *and0;
Reloc *r;
......@@ -3575,7 +3571,8 @@ asmins(Link *ctxt, Prog *p)
ctxt->andptr++;
}
n = ctxt->andptr - ctxt->and;
for(r=ctxt->cursym->r+ctxt->cursym->nr; r-- > ctxt->cursym->r; ) {
for(i=ctxt->cursym->nr-1; i>=0; i--) {
r = ctxt->cursym->r+i;
if(r->off < p->pc)
break;
if(ctxt->rexflag)
......
......@@ -43,8 +43,6 @@ enum
FuncAlign = 16
};
extern char *anames6[];
typedef struct Optab Optab;
struct Optab
......@@ -142,7 +140,7 @@ enum
};
static uchar ycover[Ymax*Ymax];
static char reg[D_NONE];
static int reg[D_NONE];
static void asmins(Link *ctxt, Prog *p);
static uchar ynone[] =
......@@ -1902,7 +1900,11 @@ bad:
return;
}
#define E 0xff
enum
{
E = 0xff,
};
static uchar ymovtab[] =
{
/* push */
......@@ -2134,7 +2136,7 @@ mediaop(Link *ctxt, Optab *o, int op, int osize, int z)
break;
}
default:
if(ctxt->andptr == ctxt->and || ctxt->andptr[-1] != Pm)
if(ctxt->andptr == ctxt->and || ctxt->and[ctxt->andptr - ctxt->and - 1] != Pm)
*ctxt->andptr++ = Pm;
break;
}
......@@ -2289,8 +2291,13 @@ found:
*ctxt->andptr++ = p->from.offset;
break;
case Zcallindreg:
r = addrel(ctxt->cursym);
r->off = p->pc;
r->type = R_CALLIND;
r->siz = 0;
// fallthrough
case Zo_m:
case_Zo_m:
*ctxt->andptr++ = op;
asmand(ctxt, &p->to, o->op[z+1]);
break;
......@@ -2511,13 +2518,6 @@ found:
put4(ctxt, 0);
break;
case Zcallindreg:
r = addrel(ctxt->cursym);
r->off = p->pc;
r->type = R_CALLIND;
r->siz = 0;
goto case_Zo_m;
case Zbyte:
v = vaddr(ctxt, &p->from, &rel);
if(rel.siz != 0) {
......
......@@ -217,7 +217,7 @@ conv:
return fmtstrcpy(fp, str);
}
char* regstr[] =
static char* regstr[] =
{
"AL", /* [D_AL] */
"CL",
......
......@@ -211,7 +211,7 @@ conv:
return fmtstrcpy(fp, str);
}
char* regstr[] =
static char* regstr[] =
{
"AL", /* [D_AL] */
"CL",
......
......@@ -707,28 +707,28 @@ softfloat(Link *ctxt, LSym *cursym)
default:
goto notsoft;
}
soft:
if (!wasfloat || (p->mark&LABEL)) {
next = ctxt->arch->prg();
*next = *p;
soft:
if (!wasfloat || (p->mark&LABEL)) {
next = ctxt->arch->prg();
*next = *p;
// BL _sfloat(SB)
*p = zprg;
p->link = next;
p->as = ABL;
// BL _sfloat(SB)
*p = zprg;
p->link = next;
p->as = ABL;
p->to.type = D_BRANCH;
p->to.sym = symsfloat;
p->lineno = next->lineno;
p = next;
wasfloat = 1;
}
break;
p->to.sym = symsfloat;
p->lineno = next->lineno;
notsoft:
wasfloat = 0;
p = next;
wasfloat = 1;
}
continue;
notsoft:
wasfloat = 0;
}
}
......
......@@ -194,19 +194,14 @@ LSym*
linknewsym(Link *ctxt, char *symb, int v)
{
LSym *s;
int l;
l = strlen(symb) + 1;
s = malloc(sizeof(*s));
memset(s, 0, sizeof(*s));
s->dynid = -1;
s->plt = -1;
s->got = -1;
s->name = malloc(l + 1);
memmove(s->name, symb, l);
s->name[l] = '\0';
s->name = estrdup(symb);
s->type = 0;
s->version = v;
s->value = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment