xref: /plan9-contrib/sys/src/cmd/6c/gc.h (revision 40d015479ed36701ae6dcfd8814f849fc6285e8d)
1e887ea33SDavid du Colombier #include	"../cc/cc.h"
2e887ea33SDavid du Colombier #include	"../6c/6.out.h"
3e887ea33SDavid du Colombier 
4e887ea33SDavid du Colombier /*
5e887ea33SDavid du Colombier  * 6c/amd64
6e887ea33SDavid du Colombier  * Intel 386 with AMD64 extensions
7e887ea33SDavid du Colombier  */
8e887ea33SDavid du Colombier #define	SZ_CHAR		1
9e887ea33SDavid du Colombier #define	SZ_SHORT	2
10e887ea33SDavid du Colombier #define	SZ_INT		4
11e887ea33SDavid du Colombier #define	SZ_LONG		4
12e887ea33SDavid du Colombier #define	SZ_IND		8
13e887ea33SDavid du Colombier #define	SZ_FLOAT	4
14e887ea33SDavid du Colombier #define	SZ_VLONG	8
15e887ea33SDavid du Colombier #define	SZ_DOUBLE	8
16e887ea33SDavid du Colombier #define	FNX		100
17e887ea33SDavid du Colombier 
18e887ea33SDavid du Colombier typedef	struct	Adr	Adr;
19e887ea33SDavid du Colombier typedef	struct	Prog	Prog;
20e887ea33SDavid du Colombier typedef	struct	Case	Case;
21e887ea33SDavid du Colombier typedef	struct	C1	C1;
22e887ea33SDavid du Colombier typedef	struct	Var	Var;
23e887ea33SDavid du Colombier typedef	struct	Reg	Reg;
24e887ea33SDavid du Colombier typedef	struct	Rgn	Rgn;
25e887ea33SDavid du Colombier typedef	struct	Renv	Renv;
26e887ea33SDavid du Colombier 
27e887ea33SDavid du Colombier EXTERN	struct
28e887ea33SDavid du Colombier {
29e887ea33SDavid du Colombier 	Node*	regtree;
30e887ea33SDavid du Colombier 	Node*	basetree;
31e887ea33SDavid du Colombier 	short	scale;
32e887ea33SDavid du Colombier 	short	reg;
33e887ea33SDavid du Colombier 	short	ptr;
34e887ea33SDavid du Colombier } idx;
35e887ea33SDavid du Colombier 
36e887ea33SDavid du Colombier struct	Adr
37e887ea33SDavid du Colombier {
38e887ea33SDavid du Colombier 	vlong	offset;
39e887ea33SDavid du Colombier 	double	dval;
40e887ea33SDavid du Colombier 	char	sval[NSNAME];
41e887ea33SDavid du Colombier 
42e887ea33SDavid du Colombier 	Sym*	sym;
43e887ea33SDavid du Colombier 	uchar	type;
44e887ea33SDavid du Colombier 	uchar	index;
45e887ea33SDavid du Colombier 	uchar	etype;
46e887ea33SDavid du Colombier 	uchar	scale;	/* doubles as width in DATA op */
47e887ea33SDavid du Colombier };
48e887ea33SDavid du Colombier #define	A	((Adr*)0)
49e887ea33SDavid du Colombier 
50e887ea33SDavid du Colombier #define	INDEXED	9
51e887ea33SDavid du Colombier struct	Prog
52e887ea33SDavid du Colombier {
53e887ea33SDavid du Colombier 	Adr	from;
54e887ea33SDavid du Colombier 	Adr	to;
55e887ea33SDavid du Colombier 	Prog*	link;
56e887ea33SDavid du Colombier 	long	lineno;
57e887ea33SDavid du Colombier 	short	as;
58e887ea33SDavid du Colombier };
59e887ea33SDavid du Colombier #define	P	((Prog*)0)
60e887ea33SDavid du Colombier 
61e887ea33SDavid du Colombier struct	Case
62e887ea33SDavid du Colombier {
63e887ea33SDavid du Colombier 	Case*	link;
64e887ea33SDavid du Colombier 	vlong	val;
65e887ea33SDavid du Colombier 	long	label;
66e887ea33SDavid du Colombier 	char	def;
67e887ea33SDavid du Colombier 	char	isv;
68e887ea33SDavid du Colombier };
69e887ea33SDavid du Colombier #define	C	((Case*)0)
70e887ea33SDavid du Colombier 
71e887ea33SDavid du Colombier struct	C1
72e887ea33SDavid du Colombier {
73e887ea33SDavid du Colombier 	vlong	val;
74e887ea33SDavid du Colombier 	long	label;
75e887ea33SDavid du Colombier };
76e887ea33SDavid du Colombier 
77e887ea33SDavid du Colombier struct	Var
78e887ea33SDavid du Colombier {
79e887ea33SDavid du Colombier 	vlong	offset;
80e887ea33SDavid du Colombier 	Sym*	sym;
81e887ea33SDavid du Colombier 	char	name;
82e887ea33SDavid du Colombier 	char	etype;
83e887ea33SDavid du Colombier };
84e887ea33SDavid du Colombier 
85e887ea33SDavid du Colombier struct	Reg
86e887ea33SDavid du Colombier {
87e887ea33SDavid du Colombier 	long	pc;
88e887ea33SDavid du Colombier 	long	rpo;		/* reverse post ordering */
89e887ea33SDavid du Colombier 
90e887ea33SDavid du Colombier 	Bits	set;
91e887ea33SDavid du Colombier 	Bits	use1;
92e887ea33SDavid du Colombier 	Bits	use2;
93e887ea33SDavid du Colombier 
94e887ea33SDavid du Colombier 	Bits	refbehind;
95e887ea33SDavid du Colombier 	Bits	refahead;
96e887ea33SDavid du Colombier 	Bits	calbehind;
97e887ea33SDavid du Colombier 	Bits	calahead;
98e887ea33SDavid du Colombier 	Bits	regdiff;
99e887ea33SDavid du Colombier 	Bits	act;
100e887ea33SDavid du Colombier 
101e887ea33SDavid du Colombier 	long	regu;
102e887ea33SDavid du Colombier 	long	loop;		/* could be shorter */
103e887ea33SDavid du Colombier 
104e887ea33SDavid du Colombier 	Reg*	log5;
105e887ea33SDavid du Colombier 	long	active;
106e887ea33SDavid du Colombier 
107e887ea33SDavid du Colombier 	Reg*	p1;
108e887ea33SDavid du Colombier 	Reg*	p2;
109e887ea33SDavid du Colombier 	Reg*	p2link;
110e887ea33SDavid du Colombier 	Reg*	s1;
111e887ea33SDavid du Colombier 	Reg*	s2;
112e887ea33SDavid du Colombier 	Reg*	link;
113e887ea33SDavid du Colombier 	Prog*	prog;
114e887ea33SDavid du Colombier };
115e887ea33SDavid du Colombier #define	R	((Reg*)0)
116e887ea33SDavid du Colombier 
117e887ea33SDavid du Colombier struct	Renv
118e887ea33SDavid du Colombier {
119e887ea33SDavid du Colombier 	int	safe;
120e887ea33SDavid du Colombier 	Node	base;
121e887ea33SDavid du Colombier 	Node*	saved;
122e887ea33SDavid du Colombier 	Node*	scope;
123e887ea33SDavid du Colombier };
124e887ea33SDavid du Colombier 
125*40d01547SDavid du Colombier #define	NRGN	1000
126e887ea33SDavid du Colombier struct	Rgn
127e887ea33SDavid du Colombier {
128e887ea33SDavid du Colombier 	Reg*	enter;
129e887ea33SDavid du Colombier 	short	cost;
130e887ea33SDavid du Colombier 	short	varno;
131e887ea33SDavid du Colombier 	short	regno;
132e887ea33SDavid du Colombier };
133e887ea33SDavid du Colombier 
134e887ea33SDavid du Colombier EXTERN	long	breakpc;
135e887ea33SDavid du Colombier EXTERN	long	nbreak;
136e887ea33SDavid du Colombier EXTERN	Case*	cases;
137e887ea33SDavid du Colombier EXTERN	Node	constnode;
138e887ea33SDavid du Colombier EXTERN	Node	fconstnode;
139e887ea33SDavid du Colombier EXTERN	Node	vconstnode;
140e887ea33SDavid du Colombier EXTERN	long	continpc;
141e887ea33SDavid du Colombier EXTERN	long	curarg;
142e887ea33SDavid du Colombier EXTERN	long	cursafe;
143e887ea33SDavid du Colombier EXTERN	Prog*	firstp;
144e887ea33SDavid du Colombier EXTERN	Prog*	lastp;
145e887ea33SDavid du Colombier EXTERN	long	maxargsafe;
146e887ea33SDavid du Colombier EXTERN	int	mnstring;
147e887ea33SDavid du Colombier EXTERN	Node*	nodrat;
148e887ea33SDavid du Colombier EXTERN	Node*	nodret;
149e887ea33SDavid du Colombier EXTERN	Node*	nodsafe;
150e887ea33SDavid du Colombier EXTERN	long	nrathole;
151e887ea33SDavid du Colombier EXTERN	long	nstring;
152e887ea33SDavid du Colombier EXTERN	Prog*	p;
153e887ea33SDavid du Colombier EXTERN	long	pc;
154e887ea33SDavid du Colombier EXTERN	Node	lregnode;
155e887ea33SDavid du Colombier EXTERN	Node	qregnode;
156e887ea33SDavid du Colombier EXTERN	char	string[NSNAME];
157e887ea33SDavid du Colombier EXTERN	Sym*	symrathole;
158e887ea33SDavid du Colombier EXTERN	Node	znode;
159e887ea33SDavid du Colombier EXTERN	Prog	zprog;
160*40d01547SDavid du Colombier EXTERN	int	reg[D_XREG];
161e887ea33SDavid du Colombier EXTERN	long	exregoffset;
162e887ea33SDavid du Colombier EXTERN	long	exfregoffset;
163e887ea33SDavid du Colombier EXTERN	uchar	typechlpv[NTYPE];
164e887ea33SDavid du Colombier 
165e887ea33SDavid du Colombier #define	BLOAD(r)	band(bnot(r->refbehind), r->refahead)
166e887ea33SDavid du Colombier #define	BSTORE(r)	band(bnot(r->calbehind), r->calahead)
167e887ea33SDavid du Colombier #define	LOAD(r)		(~r->refbehind.b[z] & r->refahead.b[z])
168e887ea33SDavid du Colombier #define	STORE(r)	(~r->calbehind.b[z] & r->calahead.b[z])
169e887ea33SDavid du Colombier 
170e887ea33SDavid du Colombier #define	bset(a,n)	((a).b[(n)/32]&(1L<<(n)%32))
171e887ea33SDavid du Colombier 
172e887ea33SDavid du Colombier #define	CLOAD	5
173e887ea33SDavid du Colombier #define	CREF	5
174e887ea33SDavid du Colombier #define	CINF	1000
175e887ea33SDavid du Colombier #define	LOOP	3
176e887ea33SDavid du Colombier 
177e887ea33SDavid du Colombier EXTERN	Rgn	region[NRGN];
178e887ea33SDavid du Colombier EXTERN	Rgn*	rgp;
179e887ea33SDavid du Colombier EXTERN	int	nregion;
180e887ea33SDavid du Colombier EXTERN	int	nvar;
181e887ea33SDavid du Colombier 
182e887ea33SDavid du Colombier EXTERN	Bits	externs;
183e887ea33SDavid du Colombier EXTERN	Bits	params;
184e887ea33SDavid du Colombier EXTERN	Bits	consts;
185e887ea33SDavid du Colombier EXTERN	Bits	addrs;
186e887ea33SDavid du Colombier 
187e887ea33SDavid du Colombier EXTERN	long	regbits;
188e887ea33SDavid du Colombier EXTERN	long	exregbits;
189e887ea33SDavid du Colombier 
190e887ea33SDavid du Colombier EXTERN	int	change;
191e887ea33SDavid du Colombier EXTERN	int	suppress;
192e887ea33SDavid du Colombier 
193e887ea33SDavid du Colombier EXTERN	Reg*	firstr;
194e887ea33SDavid du Colombier EXTERN	Reg*	lastr;
195e887ea33SDavid du Colombier EXTERN	Reg	zreg;
196e887ea33SDavid du Colombier EXTERN	Reg*	freer;
197e887ea33SDavid du Colombier EXTERN	Var	var[NVAR];
198e887ea33SDavid du Colombier EXTERN	long*	idom;
199e887ea33SDavid du Colombier EXTERN	Reg**	rpo2r;
200e887ea33SDavid du Colombier EXTERN	long	maxnr;
201e887ea33SDavid du Colombier 
202e887ea33SDavid du Colombier extern	char*	anames[];
203e887ea33SDavid du Colombier 
204e887ea33SDavid du Colombier /*
205e887ea33SDavid du Colombier  * sgen.c
206e887ea33SDavid du Colombier  */
207e887ea33SDavid du Colombier void	codgen(Node*, Node*);
208e887ea33SDavid du Colombier void	gen(Node*);
209e887ea33SDavid du Colombier void	noretval(int);
210e887ea33SDavid du Colombier void	usedset(Node*, int);
211e887ea33SDavid du Colombier void	xcom(Node*);
212e887ea33SDavid du Colombier void	indx(Node*);
213e887ea33SDavid du Colombier int	bcomplex(Node*, Node*);
214e887ea33SDavid du Colombier 
215e887ea33SDavid du Colombier /*
216e887ea33SDavid du Colombier  * cgen.c
217e887ea33SDavid du Colombier  */
218e887ea33SDavid du Colombier void	zeroregm(Node*);
219e887ea33SDavid du Colombier void	cgen(Node*, Node*);
220e887ea33SDavid du Colombier void	reglcgen(Node*, Node*, Node*);
221e887ea33SDavid du Colombier void	lcgen(Node*, Node*);
222e887ea33SDavid du Colombier void	bcgen(Node*, int);
223e887ea33SDavid du Colombier void	boolgen(Node*, int, Node*);
224e887ea33SDavid du Colombier void	sugen(Node*, Node*, long);
225e887ea33SDavid du Colombier int	needreg(Node*, int);
226e887ea33SDavid du Colombier int	hardconst(Node*);
227e887ea33SDavid du Colombier int	immconst(Node*);
228e887ea33SDavid du Colombier 
229e887ea33SDavid du Colombier /*
230e887ea33SDavid du Colombier  * cgen64.c
231e887ea33SDavid du Colombier  */
232e887ea33SDavid du Colombier int	vaddr(Node*, int);
233e887ea33SDavid du Colombier void	loadpair(Node*, Node*);
234e887ea33SDavid du Colombier int	cgen64(Node*, Node*);
235e887ea33SDavid du Colombier void	testv(Node*, int);
236e887ea33SDavid du Colombier 
237e887ea33SDavid du Colombier /*
238e887ea33SDavid du Colombier  * txt.c
239e887ea33SDavid du Colombier  */
240e887ea33SDavid du Colombier void	ginit(void);
241e887ea33SDavid du Colombier void	gclean(void);
242e887ea33SDavid du Colombier void	nextpc(void);
243e887ea33SDavid du Colombier void	gargs(Node*, Node*, Node*);
244e887ea33SDavid du Colombier void	garg1(Node*, Node*, Node*, int, Node**);
245e887ea33SDavid du Colombier Node*	nodconst(long);
246e887ea33SDavid du Colombier Node*	nodfconst(double);
247e887ea33SDavid du Colombier Node*	nodgconst(vlong, Type*);
248e887ea33SDavid du Colombier int	nodreg(Node*, Node*, int);
249e887ea33SDavid du Colombier int	isreg(Node*, int);
250e887ea33SDavid du Colombier void	regret(Node*, Node*);
251e887ea33SDavid du Colombier void	regalloc(Node*, Node*, Node*);
252e887ea33SDavid du Colombier void	regfree(Node*);
253e887ea33SDavid du Colombier void	regialloc(Node*, Node*, Node*);
254e887ea33SDavid du Colombier void	regsalloc(Node*, Node*);
255e887ea33SDavid du Colombier void	regaalloc1(Node*, Node*);
256e887ea33SDavid du Colombier void	regaalloc(Node*, Node*);
257e887ea33SDavid du Colombier void	regind(Node*, Node*);
258e887ea33SDavid du Colombier void	gprep(Node*, Node*);
259e887ea33SDavid du Colombier void	naddr(Node*, Adr*);
260e887ea33SDavid du Colombier void	gcmp(int, Node*, vlong);
261e887ea33SDavid du Colombier void	gmove(Node*, Node*);
262e887ea33SDavid du Colombier void	gins(int a, Node*, Node*);
263e887ea33SDavid du Colombier void	gopcode(int, Type*, Node*, Node*);
264e887ea33SDavid du Colombier int	samaddr(Node*, Node*);
265e887ea33SDavid du Colombier void	gbranch(int);
266e887ea33SDavid du Colombier void	patch(Prog*, long);
267e887ea33SDavid du Colombier int	sconst(Node*);
268e887ea33SDavid du Colombier void	gpseudo(int, Sym*, Node*);
269e887ea33SDavid du Colombier 
270e887ea33SDavid du Colombier /*
271e887ea33SDavid du Colombier  * swt.c
272e887ea33SDavid du Colombier  */
273e887ea33SDavid du Colombier int	swcmp(const void*, const void*);
274e887ea33SDavid du Colombier void	doswit(Node*);
275e887ea33SDavid du Colombier void	swit1(C1*, int, long, Node*);
276e887ea33SDavid du Colombier void	casf(void);
277e887ea33SDavid du Colombier void	bitload(Node*, Node*, Node*, Node*, Node*);
278e887ea33SDavid du Colombier void	bitstore(Node*, Node*, Node*, Node*, Node*);
279e887ea33SDavid du Colombier long	outstring(char*, long);
280e887ea33SDavid du Colombier void	nullwarn(Node*, Node*);
281e887ea33SDavid du Colombier void	gextern(Sym*, Node*, long, long);
282e887ea33SDavid du Colombier void	outcode(void);
283e887ea33SDavid du Colombier void	ieeedtod(Ieee*, double);
284e887ea33SDavid du Colombier 
285e887ea33SDavid du Colombier /*
286e887ea33SDavid du Colombier  * list
287e887ea33SDavid du Colombier  */
288e887ea33SDavid du Colombier void	listinit(void);
289e887ea33SDavid du Colombier int	Pconv(Fmt*);
290e887ea33SDavid du Colombier int	Aconv(Fmt*);
291e887ea33SDavid du Colombier int	Dconv(Fmt*);
292e887ea33SDavid du Colombier int	Sconv(Fmt*);
293e887ea33SDavid du Colombier int	Rconv(Fmt*);
294e887ea33SDavid du Colombier int	Xconv(Fmt*);
295e887ea33SDavid du Colombier int	Bconv(Fmt*);
296e887ea33SDavid du Colombier 
297e887ea33SDavid du Colombier /*
298e887ea33SDavid du Colombier  * reg.c
299e887ea33SDavid du Colombier  */
300e887ea33SDavid du Colombier Reg*	rega(void);
301e887ea33SDavid du Colombier int	rcmp(const void*, const void*);
302e887ea33SDavid du Colombier void	regopt(Prog*);
303e887ea33SDavid du Colombier void	addmove(Reg*, int, int, int);
304e887ea33SDavid du Colombier Bits	mkvar(Reg*, Adr*);
305e887ea33SDavid du Colombier void	prop(Reg*, Bits, Bits);
306e887ea33SDavid du Colombier void	loopit(Reg*, long);
307e887ea33SDavid du Colombier void	synch(Reg*, Bits);
308e887ea33SDavid du Colombier ulong	allreg(ulong, Rgn*);
309e887ea33SDavid du Colombier void	paint1(Reg*, int);
310e887ea33SDavid du Colombier ulong	paint2(Reg*, int);
311e887ea33SDavid du Colombier void	paint3(Reg*, int, long, int);
312e887ea33SDavid du Colombier void	addreg(Adr*, int);
313e887ea33SDavid du Colombier 
314e887ea33SDavid du Colombier /*
315e887ea33SDavid du Colombier  * peep.c
316e887ea33SDavid du Colombier  */
317e887ea33SDavid du Colombier void	peep(void);
318e887ea33SDavid du Colombier void	excise(Reg*);
319e887ea33SDavid du Colombier Reg*	uniqp(Reg*);
320e887ea33SDavid du Colombier Reg*	uniqs(Reg*);
321e887ea33SDavid du Colombier int	regtyp(Adr*);
322e887ea33SDavid du Colombier int	anyvar(Adr*);
323e887ea33SDavid du Colombier int	subprop(Reg*);
324e887ea33SDavid du Colombier int	copyprop(Reg*);
325e887ea33SDavid du Colombier int	copy1(Adr*, Adr*, Reg*, int);
326e887ea33SDavid du Colombier int	copyu(Prog*, Adr*, Adr*);
327e887ea33SDavid du Colombier 
328e887ea33SDavid du Colombier int	copyas(Adr*, Adr*);
329e887ea33SDavid du Colombier int	copyau(Adr*, Adr*);
330e887ea33SDavid du Colombier int	copysub(Adr*, Adr*, Adr*, int);
331e887ea33SDavid du Colombier int	copysub1(Prog*, Adr*, Adr*, int);
332e887ea33SDavid du Colombier 
333e887ea33SDavid du Colombier long	RtoB(int);
334e887ea33SDavid du Colombier long	FtoB(int);
335e887ea33SDavid du Colombier int	BtoR(long);
336e887ea33SDavid du Colombier int	BtoF(long);
337e887ea33SDavid du Colombier 
338e887ea33SDavid du Colombier #define	isregtype(t)	((t)>= D_AX && (t)<=D_R15)
339e887ea33SDavid du Colombier 
340e887ea33SDavid du Colombier /*
341e887ea33SDavid du Colombier  * bound
342e887ea33SDavid du Colombier  */
343e887ea33SDavid du Colombier void	comtarg(void);
344e887ea33SDavid du Colombier 
345e887ea33SDavid du Colombier /*
346e887ea33SDavid du Colombier  * com64
347e887ea33SDavid du Colombier  */
348e887ea33SDavid du Colombier int	cond(int);
349e887ea33SDavid du Colombier int	com64(Node*);
350e887ea33SDavid du Colombier void	com64init(void);
351e887ea33SDavid du Colombier void	bool64(Node*);
352e887ea33SDavid du Colombier long	lo64v(Node*);
353e887ea33SDavid du Colombier long	hi64v(Node*);
354e887ea33SDavid du Colombier Node*	lo64(Node*);
355e887ea33SDavid du Colombier Node*	hi64(Node*);
356e887ea33SDavid du Colombier 
357e887ea33SDavid du Colombier /*
358e887ea33SDavid du Colombier  * div/mul
359e887ea33SDavid du Colombier  */
360e887ea33SDavid du Colombier void	sdivgen(Node*, Node*, Node*, Node*);
361e887ea33SDavid du Colombier void	udivgen(Node*, Node*, Node*, Node*);
362e887ea33SDavid du Colombier void	sdiv2(long, int, Node*, Node*);
363e887ea33SDavid du Colombier void	smod2(long, int, Node*, Node*);
364e887ea33SDavid du Colombier void	mulgen(Type*, Node*, Node*);
365e887ea33SDavid du Colombier void	genmuladd(Node*, Node*, int, Node*);
366e887ea33SDavid du Colombier void	shiftit(Type*, Node*, Node*);
367e887ea33SDavid du Colombier 
368e887ea33SDavid du Colombier #pragma	varargck	type	"A"	int
369e887ea33SDavid du Colombier #pragma	varargck	type	"B"	Bits
370e887ea33SDavid du Colombier #pragma	varargck	type	"D"	Adr*
371e887ea33SDavid du Colombier #pragma	varargck	type	"P"	Prog*
372e887ea33SDavid du Colombier #pragma	varargck	type	"R"	int
373e887ea33SDavid du Colombier #pragma	varargck	type	"S"	char*
374e887ea33SDavid du Colombier 
375e887ea33SDavid du Colombier #define	D_X7	(D_X0+7)
376e887ea33SDavid du Colombier 
377e887ea33SDavid du Colombier void	fgopcode(int, Node*, Node*, int, int);
378