137da2899SCharles.Forsyth #include "limbo.h"
237da2899SCharles.Forsyth
337da2899SCharles.Forsyth #define bzero bbzero /* bsd name space pollution */
437da2899SCharles.Forsyth /*
537da2899SCharles.Forsyth (r, s) := f(); => r, s have def on same pc
637da2899SCharles.Forsyth s = g(); => this def kills previous r def (and s def)
737da2899SCharles.Forsyth solution: r has def pc, s has def pc+1 and next instruction has pc pc+2
837da2899SCharles.Forsyth */
937da2899SCharles.Forsyth
1037da2899SCharles.Forsyth #define BLEN (8*sizeof(ulong))
1137da2899SCharles.Forsyth #define BSHIFT 5 /* assumes ulong 4 */
1237da2899SCharles.Forsyth #define BMASK (BLEN-1)
1337da2899SCharles.Forsyth
1437da2899SCharles.Forsyth #define SIGN(n) (1<<(n-1))
1537da2899SCharles.Forsyth #define MSK(n) (SIGN(n)|(SIGN(n)-1))
1637da2899SCharles.Forsyth #define MASK(a, b) (MSK((b)-(a)+1)<<(a))
1737da2899SCharles.Forsyth
1837da2899SCharles.Forsyth #define isnilsrc(s) ((s)->start.line == 0 && (s)->stop.line == 0 && (s)->start.pos == 0 && (s)->stop.pos == 0)
1937da2899SCharles.Forsyth
2037da2899SCharles.Forsyth #define limbovar(d) ((d)->sym->name[0] != '.')
2137da2899SCharles.Forsyth #define structure(t) ((t)->kind == Tadt || (t)->kind == Ttuple)
2237da2899SCharles.Forsyth
2337da2899SCharles.Forsyth enum
2437da2899SCharles.Forsyth {
2537da2899SCharles.Forsyth Bclr,
2637da2899SCharles.Forsyth Band,
2737da2899SCharles.Forsyth Bandinv,
2837da2899SCharles.Forsyth Bstore,
2937da2899SCharles.Forsyth Bandrev,
3037da2899SCharles.Forsyth Bnoop,
3137da2899SCharles.Forsyth Bxor,
3237da2899SCharles.Forsyth Bor,
3337da2899SCharles.Forsyth Bnor,
3437da2899SCharles.Forsyth Bequiv,
3537da2899SCharles.Forsyth Binv,
3637da2899SCharles.Forsyth Bimpby,
3737da2899SCharles.Forsyth Brev,
3837da2899SCharles.Forsyth Bimp,
3937da2899SCharles.Forsyth Bnand,
4037da2899SCharles.Forsyth Bset,
4137da2899SCharles.Forsyth };
4237da2899SCharles.Forsyth
4337da2899SCharles.Forsyth enum
4437da2899SCharles.Forsyth {
4537da2899SCharles.Forsyth Suse = 1,
4637da2899SCharles.Forsyth Muse = 2,
4737da2899SCharles.Forsyth Duse = 4,
4837da2899SCharles.Forsyth Sdef = 8,
4937da2899SCharles.Forsyth Mdef = 16,
5037da2899SCharles.Forsyth Ddef = 32,
5137da2899SCharles.Forsyth Tuse1 = 64, /* fixed point temporary */
5237da2899SCharles.Forsyth Tuse2 = 128, /* fixed point temporary */
5337da2899SCharles.Forsyth Mduse = 256, /* D used if M nil */
5437da2899SCharles.Forsyth
5537da2899SCharles.Forsyth None = 0,
5637da2899SCharles.Forsyth Unop = Suse|Ddef,
5737da2899SCharles.Forsyth Cunop = Muse|Ddef,
5837da2899SCharles.Forsyth Threop = Suse|Muse|Ddef,
5937da2899SCharles.Forsyth Binop = Suse|Muse|Ddef|Mduse,
6037da2899SCharles.Forsyth Mbinop = Suse|Mdef|Duse, /* strange */
6137da2899SCharles.Forsyth Abinop=Suse|Duse|Ddef,
6237da2899SCharles.Forsyth Mabinop = Suse|Muse|Duse|Ddef,
6337da2899SCharles.Forsyth Use1 = Suse,
6437da2899SCharles.Forsyth Use2 = Suse|Duse,
6537da2899SCharles.Forsyth Use3 = Suse|Muse|Duse,
6637da2899SCharles.Forsyth };
6737da2899SCharles.Forsyth
6837da2899SCharles.Forsyth enum
6937da2899SCharles.Forsyth {
7037da2899SCharles.Forsyth Sshift = 10,
7137da2899SCharles.Forsyth Mshift = 5,
7237da2899SCharles.Forsyth Dshift = 0,
7337da2899SCharles.Forsyth };
7437da2899SCharles.Forsyth
7537da2899SCharles.Forsyth #define S(x) ((x)<<Sshift)
7637da2899SCharles.Forsyth #define M(x) ((x)<<Mshift)
7737da2899SCharles.Forsyth #define D(x) ((x)<<Dshift)
7837da2899SCharles.Forsyth
7937da2899SCharles.Forsyth #define SS(x) (((x)>>Sshift)&0x1f)
8037da2899SCharles.Forsyth #define SM(x) (((x)>>Mshift)&0x1f)
8137da2899SCharles.Forsyth #define SD(x) (((x)>>Dshift)&0x1f)
8237da2899SCharles.Forsyth
8337da2899SCharles.Forsyth enum
8437da2899SCharles.Forsyth {
8537da2899SCharles.Forsyth I = 0, /* ignore */
8637da2899SCharles.Forsyth B = 1, /* byte */
8737da2899SCharles.Forsyth W = 4, /* int */
8837da2899SCharles.Forsyth P = 4, /* pointer */
8937da2899SCharles.Forsyth A = 4, /* array */
9037da2899SCharles.Forsyth C = 4, /* string */
9137da2899SCharles.Forsyth X = 4, /* fixed */
9237da2899SCharles.Forsyth R = 4, /* float */
9337da2899SCharles.Forsyth L = 8, /* big */
9437da2899SCharles.Forsyth F = 8, /* real */
9537da2899SCharles.Forsyth Sh = 2, /* short */
9637da2899SCharles.Forsyth Pc = 4, /* pc */
9737da2899SCharles.Forsyth Mp = 16, /* memory */
9837da2899SCharles.Forsyth
9937da2899SCharles.Forsyth Bop2 = S(B)|D(B),
10037da2899SCharles.Forsyth Bop = S(B)|M(B)|D(B),
10137da2899SCharles.Forsyth Bopb = S(B)|M(B)|D(Pc),
10237da2899SCharles.Forsyth Wop2 = S(W)|D(W),
10337da2899SCharles.Forsyth Wop = S(W)|M(W)|D(W),
10437da2899SCharles.Forsyth Wopb = S(W)|M(W)|D(Pc),
10537da2899SCharles.Forsyth Lop2 = S(L)|D(L),
10637da2899SCharles.Forsyth Lop = S(L)|M(L)|D(L),
10737da2899SCharles.Forsyth Lopb = S(L)|M(L)|D(Pc),
10837da2899SCharles.Forsyth Cop2 = Wop2,
10937da2899SCharles.Forsyth Cop = Wop,
11037da2899SCharles.Forsyth Copb = Wopb,
11137da2899SCharles.Forsyth Fop2 = Lop2,
11237da2899SCharles.Forsyth Fop = Lop,
11337da2899SCharles.Forsyth Fopb = Lopb,
11437da2899SCharles.Forsyth Xop = Wop,
11537da2899SCharles.Forsyth };
11637da2899SCharles.Forsyth
11737da2899SCharles.Forsyth typedef struct Array Array;
11837da2899SCharles.Forsyth typedef struct Bits Bits;
11937da2899SCharles.Forsyth typedef struct Blist Blist;
12037da2899SCharles.Forsyth typedef struct Block Block;
12137da2899SCharles.Forsyth typedef struct Idlist Idlist;
12237da2899SCharles.Forsyth typedef struct Optab Optab;
12337da2899SCharles.Forsyth
12437da2899SCharles.Forsyth struct Array
12537da2899SCharles.Forsyth {
12637da2899SCharles.Forsyth int n;
12737da2899SCharles.Forsyth int m;
12837da2899SCharles.Forsyth Block **a;
12937da2899SCharles.Forsyth };
13037da2899SCharles.Forsyth
13137da2899SCharles.Forsyth struct Bits
13237da2899SCharles.Forsyth {
13337da2899SCharles.Forsyth int n;
13437da2899SCharles.Forsyth ulong *b;
13537da2899SCharles.Forsyth };
13637da2899SCharles.Forsyth
13737da2899SCharles.Forsyth struct Blist
13837da2899SCharles.Forsyth {
13937da2899SCharles.Forsyth Block *block;
14037da2899SCharles.Forsyth Blist *next;
14137da2899SCharles.Forsyth };
14237da2899SCharles.Forsyth
14337da2899SCharles.Forsyth struct Block
14437da2899SCharles.Forsyth {
14537da2899SCharles.Forsyth int dfn;
14637da2899SCharles.Forsyth int flags;
14737da2899SCharles.Forsyth Inst *first;
14837da2899SCharles.Forsyth Inst *last;
14937da2899SCharles.Forsyth Block *prev;
15037da2899SCharles.Forsyth Block *next;
15137da2899SCharles.Forsyth Blist *pred;
15237da2899SCharles.Forsyth Blist *succ;
15337da2899SCharles.Forsyth Bits kill;
15437da2899SCharles.Forsyth Bits gen;
15537da2899SCharles.Forsyth Bits in;
15637da2899SCharles.Forsyth Bits out;
15737da2899SCharles.Forsyth };
15837da2899SCharles.Forsyth
15937da2899SCharles.Forsyth struct Idlist
16037da2899SCharles.Forsyth {
16137da2899SCharles.Forsyth int id;
16237da2899SCharles.Forsyth Idlist *next;
16337da2899SCharles.Forsyth };
16437da2899SCharles.Forsyth
16537da2899SCharles.Forsyth struct Optab
16637da2899SCharles.Forsyth {
16737da2899SCharles.Forsyth short flags;
16837da2899SCharles.Forsyth short size;
16937da2899SCharles.Forsyth };
17037da2899SCharles.Forsyth
17137da2899SCharles.Forsyth Block zblock;
17237da2899SCharles.Forsyth Decl *regdecls;
17337da2899SCharles.Forsyth Idlist *frelist;
17437da2899SCharles.Forsyth Idlist *deflist;
17537da2899SCharles.Forsyth Idlist *uselist;
17637da2899SCharles.Forsyth
17737da2899SCharles.Forsyth static void
addlist(Idlist ** hd,int id)17837da2899SCharles.Forsyth addlist(Idlist **hd, int id)
17937da2899SCharles.Forsyth {
18037da2899SCharles.Forsyth Idlist *il;
18137da2899SCharles.Forsyth
18237da2899SCharles.Forsyth if(frelist == nil)
18337da2899SCharles.Forsyth il = (Idlist*)malloc(sizeof(Idlist));
18437da2899SCharles.Forsyth else{
18537da2899SCharles.Forsyth il = frelist;
18637da2899SCharles.Forsyth frelist = frelist->next;
18737da2899SCharles.Forsyth }
18837da2899SCharles.Forsyth il->id = id;
18937da2899SCharles.Forsyth il->next = *hd;
19037da2899SCharles.Forsyth *hd = il;
19137da2899SCharles.Forsyth }
19237da2899SCharles.Forsyth
19337da2899SCharles.Forsyth static void
freelist(Idlist ** hd)19437da2899SCharles.Forsyth freelist(Idlist **hd)
19537da2899SCharles.Forsyth {
19637da2899SCharles.Forsyth Idlist *il;
19737da2899SCharles.Forsyth
19837da2899SCharles.Forsyth for(il = *hd; il != nil && il->next != nil; il = il->next)
19937da2899SCharles.Forsyth ;
20037da2899SCharles.Forsyth if(il != nil){
20137da2899SCharles.Forsyth il->next = frelist;
20237da2899SCharles.Forsyth frelist = *hd;
20337da2899SCharles.Forsyth *hd = nil;
20437da2899SCharles.Forsyth }
20537da2899SCharles.Forsyth }
20637da2899SCharles.Forsyth
20737da2899SCharles.Forsyth Optab opflags[] = {
20837da2899SCharles.Forsyth /* INOP */ None, 0,
20937da2899SCharles.Forsyth /* IALT */ Unop, S(Mp)|D(W),
21037da2899SCharles.Forsyth /* INBALT */ Unop, S(Mp)|D(W),
21137da2899SCharles.Forsyth /* IGOTO */ Use2, S(W)|D(I),
21237da2899SCharles.Forsyth /* ICALL */ Use2, S(P)|D(Pc),
21337da2899SCharles.Forsyth /* IFRAME */ Unop, S(W)|D(P),
21437da2899SCharles.Forsyth /* ISPAWN */ Use2, S(P)|D(Pc),
21537da2899SCharles.Forsyth /* IRUNT */ None, 0,
21637da2899SCharles.Forsyth /* ILOAD */ Threop, S(C)|M(P)|D(P),
21737da2899SCharles.Forsyth /* IMCALL */ Use3, S(P)|M(W)|D(P),
21837da2899SCharles.Forsyth /* IMSPAWN */ Use3, S(P)|M(W)|D(P),
21937da2899SCharles.Forsyth /* IMFRAME */ Threop, S(P)|M(W)|D(P),
22037da2899SCharles.Forsyth /* IRET */ None, 0,
22137da2899SCharles.Forsyth /* IJMP */ Duse, D(Pc),
22237da2899SCharles.Forsyth /* ICASE */ Use2, S(W)|D(I),
22337da2899SCharles.Forsyth /* IEXIT */ None, 0,
22437da2899SCharles.Forsyth /* INEW */ Unop, S(W)|D(P),
22537da2899SCharles.Forsyth /* INEWA */ Threop, S(W)|M(W)|D(P),
22637da2899SCharles.Forsyth /* INEWCB */ Cunop, M(W)|D(P),
22737da2899SCharles.Forsyth /* INEWCW */ Cunop, M(W)|D(P),
22837da2899SCharles.Forsyth /* INEWCF */ Cunop, M(W)|D(P),
22937da2899SCharles.Forsyth /* INEWCP */ Cunop, M(W)|D(P),
23037da2899SCharles.Forsyth /* INEWCM */ Threop, S(W)|M(W)|D(P),
23137da2899SCharles.Forsyth /* INEWCMP */ Threop, S(W)|M(W)|D(P),
23237da2899SCharles.Forsyth /* ISEND */ Use2, S(Mp)|D(P),
23337da2899SCharles.Forsyth /* IRECV */ Unop, S(P)|D(Mp),
23437da2899SCharles.Forsyth /* ICONSB */ Abinop, S(B)|D(P),
23537da2899SCharles.Forsyth /* ICONSW */ Abinop, S(W)|D(P),
23637da2899SCharles.Forsyth /* ICONSP */ Abinop, S(P)|D(P),
23737da2899SCharles.Forsyth /* ICONSF */ Abinop, S(F)|D(P),
23837da2899SCharles.Forsyth /* ICONSM */ Mabinop, S(Mp)|M(W)|D(P),
23937da2899SCharles.Forsyth /* ICONSMP */ Mabinop, S(Mp)|M(W)|D(P),
24037da2899SCharles.Forsyth /* IHEADB */ Unop, S(P)|D(B),
24137da2899SCharles.Forsyth /* IHEADW */ Unop, S(P)|D(W),
24237da2899SCharles.Forsyth /* IHEADP */ Unop, S(P)|D(P),
24337da2899SCharles.Forsyth /* IHEADF */ Unop, S(P)|D(F),
24437da2899SCharles.Forsyth /* IHEADM */ Threop, S(P)|M(W)|D(Mp),
24537da2899SCharles.Forsyth /* IHEADMP */ Threop, S(P)|M(W)|D(Mp),
24637da2899SCharles.Forsyth /* ITAIL */ Unop, S(P)|D(P),
24737da2899SCharles.Forsyth /* ILEA */ Ddef, S(Mp)|D(P), /* S done specially cos of ALT */
24837da2899SCharles.Forsyth /* IINDX */ Mbinop, S(P)|M(P)|D(W),
24937da2899SCharles.Forsyth /* IMOVP */ Unop, S(P)|D(P),
25037da2899SCharles.Forsyth /* IMOVM */ Threop, S(Mp)|M(W)|D(Mp),
25137da2899SCharles.Forsyth /* IMOVMP */ Threop, S(Mp)|M(W)|D(Mp),
25237da2899SCharles.Forsyth /* IMOVB */ Unop, Bop2,
25337da2899SCharles.Forsyth /* IMOVW */ Unop, Wop2,
25437da2899SCharles.Forsyth /* IMOVF */ Unop, Fop2,
25537da2899SCharles.Forsyth /* ICVTBW */ Unop, S(B)|D(W),
25637da2899SCharles.Forsyth /* ICVTWB */ Unop, S(W)|D(B),
25737da2899SCharles.Forsyth /* ICVTFW */ Unop, S(F)|D(W),
25837da2899SCharles.Forsyth /* ICVTWF */ Unop, S(W)|D(F),
25937da2899SCharles.Forsyth /* ICVTCA */ Unop, S(C)|D(A),
26037da2899SCharles.Forsyth /* ICVTAC */ Unop, S(A)|D(C),
26137da2899SCharles.Forsyth /* ICVTWC */ Unop, S(W)|D(C),
26237da2899SCharles.Forsyth /* ICVTCW */ Unop, S(C)|D(W),
26337da2899SCharles.Forsyth /* ICVTFC */ Unop, S(F)|D(C),
26437da2899SCharles.Forsyth /* ICVTCF */ Unop, S(C)|D(F),
26537da2899SCharles.Forsyth /* IADDB */ Binop, Bop,
26637da2899SCharles.Forsyth /* IADDW */ Binop, Wop,
26737da2899SCharles.Forsyth /* IADDF */ Binop, Fop,
26837da2899SCharles.Forsyth /* ISUBB */ Binop, Bop,
26937da2899SCharles.Forsyth /* ISUBW */ Binop, Wop,
27037da2899SCharles.Forsyth /* ISUBF */ Binop, Fop,
27137da2899SCharles.Forsyth /* IMULB */ Binop, Bop,
27237da2899SCharles.Forsyth /* IMULW */ Binop, Wop,
27337da2899SCharles.Forsyth /* IMULF */ Binop, Fop,
27437da2899SCharles.Forsyth /* IDIVB */ Binop, Bop,
27537da2899SCharles.Forsyth /* IDIVW */ Binop, Wop,
27637da2899SCharles.Forsyth /* IDIVF */ Binop, Fop,
27737da2899SCharles.Forsyth /* IMODW */ Binop, Wop,
27837da2899SCharles.Forsyth /* IMODB */ Binop, Bop,
27937da2899SCharles.Forsyth /* IANDB */ Binop, Bop,
28037da2899SCharles.Forsyth /* IANDW */ Binop, Wop,
28137da2899SCharles.Forsyth /* IORB */ Binop, Bop,
28237da2899SCharles.Forsyth /* IORW */ Binop, Wop,
28337da2899SCharles.Forsyth /* IXORB */ Binop, Bop,
28437da2899SCharles.Forsyth /* IXORW */ Binop, Wop,
28537da2899SCharles.Forsyth /* ISHLB */ Binop, S(W)|M(B)|D(B),
28637da2899SCharles.Forsyth /* ISHLW */ Binop, Wop,
28737da2899SCharles.Forsyth /* ISHRB */ Binop, S(W)|M(B)|D(B),
28837da2899SCharles.Forsyth /* ISHRW */ Binop, Wop,
28937da2899SCharles.Forsyth /* IINSC */ Mabinop, S(W)|M(W)|D(C),
29037da2899SCharles.Forsyth /* IINDC */ Threop, S(C)|M(W)|D(W),
29137da2899SCharles.Forsyth /* IADDC */ Binop, Cop,
29237da2899SCharles.Forsyth /* ILENC */ Unop, S(C)|D(W),
29337da2899SCharles.Forsyth /* ILENA */ Unop, S(A)|D(W),
29437da2899SCharles.Forsyth /* ILENL */ Unop, S(P)|D(W),
29537da2899SCharles.Forsyth /* IBEQB */ Use3, Bopb,
29637da2899SCharles.Forsyth /* IBNEB */ Use3, Bopb,
29737da2899SCharles.Forsyth /* IBLTB */ Use3, Bopb,
29837da2899SCharles.Forsyth /* IBLEB */ Use3, Bopb,
29937da2899SCharles.Forsyth /* IBGTB */ Use3, Bopb,
30037da2899SCharles.Forsyth /* IBGEB */ Use3, Bopb,
30137da2899SCharles.Forsyth /* IBEQW */ Use3, Wopb,
30237da2899SCharles.Forsyth /* IBNEW */ Use3, Wopb,
30337da2899SCharles.Forsyth /* IBLTW */ Use3, Wopb,
30437da2899SCharles.Forsyth /* IBLEW */ Use3, Wopb,
30537da2899SCharles.Forsyth /* IBGTW */ Use3, Wopb,
30637da2899SCharles.Forsyth /* IBGEW */ Use3, Wopb,
30737da2899SCharles.Forsyth /* IBEQF */ Use3, Fopb,
30837da2899SCharles.Forsyth /* IBNEF */ Use3, Fopb,
30937da2899SCharles.Forsyth /* IBLTF */ Use3, Fopb,
31037da2899SCharles.Forsyth /* IBLEF */ Use3, Fopb,
31137da2899SCharles.Forsyth /* IBGTF */ Use3, Fopb,
31237da2899SCharles.Forsyth /* IBGEF */ Use3, Fopb,
31337da2899SCharles.Forsyth /* IBEQC */ Use3, Copb,
31437da2899SCharles.Forsyth /* IBNEC */ Use3, Copb,
31537da2899SCharles.Forsyth /* IBLTC */ Use3, Copb,
31637da2899SCharles.Forsyth /* IBLEC */ Use3, Copb,
31737da2899SCharles.Forsyth /* IBGTC */ Use3, Copb,
31837da2899SCharles.Forsyth /* IBGEC */ Use3, Copb,
31937da2899SCharles.Forsyth /* ISLICEA */ Mabinop, S(W)|M(W)|D(P),
32037da2899SCharles.Forsyth /* ISLICELA */ Use3, S(P)|M(W)|D(P),
32137da2899SCharles.Forsyth /* ISLICEC */ Mabinop, S(W)|M(W)|D(C),
32237da2899SCharles.Forsyth /* IINDW */ Mbinop, S(P)|M(P)|D(W),
32337da2899SCharles.Forsyth /* IINDF */ Mbinop, S(P)|M(P)|D(W),
32437da2899SCharles.Forsyth /* IINDB */ Mbinop, S(P)|M(P)|D(W),
32537da2899SCharles.Forsyth /* INEGF */ Unop, Fop2,
32637da2899SCharles.Forsyth /* IMOVL */ Unop, Lop2,
32737da2899SCharles.Forsyth /* IADDL */ Binop, Lop,
32837da2899SCharles.Forsyth /* ISUBL */ Binop, Lop,
32937da2899SCharles.Forsyth /* IDIVL */ Binop, Lop,
33037da2899SCharles.Forsyth /* IMODL */ Binop, Lop,
33137da2899SCharles.Forsyth /* IMULL */ Binop, Lop,
33237da2899SCharles.Forsyth /* IANDL */ Binop, Lop,
33337da2899SCharles.Forsyth /* IORL */ Binop, Lop,
33437da2899SCharles.Forsyth /* IXORL */ Binop, Lop,
33537da2899SCharles.Forsyth /* ISHLL */ Binop, S(W)|M(L)|D(L),
33637da2899SCharles.Forsyth /* ISHRL */ Binop, S(W)|M(L)|D(L),
33737da2899SCharles.Forsyth /* IBNEL */ Use3, Lopb,
33837da2899SCharles.Forsyth /* IBLTL */ Use3, Lopb,
33937da2899SCharles.Forsyth /* IBLEL */ Use3, Lopb,
34037da2899SCharles.Forsyth /* IBGTL */ Use3, Lopb,
34137da2899SCharles.Forsyth /* IBGEL */ Use3, Lopb,
34237da2899SCharles.Forsyth /* IBEQL */ Use3, Lopb,
34337da2899SCharles.Forsyth /* ICVTLF */ Unop, S(L)|D(F),
34437da2899SCharles.Forsyth /* ICVTFL */ Unop, S(F)|D(L),
34537da2899SCharles.Forsyth /* ICVTLW */ Unop, S(L)|D(W),
34637da2899SCharles.Forsyth /* ICVTWL */ Unop, S(W)|D(L),
34737da2899SCharles.Forsyth /* ICVTLC */ Unop, S(L)|D(C),
34837da2899SCharles.Forsyth /* ICVTCL */ Unop, S(C)|D(L),
34937da2899SCharles.Forsyth /* IHEADL */ Unop, S(P)|D(L),
35037da2899SCharles.Forsyth /* ICONSL */ Abinop, S(L)|D(P),
35137da2899SCharles.Forsyth /* INEWCL */ Cunop, M(W)|D(P),
35237da2899SCharles.Forsyth /* ICASEC */ Use2, S(C)|D(I),
35337da2899SCharles.Forsyth /* IINDL */ Mbinop, S(P)|M(P)|D(W),
35437da2899SCharles.Forsyth /* IMOVPC */ Unop, S(W)|D(P),
35537da2899SCharles.Forsyth /* ITCMP */ Use2, S(P)|D(P),
35637da2899SCharles.Forsyth /* IMNEWZ */ Threop, S(P)|M(W)|D(P),
35737da2899SCharles.Forsyth /* ICVTRF */ Unop, S(R)|D(F),
35837da2899SCharles.Forsyth /* ICVTFR */ Unop, S(F)|D(R),
35937da2899SCharles.Forsyth /* ICVTWS */ Unop, S(W)|D(Sh),
36037da2899SCharles.Forsyth /* ICVTSW */ Unop, S(Sh)|D(W),
36137da2899SCharles.Forsyth /* ILSRW */ Binop, Wop,
36237da2899SCharles.Forsyth /* ILSRL */ Binop, S(W)|M(L)|D(L),
36337da2899SCharles.Forsyth /* IECLR */ None, 0,
36437da2899SCharles.Forsyth /* INEWZ */ Unop, S(W)|D(P),
36537da2899SCharles.Forsyth /* INEWAZ */ Threop, S(W)|M(W)|D(P),
36637da2899SCharles.Forsyth /* IRAISE */ Use1, S(P),
36737da2899SCharles.Forsyth /* ICASEL */ Use2, S(L)|D(I),
36837da2899SCharles.Forsyth /* IMULX */ Binop|Tuse2, Xop,
36937da2899SCharles.Forsyth /* IDIVX */ Binop|Tuse2, Xop,
37037da2899SCharles.Forsyth /* ICVTXX */ Threop, Xop,
37137da2899SCharles.Forsyth /* IMULX0 */ Binop|Tuse1|Tuse2, Xop,
37237da2899SCharles.Forsyth /* IDIVX0 */ Binop|Tuse1|Tuse2, Xop,
37337da2899SCharles.Forsyth /* ICVTXX0 */ Threop|Tuse1, Xop,
37437da2899SCharles.Forsyth /* IMULX1 */ Binop|Tuse1|Tuse2, Xop,
37537da2899SCharles.Forsyth /* IDIVX1 */ Binop|Tuse1|Tuse2, Xop,
37637da2899SCharles.Forsyth /* ICVTXX1 */ Threop|Tuse1, Xop,
37737da2899SCharles.Forsyth /* ICVTFX */ Threop, S(F)|M(F)|D(X),
37837da2899SCharles.Forsyth /* ICVTXF */ Threop, S(X)|M(F)|D(F),
37937da2899SCharles.Forsyth /* IEXPW */ Binop, S(W)|M(W)|D(W),
38037da2899SCharles.Forsyth /* IEXPL */ Binop, S(W)|M(L)|D(L),
38137da2899SCharles.Forsyth /* IEXPF */ Binop, S(W)|M(F)|D(F),
38237da2899SCharles.Forsyth /* ISELF */ Ddef, D(P),
38337da2899SCharles.Forsyth /* IEXC */ None, 0,
38437da2899SCharles.Forsyth /* IEXC0 */ None, 0,
38537da2899SCharles.Forsyth /* INOOP */ None, 0,
38637da2899SCharles.Forsyth };
38737da2899SCharles.Forsyth
38837da2899SCharles.Forsyth /*
38937da2899SCharles.Forsyth static int
39037da2899SCharles.Forsyth pop(int i)
39137da2899SCharles.Forsyth {
39237da2899SCharles.Forsyth i = (i & 0x55555555) + ((i>>1) & 0x55555555);
39337da2899SCharles.Forsyth i = (i & 0x33333333) + ((i>>2) & 0x33333333);
39437da2899SCharles.Forsyth i = (i & 0x0F0F0F0F) + ((i>>4) & 0x0F0F0F0F);
39537da2899SCharles.Forsyth i = (i & 0x00FF00FF) + ((i>>8) & 0x00FF00FF);
39637da2899SCharles.Forsyth i = (i & 0x0000FFFF) + ((i>>16) & 0x0000FFFF);
39737da2899SCharles.Forsyth return i;
39837da2899SCharles.Forsyth }
39937da2899SCharles.Forsyth */
40037da2899SCharles.Forsyth
40137da2899SCharles.Forsyth static int
bitc(uint x)40237da2899SCharles.Forsyth bitc(uint x)
40337da2899SCharles.Forsyth {
40437da2899SCharles.Forsyth uint n;
40537da2899SCharles.Forsyth
40637da2899SCharles.Forsyth n = (x>>1)&0x77777777;
40737da2899SCharles.Forsyth x -= n;
40837da2899SCharles.Forsyth n = (n>>1)&0x77777777;
40937da2899SCharles.Forsyth x -= n;
41037da2899SCharles.Forsyth n = (n>>1)&0x77777777;
41137da2899SCharles.Forsyth x -= n;
41237da2899SCharles.Forsyth x = (x+(x>>4))&0x0f0f0f0f;
41337da2899SCharles.Forsyth x *= 0x01010101;
41437da2899SCharles.Forsyth return x>>24;
41537da2899SCharles.Forsyth }
41637da2899SCharles.Forsyth
41737da2899SCharles.Forsyth /*
41837da2899SCharles.Forsyth static int
41937da2899SCharles.Forsyth top(uint x)
42037da2899SCharles.Forsyth {
42137da2899SCharles.Forsyth int i;
42237da2899SCharles.Forsyth
42337da2899SCharles.Forsyth for(i = -1; x; i++)
42437da2899SCharles.Forsyth x >>= 1;
42537da2899SCharles.Forsyth return i;
42637da2899SCharles.Forsyth }
42737da2899SCharles.Forsyth */
42837da2899SCharles.Forsyth
42937da2899SCharles.Forsyth static int
topb(uint x)43037da2899SCharles.Forsyth topb(uint x)
43137da2899SCharles.Forsyth {
43237da2899SCharles.Forsyth int i;
43337da2899SCharles.Forsyth
43437da2899SCharles.Forsyth if(x == 0)
43537da2899SCharles.Forsyth return -1;
43637da2899SCharles.Forsyth i = 0;
43737da2899SCharles.Forsyth if(x&0xffff0000){
43837da2899SCharles.Forsyth i |= 16;
43937da2899SCharles.Forsyth x >>= 16;
44037da2899SCharles.Forsyth }
44137da2899SCharles.Forsyth if(x&0xff00){
44237da2899SCharles.Forsyth i |= 8;
44337da2899SCharles.Forsyth x >>= 8;
44437da2899SCharles.Forsyth }
44537da2899SCharles.Forsyth if(x&0xf0){
44637da2899SCharles.Forsyth i |= 4;
44737da2899SCharles.Forsyth x >>= 4;
44837da2899SCharles.Forsyth }
44937da2899SCharles.Forsyth if(x&0xc){
45037da2899SCharles.Forsyth i |= 2;
45137da2899SCharles.Forsyth x >>= 2;
45237da2899SCharles.Forsyth }
45337da2899SCharles.Forsyth if(x&0x2)
45437da2899SCharles.Forsyth i |= 1;
45537da2899SCharles.Forsyth return i;
45637da2899SCharles.Forsyth }
45737da2899SCharles.Forsyth
45837da2899SCharles.Forsyth /*
45937da2899SCharles.Forsyth static int
46037da2899SCharles.Forsyth lowb(uint x)
46137da2899SCharles.Forsyth {
46237da2899SCharles.Forsyth int i;
46337da2899SCharles.Forsyth
46437da2899SCharles.Forsyth if(x == 0)
46537da2899SCharles.Forsyth return -1;
46637da2899SCharles.Forsyth for(i = BLEN; x; i--)
46737da2899SCharles.Forsyth x <<= 1;
46837da2899SCharles.Forsyth return i;
46937da2899SCharles.Forsyth }
47037da2899SCharles.Forsyth */
47137da2899SCharles.Forsyth
47237da2899SCharles.Forsyth static int
lowb(uint x)47337da2899SCharles.Forsyth lowb(uint x)
47437da2899SCharles.Forsyth {
47537da2899SCharles.Forsyth int i;
47637da2899SCharles.Forsyth
47737da2899SCharles.Forsyth if(x == 0)
47837da2899SCharles.Forsyth return -1;
47937da2899SCharles.Forsyth i = 0;
48037da2899SCharles.Forsyth if((x&0xffff) == 0){
48137da2899SCharles.Forsyth i |= 16;
48237da2899SCharles.Forsyth x >>= 16;
48337da2899SCharles.Forsyth }
48437da2899SCharles.Forsyth if((x&0xff) == 0){
48537da2899SCharles.Forsyth i |= 8;
48637da2899SCharles.Forsyth x >>= 8;
48737da2899SCharles.Forsyth }
48837da2899SCharles.Forsyth if((x&0xf) == 0){
48937da2899SCharles.Forsyth i |= 4;
49037da2899SCharles.Forsyth x >>= 4;
49137da2899SCharles.Forsyth }
49237da2899SCharles.Forsyth if((x&0x3) == 0){
49337da2899SCharles.Forsyth i |= 2;
49437da2899SCharles.Forsyth x >>= 2;
49537da2899SCharles.Forsyth }
49637da2899SCharles.Forsyth return i+1-(x&1);
49737da2899SCharles.Forsyth }
49837da2899SCharles.Forsyth
49937da2899SCharles.Forsyth static void
pbit(int x,int n)50037da2899SCharles.Forsyth pbit(int x, int n)
50137da2899SCharles.Forsyth {
50237da2899SCharles.Forsyth int i, m;
50337da2899SCharles.Forsyth
50437da2899SCharles.Forsyth m = 1;
50537da2899SCharles.Forsyth for(i = 0; i < BLEN; i++){
50637da2899SCharles.Forsyth if(x&m)
50737da2899SCharles.Forsyth print("%d ", i+n);
50837da2899SCharles.Forsyth m <<= 1;
50937da2899SCharles.Forsyth }
51037da2899SCharles.Forsyth }
51137da2899SCharles.Forsyth
51237da2899SCharles.Forsyth static ulong
bop(int o,ulong s,ulong d)51337da2899SCharles.Forsyth bop(int o, ulong s, ulong d)
51437da2899SCharles.Forsyth {
51537da2899SCharles.Forsyth switch(o){
51637da2899SCharles.Forsyth case Bclr: return 0;
51737da2899SCharles.Forsyth case Band: return s & d;
51837da2899SCharles.Forsyth case Bandinv: return s & ~d;
51937da2899SCharles.Forsyth case Bstore: return s;
52037da2899SCharles.Forsyth case Bandrev: return ~s & d;
52137da2899SCharles.Forsyth case Bnoop: return d;
52237da2899SCharles.Forsyth case Bxor: return s ^ d;
52337da2899SCharles.Forsyth case Bor: return s | d;
52437da2899SCharles.Forsyth case Bnor: return ~(s | d);
52537da2899SCharles.Forsyth case Bequiv: return ~(s ^ d);
52637da2899SCharles.Forsyth case Binv: return ~d;
52737da2899SCharles.Forsyth case Bimpby: return s | ~d;
52837da2899SCharles.Forsyth case Brev: return ~s;
52937da2899SCharles.Forsyth case Bimp: return ~s | d;
53037da2899SCharles.Forsyth case Bnand: return ~(s & d);
53137da2899SCharles.Forsyth case Bset: return 0xffffffff;
53237da2899SCharles.Forsyth }
53337da2899SCharles.Forsyth return 0;
53437da2899SCharles.Forsyth }
53537da2899SCharles.Forsyth
53637da2899SCharles.Forsyth static Bits
bnew(int n,int bits)53737da2899SCharles.Forsyth bnew(int n, int bits)
53837da2899SCharles.Forsyth {
53937da2899SCharles.Forsyth Bits b;
54037da2899SCharles.Forsyth
54137da2899SCharles.Forsyth if(bits)
54237da2899SCharles.Forsyth b.n = (n+BLEN-1)>>BSHIFT;
54337da2899SCharles.Forsyth else
54437da2899SCharles.Forsyth b.n = n;
54537da2899SCharles.Forsyth b.b = allocmem(b.n*sizeof(ulong));
54637da2899SCharles.Forsyth memset(b.b, 0, b.n*sizeof(ulong));
54737da2899SCharles.Forsyth return b;
54837da2899SCharles.Forsyth }
54937da2899SCharles.Forsyth
55037da2899SCharles.Forsyth static void
bfree(Bits b)55137da2899SCharles.Forsyth bfree(Bits b)
55237da2899SCharles.Forsyth {
55337da2899SCharles.Forsyth free(b.b);
55437da2899SCharles.Forsyth }
55537da2899SCharles.Forsyth
55637da2899SCharles.Forsyth static void
bset(Bits b,int n)55737da2899SCharles.Forsyth bset(Bits b, int n)
55837da2899SCharles.Forsyth {
55937da2899SCharles.Forsyth b.b[n>>BSHIFT] |= 1<<(n&BMASK);
56037da2899SCharles.Forsyth }
56137da2899SCharles.Forsyth
56237da2899SCharles.Forsyth static void
bclr(Bits b,int n)56337da2899SCharles.Forsyth bclr(Bits b, int n)
56437da2899SCharles.Forsyth {
56537da2899SCharles.Forsyth b.b[n>>BSHIFT] &= ~(1<<(n&BMASK));
56637da2899SCharles.Forsyth }
56737da2899SCharles.Forsyth
56837da2899SCharles.Forsyth static int
bmem(Bits b,int n)56937da2899SCharles.Forsyth bmem(Bits b, int n)
57037da2899SCharles.Forsyth {
57137da2899SCharles.Forsyth return b.b[n>>BSHIFT] & (1<<(n&BMASK));
57237da2899SCharles.Forsyth }
57337da2899SCharles.Forsyth
57437da2899SCharles.Forsyth static void
bsets(Bits b,int m,int n)57537da2899SCharles.Forsyth bsets(Bits b, int m, int n)
57637da2899SCharles.Forsyth {
57737da2899SCharles.Forsyth int i, c1, c2;
57837da2899SCharles.Forsyth
57937da2899SCharles.Forsyth c1 = m>>BSHIFT;
58037da2899SCharles.Forsyth c2 = n>>BSHIFT;
58137da2899SCharles.Forsyth m &= BMASK;
58237da2899SCharles.Forsyth n &= BMASK;
58337da2899SCharles.Forsyth if(c1 == c2){
58437da2899SCharles.Forsyth b.b[c1] |= MASK(m, n);
58537da2899SCharles.Forsyth return;
58637da2899SCharles.Forsyth }
58737da2899SCharles.Forsyth for(i = c1+1; i < c2; i++)
58837da2899SCharles.Forsyth b.b[i] = 0xffffffff;
58937da2899SCharles.Forsyth b.b[c1] |= MASK(m, BLEN-1);
59037da2899SCharles.Forsyth b.b[c2] |= MASK(0, n);
59137da2899SCharles.Forsyth }
59237da2899SCharles.Forsyth
59337da2899SCharles.Forsyth static void
bclrs(Bits b,int m,int n)59437da2899SCharles.Forsyth bclrs(Bits b, int m, int n)
59537da2899SCharles.Forsyth {
59637da2899SCharles.Forsyth int i, c1, c2;
59737da2899SCharles.Forsyth
59837da2899SCharles.Forsyth if(n < 0)
59937da2899SCharles.Forsyth n = (b.n<<BSHIFT)-1;
60037da2899SCharles.Forsyth c1 = m>>BSHIFT;
60137da2899SCharles.Forsyth c2 = n>>BSHIFT;
60237da2899SCharles.Forsyth m &= BMASK;
60337da2899SCharles.Forsyth n &= BMASK;
60437da2899SCharles.Forsyth if(c1 == c2){
60537da2899SCharles.Forsyth b.b[c1] &= ~MASK(m, n);
60637da2899SCharles.Forsyth return;
60737da2899SCharles.Forsyth }
60837da2899SCharles.Forsyth for(i = c1+1; i < c2; i++)
60937da2899SCharles.Forsyth b.b[i] = 0;
61037da2899SCharles.Forsyth b.b[c1] &= ~MASK(m, BLEN-1);
61137da2899SCharles.Forsyth b.b[c2] &= ~MASK(0, n);
61237da2899SCharles.Forsyth }
61337da2899SCharles.Forsyth
61437da2899SCharles.Forsyth /* b = a op b */
61537da2899SCharles.Forsyth static Bits
boper(int o,Bits a,Bits b)61637da2899SCharles.Forsyth boper(int o, Bits a, Bits b)
61737da2899SCharles.Forsyth {
61837da2899SCharles.Forsyth int i, n;
61937da2899SCharles.Forsyth
62037da2899SCharles.Forsyth n = a.n;
62137da2899SCharles.Forsyth if(b.n != n)
62237da2899SCharles.Forsyth fatal("boper %d %d %d", o, a.n, b.n);
62337da2899SCharles.Forsyth for(i = 0; i < n; i++)
62437da2899SCharles.Forsyth b.b[i] = bop(o, a.b[i], b.b[i]);
62537da2899SCharles.Forsyth return b;
62637da2899SCharles.Forsyth }
62737da2899SCharles.Forsyth
62837da2899SCharles.Forsyth static int
beq(Bits a,Bits b)62937da2899SCharles.Forsyth beq(Bits a, Bits b)
63037da2899SCharles.Forsyth {
63137da2899SCharles.Forsyth int i, n;
63237da2899SCharles.Forsyth
63337da2899SCharles.Forsyth n = a.n;
63437da2899SCharles.Forsyth for(i = 0; i < n; i++)
63537da2899SCharles.Forsyth if(a.b[i] != b.b[i])
63637da2899SCharles.Forsyth return 0;
63737da2899SCharles.Forsyth return 1;
63837da2899SCharles.Forsyth }
63937da2899SCharles.Forsyth
64037da2899SCharles.Forsyth static int
bzero(Bits b)64137da2899SCharles.Forsyth bzero(Bits b)
64237da2899SCharles.Forsyth {
64337da2899SCharles.Forsyth int i, n;
64437da2899SCharles.Forsyth
64537da2899SCharles.Forsyth n = b.n;
64637da2899SCharles.Forsyth for(i = 0; i < n; i++)
64737da2899SCharles.Forsyth if(b.b[i] != 0)
64837da2899SCharles.Forsyth return 0;
64937da2899SCharles.Forsyth return 1;
65037da2899SCharles.Forsyth }
65137da2899SCharles.Forsyth
65237da2899SCharles.Forsyth static int
bitcnt(Bits b)65337da2899SCharles.Forsyth bitcnt(Bits b)
65437da2899SCharles.Forsyth {
65537da2899SCharles.Forsyth int i, m, n;
65637da2899SCharles.Forsyth
65737da2899SCharles.Forsyth m = b.n;
65837da2899SCharles.Forsyth n = 0;
65937da2899SCharles.Forsyth for(i = 0; i < m; i++)
66037da2899SCharles.Forsyth n += bitc(b.b[i]);
66137da2899SCharles.Forsyth return n;
66237da2899SCharles.Forsyth }
66337da2899SCharles.Forsyth
66437da2899SCharles.Forsyth static int
topbit(Bits b)66537da2899SCharles.Forsyth topbit(Bits b)
66637da2899SCharles.Forsyth {
66737da2899SCharles.Forsyth int i, n;
66837da2899SCharles.Forsyth
66937da2899SCharles.Forsyth n = b.n;
67037da2899SCharles.Forsyth for(i = n-1; i >= 0; i--)
67137da2899SCharles.Forsyth if(b.b[i] != 0)
67237da2899SCharles.Forsyth return (i<<BSHIFT)+topb(b.b[i]);
67337da2899SCharles.Forsyth return -1;
67437da2899SCharles.Forsyth }
67537da2899SCharles.Forsyth
67637da2899SCharles.Forsyth static int
lowbit(Bits b)67737da2899SCharles.Forsyth lowbit(Bits b)
67837da2899SCharles.Forsyth {
67937da2899SCharles.Forsyth int i, n;
68037da2899SCharles.Forsyth
68137da2899SCharles.Forsyth n = b.n;
68237da2899SCharles.Forsyth for(i = 0; i < n; i++)
68337da2899SCharles.Forsyth if(b.b[i] != 0)
68437da2899SCharles.Forsyth return (i<<BSHIFT)+lowb(b.b[i]);
68537da2899SCharles.Forsyth return -1;
68637da2899SCharles.Forsyth }
68737da2899SCharles.Forsyth
68837da2899SCharles.Forsyth static void
pbits(Bits b)68937da2899SCharles.Forsyth pbits(Bits b)
69037da2899SCharles.Forsyth {
69137da2899SCharles.Forsyth int i, n;
69237da2899SCharles.Forsyth
69337da2899SCharles.Forsyth n = b.n;
69437da2899SCharles.Forsyth for(i = 0; i < n; i++)
69537da2899SCharles.Forsyth pbit(b.b[i], i<<BSHIFT);
69637da2899SCharles.Forsyth }
69737da2899SCharles.Forsyth
69837da2899SCharles.Forsyth static char*
decname(Decl * d)69937da2899SCharles.Forsyth decname(Decl *d)
70037da2899SCharles.Forsyth {
70137da2899SCharles.Forsyth if(d->sym == nil)
7026e425a9dSCharles.Forsyth return "<nil>";
70337da2899SCharles.Forsyth return d->sym->name;
70437da2899SCharles.Forsyth }
70537da2899SCharles.Forsyth
70637da2899SCharles.Forsyth static void
warning(Inst * i,char * s,Decl * d,Decl * sd)70737da2899SCharles.Forsyth warning(Inst *i, char *s, Decl *d, Decl *sd)
70837da2899SCharles.Forsyth {
70937da2899SCharles.Forsyth int n;
71037da2899SCharles.Forsyth char *f;
71137da2899SCharles.Forsyth Decl *ds;
71237da2899SCharles.Forsyth
71337da2899SCharles.Forsyth n = 0;
71437da2899SCharles.Forsyth for(ds = sd; ds != nil; ds = ds->next)
71537da2899SCharles.Forsyth if(ds->link == d)
71637da2899SCharles.Forsyth n += strlen(ds->sym->name)+1;
71737da2899SCharles.Forsyth if(n == 0){
71837da2899SCharles.Forsyth warn(i->src.start, "%s: %s", d->sym->name, s);
71937da2899SCharles.Forsyth return;
72037da2899SCharles.Forsyth }
72137da2899SCharles.Forsyth n += strlen(d->sym->name);
72237da2899SCharles.Forsyth f = malloc(n+1);
72337da2899SCharles.Forsyth strcpy(f, d->sym->name);
72437da2899SCharles.Forsyth for(ds = sd; ds != nil; ds = ds->next){
72537da2899SCharles.Forsyth if(ds->link == d){
72637da2899SCharles.Forsyth strcat(f, "/");
72737da2899SCharles.Forsyth strcat(f, ds->sym->name);
72837da2899SCharles.Forsyth }
72937da2899SCharles.Forsyth }
73037da2899SCharles.Forsyth warn(i->src.start, "%s: %s", f, s);
73137da2899SCharles.Forsyth free(f);
73237da2899SCharles.Forsyth }
73337da2899SCharles.Forsyth
73437da2899SCharles.Forsyth static int
inspc(Inst * in)73537da2899SCharles.Forsyth inspc(Inst *in)
73637da2899SCharles.Forsyth {
73737da2899SCharles.Forsyth int n;
73837da2899SCharles.Forsyth Inst *i;
73937da2899SCharles.Forsyth
74037da2899SCharles.Forsyth n = 0;
74137da2899SCharles.Forsyth for(i = in; i != nil; i = i->next)
74237da2899SCharles.Forsyth i->pc = n++;
74337da2899SCharles.Forsyth return n;
74437da2899SCharles.Forsyth }
74537da2899SCharles.Forsyth
74637da2899SCharles.Forsyth static Inst*
pc2i(Block * b,int pc)74737da2899SCharles.Forsyth pc2i(Block *b, int pc)
74837da2899SCharles.Forsyth {
74937da2899SCharles.Forsyth Inst *i;
75037da2899SCharles.Forsyth
75137da2899SCharles.Forsyth for( ; b != nil; b = b->next){
75237da2899SCharles.Forsyth if(pc > b->last->pc)
75337da2899SCharles.Forsyth continue;
75437da2899SCharles.Forsyth for(i = b->first; ; i = i->next){
75537da2899SCharles.Forsyth if(i->pc == pc)
75637da2899SCharles.Forsyth return i;
75737da2899SCharles.Forsyth if(i == b->last)
75837da2899SCharles.Forsyth fatal("pc2i a");
75937da2899SCharles.Forsyth }
76037da2899SCharles.Forsyth }
76137da2899SCharles.Forsyth fatal("pc2i b");
76237da2899SCharles.Forsyth return nil;
76337da2899SCharles.Forsyth }
76437da2899SCharles.Forsyth
76537da2899SCharles.Forsyth static void
padr(int am,Addr * a,Inst * br)76637da2899SCharles.Forsyth padr(int am, Addr *a, Inst *br)
76737da2899SCharles.Forsyth {
76837da2899SCharles.Forsyth long reg;
76937da2899SCharles.Forsyth
77037da2899SCharles.Forsyth if(br != nil){
77137da2899SCharles.Forsyth print("$%ld", br->pc);
77237da2899SCharles.Forsyth return;
77337da2899SCharles.Forsyth }
77437da2899SCharles.Forsyth reg = a->reg;
77537da2899SCharles.Forsyth if(a->decl != nil && am != Adesc)
77637da2899SCharles.Forsyth reg += a->decl->offset;
77737da2899SCharles.Forsyth switch(am){
77837da2899SCharles.Forsyth case Anone:
77937da2899SCharles.Forsyth print("-");
78037da2899SCharles.Forsyth break;
78137da2899SCharles.Forsyth case Aimm:
78237da2899SCharles.Forsyth case Apc:
78337da2899SCharles.Forsyth case Adesc:
78437da2899SCharles.Forsyth print("$%ld", a->offset);
78537da2899SCharles.Forsyth break;
78637da2899SCharles.Forsyth case Aoff:
78737da2899SCharles.Forsyth print("$%ld", a->decl->iface->offset);
78837da2899SCharles.Forsyth break;
78937da2899SCharles.Forsyth case Anoff:
79037da2899SCharles.Forsyth print("-$%ld", a->decl->iface->offset);
79137da2899SCharles.Forsyth break;
79237da2899SCharles.Forsyth case Afp:
79337da2899SCharles.Forsyth print("%ld(fp)", reg);
79437da2899SCharles.Forsyth break;
79537da2899SCharles.Forsyth case Afpind:
79637da2899SCharles.Forsyth print("%ld(%ld(fp))", a->offset, reg);
79737da2899SCharles.Forsyth break;
79837da2899SCharles.Forsyth case Amp:
79937da2899SCharles.Forsyth print("%ld(mp)", reg);
80037da2899SCharles.Forsyth break;
80137da2899SCharles.Forsyth case Ampind:
80237da2899SCharles.Forsyth print("%ld(%ld(mp))", a->offset, reg);
80337da2899SCharles.Forsyth break;
80437da2899SCharles.Forsyth case Aldt:
80537da2899SCharles.Forsyth print("$%ld", reg);
80637da2899SCharles.Forsyth break;
80737da2899SCharles.Forsyth case Aerr:
80837da2899SCharles.Forsyth default:
80937da2899SCharles.Forsyth print("%ld(%ld(?%d?))", a->offset, reg, am);
81037da2899SCharles.Forsyth break;
81137da2899SCharles.Forsyth }
81237da2899SCharles.Forsyth }
81337da2899SCharles.Forsyth
81437da2899SCharles.Forsyth static void
pins(Inst * i)81537da2899SCharles.Forsyth pins(Inst *i)
81637da2899SCharles.Forsyth {
81737da2899SCharles.Forsyth /* print("%L %ld ", i->src.start, i->pc); */
81837da2899SCharles.Forsyth print(" %ld ", i->pc);
819*1ca4518dSCharles.Forsyth if(i->op < MAXDIS)
82037da2899SCharles.Forsyth print("%s", instname[i->op]);
82137da2899SCharles.Forsyth else
82237da2899SCharles.Forsyth print("noop");
82337da2899SCharles.Forsyth print(" ");
82437da2899SCharles.Forsyth padr(i->sm, &i->s, nil);
82537da2899SCharles.Forsyth print(", ");
82637da2899SCharles.Forsyth padr(i->mm, &i->m, nil);
82737da2899SCharles.Forsyth print(", ");
82837da2899SCharles.Forsyth padr(i->dm, &i->d, i->branch);
82937da2899SCharles.Forsyth print("\n");
83037da2899SCharles.Forsyth }
83137da2899SCharles.Forsyth
83237da2899SCharles.Forsyth static void
blfree(Blist * bl)83337da2899SCharles.Forsyth blfree(Blist *bl)
83437da2899SCharles.Forsyth {
83537da2899SCharles.Forsyth Blist *nbl;
83637da2899SCharles.Forsyth
83737da2899SCharles.Forsyth for( ; bl != nil; bl = nbl){
83837da2899SCharles.Forsyth nbl = bl->next;
83937da2899SCharles.Forsyth free(bl);
84037da2899SCharles.Forsyth }
84137da2899SCharles.Forsyth }
84237da2899SCharles.Forsyth
84337da2899SCharles.Forsyth static void
freebits(Bits * bs,int nv)84437da2899SCharles.Forsyth freebits(Bits *bs, int nv)
84537da2899SCharles.Forsyth {
84637da2899SCharles.Forsyth int i;
84737da2899SCharles.Forsyth
84837da2899SCharles.Forsyth for(i = 0; i < nv; i++)
84937da2899SCharles.Forsyth bfree(bs[i]);
85037da2899SCharles.Forsyth free(bs);
85137da2899SCharles.Forsyth }
85237da2899SCharles.Forsyth
85337da2899SCharles.Forsyth static void
freeblks(Block * b)85437da2899SCharles.Forsyth freeblks(Block *b)
85537da2899SCharles.Forsyth {
85637da2899SCharles.Forsyth Block *nb;
85737da2899SCharles.Forsyth
85837da2899SCharles.Forsyth for( ; b != nil; b = nb){
85937da2899SCharles.Forsyth blfree(b->pred);
86037da2899SCharles.Forsyth blfree(b->succ);
86137da2899SCharles.Forsyth bfree(b->kill);
86237da2899SCharles.Forsyth bfree(b->gen);
86337da2899SCharles.Forsyth bfree(b->in);
86437da2899SCharles.Forsyth bfree(b->out);
86537da2899SCharles.Forsyth nb = b->next;
86637da2899SCharles.Forsyth free(b);
86737da2899SCharles.Forsyth }
86837da2899SCharles.Forsyth }
86937da2899SCharles.Forsyth
87037da2899SCharles.Forsyth static int
len(Decl * d)87137da2899SCharles.Forsyth len(Decl *d)
87237da2899SCharles.Forsyth {
87337da2899SCharles.Forsyth int n;
87437da2899SCharles.Forsyth
87537da2899SCharles.Forsyth n = 0;
87637da2899SCharles.Forsyth for( ; d != nil; d = d->next)
87737da2899SCharles.Forsyth n++;
87837da2899SCharles.Forsyth return n;
87937da2899SCharles.Forsyth }
88037da2899SCharles.Forsyth
88137da2899SCharles.Forsyth static Bits*
allocbits(int nv,int npc)88237da2899SCharles.Forsyth allocbits(int nv, int npc)
88337da2899SCharles.Forsyth {
88437da2899SCharles.Forsyth int i;
88537da2899SCharles.Forsyth Bits *defs;
88637da2899SCharles.Forsyth
88737da2899SCharles.Forsyth defs = (Bits*)allocmem(nv*sizeof(Bits));
88837da2899SCharles.Forsyth for(i = 0; i < nv; i++)
88937da2899SCharles.Forsyth defs[i] = bnew(npc, 1);
89037da2899SCharles.Forsyth return defs;
89137da2899SCharles.Forsyth }
89237da2899SCharles.Forsyth
89337da2899SCharles.Forsyth static int
bitcount(Bits * bs,int nv)89437da2899SCharles.Forsyth bitcount(Bits *bs, int nv)
89537da2899SCharles.Forsyth {
89637da2899SCharles.Forsyth int i, n;
89737da2899SCharles.Forsyth
89837da2899SCharles.Forsyth n = 0;
89937da2899SCharles.Forsyth for(i = 0; i < nv; i++)
90037da2899SCharles.Forsyth n += bitcnt(bs[i]);
90137da2899SCharles.Forsyth return n;
90237da2899SCharles.Forsyth }
90337da2899SCharles.Forsyth
90437da2899SCharles.Forsyth static Block*
mkblock(Inst * i)90537da2899SCharles.Forsyth mkblock(Inst *i)
90637da2899SCharles.Forsyth {
90737da2899SCharles.Forsyth Block *b;
90837da2899SCharles.Forsyth
90937da2899SCharles.Forsyth b = allocmem(sizeof(Block));
91037da2899SCharles.Forsyth *b = zblock;
91137da2899SCharles.Forsyth b->first = b->last = i;
91237da2899SCharles.Forsyth return b;
91337da2899SCharles.Forsyth }
91437da2899SCharles.Forsyth
91537da2899SCharles.Forsyth static Blist*
mkblist(Block * b,Blist * nbl)91637da2899SCharles.Forsyth mkblist(Block *b, Blist *nbl)
91737da2899SCharles.Forsyth {
91837da2899SCharles.Forsyth Blist *bl;
91937da2899SCharles.Forsyth
92037da2899SCharles.Forsyth bl = allocmem(sizeof(Blist));
92137da2899SCharles.Forsyth bl->block = b;
92237da2899SCharles.Forsyth bl->next = nbl;
92337da2899SCharles.Forsyth return bl;
92437da2899SCharles.Forsyth }
92537da2899SCharles.Forsyth
92637da2899SCharles.Forsyth static void
leader(Inst * i,Array * ab)92737da2899SCharles.Forsyth leader(Inst *i, Array *ab)
92837da2899SCharles.Forsyth {
92937da2899SCharles.Forsyth int m, n;
93037da2899SCharles.Forsyth Block *b, **a;
93137da2899SCharles.Forsyth
93237da2899SCharles.Forsyth if(i != nil && i->pc == 0){
93337da2899SCharles.Forsyth if((n = ab->n) == (m = ab->m)){
93437da2899SCharles.Forsyth a = ab->a;
93537da2899SCharles.Forsyth ab->a = allocmem(2*m*sizeof(Block*));
93637da2899SCharles.Forsyth memcpy(ab->a, a, m*sizeof(Block*));
93737da2899SCharles.Forsyth ab->m = 2*m;
93837da2899SCharles.Forsyth free(a);
93937da2899SCharles.Forsyth }
94037da2899SCharles.Forsyth b = mkblock(i);
94137da2899SCharles.Forsyth b->dfn = n;
94237da2899SCharles.Forsyth ab->a[n] = b;
94337da2899SCharles.Forsyth i->pc = ab->n = n+1;
94437da2899SCharles.Forsyth }
94537da2899SCharles.Forsyth }
94637da2899SCharles.Forsyth
94737da2899SCharles.Forsyth static Block*
findb(Inst * i,Array * ab)94837da2899SCharles.Forsyth findb(Inst *i, Array *ab)
94937da2899SCharles.Forsyth {
95037da2899SCharles.Forsyth if(i == nil)
95137da2899SCharles.Forsyth return nil;
95237da2899SCharles.Forsyth if(i->pc <= 0)
95337da2899SCharles.Forsyth fatal("pc <= 0 in findb");
95437da2899SCharles.Forsyth return ab->a[i->pc-1];
95537da2899SCharles.Forsyth }
95637da2899SCharles.Forsyth
95737da2899SCharles.Forsyth static int
memb(Block * b,Blist * bl)95837da2899SCharles.Forsyth memb(Block *b, Blist *bl)
95937da2899SCharles.Forsyth {
96037da2899SCharles.Forsyth for( ; bl != nil; bl = bl->next)
96137da2899SCharles.Forsyth if(bl->block == b)
96237da2899SCharles.Forsyth return 1;
96337da2899SCharles.Forsyth return 0;
96437da2899SCharles.Forsyth }
96537da2899SCharles.Forsyth
96637da2899SCharles.Forsyth static int
canfallthrough(Inst * i)96737da2899SCharles.Forsyth canfallthrough(Inst *i)
96837da2899SCharles.Forsyth {
96937da2899SCharles.Forsyth if(i == nil)
97037da2899SCharles.Forsyth return 0;
97137da2899SCharles.Forsyth switch(i->op){
97237da2899SCharles.Forsyth case IGOTO:
97337da2899SCharles.Forsyth case ICASE:
97437da2899SCharles.Forsyth case ICASEL:
97537da2899SCharles.Forsyth case ICASEC:
97637da2899SCharles.Forsyth case IRET:
97737da2899SCharles.Forsyth case IEXIT:
97837da2899SCharles.Forsyth case IRAISE:
97937da2899SCharles.Forsyth case IJMP:
98037da2899SCharles.Forsyth return 0;
98137da2899SCharles.Forsyth case INOOP:
98237da2899SCharles.Forsyth return i->branch != nil;
98337da2899SCharles.Forsyth }
98437da2899SCharles.Forsyth return 1;
98537da2899SCharles.Forsyth }
98637da2899SCharles.Forsyth
98737da2899SCharles.Forsyth static void
predsucc(Block * b1,Block * b2)98837da2899SCharles.Forsyth predsucc(Block *b1, Block *b2)
98937da2899SCharles.Forsyth {
99037da2899SCharles.Forsyth if(b1 == nil || b2 == nil)
99137da2899SCharles.Forsyth return;
99237da2899SCharles.Forsyth if(!memb(b1, b2->pred))
99337da2899SCharles.Forsyth b2->pred = mkblist(b1, b2->pred);
99437da2899SCharles.Forsyth if(!memb(b2, b1->succ))
99537da2899SCharles.Forsyth b1->succ = mkblist(b2, b1->succ);
99637da2899SCharles.Forsyth }
99737da2899SCharles.Forsyth
99837da2899SCharles.Forsyth static Block*
mkblocks(Inst * in,int * nb)99937da2899SCharles.Forsyth mkblocks(Inst *in, int *nb)
100037da2899SCharles.Forsyth {
100137da2899SCharles.Forsyth Inst *i;
100237da2899SCharles.Forsyth Block *b, *firstb, *lastb;
100337da2899SCharles.Forsyth Label *lab;
100437da2899SCharles.Forsyth Array *ab;
100537da2899SCharles.Forsyth int j, n;
100637da2899SCharles.Forsyth
100737da2899SCharles.Forsyth ab = allocmem(sizeof(Array));
100837da2899SCharles.Forsyth ab->n = 0;
100937da2899SCharles.Forsyth ab->m = 16;
101037da2899SCharles.Forsyth ab->a = allocmem(ab->m*sizeof(Block*));
101137da2899SCharles.Forsyth leader(in, ab);
101237da2899SCharles.Forsyth for(i = in; i != nil; i = i->next){
101337da2899SCharles.Forsyth switch(i->op){
101437da2899SCharles.Forsyth case IGOTO:
101537da2899SCharles.Forsyth case ICASE:
101637da2899SCharles.Forsyth case ICASEL:
101737da2899SCharles.Forsyth case ICASEC:
101837da2899SCharles.Forsyth case INOOP:
101937da2899SCharles.Forsyth if(i->op == INOOP && i->branch != nil){
102037da2899SCharles.Forsyth leader(i->branch, ab);
102137da2899SCharles.Forsyth leader(i->next, ab);
102237da2899SCharles.Forsyth break;
102337da2899SCharles.Forsyth }
102437da2899SCharles.Forsyth leader(i->d.decl->ty->cse->iwild, ab);
102537da2899SCharles.Forsyth lab = i->d.decl->ty->cse->labs;
102637da2899SCharles.Forsyth n = i->d.decl->ty->cse->nlab;
102737da2899SCharles.Forsyth for(j = 0; j < n; j++)
102837da2899SCharles.Forsyth leader(lab[j].inst, ab);
102937da2899SCharles.Forsyth leader(i->next, ab);
103037da2899SCharles.Forsyth break;
103137da2899SCharles.Forsyth case IRET:
103237da2899SCharles.Forsyth case IEXIT:
103337da2899SCharles.Forsyth case IRAISE:
103437da2899SCharles.Forsyth leader(i->next, ab);
103537da2899SCharles.Forsyth break;
103637da2899SCharles.Forsyth case IJMP:
103737da2899SCharles.Forsyth leader(i->branch, ab);
103837da2899SCharles.Forsyth leader(i->next, ab);
103937da2899SCharles.Forsyth break;
104037da2899SCharles.Forsyth default:
104137da2899SCharles.Forsyth if(i->branch != nil){
104237da2899SCharles.Forsyth leader(i->branch, ab);
104337da2899SCharles.Forsyth leader(i->next, ab);
104437da2899SCharles.Forsyth }
104537da2899SCharles.Forsyth break;
104637da2899SCharles.Forsyth }
104737da2899SCharles.Forsyth }
104837da2899SCharles.Forsyth firstb = lastb = mkblock(nil);
104937da2899SCharles.Forsyth for(i = in; i != nil; i = i->next){
105037da2899SCharles.Forsyth if(i->pc != 0){
105137da2899SCharles.Forsyth b = findb(i, ab);
105237da2899SCharles.Forsyth b->prev = lastb;
105337da2899SCharles.Forsyth lastb->next = b;
105437da2899SCharles.Forsyth if(canfallthrough(lastb->last))
105537da2899SCharles.Forsyth predsucc(lastb, b);
105637da2899SCharles.Forsyth lastb = b;
105737da2899SCharles.Forsyth }
105837da2899SCharles.Forsyth else
105937da2899SCharles.Forsyth lastb->last = i;
106037da2899SCharles.Forsyth switch(i->op){
106137da2899SCharles.Forsyth case IGOTO:
106237da2899SCharles.Forsyth case ICASE:
106337da2899SCharles.Forsyth case ICASEL:
106437da2899SCharles.Forsyth case ICASEC:
106537da2899SCharles.Forsyth case INOOP:
106637da2899SCharles.Forsyth if(i->op == INOOP && i->branch != nil){
106737da2899SCharles.Forsyth b = findb(i->next, ab);
106837da2899SCharles.Forsyth predsucc(lastb, b);
106937da2899SCharles.Forsyth b = findb(i->branch, ab);
107037da2899SCharles.Forsyth predsucc(lastb, b);
107137da2899SCharles.Forsyth break;
107237da2899SCharles.Forsyth }
107337da2899SCharles.Forsyth b = findb(i->d.decl->ty->cse->iwild, ab);
107437da2899SCharles.Forsyth predsucc(lastb, b);
107537da2899SCharles.Forsyth lab = i->d.decl->ty->cse->labs;
107637da2899SCharles.Forsyth n = i->d.decl->ty->cse->nlab;
107737da2899SCharles.Forsyth for(j = 0; j < n; j++){
107837da2899SCharles.Forsyth b = findb(lab[j].inst, ab);
107937da2899SCharles.Forsyth predsucc(lastb, b);
108037da2899SCharles.Forsyth }
108137da2899SCharles.Forsyth break;
108237da2899SCharles.Forsyth case IRET:
108337da2899SCharles.Forsyth case IEXIT:
108437da2899SCharles.Forsyth case IRAISE:
108537da2899SCharles.Forsyth break;
108637da2899SCharles.Forsyth case IJMP:
108737da2899SCharles.Forsyth b = findb(i->branch, ab);
108837da2899SCharles.Forsyth predsucc(lastb, b);
108937da2899SCharles.Forsyth break;
109037da2899SCharles.Forsyth default:
109137da2899SCharles.Forsyth if(i->branch != nil){
109237da2899SCharles.Forsyth b = findb(i->next, ab);
109337da2899SCharles.Forsyth predsucc(lastb, b);
109437da2899SCharles.Forsyth b = findb(i->branch, ab);
109537da2899SCharles.Forsyth predsucc(lastb, b);
109637da2899SCharles.Forsyth }
109737da2899SCharles.Forsyth break;
109837da2899SCharles.Forsyth }
109937da2899SCharles.Forsyth }
110037da2899SCharles.Forsyth *nb = ab->n;
110137da2899SCharles.Forsyth free(ab->a);
110237da2899SCharles.Forsyth free(ab);
110337da2899SCharles.Forsyth b = firstb->next;
110437da2899SCharles.Forsyth b->prev = nil;
110537da2899SCharles.Forsyth return b;
110637da2899SCharles.Forsyth }
110737da2899SCharles.Forsyth
110837da2899SCharles.Forsyth static int
back(Block * b1,Block * b2)110937da2899SCharles.Forsyth back(Block *b1, Block *b2)
111037da2899SCharles.Forsyth {
111137da2899SCharles.Forsyth return b1->dfn >= b2->dfn;
111237da2899SCharles.Forsyth }
111337da2899SCharles.Forsyth
111437da2899SCharles.Forsyth static void
pblocks(Block * b,int nb)111537da2899SCharles.Forsyth pblocks(Block *b, int nb)
111637da2899SCharles.Forsyth {
111737da2899SCharles.Forsyth Inst *i;
111837da2899SCharles.Forsyth Blist *bl;
111937da2899SCharles.Forsyth
112037da2899SCharles.Forsyth print("--------------------%d blocks--------------------\n", nb);
112137da2899SCharles.Forsyth print("------------------------------------------------\n");
112237da2899SCharles.Forsyth for( ; b != nil; b = b->next){
112337da2899SCharles.Forsyth print("dfn=%d\n", b->dfn);
112437da2899SCharles.Forsyth print(" pred ");
112537da2899SCharles.Forsyth for(bl = b->pred; bl != nil; bl = bl->next)
112637da2899SCharles.Forsyth print("%d%s ", bl->block->dfn, back(bl->block, b) ? "*" : "");
112737da2899SCharles.Forsyth print("\n");
112837da2899SCharles.Forsyth print(" succ ");
112937da2899SCharles.Forsyth for(bl = b->succ; bl != nil; bl = bl->next)
113037da2899SCharles.Forsyth print("%d%s ", bl->block->dfn, back(b, bl->block) ? "*" : "");
113137da2899SCharles.Forsyth print("\n");
113237da2899SCharles.Forsyth for(i = b->first; i != nil; i = i->next){
113337da2899SCharles.Forsyth // print(" %I\n", i);
113437da2899SCharles.Forsyth pins(i);
113537da2899SCharles.Forsyth if(i == b->last)
113637da2899SCharles.Forsyth break;
113737da2899SCharles.Forsyth }
113837da2899SCharles.Forsyth }
113937da2899SCharles.Forsyth print("------------------------------------------------\n");
114037da2899SCharles.Forsyth }
114137da2899SCharles.Forsyth
114237da2899SCharles.Forsyth static void
ckblocks(Inst * in,Block * b,int nb)114337da2899SCharles.Forsyth ckblocks(Inst *in, Block *b, int nb)
114437da2899SCharles.Forsyth {
114537da2899SCharles.Forsyth int n;
114637da2899SCharles.Forsyth Block *lastb;
114737da2899SCharles.Forsyth
114837da2899SCharles.Forsyth if(b->first != in)
114937da2899SCharles.Forsyth fatal("A - %d", b->dfn);
115037da2899SCharles.Forsyth n = 0;
115137da2899SCharles.Forsyth lastb = nil;
115237da2899SCharles.Forsyth for( ; b != nil; b = b->next){
115337da2899SCharles.Forsyth n++;
115437da2899SCharles.Forsyth if(b->prev != lastb)
115537da2899SCharles.Forsyth fatal("a - %d\n", b->dfn);
115637da2899SCharles.Forsyth if(b->prev != nil && b->prev->next != b)
115737da2899SCharles.Forsyth fatal("b - %d\n", b->dfn);
115837da2899SCharles.Forsyth if(b->next != nil && b->next->prev != b)
115937da2899SCharles.Forsyth fatal("c - %d\n", b->dfn);
116037da2899SCharles.Forsyth
116137da2899SCharles.Forsyth if(b->prev != nil && b->prev->last->next != b->first)
116237da2899SCharles.Forsyth fatal("B - %d\n", b->dfn);
116337da2899SCharles.Forsyth if(b->next != nil && b->last->next != b->next->first)
116437da2899SCharles.Forsyth fatal("C - %d\n", b->dfn);
116537da2899SCharles.Forsyth if(b->next == nil && b->last->next != nil)
116637da2899SCharles.Forsyth fatal("D - %d\n", b->dfn);
116737da2899SCharles.Forsyth
116837da2899SCharles.Forsyth if(b->last->branch != nil && b->succ->block->first != b->last->branch)
116937da2899SCharles.Forsyth fatal("0 - %d\n", b->dfn);
117037da2899SCharles.Forsyth
117137da2899SCharles.Forsyth lastb = b;
117237da2899SCharles.Forsyth }
117337da2899SCharles.Forsyth if(n != nb)
117437da2899SCharles.Forsyth fatal("N - %d %d\n", n, nb);
117537da2899SCharles.Forsyth }
117637da2899SCharles.Forsyth
117737da2899SCharles.Forsyth static void
dfs0(Block * b,int * n)117837da2899SCharles.Forsyth dfs0(Block *b, int *n)
117937da2899SCharles.Forsyth {
118037da2899SCharles.Forsyth Block *s;
118137da2899SCharles.Forsyth Blist *bl;
118237da2899SCharles.Forsyth
118337da2899SCharles.Forsyth b->flags = 1;
118437da2899SCharles.Forsyth for(bl = b->succ; bl != nil; bl = bl->next){
118537da2899SCharles.Forsyth s = bl->block;
118637da2899SCharles.Forsyth if(s->flags == 0)
118737da2899SCharles.Forsyth dfs0(s, n);
118837da2899SCharles.Forsyth }
118937da2899SCharles.Forsyth b->dfn = --(*n);
119037da2899SCharles.Forsyth }
119137da2899SCharles.Forsyth
119237da2899SCharles.Forsyth static int
dfs(Block * b,int nb)119337da2899SCharles.Forsyth dfs(Block *b, int nb)
119437da2899SCharles.Forsyth {
119537da2899SCharles.Forsyth int n, u;
119637da2899SCharles.Forsyth Block *b0;
119737da2899SCharles.Forsyth
119837da2899SCharles.Forsyth b0 = b;
119937da2899SCharles.Forsyth n = nb;
120037da2899SCharles.Forsyth dfs0(b0, &n);
120137da2899SCharles.Forsyth u = 0;
120237da2899SCharles.Forsyth for(b = b0; b != nil; b = b->next){
120337da2899SCharles.Forsyth if(b->flags == 0){ /* unreachable: see foldbranch */
120437da2899SCharles.Forsyth fatal("found unreachable code");
120537da2899SCharles.Forsyth u++;
120637da2899SCharles.Forsyth b->prev->next = b->next;
120737da2899SCharles.Forsyth if(b->next){
120837da2899SCharles.Forsyth b->next->prev = b->prev;
120937da2899SCharles.Forsyth b->prev->last->next = b->next->first;
121037da2899SCharles.Forsyth }
121137da2899SCharles.Forsyth else
121237da2899SCharles.Forsyth b->prev->last->next = nil;
121337da2899SCharles.Forsyth }
121437da2899SCharles.Forsyth b->flags = 0;
121537da2899SCharles.Forsyth }
121637da2899SCharles.Forsyth if(u){
121737da2899SCharles.Forsyth for(b = b0; b != nil; b = b->next)
121837da2899SCharles.Forsyth b->dfn -= u;
121937da2899SCharles.Forsyth }
122037da2899SCharles.Forsyth return nb-u;
122137da2899SCharles.Forsyth }
122237da2899SCharles.Forsyth
122337da2899SCharles.Forsyth static void
loop0(Block * b)122437da2899SCharles.Forsyth loop0(Block *b)
122537da2899SCharles.Forsyth {
122637da2899SCharles.Forsyth Block *p;
122737da2899SCharles.Forsyth Blist *bl;
122837da2899SCharles.Forsyth
122937da2899SCharles.Forsyth b->flags = 1;
123037da2899SCharles.Forsyth for(bl = b->pred; bl != nil; bl = bl->next){
123137da2899SCharles.Forsyth p = bl->block;
123237da2899SCharles.Forsyth if(p->flags == 0)
123337da2899SCharles.Forsyth loop0(p);
123437da2899SCharles.Forsyth }
123537da2899SCharles.Forsyth }
123637da2899SCharles.Forsyth
123737da2899SCharles.Forsyth /* b1->b2 a back edge */
123837da2899SCharles.Forsyth static void
loop(Block * b,Block * b1,Block * b2)123937da2899SCharles.Forsyth loop(Block *b, Block *b1, Block *b2)
124037da2899SCharles.Forsyth {
124137da2899SCharles.Forsyth if(0 && debug['o'])
124237da2899SCharles.Forsyth print("back edge %d->%d\n", b1->dfn, b2->dfn);
124337da2899SCharles.Forsyth b2->flags = 1;
124437da2899SCharles.Forsyth if(b1->flags == 0)
124537da2899SCharles.Forsyth loop0(b1);
124637da2899SCharles.Forsyth if(0 && debug['o'])
124737da2899SCharles.Forsyth print(" loop ");
124837da2899SCharles.Forsyth for( ; b != nil; b = b->next){
124937da2899SCharles.Forsyth if(b->flags && 0 && debug['o'])
125037da2899SCharles.Forsyth print("%d ", b->dfn);
125137da2899SCharles.Forsyth b->flags = 0;
125237da2899SCharles.Forsyth }
125337da2899SCharles.Forsyth if(0 && debug['o'])
125437da2899SCharles.Forsyth print("\n");
125537da2899SCharles.Forsyth }
125637da2899SCharles.Forsyth
125737da2899SCharles.Forsyth static void
loops(Block * b)125837da2899SCharles.Forsyth loops(Block *b)
125937da2899SCharles.Forsyth {
126037da2899SCharles.Forsyth Block *b0;
126137da2899SCharles.Forsyth Blist *bl;
126237da2899SCharles.Forsyth
126337da2899SCharles.Forsyth b0 = b;
126437da2899SCharles.Forsyth for( ; b != nil; b = b->next){
126537da2899SCharles.Forsyth for(bl = b->succ; bl != nil; bl = bl->next){
126637da2899SCharles.Forsyth if(back(b, bl->block))
126737da2899SCharles.Forsyth loop(b0, b, bl->block);
126837da2899SCharles.Forsyth }
126937da2899SCharles.Forsyth }
127037da2899SCharles.Forsyth }
127137da2899SCharles.Forsyth
127237da2899SCharles.Forsyth static int
imm(int m,Addr * a)127337da2899SCharles.Forsyth imm(int m, Addr *a)
127437da2899SCharles.Forsyth {
127537da2899SCharles.Forsyth if(m == Aimm)
127637da2899SCharles.Forsyth return a->offset;
127737da2899SCharles.Forsyth fatal("bad immediate value");
127837da2899SCharles.Forsyth return -1;
127937da2899SCharles.Forsyth }
128037da2899SCharles.Forsyth
128137da2899SCharles.Forsyth static int
desc(int m,Addr * a)128237da2899SCharles.Forsyth desc(int m, Addr *a)
128337da2899SCharles.Forsyth {
128437da2899SCharles.Forsyth if(m == Adesc)
128537da2899SCharles.Forsyth return a->decl->desc->size;
128637da2899SCharles.Forsyth fatal("bad descriptor value");
128737da2899SCharles.Forsyth return -1;
128837da2899SCharles.Forsyth }
128937da2899SCharles.Forsyth
129037da2899SCharles.Forsyth static int
fpoff(int m,Addr * a)129137da2899SCharles.Forsyth fpoff(int m, Addr *a)
129237da2899SCharles.Forsyth {
129337da2899SCharles.Forsyth int off;
129437da2899SCharles.Forsyth Decl *d;
129537da2899SCharles.Forsyth
129637da2899SCharles.Forsyth if(m == Afp || m == Afpind){
129737da2899SCharles.Forsyth off = a->reg;
129837da2899SCharles.Forsyth if((d = a->decl) != nil)
129937da2899SCharles.Forsyth off += d->offset;
130037da2899SCharles.Forsyth return off;
130137da2899SCharles.Forsyth }
130237da2899SCharles.Forsyth return -1;
130337da2899SCharles.Forsyth }
130437da2899SCharles.Forsyth
130537da2899SCharles.Forsyth static int
size(Inst * i)130637da2899SCharles.Forsyth size(Inst *i)
130737da2899SCharles.Forsyth {
130837da2899SCharles.Forsyth switch(i->op){
130937da2899SCharles.Forsyth case ISEND:
131037da2899SCharles.Forsyth case IRECV:
131137da2899SCharles.Forsyth case IALT:
131237da2899SCharles.Forsyth case INBALT:
131337da2899SCharles.Forsyth case ILEA:
131437da2899SCharles.Forsyth return i->m.offset;
131537da2899SCharles.Forsyth case IMOVM:
131637da2899SCharles.Forsyth case IHEADM:
131737da2899SCharles.Forsyth case ICONSM:
131837da2899SCharles.Forsyth return imm(i->mm, &i->m);
131937da2899SCharles.Forsyth case IMOVMP:
132037da2899SCharles.Forsyth case IHEADMP:
132137da2899SCharles.Forsyth case ICONSMP:
132237da2899SCharles.Forsyth return desc(i->mm, &i->m);
132337da2899SCharles.Forsyth break;
132437da2899SCharles.Forsyth }
132537da2899SCharles.Forsyth fatal("bad op in size");
132637da2899SCharles.Forsyth return -1;
132737da2899SCharles.Forsyth }
132837da2899SCharles.Forsyth
132937da2899SCharles.Forsyth static Decl*
mkdec(int o)133037da2899SCharles.Forsyth mkdec(int o)
133137da2899SCharles.Forsyth {
133237da2899SCharles.Forsyth Decl *d;
133337da2899SCharles.Forsyth
133437da2899SCharles.Forsyth d = mkdecl(&nosrc, Dlocal, tint);
133537da2899SCharles.Forsyth d->offset = o;
133637da2899SCharles.Forsyth return d;
133737da2899SCharles.Forsyth }
133837da2899SCharles.Forsyth
133937da2899SCharles.Forsyth static void
mkdecls(void)134037da2899SCharles.Forsyth mkdecls(void)
134137da2899SCharles.Forsyth {
134237da2899SCharles.Forsyth regdecls = mkdec(REGRET*IBY2WD);
134337da2899SCharles.Forsyth regdecls->next = mkdec(STemp);
134437da2899SCharles.Forsyth regdecls->next->next = mkdec(DTemp);
134537da2899SCharles.Forsyth }
134637da2899SCharles.Forsyth
134737da2899SCharles.Forsyth static Decl*
sharedecls(Decl * d)134837da2899SCharles.Forsyth sharedecls(Decl *d)
134937da2899SCharles.Forsyth {
135037da2899SCharles.Forsyth Decl *ld;
135137da2899SCharles.Forsyth
135237da2899SCharles.Forsyth ld = d;
135337da2899SCharles.Forsyth for(d = d->next ; d != nil; d = d->next){
135437da2899SCharles.Forsyth if(d->offset <= ld->offset)
135537da2899SCharles.Forsyth break;
135637da2899SCharles.Forsyth ld = d;
135737da2899SCharles.Forsyth }
135837da2899SCharles.Forsyth return d;
135937da2899SCharles.Forsyth }
136037da2899SCharles.Forsyth
136137da2899SCharles.Forsyth static int
finddec(int o,int s,Decl * vars,int * nv,Inst * i)136237da2899SCharles.Forsyth finddec(int o, int s, Decl *vars, int *nv, Inst *i)
136337da2899SCharles.Forsyth {
136437da2899SCharles.Forsyth int m, n;
136537da2899SCharles.Forsyth Decl *d;
136637da2899SCharles.Forsyth
136737da2899SCharles.Forsyth n = 0;
136837da2899SCharles.Forsyth for(d = vars; d != nil; d = d->next){
136937da2899SCharles.Forsyth if(o >= d->offset && o < d->offset+d->ty->size){
137037da2899SCharles.Forsyth m = 1;
137137da2899SCharles.Forsyth while(o+s > d->offset+d->ty->size){
137237da2899SCharles.Forsyth m++;
137337da2899SCharles.Forsyth d = d->next;
137437da2899SCharles.Forsyth }
137537da2899SCharles.Forsyth *nv = m;
137637da2899SCharles.Forsyth return n;
137737da2899SCharles.Forsyth }
137837da2899SCharles.Forsyth n++;
137937da2899SCharles.Forsyth }
138037da2899SCharles.Forsyth // print("%d %d missing\n", o, s);
138137da2899SCharles.Forsyth pins(i);
138237da2899SCharles.Forsyth fatal("missing decl");
138337da2899SCharles.Forsyth return -1;
138437da2899SCharles.Forsyth }
138537da2899SCharles.Forsyth
138637da2899SCharles.Forsyth static void
setud(Bits * b,int id,int n,int pc)138737da2899SCharles.Forsyth setud(Bits *b, int id, int n, int pc)
138837da2899SCharles.Forsyth {
138937da2899SCharles.Forsyth if(id < 0)
139037da2899SCharles.Forsyth return;
139137da2899SCharles.Forsyth while(--n >= 0)
139237da2899SCharles.Forsyth bset(b[id++], pc);
139337da2899SCharles.Forsyth }
139437da2899SCharles.Forsyth
139537da2899SCharles.Forsyth static void
ud(Inst * i,Decl * vars,Bits * uses,Bits * defs)139637da2899SCharles.Forsyth ud(Inst *i, Decl *vars, Bits *uses, Bits *defs)
139737da2899SCharles.Forsyth {
139837da2899SCharles.Forsyth ushort f;
139937da2899SCharles.Forsyth int id, j, nv, pc, sz, s, m, d, ss, sm, sd;
140037da2899SCharles.Forsyth Optab *t;
140137da2899SCharles.Forsyth Idlist *l;
140237da2899SCharles.Forsyth
140337da2899SCharles.Forsyth pc = i->pc;
140437da2899SCharles.Forsyth ss = 0;
140537da2899SCharles.Forsyth t = &opflags[i->op];
140637da2899SCharles.Forsyth f = t->flags;
140737da2899SCharles.Forsyth sz = t->size;
140837da2899SCharles.Forsyth s = fpoff(i->sm, &i->s);
140937da2899SCharles.Forsyth m = fpoff(i->mm, &i->m);
141037da2899SCharles.Forsyth d = fpoff(i->dm, &i->d);
141137da2899SCharles.Forsyth if(f&Mduse && i->mm == Anone)
141237da2899SCharles.Forsyth f |= Duse;
141337da2899SCharles.Forsyth if(s >= 0){
141437da2899SCharles.Forsyth if(i->sm == Afp){
141537da2899SCharles.Forsyth ss = SS(sz);
141637da2899SCharles.Forsyth if(ss == Mp)
141737da2899SCharles.Forsyth ss = size(i);
141837da2899SCharles.Forsyth }
141937da2899SCharles.Forsyth else
142037da2899SCharles.Forsyth ss = IBY2WD;
142137da2899SCharles.Forsyth id = finddec(s, ss, vars, &nv, i);
142237da2899SCharles.Forsyth if(f&Suse)
142337da2899SCharles.Forsyth setud(uses, id, nv, pc);
142437da2899SCharles.Forsyth if(f&Sdef){
142537da2899SCharles.Forsyth if(i->sm == Afp)
142637da2899SCharles.Forsyth setud(defs, id, nv, pc);
142737da2899SCharles.Forsyth else
142837da2899SCharles.Forsyth setud(uses, id, nv, pc);
142937da2899SCharles.Forsyth }
143037da2899SCharles.Forsyth }
143137da2899SCharles.Forsyth if(m >= 0){
143237da2899SCharles.Forsyth if(i->mm == Afp){
143337da2899SCharles.Forsyth sm = SM(sz);
143437da2899SCharles.Forsyth if(sm == Mp)
143537da2899SCharles.Forsyth sm = size(i);
143637da2899SCharles.Forsyth }
143737da2899SCharles.Forsyth else
143837da2899SCharles.Forsyth sm = IBY2WD;
143937da2899SCharles.Forsyth id = finddec(m, sm, vars, &nv, i);
144037da2899SCharles.Forsyth if(f&Muse)
144137da2899SCharles.Forsyth setud(uses, id, nv, pc);
144237da2899SCharles.Forsyth if(f&Mdef){
144337da2899SCharles.Forsyth if(i->mm == Afp)
144437da2899SCharles.Forsyth setud(defs, id, nv, pc);
144537da2899SCharles.Forsyth else
144637da2899SCharles.Forsyth setud(uses, id, nv, pc);
144737da2899SCharles.Forsyth }
144837da2899SCharles.Forsyth }
144937da2899SCharles.Forsyth if(d >= 0){
145037da2899SCharles.Forsyth if(i->dm == Afp){
145137da2899SCharles.Forsyth sd = SD(sz);
145237da2899SCharles.Forsyth if(sd == Mp)
145337da2899SCharles.Forsyth sd = size(i);
145437da2899SCharles.Forsyth }
145537da2899SCharles.Forsyth else
145637da2899SCharles.Forsyth sd = IBY2WD;
145737da2899SCharles.Forsyth id = finddec(d, sd, vars, &nv, i);
145837da2899SCharles.Forsyth if(f&Duse)
145937da2899SCharles.Forsyth setud(uses, id, nv, pc);
146037da2899SCharles.Forsyth if(f&Ddef){
146137da2899SCharles.Forsyth if(i->dm == Afp)
146237da2899SCharles.Forsyth setud(defs, id, nv, pc);
146337da2899SCharles.Forsyth else
146437da2899SCharles.Forsyth setud(uses, id, nv, pc);
146537da2899SCharles.Forsyth }
146637da2899SCharles.Forsyth }
146737da2899SCharles.Forsyth if(f&Tuse1){
146837da2899SCharles.Forsyth id = finddec(STemp, IBY2WD, vars, &nv, i);
146937da2899SCharles.Forsyth setud(uses, id, nv, pc);
147037da2899SCharles.Forsyth }
147137da2899SCharles.Forsyth if(f&Tuse2){
147237da2899SCharles.Forsyth id = finddec(DTemp, IBY2WD, vars, &nv, i);
147337da2899SCharles.Forsyth setud(uses, id, nv, pc);
147437da2899SCharles.Forsyth }
147537da2899SCharles.Forsyth if(i->op == ILEA){
147637da2899SCharles.Forsyth if(s >= 0){
147737da2899SCharles.Forsyth id = finddec(s, ss, vars, &nv, i);
147837da2899SCharles.Forsyth if(i->sm == Afp && i->m.reg == 0)
147937da2899SCharles.Forsyth setud(defs, id, nv, pc);
148037da2899SCharles.Forsyth else
148137da2899SCharles.Forsyth setud(uses, id, nv, pc);
148237da2899SCharles.Forsyth }
148337da2899SCharles.Forsyth }
148437da2899SCharles.Forsyth if(0)
148537da2899SCharles.Forsyth switch(i->op){
148637da2899SCharles.Forsyth case ILEA:
148737da2899SCharles.Forsyth if(s >= 0){
148837da2899SCharles.Forsyth id = finddec(s, ss, vars, &nv, i);
148937da2899SCharles.Forsyth if(id < 0)
149037da2899SCharles.Forsyth break;
149137da2899SCharles.Forsyth for(j = 0; j < nv; j++){
149237da2899SCharles.Forsyth if(i->sm == Afp && i->m.reg == 0)
149337da2899SCharles.Forsyth addlist(&deflist, id++);
149437da2899SCharles.Forsyth else
149537da2899SCharles.Forsyth addlist(&uselist, id++);
149637da2899SCharles.Forsyth }
149737da2899SCharles.Forsyth }
149837da2899SCharles.Forsyth break;
149937da2899SCharles.Forsyth case IALT:
150037da2899SCharles.Forsyth case INBALT:
150137da2899SCharles.Forsyth case ICALL:
150237da2899SCharles.Forsyth case IMCALL:
150337da2899SCharles.Forsyth for(l = deflist; l != nil; l = l->next){
150437da2899SCharles.Forsyth id = l->id;
150537da2899SCharles.Forsyth bset(defs[id], pc);
150637da2899SCharles.Forsyth }
150737da2899SCharles.Forsyth for(l = uselist; l != nil; l = l->next){
150837da2899SCharles.Forsyth id = l->id;
150937da2899SCharles.Forsyth bset(uses[id], pc);
151037da2899SCharles.Forsyth }
151137da2899SCharles.Forsyth freelist(&deflist);
151237da2899SCharles.Forsyth freelist(&uselist);
151337da2899SCharles.Forsyth break;
151437da2899SCharles.Forsyth }
151537da2899SCharles.Forsyth }
151637da2899SCharles.Forsyth
151737da2899SCharles.Forsyth static void
usedef(Inst * in,Decl * vars,Bits * uses,Bits * defs)151837da2899SCharles.Forsyth usedef(Inst *in, Decl *vars, Bits *uses, Bits *defs)
151937da2899SCharles.Forsyth {
152037da2899SCharles.Forsyth Inst *i;
152137da2899SCharles.Forsyth
152237da2899SCharles.Forsyth for(i = in; i != nil; i = i->next)
152337da2899SCharles.Forsyth ud(i, vars, uses, defs);
152437da2899SCharles.Forsyth }
152537da2899SCharles.Forsyth
152637da2899SCharles.Forsyth static void
pusedef(Bits * ud,int nv,Decl * d,char * s)152737da2899SCharles.Forsyth pusedef(Bits *ud, int nv, Decl *d, char *s)
152837da2899SCharles.Forsyth {
152937da2899SCharles.Forsyth int i;
153037da2899SCharles.Forsyth
153137da2899SCharles.Forsyth print("%s\n", s);
153237da2899SCharles.Forsyth for(i = 0; i < nv; i++){
153337da2899SCharles.Forsyth if(!bzero(ud[i])){
153437da2899SCharles.Forsyth print("\t%s(%ld): ", decname(d), d->offset);
153537da2899SCharles.Forsyth pbits(ud[i]);
153637da2899SCharles.Forsyth print("\n");
153737da2899SCharles.Forsyth }
153837da2899SCharles.Forsyth d = d->next;
153937da2899SCharles.Forsyth }
154037da2899SCharles.Forsyth }
154137da2899SCharles.Forsyth
154237da2899SCharles.Forsyth static void
dummydefs(Bits * defs,int nv,int npc)154337da2899SCharles.Forsyth dummydefs(Bits *defs, int nv, int npc)
154437da2899SCharles.Forsyth {
154537da2899SCharles.Forsyth int i;
154637da2899SCharles.Forsyth
154737da2899SCharles.Forsyth for(i = 0; i < nv; i++)
154837da2899SCharles.Forsyth bset(defs[i], npc++);
154937da2899SCharles.Forsyth }
155037da2899SCharles.Forsyth
155137da2899SCharles.Forsyth static void
dogenkill(Block * b,Bits * defs,int nv)155237da2899SCharles.Forsyth dogenkill(Block *b, Bits *defs, int nv)
155337da2899SCharles.Forsyth {
155437da2899SCharles.Forsyth int i, n, t;
155537da2899SCharles.Forsyth Bits v;
155637da2899SCharles.Forsyth
155737da2899SCharles.Forsyth n = defs[0].n;
155837da2899SCharles.Forsyth v = bnew(n, 0);
155937da2899SCharles.Forsyth for( ; b != nil; b = b->next){
156037da2899SCharles.Forsyth b->gen = bnew(n, 0);
156137da2899SCharles.Forsyth b->kill = bnew(n, 0);
156237da2899SCharles.Forsyth b->in = bnew(n, 0);
156337da2899SCharles.Forsyth b->out = bnew(n, 0);
156437da2899SCharles.Forsyth for(i = 0; i < nv; i++){
156537da2899SCharles.Forsyth boper(Bclr, v, v);
156637da2899SCharles.Forsyth bsets(v, b->first->pc, b->last->pc);
156737da2899SCharles.Forsyth boper(Band, defs[i], v);
156837da2899SCharles.Forsyth t = topbit(v);
156937da2899SCharles.Forsyth if(t >= 0)
157037da2899SCharles.Forsyth bset(b->gen, t);
157137da2899SCharles.Forsyth else
157237da2899SCharles.Forsyth continue;
157337da2899SCharles.Forsyth boper(Bclr, v, v);
157437da2899SCharles.Forsyth bsets(v, b->first->pc, b->last->pc);
157537da2899SCharles.Forsyth boper(Binv, v, v);
157637da2899SCharles.Forsyth boper(Band, defs[i], v);
157737da2899SCharles.Forsyth boper(Bor, v, b->kill);
157837da2899SCharles.Forsyth }
157937da2899SCharles.Forsyth }
158037da2899SCharles.Forsyth bfree(v);
158137da2899SCharles.Forsyth }
158237da2899SCharles.Forsyth
158337da2899SCharles.Forsyth static void
udflow(Block * b,int nv,int npc)158437da2899SCharles.Forsyth udflow(Block *b, int nv, int npc)
158537da2899SCharles.Forsyth {
158637da2899SCharles.Forsyth int iter;
158737da2899SCharles.Forsyth Block *b0, *p;
158837da2899SCharles.Forsyth Blist *bl;
158937da2899SCharles.Forsyth Bits newin;
159037da2899SCharles.Forsyth
159137da2899SCharles.Forsyth b0 = b;
159237da2899SCharles.Forsyth for(b = b0; b != nil; b = b->next)
159337da2899SCharles.Forsyth boper(Bstore, b->gen, b->out);
159437da2899SCharles.Forsyth newin = bnew(b0->in.n, 0);
159537da2899SCharles.Forsyth iter = 1;
159637da2899SCharles.Forsyth while(iter){
159737da2899SCharles.Forsyth iter = 0;
159837da2899SCharles.Forsyth for(b = b0; b != nil; b = b->next){
159937da2899SCharles.Forsyth boper(Bclr, newin, newin);
160037da2899SCharles.Forsyth for(bl = b->pred; bl != nil; bl = bl->next){
160137da2899SCharles.Forsyth p = bl->block;
160237da2899SCharles.Forsyth boper(Bor, p->out, newin);
160337da2899SCharles.Forsyth }
160437da2899SCharles.Forsyth if(b == b0)
160537da2899SCharles.Forsyth bsets(newin, npc, npc+nv-1);
160637da2899SCharles.Forsyth if(!beq(b->in, newin))
160737da2899SCharles.Forsyth iter = 1;
160837da2899SCharles.Forsyth boper(Bstore, newin, b->in);
160937da2899SCharles.Forsyth boper(Bstore, b->in, b->out);
161037da2899SCharles.Forsyth boper(Bandrev, b->kill, b->out);
161137da2899SCharles.Forsyth boper(Bor, b->gen, b->out);
161237da2899SCharles.Forsyth }
161337da2899SCharles.Forsyth }
161437da2899SCharles.Forsyth bfree(newin);
161537da2899SCharles.Forsyth }
161637da2899SCharles.Forsyth
161737da2899SCharles.Forsyth static void
pflows(Block * b)161837da2899SCharles.Forsyth pflows(Block *b)
161937da2899SCharles.Forsyth {
162037da2899SCharles.Forsyth for( ; b != nil; b = b->next){
162137da2899SCharles.Forsyth print("block %d\n", b->dfn);
162237da2899SCharles.Forsyth print(" gen: "); pbits(b->gen); print("\n");
162337da2899SCharles.Forsyth print(" kill: "); pbits(b->kill); print("\n");
162437da2899SCharles.Forsyth print(" in: "); pbits(b->in); print("\n");
162537da2899SCharles.Forsyth print(" out: "); pbits(b->out); print("\n");
162637da2899SCharles.Forsyth }
162737da2899SCharles.Forsyth }
162837da2899SCharles.Forsyth
162937da2899SCharles.Forsyth static int
set(Decl * d)163037da2899SCharles.Forsyth set(Decl *d)
163137da2899SCharles.Forsyth {
163237da2899SCharles.Forsyth if(d->store == Darg)
163337da2899SCharles.Forsyth return 1;
163437da2899SCharles.Forsyth if(d->sym == nil) /* || d->sym->name[0] == '.') */
163537da2899SCharles.Forsyth return 1;
163637da2899SCharles.Forsyth if(tattr[d->ty->kind].isptr || d->ty->kind == Texception)
163737da2899SCharles.Forsyth return 1;
163837da2899SCharles.Forsyth return 0;
163937da2899SCharles.Forsyth }
164037da2899SCharles.Forsyth
164137da2899SCharles.Forsyth static int
used(Decl * d)164237da2899SCharles.Forsyth used(Decl *d)
164337da2899SCharles.Forsyth {
164437da2899SCharles.Forsyth if(d->sym == nil ) /* || d->sym->name[0] == '.') */
164537da2899SCharles.Forsyth return 1;
164637da2899SCharles.Forsyth return 0;
164737da2899SCharles.Forsyth }
164837da2899SCharles.Forsyth
164937da2899SCharles.Forsyth static void
udchain(Block * b,Decl * ds,int nv,int npc,Bits * defs,Bits * uses,Decl * sd)165037da2899SCharles.Forsyth udchain(Block *b, Decl *ds, int nv, int npc, Bits *defs, Bits *uses, Decl *sd)
165137da2899SCharles.Forsyth {
165237da2899SCharles.Forsyth int i, n, p, q;
165337da2899SCharles.Forsyth Bits d, u, dd, ud;
165437da2899SCharles.Forsyth Block *b0;
165537da2899SCharles.Forsyth Inst *in;
165637da2899SCharles.Forsyth
165737da2899SCharles.Forsyth b0 = b;
165837da2899SCharles.Forsyth n = defs[0].n;
165937da2899SCharles.Forsyth u = bnew(n, 0);
166037da2899SCharles.Forsyth d = bnew(n, 0);
166137da2899SCharles.Forsyth dd = bnew(n, 0);
166237da2899SCharles.Forsyth ud = bnew(n, 0);
166337da2899SCharles.Forsyth for(i = 0; i < nv; i++){
166437da2899SCharles.Forsyth boper(Bstore, defs[i], ud);
166537da2899SCharles.Forsyth bclr(ud, npc+i);
166637da2899SCharles.Forsyth for(b = b0 ; b != nil; b = b->next){
166737da2899SCharles.Forsyth boper(Bclr, u, u);
166837da2899SCharles.Forsyth bsets(u, b->first->pc, b->last->pc);
166937da2899SCharles.Forsyth boper(Band, uses[i], u);
167037da2899SCharles.Forsyth boper(Bclr, d, d);
167137da2899SCharles.Forsyth bsets(d, b->first->pc, b->last->pc);
167237da2899SCharles.Forsyth boper(Band, defs[i], d);
167337da2899SCharles.Forsyth for(;;){
167437da2899SCharles.Forsyth p = topbit(u);
167537da2899SCharles.Forsyth if(p < 0)
167637da2899SCharles.Forsyth break;
167737da2899SCharles.Forsyth bclr(u, p);
167837da2899SCharles.Forsyth bclrs(d, p, -1);
167937da2899SCharles.Forsyth q = topbit(d);
168037da2899SCharles.Forsyth if(q >= 0){
168137da2899SCharles.Forsyth bclr(ud, q);
168237da2899SCharles.Forsyth if(debug['o'])
168337da2899SCharles.Forsyth print("udc b=%d v=%d(%s/%ld) u=%d d=%d\n", b->dfn, i, decname(ds), ds->offset, p, q);
168437da2899SCharles.Forsyth }
168537da2899SCharles.Forsyth else{
168637da2899SCharles.Forsyth boper(Bstore, defs[i], dd);
168737da2899SCharles.Forsyth boper(Band, b->in, dd);
168837da2899SCharles.Forsyth boper(Bandrev, dd, ud);
168937da2899SCharles.Forsyth if(!bzero(dd)){
169037da2899SCharles.Forsyth if(debug['o']){
169137da2899SCharles.Forsyth print("udc b=%d v=%d(%s/%ld) u=%d d=", b->dfn, i, decname(ds), ds->offset, p);
169237da2899SCharles.Forsyth pbits(dd);
169337da2899SCharles.Forsyth print("\n");
169437da2899SCharles.Forsyth }
169537da2899SCharles.Forsyth if(bmem(dd, npc+i) && !set(ds))
169637da2899SCharles.Forsyth warning(pc2i(b0, p), "used and not set", ds, sd);
169737da2899SCharles.Forsyth }
169837da2899SCharles.Forsyth else
169937da2899SCharles.Forsyth fatal("no defs in udchain");
170037da2899SCharles.Forsyth }
170137da2899SCharles.Forsyth }
170237da2899SCharles.Forsyth }
170337da2899SCharles.Forsyth for(;;){
170437da2899SCharles.Forsyth p = topbit(ud);
170537da2899SCharles.Forsyth if(p < 0)
170637da2899SCharles.Forsyth break;
170737da2899SCharles.Forsyth bclr(ud, p);
170837da2899SCharles.Forsyth if(!used(ds)){
170937da2899SCharles.Forsyth in = pc2i(b0, p);
171037da2899SCharles.Forsyth if(isnilsrc(&in->src)) /* nilling code */
171137da2899SCharles.Forsyth in->op = INOOP; /* elim p from bitmaps ? */
171237da2899SCharles.Forsyth else if(limbovar(ds) && !structure(ds->ty))
171337da2899SCharles.Forsyth warning(in, "set and not used", ds, sd);
171437da2899SCharles.Forsyth }
171537da2899SCharles.Forsyth }
171637da2899SCharles.Forsyth ds = ds->next;
171737da2899SCharles.Forsyth }
171837da2899SCharles.Forsyth bfree(u);
171937da2899SCharles.Forsyth bfree(d);
172037da2899SCharles.Forsyth bfree(dd);
172137da2899SCharles.Forsyth bfree(ud);
172237da2899SCharles.Forsyth }
172337da2899SCharles.Forsyth
172437da2899SCharles.Forsyth static void
ckflags(void)172537da2899SCharles.Forsyth ckflags(void)
172637da2899SCharles.Forsyth {
172737da2899SCharles.Forsyth int i, j, k, n;
172837da2899SCharles.Forsyth Optab *o;
172937da2899SCharles.Forsyth
173037da2899SCharles.Forsyth n = nelem(opflags);
173137da2899SCharles.Forsyth o = opflags;
173237da2899SCharles.Forsyth for(i = 0; i < n; i++){
173337da2899SCharles.Forsyth j = (o->flags&(Suse|Sdef)) != 0;
173437da2899SCharles.Forsyth k = SS(o->size) != 0;
173537da2899SCharles.Forsyth if(j != k){
173637da2899SCharles.Forsyth if(!(j == 0 && k == 1 && i == ILEA))
173737da2899SCharles.Forsyth fatal("S %ld %s\n", o-opflags, instname[i]);
173837da2899SCharles.Forsyth }
173937da2899SCharles.Forsyth j = (o->flags&(Muse|Mdef)) != 0;
174037da2899SCharles.Forsyth k = SM(o->size) != 0;
174137da2899SCharles.Forsyth if(j != k)
174237da2899SCharles.Forsyth fatal("M %ld %s\n", o-opflags, instname[i]);
174337da2899SCharles.Forsyth j = (o->flags&(Duse|Ddef)) != 0;
174437da2899SCharles.Forsyth k = SD(o->size) != 0;
174537da2899SCharles.Forsyth if(j != k){
174637da2899SCharles.Forsyth if(!(j == 1 && k == 0 && (i == IGOTO || i == ICASE || i == ICASEC || i == ICASEL)))
174737da2899SCharles.Forsyth fatal("D %ld %s\n", o-opflags, instname[i]);
174837da2899SCharles.Forsyth }
174937da2899SCharles.Forsyth o++;
175037da2899SCharles.Forsyth }
175137da2899SCharles.Forsyth }
175237da2899SCharles.Forsyth
175337da2899SCharles.Forsyth void
optim(Inst * in,Decl * d)175437da2899SCharles.Forsyth optim(Inst *in, Decl *d)
175537da2899SCharles.Forsyth {
175637da2899SCharles.Forsyth int nb, npc, nv, nd, nu;
175737da2899SCharles.Forsyth Block *b;
175837da2899SCharles.Forsyth Bits *uses, *defs;
175937da2899SCharles.Forsyth Decl *sd;
176037da2899SCharles.Forsyth
176137da2899SCharles.Forsyth ckflags();
176237da2899SCharles.Forsyth if(debug['o'])
176337da2899SCharles.Forsyth print("************************************************\nfunction %s\n************************************************\n", d->sym->name);
176437da2899SCharles.Forsyth if(in == nil || errors > 0)
176537da2899SCharles.Forsyth return;
176637da2899SCharles.Forsyth d = d->ty->ids;
176737da2899SCharles.Forsyth if(regdecls == nil)
176837da2899SCharles.Forsyth mkdecls();
176937da2899SCharles.Forsyth regdecls->next->next->next = d;
177037da2899SCharles.Forsyth d = regdecls;
177137da2899SCharles.Forsyth sd = sharedecls(d);
177237da2899SCharles.Forsyth if(debug['o'])
177337da2899SCharles.Forsyth printdecls(d);
177437da2899SCharles.Forsyth b = mkblocks(in, &nb);
177537da2899SCharles.Forsyth ckblocks(in, b, nb);
177637da2899SCharles.Forsyth npc = inspc(in);
177737da2899SCharles.Forsyth nb = dfs(b, nb);
177837da2899SCharles.Forsyth if(debug['o'])
177937da2899SCharles.Forsyth pblocks(b, nb);
178037da2899SCharles.Forsyth loops(b);
178137da2899SCharles.Forsyth nv = len(d);
178237da2899SCharles.Forsyth uses = allocbits(nv, npc+nv);
178337da2899SCharles.Forsyth defs = allocbits(nv, npc+nv);
178437da2899SCharles.Forsyth dummydefs(defs, nv, npc);
178537da2899SCharles.Forsyth usedef(in, d, uses, defs);
178637da2899SCharles.Forsyth if(debug['o']){
178737da2899SCharles.Forsyth pusedef(uses, nv, d, "uses");
178837da2899SCharles.Forsyth pusedef(defs, nv, d, "defs");
178937da2899SCharles.Forsyth }
179037da2899SCharles.Forsyth nu = bitcount(uses, nv);
179137da2899SCharles.Forsyth nd = bitcount(defs, nv);
179237da2899SCharles.Forsyth dogenkill(b, defs, nv);
179337da2899SCharles.Forsyth udflow(b, nv, npc);
179437da2899SCharles.Forsyth if(debug['o'])
179537da2899SCharles.Forsyth pflows(b);
179637da2899SCharles.Forsyth udchain(b, d, nv, npc, defs, uses, sd);
179737da2899SCharles.Forsyth freeblks(b);
179837da2899SCharles.Forsyth freebits(uses, nv);
179937da2899SCharles.Forsyth freebits(defs, nv);
180037da2899SCharles.Forsyth if(debug['o'])
180137da2899SCharles.Forsyth print("nb=%d npc=%d nv=%d nd=%d nu=%d\n", nb, npc, nv, nd, nu);
180237da2899SCharles.Forsyth }
180337da2899SCharles.Forsyth
1804