mirror of
https://github.com/golang/go
synced 2024-11-18 18:14:43 -07:00
[dev.cc] liblink: arrange for Prog* argument in vaddr
The argument is unused in the C code but will be used in the Go translation, because the Prog holds information needed to invoke the right meaning of %A in the ctxt->diag calls in vaddr. Change-Id: I501830f8ea0e909aafd8ec9ef5d7338e109d9548 Reviewed-on: https://go-review.googlesource.com/3041 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
68b78b8abd
commit
3b2de80309
@ -1533,7 +1533,7 @@ static Optab optab[] =
|
||||
};
|
||||
|
||||
static Optab* opindex[ALAST+1];
|
||||
static vlong vaddr(Link*, Addr*, Reloc*);
|
||||
static vlong vaddr(Link*, Prog*, Addr*, Reloc*);
|
||||
|
||||
// isextern reports whether s describes an external symbol that must avoid pc-relative addressing.
|
||||
// This happens on systems like Solaris that call .so functions instead of system calls.
|
||||
@ -2231,7 +2231,7 @@ relput4(Link *ctxt, Prog *p, Addr *a)
|
||||
vlong v;
|
||||
Reloc rel, *r;
|
||||
|
||||
v = vaddr(ctxt, a, &rel);
|
||||
v = vaddr(ctxt, p, a, &rel);
|
||||
if(rel.siz != 0) {
|
||||
if(rel.siz != 4)
|
||||
ctxt->diag("bad reloc");
|
||||
@ -2263,7 +2263,7 @@ relput8(Prog *p, Addr *a)
|
||||
vlong v;
|
||||
Reloc rel, *r;
|
||||
|
||||
v = vaddr(ctxt, a, &rel);
|
||||
v = vaddr(ctxt, p, a, &rel);
|
||||
if(rel.siz != 0) {
|
||||
r = addrel(ctxt->cursym);
|
||||
*r = rel;
|
||||
@ -2275,12 +2275,14 @@ relput8(Prog *p, Addr *a)
|
||||
*/
|
||||
|
||||
static vlong
|
||||
vaddr(Link *ctxt, Addr *a, Reloc *r)
|
||||
vaddr(Link *ctxt, Prog *p, Addr *a, Reloc *r)
|
||||
{
|
||||
int t;
|
||||
vlong v;
|
||||
LSym *s;
|
||||
|
||||
USED(p);
|
||||
|
||||
if(r != nil)
|
||||
memset(r, 0, sizeof *r);
|
||||
|
||||
@ -2330,13 +2332,15 @@ vaddr(Link *ctxt, Addr *a, Reloc *r)
|
||||
}
|
||||
|
||||
static void
|
||||
asmandsz(Link *ctxt, Addr *a, int r, int rex, int m64)
|
||||
asmandsz(Link *ctxt, Prog *p, Addr *a, int r, int rex, int m64)
|
||||
{
|
||||
int32 v;
|
||||
int t, scale;
|
||||
Reloc rel;
|
||||
|
||||
USED(m64);
|
||||
USED(p);
|
||||
|
||||
rex &= (0x40 | Rxr);
|
||||
v = a->offset;
|
||||
t = a->type;
|
||||
@ -2351,7 +2355,7 @@ asmandsz(Link *ctxt, Addr *a, int r, int rex, int m64)
|
||||
if(!isextern(a->sym))
|
||||
goto bad;
|
||||
t = D_NONE;
|
||||
v = vaddr(ctxt, a, &rel);
|
||||
v = vaddr(ctxt, p, a, &rel);
|
||||
break;
|
||||
case D_AUTO:
|
||||
case D_PARAM:
|
||||
@ -2397,7 +2401,7 @@ asmandsz(Link *ctxt, Addr *a, int r, int rex, int m64)
|
||||
case D_STATIC:
|
||||
case D_EXTERN:
|
||||
t = D_NONE;
|
||||
v = vaddr(ctxt, a, &rel);
|
||||
v = vaddr(ctxt, p, a, &rel);
|
||||
break;
|
||||
case D_AUTO:
|
||||
case D_PARAM:
|
||||
@ -2408,7 +2412,7 @@ asmandsz(Link *ctxt, Addr *a, int r, int rex, int m64)
|
||||
} else
|
||||
t -= D_INDIR;
|
||||
if(t == D_TLS)
|
||||
v = vaddr(ctxt, a, &rel);
|
||||
v = vaddr(ctxt, p, a, &rel);
|
||||
|
||||
ctxt->rexflag |= (regrex[t] & Rxb) | rex;
|
||||
if(t == D_NONE || (D_CS <= t && t <= D_GS) || t == D_TLS) {
|
||||
@ -2483,15 +2487,15 @@ bad:
|
||||
}
|
||||
|
||||
static void
|
||||
asmand(Link *ctxt, Addr *a, Addr *ra)
|
||||
asmand(Link *ctxt, Prog *p, Addr *a, Addr *ra)
|
||||
{
|
||||
asmandsz(ctxt, a, reg[ra->type], regrex[ra->type], 0);
|
||||
asmandsz(ctxt, p, a, reg[ra->type], regrex[ra->type], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
asmando(Link *ctxt, Addr *a, int o)
|
||||
asmando(Link *ctxt, Prog *p, Addr *a, int o)
|
||||
{
|
||||
asmandsz(ctxt, a, o, 0, 0);
|
||||
asmandsz(ctxt, p, a, o, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2825,7 +2829,7 @@ found:
|
||||
case Zlitm_r:
|
||||
for(; op = o->op[z]; z++)
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->from, &p->to);
|
||||
asmand(ctxt, p, &p->from, &p->to);
|
||||
break;
|
||||
|
||||
case Zmb_r:
|
||||
@ -2833,42 +2837,42 @@ found:
|
||||
/* fall through */
|
||||
case Zm_r:
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->from, &p->to);
|
||||
asmand(ctxt, p, &p->from, &p->to);
|
||||
break;
|
||||
case Zm2_r:
|
||||
*ctxt->andptr++ = op;
|
||||
*ctxt->andptr++ = o->op[z+1];
|
||||
asmand(ctxt, &p->from, &p->to);
|
||||
asmand(ctxt, p, &p->from, &p->to);
|
||||
break;
|
||||
|
||||
case Zm_r_xm:
|
||||
mediaop(ctxt, o, op, t[3], z);
|
||||
asmand(ctxt, &p->from, &p->to);
|
||||
asmand(ctxt, p, &p->from, &p->to);
|
||||
break;
|
||||
|
||||
case Zm_r_xm_nr:
|
||||
ctxt->rexflag = 0;
|
||||
mediaop(ctxt, o, op, t[3], z);
|
||||
asmand(ctxt, &p->from, &p->to);
|
||||
asmand(ctxt, p, &p->from, &p->to);
|
||||
break;
|
||||
|
||||
case Zm_r_i_xm:
|
||||
mediaop(ctxt, o, op, t[3], z);
|
||||
asmand(ctxt, &p->from, &p->to);
|
||||
asmand(ctxt, p, &p->from, &p->to);
|
||||
*ctxt->andptr++ = p->to.offset;
|
||||
break;
|
||||
|
||||
case Zm_r_3d:
|
||||
*ctxt->andptr++ = 0x0f;
|
||||
*ctxt->andptr++ = 0x0f;
|
||||
asmand(ctxt, &p->from, &p->to);
|
||||
asmand(ctxt, p, &p->from, &p->to);
|
||||
*ctxt->andptr++ = op;
|
||||
break;
|
||||
|
||||
case Zibm_r:
|
||||
while ((op = o->op[z++]) != 0)
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->from, &p->to);
|
||||
asmand(ctxt, p, &p->from, &p->to);
|
||||
*ctxt->andptr++ = p->to.offset;
|
||||
break;
|
||||
|
||||
@ -2878,41 +2882,41 @@ found:
|
||||
ctxt->diag("asmins: Zaut sb type ADDR");
|
||||
p->from.type = p->from.index;
|
||||
p->from.index = D_NONE;
|
||||
asmand(ctxt, &p->from, &p->to);
|
||||
asmand(ctxt, p, &p->from, &p->to);
|
||||
p->from.index = p->from.type;
|
||||
p->from.type = D_ADDR;
|
||||
break;
|
||||
|
||||
case Zm_o:
|
||||
*ctxt->andptr++ = op;
|
||||
asmando(ctxt, &p->from, o->op[z+1]);
|
||||
asmando(ctxt, p, &p->from, o->op[z+1]);
|
||||
break;
|
||||
|
||||
case Zr_m:
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->to, &p->from);
|
||||
asmand(ctxt, p, &p->to, &p->from);
|
||||
break;
|
||||
|
||||
case Zr_m_xm:
|
||||
mediaop(ctxt, o, op, t[3], z);
|
||||
asmand(ctxt, &p->to, &p->from);
|
||||
asmand(ctxt, p, &p->to, &p->from);
|
||||
break;
|
||||
|
||||
case Zr_m_xm_nr:
|
||||
ctxt->rexflag = 0;
|
||||
mediaop(ctxt, o, op, t[3], z);
|
||||
asmand(ctxt, &p->to, &p->from);
|
||||
asmand(ctxt, p, &p->to, &p->from);
|
||||
break;
|
||||
|
||||
case Zr_m_i_xm:
|
||||
mediaop(ctxt, o, op, t[3], z);
|
||||
asmand(ctxt, &p->to, &p->from);
|
||||
asmand(ctxt, p, &p->to, &p->from);
|
||||
*ctxt->andptr++ = p->from.offset;
|
||||
break;
|
||||
|
||||
case Zo_m:
|
||||
*ctxt->andptr++ = op;
|
||||
asmando(ctxt, &p->to, o->op[z+1]);
|
||||
asmando(ctxt, p, &p->to, o->op[z+1]);
|
||||
break;
|
||||
|
||||
case Zcallindreg:
|
||||
@ -2923,25 +2927,25 @@ found:
|
||||
// fallthrough
|
||||
case Zo_m64:
|
||||
*ctxt->andptr++ = op;
|
||||
asmandsz(ctxt, &p->to, o->op[z+1], 0, 1);
|
||||
asmandsz(ctxt, p, &p->to, o->op[z+1], 0, 1);
|
||||
break;
|
||||
|
||||
case Zm_ibo:
|
||||
*ctxt->andptr++ = op;
|
||||
asmando(ctxt, &p->from, o->op[z+1]);
|
||||
*ctxt->andptr++ = vaddr(ctxt, &p->to, nil);
|
||||
asmando(ctxt, p, &p->from, o->op[z+1]);
|
||||
*ctxt->andptr++ = vaddr(ctxt, p, &p->to, nil);
|
||||
break;
|
||||
|
||||
case Zibo_m:
|
||||
*ctxt->andptr++ = op;
|
||||
asmando(ctxt, &p->to, o->op[z+1]);
|
||||
*ctxt->andptr++ = vaddr(ctxt, &p->from, nil);
|
||||
asmando(ctxt, p, &p->to, o->op[z+1]);
|
||||
*ctxt->andptr++ = vaddr(ctxt, p, &p->from, nil);
|
||||
break;
|
||||
|
||||
case Zibo_m_xm:
|
||||
z = mediaop(ctxt, o, op, t[3], z);
|
||||
asmando(ctxt, &p->to, o->op[z+1]);
|
||||
*ctxt->andptr++ = vaddr(ctxt, &p->from, nil);
|
||||
asmando(ctxt, p, &p->to, o->op[z+1]);
|
||||
*ctxt->andptr++ = vaddr(ctxt, p, &p->from, nil);
|
||||
break;
|
||||
|
||||
case Z_ib:
|
||||
@ -2951,20 +2955,20 @@ found:
|
||||
else
|
||||
a = &p->to;
|
||||
*ctxt->andptr++ = op;
|
||||
*ctxt->andptr++ = vaddr(ctxt, a, nil);
|
||||
*ctxt->andptr++ = vaddr(ctxt, p, a, nil);
|
||||
break;
|
||||
|
||||
case Zib_rp:
|
||||
ctxt->rexflag |= regrex[p->to.type] & (Rxb|0x40);
|
||||
*ctxt->andptr++ = op + reg[p->to.type];
|
||||
*ctxt->andptr++ = vaddr(ctxt, &p->from, nil);
|
||||
*ctxt->andptr++ = vaddr(ctxt, p, &p->from, nil);
|
||||
break;
|
||||
|
||||
case Zil_rp:
|
||||
ctxt->rexflag |= regrex[p->to.type] & Rxb;
|
||||
*ctxt->andptr++ = op + reg[p->to.type];
|
||||
if(o->prefix == Pe) {
|
||||
v = vaddr(ctxt, &p->from, nil);
|
||||
v = vaddr(ctxt, p, &p->from, nil);
|
||||
*ctxt->andptr++ = v;
|
||||
*ctxt->andptr++ = v>>8;
|
||||
}
|
||||
@ -2975,14 +2979,14 @@ found:
|
||||
case Zo_iw:
|
||||
*ctxt->andptr++ = op;
|
||||
if(p->from.type != D_NONE){
|
||||
v = vaddr(ctxt, &p->from, nil);
|
||||
v = vaddr(ctxt, p, &p->from, nil);
|
||||
*ctxt->andptr++ = v;
|
||||
*ctxt->andptr++ = v>>8;
|
||||
}
|
||||
break;
|
||||
|
||||
case Ziq_rp:
|
||||
v = vaddr(ctxt, &p->from, &rel);
|
||||
v = vaddr(ctxt, p, &p->from, &rel);
|
||||
l = v>>32;
|
||||
if(l == 0 && rel.siz != 8){
|
||||
//p->mark |= 0100;
|
||||
@ -3000,7 +3004,7 @@ found:
|
||||
//p->mark |= 0100;
|
||||
//print("sign: %llux %P\n", v, p);
|
||||
*ctxt->andptr ++ = 0xc7;
|
||||
asmando(ctxt, &p->to, 0);
|
||||
asmando(ctxt, p, &p->to, 0);
|
||||
put4(ctxt, v);
|
||||
}else{ /* need all 8 */
|
||||
//print("all: %llux %P\n", v, p);
|
||||
@ -3017,8 +3021,8 @@ found:
|
||||
|
||||
case Zib_rr:
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->to, &p->to);
|
||||
*ctxt->andptr++ = vaddr(ctxt, &p->from, nil);
|
||||
asmand(ctxt, p, &p->to, &p->to);
|
||||
*ctxt->andptr++ = vaddr(ctxt, p, &p->from, nil);
|
||||
break;
|
||||
|
||||
case Z_il:
|
||||
@ -3029,7 +3033,7 @@ found:
|
||||
a = &p->to;
|
||||
*ctxt->andptr++ = op;
|
||||
if(o->prefix == Pe) {
|
||||
v = vaddr(ctxt, a, nil);
|
||||
v = vaddr(ctxt, p, a, nil);
|
||||
*ctxt->andptr++ = v;
|
||||
*ctxt->andptr++ = v>>8;
|
||||
}
|
||||
@ -3042,13 +3046,13 @@ found:
|
||||
*ctxt->andptr++ = op;
|
||||
if(t[2] == Zilo_m) {
|
||||
a = &p->from;
|
||||
asmando(ctxt, &p->to, o->op[z+1]);
|
||||
asmando(ctxt, p, &p->to, o->op[z+1]);
|
||||
} else {
|
||||
a = &p->to;
|
||||
asmando(ctxt, &p->from, o->op[z+1]);
|
||||
asmando(ctxt, p, &p->from, o->op[z+1]);
|
||||
}
|
||||
if(o->prefix == Pe) {
|
||||
v = vaddr(ctxt, a, nil);
|
||||
v = vaddr(ctxt, p, a, nil);
|
||||
*ctxt->andptr++ = v;
|
||||
*ctxt->andptr++ = v>>8;
|
||||
}
|
||||
@ -3058,9 +3062,9 @@ found:
|
||||
|
||||
case Zil_rr:
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->to, &p->to);
|
||||
asmand(ctxt, p, &p->to, &p->to);
|
||||
if(o->prefix == Pe) {
|
||||
v = vaddr(ctxt, &p->from, nil);
|
||||
v = vaddr(ctxt, p, &p->from, nil);
|
||||
*ctxt->andptr++ = v;
|
||||
*ctxt->andptr++ = v>>8;
|
||||
}
|
||||
@ -3081,7 +3085,7 @@ found:
|
||||
case Zclr:
|
||||
ctxt->rexflag &= ~Pw;
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->to, &p->to);
|
||||
asmand(ctxt, p, &p->to, &p->to);
|
||||
break;
|
||||
|
||||
case Zcall:
|
||||
@ -3192,7 +3196,7 @@ found:
|
||||
break;
|
||||
|
||||
case Zbyte:
|
||||
v = vaddr(ctxt, &p->from, &rel);
|
||||
v = vaddr(ctxt, p, &p->from, &rel);
|
||||
if(rel.siz != 0) {
|
||||
rel.siz = op;
|
||||
r = addrel(ctxt->cursym);
|
||||
@ -3241,11 +3245,11 @@ bad:
|
||||
// We certainly don't want to exchange
|
||||
// with AX if the op is MUL or DIV.
|
||||
*ctxt->andptr++ = 0x87; /* xchg lhs,bx */
|
||||
asmando(ctxt, &p->from, reg[D_BX]);
|
||||
asmando(ctxt, p, &p->from, reg[D_BX]);
|
||||
subreg(&pp, z, D_BX);
|
||||
doasm(ctxt, &pp);
|
||||
*ctxt->andptr++ = 0x87; /* xchg lhs,bx */
|
||||
asmando(ctxt, &p->from, reg[D_BX]);
|
||||
asmando(ctxt, p, &p->from, reg[D_BX]);
|
||||
} else {
|
||||
*ctxt->andptr++ = 0x90 + reg[z]; /* xchg lsh,ax */
|
||||
subreg(&pp, z, D_AX);
|
||||
@ -3258,11 +3262,11 @@ bad:
|
||||
if(z >= D_BP && z <= D_DI) {
|
||||
if(isax(&p->from)) {
|
||||
*ctxt->andptr++ = 0x87; /* xchg rhs,bx */
|
||||
asmando(ctxt, &p->to, reg[D_BX]);
|
||||
asmando(ctxt, p, &p->to, reg[D_BX]);
|
||||
subreg(&pp, z, D_BX);
|
||||
doasm(ctxt, &pp);
|
||||
*ctxt->andptr++ = 0x87; /* xchg rhs,bx */
|
||||
asmando(ctxt, &p->to, reg[D_BX]);
|
||||
asmando(ctxt, p, &p->to, reg[D_BX]);
|
||||
} else {
|
||||
*ctxt->andptr++ = 0x90 + reg[z]; /* xchg rsh,ax */
|
||||
subreg(&pp, z, D_AX);
|
||||
@ -3288,25 +3292,25 @@ mfound:
|
||||
|
||||
case 1: /* r,m */
|
||||
*ctxt->andptr++ = t[0];
|
||||
asmando(ctxt, &p->to, t[1]);
|
||||
asmando(ctxt, p, &p->to, t[1]);
|
||||
break;
|
||||
|
||||
case 2: /* m,r */
|
||||
*ctxt->andptr++ = t[0];
|
||||
asmando(ctxt, &p->from, t[1]);
|
||||
asmando(ctxt, p, &p->from, t[1]);
|
||||
break;
|
||||
|
||||
case 3: /* r,m - 2op */
|
||||
*ctxt->andptr++ = t[0];
|
||||
*ctxt->andptr++ = t[1];
|
||||
asmando(ctxt, &p->to, t[2]);
|
||||
asmando(ctxt, p, &p->to, t[2]);
|
||||
ctxt->rexflag |= regrex[p->from.type] & (Rxr|0x40);
|
||||
break;
|
||||
|
||||
case 4: /* m,r - 2op */
|
||||
*ctxt->andptr++ = t[0];
|
||||
*ctxt->andptr++ = t[1];
|
||||
asmando(ctxt, &p->from, t[2]);
|
||||
asmando(ctxt, p, &p->from, t[2]);
|
||||
ctxt->rexflag |= regrex[p->to.type] & (Rxr|0x40);
|
||||
break;
|
||||
|
||||
@ -3335,7 +3339,7 @@ mfound:
|
||||
*ctxt->andptr++ = 0xb5;
|
||||
break;
|
||||
}
|
||||
asmand(ctxt, &p->from, &p->to);
|
||||
asmand(ctxt, p, &p->from, &p->to);
|
||||
break;
|
||||
|
||||
case 6: /* double shift */
|
||||
@ -3355,14 +3359,14 @@ mfound:
|
||||
case D_CONST:
|
||||
*ctxt->andptr++ = 0x0f;
|
||||
*ctxt->andptr++ = t[0];
|
||||
asmandsz(ctxt, &p->to, reg[(int)p->from.index], regrex[(int)p->from.index], 0);
|
||||
asmandsz(ctxt, p, &p->to, reg[(int)p->from.index], regrex[(int)p->from.index], 0);
|
||||
*ctxt->andptr++ = p->from.offset;
|
||||
break;
|
||||
case D_CL:
|
||||
case D_CX:
|
||||
*ctxt->andptr++ = 0x0f;
|
||||
*ctxt->andptr++ = t[1];
|
||||
asmandsz(ctxt, &p->to, reg[(int)p->from.index], regrex[(int)p->from.index], 0);
|
||||
asmandsz(ctxt, p, &p->to, reg[(int)p->from.index], regrex[(int)p->from.index], 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -3386,7 +3390,7 @@ mfound:
|
||||
pp.from.index = D_NONE;
|
||||
ctxt->rexflag |= Pw;
|
||||
*ctxt->andptr++ = 0x8B;
|
||||
asmand(ctxt, &pp.from, &p->to);
|
||||
asmand(ctxt, p, &pp.from, &p->to);
|
||||
break;
|
||||
|
||||
case Hsolaris: // TODO(rsc): Delete Hsolaris from list. Should not use this code. See progedit in obj6.c.
|
||||
@ -3399,7 +3403,7 @@ mfound:
|
||||
ctxt->rexflag |= Pw;
|
||||
*ctxt->andptr++ = 0x64; // FS
|
||||
*ctxt->andptr++ = 0x8B;
|
||||
asmand(ctxt, &pp.from, &p->to);
|
||||
asmand(ctxt, p, &pp.from, &p->to);
|
||||
break;
|
||||
|
||||
case Hwindows:
|
||||
@ -3412,7 +3416,7 @@ mfound:
|
||||
ctxt->rexflag |= Pw;
|
||||
*ctxt->andptr++ = 0x65; // GS
|
||||
*ctxt->andptr++ = 0x8B;
|
||||
asmand(ctxt, &pp.from, &p->to);
|
||||
asmand(ctxt, p, &pp.from, &p->to);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -1169,7 +1169,7 @@ static Optab optab[] =
|
||||
{0}
|
||||
};
|
||||
|
||||
static int32 vaddr(Link*, Addr*, Reloc*);
|
||||
static int32 vaddr(Link*, Prog*, Addr*, Reloc*);
|
||||
|
||||
// single-instruction no-ops of various lengths.
|
||||
// constructed by hand and disassembled with gdb to verify.
|
||||
@ -1711,7 +1711,7 @@ relput4(Link *ctxt, Prog *p, Addr *a)
|
||||
vlong v;
|
||||
Reloc rel, *r;
|
||||
|
||||
v = vaddr(ctxt, a, &rel);
|
||||
v = vaddr(ctxt, p, a, &rel);
|
||||
if(rel.siz != 0) {
|
||||
if(rel.siz != 4)
|
||||
ctxt->diag("bad reloc");
|
||||
@ -1723,12 +1723,14 @@ relput4(Link *ctxt, Prog *p, Addr *a)
|
||||
}
|
||||
|
||||
static int32
|
||||
vaddr(Link *ctxt, Addr *a, Reloc *r)
|
||||
vaddr(Link *ctxt, Prog *p, Addr *a, Reloc *r)
|
||||
{
|
||||
int t;
|
||||
int32 v;
|
||||
LSym *s;
|
||||
|
||||
USED(p);
|
||||
|
||||
if(r != nil)
|
||||
memset(r, 0, sizeof *r);
|
||||
|
||||
@ -1770,11 +1772,13 @@ vaddr(Link *ctxt, Addr *a, Reloc *r)
|
||||
}
|
||||
|
||||
static void
|
||||
asmand(Link *ctxt, Addr *a, int r)
|
||||
asmand(Link *ctxt, Prog *p, Addr *a, int r)
|
||||
{
|
||||
int32 v;
|
||||
int t, scale;
|
||||
Reloc rel;
|
||||
|
||||
USED(p);
|
||||
|
||||
v = a->offset;
|
||||
t = a->type;
|
||||
@ -1787,7 +1791,7 @@ asmand(Link *ctxt, Addr *a, int r)
|
||||
case D_STATIC:
|
||||
case D_EXTERN:
|
||||
t = D_NONE;
|
||||
v = vaddr(ctxt, a, &rel);
|
||||
v = vaddr(ctxt, p, a, &rel);
|
||||
break;
|
||||
case D_AUTO:
|
||||
case D_PARAM:
|
||||
@ -1832,7 +1836,7 @@ asmand(Link *ctxt, Addr *a, int r)
|
||||
case D_STATIC:
|
||||
case D_EXTERN:
|
||||
t = D_NONE;
|
||||
v = vaddr(ctxt, a, &rel);
|
||||
v = vaddr(ctxt, p, a, &rel);
|
||||
break;
|
||||
case D_AUTO:
|
||||
case D_PARAM:
|
||||
@ -1843,7 +1847,7 @@ asmand(Link *ctxt, Addr *a, int r)
|
||||
} else
|
||||
t -= D_INDIR;
|
||||
if(t == D_TLS)
|
||||
v = vaddr(ctxt, a, &rel);
|
||||
v = vaddr(ctxt, p, a, &rel);
|
||||
|
||||
if(t == D_NONE || (D_CS <= t && t <= D_GS) || t == D_TLS) {
|
||||
*ctxt->andptr++ = (0 << 6) | (5 << 0) | (r << 3);
|
||||
@ -2235,35 +2239,35 @@ found:
|
||||
case Zlitm_r:
|
||||
for(; op = o->op[z]; z++)
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->from, reg[p->to.type]);
|
||||
asmand(ctxt, p, &p->from, reg[p->to.type]);
|
||||
break;
|
||||
|
||||
case Zm_r:
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->from, reg[p->to.type]);
|
||||
asmand(ctxt, p, &p->from, reg[p->to.type]);
|
||||
break;
|
||||
|
||||
case Zm2_r:
|
||||
*ctxt->andptr++ = op;
|
||||
*ctxt->andptr++ = o->op[z+1];
|
||||
asmand(ctxt, &p->from, reg[p->to.type]);
|
||||
asmand(ctxt, p, &p->from, reg[p->to.type]);
|
||||
break;
|
||||
|
||||
case Zm_r_xm:
|
||||
mediaop(ctxt, o, op, t[3], z);
|
||||
asmand(ctxt, &p->from, reg[p->to.type]);
|
||||
asmand(ctxt, p, &p->from, reg[p->to.type]);
|
||||
break;
|
||||
|
||||
case Zm_r_i_xm:
|
||||
mediaop(ctxt, o, op, t[3], z);
|
||||
asmand(ctxt, &p->from, reg[p->to.type]);
|
||||
asmand(ctxt, p, &p->from, reg[p->to.type]);
|
||||
*ctxt->andptr++ = p->to.offset;
|
||||
break;
|
||||
|
||||
case Zibm_r:
|
||||
while ((op = o->op[z++]) != 0)
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->from, reg[p->to.type]);
|
||||
asmand(ctxt, p, &p->from, reg[p->to.type]);
|
||||
*ctxt->andptr++ = p->to.offset;
|
||||
break;
|
||||
|
||||
@ -2274,7 +2278,7 @@ found:
|
||||
p->from.type = p->from.index;
|
||||
p->from.index = D_NONE;
|
||||
p->ft = 0;
|
||||
asmand(ctxt, &p->from, reg[p->to.type]);
|
||||
asmand(ctxt, p, &p->from, reg[p->to.type]);
|
||||
p->from.index = p->from.type;
|
||||
p->from.type = D_ADDR;
|
||||
p->ft = 0;
|
||||
@ -2282,22 +2286,22 @@ found:
|
||||
|
||||
case Zm_o:
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->from, o->op[z+1]);
|
||||
asmand(ctxt, p, &p->from, o->op[z+1]);
|
||||
break;
|
||||
|
||||
case Zr_m:
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->to, reg[p->from.type]);
|
||||
asmand(ctxt, p, &p->to, reg[p->from.type]);
|
||||
break;
|
||||
|
||||
case Zr_m_xm:
|
||||
mediaop(ctxt, o, op, t[3], z);
|
||||
asmand(ctxt, &p->to, reg[p->from.type]);
|
||||
asmand(ctxt, p, &p->to, reg[p->from.type]);
|
||||
break;
|
||||
|
||||
case Zr_m_i_xm:
|
||||
mediaop(ctxt, o, op, t[3], z);
|
||||
asmand(ctxt, &p->to, reg[p->from.type]);
|
||||
asmand(ctxt, p, &p->to, reg[p->from.type]);
|
||||
*ctxt->andptr++ = p->from.offset;
|
||||
break;
|
||||
|
||||
@ -2309,19 +2313,19 @@ found:
|
||||
// fallthrough
|
||||
case Zo_m:
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->to, o->op[z+1]);
|
||||
asmand(ctxt, p, &p->to, o->op[z+1]);
|
||||
break;
|
||||
|
||||
case Zm_ibo:
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->from, o->op[z+1]);
|
||||
*ctxt->andptr++ = vaddr(ctxt, &p->to, nil);
|
||||
asmand(ctxt, p, &p->from, o->op[z+1]);
|
||||
*ctxt->andptr++ = vaddr(ctxt, p, &p->to, nil);
|
||||
break;
|
||||
|
||||
case Zibo_m:
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->to, o->op[z+1]);
|
||||
*ctxt->andptr++ = vaddr(ctxt, &p->from, nil);
|
||||
asmand(ctxt, p, &p->to, o->op[z+1]);
|
||||
*ctxt->andptr++ = vaddr(ctxt, p, &p->from, nil);
|
||||
break;
|
||||
|
||||
case Z_ib:
|
||||
@ -2330,20 +2334,20 @@ found:
|
||||
a = &p->from;
|
||||
else
|
||||
a = &p->to;
|
||||
v = vaddr(ctxt, a, nil);
|
||||
v = vaddr(ctxt, p, a, nil);
|
||||
*ctxt->andptr++ = op;
|
||||
*ctxt->andptr++ = v;
|
||||
break;
|
||||
|
||||
case Zib_rp:
|
||||
*ctxt->andptr++ = op + reg[p->to.type];
|
||||
*ctxt->andptr++ = vaddr(ctxt, &p->from, nil);
|
||||
*ctxt->andptr++ = vaddr(ctxt, p, &p->from, nil);
|
||||
break;
|
||||
|
||||
case Zil_rp:
|
||||
*ctxt->andptr++ = op + reg[p->to.type];
|
||||
if(o->prefix == Pe) {
|
||||
v = vaddr(ctxt, &p->from, nil);
|
||||
v = vaddr(ctxt, p, &p->from, nil);
|
||||
*ctxt->andptr++ = v;
|
||||
*ctxt->andptr++ = v>>8;
|
||||
}
|
||||
@ -2353,8 +2357,8 @@ found:
|
||||
|
||||
case Zib_rr:
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->to, reg[p->to.type]);
|
||||
*ctxt->andptr++ = vaddr(ctxt, &p->from, nil);
|
||||
asmand(ctxt, p, &p->to, reg[p->to.type]);
|
||||
*ctxt->andptr++ = vaddr(ctxt, p, &p->from, nil);
|
||||
break;
|
||||
|
||||
case Z_il:
|
||||
@ -2365,7 +2369,7 @@ found:
|
||||
a = &p->to;
|
||||
*ctxt->andptr++ = op;
|
||||
if(o->prefix == Pe) {
|
||||
v = vaddr(ctxt, a, nil);
|
||||
v = vaddr(ctxt, p, a, nil);
|
||||
*ctxt->andptr++ = v;
|
||||
*ctxt->andptr++ = v>>8;
|
||||
}
|
||||
@ -2378,13 +2382,13 @@ found:
|
||||
*ctxt->andptr++ = op;
|
||||
if(t[2] == Zilo_m) {
|
||||
a = &p->from;
|
||||
asmand(ctxt, &p->to, o->op[z+1]);
|
||||
asmand(ctxt, p, &p->to, o->op[z+1]);
|
||||
} else {
|
||||
a = &p->to;
|
||||
asmand(ctxt, &p->from, o->op[z+1]);
|
||||
asmand(ctxt, p, &p->from, o->op[z+1]);
|
||||
}
|
||||
if(o->prefix == Pe) {
|
||||
v = vaddr(ctxt, a, nil);
|
||||
v = vaddr(ctxt, p, a, nil);
|
||||
*ctxt->andptr++ = v;
|
||||
*ctxt->andptr++ = v>>8;
|
||||
}
|
||||
@ -2394,9 +2398,9 @@ found:
|
||||
|
||||
case Zil_rr:
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->to, reg[p->to.type]);
|
||||
asmand(ctxt, p, &p->to, reg[p->to.type]);
|
||||
if(o->prefix == Pe) {
|
||||
v = vaddr(ctxt, &p->from, nil);
|
||||
v = vaddr(ctxt, p, &p->from, nil);
|
||||
*ctxt->andptr++ = v;
|
||||
*ctxt->andptr++ = v>>8;
|
||||
}
|
||||
@ -2414,7 +2418,7 @@ found:
|
||||
|
||||
case Zclr:
|
||||
*ctxt->andptr++ = op;
|
||||
asmand(ctxt, &p->to, reg[p->to.type]);
|
||||
asmand(ctxt, p, &p->to, reg[p->to.type]);
|
||||
break;
|
||||
|
||||
case Zcall:
|
||||
@ -2529,7 +2533,7 @@ found:
|
||||
break;
|
||||
|
||||
case Zbyte:
|
||||
v = vaddr(ctxt, &p->from, &rel);
|
||||
v = vaddr(ctxt, p, &p->from, &rel);
|
||||
if(rel.siz != 0) {
|
||||
rel.siz = op;
|
||||
r = addrel(ctxt->cursym);
|
||||
@ -2570,11 +2574,11 @@ bad:
|
||||
if(z >= D_BP && z <= D_DI) {
|
||||
if((breg = byteswapreg(ctxt, &p->to)) != D_AX) {
|
||||
*ctxt->andptr++ = 0x87; /* xchg lhs,bx */
|
||||
asmand(ctxt, &p->from, reg[breg]);
|
||||
asmand(ctxt, p, &p->from, reg[breg]);
|
||||
subreg(&pp, z, breg);
|
||||
doasm(ctxt, &pp);
|
||||
*ctxt->andptr++ = 0x87; /* xchg lhs,bx */
|
||||
asmand(ctxt, &p->from, reg[breg]);
|
||||
asmand(ctxt, p, &p->from, reg[breg]);
|
||||
} else {
|
||||
*ctxt->andptr++ = 0x90 + reg[z]; /* xchg lsh,ax */
|
||||
subreg(&pp, z, D_AX);
|
||||
@ -2587,11 +2591,11 @@ bad:
|
||||
if(z >= D_BP && z <= D_DI) {
|
||||
if((breg = byteswapreg(ctxt, &p->from)) != D_AX) {
|
||||
*ctxt->andptr++ = 0x87; /* xchg rhs,bx */
|
||||
asmand(ctxt, &p->to, reg[breg]);
|
||||
asmand(ctxt, p, &p->to, reg[breg]);
|
||||
subreg(&pp, z, breg);
|
||||
doasm(ctxt, &pp);
|
||||
*ctxt->andptr++ = 0x87; /* xchg rhs,bx */
|
||||
asmand(ctxt, &p->to, reg[breg]);
|
||||
asmand(ctxt, p, &p->to, reg[breg]);
|
||||
} else {
|
||||
*ctxt->andptr++ = 0x90 + reg[z]; /* xchg rsh,ax */
|
||||
subreg(&pp, z, D_AX);
|
||||
@ -2616,24 +2620,24 @@ mfound:
|
||||
|
||||
case 1: /* r,m */
|
||||
*ctxt->andptr++ = t[4];
|
||||
asmand(ctxt, &p->to, t[5]);
|
||||
asmand(ctxt, p, &p->to, t[5]);
|
||||
break;
|
||||
|
||||
case 2: /* m,r */
|
||||
*ctxt->andptr++ = t[4];
|
||||
asmand(ctxt, &p->from, t[5]);
|
||||
asmand(ctxt, p, &p->from, t[5]);
|
||||
break;
|
||||
|
||||
case 3: /* r,m - 2op */
|
||||
*ctxt->andptr++ = t[4];
|
||||
*ctxt->andptr++ = t[5];
|
||||
asmand(ctxt, &p->to, t[6]);
|
||||
asmand(ctxt, p, &p->to, t[6]);
|
||||
break;
|
||||
|
||||
case 4: /* m,r - 2op */
|
||||
*ctxt->andptr++ = t[4];
|
||||
*ctxt->andptr++ = t[5];
|
||||
asmand(ctxt, &p->from, t[6]);
|
||||
asmand(ctxt, p, &p->from, t[6]);
|
||||
break;
|
||||
|
||||
case 5: /* load full pointer, trash heap */
|
||||
@ -2661,7 +2665,7 @@ mfound:
|
||||
*ctxt->andptr++ = 0xb5;
|
||||
break;
|
||||
}
|
||||
asmand(ctxt, &p->from, reg[p->to.type]);
|
||||
asmand(ctxt, p, &p->from, reg[p->to.type]);
|
||||
break;
|
||||
|
||||
case 6: /* double shift */
|
||||
@ -2672,14 +2676,14 @@ mfound:
|
||||
case D_CONST:
|
||||
*ctxt->andptr++ = 0x0f;
|
||||
*ctxt->andptr++ = t[4];
|
||||
asmand(ctxt, &p->to, reg[p->from.index]);
|
||||
asmand(ctxt, p, &p->to, reg[p->from.index]);
|
||||
*ctxt->andptr++ = p->from.offset;
|
||||
break;
|
||||
case D_CL:
|
||||
case D_CX:
|
||||
*ctxt->andptr++ = 0x0f;
|
||||
*ctxt->andptr++ = t[5];
|
||||
asmand(ctxt, &p->to, reg[p->from.index]);
|
||||
asmand(ctxt, p, &p->to, reg[p->from.index]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -2691,7 +2695,7 @@ mfound:
|
||||
} else
|
||||
*ctxt->andptr++ = t[4];
|
||||
*ctxt->andptr++ = t[5];
|
||||
asmand(ctxt, &p->from, reg[p->to.type]);
|
||||
asmand(ctxt, p, &p->from, reg[p->to.type]);
|
||||
break;
|
||||
|
||||
case 8: /* mov tls, r */
|
||||
@ -2713,7 +2717,7 @@ mfound:
|
||||
pp.from.scale = 0;
|
||||
*ctxt->andptr++ = 0x65; // GS
|
||||
*ctxt->andptr++ = 0x8B;
|
||||
asmand(ctxt, &pp.from, reg[p->to.type]);
|
||||
asmand(ctxt, p, &pp.from, reg[p->to.type]);
|
||||
break;
|
||||
|
||||
case Hplan9:
|
||||
@ -2725,7 +2729,7 @@ mfound:
|
||||
pp.from.offset = 0;
|
||||
pp.from.index = D_NONE;
|
||||
*ctxt->andptr++ = 0x8B;
|
||||
asmand(ctxt, &pp.from, reg[p->to.type]);
|
||||
asmand(ctxt, p, &pp.from, reg[p->to.type]);
|
||||
break;
|
||||
|
||||
case Hwindows:
|
||||
@ -2737,7 +2741,7 @@ mfound:
|
||||
pp.from.scale = 0;
|
||||
*ctxt->andptr++ = 0x64; // FS
|
||||
*ctxt->andptr++ = 0x8B;
|
||||
asmand(ctxt, &pp.from, reg[p->to.type]);
|
||||
asmand(ctxt, p, &pp.from, reg[p->to.type]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user