Commit 63e1b714 authored by Kai Backman's avatar Kai Backman

Rebooted 5g effort from 6g. Tons of minor fixes and tweaks to

get the code going.

R=rsc
APPROVED=rsc
DELTA=4752  (1723 added, 948 deleted, 2081 changed)
OCL=29403
CL=29530
parent 97fe5572
......@@ -11,18 +11,16 @@ HFILES=\
../gc/go.h\
../5l/5.out.h\
gg.h\
# opt.h\
opt.h\
OFILES=\
../5l/enam.$O\
list.$O\
align.$O\
obj.$O\
gen.$O\
gsubr.$O\
gobj.$O\
galign.$O\
ggen.$O\
cgen.$O\
# peep.$O\
# reg.$O\
gsubr.$O\
../5l/enam.$O\
LIB=\
../gc/gc.a$O
......
This diff is collapsed.
......@@ -16,7 +16,7 @@ Typedef typedefs[] =
{
"int", TINT, TINT32,
"uint", TUINT, TUINT32,
"uintptr", TUINTPTR, TUINT32,
"uintptr", TUINTPTR, TUINT64,
"float", TFLOAT, TFLOAT32,
0
};
......@@ -24,8 +24,8 @@ Typedef typedefs[] =
void
betypeinit(void)
{
maxround = 4;
widthptr = 4;
maxround = 8;
widthptr = 8;
zprog.link = P;
zprog.as = AGOK;
......
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#undef EXTERN
#define EXTERN
#include "gg.h"
void
compile(Node *fn)
{
Plist *pl;
Node nod1;
Prog *ptxt;
int32 lno;
Type *t;
Iter save;
if(newproc == N) {
newproc = sysfunc("newproc");
deferproc = sysfunc("deferproc");
deferreturn = sysfunc("deferreturn");
throwindex = sysfunc("throwindex");
throwreturn = sysfunc("throwreturn");
}
if(fn->nbody == N)
return;
// set up domain for labels
labellist = L;
lno = setlineno(fn);
curfn = fn;
dowidth(curfn->type);
if(curfn->type->outnamed) {
// add clearing of the output parameters
t = structfirst(&save, getoutarg(curfn->type));
while(t != T) {
if(t->nname != N)
curfn->nbody = list(nod(OAS, t->nname, N), curfn->nbody);
t = structnext(&save);
}
}
hasdefer = 0;
walk(curfn);
if(nerrors != 0)
goto ret;
allocparams();
continpc = P;
breakpc = P;
pl = newplist();
pl->name = curfn->nname;
pl->locals = autodcl;
nodconst(&nod1, types[TINT32], 0);
ptxt = gins(ATEXT, curfn->nname, &nod1);
afunclit(&ptxt->from);
// ginit();
gen(curfn->enter);
gen(curfn->nbody);
// gclean();
checklabels();
// if(curfn->type->outtuple != 0)
// ginscall(throwreturn, 0);
// if(hasdefer)
// ginscall(deferreturn, 0);
pc->as = ARET; // overwrite AEND
pc->lineno = lineno;
// if(!debug['N'] || debug['R'] || debug['P'])
// regopt(ptxt);
// fill in argument size
ptxt->to.offset2 = rnd(curfn->type->argwid, maxround);
// fill in final stack size
if(stksize > maxstksize)
maxstksize = stksize;
ptxt->to.offset = rnd(maxstksize+maxarg, maxround);
maxstksize = 0;
if(debug['f'])
frame(0);
ret:
lineno = lno;
}
void
clearfat(Node *nl)
{
fatal("clearfat");
}
/*
* generate:
* call f
* proc=0 normal call
* proc=1 goroutine run in new proc
* proc=2 defer call save away stack
*/
void
ginscall(Node *f, int proc)
{
// Prog *p;
// Node reg, con;
// switch(proc) {
// default:
// fatal("ginscall: bad proc %d", proc);
// break;
// case 0: // normal call
// p = gins(ACALL, N, f);
// afunclit(&p->to);
// break;
// case 1: // call in new proc (go)
// case 2: // defered call (defer)
// nodreg(&reg, types[TINT32], D_AX);
// gins(APUSHL, f, N);
// nodconst(&con, types[TINT32], argsize(f->type));
// gins(APUSHL, &con, N);
// if(proc == 1)
// ginscall(newproc, 0);
// else
// ginscall(deferproc, 0);
// gins(APOPL, N, &reg);
// gins(APOPL, N, &reg);
// break;
// }
}
/*
* n is call to interface method.
* generate res = n.
*/
void
cgen_callinter(Node *n, Node *res, int proc)
{
fatal("cgen_call");
}
/*
* generate function call;
* proc=0 normal call
* proc=1 goroutine run in new proc
* proc=2 defer call save away stack
*/
void
cgen_call(Node *n, int proc)
{
fatal("cgen_call_unimplemented");
// Type *t;
// Node nod, afun;
// if(n == N)
// return;
// if(n->left->ullman >= UINF) {
// // if name involves a fn call
// // precompute the address of the fn
// tempalloc(&afun, types[tptr]);
// cgen(n->left, &afun);
// }
// gen(n->right); // assign the args
// t = n->left->type;
// setmaxarg(t);
// // call tempname pointer
// if(n->left->ullman >= UINF) {
// regalloc(&nod, types[tptr], N);
// cgen_as(&nod, &afun);
// tempfree(&afun);
// nod.type = t;
// ginscall(&nod, proc);
// regfree(&nod);
// return;
// }
// // call pointer
// if(n->left->op != ONAME || n->left->class != PFUNC) {
// regalloc(&nod, types[tptr], N);
// cgen_as(&nod, n->left);
// nod.type = t;
// ginscall(&nod, proc);
// regfree(&nod);
// return;
// }
// // call direct
// n->left->method = 1;
// ginscall(n->left, proc);
}
/*
* call to n has already been generated.
* generate:
* res = return value from call.
*/
void
cgen_callret(Node *n, Node *res)
{
fatal("cgen_callret_unimplemented");
// Node nod;
// Type *fp, *t;
// Iter flist;
// t = n->left->type;
// if(t->etype == TPTR32 || t->etype == TPTR64)
// t = t->type;
// fp = structfirst(&flist, getoutarg(t));
// if(fp == T)
// fatal("cgen_callret: nil");
// memset(&nod, 0, sizeof(nod));
// nod.op = OINDREG;
// nod.val.u.reg = D_SP;
// nod.addable = 1;
// nod.xoffset = fp->width;
// nod.type = fp->type;
// cgen_as(res, &nod);
}
/*
* call to n has already been generated.
* generate:
* res = &return value from call.
*/
void
cgen_aret(Node *n, Node *res)
{
// Node nod1, nod2;
// Type *fp, *t;
// Iter flist;
// t = n->left->type;
// if(isptr[t->etype])
// t = t->type;
// fp = structfirst(&flist, getoutarg(t));
// if(fp == T)
// fatal("cgen_aret: nil");
// memset(&nod1, 0, sizeof(nod1));
// nod1.op = OINDREG;
// nod1.val.u.reg = D_SP;
// nod1.addable = 1;
// nod1.xoffset = fp->width;
// nod1.type = fp->type;
// if(res->op != OREGISTER) {
// regalloc(&nod2, types[tptr], res);
// gins(ALEAL, &nod1, &nod2);
// gins(AMOVL, &nod2, res);
// regfree(&nod2);
// } else
// gins(ALEAL, &nod1, res);
}
/*
* generate return.
* n->left is assignments to return values.
*/
void
cgen_ret(Node *n)
{
gen(n->left); // copy out args
if(hasdefer)
ginscall(deferreturn, 0);
gins(ARET, N, N);
}
/*
* generate += *= etc.
*/
void
cgen_asop(Node *n)
{
fatal("cgen_asop");
}
/*
* generate division according to op, one of:
* res = nl / nr
* res = nl % nr
*/
void
cgen_div(int op, Node *nl, Node *nr, Node *res)
{
fatal("cgen_div");
}
/*
* generate shift according to op, one of:
* res = nl << nr
* res = nl >> nr
*/
void
cgen_shift(int op, Node *nl, Node *nr, Node *res)
{
fatal("cgen_shift");
}
/*
* generate byte multiply:
* res = nl * nr
* no byte multiply instruction so have to do
* 16-bit multiply and take bottom half.
*/
void
cgen_bmul(int op, Node *nl, Node *nr, Node *res)
{
fatal("cgen_bmul");
}
......@@ -19,12 +19,12 @@ struct Addr
{
int32 offset;
int32 offset2;
double dval;
Prog* branch;
char sval[NSNAME];
Sym* sym;
int width;
uchar type;
uchar index;
uchar etype;
......@@ -47,7 +47,7 @@ EXTERN Biobuf* bout;
EXTERN int32 dynloc;
EXTERN uchar reg[D_NONE];
EXTERN int32 pcloc; // instruction counter
/*EXTERN String emptystring;*/
EXTERN Strlit emptystring;
extern char* anames[];
EXTERN Hist* hist;
EXTERN Prog zprog;
......@@ -57,7 +57,6 @@ EXTERN Node* deferproc;
EXTERN Node* deferreturn;
EXTERN Node* throwindex;
EXTERN Node* throwreturn;
EXTERN int maxstksize;
/*
* gen.c
......@@ -80,6 +79,7 @@ void genconv(Type*, Type*);
void allocparams(void);
void checklabels();
void ginscall(Node*, int);
int gen_as_init(Node*, Node*);
/*
* cgen
......@@ -94,8 +94,6 @@ Prog* gins(int, Node*, Node*);
int samaddr(Node*, Node*);
void naddr(Node*, Addr*);
void cgen_aret(Node*, Node*);
int cgen64(Node*, Node*);
int is64(Type*);
/*
* gsubr.c
......@@ -117,19 +115,22 @@ void ginit(void);
void gclean(void);
void regalloc(Node*, Type*, Node*);
void regfree(Node*);
void tempalloc(Node*, Type*);
void tempfree(Node*);
Node* nodarg(Type*, int);
void nodreg(Node*, Type*, int);
void nodindreg(Node*, Type*, int);
void nodconst(Node*, Type*, int64);
void gconreg(int, vlong, int);
void buildtxt(void);
Plist* newplist(void);
int isfat(Type*);
void sudoclean(void);
int sudoaddable(Node*, Addr*);
int sudoaddable(int, Node*, Addr*);
void afunclit(Addr*);
void datagostring(Strlit*, Addr*);
/*
* obj.c
*/
void datastring(char*, int, Addr*);
/*
* list.c
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -80,19 +80,19 @@ Dconv(Fmt *fp)
a = va_arg(fp->args, Addr*);
i = a->type;
// TODO(kaib): add back
// if(i >= D_INDIR) {
// if(a->offset)
// snprint(str, sizeof(str), "%ld(%R)", a->offset, i-D_INDIR);
// else
// snprint(str, sizeof(str), "(%R)", i-D_INDIR);
// goto brk;
// }
// TODO(kaib): Add back
// if(i >= D_INDIR) {
// if(a->offset)
// snprint(str, sizeof(str), "%d(%R)", a->offset, i-D_INDIR);
// else
// snprint(str, sizeof(str), "(%R)", i-D_INDIR);
// goto brk;
// }
switch(i) {
default:
if(a->offset)
snprint(str, sizeof(str), "$%ld,%R", a->offset, i);
snprint(str, sizeof(str), "$%d,%R", a->offset, i);
else
snprint(str, sizeof(str), "%R", i);
break;
......@@ -102,33 +102,33 @@ Dconv(Fmt *fp)
break;
case D_BRANCH:
snprint(str, sizeof(str), "%ld", a->branch->loc);
snprint(str, sizeof(str), "%d", a->branch->loc);
break;
case D_EXTERN:
snprint(str, sizeof(str), "%S+%ld(SB)", a->sym, a->offset);
snprint(str, sizeof(str), "%S+%d(SB)", a->sym, a->offset);
break;
case D_STATIC:
snprint(str, sizeof(str), "%S<>+%ld(SB)", a->sym, a->offset);
snprint(str, sizeof(str), "%S<>+%d(SB)", a->sym, a->offset);
break;
case D_AUTO:
snprint(str, sizeof(str), "%S+%ld(SP)", a->sym, a->offset);
snprint(str, sizeof(str), "%S+%d(SP)", a->sym, a->offset);
break;
case D_PARAM:
snprint(str, sizeof(str), "%S+%ld(FP)", a->sym, a->offset);
snprint(str, sizeof(str), "%S+%d(FP)", a->sym, a->offset);
break;
case D_CONST:
if(fp->flags & FmtLong) {
d1 = a->offset;
d2 = a->offset2;
d1 = a->offset & 0xffffffffLL;
d2 = (a->offset>>32) & 0xffffffffLL;
snprint(str, sizeof(str), "$%lud-%lud", (ulong)d1, (ulong)d2);
break;
}
snprint(str, sizeof(str), "$%ld", a->offset);
snprint(str, sizeof(str), "$%d", a->offset);
break;
case D_FCONST:
......@@ -139,14 +139,14 @@ Dconv(Fmt *fp)
snprint(str, sizeof(str), "$\"%Y\"", a->sval);
break;
// TODO(kaib): add back
// case D_ADDR:
// a->type = a->index;
// a->index = D_NONE;
// snprint(str, sizeof(str), "$%D", a);
// a->index = a->type;
// a->type = D_ADDR;
// goto conv;
// TODO(kaib): Add back
// case D_ADDR:
// a->type = a->index;
// a->index = D_NONE;
// snprint(str, sizeof(str), "$%D", a);
// a->index = a->type;
// a->type = D_ADDR;
// goto conv;
}
brk:
if(a->index != D_NONE) {
......@@ -159,75 +159,23 @@ conv:
static char* regstr[] =
{
"AL", /* [D_AL] */
"CL",
"DL",
"BL",
"AH", /* [D_AH] */
"CH",
"DH",
"BH",
"AX", /* [D_AX] */
"CX",
"DX",
"BX",
"SP",
"BP",
"SI",
"DI",
"F0", /* [D_F0] */
"F1",
"F2",
"F3",
"F4",
"F5",
"F6",
"F7",
"CS", /* [D_CS] */
"SS",
"DS",
"ES",
"FS",
"GS",
"GDTR", /* [D_GDTR] */
"IDTR", /* [D_IDTR] */
"LDTR", /* [D_LDTR] */
"MSW", /* [D_MSW] */
"TASK", /* [D_TASK] */
"CR0", /* [D_CR] */
"CR1",
"CR2",
"CR3",
"CR4",
"CR5",
"CR6",
"CR7",
"DR0", /* [D_DR] */
"DR1",
"DR2",
"DR3",
"DR4",
"DR5",
"DR6",
"DR7",
"TR0", /* [D_TR] */
"TR1",
"TR2",
"TR3",
"TR4",
"TR5",
"TR6",
"TR7",
"NONE", /* [D_NONE] */
"R0",
"R1",
"R2",
"R3",
"R4",
"R5",
"R6",
"R7",
"R8",
"R9",
"R10",
"R11",
"R12",
"R13",
"R14",
"R15",
"NONE",
};
int
......
// Inferno utils/5c/gc.h
// http://code.google.com/p/inferno-os/source/browse/utils/5c/gc.h
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#define Z N
#define Adr Addr
#define D_HI D_NONE
#define D_LO D_NONE
#define isregtype(t) ((t)>= D_AX && (t)<=D_R15)
#define BLOAD(r) band(bnot(r->refbehind), r->refahead)
#define BSTORE(r) band(bnot(r->calbehind), r->calahead)
#define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z])
#define STORE(r) (~r->calbehind.b[z] & r->calahead.b[z])
#define CLOAD 5
#define CREF 5
#define CINF 1000
#define LOOP 3
typedef struct Reg Reg;
typedef struct Rgn Rgn;
struct Reg
{
Bits set;
Bits use1;
Bits use2;
Bits refbehind;
Bits refahead;
Bits calbehind;
Bits calahead;
Bits regdiff;
Bits act;
int32 regu; // register used bitmap
int32 rpo; // reverse post ordering
int32 active;
uint16 loop; // x5 for every loop
uchar refset; // diagnostic generated
Reg* p1;
Reg* p2;
Reg* p2link;
Reg* s1;
Reg* s2;
Reg* link;
Prog* prog;
};
#define R ((Reg*)0)
#define NRGN 600
struct Rgn
{
Reg* enter;
short cost;
short varno;
short regno;
};
EXTERN int32 exregoffset; // not set
EXTERN int32 exfregoffset; // not set
EXTERN Reg* firstr;
EXTERN Reg* lastr;
EXTERN Reg zreg;
EXTERN Reg* freer;
EXTERN Reg** rpo2r;
EXTERN Rgn region[NRGN];
EXTERN Rgn* rgp;
EXTERN int nregion;
EXTERN int nvar;
EXTERN int32 regbits;
EXTERN int32 exregbits;
EXTERN Bits externs;
EXTERN Bits params;
EXTERN Bits consts;
EXTERN Bits addrs;
EXTERN Bits ovar;
EXTERN int change;
EXTERN int32 maxnr;
EXTERN int32* idom;
EXTERN struct
{
int32 ncvtreg;
int32 nspill;
int32 nreload;
int32 ndelmov;
int32 nvar;
int32 naddr;
} ostats;
/*
* reg.c
*/
Reg* rega(void);
int rcmp(const void*, const void*);
void regopt(Prog*);
void addmove(Reg*, int, int, int);
Bits mkvar(Reg*, Adr*);
void prop(Reg*, Bits, Bits);
void loopit(Reg*, int32);
void synch(Reg*, Bits);
uint32 allreg(uint32, Rgn*);
void paint1(Reg*, int);
uint32 paint2(Reg*, int);
void paint3(Reg*, int, int32, int);
void addreg(Adr*, int);
void dumpit(char *str, Reg *r0);
int noreturn(Prog *p);
/*
* peep.c
*/
void peep(void);
void excise(Reg*);
Reg* uniqp(Reg*);
Reg* uniqs(Reg*);
int regtyp(Adr*);
int anyvar(Adr*);
int subprop(Reg*);
int copyprop(Reg*);
int copy1(Adr*, Adr*, Reg*, int);
int copyu(Prog*, Adr*, Adr*);
int copyas(Adr*, Adr*);
int copyau(Adr*, Adr*);
int copysub(Adr*, Adr*, Adr*, int);
int copysub1(Prog*, Adr*, Adr*, int);
int32 RtoB(int);
int32 FtoB(int);
int BtoR(int32);
int BtoF(int32);
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