diff options
| author | Russ Cox <rsc@golang.org> | 2015-01-29 20:19:07 -0500 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2015-02-03 18:23:05 +0000 |
| commit | 2e5b065ac24912be82e7082eeb136afd18d9734b (patch) | |
| tree | 9658f6b04dda8a9dd921bad95b2ca5adceb90f9b /src/cmd/gc | |
| parent | 3ac37c72ae56a229bdc75986a4071b29bd7298c8 (diff) | |
| download | go-2e5b065ac24912be82e7082eeb136afd18d9734b.tar.xz | |
liblink: define fixed A-numbers for common instructions
This makes names like ANOP, ATEXT, AGLOBL, ACALL, AJMP, ARET
available for use by architecture-independent processing passes.
On arm and ppc64, the alternate names are now aliases for the
official ones (ABL for ACALL, AB or ABR for AJMP, ARETURN for ARET).
Change-Id: Id027771243795af2b3745199c645b6e1bedd7d18
Reviewed-on: https://go-review.googlesource.com/3577
Reviewed-by: Aram Hăvărneanu <aram@mgk.ro>
Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/cmd/gc')
| -rw-r--r-- | src/cmd/gc/go.h | 18 | ||||
| -rw-r--r-- | src/cmd/gc/pgen.c | 20 | ||||
| -rw-r--r-- | src/cmd/gc/plive.c | 42 | ||||
| -rw-r--r-- | src/cmd/gc/popt.c | 26 |
4 files changed, 45 insertions, 61 deletions
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index fe74f3484d..da1fd64e86 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -1657,23 +1657,7 @@ struct Arch char *thestring; LinkArch *thelinkarch; Typedef *typedefs; - - int ACALL; - int ACHECKNIL; - int ADATA; - int AFUNCDATA; - int AGLOBL; - int AJMP; - int ANAME; - int ANOP; - int APCDATA; - int ARET; - int ASIGNAME; - int ATEXT; - int ATYPE; - int AUNDEF; - int AVARDEF; - int AVARKILL; + vlong MAXWIDTH; void (*afunclit)(Addr*, Node*); diff --git a/src/cmd/gc/pgen.c b/src/cmd/gc/pgen.c index 183bd71426..ec1628651e 100644 --- a/src/cmd/gc/pgen.c +++ b/src/cmd/gc/pgen.c @@ -30,7 +30,7 @@ makefuncdatasym(char *namefmt, int64 funcdatakind) pnod = newname(sym); pnod->class = PEXTERN; nodconst(&nod, types[TINT32], funcdatakind); - arch.gins(arch.AFUNCDATA, &nod, pnod); + arch.gins(AFUNCDATA, &nod, pnod); return sym; } @@ -110,13 +110,13 @@ gvardefx(Node *n, int as) void gvardef(Node *n) { - gvardefx(n, arch.AVARDEF); + gvardefx(n, AVARDEF); } void gvarkill(Node *n) { - gvardefx(n, arch.AVARKILL); + gvardefx(n, AVARKILL); } static void @@ -125,10 +125,10 @@ removevardef(Prog *firstp) Prog *p; for(p = firstp; p != P; p = p->link) { - while(p->link != P && (p->link->as == arch.AVARDEF || p->link->as == arch.AVARKILL)) + while(p->link != P && (p->link->as == AVARDEF || p->link->as == AVARKILL)) p->link = p->link->link; if(p->to.type == TYPE_BRANCH) - while(p->to.u.branch != P && (p->to.u.branch->as == arch.AVARDEF || p->to.u.branch->as == arch.AVARKILL)) + while(p->to.u.branch != P && (p->to.u.branch->as == AVARDEF || p->to.u.branch->as == AVARKILL)) p->to.u.branch = p->to.u.branch->link; } } @@ -229,7 +229,7 @@ compile(Node *fn) setlineno(curfn); nodconst(&nod1, types[TINT32], 0); - ptxt = arch.gins(arch.ATEXT, isblank(curfn->nname) ? N : curfn->nname, &nod1); + ptxt = arch.gins(ATEXT, isblank(curfn->nname) ? N : curfn->nname, &nod1); if(fn->dupok) ptxt->from3.offset |= DUPOK; if(fn->wrapper) @@ -266,7 +266,7 @@ compile(Node *fn) case PPARAM: case PPARAMOUT: nodconst(&nod1, types[TUINTPTR], l->n->type->width); - p = arch.gins(arch.ATYPE, l->n, &nod1); + p = arch.gins(ATYPE, l->n, &nod1); p->from.gotype = linksym(ngotype(l->n)); break; } @@ -297,7 +297,7 @@ compile(Node *fn) if(nerrors != 0) goto ret; - pc->as = arch.ARET; // overwrite AEND + pc->as = ARET; // overwrite AEND pc->lineno = lineno; fixjmp(ptxt); @@ -535,9 +535,9 @@ cgen_checknil(Node *n) if(((arch.thechar == '5' || arch.thechar == '9') && n->op != OREGISTER) || !n->addable || n->op == OLITERAL) { arch.regalloc(®, types[tptr], n); arch.cgen(n, ®); - arch.gins(arch.ACHECKNIL, ®, N); + arch.gins(ACHECKNIL, ®, N); arch.regfree(®); return; } - arch.gins(arch.ACHECKNIL, n, N); + arch.gins(ACHECKNIL, n, N); } diff --git a/src/cmd/gc/plive.c b/src/cmd/gc/plive.c index ba98a9772f..0461085b5b 100644 --- a/src/cmd/gc/plive.c +++ b/src/cmd/gc/plive.c @@ -371,7 +371,7 @@ iscall(Prog *prog, LSym *name) fatal("iscall: prog is nil"); if(name == nil) fatal("iscall: function name is nil"); - if(prog->as != arch.ACALL) + if(prog->as != ACALL) return 0; return name == prog->to.sym; } @@ -519,7 +519,7 @@ newcfg(Prog *firstp) p->to.u.branch->opt = newblock(p->to.u.branch); arrayadd(cfg, &p->to.u.branch->opt); } - if(p->as != arch.AJMP && p->link != nil && p->link->opt == nil) { + if(p->as != AJMP && p->link != nil && p->link->opt == nil) { p->link->opt = newblock(p->link); arrayadd(cfg, &p->link->opt); } @@ -544,7 +544,7 @@ newcfg(Prog *firstp) // Stop before an unreachable RET, to avoid creating // unreachable control flow nodes. - if(p->link != nil && p->link->as == arch.ARET && p->link->mode == 1) + if(p->link != nil && p->link->as == ARET && p->link->mode == 1) break; // Collect basic blocks with selectgo calls. @@ -556,7 +556,7 @@ newcfg(Prog *firstp) if(bb->last->link != nil) { // Add a fall-through when the instruction is // not an unconditional control transfer. - if(bb->last->as != arch.AJMP && bb->last->as != arch.ARET && bb->last->as != arch.AUNDEF) + if(bb->last->as != AJMP && bb->last->as != ARET && bb->last->as != AUNDEF) addedge(bb, bb->last->link->opt); } } @@ -678,7 +678,7 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit) bvresetall(avarinit); arch.proginfo(&info, prog); - if(prog->as == arch.ARET) { + if(prog->as == ARET) { // Return instructions implicitly read all the arguments. For // the sake of correctness, out arguments must be read. For the // sake of backtrace quality, we read in arguments as well. @@ -711,7 +711,7 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit) } return; } - if(prog->as == arch.ATEXT) { + if(prog->as == ATEXT) { // A text instruction marks the entry point to a function and // the definition point of all in arguments. for(i = 0; i < arraylength(vars); i++) { @@ -764,9 +764,9 @@ Next: if(pos >= arraylength(vars) || *(Node**)arrayget(vars, pos) != to->node) fatal("bad bookkeeping in liveness %N %d", to->node, pos); if(((Node*)(to->node))->addrtaken) { - if(prog->as != arch.AVARKILL) + if(prog->as != AVARKILL) bvset(avarinit, pos); - if(prog->as == arch.AVARDEF || prog->as == arch.AVARKILL) + if(prog->as == AVARDEF || prog->as == AVARKILL) bvset(varkill, pos); } else { // RightRead is a read, obviously. @@ -780,7 +780,7 @@ Next: if((info.flags & RightRead) || (info.flags & (RightAddr|RightWrite)) == RightAddr) bvset(uevar, pos); if(info.flags & RightWrite) - if(to->node != nil && (!arch.isfat(((Node*)(to->node))->type) || prog->as == arch.AVARDEF)) + if(to->node != nil && (!arch.isfat(((Node*)(to->node))->type) || prog->as == AVARDEF)) bvset(varkill, pos); } } @@ -952,7 +952,7 @@ livenessprintblock(Liveness *lv, BasicBlock *bb) print("\tprog:\n"); for(prog = bb->first;; prog = prog->link) { print("\t\t%P", prog); - if(prog->as == arch.APCDATA && prog->from.offset == PCDATA_StackMapIndex) { + if(prog->as == APCDATA && prog->from.offset == PCDATA_StackMapIndex) { pos = prog->to.offset; live = *(Bvec**)arrayget(lv->livepointers, pos); print(" "); @@ -1048,7 +1048,7 @@ checkptxt(Node *fn, Prog *firstp) for(p = firstp; p != P; p = p->link) { if(0) print("analyzing '%P'\n", p); - if(p->as != arch.ADATA && p->as != arch.AGLOBL && p->as != arch.ANAME && p->as != arch.ASIGNAME && p->as != arch.ATYPE) + if(p->as != ADATA && p->as != AGLOBL && p->as != ATYPE) checkprog(fn, p); } } @@ -1233,7 +1233,7 @@ newpcdataprog(Prog *prog, int32 index) nodconst(&from, types[TINT32], PCDATA_StackMapIndex); nodconst(&to, types[TINT32], index); - pcdata = unlinkedprog(arch.APCDATA); + pcdata = unlinkedprog(APCDATA); pcdata->lineno = prog->lineno; arch.naddr(&from, &pcdata->from, 0); arch.naddr(&to, &pcdata->to, 0); @@ -1245,7 +1245,7 @@ newpcdataprog(Prog *prog, int32 index) static int issafepoint(Prog *prog) { - return prog->as == arch.ATEXT || prog->as == arch.ACALL; + return prog->as == ATEXT || prog->as == ACALL; } // Initializes the sets for solving the live variables. Visits all the @@ -1542,7 +1542,7 @@ livenessepilogue(Liveness *lv) // walk backward, emit pcdata and populate the maps pos = bb->lastbitmapindex; if(pos < 0) { - // the first block we encounter should have the arch.ATEXT so + // the first block we encounter should have the ATEXT so // at no point should pos ever be less than zero. fatal("livenessepilogue"); } @@ -1569,7 +1569,7 @@ livenessepilogue(Liveness *lv) // Useful sanity check: on entry to the function, // the only things that can possibly be live are the // input parameters. - if(p->as == arch.ATEXT) { + if(p->as == ATEXT) { for(j = 0; j < liveout->n; j++) { if(!bvget(liveout, j)) continue; @@ -1587,7 +1587,7 @@ livenessepilogue(Liveness *lv) // Ambiguously live variables are zeroed immediately after // function entry. Mark them live for all the non-entry bitmaps // so that GODEBUG=gcdead=1 mode does not poison them. - if(p->as == arch.ACALL) + if(p->as == ACALL) bvor(locals, locals, ambig); // Show live pointer bitmaps. @@ -1597,9 +1597,9 @@ livenessepilogue(Liveness *lv) if(msg != nil) { fmtstrinit(&fmt); fmtprint(&fmt, "%L: live at ", p->lineno); - if(p->as == arch.ACALL && p->to.node) + if(p->as == ACALL && p->to.node) fmtprint(&fmt, "call to %s:", ((Node*)(p->to.node))->sym->name); - else if(p->as == arch.ACALL) + else if(p->as == ACALL) fmtprint(&fmt, "indirect call:"); else fmtprint(&fmt, "entry to %s:", ((Node*)(p->from.node))->sym->name); @@ -1620,7 +1620,7 @@ livenessepilogue(Liveness *lv) // Only CALL instructions need a PCDATA annotation. // The TEXT instruction annotation is implicit. - if(p->as == arch.ACALL) { + if(p->as == ACALL) { if(isdeferreturn(p)) { // runtime.deferreturn modifies its return address to return // back to the CALL, not to the subsequent instruction. @@ -1768,7 +1768,7 @@ livenesscompact(Liveness *lv) // Rewrite PCDATA instructions to use new numbering. for(p=lv->ptxt; p != P; p=p->link) { - if(p->as == arch.APCDATA && p->from.offset == PCDATA_StackMapIndex) { + if(p->as == APCDATA && p->from.offset == PCDATA_StackMapIndex) { i = p->to.offset; if(i >= 0) p->to.offset = remap[i]; @@ -1855,7 +1855,7 @@ livenessprintdebug(Liveness *lv) // program listing, with individual effects listed for(p = bb->first;; p = p->link) { print("%P\n", p); - if(p->as == arch.APCDATA && p->from.offset == PCDATA_StackMapIndex) + if(p->as == APCDATA && p->from.offset == PCDATA_StackMapIndex) pcdata = p->to.offset; progeffects(p, lv->vars, uevar, varkill, avarinit); printed = 0; diff --git a/src/cmd/gc/popt.c b/src/cmd/gc/popt.c index a86d3dfa15..f71702431a 100644 --- a/src/cmd/gc/popt.c +++ b/src/cmd/gc/popt.c @@ -81,7 +81,7 @@ chasejmp(Prog *p, int *jmploop) int n; n = 0; - while(p != P && p->as == arch.AJMP && p->to.type == TYPE_BRANCH) { + while(p != P && p->as == AJMP && p->to.type == TYPE_BRANCH) { if(++n > 10) { *jmploop = 1; break; @@ -112,9 +112,9 @@ mark(Prog *firstp) if(p->opt != dead) break; p->opt = alive; - if(p->as != arch.ACALL && p->to.type == TYPE_BRANCH && p->to.u.branch) + if(p->as != ACALL && p->to.type == TYPE_BRANCH && p->to.u.branch) mark(p->to.u.branch); - if(p->as == arch.AJMP || p->as == arch.ARET || p->as == arch.AUNDEF) + if(p->as == AJMP || p->as == ARET || p->as == AUNDEF) break; } } @@ -133,7 +133,7 @@ fixjmp(Prog *firstp) for(p=firstp; p; p=p->link) { if(debug['R'] && debug['v']) print("%P\n", p); - if(p->as != arch.ACALL && p->to.type == TYPE_BRANCH && p->to.u.branch && p->to.u.branch->as == arch.AJMP) { + if(p->as != ACALL && p->to.type == TYPE_BRANCH && p->to.u.branch && p->to.u.branch->as == AJMP) { p->to.u.branch = chasejmp(p->to.u.branch, &jmploop); if(debug['R'] && debug['v']) print("->%P\n", p); @@ -150,8 +150,8 @@ fixjmp(Prog *firstp) last = nil; for(p=firstp; p; p=p->link) { if(p->opt == dead) { - if(p->link == P && p->as == arch.ARET && last && last->as != arch.ARET) { - // This is the final arch.ARET, and the code so far doesn't have one. + if(p->link == P && p->as == ARET && last && last->as != ARET) { + // This is the final ARET, and the code so far doesn't have one. // Let it stay. The register allocator assumes that all live code in // the function can be traversed by starting at all the RET instructions // and following predecessor links. If we remove the final RET, @@ -176,7 +176,7 @@ fixjmp(Prog *firstp) if(!jmploop) { last = nil; for(p=firstp; p; p=p->link) { - if(p->as == arch.AJMP && p->to.type == TYPE_BRANCH && p->to.u.branch == p->link) { + if(p->as == AJMP && p->to.type == TYPE_BRANCH && p->to.u.branch == p->link) { if(debug['R'] && debug['v']) print("del %P\n", p); continue; @@ -620,7 +620,7 @@ mergetemp(Prog *firstp) p = r->f.prog; arch.proginfo(&info, p); if(p->to.node == v->node && (info.flags & RightWrite) && !(info.flags & RightRead)) { - p->as = arch.ANOP; + p->as = ANOP; p->to = zprog.to; v->removed = 1; if(Debug) @@ -813,7 +813,7 @@ varkillwalk(TempVar *v, TempFlow *r0, uint32 gen) v->end = p->pc; if(v->start > p->pc) v->start = p->pc; - if(p->as == arch.ARET || (p->as == arch.AVARKILL && p->to.node == v->node)) + if(p->as == ARET || (p->as == AVARKILL && p->to.node == v->node)) break; } @@ -865,7 +865,7 @@ nilopt(Prog *firstp) nkill = 0; for(r = (NilFlow*)g->start; r != nil; r = (NilFlow*)r->f.link) { p = r->f.prog; - if(p->as != arch.ACHECKNIL || !arch.regtyp(&p->from)) + if(p->as != ACHECKNIL || !arch.regtyp(&p->from)) continue; ncheck++; if(arch.stackaddr(&p->from)) { @@ -916,7 +916,7 @@ nilwalkback(NilFlow *rcheck) // without first finding the check, so this one is unchecked. return; } - if(r != rcheck && p->as == arch.ACHECKNIL && arch.sameaddr(&p->from, &rcheck->f.prog->from)) { + if(r != rcheck && p->as == ACHECKNIL && arch.sameaddr(&p->from, &rcheck->f.prog->from)) { rcheck->kill = 1; return; } @@ -937,7 +937,7 @@ nilwalkback(NilFlow *rcheck) // If same check, stop this loop but still check // alternate predecessors up to this point. - if(r1 != rcheck && p->as == arch.ACHECKNIL && arch.sameaddr(&p->from, &rcheck->f.prog->from)) + if(r1 != rcheck && p->as == ACHECKNIL && arch.sameaddr(&p->from, &rcheck->f.prog->from)) break; arch.proginfo(&info, p); @@ -993,7 +993,7 @@ nilwalkfwd(NilFlow *rcheck) } // Stop if another nil check happens. - if(p->as == arch.ACHECKNIL) + if(p->as == ACHECKNIL) return; // Stop if value is lost. if((info.flags & RightWrite) && arch.sameaddr(&p->to, &rcheck->f.prog->from)) |
