Commit 837c204a authored by Russ Cox's avatar Russ Cox

6l, 8l: avoid recursion in asmandsz

The old code said

	if(x) {
		handle a
		return
	}
	aa = *a
	rewrite aa to make x true
	recursivecall(&aa)

The new code says

	params = copy out of a
	if(!x) {
		rewrite params to make x true
	}
	handle params

but it's hard to see that in the Rietveld diffs because
it gets confused by changes in indentation.

Avoiding the recursion makes other changes easier.

R=ken2
CC=golang-dev
https://golang.org/cl/2533041
parent be2c2120
...@@ -531,11 +531,11 @@ oclass(Adr *a) ...@@ -531,11 +531,11 @@ oclass(Adr *a)
} }
void void
asmidx(Adr *a, int base) asmidx(int scale, int index, int base)
{ {
int i; int i;
switch(a->index) { switch(index) {
default: default:
goto bad; goto bad;
...@@ -560,10 +560,10 @@ asmidx(Adr *a, int base) ...@@ -560,10 +560,10 @@ asmidx(Adr *a, int base)
case D_BP: case D_BP:
case D_SI: case D_SI:
case D_DI: case D_DI:
i = reg[(int)a->index] << 3; i = reg[index] << 3;
break; break;
} }
switch(a->scale) { switch(scale) {
default: default:
goto bad; goto bad;
case 1: case 1:
...@@ -609,7 +609,7 @@ bas: ...@@ -609,7 +609,7 @@ bas:
*andptr++ = i; *andptr++ = i;
return; return;
bad: bad:
diag("asmidx: bad address %D", a); diag("asmidx: bad address %d/%d/%d", scale, index, base);
*andptr++ = 0; *andptr++ = 0;
return; return;
} }
...@@ -689,54 +689,49 @@ static void ...@@ -689,54 +689,49 @@ static void
asmandsz(Adr *a, int r, int rex, int m64) asmandsz(Adr *a, int r, int rex, int m64)
{ {
int32 v; int32 v;
int t; int t, scale;
Adr aa;
rex &= (0x40 | Rxr); rex &= (0x40 | Rxr);
v = a->offset; v = a->offset;
t = a->type; t = a->type;
if(a->index != D_NONE) { if(a->index != D_NONE) {
if(t >= D_INDIR) { if(t < D_INDIR) {
t -= D_INDIR; switch(t) {
rexflag |= (regrex[(int)a->index] & Rxx) | (regrex[t] & Rxb) | rex; default:
if(t == D_NONE) { goto bad;
*andptr++ = (0 << 6) | (4 << 0) | (r << 3); case D_STATIC:
asmidx(a, t); case D_EXTERN:
put4(v); t = D_NONE;
return; v = vaddr(a);
} break;
if(v == 0 && t != D_BP && t != D_R13) { case D_AUTO:
*andptr++ = (0 << 6) | (4 << 0) | (r << 3); case D_PARAM:
asmidx(a, t); t = D_SP;
return; break;
}
if(v >= -128 && v < 128) {
*andptr++ = (1 << 6) | (4 << 0) | (r << 3);
asmidx(a, t);
*andptr++ = v;
return;
} }
*andptr++ = (2 << 6) | (4 << 0) | (r << 3); } else
asmidx(a, t); t -= D_INDIR;
rexflag |= (regrex[(int)a->index] & Rxx) | (regrex[t] & Rxb) | rex;
if(t == D_NONE) {
*andptr++ = (0 << 6) | (4 << 0) | (r << 3);
asmidx(a->scale, a->index, t);
put4(v); put4(v);
return; return;
} }
switch(t) { if(v == 0 && t != D_BP && t != D_R13) {
default: *andptr++ = (0 << 6) | (4 << 0) | (r << 3);
goto bad; asmidx(a->scale, a->index, t);
case D_STATIC: return;
case D_EXTERN: }
aa.type = D_NONE+D_INDIR; if(v >= -128 && v < 128) {
break; *andptr++ = (1 << 6) | (4 << 0) | (r << 3);
case D_AUTO: asmidx(a->scale, a->index, t);
case D_PARAM: *andptr++ = v;
aa.type = D_SP+D_INDIR; return;
break;
} }
aa.offset = vaddr(a); *andptr++ = (2 << 6) | (4 << 0) | (r << 3);
aa.index = a->index; asmidx(a->scale, a->index, t);
aa.scale = a->scale; put4(v);
asmandsz(&aa, r, rex, m64);
return; return;
} }
if(t >= D_AL && t <= D_X0+15) { if(t >= D_AL && t <= D_X0+15) {
...@@ -746,72 +741,72 @@ asmandsz(Adr *a, int r, int rex, int m64) ...@@ -746,72 +741,72 @@ asmandsz(Adr *a, int r, int rex, int m64)
rexflag |= (regrex[t] & (0x40 | Rxb)) | rex; rexflag |= (regrex[t] & (0x40 | Rxb)) | rex;
return; return;
} }
if(t >= D_INDIR) {
scale = a->scale;
if(t < D_INDIR) {
switch(a->type) {
default:
goto bad;
case D_STATIC:
case D_EXTERN:
t = D_NONE;
v = vaddr(a);
break;
case D_AUTO:
case D_PARAM:
t = D_SP;
break;
}
scale = 1;
} else
t -= D_INDIR; t -= D_INDIR;
rexflag |= (regrex[t] & Rxb) | rex;
if(t == D_NONE || (D_CS <= t && t <= D_GS)) { rexflag |= (regrex[t] & Rxb) | rex;
if(asmode != 64){ if(t == D_NONE || (D_CS <= t && t <= D_GS)) {
*andptr++ = (0 << 6) | (5 << 0) | (r << 3); if(asmode != 64){
put4(v); *andptr++ = (0 << 6) | (5 << 0) | (r << 3);
return;
}
/* temporary */
*andptr++ = (0 << 6) | (4 << 0) | (r << 3); /* sib present */
*andptr++ = (0 << 6) | (4 << 3) | (5 << 0); /* DS:d32 */
put4(v); put4(v);
return; return;
} }
if(t == D_SP || t == D_R12) { /* temporary */
if(v == 0) { *andptr++ = (0 << 6) | (4 << 0) | (r << 3); /* sib present */
*andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3); *andptr++ = (0 << 6) | (4 << 3) | (5 << 0); /* DS:d32 */
asmidx(a, t); put4(v);
return; return;
} }
if(v >= -128 && v < 128) { if(t == D_SP || t == D_R12) {
*andptr++ = (1 << 6) | (reg[t] << 0) | (r << 3); if(v == 0) {
asmidx(a, t); *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
*andptr++ = v; asmidx(scale, D_NONE, t);
return;
}
*andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
asmidx(a, t);
put4(v);
return; return;
} }
if(t >= D_AX && t <= D_R15) { if(v >= -128 && v < 128) {
if(v == 0 && t != D_BP && t != D_R13) { *andptr++ = (1 << 6) | (reg[t] << 0) | (r << 3);
*andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3); asmidx(scale, D_NONE, t);
return; *andptr++ = v;
}
if(v >= -128 && v < 128) {
andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
andptr[1] = v;
andptr += 2;
return;
}
*andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
put4(v);
return; return;
} }
goto bad; *andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
asmidx(scale, D_NONE, t);
put4(v);
return;
} }
switch(a->type) { if(t >= D_AX && t <= D_R15) {
default: if(v == 0 && t != D_BP && t != D_R13) {
goto bad; *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
case D_STATIC: return;
case D_EXTERN: }
aa.type = D_NONE+D_INDIR; if(v >= -128 && v < 128) {
break; andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
case D_AUTO: andptr[1] = v;
case D_PARAM: andptr += 2;
aa.type = D_SP+D_INDIR; return;
break; }
*andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
put4(v);
return;
} }
aa.index = D_NONE;
aa.scale = 1;
aa.offset = vaddr(a);
asmandsz(&aa, r, rex, m64);
return;
bad: bad:
diag("asmand: bad address %D", a); diag("asmand: bad address %D", a);
return; return;
......
...@@ -405,11 +405,11 @@ oclass(Adr *a) ...@@ -405,11 +405,11 @@ oclass(Adr *a)
} }
void void
asmidx(Adr *a, int base) asmidx(int scale, int index, int base)
{ {
int i; int i;
switch(a->index) { switch(index) {
default: default:
goto bad; goto bad;
...@@ -424,10 +424,10 @@ asmidx(Adr *a, int base) ...@@ -424,10 +424,10 @@ asmidx(Adr *a, int base)
case D_BP: case D_BP:
case D_SI: case D_SI:
case D_DI: case D_DI:
i = reg[a->index] << 3; i = reg[index] << 3;
break; break;
} }
switch(a->scale) { switch(scale) {
default: default:
goto bad; goto bad;
case 1: case 1:
...@@ -463,7 +463,7 @@ bas: ...@@ -463,7 +463,7 @@ bas:
*andptr++ = i; *andptr++ = i;
return; return;
bad: bad:
diag("asmidx: bad address %D", a); diag("asmidx: bad address %d,%d,%d", scale, index, base);
*andptr++ = 0; *andptr++ = 0;
return; return;
} }
...@@ -530,118 +530,114 @@ void ...@@ -530,118 +530,114 @@ void
asmand(Adr *a, int r) asmand(Adr *a, int r)
{ {
int32 v; int32 v;
int t; int t, scale;
Adr aa;
v = a->offset; v = a->offset;
t = a->type; t = a->type;
if(a->index != D_NONE) { if(a->index != D_NONE) {
if(t >= D_INDIR && t < 2*D_INDIR) { if(t < D_INDIR || t >= 2*D_INDIR) {
t -= D_INDIR; switch(t) {
if(t == D_NONE) { default:
*andptr++ = (0 << 6) | (4 << 0) | (r << 3); goto bad;
asmidx(a, t); case D_STATIC:
put4(v); case D_EXTERN:
return; t = D_NONE;
} v = vaddr(a);
if(v == 0 && t != D_BP) { break;
*andptr++ = (0 << 6) | (4 << 0) | (r << 3); case D_AUTO:
asmidx(a, t); case D_PARAM:
return; t = D_SP;
} break;
if(v >= -128 && v < 128) {
*andptr++ = (1 << 6) | (4 << 0) | (r << 3);
asmidx(a, t);
*andptr++ = v;
return;
} }
*andptr++ = (2 << 6) | (4 << 0) | (r << 3); } else
asmidx(a, t); t -= D_INDIR;
if(t == D_NONE) {
*andptr++ = (0 << 6) | (4 << 0) | (r << 3);
asmidx(a->scale, a->index, t);
put4(v); put4(v);
return; return;
} }
switch(t) { if(v == 0 && t != D_BP) {
*andptr++ = (0 << 6) | (4 << 0) | (r << 3);
asmidx(a->scale, a->index, t);
return;
}
if(v >= -128 && v < 128) {
*andptr++ = (1 << 6) | (4 << 0) | (r << 3);
asmidx(a->scale, a->index, t);
*andptr++ = v;
return;
}
*andptr++ = (2 << 6) | (4 << 0) | (r << 3);
asmidx(a->scale, a->index, t);
put4(v);
return;
}
if(t >= D_AL && t <= D_F0+7) {
if(v)
goto bad;
*andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
return;
}
scale = a->scale;
if(t < D_INDIR || t >= 2*D_INDIR) {
switch(a->type) {
default: default:
goto bad; goto bad;
case D_STATIC: case D_STATIC:
case D_EXTERN: case D_EXTERN:
aa.type = D_NONE+D_INDIR; t = D_NONE;
v = vaddr(a);
break; break;
case D_AUTO: case D_AUTO:
case D_PARAM: case D_PARAM:
aa.type = D_SP+D_INDIR; t = D_SP;
break; break;
} }
aa.offset = vaddr(a); scale = 1;
aa.index = a->index; } else
aa.scale = a->scale; t -= D_INDIR;
asmand(&aa, r);
return; if(t == D_NONE || (D_CS <= t && t <= D_GS)) {
} *andptr++ = (0 << 6) | (5 << 0) | (r << 3);
if(t >= D_AL && t <= D_F0+7) { put4(v);
if(v)
goto bad;
*andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
return; return;
} }
if(t >= D_INDIR && t < 2*D_INDIR) { if(t == D_SP) {
t -= D_INDIR; if(v == 0) {
if(t == D_NONE || (D_CS <= t && t <= D_GS)) { *andptr++ = (0 << 6) | (4 << 0) | (r << 3);
*andptr++ = (0 << 6) | (5 << 0) | (r << 3); asmidx(scale, D_NONE, t);
put4(v);
return; return;
} }
if(t == D_SP) { if(v >= -128 && v < 128) {
if(v == 0) { *andptr++ = (1 << 6) | (4 << 0) | (r << 3);
*andptr++ = (0 << 6) | (4 << 0) | (r << 3); asmidx(scale, D_NONE, t);
asmidx(a, D_SP); *andptr++ = v;
return;
}
if(v >= -128 && v < 128) {
*andptr++ = (1 << 6) | (4 << 0) | (r << 3);
asmidx(a, D_SP);
*andptr++ = v;
return;
}
*andptr++ = (2 << 6) | (4 << 0) | (r << 3);
asmidx(a, D_SP);
put4(v);
return; return;
} }
if(t >= D_AX && t <= D_DI) { *andptr++ = (2 << 6) | (4 << 0) | (r << 3);
if(v == 0 && t != D_BP) { asmidx(scale, D_NONE, t);
*andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3); put4(v);
return; return;
} }
if(v >= -128 && v < 128) { if(t >= D_AX && t <= D_DI) {
andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3); if(v == 0 && t != D_BP) {
andptr[1] = v; *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
andptr += 2;
return;
}
*andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
put4(v);
return; return;
} }
goto bad; if(v >= -128 && v < 128) {
} andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
switch(a->type) { andptr[1] = v;
default: andptr += 2;
goto bad; return;
case D_STATIC: }
case D_EXTERN: *andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
aa.type = D_NONE+D_INDIR; put4(v);
break; return;
case D_AUTO:
case D_PARAM:
aa.type = D_SP+D_INDIR;
break;
} }
aa.index = D_NONE;
aa.scale = 1;
aa.offset = vaddr(a);
asmand(&aa, r);
return;
bad: bad:
diag("asmand: bad address %D", a); diag("asmand: bad address %D", a);
return; return;
......
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