|  | // 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; | 
|  | 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); |