diff options
| author | Russ Cox <rsc@golang.org> | 2015-01-26 15:15:43 -0500 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2015-01-30 03:16:19 +0000 |
| commit | a5b1baeed7d26a3d8aea86bbabe81f59c3d4e9d6 (patch) | |
| tree | 4a0222814771277f93201d329d5cfd3f811f6f79 /src/liblink/obj8.c | |
| parent | 604138e87bb0d992319ed2ccc034f9a2591a8363 (diff) | |
| download | go-a5b1baeed7d26a3d8aea86bbabe81f59c3d4e9d6.tar.xz | |
cmd/8a, cmd/8g, cmd/8l, liblink: update for portable Prog, Addr
Change-Id: I19ed283962aa0221cf806307bde9ea0773a1bfd4
Reviewed-on: https://go-review.googlesource.com/3518
Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/liblink/obj8.c')
| -rw-r--r-- | src/liblink/obj8.c | 248 |
1 files changed, 129 insertions, 119 deletions
diff --git a/src/liblink/obj8.c b/src/liblink/obj8.c index 4e28709b81..cceeeb1b87 100644 --- a/src/liblink/obj8.c +++ b/src/liblink/obj8.c @@ -39,29 +39,18 @@ static Prog zprg = { .back = 2, .as = AGOK, .from = { - .type = D_NONE, - .index = D_NONE, + .type = TYPE_NONE, + .index = REG_NONE, .scale = 1, }, .to = { - .type = D_NONE, - .index = D_NONE, + .type = TYPE_NONE, + .index = REG_NONE, .scale = 1, }, }; static int -symtype(Addr *a) -{ - int t; - - t = a->type; - if(t == D_ADDR) - t = a->index; - return t; -} - -static int isdata(Prog *p) { return p->as == ADATA || p->as == AGLOBL; @@ -120,20 +109,22 @@ progedit(Link *ctxt, Prog *p) // become // NOP // ... off(TLS) ... - if(p->as == AMOVL && p->from.type == D_TLS && D_AX <= p->to.type && p->to.type <= D_DI) { + if(p->as == AMOVL && p->from.type == TYPE_REG && p->from.reg == REG_TLS && p->to.type == TYPE_REG && REG_AX <= p->to.reg && p->to.reg <= REG_DI) { p->as = ANOP; - p->from.type = D_NONE; - p->to.type = D_NONE; + p->from.type = TYPE_NONE; + p->to.type = TYPE_NONE; } - if(p->from.index == D_TLS && D_INDIR+D_AX <= p->from.type && p->from.type <= D_INDIR+D_DI) { - p->from.type = D_INDIR+D_TLS; + if(p->from.type == TYPE_MEM && p->from.index == REG_TLS && REG_AX <= p->from.reg && p->from.reg <= REG_DI) { + p->from.type = TYPE_MEM; + p->from.reg = REG_TLS; p->from.scale = 0; - p->from.index = D_NONE; + p->from.index = REG_NONE; } - if(p->to.index == D_TLS && D_INDIR+D_AX <= p->to.type && p->to.type <= D_INDIR+D_DI) { - p->to.type = D_INDIR+D_TLS; + if(p->to.type == TYPE_MEM && p->to.index == REG_TLS && REG_AX <= p->to.reg && p->to.reg <= REG_DI) { + p->to.type = TYPE_MEM; + p->to.reg = REG_TLS; p->to.scale = 0; - p->to.index = D_NONE; + p->to.index = REG_NONE; } } else { // As a courtesy to the C compilers, rewrite TLS local exec load as TLS initial exec load. @@ -143,35 +134,36 @@ progedit(Link *ctxt, Prog *p) // MOVL TLS, BX // MOVL off(BX)(TLS*1), BX // This allows the C compilers to emit references to m and g using the direct off(TLS) form. - if(p->as == AMOVL && p->from.type == D_INDIR+D_TLS && D_AX <= p->to.type && p->to.type <= D_DI) { + if(p->as == AMOVL && p->from.type == TYPE_MEM && p->from.reg == REG_TLS && p->to.type == TYPE_REG && REG_AX <= p->to.reg && p->to.reg <= REG_DI) { q = appendp(ctxt, p); q->as = p->as; - q->from = p->from; - q->from.type = D_INDIR + p->to.type; - q->from.index = D_TLS; + q->from.type = TYPE_MEM; + q->from.reg = p->to.reg; + q->from.index = REG_TLS; q->from.scale = 2; // TODO: use 1 q->to = p->to; - p->from.type = D_TLS; - p->from.index = D_NONE; + p->from.type = TYPE_REG; + p->from.reg = REG_TLS; + p->from.index = REG_NONE; p->from.offset = 0; } } // TODO: Remove. if(ctxt->headtype == Hplan9) { - if(p->from.scale == 1 && p->from.index == D_TLS) + if(p->from.scale == 1 && p->from.index == REG_TLS) p->from.scale = 2; - if(p->to.scale == 1 && p->to.index == D_TLS) + if(p->to.scale == 1 && p->to.index == REG_TLS) p->to.scale = 2; } - // Rewrite CALL/JMP/RET to symbol as D_BRANCH. + // Rewrite CALL/JMP/RET to symbol as TYPE_BRANCH. switch(p->as) { case ACALL: case AJMP: case ARET: - if((p->to.type == D_EXTERN || p->to.type == D_STATIC) && p->to.sym != nil) - p->to.type = D_BRANCH; + if(p->to.type == TYPE_MEM && (p->to.name == NAME_EXTERN || p->to.name == NAME_STATIC) && p->to.sym != nil) + p->to.type = TYPE_BRANCH; break; } @@ -179,13 +171,11 @@ progedit(Link *ctxt, Prog *p) switch(p->as) { case AMOVSS: // Convert AMOVSS $(0), Xx to AXORPS Xx, Xx - if(p->from.type == D_FCONST) + if(p->from.type == TYPE_FCONST) if(p->from.u.dval == 0) - if(p->to.type >= D_X0) - if(p->to.type <= D_X7) { + if(p->to.type == TYPE_REG && REG_X0 <= p->to.reg && p->to.reg <= REG_X7) { p->as = AXORPS; - p->from.type = p->to.type; - p->from.index = p->to.index; + p->from = p->to; break; } // fallthrough @@ -205,7 +195,7 @@ progedit(Link *ctxt, Prog *p) case ADIVSS: case ACOMISS: case AUCOMISS: - if(p->from.type == D_FCONST) { + if(p->from.type == TYPE_FCONST) { uint32 i32; float32 f32; f32 = p->from.u.dval; @@ -217,7 +207,8 @@ progedit(Link *ctxt, Prog *p) adduint32(ctxt, s, i32); s->reachable = 0; } - p->from.type = D_EXTERN; + p->from.type = TYPE_MEM; + p->from.name = NAME_EXTERN; p->from.sym = s; p->from.offset = 0; } @@ -225,13 +216,11 @@ progedit(Link *ctxt, Prog *p) case AMOVSD: // Convert AMOVSD $(0), Xx to AXORPS Xx, Xx - if(p->from.type == D_FCONST) + if(p->from.type == TYPE_FCONST) if(p->from.u.dval == 0) - if(p->to.type >= D_X0) - if(p->to.type <= D_X7) { + if(p->to.type == TYPE_REG && REG_X0 <= p->to.reg && p->to.reg <= REG_X7) { p->as = AXORPS; - p->from.type = p->to.type; - p->from.index = p->to.index; + p->from = p->to; break; } // fallthrough @@ -251,7 +240,7 @@ progedit(Link *ctxt, Prog *p) case ADIVSD: case ACOMISD: case AUCOMISD: - if(p->from.type == D_FCONST) { + if(p->from.type == TYPE_FCONST) { uint64 i64; memmove(&i64, &p->from.u.dval, 8); sprint(literal, "$f64.%016llux", i64); @@ -261,7 +250,8 @@ progedit(Link *ctxt, Prog *p) adduint64(ctxt, s, i64); s->reachable = 0; } - p->from.type = D_EXTERN; + p->from.type = TYPE_MEM; + p->from.name = NAME_EXTERN; p->from.sym = s; p->from.offset = 0; } @@ -283,7 +273,7 @@ static Prog* load_g_cx(Link*, Prog*); static Prog* stacksplit(Link*, Prog*, int32, int, Prog**); static void -addstacksplit(Link *ctxt, LSym *cursym) +preprocess(Link *ctxt, LSym *cursym) { Prog *p, *q, *p1, *p2; int32 autoffset, deltasp; @@ -308,7 +298,7 @@ addstacksplit(Link *ctxt, LSym *cursym) autoffset = 0; cursym->locals = autoffset; - cursym->args = p->to.offset2; + cursym->args = p->to.u.argsize; q = nil; @@ -322,7 +312,7 @@ addstacksplit(Link *ctxt, LSym *cursym) if(autoffset) { p = appendp(ctxt, p); p->as = AADJSP; - p->from.type = D_CONST; + p->from.type = TYPE_CONST; p->from.offset = autoffset; p->spadj = autoffset; } else { @@ -358,41 +348,51 @@ addstacksplit(Link *ctxt, LSym *cursym) p = appendp(ctxt, p); p->as = AMOVL; - p->from.type = D_INDIR+D_CX; + p->from.type = TYPE_MEM; + p->from.reg = REG_CX; p->from.offset = 4*ctxt->arch->ptrsize; // G.panic - p->to.type = D_BX; + p->to.type = TYPE_REG; + p->to.reg = REG_BX; p = appendp(ctxt, p); p->as = ATESTL; - p->from.type = D_BX; - p->to.type = D_BX; + p->from.type = TYPE_REG; + p->from.reg = REG_BX; + p->to.type = TYPE_REG; + p->to.reg = REG_BX; p = appendp(ctxt, p); p->as = AJEQ; - p->to.type = D_BRANCH; + p->to.type = TYPE_BRANCH; p1 = p; p = appendp(ctxt, p); p->as = ALEAL; - p->from.type = D_INDIR+D_SP; + p->from.type = TYPE_MEM; + p->from.reg = REG_SP; p->from.offset = autoffset+4; - p->to.type = D_DI; + p->to.type = TYPE_REG; + p->to.reg = REG_DI; p = appendp(ctxt, p); p->as = ACMPL; - p->from.type = D_INDIR+D_BX; + p->from.type = TYPE_MEM; + p->from.reg = REG_BX; p->from.offset = 0; // Panic.argp - p->to.type = D_DI; + p->to.type = TYPE_REG; + p->to.reg = REG_DI; p = appendp(ctxt, p); p->as = AJNE; - p->to.type = D_BRANCH; + p->to.type = TYPE_BRANCH; p2 = p; p = appendp(ctxt, p); p->as = AMOVL; - p->from.type = D_SP; - p->to.type = D_INDIR+D_BX; + p->from.type = TYPE_REG; + p->from.reg = REG_SP; + p->to.type = TYPE_MEM; + p->to.reg = REG_BX; p->to.offset = 0; // Panic.argp p = appendp(ctxt, p); @@ -407,20 +407,24 @@ addstacksplit(Link *ctxt, LSym *cursym) // false positives in garbage collection. p = appendp(ctxt, p); p->as = AMOVL; - p->from.type = D_SP; - p->to.type = D_DI; + p->from.type = TYPE_REG; + p->from.reg = REG_SP; + p->to.type = TYPE_REG; + p->to.reg = REG_DI; p = appendp(ctxt, p); p->as = AMOVL; - p->from.type = D_CONST; + p->from.type = TYPE_CONST; p->from.offset = autoffset/4; - p->to.type = D_CX; + p->to.type = TYPE_REG; + p->to.reg = REG_CX; p = appendp(ctxt, p); p->as = AMOVL; - p->from.type = D_CONST; + p->from.type = TYPE_CONST; p->from.offset = 0; - p->to.type = D_AX; + p->to.type = TYPE_REG; + p->to.reg = REG_AX; p = appendp(ctxt, p); p->as = AREP; @@ -430,15 +434,15 @@ addstacksplit(Link *ctxt, LSym *cursym) } for(; p != nil; p = p->link) { - a = p->from.type; - if(a == D_AUTO) + a = p->from.name; + if(a == NAME_AUTO) p->from.offset += deltasp; - if(a == D_PARAM) + if(a == NAME_PARAM) p->from.offset += deltasp + 4; - a = p->to.type; - if(a == D_AUTO) + a = p->to.name; + if(a == NAME_AUTO) p->to.offset += deltasp; - if(a == D_PARAM) + if(a == NAME_PARAM) p->to.offset += deltasp + 4; switch(p->as) { @@ -473,7 +477,7 @@ addstacksplit(Link *ctxt, LSym *cursym) if(autoffset) { p->as = AADJSP; - p->from.type = D_CONST; + p->from.type = TYPE_CONST; p->from.offset = -autoffset; p->spadj = -autoffset; p = appendp(ctxt, p); @@ -500,16 +504,18 @@ load_g_cx(Link *ctxt, Prog *p) Prog *next; p->as = AMOVL; - p->from.type = D_INDIR+D_TLS; + p->from.type = TYPE_MEM; + p->from.reg = REG_TLS; p->from.offset = 0; - p->to.type = D_CX; + p->to.type = TYPE_REG; + p->to.reg = REG_CX; next = p->link; progedit(ctxt, p); while(p->link != next) p = p->link; - if(p->from.index == D_TLS) + if(p->from.index == REG_TLS) p->from.scale = 2; return p; @@ -534,19 +540,21 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok) // catches out-of-sync stack guard info. p = appendp(ctxt, p); p->as = ACMPL; - p->from.type = D_INDIR+D_CX; + p->from.type = TYPE_MEM; + p->from.reg = REG_CX; p->from.offset = 4; - p->to.type = D_SP; + p->to.type = TYPE_REG; + p->to.reg = REG_SP; p = appendp(ctxt, p); p->as = AJCC; - p->to.type = D_BRANCH; + p->to.type = TYPE_BRANCH; p->to.offset = 4; q1 = p; p = appendp(ctxt, p); p->as = AINT; - p->from.type = D_CONST; + p->from.type = TYPE_CONST; p->from.offset = 3; p = appendp(ctxt, p); @@ -560,8 +568,10 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok) // CMPL SP, stackguard p = appendp(ctxt, p); p->as = ACMPL; - p->from.type = D_SP; - p->to.type = D_INDIR+D_CX; + p->from.type = TYPE_REG; + p->from.reg = REG_SP; + p->to.type = TYPE_MEM; + p->to.reg = REG_CX; p->to.offset = 2*ctxt->arch->ptrsize; // G.stackguard0 if(ctxt->cursym->cfunc) p->to.offset = 3*ctxt->arch->ptrsize; // G.stackguard1 @@ -571,14 +581,18 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok) // CMPL AX, stackguard p = appendp(ctxt, p); p->as = ALEAL; - p->from.type = D_INDIR+D_SP; + p->from.type = TYPE_MEM; + p->from.reg = REG_SP; p->from.offset = -(framesize-StackSmall); - p->to.type = D_AX; + p->to.type = TYPE_REG; + p->to.reg = REG_AX; p = appendp(ctxt, p); p->as = ACMPL; - p->from.type = D_AX; - p->to.type = D_INDIR+D_CX; + p->from.type = TYPE_REG; + p->from.reg = REG_AX; + p->to.type = TYPE_MEM; + p->to.reg = REG_CX; p->to.offset = 2*ctxt->arch->ptrsize; // G.stackguard0 if(ctxt->cursym->cfunc) p->to.offset = 3*ctxt->arch->ptrsize; // G.stackguard1 @@ -599,53 +613,61 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok) // CMPL AX, $(framesize+(StackGuard-StackSmall)) p = appendp(ctxt, p); p->as = AMOVL; - p->from.type = D_INDIR+D_CX; + p->from.type = TYPE_MEM; + p->from.reg = REG_CX; p->from.offset = 0; p->from.offset = 2*ctxt->arch->ptrsize; // G.stackguard0 if(ctxt->cursym->cfunc) p->from.offset = 3*ctxt->arch->ptrsize; // G.stackguard1 - p->to.type = D_SI; + p->to.type = TYPE_REG; + p->to.reg = REG_SI; p = appendp(ctxt, p); p->as = ACMPL; - p->from.type = D_SI; - p->to.type = D_CONST; + p->from.type = TYPE_REG; + p->from.reg = REG_SI; + p->to.type = TYPE_CONST; p->to.offset = (uint32)StackPreempt; p = appendp(ctxt, p); p->as = AJEQ; - p->to.type = D_BRANCH; + p->to.type = TYPE_BRANCH; q1 = p; p = appendp(ctxt, p); p->as = ALEAL; - p->from.type = D_INDIR+D_SP; + p->from.type = TYPE_MEM; + p->from.reg = REG_SP; p->from.offset = StackGuard; - p->to.type = D_AX; + p->to.type = TYPE_REG; + p->to.reg = REG_AX; p = appendp(ctxt, p); p->as = ASUBL; - p->from.type = D_SI; + p->from.type = TYPE_REG; + p->from.reg = REG_SI; p->from.offset = 0; - p->to.type = D_AX; + p->to.type = TYPE_REG; + p->to.reg = REG_AX; p = appendp(ctxt, p); p->as = ACMPL; - p->from.type = D_AX; - p->to.type = D_CONST; + p->from.type = TYPE_REG; + p->from.reg = REG_AX; + p->to.type = TYPE_CONST; p->to.offset = framesize+(StackGuard-StackSmall); } // common p = appendp(ctxt, p); p->as = AJHI; - p->to.type = D_BRANCH; + p->to.type = TYPE_BRANCH; p->to.offset = 4; q = p; p = appendp(ctxt, p); p->as = ACALL; - p->to.type = D_BRANCH; + p->to.type = TYPE_BRANCH; if(ctxt->cursym->cfunc) p->to.sym = linklookup(ctxt, "runtime.morestackc", 0); else @@ -653,7 +675,7 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok) p = appendp(ctxt, p); p->as = AJMP; - p->to.type = D_BRANCH; + p->to.type = TYPE_BRANCH; p->pcond = ctxt->cursym->text->link; if(q != nil) @@ -804,7 +826,7 @@ loop: q = ctxt->arch->prg(); q->as = AJMP; q->lineno = p->lineno; - q->to.type = D_BRANCH; + q->to.type = TYPE_BRANCH; q->to.offset = p->pc; q->pcond = p; p = q; @@ -829,7 +851,7 @@ loop: p->pcond = q; if((q = brchain(ctxt, p->link)) != nil) p->link = q; - if(p->from.type == D_CONST) { + if(p->from.type == TYPE_CONST) { if(p->from.offset == 1) { /* * expect conditional jump to be taken. @@ -864,7 +886,7 @@ LinkArch link386 = { .thechar = '8', .endian = LittleEndian, - .addstacksplit = addstacksplit, + .preprocess = preprocess, .assemble = span8, .datasize = datasize, .follow = follow, @@ -873,24 +895,12 @@ LinkArch link386 = { .prg = prg, .progedit = progedit, .settextflag = settextflag, - .symtype = symtype, .textflag = textflag, .minlc = 1, .ptrsize = 4, .regsize = 4, - .D_ADDR = D_ADDR, - .D_AUTO = D_AUTO, - .D_BRANCH = D_BRANCH, - .D_CONST = D_CONST, - .D_EXTERN = D_EXTERN, - .D_FCONST = D_FCONST, - .D_NONE = D_NONE, - .D_PARAM = D_PARAM, - .D_SCONST = D_SCONST, - .D_STATIC = D_STATIC, - .ACALL = ACALL, .ADATA = ADATA, .AEND = AEND, |
