summaryrefslogtreecommitdiff
path: root/src/old/c/gsubr.c
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2008-06-04 14:46:07 -0700
committerRob Pike <r@golang.org>2008-06-04 14:46:07 -0700
commit5cf1e37b96825023b2da8de9be3a07d1987bb306 (patch)
treefda9e615c7d6ddb748cee567027fae05ba9215ae /src/old/c/gsubr.c
parent0a2697043d69739b27b6ba872b2092a4c2bb61a8 (diff)
downloadgolang-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.c524
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;
+}