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 @@ ...@@ -29,6 +29,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#include <bio.h> #include <bio.h>
#include <link.h>
#include "../5l/5.out.h" #include "../5l/5.out.h"
#ifndef EXTERN #ifndef EXTERN
...@@ -43,9 +44,7 @@ ...@@ -43,9 +44,7 @@
#define ungetc ccungetc #define ungetc ccungetc
typedef struct Sym Sym; typedef struct Sym Sym;
typedef struct Gen Gen;
typedef struct Io Io; typedef struct Io Io;
typedef struct Hist Hist;
#define MAXALIGN 7 #define MAXALIGN 7
#define FPCHIP 1 #define FPCHIP 1
...@@ -88,33 +87,6 @@ struct Io ...@@ -88,33 +87,6 @@ struct Io
}; };
#define I ((Io*)0) #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 enum
{ {
CLAST, CLAST,
...@@ -129,9 +101,7 @@ EXTERN char debug[256]; ...@@ -129,9 +101,7 @@ EXTERN char debug[256];
EXTERN Sym* hash[NHASH]; EXTERN Sym* hash[NHASH];
EXTERN char** Dlist; EXTERN char** Dlist;
EXTERN int nDlist; EXTERN int nDlist;
EXTERN Hist* ehist;
EXTERN int newflag; EXTERN int newflag;
EXTERN Hist* hist;
EXTERN char* hunk; EXTERN char* hunk;
EXTERN char** include; EXTERN char** include;
EXTERN Io* iofree; EXTERN Io* iofree;
...@@ -142,10 +112,9 @@ EXTERN int nerrors; ...@@ -142,10 +112,9 @@ EXTERN int nerrors;
EXTERN int32 nhunk; EXTERN int32 nhunk;
EXTERN int ninclude; EXTERN int ninclude;
EXTERN int32 nsymb; EXTERN int32 nsymb;
EXTERN Gen nullgen; EXTERN Addr nullgen;
EXTERN char* outfile; EXTERN char* outfile;
EXTERN int pass; EXTERN int pass;
EXTERN char* pathname;
EXTERN int32 pc; EXTERN int32 pc;
EXTERN int peekc; EXTERN int peekc;
EXTERN int32 stmtline; EXTERN int32 stmtline;
...@@ -155,6 +124,7 @@ EXTERN int thechar; ...@@ -155,6 +124,7 @@ EXTERN int thechar;
EXTERN char* thestring; EXTERN char* thestring;
EXTERN int32 thunk; EXTERN int32 thunk;
EXTERN Biobuf obuf; EXTERN Biobuf obuf;
EXTERN Link* ctxt;
void* alloc(int32); void* alloc(int32);
void* allocn(void*, int32, int32); void* allocn(void*, int32, int32);
...@@ -174,11 +144,8 @@ int escchar(int); ...@@ -174,11 +144,8 @@ int escchar(int);
void cinit(void); void cinit(void);
void pinit(char*); void pinit(char*);
void cclean(void); void cclean(void);
int isreg(Gen*); int isreg(Addr*);
void outcode(int, int, Gen*, int, Gen*); void outcode(int, int, Addr*, int, Addr*);
void zname(char*, int, int);
void zaddr(Gen*, int);
void ieeedtod(Ieee*, double);
int filbuf(void); int filbuf(void);
Sym* getsym(void); Sym* getsym(void);
void domacro(void); void domacro(void);
...@@ -190,7 +157,6 @@ void maclin(void); ...@@ -190,7 +157,6 @@ void maclin(void);
void macprag(void); void macprag(void);
void macif(int); void macif(int);
void macend(void); void macend(void);
void outhist(void);
void dodefine(char*); void dodefine(char*);
void prfile(int32); void prfile(int32);
void linehist(char*, int); void linehist(char*, int);
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
int32 lval; int32 lval;
double dval; double dval;
char sval[8]; char sval[8];
Gen gen; LAddr addr;
} }
%left '|' %left '|'
%left '^' %left '^'
...@@ -62,8 +62,8 @@ ...@@ -62,8 +62,8 @@
%token <sym> LNAME LLAB LVAR %token <sym> LNAME LLAB LVAR
%type <lval> con expr oexpr pointer offset sreg spreg creg %type <lval> con expr oexpr pointer offset sreg spreg creg
%type <lval> rcon cond reglist %type <lval> rcon cond reglist
%type <gen> gen rel reg regreg freg shift fcon frcon %type <addr> gen rel reg regreg freg shift fcon frcon
%type <gen> imm ximm name oreg ireg nireg ioreg imsr %type <addr> imm ximm name oreg ireg nireg ioreg imsr
%% %%
prog: prog:
| prog | prog
...@@ -175,7 +175,7 @@ inst: ...@@ -175,7 +175,7 @@ inst:
*/ */
| LTYPE8 cond ioreg ',' '[' reglist ']' | LTYPE8 cond ioreg ',' '[' reglist ']'
{ {
Gen g; LAddr g;
g = nullgen; g = nullgen;
g.type = D_CONST; g.type = D_CONST;
...@@ -184,7 +184,7 @@ inst: ...@@ -184,7 +184,7 @@ inst:
} }
| LTYPE8 cond '[' reglist ']' ',' ioreg | LTYPE8 cond '[' reglist ']' ',' ioreg
{ {
Gen g; LAddr g;
g = nullgen; g = nullgen;
g.type = D_CONST; g.type = D_CONST;
...@@ -279,7 +279,7 @@ inst: ...@@ -279,7 +279,7 @@ inst:
*/ */
| LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr | LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
{ {
Gen g; LAddr g;
g = nullgen; g = nullgen;
g.type = D_CONST; g.type = D_CONST;
...@@ -377,14 +377,12 @@ rel: ...@@ -377,14 +377,12 @@ rel:
if(pass == 2) if(pass == 2)
yyerror("undefined label: %s", $1->name); yyerror("undefined label: %s", $1->name);
$$.type = D_BRANCH; $$.type = D_BRANCH;
$$.sym = $1;
$$.offset = $2; $$.offset = $2;
} }
| LLAB offset | LLAB offset
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_BRANCH; $$.type = D_BRANCH;
$$.sym = $1;
$$.offset = $1->value + $2; $$.offset = $1->value + $2;
} }
...@@ -408,7 +406,7 @@ ximm: '$' con ...@@ -408,7 +406,7 @@ ximm: '$' con
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_SCONST; $$.type = D_SCONST;
memcpy($$.sval, $2, sizeof($$.sval)); memcpy($$.u.sval, $2, sizeof($$.u.sval));
} }
| fcon | fcon
...@@ -417,13 +415,13 @@ fcon: ...@@ -417,13 +415,13 @@ fcon:
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FCONST; $$.type = D_FCONST;
$$.dval = $2; $$.u.dval = $2;
} }
| '$' '-' LFCONST | '$' '-' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FCONST; $$.type = D_FCONST;
$$.dval = -$3; $$.u.dval = -$3;
} }
reglist: reglist:
...@@ -635,7 +633,7 @@ name: ...@@ -635,7 +633,7 @@ name:
$$ = nullgen; $$ = nullgen;
$$.type = D_OREG; $$.type = D_OREG;
$$.name = $3; $$.name = $3;
$$.sym = S; $$.sym = nil;
$$.offset = $1; $$.offset = $1;
} }
| LNAME offset '(' pointer ')' | LNAME offset '(' pointer ')'
...@@ -643,7 +641,7 @@ name: ...@@ -643,7 +641,7 @@ name:
$$ = nullgen; $$ = nullgen;
$$.type = D_OREG; $$.type = D_OREG;
$$.name = $4; $$.name = $4;
$$.sym = $1; $$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2; $$.offset = $2;
} }
| LNAME '<' '>' offset '(' LSB ')' | LNAME '<' '>' offset '(' LSB ')'
...@@ -651,7 +649,7 @@ name: ...@@ -651,7 +649,7 @@ name:
$$ = nullgen; $$ = nullgen;
$$.type = D_OREG; $$.type = D_OREG;
$$.name = D_STATIC; $$.name = D_STATIC;
$$.sym = $1; $$.sym = linklookup(ctxt, $1->name, 1);
$$.offset = $4; $$.offset = $4;
} }
......
...@@ -59,6 +59,8 @@ main(int argc, char *argv[]) ...@@ -59,6 +59,8 @@ main(int argc, char *argv[])
thechar = '5'; thechar = '5';
thestring = "arm"; thestring = "arm";
ctxt = linknew(&linkarm);
ctxt->diag = yyerror;
ensuresymb(NSYMB); ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug)); memset(debug, 0, sizeof(debug));
...@@ -90,10 +92,15 @@ main(int argc, char *argv[]) ...@@ -90,10 +92,15 @@ main(int argc, char *argv[])
p = ARGF(); p = ARGF();
setinclude(p); setinclude(p);
break; break;
case 't': case 't':
thechar = 't'; thechar = 't';
thestring = "thumb"; thestring = "thumb";
break; break;
case 'S':
ctxt->debugasm++;
break;
} ARGEND } ARGEND
if(*argv == 0) { if(*argv == 0) {
print("usage: %ca [-options] file.s\n", thechar); print("usage: %ca [-options] file.s\n", thechar);
...@@ -143,30 +150,23 @@ assemble(char *file) ...@@ -143,30 +150,23 @@ assemble(char *file)
errorexit(); errorexit();
} }
Binit(&obuf, of, OWRITE); Binit(&obuf, of, OWRITE);
pass = 1;
pinit(file);
Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion());
Bprint(&obuf, "\n!\n");
for(i=0; i<nDlist; i++) for(pass = 1; pass <= 2; pass++) {
dodefine(Dlist[i]); pinit(file);
yyparse(); for(i=0; i<nDlist; i++)
if(nerrors) { dodefine(Dlist[i]);
yyparse();
cclean(); cclean();
return nerrors; if(nerrors)
return nerrors;
} }
Bprint(&obuf, "\n!\n"); linkouthist(ctxt, &obuf);
linkwritefuncs(ctxt, &obuf);
pass = 2; Bflush(&obuf);
outhist(); return 0;
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
return nerrors;
} }
struct struct
...@@ -426,15 +426,9 @@ cinit(void) ...@@ -426,15 +426,9 @@ cinit(void)
Sym *s; Sym *s;
int i; int i;
nullgen.sym = S;
nullgen.offset = 0;
nullgen.type = D_NONE; nullgen.type = D_NONE;
nullgen.name = D_NONE; nullgen.name = D_NONE;
nullgen.reg = NREG; nullgen.reg = NREG;
if(FPCHIP)
nullgen.dval = 0;
for(i=0; i<sizeof(nullgen.sval); i++)
nullgen.sval[i] = 0;
nerrors = 0; nerrors = 0;
iostack = I; iostack = I;
...@@ -448,13 +442,6 @@ cinit(void) ...@@ -448,13 +442,6 @@ cinit(void)
s->type = itab[i].type; s->type = itab[i].type;
s->value = itab[i].value; 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 void
...@@ -466,7 +453,7 @@ syminit(Sym *s) ...@@ -466,7 +453,7 @@ syminit(Sym *s)
} }
int int
isreg(Gen *g) isreg(Addr *g)
{ {
USED(g); USED(g);
...@@ -476,81 +463,7 @@ isreg(Gen *g) ...@@ -476,81 +463,7 @@ isreg(Gen *g)
void void
cclean(void) cclean(void)
{ {
outcode(AEND, Always, &nullgen, NREG, &nullgen); 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[] = static int bcode[] =
...@@ -573,11 +486,13 @@ static int bcode[] = ...@@ -573,11 +486,13 @@ static int bcode[] =
ANOP, ANOP,
}; };
static Prog *lastpc;
void 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; Prog *p;
Sym *s; Plist *pl;
/* hack to make B.NE etc. work: turn it into the corresponding conditional */ /* hack to make B.NE etc. work: turn it into the corresponding conditional */
if(a == AB){ if(a == AB){
...@@ -587,154 +502,27 @@ outcode(int a, int scond, Gen *g1, int reg, Gen *g2) ...@@ -587,154 +502,27 @@ outcode(int a, int scond, Gen *g1, int reg, Gen *g2)
if(pass == 1) if(pass == 1)
goto out; goto out;
jackpot:
sf = 0; p = malloc(sizeof *p);
s = g1->sym; memset(p, 0, sizeof *p);
while(s != S) { p->as = a;
sf = s->sym; p->lineno = stmtline;
if(sf < 0 || sf >= NSYM) p->scond = scond;
sf = 0; p->from = *g1;
t = g1->name; p->reg = reg;
if(h[sf].type == t) p->to = *g2;
if(h[sf].sym == s)
break; if(lastpc == nil) {
zname(s->name, t, sym); pl = linknewplist(ctxt);
s->sym = sym; pl->firstpc = p;
h[sym].sym = s; } else
h[sym].type = t; lastpc->link = p;
sf = sym; lastpc = p;
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);
out: out:
if(a != AGLOBL && a != ADATA) if(a != AGLOBL && a != ADATA)
pc++; 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/lexbody"
#include "../cc/macbody" #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 /* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. 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
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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation; either version 2, or (at your option)
(at your option) any later version. any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License 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 /* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work part or all of the Bison parser skeleton and distribute that work
...@@ -26,11 +29,10 @@ ...@@ -26,11 +29,10 @@
special exception, which will cause the skeleton and the resulting special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public Bison output files to be licensed under the GNU General Public
License without this special exception. License without this special exception.
This special exception was added by the Free Software Foundation in This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */ version 2.2 of Bison. */
/* Tokens. */ /* Tokens. */
#ifndef YYTOKENTYPE #ifndef YYTOKENTYPE
# define YYTOKENTYPE # define YYTOKENTYPE
...@@ -142,27 +144,21 @@ ...@@ -142,27 +144,21 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE typedef union YYSTYPE
{
/* Line 2068 of yacc.c */
#line 39 "a.y" #line 39 "a.y"
{
Sym *sym; Sym *sym;
int32 lval; int32 lval;
double dval; double dval;
char sval[8]; char sval[8];
Gen gen; Addr addr;
}
/* Line 1529 of yacc.c. */
#line 157 "y.tab.h"
/* Line 2068 of yacc.c */ YYSTYPE;
#line 160 "y.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif #endif
extern YYSTYPE yylval; extern YYSTYPE yylval;
...@@ -29,9 +29,9 @@ ...@@ -29,9 +29,9 @@
// THE SOFTWARE. // THE SOFTWARE.
#include <bio.h> #include <bio.h>
#include <link.h>
#include "../6l/6.out.h" #include "../6l/6.out.h"
#ifndef EXTERN #ifndef EXTERN
#define EXTERN extern #define EXTERN extern
#endif #endif
...@@ -45,10 +45,8 @@ ...@@ -45,10 +45,8 @@
typedef struct Sym Sym; typedef struct Sym Sym;
typedef struct Ref Ref; typedef struct Ref Ref;
typedef struct Gen Gen;
typedef struct Io Io; typedef struct Io Io;
typedef struct Hist Hist; typedef struct Addr2 Addr2;
typedef struct Gen2 Gen2;
#define MAXALIGN 7 #define MAXALIGN 7
#define FPCHIP 1 #define FPCHIP 1
...@@ -97,36 +95,11 @@ struct Io ...@@ -97,36 +95,11 @@ struct Io
}; };
#define I ((Io*)0) #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;
};
struct Gen2
{
Gen from;
Gen to;
};
struct Hist
{ {
Hist* link; Addr from;
char* name; Addr to;
int32 line;
vlong offset;
}; };
#define H ((Hist*)0)
enum enum
{ {
...@@ -136,14 +109,11 @@ enum ...@@ -136,14 +109,11 @@ enum
CPREPROC, CPREPROC,
}; };
EXTERN char debug[256]; EXTERN char debug[256];
EXTERN Sym* hash[NHASH]; EXTERN Sym* hash[NHASH];
EXTERN char** Dlist; EXTERN char** Dlist;
EXTERN int nDlist; EXTERN int nDlist;
EXTERN Hist* ehist;
EXTERN int newflag; EXTERN int newflag;
EXTERN Hist* hist;
EXTERN char* hunk; EXTERN char* hunk;
EXTERN char** include; EXTERN char** include;
EXTERN Io* iofree; EXTERN Io* iofree;
...@@ -154,10 +124,9 @@ EXTERN int nerrors; ...@@ -154,10 +124,9 @@ EXTERN int nerrors;
EXTERN int32 nhunk; EXTERN int32 nhunk;
EXTERN int ninclude; EXTERN int ninclude;
EXTERN int32 nsymb; EXTERN int32 nsymb;
EXTERN Gen nullgen; EXTERN Addr nullgen;
EXTERN char* outfile; EXTERN char* outfile;
EXTERN int pass; EXTERN int pass;
EXTERN char* pathname;
EXTERN int32 pc; EXTERN int32 pc;
EXTERN int peekc; EXTERN int peekc;
EXTERN int32 stmtline; EXTERN int32 stmtline;
...@@ -167,6 +136,7 @@ EXTERN int thechar; ...@@ -167,6 +136,7 @@ EXTERN int thechar;
EXTERN char* thestring; EXTERN char* thestring;
EXTERN int32 thunk; EXTERN int32 thunk;
EXTERN Biobuf obuf; EXTERN Biobuf obuf;
EXTERN Link* ctxt;
void* alloc(int32); void* alloc(int32);
void* allocn(void*, int32, int32); void* allocn(void*, int32, int32);
...@@ -187,12 +157,11 @@ void cinit(void); ...@@ -187,12 +157,11 @@ void cinit(void);
void checkscale(int); void checkscale(int);
void pinit(char*); void pinit(char*);
void cclean(void); void cclean(void);
int isreg(Gen*); int isreg(Addr*);
void outcode(int, Gen2*); void outcode(int, Addr2*);
void outhist(void); void outhist(void);
void zaddr(Gen*, int); void zaddr(Addr*, int);
void zname(char*, int, int); void zname(char*, int, int);
void ieeedtod(Ieee*, double);
int filbuf(void); int filbuf(void);
Sym* getsym(void); Sym* getsym(void);
void domacro(void); void domacro(void);
......
...@@ -40,8 +40,8 @@ ...@@ -40,8 +40,8 @@
vlong lval; vlong lval;
double dval; double dval;
char sval[8]; char sval[8];
Gen gen; LAddr addr;
Gen2 gen2; Addr2 addr2;
} }
%left '|' %left '|'
%left '^' %left '^'
...@@ -58,10 +58,10 @@ ...@@ -58,10 +58,10 @@
%token <sval> LSCONST LSP %token <sval> LSCONST LSP
%token <sym> LNAME LLAB LVAR %token <sym> LNAME LLAB LVAR
%type <lval> con con2 expr pointer offset %type <lval> con con2 expr pointer offset
%type <gen> mem imm imm2 reg nam rel rem rim rom omem nmem %type <addr> mem imm imm2 reg nam rel rem rim rom omem nmem
%type <gen2> nonnon nonrel nonrem rimnon rimrem remrim %type <addr2> nonnon nonrel nonrem rimnon rimrem remrim
%type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 %type <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9
%type <gen2> spec10 spec11 spec12 spec13 %type <addr2> spec10 spec11 spec12 spec13
%% %%
prog: prog:
| prog | prog
...@@ -367,14 +367,12 @@ rel: ...@@ -367,14 +367,12 @@ rel:
if(pass == 2) if(pass == 2)
yyerror("undefined label: %s", $1->name); yyerror("undefined label: %s", $1->name);
$$.type = D_BRANCH; $$.type = D_BRANCH;
$$.sym = $1;
$$.offset = $2; $$.offset = $2;
} }
| LLAB offset | LLAB offset
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_BRANCH; $$.type = D_BRANCH;
$$.sym = $1;
$$.offset = $1->value + $2; $$.offset = $1->value + $2;
} }
...@@ -444,31 +442,31 @@ imm: ...@@ -444,31 +442,31 @@ imm:
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_SCONST; $$.type = D_SCONST;
memcpy($$.sval, $2, sizeof($$.sval)); memcpy($$.u.sval, $2, sizeof($$.u.sval));
} }
| '$' LFCONST | '$' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FCONST; $$.type = D_FCONST;
$$.dval = $2; $$.u.dval = $2;
} }
| '$' '(' LFCONST ')' | '$' '(' LFCONST ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FCONST; $$.type = D_FCONST;
$$.dval = $3; $$.u.dval = $3;
} }
| '$' '(' '-' LFCONST ')' | '$' '(' '-' LFCONST ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FCONST; $$.type = D_FCONST;
$$.dval = -$4; $$.u.dval = -$4;
} }
| '$' '-' LFCONST | '$' '-' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FCONST; $$.type = D_FCONST;
$$.dval = -$3; $$.u.dval = -$3;
} }
mem: mem:
...@@ -572,14 +570,14 @@ nam: ...@@ -572,14 +570,14 @@ nam:
{ {
$$ = nullgen; $$ = nullgen;
$$.type = $4; $$.type = $4;
$$.sym = $1; $$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2; $$.offset = $2;
} }
| LNAME '<' '>' offset '(' LSB ')' | LNAME '<' '>' offset '(' LSB ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_STATIC; $$.type = D_STATIC;
$$.sym = $1; $$.sym = linklookup(ctxt, $1->name, 1);
$$.offset = $4; $$.offset = $4;
} }
......
...@@ -65,6 +65,8 @@ main(int argc, char *argv[]) ...@@ -65,6 +65,8 @@ main(int argc, char *argv[])
thechar = '6'; thechar = '6';
thestring = "amd64"; thestring = "amd64";
ctxt = linknew(&linkamd64);
ctxt->diag = yyerror;
ensuresymb(NSYMB); ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug)); memset(debug, 0, sizeof(debug));
...@@ -96,6 +98,10 @@ main(int argc, char *argv[]) ...@@ -96,6 +98,10 @@ main(int argc, char *argv[])
p = ARGF(); p = ARGF();
setinclude(p); setinclude(p);
break; break;
case 'S':
ctxt->debugasm++;
break;
} ARGEND } ARGEND
if(*argv == 0) { if(*argv == 0) {
print("usage: %ca [-options] file.s\n", thechar); print("usage: %ca [-options] file.s\n", thechar);
...@@ -145,30 +151,23 @@ assemble(char *file) ...@@ -145,30 +151,23 @@ assemble(char *file)
errorexit(); errorexit();
} }
Binit(&obuf, of, OWRITE); Binit(&obuf, of, OWRITE);
pass = 1;
pinit(file);
Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion());
Bprint(&obuf, "\n!\n");
for(i=0; i<nDlist; i++) for(pass = 1; pass <= 2; pass++) {
dodefine(Dlist[i]); pinit(file);
yyparse(); for(i=0; i<nDlist; i++)
if(nerrors) { dodefine(Dlist[i]);
yyparse();
cclean(); cclean();
return nerrors; if(nerrors)
return nerrors;
} }
Bprint(&obuf, "\n!\n"); linkouthist(ctxt, &obuf);
linkwritefuncs(ctxt, &obuf);
pass = 2; Bflush(&obuf);
outhist(); return 0;
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
return nerrors;
} }
struct struct
...@@ -1031,15 +1030,8 @@ cinit(void) ...@@ -1031,15 +1030,8 @@ cinit(void)
Sym *s; Sym *s;
int i; 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.type = D_NONE;
nullgen.index = D_NONE; nullgen.index = D_NONE;
nullgen.scale = 0;
nerrors = 0; nerrors = 0;
iostack = I; iostack = I;
...@@ -1055,13 +1047,6 @@ cinit(void) ...@@ -1055,13 +1047,6 @@ cinit(void)
s->type = itab[i].type; s->type = itab[i].type;
s->value = itab[i].value; 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 void
...@@ -1089,255 +1074,42 @@ syminit(Sym *s) ...@@ -1089,255 +1074,42 @@ syminit(Sym *s)
void void
cclean(void) cclean(void)
{ {
Gen2 g2; Addr2 g2;
g2.from = nullgen; g2.from = nullgen;
g2.to = nullgen; g2.to = nullgen;
outcode(AEND, &g2); outcode(AEND, &g2);
Bflush(&obuf);
} }
void static Prog *lastpc;
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);
}
void void
outcode(int a, Gen2 *g2) outcode(int a, Addr2 *g2)
{ {
int sf, st, t; Prog *p;
Sym *s; Plist *pl;
if(pass == 1) if(pass == 1)
goto out; goto out;
jackpot: p = malloc(sizeof *p);
sf = 0; memset(p, 0, sizeof *p);
s = g2->from.sym; p->as = a;
while(s != S) { p->lineno = stmtline;
sf = s->sym; p->from = g2->from;
if(sf < 0 || sf >= NSYM) p->to = g2->to;
sf = 0;
t = g2->from.type; if(lastpc == nil) {
if(t == D_ADDR) pl = linknewplist(ctxt);
t = g2->from.index; pl->firstpc = p;
if(h[sf].type == t) } else
if(h[sf].sym == s) lastpc->link = p;
break; lastpc = p;
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);
out: out:
if(a != AGLOBL && a != ADATA) if(a != AGLOBL && a != ADATA)
pc++; 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/lexbody"
#include "../cc/macbody" #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 /* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. 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
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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation; either version 2, or (at your option)
(at your option) any later version. any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License 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 /* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work part or all of the Bison parser skeleton and distribute that work
...@@ -26,11 +29,10 @@ ...@@ -26,11 +29,10 @@
special exception, which will cause the skeleton and the resulting special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public Bison output files to be licensed under the GNU General Public
License without this special exception. License without this special exception.
This special exception was added by the Free Software Foundation in This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */ version 2.2 of Bison. */
/* Tokens. */ /* Tokens. */
#ifndef YYTOKENTYPE #ifndef YYTOKENTYPE
# define YYTOKENTYPE # define YYTOKENTYPE
...@@ -116,28 +118,22 @@ ...@@ -116,28 +118,22 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE typedef union YYSTYPE
{
/* Line 2068 of yacc.c */
#line 38 "a.y" #line 38 "a.y"
{
Sym *sym; Sym *sym;
vlong lval; vlong lval;
double dval; double dval;
char sval[8]; char sval[8];
Gen gen; Addr addr;
Gen2 gen2; Addr2 addr2;
}
/* Line 1529 of yacc.c. */
#line 132 "y.tab.h"
/* Line 2068 of yacc.c */ YYSTYPE;
#line 135 "y.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif #endif
extern YYSTYPE yylval; extern YYSTYPE yylval;
...@@ -29,9 +29,9 @@ ...@@ -29,9 +29,9 @@
// THE SOFTWARE. // THE SOFTWARE.
#include <bio.h> #include <bio.h>
#include <link.h>
#include "../8l/8.out.h" #include "../8l/8.out.h"
#ifndef EXTERN #ifndef EXTERN
#define EXTERN extern #define EXTERN extern
#endif #endif
...@@ -45,10 +45,8 @@ ...@@ -45,10 +45,8 @@
typedef struct Sym Sym; typedef struct Sym Sym;
typedef struct Ref Ref; typedef struct Ref Ref;
typedef struct Gen Gen;
typedef struct Io Io; typedef struct Io Io;
typedef struct Hist Hist; typedef struct Addr2 Addr2;
typedef struct Gen2 Gen2;
#define MAXALIGN 7 #define MAXALIGN 7
#define FPCHIP 1 #define FPCHIP 1
...@@ -97,37 +95,11 @@ struct Io ...@@ -97,37 +95,11 @@ struct Io
}; };
#define I ((Io*)0) #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;
};
struct Gen2
{
Gen from;
Gen to;
};
struct Hist
{ {
Hist* link; Addr from;
char* name; Addr to;
int32 line;
int32 offset;
}; };
#define H ((Hist*)0)
enum enum
{ {
...@@ -137,14 +109,11 @@ enum ...@@ -137,14 +109,11 @@ enum
CPREPROC, CPREPROC,
}; };
EXTERN char debug[256]; EXTERN char debug[256];
EXTERN Sym* hash[NHASH]; EXTERN Sym* hash[NHASH];
EXTERN char** Dlist; EXTERN char** Dlist;
EXTERN int nDlist; EXTERN int nDlist;
EXTERN Hist* ehist;
EXTERN int newflag; EXTERN int newflag;
EXTERN Hist* hist;
EXTERN char* hunk; EXTERN char* hunk;
EXTERN char** include; EXTERN char** include;
EXTERN Io* iofree; EXTERN Io* iofree;
...@@ -155,10 +124,9 @@ EXTERN int nerrors; ...@@ -155,10 +124,9 @@ EXTERN int nerrors;
EXTERN int32 nhunk; EXTERN int32 nhunk;
EXTERN int ninclude; EXTERN int ninclude;
EXTERN int32 nsymb; EXTERN int32 nsymb;
EXTERN Gen nullgen; EXTERN Addr nullgen;
EXTERN char* outfile; EXTERN char* outfile;
EXTERN int pass; EXTERN int pass;
EXTERN char* pathname;
EXTERN int32 pc; EXTERN int32 pc;
EXTERN int peekc; EXTERN int peekc;
EXTERN int32 stmtline; EXTERN int32 stmtline;
...@@ -168,6 +136,7 @@ EXTERN int thechar; ...@@ -168,6 +136,7 @@ EXTERN int thechar;
EXTERN char* thestring; EXTERN char* thestring;
EXTERN int32 thunk; EXTERN int32 thunk;
EXTERN Biobuf obuf; EXTERN Biobuf obuf;
EXTERN Link* ctxt;
void* alloc(int32); void* alloc(int32);
void* allocn(void*, int32, int32); void* allocn(void*, int32, int32);
...@@ -188,12 +157,9 @@ void cinit(void); ...@@ -188,12 +157,9 @@ void cinit(void);
void checkscale(int); void checkscale(int);
void pinit(char*); void pinit(char*);
void cclean(void); void cclean(void);
int isreg(Gen*); int isreg(Addr*);
void outcode(int, Gen2*); void outcode(int, Addr2*);
void outhist(void); void outhist(void);
void zaddr(Gen*, int);
void zname(char*, int, int);
void ieeedtod(Ieee*, double);
int filbuf(void); int filbuf(void);
Sym* getsym(void); Sym* getsym(void);
void domacro(void); void domacro(void);
......
...@@ -44,8 +44,8 @@ ...@@ -44,8 +44,8 @@
} con2; } con2;
double dval; double dval;
char sval[8]; char sval[8];
Gen gen; LAddr addr;
Gen2 gen2; Addr2 addr2;
} }
%left '|' %left '|'
%left '^' %left '^'
...@@ -62,9 +62,9 @@ ...@@ -62,9 +62,9 @@
%token <sym> LNAME LLAB LVAR %token <sym> LNAME LLAB LVAR
%type <lval> con expr pointer offset %type <lval> con expr pointer offset
%type <con2> con2 %type <con2> con2
%type <gen> mem imm imm2 reg nam rel rem rim rom omem nmem %type <addr> mem imm imm2 reg nam rel rem rim rom omem nmem
%type <gen2> nonnon nonrel nonrem rimnon rimrem remrim %type <addr2> nonnon nonrel nonrem rimnon rimrem remrim
%type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12 %type <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12
%% %%
prog: prog:
| prog | prog
...@@ -366,14 +366,12 @@ rel: ...@@ -366,14 +366,12 @@ rel:
if(pass == 2) if(pass == 2)
yyerror("undefined label: %s", $1->name); yyerror("undefined label: %s", $1->name);
$$.type = D_BRANCH; $$.type = D_BRANCH;
$$.sym = $1;
$$.offset = $2; $$.offset = $2;
} }
| LLAB offset | LLAB offset
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_BRANCH; $$.type = D_BRANCH;
$$.sym = $1;
$$.offset = $1->value + $2; $$.offset = $1->value + $2;
} }
...@@ -431,31 +429,31 @@ imm: ...@@ -431,31 +429,31 @@ imm:
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_SCONST; $$.type = D_SCONST;
memcpy($$.sval, $2, sizeof($$.sval)); memcpy($$.u.sval, $2, sizeof($$.u.sval));
} }
| '$' LFCONST | '$' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FCONST; $$.type = D_FCONST;
$$.dval = $2; $$.u.dval = $2;
} }
| '$' '(' LFCONST ')' | '$' '(' LFCONST ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FCONST; $$.type = D_FCONST;
$$.dval = $3; $$.u.dval = $3;
} }
| '$' '(' '-' LFCONST ')' | '$' '(' '-' LFCONST ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FCONST; $$.type = D_FCONST;
$$.dval = -$4; $$.u.dval = -$4;
} }
| '$' '-' LFCONST | '$' '-' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_FCONST; $$.type = D_FCONST;
$$.dval = -$3; $$.u.dval = -$3;
} }
imm2: imm2:
...@@ -590,14 +588,14 @@ nam: ...@@ -590,14 +588,14 @@ nam:
{ {
$$ = nullgen; $$ = nullgen;
$$.type = $4; $$.type = $4;
$$.sym = $1; $$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2; $$.offset = $2;
} }
| LNAME '<' '>' offset '(' LSB ')' | LNAME '<' '>' offset '(' LSB ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.type = D_STATIC; $$.type = D_STATIC;
$$.sym = $1; $$.sym = linklookup(ctxt, $1->name, 1);
$$.offset = $4; $$.offset = $4;
} }
......
...@@ -65,6 +65,8 @@ main(int argc, char *argv[]) ...@@ -65,6 +65,8 @@ main(int argc, char *argv[])
thechar = '8'; thechar = '8';
thestring = "386"; thestring = "386";
ctxt = linknew(&link386);
ctxt->diag = yyerror;
ensuresymb(NSYMB); ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug)); memset(debug, 0, sizeof(debug));
...@@ -96,6 +98,10 @@ main(int argc, char *argv[]) ...@@ -96,6 +98,10 @@ main(int argc, char *argv[])
p = ARGF(); p = ARGF();
setinclude(p); setinclude(p);
break; break;
case 'S':
ctxt->debugasm++;
break;
} ARGEND } ARGEND
if(*argv == 0) { if(*argv == 0) {
print("usage: %ca [-options] file.s\n", thechar); print("usage: %ca [-options] file.s\n", thechar);
...@@ -145,30 +151,23 @@ assemble(char *file) ...@@ -145,30 +151,23 @@ assemble(char *file)
errorexit(); errorexit();
} }
Binit(&obuf, of, OWRITE); Binit(&obuf, of, OWRITE);
pass = 1;
pinit(file);
Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion());
Bprint(&obuf, "\n!\n");
for(i=0; i<nDlist; i++) for(pass = 1; pass <= 2; pass++) {
dodefine(Dlist[i]); pinit(file);
yyparse(); for(i=0; i<nDlist; i++)
if(nerrors) { dodefine(Dlist[i]);
yyparse();
cclean(); cclean();
return nerrors; if(nerrors)
return nerrors;
} }
Bprint(&obuf, "\n!\n"); linkouthist(ctxt, &obuf);
linkwritefuncs(ctxt, &obuf);
pass = 2; Bflush(&obuf);
outhist(); return 0;
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
return nerrors;
} }
struct struct
...@@ -810,15 +809,8 @@ cinit(void) ...@@ -810,15 +809,8 @@ cinit(void)
Sym *s; Sym *s;
int i; 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.type = D_NONE;
nullgen.index = D_NONE; nullgen.index = D_NONE;
nullgen.scale = 0;
nerrors = 0; nerrors = 0;
iostack = I; iostack = I;
...@@ -834,13 +826,6 @@ cinit(void) ...@@ -834,13 +826,6 @@ cinit(void)
s->type = itab[i].type; s->type = itab[i].type;
s->value = itab[i].value; 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 void
...@@ -868,252 +853,42 @@ syminit(Sym *s) ...@@ -868,252 +853,42 @@ syminit(Sym *s)
void void
cclean(void) cclean(void)
{ {
Gen2 g2; Addr2 g2;
g2.from = nullgen; g2.from = nullgen;
g2.to = nullgen; g2.to = nullgen;
outcode(AEND, &g2); outcode(AEND, &g2);
Bflush(&obuf);
} }
void static Prog *lastpc;
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);
}
void void
outcode(int a, Gen2 *g2) outcode(int a, Addr2 *g2)
{ {
int sf, st, t; Prog *p;
Sym *s; Plist *pl;
if(pass == 1) if(pass == 1)
goto out; goto out;
jackpot: p = malloc(sizeof *p);
sf = 0; memset(p, 0, sizeof *p);
s = g2->from.sym; p->as = a;
while(s != S) { p->lineno = stmtline;
sf = s->sym; p->from = g2->from;
if(sf < 0 || sf >= NSYM) p->to = g2->to;
sf = 0;
t = g2->from.type; if(lastpc == nil) {
if(t == D_ADDR) pl = linknewplist(ctxt);
t = g2->from.index; pl->firstpc = p;
if(h[sf].type == t) } else
if(h[sf].sym == s) lastpc->link = p;
break; lastpc = p;
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);
out: out:
if(a != AGLOBL && a != ADATA) if(a != AGLOBL && a != ADATA)
pc++; 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/lexbody"
#include "../cc/macbody" #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 /* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. 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
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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation; either version 2, or (at your option)
(at your option) any later version. any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License 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 /* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work part or all of the Bison parser skeleton and distribute that work
...@@ -26,11 +29,10 @@ ...@@ -26,11 +29,10 @@
special exception, which will cause the skeleton and the resulting special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public Bison output files to be licensed under the GNU General Public
License without this special exception. License without this special exception.
This special exception was added by the Free Software Foundation in This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */ version 2.2 of Bison. */
/* Tokens. */ /* Tokens. */
#ifndef YYTOKENTYPE #ifndef YYTOKENTYPE
# define YYTOKENTYPE # define YYTOKENTYPE
...@@ -112,11 +114,8 @@ ...@@ -112,11 +114,8 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE typedef union YYSTYPE
{
/* Line 2068 of yacc.c */
#line 38 "a.y" #line 38 "a.y"
{
Sym *sym; Sym *sym;
int32 lval; int32 lval;
struct { struct {
...@@ -125,19 +124,16 @@ typedef union YYSTYPE ...@@ -125,19 +124,16 @@ typedef union YYSTYPE
} con2; } con2;
double dval; double dval;
char sval[8]; char sval[8];
Gen gen; Addr addr;
Gen2 gen2; Addr2 addr2;
}
/* Line 1529 of yacc.c. */
#line 132 "y.tab.h"
/* Line 2068 of yacc.c */ YYSTYPE;
#line 135 "y.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif #endif
extern YYSTYPE yylval; extern YYSTYPE yylval;
...@@ -209,7 +209,7 @@ newfile(char *s, int f) ...@@ -209,7 +209,7 @@ newfile(char *s, int f)
errorexit(); errorexit();
} }
fi.c = 0; fi.c = 0;
linehist(s, 0); linklinehist(ctxt, lineno, s, 0);
} }
Sym* Sym*
...@@ -477,7 +477,7 @@ l1: ...@@ -477,7 +477,7 @@ l1:
return LCONST; return LCONST;
case '"': case '"':
memcpy(yylval.sval, nullgen.sval, sizeof(yylval.sval)); memcpy(yylval.sval, nullgen.u.sval, sizeof(yylval.sval));
cp = yylval.sval; cp = yylval.sval;
c1 = 0; c1 = 0;
for(;;) { for(;;) {
...@@ -638,10 +638,6 @@ pinit(char *f) ...@@ -638,10 +638,6 @@ pinit(char *f)
pc = 0; pc = 0;
peekc = IGN; peekc = IGN;
sym = 1; sym = 1;
for(i=0; i<NSYM; i++) {
h[i].type = 0;
h[i].sym = S;
}
for(i=0; i<NHASH; i++) for(i=0; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->link) for(s = hash[i]; s != S; s = s->link)
s->macro = 0; s->macro = 0;
...@@ -661,7 +657,7 @@ loop: ...@@ -661,7 +657,7 @@ loop:
fi.c = read(i->f, i->b, BUFSIZ) - 1; fi.c = read(i->f, i->b, BUFSIZ) - 1;
if(fi.c < 0) { if(fi.c < 0) {
close(i->f); close(i->f);
linehist(0, 0); linklinehist(ctxt, lineno, 0, 0);
goto pop; goto pop;
} }
fi.p = i->b + 1; fi.p = i->b + 1;
...@@ -709,67 +705,5 @@ yyerror(char *a, ...) ...@@ -709,67 +705,5 @@ yyerror(char *a, ...)
void void
prfile(int32 l) prfile(int32 l)
{ {
int i, n; linkprfile(ctxt, l);
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);
} }
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