Commit f7aaa553 authored by Russ Cox's avatar Russ Cox

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
parent 7d507dc6
......@@ -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);
......
......@@ -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;
}
......
......@@ -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());
Bprint(&obuf, "\n!\n");
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
if(nerrors) {
for(pass = 1; pass <= 2; pass++) {
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
return nerrors;
if(nerrors)
return nerrors;
}
Bprint(&obuf, "\n!\n");
pass = 2;
outhist();
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
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"
This diff is collapsed.
/* 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;
......@@ -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
{
Sym* sym;
short type;
} h[NSYM];
struct Gen
{
double dval;
char sval[8];
vlong offset;
Sym* sym;
short type;
short index;
short scale;
};
struct Gen2
{
Gen from;
Gen to;
};
struct Hist
struct Addr2
{
Hist* link;
char* name;
int32 line;
vlong offset;
Addr from;
Addr to;
};
#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);
......
......@@ -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;
}
......
......@@ -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());
Bprint(&obuf, "\n!\n");
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
if(nerrors) {
for(pass = 1; pass <= 2; pass++) {
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
return nerrors;
if(nerrors)
return nerrors;
}
Bprint(&obuf, "\n!\n");
pass = 2;
outhist();
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
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);
}
void
zaddr(Gen *a, int s)
{
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);
}
static Prog *lastpc;
void
outcode(int a, Gen2 *g2)
outcode(int a, Addr2 *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"
This diff is collapsed.
/* 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;
......@@ -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
{
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;
};
struct Gen2
{
Gen from;
Gen to;
};
struct Hist
struct Addr2
{
Hist* link;
char* name;
int32 line;
int32 offset;
Addr from;
Addr to;
};
#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);
......
......@@ -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;
}
......
......@@ -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());
Bprint(&obuf, "\n!\n");
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
if(nerrors) {
for(pass = 1; pass <= 2; pass++) {
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
return nerrors;
if(nerrors)
return nerrors;
}
Bprint(&obuf, "\n!\n");
pass = 2;
outhist();
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
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);
}
void
zaddr(Gen *a, int s)
{
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);
}
static Prog *lastpc;
void
outcode(int a, Gen2 *g2)
outcode(int a, Addr2 *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"
This diff is collapsed.
/* 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;
......@@ -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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment