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; +} |