1
0
mirror of https://github.com/golang/go synced 2024-10-04 08:21:22 -06:00

[dev.power64] cmd/9a: use liblink, add required additional instructions.

LGTM=rsc
R=rsc, iant
CC=golang-codereviews
https://golang.org/cl/127730043
This commit is contained in:
Shenghou Ma 2014-08-07 14:49:41 -04:00
parent fcb842c645
commit bcf7f61f83
7 changed files with 4232 additions and 437 deletions

10
src/cmd/9a/Makefile Normal file
View File

@ -0,0 +1,10 @@
# Copyright 2012 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
include ../../Make.dist
install: y.tab.h
y.tab.h: a.y
LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y

View File

@ -27,19 +27,23 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <u.h>
#include <libc.h>
#include <bio.h>
#include "../9c/9.out.h"
#include <link.h>
#include "../9l/9.out.h"
#ifndef EXTERN
#define EXTERN extern
#endif
#undef getc
#undef ungetc
#undef BUFSIZ
#define getc ccgetc
#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
@ -48,32 +52,15 @@ typedef struct Hist Hist;
#define HISTSZ 20
#define NINCLUDE 10
#define NHUNK 10000
#ifndef EOF
#define EOF (-1)
#endif
#define IGN (-2)
#define GETC() ((--fi.c < 0)? filbuf(): *fi.p++ & 0xff)
#define NHASH 503
#define STRINGSZ 200
#define NMACRO 10
#define ALLOC(lhs, type)\
while(nhunk < sizeof(type))\
gethunk();\
lhs = (type*)hunk;\
nhunk -= sizeof(type);\
hunk += sizeof(type);
#define ALLOCN(lhs, len, n)\
if(lhs+len != hunk || nhunk < n) {\
while(nhunk <= len)\
gethunk();\
memmove(hunk, lhs, len);\
lhs = hunk;\
hunk += len;\
nhunk -= len;\
}\
hunk += n;\
nhunk -= n;
struct Sym
{
Sym* link;
@ -85,7 +72,7 @@ struct Sym
};
#define S ((Sym*)0)
struct
EXTERN struct
{
char* p;
int c;
@ -101,72 +88,47 @@ struct Io
};
#define I ((Io*)0)
struct
{
Sym* sym;
short type;
} h[NSYM];
struct Gen
{
Sym* sym;
vlong offset;
short type;
short reg;
short xreg;
short name;
ushort mask;
double dval;
char sval[8];
};
struct Hist
{
Hist* link;
char* name;
long line;
vlong offset;
};
#define H ((Hist*)0)
enum
{
CLAST,
CMACARG,
CMACRO,
CPREPROC
CPREPROC,
};
EXTERN char debug[256];
EXTERN int debug[256];
EXTERN Sym* hash[NHASH];
EXTERN char* Dlist[30];
EXTERN char** Dlist;
EXTERN int nDlist;
EXTERN Hist* ehist;
EXTERN int newflag;
EXTERN Hist* hist;
EXTERN char* hunk;
EXTERN char* include[NINCLUDE];
EXTERN char** include;
EXTERN Io* iofree;
EXTERN Io* ionext;
EXTERN Io* iostack;
EXTERN long lineno;
EXTERN int32 lineno;
EXTERN int nerrors;
EXTERN long nhunk;
EXTERN int32 nhunk;
EXTERN int nosched;
EXTERN int ninclude;
EXTERN Gen nullgen;
EXTERN int32 nsymb;
EXTERN Addr nullgen;
EXTERN char* outfile;
EXTERN int pass;
EXTERN char* pathname;
EXTERN long pc;
EXTERN int32 pc;
EXTERN int peekc;
EXTERN int sym;
EXTERN char symb[NSYMB];
EXTERN char* symb;
EXTERN int thechar;
EXTERN char* thestring;
EXTERN long thunk;
EXTERN int32 thunk;
EXTERN Biobuf obuf;
EXTERN Link* ctxt;
EXTERN Biobuf bstdout;
void* alloc(int32);
void* allocn(void*, int32, int32);
void ensuresymb(int32);
void errorexit(void);
void pushio(void);
void newio(void);
@ -174,7 +136,7 @@ void newfile(char*, int);
Sym* slookup(char*);
Sym* lookup(void);
void syminit(Sym*);
long yylex(void);
int32 yylex(void);
int getc(void);
int getnsc(void);
void unget(int);
@ -182,11 +144,8 @@ int escchar(int);
void cinit(void);
void pinit(char*);
void cclean(void);
void outcode(int, Gen*, int, Gen*);
void outgcode(int, Gen*, int, Gen*, Gen*);
void zname(char*, int, int);
void zaddr(Gen*, int);
void ieeedtod(Ieee*, double);
void outcode(int, Addr*, int, Addr*);
void outgcode(int, Addr*, int, Addr*, Addr*);
int filbuf(void);
Sym* getsym(void);
void domacro(void);
@ -199,31 +158,10 @@ void maclin(void);
void macif(int);
void macend(void);
void dodefine(char*);
void prfile(long);
void outhist(void);
void prfile(int32);
void linehist(char*, int);
void gethunk(void);
void yyerror(char*, ...);
int yyparse(void);
void setinclude(char*);
int assemble(char*);
/*
* system-dependent stuff from ../cc/compat.c
*/
enum /* keep in synch with ../cc/cc.h */
{
Plan9 = 1<<0,
Unix = 1<<1,
Windows = 1<<2
};
int mywait(int*);
int mycreat(char*, int);
int systemtype(int);
int pathchar(void);
char* mygetwd(char*, int);
int myexec(char*, char*[]);
int mydup(int, int);
int myfork(void);
int mypipe(int*);
void* mysbrk(ulong);

View File

@ -28,7 +28,11 @@
// THE SOFTWARE.
%{
#include <u.h>
#include <stdio.h> /* if we don't, bison will, and a.h re-#defines getc */
#include <libc.h>
#include "a.h"
#include "../../pkg/runtime/funcdata.h"
%}
%union
{
@ -36,7 +40,7 @@
vlong lval;
double dval;
char sval[8];
Gen gen;
Addr addr;
}
%left '|'
%left '^'
@ -50,14 +54,14 @@
%token <lval> LCONST LSP LSB LFP LPC LCREG LFLUSH
%token <lval> LREG LFREG LR LCR LF LFPSCR
%token <lval> LLR LCTR LSPR LSPREG LSEG LMSR
%token <lval> LSCHED LXLD LXST LXOP LXMV
%token <lval> LPCDAT LFUNCDAT LSCHED LXLD LXST LXOP LXMV
%token <lval> LRLWM LMOVMW LMOVEM LMOVFL LMTFSB LMA
%token <dval> LFCONST
%token <sval> LSCONST
%token <sym> LNAME LLAB LVAR
%type <lval> con expr pointer offset sreg
%type <gen> addr rreg regaddr name creg freg xlreg lr ctr
%type <gen> imm ximm fimm rel psr lcr cbit fpscr fpscrf msr mask
%type <addr> addr rreg regaddr name creg freg xlreg lr ctr
%type <addr> imm ximm fimm rel psr lcr cbit fpscr fpscrf msr mask
%%
prog:
| prog line
@ -400,7 +404,7 @@ inst:
}
| LBRA con ',' con ',' rel
{
Gen g;
Addr g;
g = nullgen;
g.type = D_CONST;
g.offset = $2;
@ -408,7 +412,7 @@ inst:
}
| LBRA con ',' con ',' addr
{
Gen g;
Addr g;
g = nullgen;
g.type = D_CONST;
g.offset = $2;
@ -416,7 +420,7 @@ inst:
}
| LBRA con ',' con ',' '(' xlreg ')'
{
Gen g;
Addr g;
g = nullgen;
g.type = D_CONST;
g.offset = $2;
@ -572,21 +576,41 @@ inst:
{
outcode($1, &nullgen, NREG, &$3);
}
| LNOP imm /* SYSCALL $num: load $num to R0 before syscall and restore R0 to 0 afterwards. */
{
outcode($1, &$2, NREG, &nullgen);
}
/*
* word
*/
| LWORD imm comma
{
if($1 == ADWORD && $2.type == D_CONST)
$2.type = D_DCONST;
outcode($1, &$2, NREG, &nullgen);
}
| LWORD ximm comma
{
if($1 == ADWORD && $2.type == D_CONST)
$2.type = D_DCONST;
outcode($1, &$2, NREG, &nullgen);
}
/*
* PCDATA
*/
| LPCDAT imm ',' imm
{
if($2.type != D_CONST || $4.type != D_CONST)
yyerror("arguments to PCDATA must be integer constants");
outcode($1, &$2, NREG, &$4);
}
/*
* FUNCDATA
*/
| LFUNCDAT imm ',' addr
{
if($2.type != D_CONST)
yyerror("index for FUNCDATA must be integer constant");
if($4.type != D_EXTERN && $4.type != D_STATIC && $4.type != D_OREG)
yyerror("value for FUNCDATA must be symbol reference");
outcode($1, &$2, NREG, &$4);
}
/*
* END
*/
@ -603,15 +627,15 @@ inst:
}
| LTEXT name ',' con ',' imm
{
$6.offset &= 0xffffffffull;
$6.offset |= (vlong)ArgsSizeUnknown << 32;
outcode($1, &$2, $4, &$6);
}
| LTEXT name ',' imm ':' imm
| LTEXT name ',' con ',' imm '-' con
{
outgcode($1, &$2, NREG, &$6, &$4);
}
| LTEXT name ',' con ',' imm ':' imm
{
outgcode($1, &$2, $4, &$8, &$6);
$6.offset &= 0xffffffffull;
$6.offset |= ($8 & 0xffffffffull) << 32;
outcode($1, &$2, $4, &$6);
}
/*
* DATA
@ -649,14 +673,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;
}
@ -774,7 +796,7 @@ mask:
con ',' con
{
int mb, me;
ulong v;
uint32 v;
$$ = nullgen;
$$.type = D_CONST;
@ -785,9 +807,9 @@ mask:
mb = me = 0;
}
if(mb <= me)
v = ((ulong)~0L>>mb) & (~0L<<(31-me));
v = ((uint32)~0L>>mb) & (~0L<<(31-me));
else
v = ~(((ulong)~0L>>(me+1)) & (~0L<<(31-(mb-1))));
v = ~(((uint32)~0L>>(me+1)) & (~0L<<(31-(mb-1))));
$$.offset = v;
}
@ -801,7 +823,7 @@ ximm:
{
$$ = nullgen;
$$.type = D_SCONST;
memcpy($$.sval, $2, sizeof($$.sval));
memcpy($$.u.sval, $2, sizeof($$.u.sval));
}
fimm:
@ -809,13 +831,13 @@ fimm:
{
$$ = nullgen;
$$.type = D_FCONST;
$$.dval = $2;
$$.u.dval = $2;
}
| '$' '-' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
$$.dval = -$3;
$$.u.dval = -$3;
}
imm: '$' con
@ -847,7 +869,7 @@ regaddr:
$$ = nullgen;
$$.type = D_OREG;
$$.reg = $2;
$$.xreg = $4;
$$.scale = $4;
$$.offset = 0;
}
@ -867,7 +889,7 @@ name:
$$ = nullgen;
$$.type = D_OREG;
$$.name = $3;
$$.sym = S;
$$.sym = nil;
$$.offset = $1;
}
| LNAME offset '(' pointer ')'
@ -875,7 +897,7 @@ name:
$$ = nullgen;
$$.type = D_OREG;
$$.name = $4;
$$.sym = $1;
$$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2;
}
| LNAME '<' '>' offset '(' LSB ')'
@ -883,7 +905,7 @@ name:
$$ = nullgen;
$$.type = D_OREG;
$$.name = D_STATIC;
$$.sym = $1;
$$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $4;
}

21
src/cmd/9a/doc.go Normal file
View File

@ -0,0 +1,21 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
/*
9a is a version of the Plan 9 assembler. The original is documented at
http://plan9.bell-labs.com/magic/man2html/1/8a
Go-specific considerations are documented at
http://golang.org/doc/asm
Its target architecture is the Power64, referred to by these tools as
power64 (big endian) or power64le (little endian).
*/
package main

View File

@ -27,29 +27,68 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// +build ignore
#define EXTERN
#include <u.h>
#include <libc.h>
#include "a.h"
#include "y.tab.h"
#include <ctype.h>
enum
{
Plan9 = 1<<0,
Unix = 1<<1,
Windows = 1<<2,
};
int
systemtype(int sys)
{
#ifdef _WIN32
return sys&Windows;
#else
return sys&Plan9;
#endif
}
int
Lconv(Fmt *fp)
{
return linklinefmt(ctxt, fp);
}
int
pathchar(void)
{
return '/';
}
void
main(int argc, char *argv[])
{
char *p;
int nout, nproc, status, i, c;
int c;
thechar = '9';
thestring = "power64";
thestring = getgoarch();
if(strcmp(thestring, "power64le") == 0)
ctxt = linknew(&linkpower64le);
else
ctxt = linknew(&linkpower64);
ctxt->diag = yyerror;
ctxt->bso = &bstdout;
Binit(&bstdout, 1, OWRITE);
listinit9();
fmtinstall('L', Lconv);
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
cinit();
outfile = 0;
include[ninclude++] = ".";
setinclude(".");
ARGBEGIN {
default:
c = ARGC();
if(c >= 0 || c < sizeof(debug))
if(c >= 0 && c < sizeof(debug))
debug[c] = 1;
break;
@ -59,62 +98,31 @@ main(int argc, char *argv[])
case 'D':
p = ARGF();
if(p)
if(p) {
if (nDlist%8 == 0)
Dlist = allocn(Dlist, nDlist*sizeof(char *),
8*sizeof(char *));
Dlist[nDlist++] = p;
}
break;
case 'I':
p = ARGF();
setinclude(p);
break;
case 'S':
ctxt->debugasm++;
break;
} ARGEND
if(*argv == 0) {
print("usage: %ca [-options] file.s\n", thechar);
errorexit();
}
if(argc > 1 && systemtype(Windows)){
print("can't assemble multiple files on windows\n");
if(argc > 1){
print("can't assemble multiple files\n");
errorexit();
}
if(argc > 1) {
nproc = 1;
if(p = getenv("NPROC"))
nproc = atol(p);
c = 0;
nout = 0;
for(;;) {
while(nout < nproc && argc > 0) {
i = myfork();
if(i < 0) {
i = mywait(&status);
if(i < 0)
errorexit();
if(status)
c++;
nout--;
continue;
}
if(i == 0) {
print("%s:\n", *argv);
if(assemble(*argv))
errorexit();
exits(0);
}
nout++;
argc--;
argv++;
}
i = mywait(&status);
if(i < 0) {
if(c)
errorexit();
exits(0);
}
if(status)
c++;
nout--;
}
}
if(assemble(argv[0]))
errorexit();
exits(0);
@ -152,33 +160,30 @@ assemble(char *file)
}
}
of = mycreat(outfile, 0664);
of = create(outfile, OWRITE, 0664);
if(of < 0) {
yyerror("%ca: cannot create %s", thechar, outfile);
errorexit();
}
Binit(&obuf, of, OWRITE);
Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion());
Bprint(&obuf, "\n!\n");
pass = 1;
nosched = 0;
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
if(nerrors) {
for(pass = 1; pass <= 2; pass++) {
nosched = 0;
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
return nerrors;
if(nerrors)
return nerrors;
}
pass = 2;
nosched = 0;
outhist();
pinit(file);
for(i=0; i<nDlist; i++)
dodefine(Dlist[i]);
yyparse();
cclean();
return nerrors;
writeobj(ctxt, &obuf);
Bflush(&obuf);
return 0;
}
struct
@ -385,6 +390,8 @@ struct
"CMP", LCMP, ACMP,
"CMPU", LCMP, ACMPU,
"CMPW", LCMP, ACMPW,
"CMPWU", LCMP, ACMPWU,
"DIVW", LLOGW, ADIVW,
"DIVWV", LLOGW, ADIVWV,
@ -477,6 +484,7 @@ struct
"NOP", LNOP, ANOP, /* ori 0,0,0 */
"SYSCALL", LNOP, ASYSCALL,
"UNDEF", LNOP, AUNDEF,
"RETURN", LRETRN, ARETURN,
"RFI", LRETRN, ARFI,
@ -591,6 +599,9 @@ struct
"SCHED", LSCHED, 0,
"NOSCHED", LSCHED, 0x80,
"PCDATA", LPCDAT, APCDATA,
"FUNCDATA", LFUNCDAT, AFUNCDATA,
0
};
@ -600,16 +611,10 @@ cinit(void)
Sym *s;
int i;
nullgen.sym = S;
nullgen.offset = 0;
nullgen.type = D_NONE;
nullgen.name = D_NONE;
nullgen.reg = NREG;
nullgen.xreg = NREG;
if(FPCHIP)
nullgen.dval = 0;
for(i=0; i<sizeof(nullgen.sval); i++)
nullgen.sval[i] = 0;
nullgen.scale = NREG; // replaced Gen.xreg with Prog.scale
nerrors = 0;
iostack = I;
@ -623,12 +628,6 @@ cinit(void)
s->type = itab[i].type;
s->value = itab[i].value;
}
ALLOCN(pathname, 0, 100);
if(mygetwd(pathname, 99) == 0) {
ALLOCN(pathname, 100, 900);
if(mygetwd(pathname, 999) == 0)
strcpy(pathname, "/???");
}
}
void
@ -644,263 +643,82 @@ cclean(void)
{
outcode(AEND, &nullgen, NREG, &nullgen);
Bflush(&obuf);
}
static Prog *lastpc;
void
zname(char *n, int t, int s)
outcode(int a, Addr *g1, int reg, Addr *g2)
{
Prog *p;
Plist *pl;
Bputc(&obuf, ANAME);
Bputc(&obuf, ANAME>>8);
Bputc(&obuf, t); /* type */
Bputc(&obuf, s); /* sym */
while(*n) {
Bputc(&obuf, *n);
n++;
}
Bputc(&obuf, 0);
}
void
zaddr(Gen *a, int s)
{
long l;
int i;
char *n;
Ieee e;
if(a->type == D_CONST){
l = a->offset;
if((vlong)l != a->offset)
a->type = D_DCONST;
}
Bputc(&obuf, a->type);
Bputc(&obuf, a->reg);
Bputc(&obuf, s);
Bputc(&obuf, a->name);
switch(a->type) {
default:
print("unknown type %d\n", a->type);
exits("arg");
case D_NONE:
case D_REG:
case D_FREG:
case D_CREG:
case D_FPSCR:
case D_MSR:
case D_OPT:
break;
case D_DCR:
case D_SPR:
case D_OREG:
case D_CONST:
case D_BRANCH:
l = a->offset;
Bputc(&obuf, l);
Bputc(&obuf, l>>8);
Bputc(&obuf, l>>16);
Bputc(&obuf, l>>24);
break;
case D_DCONST:
l = a->offset;
Bputc(&obuf, l);
Bputc(&obuf, l>>8);
Bputc(&obuf, l>>16);
Bputc(&obuf, l>>24);
l = a->offset>>32;
Bputc(&obuf, l);
Bputc(&obuf, l>>8);
Bputc(&obuf, l>>16);
Bputc(&obuf, l>>24);
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);
Bputc(&obuf, e.l);
Bputc(&obuf, e.l>>8);
Bputc(&obuf, e.l>>16);
Bputc(&obuf, e.l>>24);
Bputc(&obuf, e.h);
Bputc(&obuf, e.h>>8);
Bputc(&obuf, e.h>>16);
Bputc(&obuf, e.h>>24);
break;
}
}
int
outsim(Gen *g)
{
Sym *s;
int sno, t;
s = g->sym;
if(s == S)
return 0;
sno = s->sym;
if(sno < 0 || sno >= NSYM)
sno = 0;
t = g->name;
if(h[sno].type == t && h[sno].sym == s)
return sno;
zname(s->name, t, sym);
s->sym = sym;
h[sym].sym = s;
h[sym].type = t;
sno = sym;
sym++;
if(sym >= NSYM)
sym = 1;
return sno;
}
void
outcode(int a, Gen *g1, int reg, Gen *g2)
{
int sf, st;
if(a != AGLOBL && a != ADATA)
pc++;
if(pass == 1)
return;
if(g1->xreg != NREG) {
if(reg != NREG || g2->xreg != NREG)
goto out;
if(g1->scale != NREG) {
if(reg != NREG || g2->scale != NREG)
yyerror("bad addressing modes");
reg = g1->xreg;
reg = g1->scale;
} else
if(g2->xreg != NREG) {
if(g2->scale != NREG) {
if(reg != NREG)
yyerror("bad addressing modes");
reg = g2->xreg;
reg = g2->scale;
}
do {
sf = outsim(g1);
st = outsim(g2);
} while(sf != 0 && st == sf);
Bputc(&obuf, a);
Bputc(&obuf, a>>8);
Bputc(&obuf, reg|nosched);
Bputc(&obuf, lineno);
Bputc(&obuf, lineno>>8);
Bputc(&obuf, lineno>>16);
Bputc(&obuf, lineno>>24);
zaddr(g1, sf);
zaddr(g2, st);
}
void
outgcode(int a, Gen *g1, int reg, Gen *g2, Gen *g3)
{
int s1, s2, s3, flag;
p = ctxt->arch->prg();
p->as = a;
p->lineno = lineno;
if(nosched)
p->mark |= NOSCHED;
p->from = *g1;
p->reg = reg;
p->to = *g2;
p->pc = pc;
if(lastpc == nil) {
pl = linknewplist(ctxt);
pl->firstpc = p;
} else
lastpc->link = p;
lastpc = p;
out:
if(a != AGLOBL && a != ADATA)
pc++;
if(pass == 1)
return;
do {
s1 = outsim(g1);
s2 = outsim(g2);
s3 = outsim(g3);
} while(s1 && (s2 && s1 == s2 || s3 && s1 == s3) || s2 && (s3 && s2 == s3));
flag = 0;
if(g2->type != D_NONE)
flag = 0x40; /* flags extra operand */
Bputc(&obuf, a);
Bputc(&obuf, a>>8);
Bputc(&obuf, reg | nosched | flag);
Bputc(&obuf, lineno);
Bputc(&obuf, lineno>>8);
Bputc(&obuf, lineno>>16);
Bputc(&obuf, lineno>>24);
zaddr(g1, s1);
if(flag)
zaddr(g2, s2);
zaddr(g3, s3);
}
void
outhist(void)
outgcode(int a, Addr *g1, int reg, Addr *g2, Addr *g3)
{
Gen g;
Hist *h;
char *p, *q, *op, c;
int n;
Prog *p;
Plist *pl;
g = nullgen;
c = pathchar();
for(h = hist; h != H; h = h->link) {
p = h->name;
op = 0;
/* on windows skip drive specifier in pathname */
if(systemtype(Windows) && p && p[1] == ':'){
p += 2;
c = *p;
}
if(p && p[0] != c && h->offset == 0 && pathname){
/* on windows skip drive specifier in pathname */
if(systemtype(Windows) && pathname[1] == ':') {
op = p;
p = pathname+2;
c = *p;
} 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, ANAME>>8);
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;
if(pass == 1)
goto out;
Bputc(&obuf, AHISTORY);
Bputc(&obuf, AHISTORY>>8);
Bputc(&obuf, 0);
Bputc(&obuf, h->line);
Bputc(&obuf, h->line>>8);
Bputc(&obuf, h->line>>16);
Bputc(&obuf, h->line>>24);
zaddr(&nullgen, 0);
zaddr(&g, 0);
}
p = ctxt->arch->prg();
p->as = a;
p->lineno = lineno;
if(nosched)
p->mark |= NOSCHED;
p->from = *g1;
p->reg = reg;
p->to = *g2;
p->from3 = *g3;
p->pc = pc;
print("oc: %P\n", p);
if(lastpc == nil) {
pl = linknewplist(ctxt);
pl->firstpc = p;
} else
lastpc->link = p;
lastpc = p;
out:
if(a != AGLOBL && a != ADATA)
pc++;
}
#include "../cc/lexbody"
#include "../cc/macbody"
#include "../cc/compat"

3794
src/cmd/9a/y.tab.c Normal file

File diff suppressed because it is too large Load Diff

192
src/cmd/9a/y.tab.h Normal file
View File

@ -0,0 +1,192 @@
/* A Bison parser, made by GNU Bison 2.5. */
/* 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
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.
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/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
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
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
LMOVW = 258,
LMOVB = 259,
LABS = 260,
LLOGW = 261,
LSHW = 262,
LADDW = 263,
LCMP = 264,
LCROP = 265,
LBRA = 266,
LFMOV = 267,
LFCONV = 268,
LFCMP = 269,
LFADD = 270,
LFMA = 271,
LTRAP = 272,
LXORW = 273,
LNOP = 274,
LEND = 275,
LRETT = 276,
LWORD = 277,
LTEXT = 278,
LDATA = 279,
LRETRN = 280,
LCONST = 281,
LSP = 282,
LSB = 283,
LFP = 284,
LPC = 285,
LCREG = 286,
LFLUSH = 287,
LREG = 288,
LFREG = 289,
LR = 290,
LCR = 291,
LF = 292,
LFPSCR = 293,
LLR = 294,
LCTR = 295,
LSPR = 296,
LSPREG = 297,
LSEG = 298,
LMSR = 299,
LPCDAT = 300,
LFUNCDAT = 301,
LSCHED = 302,
LXLD = 303,
LXST = 304,
LXOP = 305,
LXMV = 306,
LRLWM = 307,
LMOVMW = 308,
LMOVEM = 309,
LMOVFL = 310,
LMTFSB = 311,
LMA = 312,
LFCONST = 313,
LSCONST = 314,
LNAME = 315,
LLAB = 316,
LVAR = 317
};
#endif
/* Tokens. */
#define LMOVW 258
#define LMOVB 259
#define LABS 260
#define LLOGW 261
#define LSHW 262
#define LADDW 263
#define LCMP 264
#define LCROP 265
#define LBRA 266
#define LFMOV 267
#define LFCONV 268
#define LFCMP 269
#define LFADD 270
#define LFMA 271
#define LTRAP 272
#define LXORW 273
#define LNOP 274
#define LEND 275
#define LRETT 276
#define LWORD 277
#define LTEXT 278
#define LDATA 279
#define LRETRN 280
#define LCONST 281
#define LSP 282
#define LSB 283
#define LFP 284
#define LPC 285
#define LCREG 286
#define LFLUSH 287
#define LREG 288
#define LFREG 289
#define LR 290
#define LCR 291
#define LF 292
#define LFPSCR 293
#define LLR 294
#define LCTR 295
#define LSPR 296
#define LSPREG 297
#define LSEG 298
#define LMSR 299
#define LPCDAT 300
#define LFUNCDAT 301
#define LSCHED 302
#define LXLD 303
#define LXST 304
#define LXOP 305
#define LXMV 306
#define LRLWM 307
#define LMOVMW 308
#define LMOVEM 309
#define LMOVFL 310
#define LMTFSB 311
#define LMA 312
#define LFCONST 313
#define LSCONST 314
#define LNAME 315
#define LLAB 316
#define LVAR 317
#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];
Addr addr;
/* Line 2068 of yacc.c */
#line 184 "y.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval;