| // Copyright 2009 The Go Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style | 
 | // license that can be found in the LICENSE file. | 
 |  | 
 | #include <u.h> | 
 | #include <libc.h> | 
 |  | 
 | #include "../gc/go.h" | 
 | #include "../5l/5.out.h" | 
 |  | 
 | #ifndef	EXTERN | 
 | #define EXTERN	extern | 
 | #endif | 
 |  | 
 | typedef	struct	Addr	Addr; | 
 |  | 
 | struct	Addr | 
 | { | 
 | 	int32	offset; | 
 | 	int32	offset2; | 
 | 	double	dval; | 
 | 	Prog*	branch; | 
 | 	char	sval[NSNAME]; | 
 |  | 
 | 	Sym*	sym; | 
 | 	int	width; | 
 | 	uchar	type; | 
 | 	char	name; | 
 | 	char	reg; | 
 | 	char pun; | 
 | 	uchar	etype; | 
 | }; | 
 | #define	A	((Addr*)0) | 
 |  | 
 | struct	Prog | 
 | { | 
 | 	short	as;		// opcode | 
 | 	uint32	loc;		// pc offset in this func | 
 | 	uint32	lineno;		// source line that generated this | 
 | 	Addr	from;		// src address | 
 | 	Addr	to;		// dst address | 
 | 	Prog*	link;		// next instruction in this func | 
 | 	void*	regp;		// points to enclosing Reg struct | 
 | 	char	reg;		// doubles as width in DATA op | 
 | 	uchar	scond; | 
 | }; | 
 |  | 
 | #define REGALLOC_R0 0 | 
 | #define REGALLOC_RMAX REGEXT | 
 | #define REGALLOC_F0 (REGALLOC_RMAX+1) | 
 | #define REGALLOC_FMAX (REGALLOC_F0 + FREGEXT) | 
 |  | 
 | EXTERN	Biobuf*	bout; | 
 | EXTERN	int32	dynloc; | 
 | EXTERN	uchar	reg[REGALLOC_FMAX]; | 
 | EXTERN	int32	pcloc;		// instruction counter | 
 | EXTERN	Strlit	emptystring; | 
 | extern	char*	anames[]; | 
 | EXTERN	Hist*	hist; | 
 | EXTERN	Prog	zprog; | 
 | EXTERN	Node*	curfn; | 
 | EXTERN	Node*	newproc; | 
 | EXTERN	Node*	deferproc; | 
 | EXTERN	Node*	deferreturn; | 
 | EXTERN	Node*	panicindex; | 
 | EXTERN	Node*	panicslice; | 
 | EXTERN	Node*	throwreturn; | 
 | EXTERN	long	unmappedzero; | 
 | EXTERN	int	maxstksize; | 
 |  | 
 | /* | 
 |  * gen.c | 
 |  */ | 
 | void	compile(Node*); | 
 | void	proglist(void); | 
 | void	gen(Node*); | 
 | Node*	lookdot(Node*, Node*, int); | 
 | void	cgen_as(Node*, Node*); | 
 | void	cgen_callmeth(Node*, int); | 
 | void	cgen_callinter(Node*, Node*, int); | 
 | void	cgen_proc(Node*, int); | 
 | void	cgen_callret(Node*, Node*); | 
 | void	cgen_dcl(Node*); | 
 | int	cgen_inline(Node*, Node*); | 
 | int	needconvert(Type*, Type*); | 
 | void	genconv(Type*, Type*); | 
 | void	allocparams(void); | 
 | void	checklabels(); | 
 | void	ginscall(Node*, int); | 
 |  | 
 | /* | 
 |  * cgen | 
 |  */ | 
 | void	agen(Node*, Node*); | 
 | Prog* cgenindex(Node *, Node *); | 
 | void	igen(Node*, Node*, Node*); | 
 | void agenr(Node *n, Node *a, Node *res); | 
 | vlong	fieldoffset(Type*, Node*); | 
 | void	bgen(Node*, int, Prog*); | 
 | void	sgen(Node*, Node*, int32); | 
 | void	gmove(Node*, Node*); | 
 | Prog*	gins(int, Node*, Node*); | 
 | int	samaddr(Node*, Node*); | 
 | void	raddr(Node *n, Prog *p); | 
 | Prog*	gcmp(int, Node*, Node*); | 
 | Prog*	gshift(int as, Node *lhs, int32 stype, int32 sval, Node *rhs); | 
 | Prog *	gregshift(int as, Node *lhs, int32 stype, Node *reg, Node *rhs); | 
 | void	naddr(Node*, Addr*, int); | 
 | void	cgen_aret(Node*, Node*); | 
 | void	cgen_shift(int, Node*, Node*, Node*); | 
 |  | 
 | /* | 
 |  * cgen64.c | 
 |  */ | 
 | void	cmp64(Node*, Node*, int, Prog*); | 
 | void	cgen64(Node*, Node*); | 
 |  | 
 | /* | 
 |  * gsubr.c | 
 |  */ | 
 | void	clearp(Prog*); | 
 | void	proglist(void); | 
 | Prog*	gbranch(int, Type*); | 
 | Prog*	prog(int); | 
 | void	gaddoffset(Node*); | 
 | void	gconv(int, int); | 
 | int	conv2pt(Type*); | 
 | vlong	convvtox(vlong, int); | 
 | void	fnparam(Type*, int, int); | 
 | Prog*	gop(int, Node*, Node*, Node*); | 
 | void	setconst(Addr*, vlong); | 
 | void	setaddr(Addr*, Node*); | 
 | int	optoas(int, Type*); | 
 | void	ginit(void); | 
 | void	gclean(void); | 
 | void	regalloc(Node*, Type*, Node*); | 
 | void	regfree(Node*); | 
 | Node*	nodarg(Type*, int); | 
 | void	nodreg(Node*, Type*, int); | 
 | void	nodindreg(Node*, Type*, int); | 
 | void	buildtxt(void); | 
 | Plist*	newplist(void); | 
 | int	isfat(Type*); | 
 | int	dotaddable(Node*, Node*); | 
 | void	sudoclean(void); | 
 | int	sudoaddable(int, Node*, Addr*, int*); | 
 | void	afunclit(Addr*); | 
 | void	datagostring(Strlit*, Addr*); | 
 | void	split64(Node*, Node*, Node*); | 
 | void	splitclean(void); | 
 | Node*	ncon(uint32 i); | 
 |  | 
 | /* | 
 |  * obj.c | 
 |  */ | 
 | void	datastring(char*, int, Addr*); | 
 |  | 
 | /* | 
 |  * list.c | 
 |  */ | 
 | int	Aconv(Fmt*); | 
 | int	Cconv(Fmt*); | 
 | int	Dconv(Fmt*); | 
 | int	Mconv(Fmt*); | 
 | int	Pconv(Fmt*); | 
 | int	Rconv(Fmt*); | 
 | int	Yconv(Fmt*); | 
 | void	listinit(void); | 
 |  | 
 | void	zaddr(Biobuf*, Addr*, int); |