mirror of
https://github.com/golang/go
synced 2024-11-19 21:34:45 -07:00
[dev.power64] cmd/9g: first check point
LGTM=rsc R=rsc, iant CC=golang-codereviews https://golang.org/cl/123170043
This commit is contained in:
parent
552d8b79dd
commit
4928b2074b
1742
src/cmd/9g/cgen.c
Normal file
1742
src/cmd/9g/cgen.c
Normal file
File diff suppressed because it is too large
Load Diff
54
src/cmd/9g/galign.c
Normal file
54
src/cmd/9g/galign.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include "gg.h"
|
||||||
|
|
||||||
|
int thechar = '9';
|
||||||
|
char* thestring = "power64";
|
||||||
|
LinkArch* thelinkarch;
|
||||||
|
|
||||||
|
void
|
||||||
|
linkarchinit(void)
|
||||||
|
{
|
||||||
|
thestring = getgoarch();
|
||||||
|
if(strcmp(thestring, "power64le") == 0)
|
||||||
|
thelinkarch = &linkpower64le;
|
||||||
|
else
|
||||||
|
thelinkarch = &linkpower64;
|
||||||
|
}
|
||||||
|
|
||||||
|
vlong MAXWIDTH = 1LL<<50;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* go declares several platform-specific type aliases:
|
||||||
|
* int, uint, float, and uintptr
|
||||||
|
*/
|
||||||
|
Typedef typedefs[] =
|
||||||
|
{
|
||||||
|
{"int", TINT, TINT64},
|
||||||
|
{"uint", TUINT, TUINT64},
|
||||||
|
{"uintptr", TUINTPTR, TUINT64},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
betypeinit(void)
|
||||||
|
{
|
||||||
|
widthptr = 8;
|
||||||
|
widthint = 8;
|
||||||
|
widthreg = 8;
|
||||||
|
|
||||||
|
zprog.link = P;
|
||||||
|
zprog.as = AGOK;
|
||||||
|
zprog.reg = NREG;
|
||||||
|
zprog.from.name = D_NONE;
|
||||||
|
zprog.from.type = D_NONE;
|
||||||
|
zprog.from.reg = NREG;
|
||||||
|
zprog.to = zprog.from;
|
||||||
|
zprog.from3 = zprog.from;
|
||||||
|
|
||||||
|
listinit9();
|
||||||
|
}
|
119
src/cmd/9g/gg.h
Normal file
119
src/cmd/9g/gg.h
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
#ifndef EXTERN
|
||||||
|
#define EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../gc/go.h"
|
||||||
|
#include "../9l/9.out.h"
|
||||||
|
|
||||||
|
// TODO(minux): Remove when no longer used.
|
||||||
|
#define noimpl sysfatal("%s not implemented (%s:%d).", __func__, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
#define TEXTFLAG reg
|
||||||
|
|
||||||
|
EXTERN int32 dynloc;
|
||||||
|
EXTERN uchar reg[NREG+NFREG];
|
||||||
|
EXTERN int32 pcloc; // instruction counter
|
||||||
|
EXTERN Strlit emptystring;
|
||||||
|
EXTERN Prog zprog;
|
||||||
|
EXTERN Node* newproc;
|
||||||
|
EXTERN Node* deferproc;
|
||||||
|
EXTERN Node* deferreturn;
|
||||||
|
EXTERN Node* panicindex;
|
||||||
|
EXTERN Node* panicslice;
|
||||||
|
EXTERN Node* panicdiv;
|
||||||
|
EXTERN Node* throwreturn;
|
||||||
|
extern vlong unmappedzero;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ggen.c
|
||||||
|
*/
|
||||||
|
void compile(Node*);
|
||||||
|
void gen(Node*);
|
||||||
|
Node* lookdot(Node*, Node*, int);
|
||||||
|
void cgen_as(Node*, Node*);
|
||||||
|
void cgen_callmeth(Node*, int);
|
||||||
|
void cgen_callinter(Node*, Node*, int);
|
||||||
|
void cgen_proc(Node*, int);
|
||||||
|
void cgen_callret(Node*, Node*);
|
||||||
|
void cgen_div(int, Node*, Node*, Node*);
|
||||||
|
void cgen_hmul(Node*, Node*, Node*);
|
||||||
|
void cgen_shift(int, int, Node*, Node*, Node*);
|
||||||
|
void cgen_dcl(Node*);
|
||||||
|
int needconvert(Type*, Type*);
|
||||||
|
void genconv(Type*, Type*);
|
||||||
|
void allocparams(void);
|
||||||
|
void checklabels(void);
|
||||||
|
void ginscall(Node*, int);
|
||||||
|
int gen_as_init(Node*);
|
||||||
|
void clearslim(Node*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cgen.c
|
||||||
|
*/
|
||||||
|
void agen(Node*, Node*);
|
||||||
|
void agenr(Node*, Node*, Node*);
|
||||||
|
void cgenr(Node*, Node*, Node*);
|
||||||
|
void igen(Node*, Node*, Node*);
|
||||||
|
vlong fieldoffset(Type*, Node*);
|
||||||
|
void sgen(Node*, Node*, int64);
|
||||||
|
void gmove(Node*, Node*);
|
||||||
|
Prog* gins(int, Node*, Node*);
|
||||||
|
int samaddr(Node*, Node*);
|
||||||
|
void naddr(Node*, Addr*, int);
|
||||||
|
void cgen_aret(Node*, Node*);
|
||||||
|
int componentgen(Node*, Node*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gsubr.c
|
||||||
|
*/
|
||||||
|
void clearp(Prog*);
|
||||||
|
Prog* gbranch(int, Type*, int);
|
||||||
|
Prog* prog(int);
|
||||||
|
void gconv(int, int);
|
||||||
|
int conv2pt(Type*);
|
||||||
|
vlong convvtox(vlong, int);
|
||||||
|
void fnparam(Type*, int, int);
|
||||||
|
Prog* gop(int, Node*, Node*, Node*);
|
||||||
|
int optoas(int, Type*);
|
||||||
|
void ginit(void);
|
||||||
|
void gclean(void);
|
||||||
|
void regalloc(Node*, Type*, Node*);
|
||||||
|
void regfree(Node*);
|
||||||
|
Node* nodarg(Type*, int);
|
||||||
|
void nodreg(Node*, Type*, int);
|
||||||
|
void nodindreg(Node*, Type*, int);
|
||||||
|
void ginscon(int, vlong, Node*);
|
||||||
|
void buildtxt(void);
|
||||||
|
Plist* newplist(void);
|
||||||
|
int isfat(Type*);
|
||||||
|
void sudoclean(void);
|
||||||
|
int sudoaddable(int, Node*, Addr*);
|
||||||
|
void afunclit(Addr*, Node*);
|
||||||
|
void nodfconst(Node*, Type*, Mpflt*);
|
||||||
|
void gtrack(Sym*);
|
||||||
|
void gargsize(vlong);
|
||||||
|
void fixlargeoffset(Node *n);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cplx.c
|
||||||
|
*/
|
||||||
|
int complexop(Node*, Node*);
|
||||||
|
void complexmove(Node*, Node*);
|
||||||
|
void complexgen(Node*, Node*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gobj.c
|
||||||
|
*/
|
||||||
|
void datastring(char*, int, Addr*);
|
||||||
|
void datagostring(Strlit*, Addr*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* list.c
|
||||||
|
*/
|
||||||
|
void listinit(void);
|
||||||
|
|
||||||
|
void zaddr(Biobuf*, Addr*, int, int);
|
1028
src/cmd/9g/ggen.c
Normal file
1028
src/cmd/9g/ggen.c
Normal file
File diff suppressed because it is too large
Load Diff
240
src/cmd/9g/gobj.c
Normal file
240
src/cmd/9g/gobj.c
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
// Derived from Inferno utils/6c/swt.c
|
||||||
|
// http://code.google.com/p/inferno-os/source/browse/utils/6c/swt.c
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include "gg.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
dsname(Sym *s, int off, char *t, int n)
|
||||||
|
{
|
||||||
|
Prog *p;
|
||||||
|
|
||||||
|
p = gins(ADATA, N, N);
|
||||||
|
p->from.type = D_OREG;
|
||||||
|
p->from.name = D_EXTERN;
|
||||||
|
p->from.offset = off;
|
||||||
|
p->from.reg = NREG;
|
||||||
|
p->from.sym = linksym(s);
|
||||||
|
|
||||||
|
p->reg = n;
|
||||||
|
|
||||||
|
p->to.type = D_SCONST;
|
||||||
|
p->to.name = D_NONE;
|
||||||
|
p->to.reg = NREG;
|
||||||
|
p->to.offset = 0;
|
||||||
|
memmove(p->to.u.sval, t, n);
|
||||||
|
return off + n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* make a refer to the data s, s+len
|
||||||
|
* emitting DATA if needed.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
datastring(char *s, int len, Addr *a)
|
||||||
|
{
|
||||||
|
Sym *sym;
|
||||||
|
|
||||||
|
sym = stringsym(s, len);
|
||||||
|
a->type = D_OREG;
|
||||||
|
a->name = D_EXTERN;
|
||||||
|
a->etype = simtype[TINT];
|
||||||
|
a->offset = widthptr+widthint; // skip header
|
||||||
|
a->reg = NREG;
|
||||||
|
a->sym = linksym(sym);
|
||||||
|
a->node = sym->def;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* make a refer to the string sval,
|
||||||
|
* emitting DATA if needed.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
datagostring(Strlit *sval, Addr *a)
|
||||||
|
{
|
||||||
|
Sym *sym;
|
||||||
|
|
||||||
|
sym = stringsym(sval->s, sval->len);
|
||||||
|
a->type = D_OREG;
|
||||||
|
a->name = D_EXTERN;
|
||||||
|
a->sym = linksym(sym);
|
||||||
|
a->reg = NREG;
|
||||||
|
a->node = sym->def;
|
||||||
|
a->offset = 0; // header
|
||||||
|
a->etype = TINT32;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdata(Node *nam, Node *nr, int wid)
|
||||||
|
{
|
||||||
|
Prog *p;
|
||||||
|
|
||||||
|
if(nr->op == OLITERAL) {
|
||||||
|
switch(nr->val.ctype) {
|
||||||
|
case CTCPLX:
|
||||||
|
gdatacomplex(nam, nr->val.u.cval);
|
||||||
|
return;
|
||||||
|
case CTSTR:
|
||||||
|
gdatastring(nam, nr->val.u.sval);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p = gins(ADATA, nam, nr);
|
||||||
|
p->reg = wid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdatacomplex(Node *nam, Mpcplx *cval)
|
||||||
|
{
|
||||||
|
Prog *p;
|
||||||
|
int w;
|
||||||
|
|
||||||
|
w = cplxsubtype(nam->type->etype);
|
||||||
|
w = types[w]->width;
|
||||||
|
|
||||||
|
p = gins(ADATA, nam, N);
|
||||||
|
p->reg = w;
|
||||||
|
p->to.type = D_FCONST;
|
||||||
|
p->to.u.dval = mpgetflt(&cval->real);
|
||||||
|
|
||||||
|
p = gins(ADATA, nam, N);
|
||||||
|
p->reg = w;
|
||||||
|
p->from.offset += w;
|
||||||
|
p->to.type = D_FCONST;
|
||||||
|
p->to.u.dval = mpgetflt(&cval->imag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdatastring(Node *nam, Strlit *sval)
|
||||||
|
{
|
||||||
|
Prog *p;
|
||||||
|
Node nod1;
|
||||||
|
|
||||||
|
p = gins(ADATA, nam, N);
|
||||||
|
datastring(sval->s, sval->len, &p->to);
|
||||||
|
p->reg = types[tptr]->width;
|
||||||
|
p->to.type = D_CONST;
|
||||||
|
p->to.etype = simtype[tptr];
|
||||||
|
|
||||||
|
nodconst(&nod1, types[TINT], sval->len);
|
||||||
|
p = gins(ADATA, nam, &nod1);
|
||||||
|
p->reg = widthint;
|
||||||
|
p->from.offset += widthptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dstringptr(Sym *s, int off, char *str)
|
||||||
|
{
|
||||||
|
Prog *p;
|
||||||
|
|
||||||
|
off = rnd(off, widthptr);
|
||||||
|
p = gins(ADATA, N, N);
|
||||||
|
p->from.type = D_OREG;
|
||||||
|
p->from.name = D_EXTERN;
|
||||||
|
p->from.sym = linksym(s);
|
||||||
|
p->from.offset = off;
|
||||||
|
p->reg = widthptr;
|
||||||
|
|
||||||
|
datastring(str, strlen(str)+1, &p->to);
|
||||||
|
p->to.type = D_CONST;
|
||||||
|
p->to.etype = simtype[TINT];
|
||||||
|
off += widthptr;
|
||||||
|
|
||||||
|
return off;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dgostrlitptr(Sym *s, int off, Strlit *lit)
|
||||||
|
{
|
||||||
|
Prog *p;
|
||||||
|
|
||||||
|
if(lit == nil)
|
||||||
|
return duintptr(s, off, 0);
|
||||||
|
|
||||||
|
off = rnd(off, widthptr);
|
||||||
|
p = gins(ADATA, N, N);
|
||||||
|
p->from.type = D_OREG;
|
||||||
|
p->from.name = D_EXTERN;
|
||||||
|
p->from.sym = linksym(s);
|
||||||
|
p->from.offset = off;
|
||||||
|
p->reg = widthptr;
|
||||||
|
datagostring(lit, &p->to);
|
||||||
|
p->to.type = D_CONST;
|
||||||
|
p->to.etype = simtype[TINT];
|
||||||
|
off += widthptr;
|
||||||
|
|
||||||
|
return off;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dgostringptr(Sym *s, int off, char *str)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
Strlit *lit;
|
||||||
|
|
||||||
|
if(str == nil)
|
||||||
|
return duintptr(s, off, 0);
|
||||||
|
|
||||||
|
n = strlen(str);
|
||||||
|
lit = mal(sizeof *lit + n);
|
||||||
|
strcpy(lit->s, str);
|
||||||
|
lit->len = n;
|
||||||
|
return dgostrlitptr(s, off, lit);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dsymptr(Sym *s, int off, Sym *x, int xoff)
|
||||||
|
{
|
||||||
|
Prog *p;
|
||||||
|
|
||||||
|
off = rnd(off, widthptr);
|
||||||
|
|
||||||
|
p = gins(ADATA, N, N);
|
||||||
|
p->from.type = D_OREG;
|
||||||
|
p->from.name = D_EXTERN;
|
||||||
|
p->from.sym = linksym(s);
|
||||||
|
p->from.offset = off;
|
||||||
|
p->reg = widthptr;
|
||||||
|
p->to.type = D_CONST;
|
||||||
|
p->to.name = D_EXTERN;
|
||||||
|
p->to.sym = linksym(x);
|
||||||
|
p->to.offset = xoff;
|
||||||
|
off += widthptr;
|
||||||
|
|
||||||
|
return off;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nopout(Prog *p)
|
||||||
|
{
|
||||||
|
p->as = ANOP;
|
||||||
|
}
|
||||||
|
|
1708
src/cmd/9g/gsubr.c
Normal file
1708
src/cmd/9g/gsubr.c
Normal file
File diff suppressed because it is too large
Load Diff
219
src/cmd/9g/opt.h
Normal file
219
src/cmd/9g/opt.h
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
// Derived from Inferno utils/6c/gc.h
|
||||||
|
// http://code.google.com/p/inferno-os/source/browse/utils/6c/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.
|
||||||
|
|
||||||
|
#include "../gc/popt.h"
|
||||||
|
|
||||||
|
#define Z N
|
||||||
|
#define Adr Addr
|
||||||
|
|
||||||
|
#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;
|
||||||
|
|
||||||
|
/*c2go
|
||||||
|
extern Node *Z;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CLOAD = 5,
|
||||||
|
CREF = 5,
|
||||||
|
CINF = 1000,
|
||||||
|
LOOP = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32 BLOAD(Reg*);
|
||||||
|
uint32 BSTORE(Reg*);
|
||||||
|
uint32 LOAD(Reg*);
|
||||||
|
uint32 STORE(Reg*);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// A Reg is a wrapper around a single Prog (one instruction) that holds
|
||||||
|
// register optimization information while the optimizer runs.
|
||||||
|
// r->prog is the instruction.
|
||||||
|
// r->prog->opt points back to r.
|
||||||
|
struct Reg
|
||||||
|
{
|
||||||
|
Flow f;
|
||||||
|
|
||||||
|
Bits set; // variables written by this instruction.
|
||||||
|
Bits use1; // variables read by prog->from.
|
||||||
|
Bits use2; // variables read by prog->to.
|
||||||
|
|
||||||
|
Bits refbehind;
|
||||||
|
Bits refahead;
|
||||||
|
Bits calbehind;
|
||||||
|
Bits calahead;
|
||||||
|
Bits regdiff;
|
||||||
|
Bits act;
|
||||||
|
|
||||||
|
int32 regu; // register used bitmap
|
||||||
|
};
|
||||||
|
#define R ((Reg*)0)
|
||||||
|
/*c2go extern Reg *R; */
|
||||||
|
|
||||||
|
#define NRGN 600
|
||||||
|
/*c2go enum { NRGN = 600 }; */
|
||||||
|
struct Rgn
|
||||||
|
{
|
||||||
|
Reg* enter;
|
||||||
|
short cost;
|
||||||
|
short varno;
|
||||||
|
short regno;
|
||||||
|
};
|
||||||
|
|
||||||
|
EXTERN int32 exregoffset; // not set
|
||||||
|
EXTERN int32 exfregoffset; // not set
|
||||||
|
EXTERN Reg zreg;
|
||||||
|
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 ivar;
|
||||||
|
EXTERN Bits ovar;
|
||||||
|
EXTERN int change;
|
||||||
|
EXTERN int32 maxnr;
|
||||||
|
|
||||||
|
EXTERN struct
|
||||||
|
{
|
||||||
|
int32 ncvtreg;
|
||||||
|
int32 nspill;
|
||||||
|
int32 nreload;
|
||||||
|
int32 ndelmov;
|
||||||
|
int32 nvar;
|
||||||
|
int32 naddr;
|
||||||
|
} ostats;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reg.c
|
||||||
|
*/
|
||||||
|
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 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 dumpone(Flow*, int);
|
||||||
|
void dumpit(char*, Flow*, int);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* peep.c
|
||||||
|
*/
|
||||||
|
void peep(Prog*);
|
||||||
|
void excise(Flow*);
|
||||||
|
int copyu(Prog*, Adr*, Adr*);
|
||||||
|
|
||||||
|
uint64 RtoB(int);
|
||||||
|
uint64 FtoB(int);
|
||||||
|
int BtoR(uint64);
|
||||||
|
int BtoF(uint64);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prog.c
|
||||||
|
*/
|
||||||
|
typedef struct ProgInfo ProgInfo;
|
||||||
|
struct ProgInfo
|
||||||
|
{
|
||||||
|
uint32 flags; // the bits below
|
||||||
|
uint64 reguse; // required registers used by this instruction
|
||||||
|
uint64 regset; // required registers set by this instruction
|
||||||
|
uint64 regindex; // registers used by addressing mode
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
// Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
|
||||||
|
Pseudo = 1<<1,
|
||||||
|
|
||||||
|
// There's nothing to say about the instruction,
|
||||||
|
// but it's still okay to see.
|
||||||
|
OK = 1<<2,
|
||||||
|
|
||||||
|
// Size of right-side write, or right-side read if no write.
|
||||||
|
SizeB = 1<<3,
|
||||||
|
SizeW = 1<<4,
|
||||||
|
SizeL = 1<<5,
|
||||||
|
SizeQ = 1<<6,
|
||||||
|
SizeF = 1<<7, // float aka float32
|
||||||
|
SizeD = 1<<8, // double aka float64
|
||||||
|
|
||||||
|
// Left side: address taken, read, write.
|
||||||
|
LeftAddr = 1<<9,
|
||||||
|
LeftRead = 1<<10,
|
||||||
|
LeftWrite = 1<<11,
|
||||||
|
|
||||||
|
// Register in middle; never written.
|
||||||
|
RegRead = 1<<12,
|
||||||
|
CanRegRead = 1<<13,
|
||||||
|
|
||||||
|
// Right side: address taken, read, write.
|
||||||
|
RightAddr = 1<<14,
|
||||||
|
RightRead = 1<<15,
|
||||||
|
RightWrite = 1<<16,
|
||||||
|
|
||||||
|
PostInc = 1<<17,
|
||||||
|
|
||||||
|
// Instruction kinds
|
||||||
|
Move = 1<<18, // straight move
|
||||||
|
Conv = 1<<19, // size conversion
|
||||||
|
Cjmp = 1<<20, // conditional jump
|
||||||
|
Break = 1<<21, // breaks control flow (no fallthrough)
|
||||||
|
Call = 1<<22, // function call
|
||||||
|
Jump = 1<<23, // jump
|
||||||
|
Skip = 1<<24, // data instruction
|
||||||
|
};
|
||||||
|
|
||||||
|
void proginfo(ProgInfo*, Prog*);
|
||||||
|
|
||||||
|
// To allow use of AJMP, ACALL, ARET in ../gc/popt.c.
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
AJMP = ABR,
|
||||||
|
ACALL = ABL,
|
||||||
|
ARET = ARETURN,
|
||||||
|
};
|
94
src/cmd/9g/peep.c
Normal file
94
src/cmd/9g/peep.c
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// Derived from Inferno utils/6c/peep.c
|
||||||
|
// http://code.google.com/p/inferno-os/source/browse/utils/6c/peep.c
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include "gg.h"
|
||||||
|
#include "opt.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
peep(Prog *p)
|
||||||
|
{
|
||||||
|
USED(p);
|
||||||
|
// TODO(minux)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
excise(Flow *r)
|
||||||
|
{
|
||||||
|
Prog *p;
|
||||||
|
|
||||||
|
p = r->prog;
|
||||||
|
if(debug['P'] && debug['v'])
|
||||||
|
print("%P ===delete===\n", p);
|
||||||
|
*p = zprog;
|
||||||
|
p->as = ANOP;
|
||||||
|
ostats.ndelmov++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
regtyp(Adr *a)
|
||||||
|
{
|
||||||
|
switch(a->type) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
case D_REG:
|
||||||
|
case D_FREG:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sameaddr(Addr *a, Addr *v)
|
||||||
|
{
|
||||||
|
if(a->type != v->type)
|
||||||
|
return 0;
|
||||||
|
if(regtyp(v) && a->reg == v->reg)
|
||||||
|
return 1;
|
||||||
|
if(v->type == D_AUTO || v->type == D_PARAM)
|
||||||
|
if(v->offset == a->offset)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
smallindir(Addr *a, Addr *reg)
|
||||||
|
{
|
||||||
|
return reg->type == D_REG && a->type == D_OREG &&
|
||||||
|
a->reg == reg->reg &&
|
||||||
|
0 <= a->offset && a->offset < 4096;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
stackaddr(Addr *a)
|
||||||
|
{
|
||||||
|
return a->type == D_REG && a->reg == REGSP;
|
||||||
|
}
|
138
src/cmd/9g/prog.c
Normal file
138
src/cmd/9g/prog.c
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include "gg.h"
|
||||||
|
#include "opt.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
LeftRdwr = LeftRead | LeftWrite,
|
||||||
|
RightRdwr = RightRead | RightWrite,
|
||||||
|
};
|
||||||
|
|
||||||
|
// This table gives the basic information about instruction
|
||||||
|
// generated by the compiler and processed in the optimizer.
|
||||||
|
// See opt.h for bit definitions.
|
||||||
|
//
|
||||||
|
// Instructions not generated need not be listed.
|
||||||
|
// As an exception to that rule, we typically write down all the
|
||||||
|
// size variants of an operation even if we just use a subset.
|
||||||
|
//
|
||||||
|
// The table is formatted for 8-space tabs.
|
||||||
|
static ProgInfo progtable[ALAST] = {
|
||||||
|
[ATYPE]= {Pseudo | Skip},
|
||||||
|
[ATEXT]= {Pseudo},
|
||||||
|
[AFUNCDATA]= {Pseudo},
|
||||||
|
[APCDATA]= {Pseudo},
|
||||||
|
[AUNDEF]= {Break},
|
||||||
|
[AUSEFIELD]= {OK},
|
||||||
|
[ACHECKNIL]= {LeftRead},
|
||||||
|
[AVARDEF]= {Pseudo | RightWrite},
|
||||||
|
[AVARKILL]= {Pseudo | RightWrite},
|
||||||
|
|
||||||
|
// NOP is an internal no-op that also stands
|
||||||
|
// for USED and SET annotations, not the Power opcode.
|
||||||
|
[ANOP]= {LeftRead | RightWrite},
|
||||||
|
|
||||||
|
// Integer
|
||||||
|
[AADD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||||
|
[ASUB]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||||
|
[ANEG]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||||
|
[AAND]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||||
|
[AOR]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||||
|
[AXOR]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||||
|
[AMULLD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||||
|
[AMULLW]= {SizeL | LeftRead | RegRead | RightWrite},
|
||||||
|
[AMULHD]= {SizeL | LeftRead | RegRead | RightWrite},
|
||||||
|
[AMULHDU]= {SizeL | LeftRead | RegRead | RightWrite},
|
||||||
|
[ADIVD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||||
|
[ADIVDU]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||||
|
[ASLD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||||
|
[ASRD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||||
|
[ASRAD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||||
|
[ACMP]= {SizeQ | LeftRead | RightRead},
|
||||||
|
[ACMPU]= {SizeQ | LeftRead | RightRead},
|
||||||
|
[ATD]= {SizeQ | RightRead},
|
||||||
|
|
||||||
|
// Floating point.
|
||||||
|
[AFADD]= {SizeD | LeftRead | RegRead | RightWrite},
|
||||||
|
[AFADDS]= {SizeF | LeftRead | RegRead | RightWrite},
|
||||||
|
[AFSUB]= {SizeD | LeftRead | RegRead | RightWrite},
|
||||||
|
[AFSUBS]= {SizeF | LeftRead | RegRead | RightWrite},
|
||||||
|
[AFMUL]= {SizeD | LeftRead | RegRead | RightWrite},
|
||||||
|
[AFMULS]= {SizeF | LeftRead | RegRead | RightWrite},
|
||||||
|
[AFDIV]= {SizeD | LeftRead | RegRead | RightWrite},
|
||||||
|
[AFDIVS]= {SizeF | LeftRead | RegRead | RightWrite},
|
||||||
|
[AFCTIDZ]= {SizeF | LeftRead | RegRead | RightWrite},
|
||||||
|
[AFCFID]= {SizeF | LeftRead | RegRead | RightWrite},
|
||||||
|
[AFCMPU]= {SizeD | LeftRead | RightRead},
|
||||||
|
[AFRSP]= {SizeD | LeftRead | RightWrite | Conv},
|
||||||
|
|
||||||
|
// Moves
|
||||||
|
[AMOVB]= {SizeB | LeftRead | RightWrite | Move | Conv},
|
||||||
|
[AMOVBU]= {SizeB | LeftRead | RightWrite | Move | Conv | PostInc},
|
||||||
|
[AMOVBZ]= {SizeB | LeftRead | RightWrite | Move | Conv},
|
||||||
|
[AMOVH]= {SizeW | LeftRead | RightWrite | Move | Conv},
|
||||||
|
[AMOVHU]= {SizeW | LeftRead | RightWrite | Move | Conv | PostInc},
|
||||||
|
[AMOVHZ]= {SizeW | LeftRead | RightWrite | Move | Conv},
|
||||||
|
[AMOVW]= {SizeL | LeftRead | RightWrite | Move | Conv},
|
||||||
|
// there is no AMOVWU.
|
||||||
|
[AMOVWZU]= {SizeL | LeftRead | RightWrite | Move | Conv | PostInc},
|
||||||
|
[AMOVWZ]= {SizeL | LeftRead | RightWrite | Move | Conv},
|
||||||
|
[AMOVD]= {SizeQ | LeftRead | RightWrite | Move},
|
||||||
|
[AMOVDU]= {SizeQ | LeftRead | RightWrite | Move | PostInc},
|
||||||
|
[AFMOVS]= {SizeF | LeftRead | RightWrite | Move | Conv},
|
||||||
|
[AFMOVD]= {SizeD | LeftRead | RightWrite | Move},
|
||||||
|
|
||||||
|
// Jumps
|
||||||
|
[ABR]= {Jump | Break},
|
||||||
|
[ABL]= {Call},
|
||||||
|
[ABEQ]= {Cjmp},
|
||||||
|
[ABNE]= {Cjmp},
|
||||||
|
[ABGE]= {Cjmp},
|
||||||
|
[ABLT]= {Cjmp},
|
||||||
|
[ABGT]= {Cjmp},
|
||||||
|
[ABLE]= {Cjmp},
|
||||||
|
[ARETURN]= {Break},
|
||||||
|
// In addtion, duffzero reads R0,R2 and writes R2. This fact must be
|
||||||
|
// encoded in peep.c (TODO)
|
||||||
|
[ADUFFZERO]= {Call},
|
||||||
|
// In addtion, duffcopy reads R0,R2,R3 and writes R2,R3. This fact must be
|
||||||
|
// encoded in peep.c (TODO)
|
||||||
|
[ADUFFCOPY]= {Call},
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
proginfo(ProgInfo *info, Prog *p)
|
||||||
|
{
|
||||||
|
*info = progtable[p->as];
|
||||||
|
if(info->flags == 0) {
|
||||||
|
*info = progtable[AADD];
|
||||||
|
fatal("proginfo: unknown instruction %P", p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((info->flags & RegRead) && p->reg == NREG) {
|
||||||
|
info->flags &= ~RegRead;
|
||||||
|
info->flags |= /*CanRegRead |*/ RightRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(p->from.type == D_OREG && p->from.reg != NREG) {
|
||||||
|
info->reguse |= RtoB(p->from.reg);
|
||||||
|
if(info->flags & PostInc) {
|
||||||
|
info->regset |= RtoB(p->from.reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(p->to.type == D_OREG && p->to.reg != NREG) {
|
||||||
|
info->reguse |= RtoB(p->to.reg);
|
||||||
|
if(info->flags & PostInc) {
|
||||||
|
info->regset |= RtoB(p->to.reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(p->from.type == D_CONST && p->from.sym != nil && (info->flags & LeftRead)) {
|
||||||
|
info->flags &= ~LeftRead;
|
||||||
|
info->flags |= LeftAddr;
|
||||||
|
}
|
||||||
|
}
|
161
src/cmd/9g/reg.c
Normal file
161
src/cmd/9g/reg.c
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
// Derived from Inferno utils/6c/reg.c
|
||||||
|
// http://code.google.com/p/inferno-os/source/browse/utils/6c/reg.c
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include "gg.h"
|
||||||
|
#include "opt.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
regopt(Prog *p)
|
||||||
|
{
|
||||||
|
USED(p);
|
||||||
|
// TODO(minux)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* track register variables including external registers:
|
||||||
|
* bit reg
|
||||||
|
* 0 R0
|
||||||
|
* 1 R1
|
||||||
|
* ... ...
|
||||||
|
* 31 R31
|
||||||
|
* 32+0 F0
|
||||||
|
* 32+1 F1
|
||||||
|
* ... ...
|
||||||
|
* 32+31 F31
|
||||||
|
*/
|
||||||
|
uint64
|
||||||
|
RtoB(int r)
|
||||||
|
{
|
||||||
|
if(r >= D_R0 && r <= D_R0+31)
|
||||||
|
return 1ULL << (r - D_R0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
BtoR(uint64 b)
|
||||||
|
{
|
||||||
|
b &= 0xffffffff;
|
||||||
|
if(b == 0)
|
||||||
|
return 0;
|
||||||
|
return bitno(b) + D_R0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64
|
||||||
|
FtoB(int r)
|
||||||
|
{
|
||||||
|
if(r >= D_F0 && r <= D_F0+31)
|
||||||
|
return 1ULL << (32 + r - D_F0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
BtoF(uint64 b)
|
||||||
|
{
|
||||||
|
b >>= 32;
|
||||||
|
if(b == 0)
|
||||||
|
return 0;
|
||||||
|
return bitno(b) + D_F0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dumpone(Flow *f, int isreg)
|
||||||
|
{
|
||||||
|
int z;
|
||||||
|
Bits bit;
|
||||||
|
Reg *r;
|
||||||
|
|
||||||
|
print("%d:%P", f->loop, f->prog);
|
||||||
|
if(isreg) {
|
||||||
|
r = (Reg*)f;
|
||||||
|
for(z=0; z<BITS; z++)
|
||||||
|
bit.b[z] =
|
||||||
|
r->set.b[z] |
|
||||||
|
r->use1.b[z] |
|
||||||
|
r->use2.b[z] |
|
||||||
|
r->refbehind.b[z] |
|
||||||
|
r->refahead.b[z] |
|
||||||
|
r->calbehind.b[z] |
|
||||||
|
r->calahead.b[z] |
|
||||||
|
r->regdiff.b[z] |
|
||||||
|
r->act.b[z] |
|
||||||
|
0;
|
||||||
|
if(bany(&bit)) {
|
||||||
|
print("\t");
|
||||||
|
if(bany(&r->set))
|
||||||
|
print(" s:%Q", r->set);
|
||||||
|
if(bany(&r->use1))
|
||||||
|
print(" u1:%Q", r->use1);
|
||||||
|
if(bany(&r->use2))
|
||||||
|
print(" u2:%Q", r->use2);
|
||||||
|
if(bany(&r->refbehind))
|
||||||
|
print(" rb:%Q ", r->refbehind);
|
||||||
|
if(bany(&r->refahead))
|
||||||
|
print(" ra:%Q ", r->refahead);
|
||||||
|
if(bany(&r->calbehind))
|
||||||
|
print(" cb:%Q ", r->calbehind);
|
||||||
|
if(bany(&r->calahead))
|
||||||
|
print(" ca:%Q ", r->calahead);
|
||||||
|
if(bany(&r->regdiff))
|
||||||
|
print(" d:%Q ", r->regdiff);
|
||||||
|
if(bany(&r->act))
|
||||||
|
print(" a:%Q ", r->act);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
dumpit(char *str, Flow *r0, int isreg)
|
||||||
|
{
|
||||||
|
Flow *r, *r1;
|
||||||
|
|
||||||
|
print("\n%s\n", str);
|
||||||
|
for(r = r0; r != nil; r = r->link) {
|
||||||
|
dumpone(r, isreg);
|
||||||
|
r1 = r->p2;
|
||||||
|
if(r1 != nil) {
|
||||||
|
print(" pred:");
|
||||||
|
for(; r1 != nil; r1 = r1->p2link)
|
||||||
|
print(" %.4ud", (int)r1->prog->pc);
|
||||||
|
print("\n");
|
||||||
|
}
|
||||||
|
// r1 = r->s1;
|
||||||
|
// if(r1 != R) {
|
||||||
|
// print(" succ:");
|
||||||
|
// for(; r1 != R; r1 = r1->s1)
|
||||||
|
// print(" %.4ud", (int)r1->prog->pc);
|
||||||
|
// print("\n");
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user