summaryrefslogtreecommitdiff
path: root/src/cmd/cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/cc')
-rw-r--r--src/cmd/cc/cc.h38
-rw-r--r--src/cmd/cc/lex.c127
-rw-r--r--src/cmd/cc/lexbody76
-rw-r--r--src/cmd/cc/macbody56
-rw-r--r--src/cmd/cc/pgen.c133
-rw-r--r--src/cmd/cc/pswt.c29
-rw-r--r--src/cmd/cc/sub.c10
7 files changed, 165 insertions, 304 deletions
diff --git a/src/cmd/cc/cc.h b/src/cmd/cc/cc.h
index af2339c97..c8aac1253 100644
--- a/src/cmd/cc/cc.h
+++ b/src/cmd/cc/cc.h
@@ -30,6 +30,7 @@
#include <libc.h>
#include <bio.h>
+#include <link.h>
#ifndef EXTERN
#define EXTERN extern
@@ -48,13 +49,13 @@ typedef struct Type Type;
typedef struct Funct Funct;
typedef struct Decl Decl;
typedef struct Io Io;
-typedef struct Hist Hist;
typedef struct Term Term;
typedef struct Init Init;
typedef struct Bits Bits;
typedef struct Bvec Bvec;
typedef struct Dynimp Dynimp;
typedef struct Dynexp Dynexp;
+typedef struct Var Var;
typedef Rune TRune; /* target system type */
@@ -83,6 +84,14 @@ struct Bvec
uint32 b[];
};
+struct Var
+{
+ vlong offset;
+ LSym* sym;
+ char name;
+ char etype;
+};
+
struct Node
{
Node* left;
@@ -114,6 +123,7 @@ struct Node
struct Sym
{
Sym* link;
+ LSym* lsym;
Type* type;
Type* suetag;
Type* tenum;
@@ -200,16 +210,6 @@ struct Io
};
#define I ((Io*)0)
-struct Hist
-{
- Hist* link;
- char* name;
- int32 line;
- int32 offset;
-};
-#define H ((Hist*)0)
-EXTERN Hist* hist;
-
struct Term
{
vlong mult;
@@ -469,7 +469,6 @@ EXTERN int32 autoffset;
EXTERN int blockno;
EXTERN Decl* dclstack;
EXTERN int debug[256];
-EXTERN Hist* ehist;
EXTERN int32 firstbit;
EXTERN Sym* firstarg;
EXTERN Type* firstargtype;
@@ -498,7 +497,6 @@ EXTERN int32 nsymb;
EXTERN Biobuf outbuf;
EXTERN Biobuf diagbuf;
EXTERN char* outfile;
-EXTERN char* pathname;
EXTERN int peekc;
EXTERN int32 stkoff;
EXTERN Type* strf;
@@ -508,8 +506,9 @@ EXTERN Sym* symstring;
EXTERN int taggen;
EXTERN Type* tfield;
EXTERN Type* tufield;
-EXTERN int thechar;
-EXTERN char* thestring;
+extern int thechar;
+extern char* thestring;
+extern LinkArch* thelinkarch;
EXTERN Type* thisfn;
EXTERN int32 thunk;
EXTERN Type* types[NALLTYPES];
@@ -525,8 +524,11 @@ EXTERN int flag_largemodel;
EXTERN int ncontin;
EXTERN int canreach;
EXTERN int warnreach;
+EXTERN int nacl;
EXTERN Bits zbits;
EXTERN Fmt pragcgobuf;
+EXTERN Biobuf bstdout;
+EXTERN Var var[NVAR];
extern char *onames[], *tnames[], *gnames[];
extern char *cnames[], *qnames[], *bnames[];
@@ -556,6 +558,7 @@ extern uchar typechlpfd[];
EXTERN uchar* typeword;
EXTERN uchar* typecmplx;
+EXTERN Link* ctxt;
extern uint32 thash1;
extern uint32 thash2;
@@ -603,6 +606,7 @@ int FNconv(Fmt*);
int Oconv(Fmt*);
int Qconv(Fmt*);
int VBconv(Fmt*);
+int Bconv(Fmt*);
void setinclude(char*);
/*
@@ -612,7 +616,6 @@ void dodefine(char*);
void domacro(void);
Sym* getsym(void);
int32 getnsn(void);
-void linehist(char*, int);
void macdef(void);
void macprag(void);
void macend(void);
@@ -731,6 +734,7 @@ void diag(Node*, char*, ...);
void warn(Node*, char*, ...);
void yyerror(char*, ...);
void fatal(Node*, char*, ...);
+LSym* linksym(Sym*);
/*
* acid.c
@@ -791,6 +795,7 @@ int32 exreg(Type*);
int32 align(int32, Type*, int, int32*);
int32 maxround(int32, int32);
int hasdotdotdot(void);
+void linkarchinit(void);
extern schar ewidth[];
@@ -814,6 +819,7 @@ int machcap(Node*);
#pragma varargck argpos diag 2
#pragma varargck argpos yyerror 1
+#pragma varargck type "B" Bits
#pragma varargck type "F" Node*
#pragma varargck type "L" int32
#pragma varargck type "Q" int32
diff --git a/src/cmd/cc/lex.c b/src/cmd/cc/lex.c
index 049dc5196..424843764 100644
--- a/src/cmd/cc/lex.c
+++ b/src/cmd/cc/lex.c
@@ -117,8 +117,28 @@ void
main(int argc, char *argv[])
{
int c;
+ char *p;
+
+ // Allow GOARCH=thestring or GOARCH=thestringsuffix,
+ // but not other values.
+ p = getgoarch();
+ if(strncmp(p, thestring, strlen(thestring)) != 0)
+ sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
+ if(strcmp(p, "amd64p32") == 0) // must be before cinit
+ ewidth[TIND] = 4;
+
+ nacl = strcmp(getgoos(), "nacl") == 0;
+ if(nacl)
+ flag_largemodel = 1;
quotefmtinstall(); // before cinit, which overrides %Q
+
+ linkarchinit();
+ ctxt = linknew(thelinkarch);
+ ctxt->diag = yyerror;
+ ctxt->bso = &bstdout;
+ Binit(&bstdout, 1, OWRITE);
+
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
tinit();
@@ -175,12 +195,14 @@ main(int argc, char *argv[])
flagcount("q", "print Go definitions", &debug['q']);
flagcount("s", "print #define assembly offsets", &debug['s']);
flagcount("t", "debug code generation", &debug['t']);
+ flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
flagcount("w", "enable warnings", &debug['w']);
flagcount("v", "increase debug verbosity", &debug['v']);
if(thechar == '6')
flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel);
flagparse(&argc, &argv, usage);
+ ctxt->debugasm = debug['S'];
if(argc < 1 && outfile == 0)
usage();
@@ -195,6 +217,7 @@ main(int argc, char *argv[])
else
c = compile(argv[0], defs, ndef);
+ Bflush(&bstdout);
if(c)
errorexit();
exits(0);
@@ -331,6 +354,7 @@ compile(char *file, char **defs, int ndef)
void
errorexit(void)
{
+ Bflush(&bstdout);
if(outfile)
remove(outfile);
exits("error");
@@ -390,7 +414,7 @@ newfile(char *s, int f)
errorexit();
}
fi.c = 0;
- linehist(s, 0);
+ linklinehist(ctxt, lineno, s, 0);
}
Sym*
@@ -1300,13 +1324,6 @@ cinit(void)
nodproto = new(OPROTO, Z, Z);
dclstack = D;
- pathname = allocn(pathname, 0, 100);
- if(getwd(pathname, 99) == 0) {
- pathname = allocn(pathname, 100, 900);
- if(getwd(pathname, 999) == 0)
- strcpy(pathname, "/???");
- }
-
fmtinstall('O', Oconv);
fmtinstall('T', Tconv);
fmtinstall('F', FNconv);
@@ -1314,6 +1331,7 @@ cinit(void)
fmtinstall('Q', Qconv);
fmtinstall('|', VBconv);
fmtinstall('U', Uconv);
+ fmtinstall('B', Bconv);
}
int
@@ -1330,7 +1348,7 @@ loop:
fi.c = read(i->f, i->b, BUFSIZ) - 1;
if(fi.c < 0) {
close(i->f);
- linehist(0, 0);
+ linklinehist(ctxt, lineno, nil, 0);
goto pop;
}
fi.p = i->b + 1;
@@ -1365,70 +1383,7 @@ Oconv(Fmt *fp)
int
Lconv(Fmt *fp)
{
- char str[STRINGSZ], s[STRINGSZ];
- Hist *h;
- struct
- {
- Hist* incl; /* start of this include file */
- int32 idel; /* delta line number to apply to include */
- Hist* line; /* start of this #line directive */
- int32 ldel; /* delta line number to apply to #line */
- } a[HISTSZ];
- int32 l, d;
- int i, n;
-
- l = va_arg(fp->args, int32);
- n = 0;
- for(h = hist; h != H; h = h->link) {
- if(l < h->line)
- break;
- if(h->name) {
- if(h->offset != 0) { /* #line directive, not #pragma */
- if(n > 0 && n < HISTSZ && h->offset >= 0) {
- a[n-1].line = h;
- a[n-1].ldel = h->line - h->offset + 1;
- }
- } else {
- if(n < HISTSZ) { /* beginning of file */
- a[n].incl = h;
- a[n].idel = h->line;
- a[n].line = 0;
- }
- n++;
- }
- continue;
- }
- n--;
- if(n > 0 && n < HISTSZ) {
- d = h->line - a[n].incl->line;
- a[n-1].ldel += d;
- a[n-1].idel += d;
- }
- }
- if(n > HISTSZ)
- n = HISTSZ;
- str[0] = 0;
- for(i=n-1; i>=0; i--) {
- if(i != n-1) {
- if(fp->flags & ~(FmtWidth|FmtPrec)) /* BUG ROB - was f3 */
- break;
- strcat(str, " ");
- }
- if(a[i].line)
- snprint(s, STRINGSZ, "%s:%d[%s:%d]",
- a[i].line->name, l-a[i].ldel+1,
- a[i].incl->name, l-a[i].idel+1);
- else
- snprint(s, STRINGSZ, "%s:%d",
- a[i].incl->name, l-a[i].idel+1);
- if(strlen(s)+strlen(str) >= STRINGSZ-10)
- break;
- strcat(str, s);
- l = a[i].incl->line - 1; /* now print out start of this file */
- }
- if(n == 0)
- strcat(str, "<eof>");
- return fmtstrcpy(fp, str);
+ return linklinefmt(ctxt, fp);
}
int
@@ -1548,6 +1503,32 @@ VBconv(Fmt *fp)
return fmtstrcpy(fp, str);
}
+int
+Bconv(Fmt *fp)
+{
+ char str[STRINGSZ], ss[STRINGSZ], *s;
+ Bits bits;
+ int i;
+
+ str[0] = 0;
+ bits = va_arg(fp->args, Bits);
+ while(bany(&bits)) {
+ i = bnum(bits);
+ if(str[0])
+ strcat(str, " ");
+ if(var[i].sym == nil) {
+ sprint(ss, "$%lld", var[i].offset);
+ s = ss;
+ } else
+ s = var[i].sym->name;
+ if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
+ break;
+ strcat(str, s);
+ bits.b[i/32] &= ~(1L << (i%32));
+ }
+ return fmtstrcpy(fp, str);
+}
+
void
setinclude(char *p)
{
diff --git a/src/cmd/cc/lexbody b/src/cmd/cc/lexbody
index 9d293b089..e24db1bc0 100644
--- a/src/cmd/cc/lexbody
+++ b/src/cmd/cc/lexbody
@@ -152,7 +152,7 @@ setinclude(char *p)
void
errorexit(void)
{
-
+ Bflush(&bstdout);
if(outfile)
remove(outfile);
exits("error");
@@ -209,7 +209,7 @@ newfile(char *s, int f)
errorexit();
}
fi.c = 0;
- linehist(s, 0);
+ linklinehist(ctxt, lineno, s, 0);
}
Sym*
@@ -477,7 +477,7 @@ l1:
return LCONST;
case '"':
- memcpy(yylval.sval, nullgen.sval, sizeof(yylval.sval));
+ memcpy(yylval.sval, nullgen.u.sval, sizeof(yylval.sval));
cp = yylval.sval;
c1 = 0;
for(;;) {
@@ -638,10 +638,6 @@ pinit(char *f)
pc = 0;
peekc = IGN;
sym = 1;
- for(i=0; i<NSYM; i++) {
- h[i].type = 0;
- h[i].sym = S;
- }
for(i=0; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->link)
s->macro = 0;
@@ -661,7 +657,7 @@ loop:
fi.c = read(i->f, i->b, BUFSIZ) - 1;
if(fi.c < 0) {
close(i->f);
- linehist(0, 0);
+ linklinehist(ctxt, lineno, 0, 0);
goto pop;
}
fi.p = i->b + 1;
@@ -709,67 +705,5 @@ yyerror(char *a, ...)
void
prfile(int32 l)
{
- int i, n;
- Hist a[HISTSZ], *h;
- int32 d;
-
- n = 0;
- for(h = hist; h != H; h = h->link) {
- if(l < h->line)
- break;
- if(h->name) {
- if(h->offset == 0) {
- if(n >= 0 && n < HISTSZ)
- a[n] = *h;
- n++;
- continue;
- }
- if(n > 0 && n < HISTSZ)
- if(a[n-1].offset == 0) {
- a[n] = *h;
- n++;
- } else
- a[n-1] = *h;
- continue;
- }
- n--;
- if(n >= 0 && n < HISTSZ) {
- d = h->line - a[n].line;
- for(i=0; i<n; i++)
- a[i].line += d;
- }
- }
- if(n > HISTSZ)
- n = HISTSZ;
- for(i=0; i<n; i++)
- print("%s:%ld ", a[i].name, (long)(l-a[i].line+a[i].offset+1));
-}
-
-void
-ieeedtod(Ieee *ieee, double native)
-{
- double fr, ho, f;
- int exp;
-
- if(native < 0) {
- ieeedtod(ieee, -native);
- ieee->h |= 0x80000000L;
- return;
- }
- if(native == 0) {
- ieee->l = 0;
- ieee->h = 0;
- return;
- }
- fr = frexp(native, &exp);
- f = 2097152L; /* shouldn't use fp constants here */
- fr = modf(fr*f, &ho);
- ieee->h = ho;
- ieee->h &= 0xfffffL;
- ieee->h |= (exp+1022L) << 20;
- f = 65536L;
- fr = modf(fr*f, &ho);
- ieee->l = ho;
- ieee->l = (uint32)ieee->l << 16;
- ieee->l |= (int32)(fr*f);
+ linkprfile(ctxt, l);
}
diff --git a/src/cmd/cc/macbody b/src/cmd/cc/macbody
index f0a507669..f6927b2f6 100644
--- a/src/cmd/cc/macbody
+++ b/src/cmd/cc/macbody
@@ -642,7 +642,7 @@ nn:
c = strlen(symb) + 1;
cp = alloc(c);
memcpy(cp, symb, c);
- linehist(cp, n);
+ linklinehist(ctxt, lineno, cp, n);
return;
bad:
@@ -713,7 +713,6 @@ macprag(void)
Sym *s;
int c0, c;
char *hp;
- Hist *h;
s = getsym();
@@ -779,18 +778,7 @@ praglib:
hp = alloc(c);
memcpy(hp, symb, c);
- h = alloc(sizeof(Hist));
- h->name = hp;
- h->line = lineno;
- h->offset = -1;
- h->link = H;
- if(ehist == H) {
- hist = h;
- ehist = h;
- return;
- }
- ehist->link = h;
- ehist = h;
+ linklinehist(ctxt, lineno, hp, -1);
return;
bad:
@@ -810,43 +798,3 @@ macend(void)
return;
}
}
-
-void
-linehist(char *f, int offset)
-{
- Hist *h;
-
- /*
- * overwrite the last #line directive if
- * no alloc has happened since the last one
- */
- if(newflag == 0 && ehist != H && offset != 0 && ehist->offset != 0)
- if(f && ehist->name && strcmp(f, ehist->name) == 0) {
- ehist->line = lineno;
- ehist->offset = offset;
- return;
- }
-
- if(debug['f'])
- if(f) {
- if(offset)
- print("%4d: %s (#line %d)\n", lineno, f, offset);
- else
- print("%4d: %s\n", lineno, f);
- } else
- print("%4d: <pop>\n", lineno);
- newflag = 0;
-
- h = alloc(sizeof(Hist));
- h->name = f;
- h->line = lineno;
- h->offset = offset;
- h->link = H;
- if(ehist == H) {
- hist = h;
- ehist = h;
- return;
- }
- ehist->link = h;
- ehist = h;
-}
diff --git a/src/cmd/cc/pgen.c b/src/cmd/cc/pgen.c
index b82872bc5..10bebc196 100644
--- a/src/cmd/cc/pgen.c
+++ b/src/cmd/cc/pgen.c
@@ -35,6 +35,26 @@ enum { BitsPerPointer = 2 };
static void dumpgcargs(Type *fn, Sym *sym);
+static Sym*
+makefuncdatasym(char *namefmt, int64 funcdatakind)
+{
+ Node nod;
+ Sym *sym;
+ static int32 nsym;
+ static char namebuf[40];
+
+ snprint(namebuf, sizeof(namebuf), namefmt, nsym++);
+ sym = slookup(namebuf);
+ sym->class = CSTATIC;
+ memset(&nod, 0, sizeof nod);
+ nod.op = ONAME;
+ nod.sym = sym;
+ nod.class = CSTATIC;
+ gins(AFUNCDATA, nodconst(funcdatakind), &nod);
+ linksym(sym)->type = SRODATA;
+ return sym;
+}
+
int
hasdotdotdot(void)
{
@@ -80,10 +100,10 @@ void
codgen(Node *n, Node *nn)
{
Prog *sp;
- Node *n1, nod, nod1, nod2;
- Sym *gcsym, *gclocalssym;
- static int ngcsym, ngclocalssym;
- static char namebuf[40];
+ Node *n1, nod, nod1;
+ Sym *gcargs;
+ Sym *gclocals;
+ int isvarargs;
cursafe = 0;
curarg = 0;
@@ -109,25 +129,11 @@ codgen(Node *n, Node *nn)
* generate funcdata symbol for this function.
* data is filled in at the end of codgen().
*/
- snprint(namebuf, sizeof namebuf, "gc·%d", ngcsym++);
- gcsym = slookup(namebuf);
- gcsym->class = CSTATIC;
-
- memset(&nod, 0, sizeof nod);
- nod.op = ONAME;
- nod.sym = gcsym;
- nod.class = CSTATIC;
- gins(AFUNCDATA, nodconst(FUNCDATA_GCArgs), &nod);
-
- snprint(namebuf, sizeof(namebuf), "gclocalssym·%d", ngclocalssym++);
- gclocalssym = slookup(namebuf);
- gclocalssym->class = CSTATIC;
-
- memset(&nod2, 0, sizeof(nod2));
- nod2.op = ONAME;
- nod2.sym = gclocalssym;
- nod2.class = CSTATIC;
- gins(AFUNCDATA, nodconst(FUNCDATA_GCLocals), &nod2);
+ isvarargs = hasdotdotdot();
+ gcargs = nil;
+ if(!isvarargs)
+ gcargs = makefuncdatasym("gcargs·%d", FUNCDATA_ArgsPointerMaps);
+ gclocals = makefuncdatasym("gclocals·%d", FUNCDATA_LocalsPointerMaps);
/*
* isolate first argument
@@ -166,7 +172,8 @@ codgen(Node *n, Node *nn)
maxargsafe = xround(maxargsafe, 8);
sp->to.offset += maxargsafe;
- dumpgcargs(thisfn, gcsym);
+ if(!isvarargs)
+ dumpgcargs(thisfn, gcargs);
// TODO(rsc): "stkoff" is not right. It does not account for
// the possibility of data stored in .safe variables.
@@ -177,9 +184,9 @@ codgen(Node *n, Node *nn)
// area its own section.
// That said, we've been using stkoff for months
// and nothing too terrible has happened.
- gextern(gclocalssym, nodconst(-stkoff), 0, 4); // locals
- gclocalssym->type = typ(0, T);
- gclocalssym->type->width = 4;
+ gextern(gclocals, nodconst(-stkoff), 0, 4); // locals
+ gclocals->type = typ(0, T);
+ gclocals->type->width = 4;
}
void
@@ -655,7 +662,9 @@ walktype1(Type *t, int32 offset, Bvec *bv, int param)
{
Type *t1;
int32 o;
+ int32 widthptr;
+ widthptr = ewidth[TIND];
switch(t->etype) {
case TCHAR:
case TUCHAR:
@@ -670,14 +679,16 @@ walktype1(Type *t, int32 offset, Bvec *bv, int param)
case TFLOAT:
case TDOUBLE:
// non-pointer types
+ for(o = 0; o < t->width; o++)
+ bvset(bv, ((offset + t->offset + o) / widthptr) * BitsPerPointer); // 1 = live scalar
break;
case TIND:
pointer:
// pointer types
- if((offset + t->offset) % ewidth[TIND] != 0)
+ if((offset + t->offset) % widthptr != 0)
yyerror("unaligned pointer");
- bvset(bv, ((offset + t->offset) / ewidth[TIND])*BitsPerPointer);
+ bvset(bv, ((offset + t->offset) / widthptr)*BitsPerPointer + 1); // 2 = live ptr
break;
case TARRAY:
@@ -715,39 +726,39 @@ dumpgcargs(Type *fn, Sym *sym)
int32 argbytes;
int32 symoffset, argoffset;
- if(hasdotdotdot()) {
- // give up for C vararg functions.
- // TODO: maybe make a map just for the args we do know?
- gextern(sym, nodconst(0), 0, 4); // nptrs=0
- symoffset = 4;
- } else {
- argbytes = (argsize() + ewidth[TIND] - 1);
- bv = bvalloc((argbytes / ewidth[TIND]) * BitsPerPointer);
- argoffset = align(0, fn->link, Aarg0, nil);
- if(argoffset > 0) {
- // The C calling convention returns structs by
- // copying them to a location pointed to by a
- // hidden first argument. This first argument
- // is a pointer.
- if(argoffset != ewidth[TIND])
- yyerror("passbyptr arg not the right size");
- bvset(bv, 0);
- }
- for(t = fn->down; t != T; t = t->down) {
- if(t->etype == TVOID)
- continue;
- argoffset = align(argoffset, t, Aarg1, nil);
- walktype1(t, argoffset, bv, 1);
- argoffset = align(argoffset, t, Aarg2, nil);
- }
- gextern(sym, nodconst(bv->n), 0, 4);
- symoffset = 4;
- for(i = 0; i < bv->n; i += 32) {
- gextern(sym, nodconst(bv->b[i/32]), symoffset, 4);
- symoffset += 4;
- }
- free(bv);
+ // Dump the length of the bitmap array. This value is always one for
+ // functions written in C.
+ symoffset = 0;
+ gextern(sym, nodconst(1), symoffset, 4);
+ symoffset += 4;
+ argbytes = (argsize() + ewidth[TIND] - 1);
+ bv = bvalloc((argbytes / ewidth[TIND]) * BitsPerPointer);
+ argoffset = align(0, fn->link, Aarg0, nil);
+ if(argoffset > 0) {
+ // The C calling convention returns structs by copying them to a
+ // location pointed to by a hidden first argument. This first
+ // argument is a pointer.
+ if(argoffset != ewidth[TIND])
+ yyerror("passbyptr arg not the right size");
+ bvset(bv, 1); // 2 = live ptr
+ }
+ for(t = fn->down; t != T; t = t->down) {
+ if(t->etype == TVOID)
+ continue;
+ argoffset = align(argoffset, t, Aarg1, nil);
+ walktype1(t, argoffset, bv, 1);
+ argoffset = align(argoffset, t, Aarg2, nil);
+ }
+ // Dump the length of the bitmap.
+ gextern(sym, nodconst(bv->n), symoffset, 4);
+ symoffset += 4;
+ // Dump the words of the bitmap.
+ for(i = 0; i < bv->n; i += 32) {
+ gextern(sym, nodconst(bv->b[i/32]), symoffset, 4);
+ symoffset += 4;
}
+ free(bv);
+ // Finalize the gc symbol.
sym->type = typ(0, T);
sym->type->width = symoffset;
}
diff --git a/src/cmd/cc/pswt.c b/src/cmd/cc/pswt.c
index cc9c22763..bae57c64d 100644
--- a/src/cmd/cc/pswt.c
+++ b/src/cmd/cc/pswt.c
@@ -138,32 +138,3 @@ nullwarn(Node *l, Node *r)
if(r != Z)
cgen(r, Z);
}
-
-void
-ieeedtod(Ieee *ieee, double native)
-{
- double fr, ho, f;
- int exp;
-
- if(native < 0) {
- ieeedtod(ieee, -native);
- ieee->h |= 0x80000000L;
- return;
- }
- if(native == 0) {
- ieee->l = 0;
- ieee->h = 0;
- return;
- }
- fr = frexp(native, &exp);
- f = 2097152L; /* shouldn't use fp constants here */
- fr = modf(fr*f, &ho);
- ieee->h = ho;
- ieee->h &= 0xfffffL;
- ieee->h |= (exp+1022L) << 20;
- f = 65536L;
- fr = modf(fr*f, &ho);
- ieee->l = ho;
- ieee->l <<= 16;
- ieee->l |= (int32)(fr*f);
-}
diff --git a/src/cmd/cc/sub.c b/src/cmd/cc/sub.c
index bed989102..94c11d021 100644
--- a/src/cmd/cc/sub.c
+++ b/src/cmd/cc/sub.c
@@ -2056,3 +2056,13 @@ mixedasop(Type *l, Type *r)
{
return !typefd[l->etype] && typefd[r->etype];
}
+
+LSym*
+linksym(Sym *s)
+{
+ if(s == nil)
+ return nil;
+ if(s->lsym != nil)
+ return s->lsym;
+ return linklookup(ctxt, s->name, s->class == CSTATIC);
+}