cmd/5a, cmd/6a, cmd/8a: use liblink

Preparation for golang.org/s/go13linker work.

This CL does not build by itself. It depends on 35740044
and 35790044 and will be submitted at the same time.

R=iant
CC=golang-dev
https://golang.org/cl/35830043
This commit is contained in:
Russ Cox 2013-12-08 22:49:56 -05:00
parent 7d507dc6e6
commit f7aaa553da
16 changed files with 1947 additions and 3622 deletions

View File

@ -29,6 +29,7 @@
// THE SOFTWARE.
#include <bio.h>
#include <link.h>
#include "../5l/5.out.h"
#ifndef EXTERN
@ -43,9 +44,7 @@
#define ungetc ccungetc
typedef struct Sym Sym;
typedef struct Gen Gen;
typedef struct Io Io;
typedef struct Hist Hist;
#define MAXALIGN 7
#define FPCHIP 1
@ -88,33 +87,6 @@ struct Io
};
#define I ((Io*)0)
EXTERN struct
{
Sym* sym;
short type;
} h[NSYM];
struct Gen
{
Sym* sym;
int32 offset;
int32 offset2;
short type;
short reg;
short name;
double dval;
char sval[8];
};
struct Hist
{
Hist* link;
char* name;
int32 line;
int32 offset;
};
#define H ((Hist*)0)
enum
{
CLAST,
@ -129,9 +101,7 @@ EXTERN char debug[256];
EXTERN Sym* hash[NHASH];
EXTERN char** Dlist;
EXTERN int nDlist;
EXTERN Hist* ehist;
EXTERN int newflag;
EXTERN Hist* hist;
EXTERN char* hunk;
EXTERN char** include;
EXTERN Io* iofree;
@ -142,10 +112,9 @@ EXTERN int nerrors;
EXTERN int32 nhunk;
EXTERN int ninclude;
EXTERN int32 nsymb;
EXTERN Gen nullgen;
EXTERN Addr nullgen;
EXTERN char* outfile;
EXTERN int pass;
EXTERN char* pathname;
EXTERN int32 pc;
EXTERN int peekc;
EXTERN int32 stmtline;
@ -155,6 +124,7 @@ EXTERN int thechar;
EXTERN char* thestring;
EXTERN int32 thunk;
EXTERN Biobuf obuf;
EXTERN Link* ctxt;
void* alloc(int32);
void* allocn(void*, int32, int32);
@ -174,11 +144,8 @@ int escchar(int);
void cinit(void);
void pinit(char*);
void cclean(void);
int isreg(Gen*);
void outcode(int, int, Gen*, int, Gen*);
void zname(char*, int, int);
void zaddr(Gen*, int);
void ieeedtod(Ieee*, double);
int isreg(Addr*);
void outcode(int, int, Addr*, int, Addr*);
int filbuf(void);
Sym* getsym(void);
void domacro(void);
@ -190,7 +157,6 @@ void maclin(void);
void macprag(void);
void macif(int);
void macend(void);
void outhist(void);
void dodefine(char*);
void prfile(int32);
void linehist(char*, int);

View File

@ -41,7 +41,7 @@
int32 lval;
double dval;
char sval[8];
Gen gen;
LAddr addr;
}
%left '|'
%left '^'
@ -62,8 +62,8 @@
%token <sym> LNAME LLAB LVAR
%type <lval> con expr oexpr pointer offset sreg spreg creg
%type <lval> rcon cond reglist
%type <gen> gen rel reg regreg freg shift fcon frcon
%type <gen> imm ximm name oreg ireg nireg ioreg imsr
%type <addr> gen rel reg regreg freg shift fcon frcon
%type <addr> imm ximm name oreg ireg nireg ioreg imsr
%%
prog:
| prog
@ -175,7 +175,7 @@ inst:
*/
| LTYPE8 cond ioreg ',' '[' reglist ']'
{
Gen g;
LAddr g;
g = nullgen;
g.type = D_CONST;
@ -184,7 +184,7 @@ inst:
}
| LTYPE8 cond '[' reglist ']' ',' ioreg
{
Gen g;
LAddr g;
g = nullgen;
g.type = D_CONST;
@ -279,7 +279,7 @@ inst:
*/
| LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
{
Gen g;
LAddr g;
g = nullgen;
g.type = D_CONST;
@ -377,14 +377,12 @@ rel:
if(pass == 2)
yyerror("undefined label: %s", $1->name);
$$.type = D_BRANCH;
$$.sym = $1;
$$.offset = $2;
}
| LLAB offset
{
$$ = nullgen;
$$.type = D_BRANCH;
$$.sym = $1;
$$.offset = $1->value + $2;
}
@ -408,7 +406,7 @@ ximm: '$' con
{
$$ = nullgen;
$$.type = D_SCONST;
memcpy($$.sval, $2, sizeof($$.sval));
memcpy($$.u.sval, $2, sizeof($$.u.sval));
}
| fcon
@ -417,13 +415,13 @@ fcon:
{
$$ = nullgen;
$$.type = D_FCONST;
$$.dval = $2;
$$.u.dval = $2;
}
| '$' '-' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
$$.dval = -$3;
$$.u.dval = -$3;
}
reglist:
@ -635,7 +633,7 @@ name:
$$ = nullgen;
$$.type = D_OREG;
$$.name = $3;
$$.sym = S;
$$.sym = nil;
$$.offset = $1;
}
| LNAME offset '(' pointer ')'
@ -643,7 +641,7 @@ name:
$$ = nullgen;
$$.type = D_OREG;
$$.name = $4;
$$.sym = $1;
$$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2;
}
| LNAME '<' '>' offset '(' LSB ')'
@ -651,7 +649,7 @@ name:
$$ = nullgen;
$$.type = D_OREG;
$$.name = D_STATIC;
$$.sym = $1;
$$.sym = linklookup(ctxt, $1->name, 1);
$$.offset = $4;
}

View File

@ -59,6 +59,8 @@ main(int argc, char *argv[])
thechar = '5';
thestring = "arm";
ctxt = linknew(&linkarm);
ctxt->diag = yyerror;
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
@ -90,10 +92,15 @@ main(int argc, char *argv[])
p = ARGF();
setinclude(p);
break;
case 't':
thechar = 't';
thestring = "thumb";
break;
case 'S':
ctxt->debugasm++;
break;
} ARGEND
if(*argv == 0) {
print("usage: %ca [-options] file.s\n", thechar);
@ -143,30 +150,23 @@ assemble(char *file)
errorexit();
}
Binit(&obuf, of, OWRITE);
pass = 1;
pinit(file);
Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion());
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
if(nerrors) {
cclean();
return nerrors;
}
Bprint(&obuf, "\n!\n");
pass = 2;
outhist();
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
return nerrors;
for(pass = 1; pass <= 2; pass++) {
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
if(nerrors)
return nerrors;
}
linkouthist(ctxt, &obuf);
linkwritefuncs(ctxt, &obuf);
Bflush(&obuf);
return 0;
}
struct
@ -426,15 +426,9 @@ cinit(void)
Sym *s;
int i;
nullgen.sym = S;
nullgen.offset = 0;
nullgen.type = D_NONE;
nullgen.name = D_NONE;
nullgen.reg = NREG;
if(FPCHIP)
nullgen.dval = 0;
for(i=0; i<sizeof(nullgen.sval); i++)
nullgen.sval[i] = 0;
nerrors = 0;
iostack = I;
@ -448,13 +442,6 @@ cinit(void)
s->type = itab[i].type;
s->value = itab[i].value;
}
pathname = allocn(pathname, 0, 100);
if(getwd(pathname, 99) == 0) {
pathname = allocn(pathname, 100, 900);
if(getwd(pathname, 999) == 0)
strcpy(pathname, "/???");
}
}
void
@ -466,7 +453,7 @@ syminit(Sym *s)
}
int
isreg(Gen *g)
isreg(Addr *g)
{
USED(g);
@ -476,81 +463,7 @@ isreg(Gen *g)
void
cclean(void)
{
outcode(AEND, Always, &nullgen, NREG, &nullgen);
Bflush(&obuf);
}
void
zname(char *n, int t, int s)
{
BPUTC(&obuf, ANAME);
BPUTC(&obuf, t); /* type */
BPUTC(&obuf, s); /* sym */
while(*n) {
BPUTC(&obuf, *n);
n++;
}
BPUTC(&obuf, 0);
}
void
zaddr(Gen *a, int s)
{
int32 l;
int i;
char *n;
Ieee e;
BPUTC(&obuf, a->type);
BPUTC(&obuf, a->reg);
BPUTC(&obuf, s);
BPUTC(&obuf, a->name);
BPUTC(&obuf, 0);
switch(a->type) {
default:
print("unknown type %d\n", a->type);
exits("arg");
case D_NONE:
case D_REG:
case D_FREG:
case D_PSR:
case D_FPCR:
break;
case D_REGREG:
case D_REGREG2:
BPUTC(&obuf, a->offset);
break;
case D_CONST2:
l = a->offset2;
BPUTLE4(&obuf, l);
// fall through
case D_OREG:
case D_CONST:
case D_BRANCH:
case D_SHIFT:
l = a->offset;
BPUTLE4(&obuf, l);
break;
case D_SCONST:
n = a->sval;
for(i=0; i<NSNAME; i++) {
BPUTC(&obuf, *n);
n++;
}
break;
case D_FCONST:
ieeedtod(&e, a->dval);
BPUTLE4(&obuf, e.l);
BPUTLE4(&obuf, e.h);
break;
}
}
static int bcode[] =
@ -573,11 +486,13 @@ static int bcode[] =
ANOP,
};
static Prog *lastpc;
void
outcode(int a, int scond, Gen *g1, int reg, Gen *g2)
outcode(int a, int scond, Addr *g1, int reg, Addr *g2)
{
int sf, st, t;
Sym *s;
Prog *p;
Plist *pl;
/* hack to make B.NE etc. work: turn it into the corresponding conditional */
if(a == AB){
@ -587,154 +502,27 @@ outcode(int a, int scond, Gen *g1, int reg, Gen *g2)
if(pass == 1)
goto out;
jackpot:
sf = 0;
s = g1->sym;
while(s != S) {
sf = s->sym;
if(sf < 0 || sf >= NSYM)
sf = 0;
t = g1->name;
if(h[sf].type == t)
if(h[sf].sym == s)
break;
zname(s->name, t, sym);
s->sym = sym;
h[sym].sym = s;
h[sym].type = t;
sf = sym;
sym++;
if(sym >= NSYM)
sym = 1;
break;
}
st = 0;
s = g2->sym;
while(s != S) {
st = s->sym;
if(st < 0 || st >= NSYM)
st = 0;
t = g2->name;
if(h[st].type == t)
if(h[st].sym == s)
break;
zname(s->name, t, sym);
s->sym = sym;
h[sym].sym = s;
h[sym].type = t;
st = sym;
sym++;
if(sym >= NSYM)
sym = 1;
if(st == sf)
goto jackpot;
break;
}
BPUTC(&obuf, a);
BPUTC(&obuf, scond);
BPUTC(&obuf, reg);
BPUTLE4(&obuf, stmtline);
zaddr(g1, sf);
zaddr(g2, st);
p = malloc(sizeof *p);
memset(p, 0, sizeof *p);
p->as = a;
p->lineno = stmtline;
p->scond = scond;
p->from = *g1;
p->reg = reg;
p->to = *g2;
if(lastpc == nil) {
pl = linknewplist(ctxt);
pl->firstpc = p;
} else
lastpc->link = p;
lastpc = p;
out:
if(a != AGLOBL && a != ADATA)
pc++;
}
void
outhist(void)
{
Gen g;
Hist *h;
char *p, *q, *op, c;
int n;
char *tofree;
static int first = 1;
static char *goroot, *goroot_final;
if(first) {
// Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL.
first = 0;
goroot = getenv("GOROOT");
goroot_final = getenv("GOROOT_FINAL");
if(goroot == nil)
goroot = "";
if(goroot_final == nil)
goroot_final = goroot;
if(strcmp(goroot, goroot_final) == 0) {
goroot = nil;
goroot_final = nil;
}
}
tofree = nil;
g = nullgen;
c = '/';
for(h = hist; h != H; h = h->link) {
p = h->name;
if(p != nil && goroot != nil) {
n = strlen(goroot);
if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') {
tofree = smprint("%s%s", goroot_final, p+n);
p = tofree;
}
}
op = 0;
if(systemtype(Windows) && p && p[1] == ':'){
c = p[2];
} else if(p && p[0] != c && h->offset == 0 && pathname){
if(systemtype(Windows) && pathname[1] == ':') {
op = p;
p = pathname;
c = p[2];
} else if(pathname[0] == c){
op = p;
p = pathname;
}
}
while(p) {
q = strchr(p, c);
if(q) {
n = q-p;
if(n == 0){
n = 1; /* leading "/" */
*p = '/'; /* don't emit "\" on windows */
}
q++;
} else {
n = strlen(p);
q = 0;
}
if(n) {
BPUTC(&obuf, ANAME);
BPUTC(&obuf, D_FILE); /* type */
BPUTC(&obuf, 1); /* sym */
BPUTC(&obuf, '<');
Bwrite(&obuf, p, n);
BPUTC(&obuf, 0);
}
p = q;
if(p == 0 && op) {
p = op;
op = 0;
}
}
g.offset = h->offset;
BPUTC(&obuf, AHISTORY);
BPUTC(&obuf, Always);
BPUTC(&obuf, 0);
BPUTLE4(&obuf, h->line);
zaddr(&nullgen, 0);
zaddr(&g, 0);
if(tofree) {
free(tofree);
tofree = nil;
}
}
}
#include "../cc/lexbody"
#include "../cc/macbody"

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,24 @@
/* A Bison parser, made by GNU Bison 2.5. */
/* A Bison parser, made by GNU Bison 2.3. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@ -26,11 +29,10 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@ -142,27 +144,21 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
/* Line 2068 of yacc.c */
#line 39 "a.y"
{
Sym *sym;
int32 lval;
double dval;
char sval[8];
Gen gen;
/* Line 2068 of yacc.c */
#line 160 "y.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
Addr addr;
}
/* Line 1529 of yacc.c. */
#line 157 "y.tab.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE yylval;

View File

@ -29,9 +29,9 @@
// THE SOFTWARE.
#include <bio.h>
#include <link.h>
#include "../6l/6.out.h"
#ifndef EXTERN
#define EXTERN extern
#endif
@ -45,10 +45,8 @@
typedef struct Sym Sym;
typedef struct Ref Ref;
typedef struct Gen Gen;
typedef struct Io Io;
typedef struct Hist Hist;
typedef struct Gen2 Gen2;
typedef struct Addr2 Addr2;
#define MAXALIGN 7
#define FPCHIP 1
@ -97,36 +95,11 @@ struct Io
};
#define I ((Io*)0)
EXTERN struct
struct Addr2
{
Sym* sym;
short type;
} h[NSYM];
struct Gen
{
double dval;
char sval[8];
vlong offset;
Sym* sym;
short type;
short index;
short scale;
Addr from;
Addr to;
};
struct Gen2
{
Gen from;
Gen to;
};
struct Hist
{
Hist* link;
char* name;
int32 line;
vlong offset;
};
#define H ((Hist*)0)
enum
{
@ -136,14 +109,11 @@ enum
CPREPROC,
};
EXTERN char debug[256];
EXTERN Sym* hash[NHASH];
EXTERN char** Dlist;
EXTERN int nDlist;
EXTERN Hist* ehist;
EXTERN int newflag;
EXTERN Hist* hist;
EXTERN char* hunk;
EXTERN char** include;
EXTERN Io* iofree;
@ -154,10 +124,9 @@ EXTERN int nerrors;
EXTERN int32 nhunk;
EXTERN int ninclude;
EXTERN int32 nsymb;
EXTERN Gen nullgen;
EXTERN Addr nullgen;
EXTERN char* outfile;
EXTERN int pass;
EXTERN char* pathname;
EXTERN int32 pc;
EXTERN int peekc;
EXTERN int32 stmtline;
@ -167,6 +136,7 @@ EXTERN int thechar;
EXTERN char* thestring;
EXTERN int32 thunk;
EXTERN Biobuf obuf;
EXTERN Link* ctxt;
void* alloc(int32);
void* allocn(void*, int32, int32);
@ -187,12 +157,11 @@ void cinit(void);
void checkscale(int);
void pinit(char*);
void cclean(void);
int isreg(Gen*);
void outcode(int, Gen2*);
int isreg(Addr*);
void outcode(int, Addr2*);
void outhist(void);
void zaddr(Gen*, int);
void zaddr(Addr*, int);
void zname(char*, int, int);
void ieeedtod(Ieee*, double);
int filbuf(void);
Sym* getsym(void);
void domacro(void);

View File

@ -40,8 +40,8 @@
vlong lval;
double dval;
char sval[8];
Gen gen;
Gen2 gen2;
LAddr addr;
Addr2 addr2;
}
%left '|'
%left '^'
@ -58,10 +58,10 @@
%token <sval> LSCONST LSP
%token <sym> LNAME LLAB LVAR
%type <lval> con con2 expr pointer offset
%type <gen> mem imm imm2 reg nam rel rem rim rom omem nmem
%type <gen2> nonnon nonrel nonrem rimnon rimrem remrim
%type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9
%type <gen2> spec10 spec11 spec12 spec13
%type <addr> mem imm imm2 reg nam rel rem rim rom omem nmem
%type <addr2> nonnon nonrel nonrem rimnon rimrem remrim
%type <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9
%type <addr2> spec10 spec11 spec12 spec13
%%
prog:
| prog
@ -367,14 +367,12 @@ rel:
if(pass == 2)
yyerror("undefined label: %s", $1->name);
$$.type = D_BRANCH;
$$.sym = $1;
$$.offset = $2;
}
| LLAB offset
{
$$ = nullgen;
$$.type = D_BRANCH;
$$.sym = $1;
$$.offset = $1->value + $2;
}
@ -444,31 +442,31 @@ imm:
{
$$ = nullgen;
$$.type = D_SCONST;
memcpy($$.sval, $2, sizeof($$.sval));
memcpy($$.u.sval, $2, sizeof($$.u.sval));
}
| '$' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
$$.dval = $2;
$$.u.dval = $2;
}
| '$' '(' LFCONST ')'
{
$$ = nullgen;
$$.type = D_FCONST;
$$.dval = $3;
$$.u.dval = $3;
}
| '$' '(' '-' LFCONST ')'
{
$$ = nullgen;
$$.type = D_FCONST;
$$.dval = -$4;
$$.u.dval = -$4;
}
| '$' '-' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
$$.dval = -$3;
$$.u.dval = -$3;
}
mem:
@ -572,14 +570,14 @@ nam:
{
$$ = nullgen;
$$.type = $4;
$$.sym = $1;
$$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2;
}
| LNAME '<' '>' offset '(' LSB ')'
{
$$ = nullgen;
$$.type = D_STATIC;
$$.sym = $1;
$$.sym = linklookup(ctxt, $1->name, 1);
$$.offset = $4;
}

View File

@ -65,6 +65,8 @@ main(int argc, char *argv[])
thechar = '6';
thestring = "amd64";
ctxt = linknew(&linkamd64);
ctxt->diag = yyerror;
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
@ -96,6 +98,10 @@ main(int argc, char *argv[])
p = ARGF();
setinclude(p);
break;
case 'S':
ctxt->debugasm++;
break;
} ARGEND
if(*argv == 0) {
print("usage: %ca [-options] file.s\n", thechar);
@ -145,30 +151,23 @@ assemble(char *file)
errorexit();
}
Binit(&obuf, of, OWRITE);
pass = 1;
pinit(file);
Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion());
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
if(nerrors) {
cclean();
return nerrors;
}
Bprint(&obuf, "\n!\n");
pass = 2;
outhist();
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
return nerrors;
for(pass = 1; pass <= 2; pass++) {
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
if(nerrors)
return nerrors;
}
linkouthist(ctxt, &obuf);
linkwritefuncs(ctxt, &obuf);
Bflush(&obuf);
return 0;
}
struct
@ -1031,15 +1030,8 @@ cinit(void)
Sym *s;
int i;
nullgen.sym = S;
nullgen.offset = 0;
if(FPCHIP)
nullgen.dval = 0;
for(i=0; i<sizeof(nullgen.sval); i++)
nullgen.sval[i] = 0;
nullgen.type = D_NONE;
nullgen.index = D_NONE;
nullgen.scale = 0;
nerrors = 0;
iostack = I;
@ -1055,13 +1047,6 @@ cinit(void)
s->type = itab[i].type;
s->value = itab[i].value;
}
pathname = allocn(pathname, 0, 100);
if(getwd(pathname, 99) == 0) {
pathname = allocn(pathname, 100, 900);
if(getwd(pathname, 999) == 0)
strcpy(pathname, "/???");
}
}
void
@ -1089,255 +1074,42 @@ syminit(Sym *s)
void
cclean(void)
{
Gen2 g2;
Addr2 g2;
g2.from = nullgen;
g2.to = nullgen;
outcode(AEND, &g2);
Bflush(&obuf);
}
void
zname(char *n, int t, int s)
{
BPUTLE2(&obuf, ANAME); /* as(2) */
BPUTC(&obuf, t); /* type */
BPUTC(&obuf, s); /* sym */
while(*n) {
BPUTC(&obuf, *n);
n++;
}
BPUTC(&obuf, 0);
}
static Prog *lastpc;
void
zaddr(Gen *a, int s)
outcode(int a, Addr2 *g2)
{
int32 l;
int i, t;
char *n;
Ieee e;
t = 0;
if(a->index != D_NONE || a->scale != 0)
t |= T_INDEX;
if(a->offset != 0) {
t |= T_OFFSET;
l = a->offset;
if((vlong)l != a->offset)
t |= T_64;
}
if(s != 0)
t |= T_SYM;
switch(a->type) {
default:
t |= T_TYPE;
break;
case D_FCONST:
t |= T_FCONST;
break;
case D_SCONST:
t |= T_SCONST;
break;
case D_NONE:
break;
}
BPUTC(&obuf, t);
if(t & T_INDEX) { /* implies index, scale */
BPUTC(&obuf, a->index);
BPUTC(&obuf, a->scale);
}
if(t & T_OFFSET) { /* implies offset */
l = a->offset;
BPUTLE4(&obuf, l);
if(t & T_64) {
l = a->offset>>32;
BPUTLE4(&obuf, l);
}
}
if(t & T_SYM) /* implies sym */
BPUTC(&obuf, s);
if(t & T_FCONST) {
ieeedtod(&e, a->dval);
l = e.l;
BPUTLE4(&obuf, l);
l = e.h;
BPUTLE4(&obuf, l);
return;
}
if(t & T_SCONST) {
n = a->sval;
for(i=0; i<NSNAME; i++) {
BPUTC(&obuf, *n);
n++;
}
return;
}
if(t & T_TYPE)
BPUTC(&obuf, a->type);
}
void
outcode(int a, Gen2 *g2)
{
int sf, st, t;
Sym *s;
Prog *p;
Plist *pl;
if(pass == 1)
goto out;
jackpot:
sf = 0;
s = g2->from.sym;
while(s != S) {
sf = s->sym;
if(sf < 0 || sf >= NSYM)
sf = 0;
t = g2->from.type;
if(t == D_ADDR)
t = g2->from.index;
if(h[sf].type == t)
if(h[sf].sym == s)
break;
zname(s->name, t, sym);
s->sym = sym;
h[sym].sym = s;
h[sym].type = t;
sf = sym;
sym++;
if(sym >= NSYM)
sym = 1;
break;
}
st = 0;
s = g2->to.sym;
while(s != S) {
st = s->sym;
if(st < 0 || st >= NSYM)
st = 0;
t = g2->to.type;
if(t == D_ADDR)
t = g2->to.index;
if(h[st].type == t)
if(h[st].sym == s)
break;
zname(s->name, t, sym);
s->sym = sym;
h[sym].sym = s;
h[sym].type = t;
st = sym;
sym++;
if(sym >= NSYM)
sym = 1;
if(st == sf)
goto jackpot;
break;
}
BPUTLE2(&obuf, a);
BPUTLE4(&obuf, stmtline);
zaddr(&g2->from, sf);
zaddr(&g2->to, st);
p = malloc(sizeof *p);
memset(p, 0, sizeof *p);
p->as = a;
p->lineno = stmtline;
p->from = g2->from;
p->to = g2->to;
if(lastpc == nil) {
pl = linknewplist(ctxt);
pl->firstpc = p;
} else
lastpc->link = p;
lastpc = p;
out:
if(a != AGLOBL && a != ADATA)
pc++;
}
void
outhist(void)
{
Gen g;
Hist *h;
char *p, *q, *op, c;
int n;
char *tofree;
static int first = 1;
static char *goroot, *goroot_final;
if(first) {
// Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL.
first = 0;
goroot = getenv("GOROOT");
goroot_final = getenv("GOROOT_FINAL");
if(goroot == nil)
goroot = "";
if(goroot_final == nil)
goroot_final = goroot;
if(strcmp(goroot, goroot_final) == 0) {
goroot = nil;
goroot_final = nil;
}
}
tofree = nil;
g = nullgen;
c = pathchar();
for(h = hist; h != H; h = h->link) {
p = h->name;
if(p != nil && goroot != nil) {
n = strlen(goroot);
if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') {
tofree = smprint("%s%s", goroot_final, p+n);
p = tofree;
}
}
op = 0;
if(systemtype(Windows) && p && p[1] == ':'){
c = p[2];
} else if(p && p[0] != c && h->offset == 0 && pathname){
if(systemtype(Windows) && pathname[1] == ':') {
op = p;
p = pathname;
c = p[2];
} else if(pathname[0] == c){
op = p;
p = pathname;
}
}
while(p) {
q = strchr(p, c);
if(q) {
n = q-p;
if(n == 0){
n = 1; /* leading "/" */
*p = '/'; /* don't emit "\" on windows */
}
q++;
} else {
n = strlen(p);
q = 0;
}
if(n) {
BPUTLE2(&obuf, ANAME);
BPUTC(&obuf, D_FILE); /* type */
BPUTC(&obuf, 1); /* sym */
BPUTC(&obuf, '<');
Bwrite(&obuf, p, n);
BPUTC(&obuf, 0);
}
p = q;
if(p == 0 && op) {
p = op;
op = 0;
}
}
g.offset = h->offset;
BPUTLE2(&obuf, AHISTORY);
BPUTLE4(&obuf, h->line);
zaddr(&nullgen, 0);
zaddr(&g, 0);
if(tofree) {
free(tofree);
tofree = nil;
}
}
}
#include "../cc/lexbody"
#include "../cc/macbody"

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,24 @@
/* A Bison parser, made by GNU Bison 2.5. */
/* A Bison parser, made by GNU Bison 2.3. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@ -26,11 +29,10 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@ -116,28 +118,22 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
/* Line 2068 of yacc.c */
#line 38 "a.y"
{
Sym *sym;
vlong lval;
double dval;
char sval[8];
Gen gen;
Gen2 gen2;
/* Line 2068 of yacc.c */
#line 135 "y.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
Addr addr;
Addr2 addr2;
}
/* Line 1529 of yacc.c. */
#line 132 "y.tab.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE yylval;

View File

@ -29,9 +29,9 @@
// THE SOFTWARE.
#include <bio.h>
#include <link.h>
#include "../8l/8.out.h"
#ifndef EXTERN
#define EXTERN extern
#endif
@ -45,10 +45,8 @@
typedef struct Sym Sym;
typedef struct Ref Ref;
typedef struct Gen Gen;
typedef struct Io Io;
typedef struct Hist Hist;
typedef struct Gen2 Gen2;
typedef struct Addr2 Addr2;
#define MAXALIGN 7
#define FPCHIP 1
@ -97,37 +95,11 @@ struct Io
};
#define I ((Io*)0)
EXTERN struct
struct Addr2
{
Sym* sym;
short type;
} h[NSYM];
struct Gen
{
double dval;
char sval[8];
int32 offset;
int32 offset2;
Sym* sym;
short type;
short index;
short scale;
Addr from;
Addr to;
};
struct Gen2
{
Gen from;
Gen to;
};
struct Hist
{
Hist* link;
char* name;
int32 line;
int32 offset;
};
#define H ((Hist*)0)
enum
{
@ -137,14 +109,11 @@ enum
CPREPROC,
};
EXTERN char debug[256];
EXTERN Sym* hash[NHASH];
EXTERN char** Dlist;
EXTERN int nDlist;
EXTERN Hist* ehist;
EXTERN int newflag;
EXTERN Hist* hist;
EXTERN char* hunk;
EXTERN char** include;
EXTERN Io* iofree;
@ -155,10 +124,9 @@ EXTERN int nerrors;
EXTERN int32 nhunk;
EXTERN int ninclude;
EXTERN int32 nsymb;
EXTERN Gen nullgen;
EXTERN Addr nullgen;
EXTERN char* outfile;
EXTERN int pass;
EXTERN char* pathname;
EXTERN int32 pc;
EXTERN int peekc;
EXTERN int32 stmtline;
@ -168,6 +136,7 @@ EXTERN int thechar;
EXTERN char* thestring;
EXTERN int32 thunk;
EXTERN Biobuf obuf;
EXTERN Link* ctxt;
void* alloc(int32);
void* allocn(void*, int32, int32);
@ -188,12 +157,9 @@ void cinit(void);
void checkscale(int);
void pinit(char*);
void cclean(void);
int isreg(Gen*);
void outcode(int, Gen2*);
int isreg(Addr*);
void outcode(int, Addr2*);
void outhist(void);
void zaddr(Gen*, int);
void zname(char*, int, int);
void ieeedtod(Ieee*, double);
int filbuf(void);
Sym* getsym(void);
void domacro(void);

View File

@ -44,8 +44,8 @@
} con2;
double dval;
char sval[8];
Gen gen;
Gen2 gen2;
LAddr addr;
Addr2 addr2;
}
%left '|'
%left '^'
@ -62,9 +62,9 @@
%token <sym> LNAME LLAB LVAR
%type <lval> con expr pointer offset
%type <con2> con2
%type <gen> mem imm imm2 reg nam rel rem rim rom omem nmem
%type <gen2> nonnon nonrel nonrem rimnon rimrem remrim
%type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12
%type <addr> mem imm imm2 reg nam rel rem rim rom omem nmem
%type <addr2> nonnon nonrel nonrem rimnon rimrem remrim
%type <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12
%%
prog:
| prog
@ -366,14 +366,12 @@ rel:
if(pass == 2)
yyerror("undefined label: %s", $1->name);
$$.type = D_BRANCH;
$$.sym = $1;
$$.offset = $2;
}
| LLAB offset
{
$$ = nullgen;
$$.type = D_BRANCH;
$$.sym = $1;
$$.offset = $1->value + $2;
}
@ -431,31 +429,31 @@ imm:
{
$$ = nullgen;
$$.type = D_SCONST;
memcpy($$.sval, $2, sizeof($$.sval));
memcpy($$.u.sval, $2, sizeof($$.u.sval));
}
| '$' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
$$.dval = $2;
$$.u.dval = $2;
}
| '$' '(' LFCONST ')'
{
$$ = nullgen;
$$.type = D_FCONST;
$$.dval = $3;
$$.u.dval = $3;
}
| '$' '(' '-' LFCONST ')'
{
$$ = nullgen;
$$.type = D_FCONST;
$$.dval = -$4;
$$.u.dval = -$4;
}
| '$' '-' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
$$.dval = -$3;
$$.u.dval = -$3;
}
imm2:
@ -590,14 +588,14 @@ nam:
{
$$ = nullgen;
$$.type = $4;
$$.sym = $1;
$$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2;
}
| LNAME '<' '>' offset '(' LSB ')'
{
$$ = nullgen;
$$.type = D_STATIC;
$$.sym = $1;
$$.sym = linklookup(ctxt, $1->name, 1);
$$.offset = $4;
}

View File

@ -65,6 +65,8 @@ main(int argc, char *argv[])
thechar = '8';
thestring = "386";
ctxt = linknew(&link386);
ctxt->diag = yyerror;
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
@ -96,6 +98,10 @@ main(int argc, char *argv[])
p = ARGF();
setinclude(p);
break;
case 'S':
ctxt->debugasm++;
break;
} ARGEND
if(*argv == 0) {
print("usage: %ca [-options] file.s\n", thechar);
@ -145,30 +151,23 @@ assemble(char *file)
errorexit();
}
Binit(&obuf, of, OWRITE);
pass = 1;
pinit(file);
Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion());
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
if(nerrors) {
cclean();
return nerrors;
}
Bprint(&obuf, "\n!\n");
pass = 2;
outhist();
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
return nerrors;
for(pass = 1; pass <= 2; pass++) {
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
if(nerrors)
return nerrors;
}
linkouthist(ctxt, &obuf);
linkwritefuncs(ctxt, &obuf);
Bflush(&obuf);
return 0;
}
struct
@ -810,15 +809,8 @@ cinit(void)
Sym *s;
int i;
nullgen.sym = S;
nullgen.offset = 0;
if(FPCHIP)
nullgen.dval = 0;
for(i=0; i<sizeof(nullgen.sval); i++)
nullgen.sval[i] = 0;
nullgen.type = D_NONE;
nullgen.index = D_NONE;
nullgen.scale = 0;
nerrors = 0;
iostack = I;
@ -834,13 +826,6 @@ cinit(void)
s->type = itab[i].type;
s->value = itab[i].value;
}
pathname = allocn(pathname, 0, 100);
if(getwd(pathname, 99) == 0) {
pathname = allocn(pathname, 100, 900);
if(getwd(pathname, 999) == 0)
strcpy(pathname, "/???");
}
}
void
@ -868,252 +853,42 @@ syminit(Sym *s)
void
cclean(void)
{
Gen2 g2;
Addr2 g2;
g2.from = nullgen;
g2.to = nullgen;
outcode(AEND, &g2);
Bflush(&obuf);
}
void
zname(char *n, int t, int s)
{
BPUTLE2(&obuf, ANAME); /* as(2) */
BPUTC(&obuf, t); /* type */
BPUTC(&obuf, s); /* sym */
while(*n) {
BPUTC(&obuf, *n);
n++;
}
BPUTC(&obuf, 0);
}
static Prog *lastpc;
void
zaddr(Gen *a, int s)
outcode(int a, Addr2 *g2)
{
int32 l;
int i, t;
char *n;
Ieee e;
t = 0;
if(a->index != D_NONE || a->scale != 0)
t |= T_INDEX;
if(a->offset != 0)
t |= T_OFFSET;
if(s != 0)
t |= T_SYM;
switch(a->type) {
default:
t |= T_TYPE;
break;
case D_FCONST:
t |= T_FCONST;
break;
case D_CONST2:
t |= T_OFFSET|T_OFFSET2;
break;
case D_SCONST:
t |= T_SCONST;
break;
case D_NONE:
break;
}
BPUTC(&obuf, t);
if(t & T_INDEX) { /* implies index, scale */
BPUTC(&obuf, a->index);
BPUTC(&obuf, a->scale);
}
if(t & T_OFFSET) { /* implies offset */
l = a->offset;
BPUTLE4(&obuf, l);
}
if(t & T_OFFSET2) {
l = a->offset2;
BPUTLE4(&obuf, l);
}
if(t & T_SYM) /* implies sym */
BPUTC(&obuf, s);
if(t & T_FCONST) {
ieeedtod(&e, a->dval);
BPUTLE4(&obuf, e.l);
BPUTLE4(&obuf, e.h);
return;
}
if(t & T_SCONST) {
n = a->sval;
for(i=0; i<NSNAME; i++) {
BPUTC(&obuf, *n);
n++;
}
return;
}
if(t & T_TYPE)
BPUTC(&obuf, a->type);
}
void
outcode(int a, Gen2 *g2)
{
int sf, st, t;
Sym *s;
Prog *p;
Plist *pl;
if(pass == 1)
goto out;
jackpot:
sf = 0;
s = g2->from.sym;
while(s != S) {
sf = s->sym;
if(sf < 0 || sf >= NSYM)
sf = 0;
t = g2->from.type;
if(t == D_ADDR)
t = g2->from.index;
if(h[sf].type == t)
if(h[sf].sym == s)
break;
zname(s->name, t, sym);
s->sym = sym;
h[sym].sym = s;
h[sym].type = t;
sf = sym;
sym++;
if(sym >= NSYM)
sym = 1;
break;
}
st = 0;
s = g2->to.sym;
while(s != S) {
st = s->sym;
if(st < 0 || st >= NSYM)
st = 0;
t = g2->to.type;
if(t == D_ADDR)
t = g2->to.index;
if(h[st].type == t)
if(h[st].sym == s)
break;
zname(s->name, t, sym);
s->sym = sym;
h[sym].sym = s;
h[sym].type = t;
st = sym;
sym++;
if(sym >= NSYM)
sym = 1;
if(st == sf)
goto jackpot;
break;
}
BPUTLE2(&obuf, a);
BPUTLE4(&obuf, stmtline);
zaddr(&g2->from, sf);
zaddr(&g2->to, st);
p = malloc(sizeof *p);
memset(p, 0, sizeof *p);
p->as = a;
p->lineno = stmtline;
p->from = g2->from;
p->to = g2->to;
if(lastpc == nil) {
pl = linknewplist(ctxt);
pl->firstpc = p;
} else
lastpc->link = p;
lastpc = p;
out:
if(a != AGLOBL && a != ADATA)
pc++;
}
void
outhist(void)
{
Gen g;
Hist *h;
char *p, *q, *op, c;
int n;
char *tofree;
static int first = 1;
static char *goroot, *goroot_final;
if(first) {
// Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL.
first = 0;
goroot = getenv("GOROOT");
goroot_final = getenv("GOROOT_FINAL");
if(goroot == nil)
goroot = "";
if(goroot_final == nil)
goroot_final = goroot;
if(strcmp(goroot, goroot_final) == 0) {
goroot = nil;
goroot_final = nil;
}
}
tofree = nil;
g = nullgen;
c = pathchar();
for(h = hist; h != H; h = h->link) {
p = h->name;
if(p != nil && goroot != nil) {
n = strlen(goroot);
if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') {
tofree = smprint("%s%s", goroot_final, p+n);
p = tofree;
}
}
op = 0;
if(systemtype(Windows) && p && p[1] == ':'){
c = p[2];
} else if(p && p[0] != c && h->offset == 0 && pathname){
if(systemtype(Windows) && pathname[1] == ':') {
op = p;
p = pathname;
c = p[2];
} else if(pathname[0] == c){
op = p;
p = pathname;
}
}
while(p) {
q = strchr(p, c);
if(q) {
n = q-p;
if(n == 0){
n = 1; /* leading "/" */
*p = '/'; /* don't emit "\" on windows */
}
q++;
} else {
n = strlen(p);
q = 0;
}
if(n) {
BPUTLE2(&obuf, ANAME);
BPUTC(&obuf, D_FILE); /* type */
BPUTC(&obuf, 1); /* sym */
BPUTC(&obuf, '<');
Bwrite(&obuf, p, n);
BPUTC(&obuf, 0);
}
p = q;
if(p == 0 && op) {
p = op;
op = 0;
}
}
g.offset = h->offset;
BPUTLE2(&obuf, AHISTORY);
BPUTLE4(&obuf, h->line);
zaddr(&nullgen, 0);
zaddr(&g, 0);
if(tofree) {
free(tofree);
tofree = nil;
}
}
}
#include "../cc/lexbody"
#include "../cc/macbody"

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,24 @@
/* A Bison parser, made by GNU Bison 2.5. */
/* A Bison parser, made by GNU Bison 2.3. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@ -26,11 +29,10 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@ -112,11 +114,8 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
/* Line 2068 of yacc.c */
#line 38 "a.y"
{
Sym *sym;
int32 lval;
struct {
@ -125,19 +124,16 @@ typedef union YYSTYPE
} con2;
double dval;
char sval[8];
Gen gen;
Gen2 gen2;
/* Line 2068 of yacc.c */
#line 135 "y.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
Addr addr;
Addr2 addr2;
}
/* Line 1529 of yacc.c. */
#line 132 "y.tab.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE yylval;

View File

@ -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);
}