diff options
| author | Rob Pike <r@golang.org> | 2008-06-04 14:46:07 -0700 | 
|---|---|---|
| committer | Rob Pike <r@golang.org> | 2008-06-04 14:46:07 -0700 | 
| commit | 5cf1e37b96825023b2da8de9be3a07d1987bb306 (patch) | |
| tree | fda9e615c7d6ddb748cee567027fae05ba9215ae /src/old/c/gsubr.c | |
| parent | 0a2697043d69739b27b6ba872b2092a4c2bb61a8 (diff) | |
| download | golang-5cf1e37b96825023b2da8de9be3a07d1987bb306.tar.gz | |
move old code into 'old' directory
add src/test dir
SVN=121166
Diffstat (limited to 'src/old/c/gsubr.c')
| -rw-r--r-- | src/old/c/gsubr.c | 524 | 
1 files changed, 524 insertions, 0 deletions
| diff --git a/src/old/c/gsubr.c b/src/old/c/gsubr.c new file mode 100644 index 000000000..2ac8ea8cf --- /dev/null +++ b/src/old/c/gsubr.c @@ -0,0 +1,524 @@ +// 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 "go.h" +#include "gen.h" + +Prog* +gbranch(int op, Node *t) +{ +	Prog *p; + +	p = prog(op); +	p->addr.type = ABRANCH; +	p->pt = conv2pt(t); +	return p; +} + +Prog* +gopcode(int op, int pt, Node *n) +{ +	Prog *p; + +	p = prog(op); +	p->pt = pt; +	p->addr.node = n; +	if(n == N) { +		p->addr.type = ANONE; +		return p; +	} +	if(n->op == OTYPE) { +		p->pt1 = conv2pt(n); +		p->addr.type = ANONE; +		return p; +	} +	p->addr.type = ANODE; +//	p->param = n->param; +	return p; +} + +Prog* +gopcodet(int op, Node *t, Node *n) +{ +	return gopcode(op, conv2pt(t), n); +} + +void +gaddoffset(Node *n) +{ +	Prog *p; + +	if(n == N || n->op != ONAME || n->sym == S) +		goto bad; +	p = gopcode(PADDO, PTADDR, n); +	return; + +bad: +	fatal("gaddoffset: %N", n); + +} + +void +gconv(int t1, int t2) +{ +	Prog *p; + +	p = gopcode(PCONV, t1, N); +	p->pt1 = t2; +} + +int +conv2pt(Node *t) +{ +	if(t == N) +		return PTxxx; +	switch(t->etype) { +	case TPTR: +		t = t->type; +		if(t == N) +			return PTERROR; +		switch(t->etype) { +		case PTSTRING: +		case PTCHAN: +		case PTMAP: +			return t->etype; +		} +		return TPTR; +	} +	return t->etype; +} + +void +patch(Prog *p, Prog *to) +{ +	if(p->addr.type != ABRANCH) +		yyerror("patch: not a branch"); +	p->addr.branch = to; +} + +Prog* +prog(int as) +{ +	Prog *p; + +	p = pc; +	pc = mal(sizeof(*pc)); + +	pc->op = PEND; +	pc->addr.type = ANONE; +	pc->loc = p->loc+1; + +	p->op = as; +	p->lineno = dynlineno; +	p->link = pc; +	return p; +} + +void +proglist(void) +{ +	Prog *p; + +	print("--- prog list ---\n"); +	for(p=firstpc; p!=P; p=p->link) +		print("%P\n", p); +} + +char*	ptnames[] = +{ +	[PTxxx]		= "", +	[PTINT8]	= "I8", +	[PTUINT8]	= "U8", +	[PTINT16]	= "I16", +	[PTUINT16]	= "U16", +	[PTINT32]	= "I32", +	[PTUINT32]	= "U32", +	[PTINT64]	= "I64", +	[PTUINT64]	= "U64", +	[PTFLOAT32]	= "F32", +	[PTFLOAT64]	= "F64", +	[PTFLOAT80]	= "F80", +	[PTBOOL]	= "B", +	[PTPTR]		= "P", +	[PTADDR]	= "A", +	[PTINTER]	= "I", +	[PTNIL]		= "N", +	[PTSTRUCT]	= "S", +	[PTSTRING]	= "Z", +	[PTCHAN]	= "C", +	[PTMAP]		= "M", +	[PTERROR]	= "?", +}; + +int +Xconv(Fmt *fp) +{ +	char buf[100]; +	int pt; + +	pt = va_arg(fp->args, int); +	if(pt < 0 || pt >= nelem(ptnames) || ptnames[pt] == nil) { +		snprint(buf, sizeof(buf), "PT(%d)", pt); +		return fmtstrcpy(fp, buf); +	} +	return fmtstrcpy(fp, ptnames[pt]); +} + +int +Qconv(Fmt *fp) +{ +	char buf[100]; +	int pt; + +	pt = va_arg(fp->args, int); +	if(pt == PTADDR) +		pt = PTPTR; +	snprint(buf, sizeof(buf), "_T_%X", pt); +	return fmtstrcpy(fp, buf); +} + +int +Rconv(Fmt *fp) +{ +	char buf[100]; +	int pt; + +	pt = va_arg(fp->args, int); +	if(pt == PTADDR) +		snprint(buf, sizeof(buf), "_R_%X", pt); +	else +		snprint(buf, sizeof(buf), "_U._R_%X", pt); +	return fmtstrcpy(fp, buf); +} + +/* +s%[ 	]*%%g +s%(\/\*.*)*%%g +s%,%\n%g +s%\n+%\n%g +s%(=0)*%%g +s%^P(.+)%	[P\1]		= "\1",%g +s%^	........*\]		=%&~%g +s%	=~%=%g +*/ + +static char* +pnames[] = +{ +	[PXXX]		= "XXX", +	[PERROR]	= "ERROR", +	[PPANIC]	= "PANIC", +	[PPRINT]	= "PRINT", +	[PGOTO]		= "GOTO", +	[PGOTOX]	= "GOTOX", +	[PCMP]		= "CMP", +	[PNEW]		= "NEW", +	[PLEN]		= "LEN", +	[PTEST]		= "TEST", +	[PCALL1]	= "CALL1", +	[PCALL2]	= "CALL2", +	[PCALLI2]	= "CALLI2", +	[PCALLM2]	= "CALLM2", +	[PCALLF2]	= "CALLF2", +	[PCALL3]	= "CALL3", +	[PRETURN]	= "RETURN", +	[PBEQ]		= "BEQ", +	[PBNE]		= "BNE", +	[PBLT]		= "BLT", +	[PBLE]		= "BLE", +	[PBGE]		= "BGE", +	[PBGT]		= "BGT", +	[PBTRUE]	= "BTRUE", +	[PBFALSE]	= "BFALSE", +	[PLOAD]		= "LOAD", +	[PLOADI]	= "LOADI", +	[PSTORE]	= "STORE", +	[PSTOREI]	= "STOREI", +	[PSTOREZ]	= "STOREZ", +	[PSTOREZI]	= "STOREZI", +	[PCONV]		= "CONV", +	[PADDR]		= "ADDR", +	[PADDO]		= "ADDO", +	[PINDEX]	= "INDEX", +	[PINDEXZ]	= "INDEXZ", +	[PCAT]		= "CAT", +	[PADD]		= "ADD", +	[PSUB]		= "SUB", +	[PSLICE]	= "SLICE", +	[PMUL]		= "MUL", +	[PDIV]		= "DIV", +	[PLSH]		= "LSH", +	[PRSH]		= "RSH", +	[PMOD]		= "MOD", +	[PMINUS]	= "MINUS", +	[PCOM]		= "COM", +	[PAND]		= "AND", +	[POR]		= "OR", +	[PXOR]		= "XOR", +	[PEND]		= "END", +}; + +int +Aconv(Fmt *fp) +{ +	char buf[100], buf1[100]; +	Prog *p; +	int o; + +	p = va_arg(fp->args, Prog*); +	if(p == P) { +		snprint(buf, sizeof(buf), "<P>"); +		goto ret; +	} + +	o = p->op; +	if(o < 0 || o >= nelem(pnames) || pnames[o] == nil) +		snprint(buf, sizeof(buf), "(A%d)", o); +	else +		snprint(buf, sizeof(buf), "%s", pnames[o]); + +	o = p->pt; +	if(o != PTxxx) { +		snprint(buf1, sizeof(buf1), "-%X", o); +		strncat(buf, buf1, sizeof(buf)); +	} + +	o = p->pt1; +	if(o != PTxxx) { +		snprint(buf1, sizeof(buf1), "-%X", o); +		strncat(buf, buf1, sizeof(buf)); +	} + +ret: +	return fmtstrcpy(fp, buf); +} + +int +Pconv(Fmt *fp) +{ +	char buf[500], buf1[500]; +	Prog *p; + +	p = va_arg(fp->args, Prog*); +	snprint(buf1, sizeof(buf1), "%4ld %4ld %-9A", p->loc, p->lineno, p); + +	switch(p->addr.type) { +	default: +		snprint(buf, sizeof(buf), "?%d", p->addr.type); +		break; + +	case ANONE: +		goto out; + +	case ANODE: +		snprint(buf, sizeof(buf), "%N", p->addr.node); +		break; + +	case ABRANCH: +		if(p->addr.branch == P) { +			snprint(buf, sizeof(buf), "<nil>"); +			break; +		} +		snprint(buf, sizeof(buf), "%ld", p->addr.branch->loc); +		break; +	} + +	strncat(buf1, " ", sizeof(buf1)); +	strncat(buf1, buf, sizeof(buf1)); + +out: +	return fmtstrcpy(fp, buf1); +} + +static char* +typedefs[] = +{ +	"int",		"int32", +	"uint",		"uint32", +	"rune",		"uint32", +	"short",	"int16", +	"ushort",	"uint16", +	"long",		"int32", +	"ulong",	"uint32", +	"vlong",	"int64", +	"uvlong",	"uint64", +	"float",	"float32", +	"double",	"float64", + +}; + +void +belexinit(int lextype) +{ +	int i; +	Sym *s0, *s1; + +	for(i=0; i<nelem(typedefs); i+=2) { +		s1 = lookup(typedefs[i+1]); +		if(s1->lexical != lextype) +			yyerror("need %s to define %s", +				typedefs[i+1], typedefs[i+0]); +		s0 = lookup(typedefs[i+0]); +		s0->lexical = s1->lexical; +		s0->otype = s1->otype; +	} + +	fmtinstall('A', Aconv);		// asm opcodes +	fmtinstall('P', Pconv);		// asm instruction +	fmtinstall('R', Rconv);		// interpreted register +	fmtinstall('Q', Qconv);		// interpreted etype +	fmtinstall('X', Xconv);		// interpreted etype + +	fmtinstall('D', Dconv);		// addressed operand +	fmtinstall('C', Cconv);		// C type +} + +vlong +convvtox(vlong v, int et) +{ +	/* botch - do truncation conversion when energetic */ +	return v; +} + +/* + * return !(op) + * eg == <=> != + */ +int +brcom(int a) +{ +	switch(a) { +	case PBEQ:	return PBNE; +	case PBNE:	return PBEQ; +	case PBLT:	return PBGE; +	case PBGT:	return PBLE; +	case PBLE:	return PBGT; +	case PBGE:	return PBLT; +	case PBTRUE:	return PBFALSE; +	case PBFALSE:	return PBTRUE; +	} +	fatal("brcom: no com for %A\n", a); +	return PERROR; +} + +/* + * return reverse(op) + * eg a op b <=> b r(op) a + */ +int +brrev(int a) +{ +	switch(a) { +	case PBEQ:	return PBEQ; +	case PBNE:	return PBNE; +	case PBLT:	return PBGT; +	case PBGT:	return PBLT; +	case PBLE:	return PBGE; +	case PBGE:	return PBLE; +	} +	fatal("brcom: no rev for %A\n", a); +	return PERROR; +} + +/* + * codegen the address of the ith + * element in the jth argument. + */ +void +fnparam(Node *t, int j, int i) +{ +	Node *a, *f; + +	switch(j) { +	default: +		fatal("fnparam: bad j"); +	case 0: +		a = getthisx(t); +		break; +	case 1: +		a = getoutargx(t); +		break; +	case 2: +		a = getinargx(t); +		break; +	} + +	f = a->type; +	while(i > 0) { +		f = f->down; +		i--; +	} +	if(f->etype != TFIELD) +		fatal("fnparam: not field"); + +	gopcode(PLOAD, PTADDR, a->nname); +	gopcode(PADDO, PTADDR, f->nname); +} + +Sig* +lsort(Sig *l, int(*f)(Sig*, Sig*)) +{ +	Sig *l1, *l2, *le; + +	if(l == 0 || l->link == 0) +		return l; + +	l1 = l; +	l2 = l; +	for(;;) { +		l2 = l2->link; +		if(l2 == 0) +			break; +		l2 = l2->link; +		if(l2 == 0) +			break; +		l1 = l1->link; +	} + +	l2 = l1->link; +	l1->link = 0; +	l1 = lsort(l, f); +	l2 = lsort(l2, f); + +	/* set up lead element */ +	if((*f)(l1, l2) < 0) { +		l = l1; +		l1 = l1->link; +	} else { +		l = l2; +		l2 = l2->link; +	} +	le = l; + +	for(;;) { +		if(l1 == 0) { +			while(l2) { +				le->link = l2; +				le = l2; +				l2 = l2->link; +			} +			le->link = 0; +			break; +		} +		if(l2 == 0) { +			while(l1) { +				le->link = l1; +				le = l1; +				l1 = l1->link; +			} +			break; +		} +		if((*f)(l1, l2) < 0) { +			le->link = l1; +			le = l1; +			l1 = l1->link; +		} else { +			le->link = l2; +			le = l2; +			l2 = l2->link; +		} +	} +	le->link = 0; +	return l; +} | 
