Commit 117b1d46 authored by Shenghou Ma's avatar Shenghou Ma

[dev.power64] cmd/9a, cmd/9c, cmd/9l, liblink: import code from Vita Nuova.

No modifications other than adding copyright header to each file, and
concatenating several cmd/9l files together to form the liblink files.

LGTM=rsc
R=rsc, iant
CC=golang-codereviews
https://golang.org/cl/123840043
parent 9512e470
// cmd/9a/a.h from Vita Nuova.
//
// 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-2008 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-2008 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 <bio.h>
#include "../9c/9.out.h"
#ifndef EXTERN
#define EXTERN extern
#endif
typedef struct Sym Sym;
typedef struct Gen Gen;
typedef struct Io Io;
typedef struct Hist Hist;
#define MAXALIGN 7
#define FPCHIP 1
#define NSYMB 8192
#define BUFSIZ 8192
#define HISTSZ 20
#define NINCLUDE 10
#define NHUNK 10000
#define EOF (-1)
#define IGN (-2)
#define GETC() ((--fi.c < 0)? filbuf(): *fi.p++ & 0xff)
#define NHASH 503
#define STRINGSZ 200
#define NMACRO 10
#define ALLOC(lhs, type)\
while(nhunk < sizeof(type))\
gethunk();\
lhs = (type*)hunk;\
nhunk -= sizeof(type);\
hunk += sizeof(type);
#define ALLOCN(lhs, len, n)\
if(lhs+len != hunk || nhunk < n) {\
while(nhunk <= len)\
gethunk();\
memmove(hunk, lhs, len);\
lhs = hunk;\
hunk += len;\
nhunk -= len;\
}\
hunk += n;\
nhunk -= n;
struct Sym
{
Sym* link;
char* macro;
vlong value;
ushort type;
char *name;
char sym;
};
#define S ((Sym*)0)
struct
{
char* p;
int c;
} fi;
struct Io
{
Io* link;
char b[BUFSIZ];
char* p;
short c;
short f;
};
#define I ((Io*)0)
struct
{
Sym* sym;
short type;
} h[NSYM];
struct Gen
{
Sym* sym;
vlong offset;
short type;
short reg;
short xreg;
short name;
ushort mask;
double dval;
char sval[8];
};
struct Hist
{
Hist* link;
char* name;
long line;
vlong offset;
};
#define H ((Hist*)0)
enum
{
CLAST,
CMACARG,
CMACRO,
CPREPROC
};
EXTERN char debug[256];
EXTERN Sym* hash[NHASH];
EXTERN char* Dlist[30];
EXTERN int nDlist;
EXTERN Hist* ehist;
EXTERN int newflag;
EXTERN Hist* hist;
EXTERN char* hunk;
EXTERN char* include[NINCLUDE];
EXTERN Io* iofree;
EXTERN Io* ionext;
EXTERN Io* iostack;
EXTERN long lineno;
EXTERN int nerrors;
EXTERN long nhunk;
EXTERN int nosched;
EXTERN int ninclude;
EXTERN Gen nullgen;
EXTERN char* outfile;
EXTERN int pass;
EXTERN char* pathname;
EXTERN long pc;
EXTERN int peekc;
EXTERN int sym;
EXTERN char symb[NSYMB];
EXTERN int thechar;
EXTERN char* thestring;
EXTERN long thunk;
EXTERN Biobuf obuf;
void errorexit(void);
void pushio(void);
void newio(void);
void newfile(char*, int);
Sym* slookup(char*);
Sym* lookup(void);
void syminit(Sym*);
long yylex(void);
int getc(void);
int getnsc(void);
void unget(int);
int escchar(int);
void cinit(void);
void pinit(char*);
void cclean(void);
void outcode(int, Gen*, int, Gen*);
void outgcode(int, Gen*, int, Gen*, Gen*);
void zname(char*, int, int);
void zaddr(Gen*, int);
void ieeedtod(Ieee*, double);
int filbuf(void);
Sym* getsym(void);
void domacro(void);
void macund(void);
void macdef(void);
void macexpand(Sym*, char*);
void macinc(void);
void macprag(void);
void maclin(void);
void macif(int);
void macend(void);
void dodefine(char*);
void prfile(long);
void outhist(void);
void linehist(char*, int);
void gethunk(void);
void yyerror(char*, ...);
int yyparse(void);
void setinclude(char*);
int assemble(char*);
/*
* system-dependent stuff from ../cc/compat.c
*/
enum /* keep in synch with ../cc/cc.h */
{
Plan9 = 1<<0,
Unix = 1<<1,
Windows = 1<<2
};
int mywait(int*);
int mycreat(char*, int);
int systemtype(int);
int pathchar(void);
char* mygetwd(char*, int);
int myexec(char*, char*[]);
int mydup(int, int);
int myfork(void);
int mypipe(int*);
void* mysbrk(ulong);
This diff is collapsed.
This diff is collapsed.
- effect of register expansion on 32-bit shifts and masks etc
9c
- multab
- floating-point conversions
- conversions of constants
- nodtype for loads
- sign-extension instruction (32-64) when in register?
- double indexing
- SLW (eg, in cat)
- scheduling
9l
- D_QCONST, DWORD
- maskgen
This diff is collapsed.
// cmd/9c/gc.h from Vita Nuova.
//
// 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-2008 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-2008 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 "../cc/cc.h"
#include "../9c/9.out.h"
/*
* 9c/powerpc64
*/
#define SZ_CHAR 1
#define SZ_SHORT 2
#define SZ_INT 4
#define SZ_LONG 4
#define SZ_IND 8
#define SZ_FLOAT 4
#define SZ_VLONG 8
#define SZ_DOUBLE 8
#define FNX 100
typedef struct Adr Adr;
typedef struct Prog Prog;
typedef struct Case Case;
typedef struct C1 C1;
typedef struct Multab Multab;
typedef struct Hintab Hintab;
typedef struct Var Var;
typedef struct Reg Reg;
typedef struct Rgn Rgn;
struct Adr
{
union
{
vlong offset;
double dval;
char sval[NSNAME];
};
Sym* sym;
char type;
char reg;
char name;
char etype;
};
#define A ((Adr*)0)
#define INDEXED 9
struct Prog
{
Adr from;
Adr from3; /* third argument for fmadd, fmsub, ... */
Adr to;
Prog* link;
long lineno;
short as;
char reg;
};
#define P ((Prog*)0)
struct Case
{
Case* link;
vlong val;
long label;
char def;
char isv;
};
#define C ((Case*)0)
struct C1
{
vlong val;
long label;
};
struct Multab
{
long val;
char code[20];
};
struct Hintab
{
ushort val;
char hint[10];
};
struct Var
{
vlong offset;
Sym* sym;
char name;
char etype;
};
struct Reg
{
long pc;
long rpo; /* reverse post ordering */
Bits set;
Bits use1;
Bits use2;
Bits refbehind;
Bits refahead;
Bits calbehind;
Bits calahead;
Bits regdiff;
Bits act;
long regu;
long loop; /* could be shorter */
union
{
Reg* log5;
long active;
};
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 long breakpc;
EXTERN long nbreak;
EXTERN Case* cases;
EXTERN Node constnode;
EXTERN Node fconstnode;
EXTERN Node vconstnode;
EXTERN long continpc;
EXTERN long curarg;
EXTERN long cursafe;
EXTERN Prog* firstp;
EXTERN Prog* lastp;
EXTERN int hintabsize;
EXTERN long maxargsafe;
EXTERN Multab multab[20];
EXTERN int mnstring;
EXTERN Node* nodrat;
EXTERN Node* nodret;
EXTERN Node* nodsafe;
EXTERN long nrathole;
EXTERN long nstring;
EXTERN Prog* p;
EXTERN long pc;
EXTERN Node regnode;
EXTERN Node qregnode;
EXTERN char string[NSNAME];
EXTERN Sym* symrathole;
EXTERN Node znode;
EXTERN Prog zprog;
EXTERN int reg[NREG+NREG];
EXTERN long exregoffset;
EXTERN long exfregoffset;
EXTERN uchar typechlpv[NTYPE];
#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 bset(a,n) ((a).b[(n)/32]&(1L<<(n)%32))
#define CLOAD 5
#define CREF 5
#define CINF 1000
#define LOOP 3
EXTERN Rgn region[NRGN];
EXTERN Rgn* rgp;
EXTERN int nregion;
EXTERN int nvar;
EXTERN Bits externs;
EXTERN Bits params;
EXTERN Bits consts;
EXTERN Bits addrs;
EXTERN long regbits;
EXTERN long exregbits;
EXTERN int change;
EXTERN int suppress;
EXTERN Reg* firstr;
EXTERN Reg* lastr;
EXTERN Reg zreg;
EXTERN Reg* freer;
EXTERN Var var[NVAR];
EXTERN long* idom;
EXTERN Reg** rpo2r;
EXTERN long maxnr;
#define R0ISZERO (debug['0']==0)
extern char* anames[];
extern Hintab hintab[];
/*
* sgen.c
*/
void codgen(Node*, Node*);
void gen(Node*);
void usedset(Node*, int);
void noretval(int);
void xcom(Node*);
int bcomplex(Node*, Node*);
/*
* cgen.c
*/
void cgen(Node*, Node*);
void reglcgen(Node*, Node*, Node*);
void lcgen(Node*, Node*);
void bcgen(Node*, int);
void boolgen(Node*, int, Node*);
void sugen(Node*, Node*, long);
void layout(Node*, Node*, int, int, Node*);
/*
* txt.c
*/
void ginit(void);
void gclean(void);
void nextpc(void);
void gargs(Node*, Node*, Node*);
void garg1(Node*, Node*, Node*, int, Node**);
Node* nodconst(long);
Node* nod32const(vlong);
Node* nodfconst(double);
void nodreg(Node*, Node*, int);
void regret(Node*, Node*);
void regalloc(Node*, Node*, Node*);
void regfree(Node*);
void regialloc(Node*, Node*, Node*);
void regsalloc(Node*, Node*);
void regaalloc1(Node*, Node*);
void regaalloc(Node*, Node*);
void regind(Node*, Node*);
void gprep(Node*, Node*);
void raddr(Node*, Prog*);
void naddr(Node*, Adr*);
void gmove(Node*, Node*);
void gins(int a, Node*, Node*);
void gopcode(int, Node*, Node*, Node*);
int samaddr(Node*, Node*);
void gbranch(int);
int immconst(Node*);
void patch(Prog*, long);
int sconst(Node*);
int sval(long);
int uconst(Node*);
void gpseudo(int, Sym*, Node*);
/*
* swt.c
*/
int swcmp(void*, void*);
void doswit(Node*);
void swit1(C1*, int, long, Node*);
void swit2(C1*, int, long, Node*, Node*);
void casf(void);
void bitload(Node*, Node*, Node*, Node*, Node*);
void bitstore(Node*, Node*, Node*, Node*, Node*);
long outstring(char*, long);
int mulcon(Node*, Node*);
Multab* mulcon0(Node*, long);
int mulcon1(Node*, long, Node*);
void nullwarn(Node*, Node*);
void sextern(Sym*, Node*, long, long);
void gextern(Sym*, Node*, long, long);
void outcode(void);
void ieeedtod(Ieee*, double);
/*
* list
*/
void listinit(void);
int Pconv(Fmt*);
int Aconv(Fmt*);
int Dconv(Fmt*);
int Sconv(Fmt*);
int Nconv(Fmt*);
int Bconv(Fmt*);
/*
* reg.c
*/
Reg* rega(void);
int rcmp(void*, void*);
void regopt(Prog*);
void addmove(Reg*, int, int, int);
Bits mkvar(Adr*, int);
void prop(Reg*, Bits, Bits);
void loopit(Reg*, long);
void synch(Reg*, Bits);
ulong allreg(ulong, Rgn*);
void paint1(Reg*, int);
ulong paint2(Reg*, int);
void paint3(Reg*, int, long, int);
void addreg(Adr*, int);
/*
* peep.c
*/
void peep(void);
void excise(Reg*);
Reg* uniqp(Reg*);
Reg* uniqs(Reg*);
int regtyp(Adr*);
int regzer(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 copyau1(Prog*, Adr*);
int copysub(Adr*, Adr*, Adr*, int);
int copysub1(Prog*, Adr*, Adr*, int);
long RtoB(int);
long FtoB(int);
int BtoR(long);
int BtoF(long);
/*
* com64.c
*/
int com64(Node*);
void com64init(void);
void bool64(Node*);
#pragma varargck type "A" int
#pragma varargck type "B" Bits
#pragma varargck type "D" Adr*
#pragma varargck type "N" Adr*
#pragma varargck type "P" Prog*
#pragma varargck type "S" char*
// cmd/9c/list.c from Vita Nuova.
//
// 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-2008 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-2008 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.
// +build ignore
#define EXTERN
#include "gc.h"
void
listinit(void)
{
fmtinstall('A', Aconv);
fmtinstall('P', Pconv);
fmtinstall('S', Sconv);
fmtinstall('N', Nconv);
fmtinstall('D', Dconv);
fmtinstall('B', Bconv);
}
int
Bconv(Fmt *fp)
{
char str[STRINGSZ], ss[STRINGSZ], *s;
Bits bits;
int i;
str[0] = 0;
bits = va_arg(fp->args, Bits);
while(bany(&bits)) {
i = bnum(bits);
if(str[0])
strcat(str, " ");
if(var[i].sym == S) {
sprint(ss, "$%lld", var[i].offset);
s = ss;
} else
s = var[i].sym->name;
if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
break;
strcat(str, s);
bits.b[i/32] &= ~(1L << (i%32));
}
return fmtstrcpy(fp, str);
}
int
Pconv(Fmt *fp)
{
char str[STRINGSZ];
Prog *p;
int a;
p = va_arg(fp->args, Prog*);
a = p->as;
if(a == ADATA)
sprint(str, " %A %D/%d,%D", a, &p->from, p->reg, &p->to);
else
if(p->as == ATEXT)
sprint(str, " %A %D,%d,%D", a, &p->from, p->reg, &p->to);
else
if(p->reg == NREG)
sprint(str, " %A %D,%D", a, &p->from, &p->to);
else
if(p->from.type != D_FREG)
sprint(str, " %A %D,R%d,%D", a, &p->from, p->reg, &p->to);
else
sprint(str, " %A %D,F%d,%D", a, &p->from, p->reg, &p->to);
return fmtstrcpy(fp, str);
}
int
Aconv(Fmt *fp)
{
char *s;
int a;
a = va_arg(fp->args, int);
s = "???";
if(a >= AXXX && a <= ALAST)
s = anames[a];
return fmtstrcpy(fp, s);
}
int
Dconv(Fmt *fp)
{
char str[STRINGSZ];
Adr *a;
a = va_arg(fp->args, Adr*);
switch(a->type) {
default:
sprint(str, "GOK-type(%d)", a->type);
break;
case D_NONE:
str[0] = 0;
if(a->name != D_NONE || a->reg != NREG || a->sym != S)
sprint(str, "%N(R%d)(NONE)", a, a->reg);
break;
case D_CONST:
if(a->reg != NREG)
sprint(str, "$%N(R%d)", a, a->reg);
else
sprint(str, "$%N", a);
break;
case D_OREG:
if(a->reg != NREG)
sprint(str, "%N(R%d)", a, a->reg);
else
sprint(str, "%N", a);
break;
case D_REG:
sprint(str, "R%d", a->reg);
if(a->name != D_NONE || a->sym != S)
sprint(str, "%N(R%d)(REG)", a, a->reg);
break;
case D_FREG:
sprint(str, "F%d", a->reg);
if(a->name != D_NONE || a->sym != S)
sprint(str, "%N(F%d)(REG)", a, a->reg);
break;
case D_CREG:
sprint(str, "C%d", a->reg);
if(a->name != D_NONE || a->sym != S)
sprint(str, "%N(C%d)(REG)", a, a->reg);
break;
case D_BRANCH:
sprint(str, "%lld(PC)", a->offset-pc);
break;
case D_FCONST:
sprint(str, "$%.17e", a->dval);
break;
case D_SCONST:
sprint(str, "$\"%S\"", a->sval);
break;
}
return fmtstrcpy(fp, str);
}
int
Sconv(Fmt *fp)
{
int i, c;
char str[STRINGSZ], *p, *a;
a = va_arg(fp->args, char*);
p = str;
for(i=0; i<NSNAME; i++) {
c = a[i] & 0xff;
if(c >= 'a' && c <= 'z' ||
c >= 'A' && c <= 'Z' ||
c >= '0' && c <= '9' ||
c == ' ' || c == '%') {
*p++ = c;
continue;
}
*p++ = '\\';
switch(c) {
case 0:
*p++ = 'z';
continue;
case '\\':
case '"':
*p++ = c;
continue;
case '\n':
*p++ = 'n';
continue;
case '\t':
*p++ = 't';
continue;
case '\r':
*p++ = 'r';
continue;
case '\f':
*p++ = 'f';
continue;
}
*p++ = (c>>6) + '0';
*p++ = ((c>>3) & 7) + '0';
*p++ = (c & 7) + '0';
}
*p = 0;
return fmtstrcpy(fp, str);
}
int
Nconv(Fmt *fp)
{
char str[STRINGSZ];
Adr *a;
Sym *s;
a = va_arg(fp->args, Adr*);
s = a->sym;
if(s == S) {
sprint(str, "%lld", a->offset);
goto out;
}
switch(a->name) {
default:
sprint(str, "GOK-name(%d)", a->name);
break;
case D_EXTERN:
sprint(str, "%s+%lld(SB)", s->name, a->offset);
break;
case D_STATIC:
sprint(str, "%s<>+%lld(SB)", s->name, a->offset);
break;
case D_AUTO:
sprint(str, "%s-%lld(SP)", s->name, -a->offset);
break;
case D_PARAM:
sprint(str, "%s+%lld(FP)", s->name, a->offset);
break;
}
out:
return fmtstrcpy(fp, str);
}
// cmd/9c/machcap.c from Vita Nuova.
//
// 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-2008 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-2008 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.
// +build ignore
#include "gc.h"
int
machcap(Node *n)
{
if(n == Z)
return 1; /* test */
switch(n->op) {
case OMUL:
case OLMUL:
case OASMUL:
case OASLMUL:
if(typechlv[n->type->etype])
return 1;
break;
case OADD:
case OAND:
case OOR:
case OSUB:
case OXOR:
case OASHL:
case OLSHR:
case OASHR:
if(typechlv[n->left->type->etype])
return 1;
break;
case OCAST:
return 1;
case OCOND:
case OCOMMA:
case OLIST:
case OANDAND:
case OOROR:
case ONOT:
return 1;
case OASADD:
case OASSUB:
case OASAND:
case OASOR:
case OASXOR:
return 1;
case OASASHL:
case OASASHR:
case OASLSHR:
return 1;
case OPOSTINC:
case OPOSTDEC:
case OPREINC:
case OPREDEC:
return 1;
case OEQ:
case ONE:
case OLE:
case OGT:
case OLT:
case OGE:
case OHI:
case OHS:
case OLO:
case OLS:
return 1;
case ONEG:
case OCOM:
break;
}
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// cmd/9c/sgen.c from Vita Nuova.
//
// 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-2008 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-2008 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.
// +build ignore
#include "gc.h"
void
noretval(int n)
{
if(n & 1) {
gins(ANOP, Z, Z);
p->to.type = D_REG;
p->to.reg = REGRET;
}
if(n & 2) {
gins(ANOP, Z, Z);
p->to.type = D_FREG;
p->to.reg = FREGRET;
}
}
/*
* calculate addressability as follows
* CONST ==> 20 $value
* NAME ==> 10 name
* REGISTER ==> 11 register
* INDREG ==> 12 *[(reg)+offset]
* &10 ==> 2 $name
* ADD(2, 20) ==> 2 $name+offset
* ADD(3, 20) ==> 3 $(reg)+offset
* &12 ==> 3 $(reg)+offset
* *11 ==> 11 ??
* *2 ==> 10 name
* *3 ==> 12 *(reg)+offset
* calculate complexity (number of registers)
*/
void
xcom(Node *n)
{
Node *l, *r;
int v;
if(n == Z)
return;
l = n->left;
r = n->right;
n->addable = 0;
n->complex = 0;
switch(n->op) {
case OCONST:
n->addable = 20;
return;
case OREGISTER:
n->addable = 11;
return;
case OINDREG:
n->addable = 12;
return;
case ONAME:
n->addable = 10;
return;
case OADDR:
xcom(l);
if(l->addable == 10)
n->addable = 2;
if(l->addable == 12)
n->addable = 3;
break;
case OIND:
xcom(l);
if(l->addable == 11)
n->addable = 12;
if(l->addable == 3)
n->addable = 12;
if(l->addable == 2)
n->addable = 10;
break;
case OADD:
xcom(l);
xcom(r);
if(l->addable == 20) {
if(r->addable == 2)
n->addable = 2;
if(r->addable == 3)
n->addable = 3;
}
if(r->addable == 20) {
if(l->addable == 2)
n->addable = 2;
if(l->addable == 3)
n->addable = 3;
}
break;
case OASMUL:
case OASLMUL:
xcom(l);
xcom(r);
v = vlog(r);
if(v >= 0) {
n->op = OASASHL;
r->vconst = v;
r->type = types[TINT];
}
break;
case OMUL:
case OLMUL:
xcom(l);
xcom(r);
v = vlog(r);
if(v >= 0) {
n->op = OASHL;
r->vconst = v;
r->type = types[TINT];
}
v = vlog(l);
if(v >= 0) {
n->op = OASHL;
n->left = r;
n->right = l;
r = l;
l = n->left;
r->vconst = v;
r->type = types[TINT];
simplifyshift(n);
}
break;
case OASLDIV:
xcom(l);
xcom(r);
v = vlog(r);
if(v >= 0) {
n->op = OASLSHR;
r->vconst = v;
r->type = types[TINT];
}
break;
case OLDIV:
xcom(l);
xcom(r);
v = vlog(r);
if(v >= 0) {
n->op = OLSHR;
r->vconst = v;
r->type = types[TINT];
simplifyshift(n);
}
break;
case OASLMOD:
xcom(l);
xcom(r);
v = vlog(r);
if(v >= 0) {
n->op = OASAND;
r->vconst--;
}
break;
case OLMOD:
xcom(l);
xcom(r);
v = vlog(r);
if(v >= 0) {
n->op = OAND;
r->vconst--;
}
break;
case OLSHR:
case OASHL:
case OASHR:
xcom(l);
xcom(r);
simplifyshift(n);
break;
default:
if(l != Z)
xcom(l);
if(r != Z)
xcom(r);
break;
}
if(n->addable >= 10)
return;
if(l != Z)
n->complex = l->complex;
if(r != Z) {
if(r->complex == n->complex)
n->complex = r->complex+1;
else
if(r->complex > n->complex)
n->complex = r->complex;
}
if(n->complex == 0)
n->complex++;
// if(com64(n))
// return;
switch(n->op) {
case OFUNC:
n->complex = FNX;
break;
case OEQ:
case ONE:
case OLE:
case OLT:
case OGE:
case OGT:
case OHI:
case OHS:
case OLO:
case OLS:
/*
* immediate operators, make const on right
*/
if(l->op == OCONST) {
n->left = r;
n->right = l;
n->op = invrel[relindex(n->op)];
}
break;
case OADD:
case OXOR:
case OAND:
case OOR:
/*
* immediate operators, make const on right
*/
if(l->op == OCONST) {
n->left = r;
n->right = l;
}
break;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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