diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:13:40 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:13:40 +0200 |
commit | 5ff4c17907d5b19510a62e08fd8d3b11e62b431d (patch) | |
tree | c0650497e988f47be9c6f2324fa692a52dea82e1 /src/cmd/8a | |
parent | 80f18fc933cf3f3e829c5455a1023d69f7b86e52 (diff) | |
download | golang-upstream/60.tar.gz |
Imported Upstream version 60upstream/60
Diffstat (limited to 'src/cmd/8a')
-rw-r--r-- | src/cmd/8a/Makefile | 25 | ||||
-rw-r--r-- | src/cmd/8a/a.h | 215 | ||||
-rw-r--r-- | src/cmd/8a/a.y | 614 | ||||
-rw-r--r-- | src/cmd/8a/doc.go | 14 | ||||
-rw-r--r-- | src/cmd/8a/lex.c | 972 |
5 files changed, 1840 insertions, 0 deletions
diff --git a/src/cmd/8a/Makefile b/src/cmd/8a/Makefile new file mode 100644 index 000000000..78d361dbd --- /dev/null +++ b/src/cmd/8a/Makefile @@ -0,0 +1,25 @@ +# 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. + +include ../../Make.inc +O:=$(HOST_O) + +TARG=8a + +HFILES=\ + a.h\ + y.tab.h\ + ../8l/8.out.h\ + +OFILES=\ + y.tab.$O\ + lex.$O\ + ../8l/enam.$O\ + +YFILES=\ + a.y\ + +include ../../Make.ccmd + +lex.$O: ../cc/macbody ../cc/lexbody diff --git a/src/cmd/8a/a.h b/src/cmd/8a/a.h new file mode 100644 index 000000000..c5c22d7ba --- /dev/null +++ b/src/cmd/8a/a.h @@ -0,0 +1,215 @@ +// Inferno utils/8a/a.h +// http://code.google.com/p/inferno-os/source/browse/utils/8a/a.h +// +// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. +// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) +// Portions Copyright © 1997-1999 Vita Nuova Limited +// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) +// Portions Copyright © 2004,2006 Bruce Ellis +// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) +// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others +// Portions Copyright © 2009 The Go Authors. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include <bio.h> +#include "../8l/8.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 Ref Ref; +typedef struct Gen Gen; +typedef struct Io Io; +typedef struct Hist Hist; +typedef struct Gen2 Gen2; + +#define MAXALIGN 7 +#define FPCHIP 1 +#define NSYMB 500 +#define BUFSIZ 8192 +#define HISTSZ 20 +#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 + +struct Sym +{ + Sym* link; + Ref* ref; + char* macro; + int32 value; + ushort type; + char *name; + char sym; +}; +#define S ((Sym*)0) + +struct Ref +{ + int class; +}; + +EXTERN struct +{ + char* p; + int c; +} fi; + +struct Io +{ + Io* link; + char b[BUFSIZ]; + char* p; + short c; + short f; +}; +#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 +{ + Hist* link; + char* name; + int32 line; + int32 offset; +}; +#define H ((Hist*)0) + +enum +{ + CLAST, + CMACARG, + CMACRO, + 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; +EXTERN Io* ionext; +EXTERN Io* iostack; +EXTERN int32 lineno; +EXTERN int nerrors; +EXTERN int32 nhunk; +EXTERN int ninclude; +EXTERN int32 nsymb; +EXTERN Gen nullgen; +EXTERN char* outfile; +EXTERN int pass; +EXTERN char* pathname; +EXTERN int32 pc; +EXTERN int peekc; +EXTERN int32 stmtline; +EXTERN int sym; +EXTERN char* symb; +EXTERN int thechar; +EXTERN char* thestring; +EXTERN int32 thunk; +EXTERN Biobuf obuf; + +void* alloc(int32); +void* allocn(void*, int32, int32); +void ensuresymb(int32); +void errorexit(void); +void pushio(void); +void newio(void); +void newfile(char*, int); +Sym* slookup(char*); +Sym* lookup(void); +void syminit(Sym*); +int32 yylex(void); +int getc(void); +int getnsc(void); +void unget(int); +int escchar(int); +void cinit(void); +void checkscale(int); +void pinit(char*); +void cclean(void); +int isreg(Gen*); +void outcode(int, Gen2*); +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); +void macund(void); +void macdef(void); +void macexpand(Sym*, char*); +void macinc(void); +void macprag(void); +void maclin(void); +void macif(int); +void macend(void); +void dodefine(char*); +void prfile(int32); +void linehist(char*, int); +void gethunk(void); +void yyerror(char*, ...); +int yyparse(void); +void setinclude(char*); +int assemble(char*); diff --git a/src/cmd/8a/a.y b/src/cmd/8a/a.y new file mode 100644 index 000000000..a8ac773da --- /dev/null +++ b/src/cmd/8a/a.y @@ -0,0 +1,614 @@ +// Inferno utils/8a/a.y +// http://code.google.com/p/inferno-os/source/browse/utils/8a/a.y +// +// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. +// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) +// Portions Copyright © 1997-1999 Vita Nuova Limited +// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) +// Portions Copyright © 2004,2006 Bruce Ellis +// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) +// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others +// Portions Copyright © 2009 The Go Authors. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// 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" +%} +%union { + Sym *sym; + int32 lval; + struct { + int32 v1; + int32 v2; + } con2; + double dval; + char sval[8]; + Gen gen; + Gen2 gen2; +} +%left '|' +%left '^' +%left '&' +%left '<' '>' +%left '+' '-' +%left '*' '/' '%' +%token <lval> LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4 +%token <lval> LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG +%token <lval> LCONST LFP LPC LSB +%token <lval> LBREG LLREG LSREG LFREG +%token <dval> LFCONST +%token <sval> LSCONST LSP +%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 +%% +prog: +| prog + { + stmtline = lineno; + } + line + +line: + LLAB ':' + { + if($1->value != pc) + yyerror("redeclaration of %s", $1->name); + $1->value = pc; + } + line +| LNAME ':' + { + $1->type = LLAB; + $1->value = pc; + } + line +| ';' +| inst ';' +| error ';' + +inst: + LNAME '=' expr + { + $1->type = LVAR; + $1->value = $3; + } +| LVAR '=' expr + { + if($1->value != $3) + yyerror("redeclaration of %s", $1->name); + $1->value = $3; + } +| LTYPE0 nonnon { outcode($1, &$2); } +| LTYPE1 nonrem { outcode($1, &$2); } +| LTYPE2 rimnon { outcode($1, &$2); } +| LTYPE3 rimrem { outcode($1, &$2); } +| LTYPE4 remrim { outcode($1, &$2); } +| LTYPER nonrel { outcode($1, &$2); } +| LTYPED spec1 { outcode($1, &$2); } +| LTYPET spec2 { outcode($1, &$2); } +| LTYPEC spec3 { outcode($1, &$2); } +| LTYPEN spec4 { outcode($1, &$2); } +| LTYPES spec5 { outcode($1, &$2); } +| LTYPEM spec6 { outcode($1, &$2); } +| LTYPEI spec7 { outcode($1, &$2); } +| LTYPEG spec8 { outcode($1, &$2); } + +nonnon: + { + $$.from = nullgen; + $$.to = nullgen; + } +| ',' + { + $$.from = nullgen; + $$.to = nullgen; + } + +rimrem: + rim ',' rem + { + $$.from = $1; + $$.to = $3; + } + +remrim: + rem ',' rim + { + $$.from = $1; + $$.to = $3; + } + +rimnon: + rim ',' + { + $$.from = $1; + $$.to = nullgen; + } +| rim + { + $$.from = $1; + $$.to = nullgen; + } + +nonrem: + ',' rem + { + $$.from = nullgen; + $$.to = $2; + } +| rem + { + $$.from = nullgen; + $$.to = $1; + } + +nonrel: + ',' rel + { + $$.from = nullgen; + $$.to = $2; + } +| rel + { + $$.from = nullgen; + $$.to = $1; + } + +spec1: /* DATA */ + nam '/' con ',' imm + { + $$.from = $1; + $$.from.scale = $3; + $$.to = $5; + } + +spec2: /* TEXT */ + mem ',' imm2 + { + $$.from = $1; + $$.to = $3; + } +| mem ',' con ',' imm2 + { + $$.from = $1; + $$.from.scale = $3; + $$.to = $5; + } + +spec3: /* JMP/CALL */ + ',' rom + { + $$.from = nullgen; + $$.to = $2; + } +| rom + { + $$.from = nullgen; + $$.to = $1; + } + +spec4: /* NOP */ + nonnon +| nonrem + +spec5: /* SHL/SHR */ + rim ',' rem + { + $$.from = $1; + $$.to = $3; + } +| rim ',' rem ':' LLREG + { + $$.from = $1; + $$.to = $3; + if($$.from.index != D_NONE) + yyerror("dp shift with lhs index"); + $$.from.index = $5; + } + +spec6: /* MOVW/MOVL */ + rim ',' rem + { + $$.from = $1; + $$.to = $3; + } +| rim ',' rem ':' LSREG + { + $$.from = $1; + $$.to = $3; + if($$.to.index != D_NONE) + yyerror("dp move with lhs index"); + $$.to.index = $5; + } + +spec7: + rim ',' + { + $$.from = $1; + $$.to = nullgen; + } +| rim + { + $$.from = $1; + $$.to = nullgen; + } +| rim ',' rem + { + $$.from = $1; + $$.to = $3; + } + +spec8: /* GLOBL */ + mem ',' imm + { + $$.from = $1; + $$.to = $3; + } +| mem ',' con ',' imm + { + $$.from = $1; + $$.from.scale = $3; + $$.to = $5; + } + +rem: + reg +| mem + +rom: + rel +| nmem +| '*' reg + { + $$ = $2; + } +| '*' omem + { + $$ = $2; + } +| reg +| omem +| imm + +rim: + rem +| imm + +rel: + con '(' LPC ')' + { + $$ = nullgen; + $$.type = D_BRANCH; + $$.offset = $1 + pc; + } +| LNAME offset + { + $$ = nullgen; + 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; + } + +reg: + LBREG + { + $$ = nullgen; + $$.type = $1; + } +| LFREG + { + $$ = nullgen; + $$.type = $1; + } +| LLREG + { + $$ = nullgen; + $$.type = $1; + } +| LSP + { + $$ = nullgen; + $$.type = D_SP; + } +| LSREG + { + $$ = nullgen; + $$.type = $1; + } + +imm: + '$' con + { + $$ = nullgen; + $$.type = D_CONST; + $$.offset = $2; + } +| '$' nam + { + $$ = $2; + $$.index = $2.type; + $$.type = D_ADDR; + /* + if($2.type == D_AUTO || $2.type == D_PARAM) + yyerror("constant cannot be automatic: %s", + $2.sym->name); + */ + } +| '$' LSCONST + { + $$ = nullgen; + $$.type = D_SCONST; + memcpy($$.sval, $2, sizeof($$.sval)); + } +| '$' LFCONST + { + $$ = nullgen; + $$.type = D_FCONST; + $$.dval = $2; + } +| '$' '(' LFCONST ')' + { + $$ = nullgen; + $$.type = D_FCONST; + $$.dval = $3; + } +| '$' '-' LFCONST + { + $$ = nullgen; + $$.type = D_FCONST; + $$.dval = -$3; + } + +imm2: + '$' con2 + { + $$ = nullgen; + $$.type = D_CONST2; + $$.offset = $2.v1; + $$.offset2 = $2.v2; + } + +con2: + LCONST + { + $$.v1 = $1; + $$.v2 = 0; + } +| '-' LCONST + { + $$.v1 = -$2; + $$.v2 = 0; + } +| LCONST '-' LCONST + { + $$.v1 = $1; + $$.v2 = $3; + } +| '-' LCONST '-' LCONST + { + $$.v1 = -$2; + $$.v2 = $4; + } + +mem: + omem +| nmem + +omem: + con + { + $$ = nullgen; + $$.type = D_INDIR+D_NONE; + $$.offset = $1; + } +| con '(' LLREG ')' + { + $$ = nullgen; + $$.type = D_INDIR+$3; + $$.offset = $1; + } +| con '(' LSP ')' + { + $$ = nullgen; + $$.type = D_INDIR+D_SP; + $$.offset = $1; + } +| con '(' LLREG '*' con ')' + { + $$ = nullgen; + $$.type = D_INDIR+D_NONE; + $$.offset = $1; + $$.index = $3; + $$.scale = $5; + checkscale($$.scale); + } +| con '(' LLREG ')' '(' LLREG '*' con ')' + { + $$ = nullgen; + $$.type = D_INDIR+$3; + $$.offset = $1; + $$.index = $6; + $$.scale = $8; + checkscale($$.scale); + } +| '(' LLREG ')' + { + $$ = nullgen; + $$.type = D_INDIR+$2; + } +| '(' LSP ')' + { + $$ = nullgen; + $$.type = D_INDIR+D_SP; + } +| con '(' LSREG ')' + { + $$ = nullgen; + $$.type = D_INDIR+$3; + $$.offset = $1; + } +| '(' LLREG '*' con ')' + { + $$ = nullgen; + $$.type = D_INDIR+D_NONE; + $$.index = $2; + $$.scale = $4; + checkscale($$.scale); + } +| '(' LLREG ')' '(' LLREG '*' con ')' + { + $$ = nullgen; + $$.type = D_INDIR+$2; + $$.index = $5; + $$.scale = $7; + checkscale($$.scale); + } + +nmem: + nam + { + $$ = $1; + } +| nam '(' LLREG '*' con ')' + { + $$ = $1; + $$.index = $3; + $$.scale = $5; + checkscale($$.scale); + } + +nam: + LNAME offset '(' pointer ')' + { + $$ = nullgen; + $$.type = $4; + $$.sym = $1; + $$.offset = $2; + } +| LNAME '<' '>' offset '(' LSB ')' + { + $$ = nullgen; + $$.type = D_STATIC; + $$.sym = $1; + $$.offset = $4; + } + +offset: + { + $$ = 0; + } +| '+' con + { + $$ = $2; + } +| '-' con + { + $$ = -$2; + } + +pointer: + LSB +| LSP + { + $$ = D_AUTO; + } +| LFP + +con: + LCONST +| LVAR + { + $$ = $1->value; + } +| '-' con + { + $$ = -$2; + } +| '+' con + { + $$ = $2; + } +| '~' con + { + $$ = ~$2; + } +| '(' expr ')' + { + $$ = $2; + } + +expr: + con +| expr '+' expr + { + $$ = $1 + $3; + } +| expr '-' expr + { + $$ = $1 - $3; + } +| expr '*' expr + { + $$ = $1 * $3; + } +| expr '/' expr + { + $$ = $1 / $3; + } +| expr '%' expr + { + $$ = $1 % $3; + } +| expr '<' '<' expr + { + $$ = $1 << $4; + } +| expr '>' '>' expr + { + $$ = $1 >> $4; + } +| expr '&' expr + { + $$ = $1 & $3; + } +| expr '^' expr + { + $$ = $1 ^ $3; + } +| expr '|' expr + { + $$ = $1 | $3; + } diff --git a/src/cmd/8a/doc.go b/src/cmd/8a/doc.go new file mode 100644 index 000000000..a43b4461f --- /dev/null +++ b/src/cmd/8a/doc.go @@ -0,0 +1,14 @@ +// 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. + +/* + +8a is a version of the Plan 9 assembler. The original is documented at + + http://plan9.bell-labs.com/magic/man2html/1/2a + +Its target architecture is the x86, referred to by these tools for historical reasons as 386. + +*/ +package documentation diff --git a/src/cmd/8a/lex.c b/src/cmd/8a/lex.c new file mode 100644 index 000000000..e56460e4b --- /dev/null +++ b/src/cmd/8a/lex.c @@ -0,0 +1,972 @@ +// Inferno utils/8a/lex.c +// http://code.google.com/p/inferno-os/source/browse/utils/8a/lex.c +// +// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. +// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) +// Portions Copyright © 1997-1999 Vita Nuova Limited +// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) +// Portions Copyright © 2004,2006 Bruce Ellis +// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) +// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others +// Portions Copyright © 2009 The Go Authors. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#define EXTERN +#include <u.h> +#include <libc.h> +#include "a.h" +#include "y.tab.h" + +enum +{ + Plan9 = 1<<0, + Unix = 1<<1, + Windows = 1<<2, +}; + +int +systemtype(int sys) +{ + return sys&Plan9; +} + +int +pathchar(void) +{ + return '/'; +} + +void +main(int argc, char *argv[]) +{ + char *p; + int c; + + thechar = '8'; + thestring = "386"; + + ensuresymb(NSYMB); + memset(debug, 0, sizeof(debug)); + cinit(); + outfile = 0; + setinclude("."); + ARGBEGIN { + default: + c = ARGC(); + if(c >= 0 || c < sizeof(debug)) + debug[c] = 1; + break; + + case 'o': + outfile = ARGF(); + break; + + case 'D': + p = ARGF(); + 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; + } ARGEND + if(*argv == 0) { + print("usage: %ca [-options] file.s\n", thechar); + errorexit(); + } + if(argc > 1){ + print("can't assemble multiple files\n"); + errorexit(); + } + if(assemble(argv[0])) + errorexit(); + exits(0); +} + +int +assemble(char *file) +{ + char *ofile, *p; + int i, of; + + ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar) + strcpy(ofile, file); + p = utfrrune(ofile, pathchar()); + if(p) { + include[0] = ofile; + *p++ = 0; + } else + p = ofile; + if(outfile == 0) { + outfile = p; + if(outfile){ + p = utfrrune(outfile, '.'); + if(p) + if(p[1] == 's' && p[2] == 0) + p[0] = 0; + p = utfrune(outfile, 0); + p[0] = '.'; + p[1] = thechar; + p[2] = 0; + } else + outfile = "/dev/null"; + } + + of = create(outfile, OWRITE, 0664); + if(of < 0) { + yyerror("%ca: cannot create %s", thechar, outfile); + errorexit(); + } + Binit(&obuf, of, OWRITE); + + pass = 1; + pinit(file); + + Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); + + for(i=0; i<nDlist; i++) + dodefine(Dlist[i]); + yyparse(); + if(nerrors) { + cclean(); + return nerrors; + } + + Bprint(&obuf, "\n!\n"); + + pass = 2; + outhist(); + pinit(file); + for(i=0; i<nDlist; i++) + dodefine(Dlist[i]); + yyparse(); + cclean(); + return nerrors; +} + +struct +{ + char *name; + ushort type; + ushort value; +} itab[] = +{ + "SP", LSP, D_AUTO, + "SB", LSB, D_EXTERN, + "FP", LFP, D_PARAM, + "PC", LPC, D_BRANCH, + + "AL", LBREG, D_AL, + "CL", LBREG, D_CL, + "DL", LBREG, D_DL, + "BL", LBREG, D_BL, + "AH", LBREG, D_AH, + "CH", LBREG, D_CH, + "DH", LBREG, D_DH, + "BH", LBREG, D_BH, + + "AX", LLREG, D_AX, + "CX", LLREG, D_CX, + "DX", LLREG, D_DX, + "BX", LLREG, D_BX, +/* "SP", LLREG, D_SP, */ + "BP", LLREG, D_BP, + "SI", LLREG, D_SI, + "DI", LLREG, D_DI, + + "F0", LFREG, D_F0+0, + "F1", LFREG, D_F0+1, + "F2", LFREG, D_F0+2, + "F3", LFREG, D_F0+3, + "F4", LFREG, D_F0+4, + "F5", LFREG, D_F0+5, + "F6", LFREG, D_F0+6, + "F7", LFREG, D_F0+7, + + "CS", LSREG, D_CS, + "SS", LSREG, D_SS, + "DS", LSREG, D_DS, + "ES", LSREG, D_ES, + "FS", LSREG, D_FS, + "GS", LSREG, D_GS, + + "GDTR", LBREG, D_GDTR, + "IDTR", LBREG, D_IDTR, + "LDTR", LBREG, D_LDTR, + "MSW", LBREG, D_MSW, + "TASK", LBREG, D_TASK, + + "CR0", LBREG, D_CR+0, + "CR1", LBREG, D_CR+1, + "CR2", LBREG, D_CR+2, + "CR3", LBREG, D_CR+3, + "CR4", LBREG, D_CR+4, + "CR5", LBREG, D_CR+5, + "CR6", LBREG, D_CR+6, + "CR7", LBREG, D_CR+7, + + "DR0", LBREG, D_DR+0, + "DR1", LBREG, D_DR+1, + "DR2", LBREG, D_DR+2, + "DR3", LBREG, D_DR+3, + "DR4", LBREG, D_DR+4, + "DR5", LBREG, D_DR+5, + "DR6", LBREG, D_DR+6, + "DR7", LBREG, D_DR+7, + + "TR0", LBREG, D_TR+0, + "TR1", LBREG, D_TR+1, + "TR2", LBREG, D_TR+2, + "TR3", LBREG, D_TR+3, + "TR4", LBREG, D_TR+4, + "TR5", LBREG, D_TR+5, + "TR6", LBREG, D_TR+6, + "TR7", LBREG, D_TR+7, + + "AAA", LTYPE0, AAAA, + "AAD", LTYPE0, AAAD, + "AAM", LTYPE0, AAAM, + "AAS", LTYPE0, AAAS, + "ADCB", LTYPE3, AADCB, + "ADCL", LTYPE3, AADCL, + "ADCW", LTYPE3, AADCW, + "ADDB", LTYPE3, AADDB, + "ADDL", LTYPE3, AADDL, + "ADDW", LTYPE3, AADDW, + "ADJSP", LTYPE2, AADJSP, + "ANDB", LTYPE3, AANDB, + "ANDL", LTYPE3, AANDL, + "ANDW", LTYPE3, AANDW, + "ARPL", LTYPE3, AARPL, + "BOUNDL", LTYPE3, ABOUNDL, + "BOUNDW", LTYPE3, ABOUNDW, + "BSFL", LTYPE3, ABSFL, + "BSFW", LTYPE3, ABSFW, + "BSRL", LTYPE3, ABSRL, + "BSRW", LTYPE3, ABSRW, + "BTCL", LTYPE3, ABTCL, + "BTCW", LTYPE3, ABTCW, + "BTL", LTYPE3, ABTL, + "BTRL", LTYPE3, ABTRL, + "BTRW", LTYPE3, ABTRW, + "BTSL", LTYPE3, ABTSL, + "BTSW", LTYPE3, ABTSW, + "BTW", LTYPE3, ABTW, + "BYTE", LTYPE2, ABYTE, + "CALL", LTYPEC, ACALL, + "CLC", LTYPE0, ACLC, + "CLD", LTYPE0, ACLD, + "CLI", LTYPE0, ACLI, + "CLTS", LTYPE0, ACLTS, + "CMC", LTYPE0, ACMC, + "CMPB", LTYPE4, ACMPB, + "CMPL", LTYPE4, ACMPL, + "CMPW", LTYPE4, ACMPW, + "CMPSB", LTYPE0, ACMPSB, + "CMPSL", LTYPE0, ACMPSL, + "CMPSW", LTYPE0, ACMPSW, + "CMPXCHG8B", LTYPE1, ACMPXCHG8B, + "CMPXCHGB", LTYPE3, ACMPXCHGB, + "CMPXCHGL", LTYPE3, ACMPXCHGL, + "CMPXCHGW", LTYPE3, ACMPXCHGW, + "DAA", LTYPE0, ADAA, + "DAS", LTYPE0, ADAS, + "DATA", LTYPED, ADATA, + "DECB", LTYPE1, ADECB, + "DECL", LTYPE1, ADECL, + "DECW", LTYPE1, ADECW, + "DIVB", LTYPE2, ADIVB, + "DIVL", LTYPE2, ADIVL, + "DIVW", LTYPE2, ADIVW, + "END", LTYPE0, AEND, + "ENTER", LTYPE2, AENTER, + "GLOBL", LTYPEG, AGLOBL, + "HLT", LTYPE0, AHLT, + "IDIVB", LTYPE2, AIDIVB, + "IDIVL", LTYPE2, AIDIVL, + "IDIVW", LTYPE2, AIDIVW, + "IMULB", LTYPE2, AIMULB, + "IMULL", LTYPE2, AIMULL, + "IMULW", LTYPE2, AIMULW, + "INB", LTYPE0, AINB, + "INL", LTYPE0, AINL, + "INW", LTYPE0, AINW, + "INCB", LTYPE1, AINCB, + "INCL", LTYPE1, AINCL, + "INCW", LTYPE1, AINCW, + "INSB", LTYPE0, AINSB, + "INSL", LTYPE0, AINSL, + "INSW", LTYPE0, AINSW, + "INT", LTYPE2, AINT, + "INTO", LTYPE0, AINTO, + "IRETL", LTYPE0, AIRETL, + "IRETW", LTYPE0, AIRETW, + + "JOS", LTYPER, AJOS, + "JO", LTYPER, AJOS, /* alternate */ + "JOC", LTYPER, AJOC, + "JNO", LTYPER, AJOC, /* alternate */ + "JCS", LTYPER, AJCS, + "JB", LTYPER, AJCS, /* alternate */ + "JC", LTYPER, AJCS, /* alternate */ + "JNAE", LTYPER, AJCS, /* alternate */ + "JLO", LTYPER, AJCS, /* alternate */ + "JCC", LTYPER, AJCC, + "JAE", LTYPER, AJCC, /* alternate */ + "JNB", LTYPER, AJCC, /* alternate */ + "JNC", LTYPER, AJCC, /* alternate */ + "JHS", LTYPER, AJCC, /* alternate */ + "JEQ", LTYPER, AJEQ, + "JE", LTYPER, AJEQ, /* alternate */ + "JZ", LTYPER, AJEQ, /* alternate */ + "JNE", LTYPER, AJNE, + "JNZ", LTYPER, AJNE, /* alternate */ + "JLS", LTYPER, AJLS, + "JBE", LTYPER, AJLS, /* alternate */ + "JNA", LTYPER, AJLS, /* alternate */ + "JHI", LTYPER, AJHI, + "JA", LTYPER, AJHI, /* alternate */ + "JNBE", LTYPER, AJHI, /* alternate */ + "JMI", LTYPER, AJMI, + "JS", LTYPER, AJMI, /* alternate */ + "JPL", LTYPER, AJPL, + "JNS", LTYPER, AJPL, /* alternate */ + "JPS", LTYPER, AJPS, + "JP", LTYPER, AJPS, /* alternate */ + "JPE", LTYPER, AJPS, /* alternate */ + "JPC", LTYPER, AJPC, + "JNP", LTYPER, AJPC, /* alternate */ + "JPO", LTYPER, AJPC, /* alternate */ + "JLT", LTYPER, AJLT, + "JL", LTYPER, AJLT, /* alternate */ + "JNGE", LTYPER, AJLT, /* alternate */ + "JGE", LTYPER, AJGE, + "JNL", LTYPER, AJGE, /* alternate */ + "JLE", LTYPER, AJLE, + "JNG", LTYPER, AJLE, /* alternate */ + "JGT", LTYPER, AJGT, + "JG", LTYPER, AJGT, /* alternate */ + "JNLE", LTYPER, AJGT, /* alternate */ + + "JCXZ", LTYPER, AJCXZ, + "JMP", LTYPEC, AJMP, + "LAHF", LTYPE0, ALAHF, + "LARL", LTYPE3, ALARL, + "LARW", LTYPE3, ALARW, + "LEAL", LTYPE3, ALEAL, + "LEAW", LTYPE3, ALEAW, + "LEAVEL", LTYPE0, ALEAVEL, + "LEAVEW", LTYPE0, ALEAVEW, + "LOCK", LTYPE0, ALOCK, + "LODSB", LTYPE0, ALODSB, + "LODSL", LTYPE0, ALODSL, + "LODSW", LTYPE0, ALODSW, + "LONG", LTYPE2, ALONG, + "LOOP", LTYPER, ALOOP, + "LOOPEQ", LTYPER, ALOOPEQ, + "LOOPNE", LTYPER, ALOOPNE, + "LSLL", LTYPE3, ALSLL, + "LSLW", LTYPE3, ALSLW, + "MOVB", LTYPE3, AMOVB, + "MOVL", LTYPEM, AMOVL, + "MOVW", LTYPEM, AMOVW, + "MOVBLSX", LTYPE3, AMOVBLSX, + "MOVBLZX", LTYPE3, AMOVBLZX, + "MOVBWSX", LTYPE3, AMOVBWSX, + "MOVBWZX", LTYPE3, AMOVBWZX, + "MOVWLSX", LTYPE3, AMOVWLSX, + "MOVWLZX", LTYPE3, AMOVWLZX, + "MOVSB", LTYPE0, AMOVSB, + "MOVSL", LTYPE0, AMOVSL, + "MOVSW", LTYPE0, AMOVSW, + "MULB", LTYPE2, AMULB, + "MULL", LTYPE2, AMULL, + "MULW", LTYPE2, AMULW, + "NEGB", LTYPE1, ANEGB, + "NEGL", LTYPE1, ANEGL, + "NEGW", LTYPE1, ANEGW, + "NOP", LTYPEN, ANOP, + "NOTB", LTYPE1, ANOTB, + "NOTL", LTYPE1, ANOTL, + "NOTW", LTYPE1, ANOTW, + "ORB", LTYPE3, AORB, + "ORL", LTYPE3, AORL, + "ORW", LTYPE3, AORW, + "OUTB", LTYPE0, AOUTB, + "OUTL", LTYPE0, AOUTL, + "OUTW", LTYPE0, AOUTW, + "OUTSB", LTYPE0, AOUTSB, + "OUTSL", LTYPE0, AOUTSL, + "OUTSW", LTYPE0, AOUTSW, + "PAUSE", LTYPEN, APAUSE, + "POPAL", LTYPE0, APOPAL, + "POPAW", LTYPE0, APOPAW, + "POPFL", LTYPE0, APOPFL, + "POPFW", LTYPE0, APOPFW, + "POPL", LTYPE1, APOPL, + "POPW", LTYPE1, APOPW, + "PUSHAL", LTYPE0, APUSHAL, + "PUSHAW", LTYPE0, APUSHAW, + "PUSHFL", LTYPE0, APUSHFL, + "PUSHFW", LTYPE0, APUSHFW, + "PUSHL", LTYPE2, APUSHL, + "PUSHW", LTYPE2, APUSHW, + "RCLB", LTYPE3, ARCLB, + "RCLL", LTYPE3, ARCLL, + "RCLW", LTYPE3, ARCLW, + "RCRB", LTYPE3, ARCRB, + "RCRL", LTYPE3, ARCRL, + "RCRW", LTYPE3, ARCRW, + "REP", LTYPE0, AREP, + "REPN", LTYPE0, AREPN, + "RET", LTYPE0, ARET, + "ROLB", LTYPE3, AROLB, + "ROLL", LTYPE3, AROLL, + "ROLW", LTYPE3, AROLW, + "RORB", LTYPE3, ARORB, + "RORL", LTYPE3, ARORL, + "RORW", LTYPE3, ARORW, + "SAHF", LTYPE0, ASAHF, + "SALB", LTYPE3, ASALB, + "SALL", LTYPE3, ASALL, + "SALW", LTYPE3, ASALW, + "SARB", LTYPE3, ASARB, + "SARL", LTYPE3, ASARL, + "SARW", LTYPE3, ASARW, + "SBBB", LTYPE3, ASBBB, + "SBBL", LTYPE3, ASBBL, + "SBBW", LTYPE3, ASBBW, + "SCASB", LTYPE0, ASCASB, + "SCASL", LTYPE0, ASCASL, + "SCASW", LTYPE0, ASCASW, + "SETCC", LTYPE1, ASETCC, + "SETCS", LTYPE1, ASETCS, + "SETEQ", LTYPE1, ASETEQ, + "SETGE", LTYPE1, ASETGE, + "SETGT", LTYPE1, ASETGT, + "SETHI", LTYPE1, ASETHI, + "SETLE", LTYPE1, ASETLE, + "SETLS", LTYPE1, ASETLS, + "SETLT", LTYPE1, ASETLT, + "SETMI", LTYPE1, ASETMI, + "SETNE", LTYPE1, ASETNE, + "SETOC", LTYPE1, ASETOC, + "SETOS", LTYPE1, ASETOS, + "SETPC", LTYPE1, ASETPC, + "SETPL", LTYPE1, ASETPL, + "SETPS", LTYPE1, ASETPS, + "CDQ", LTYPE0, ACDQ, + "CWD", LTYPE0, ACWD, + "SHLB", LTYPE3, ASHLB, + "SHLL", LTYPES, ASHLL, + "SHLW", LTYPES, ASHLW, + "SHRB", LTYPE3, ASHRB, + "SHRL", LTYPES, ASHRL, + "SHRW", LTYPES, ASHRW, + "STC", LTYPE0, ASTC, + "STD", LTYPE0, ASTD, + "STI", LTYPE0, ASTI, + "STOSB", LTYPE0, ASTOSB, + "STOSL", LTYPE0, ASTOSL, + "STOSW", LTYPE0, ASTOSW, + "SUBB", LTYPE3, ASUBB, + "SUBL", LTYPE3, ASUBL, + "SUBW", LTYPE3, ASUBW, + "SYSCALL", LTYPE0, ASYSCALL, + "TESTB", LTYPE3, ATESTB, + "TESTL", LTYPE3, ATESTL, + "TESTW", LTYPE3, ATESTW, + "TEXT", LTYPET, ATEXT, + "VERR", LTYPE2, AVERR, + "VERW", LTYPE2, AVERW, + "WAIT", LTYPE0, AWAIT, + "WORD", LTYPE2, AWORD, + "XADDB", LTYPE3, AXADDB, + "XADDL", LTYPE3, AXADDL, + "XADDW", LTYPE3, AXADDW, + "XCHGB", LTYPE3, AXCHGB, + "XCHGL", LTYPE3, AXCHGL, + "XCHGW", LTYPE3, AXCHGW, + "XLAT", LTYPE2, AXLAT, + "XORB", LTYPE3, AXORB, + "XORL", LTYPE3, AXORL, + "XORW", LTYPE3, AXORW, + + "CMOVLCC", LTYPE3, ACMOVLCC, + "CMOVLCS", LTYPE3, ACMOVLCS, + "CMOVLEQ", LTYPE3, ACMOVLEQ, + "CMOVLGE", LTYPE3, ACMOVLGE, + "CMOVLGT", LTYPE3, ACMOVLGT, + "CMOVLHI", LTYPE3, ACMOVLHI, + "CMOVLLE", LTYPE3, ACMOVLLE, + "CMOVLLS", LTYPE3, ACMOVLLS, + "CMOVLLT", LTYPE3, ACMOVLLT, + "CMOVLMI", LTYPE3, ACMOVLMI, + "CMOVLNE", LTYPE3, ACMOVLNE, + "CMOVLOC", LTYPE3, ACMOVLOC, + "CMOVLOS", LTYPE3, ACMOVLOS, + "CMOVLPC", LTYPE3, ACMOVLPC, + "CMOVLPL", LTYPE3, ACMOVLPL, + "CMOVLPS", LTYPE3, ACMOVLPS, + "CMOVWCC", LTYPE3, ACMOVWCC, + "CMOVWCS", LTYPE3, ACMOVWCS, + "CMOVWEQ", LTYPE3, ACMOVWEQ, + "CMOVWGE", LTYPE3, ACMOVWGE, + "CMOVWGT", LTYPE3, ACMOVWGT, + "CMOVWHI", LTYPE3, ACMOVWHI, + "CMOVWLE", LTYPE3, ACMOVWLE, + "CMOVWLS", LTYPE3, ACMOVWLS, + "CMOVWLT", LTYPE3, ACMOVWLT, + "CMOVWMI", LTYPE3, ACMOVWMI, + "CMOVWNE", LTYPE3, ACMOVWNE, + "CMOVWOC", LTYPE3, ACMOVWOC, + "CMOVWOS", LTYPE3, ACMOVWOS, + "CMOVWPC", LTYPE3, ACMOVWPC, + "CMOVWPL", LTYPE3, ACMOVWPL, + "CMOVWPS", LTYPE3, ACMOVWPS, + + "FMOVB", LTYPE3, AFMOVB, + "FMOVBP", LTYPE3, AFMOVBP, + "FMOVD", LTYPE3, AFMOVD, + "FMOVDP", LTYPE3, AFMOVDP, + "FMOVF", LTYPE3, AFMOVF, + "FMOVFP", LTYPE3, AFMOVFP, + "FMOVL", LTYPE3, AFMOVL, + "FMOVLP", LTYPE3, AFMOVLP, + "FMOVV", LTYPE3, AFMOVV, + "FMOVVP", LTYPE3, AFMOVVP, + "FMOVW", LTYPE3, AFMOVW, + "FMOVWP", LTYPE3, AFMOVWP, + "FMOVX", LTYPE3, AFMOVX, + "FMOVXP", LTYPE3, AFMOVXP, + "FCMOVCC", LTYPE3, AFCMOVCC, + "FCMOVCS", LTYPE3, AFCMOVCS, + "FCMOVEQ", LTYPE3, AFCMOVEQ, + "FCMOVHI", LTYPE3, AFCMOVHI, + "FCMOVLS", LTYPE3, AFCMOVLS, + "FCMOVNE", LTYPE3, AFCMOVNE, + "FCMOVNU", LTYPE3, AFCMOVNU, + "FCMOVUN", LTYPE3, AFCMOVUN, + "FCOMB", LTYPE3, AFCOMB, + "FCOMBP", LTYPE3, AFCOMBP, + "FCOMD", LTYPE3, AFCOMD, + "FCOMDP", LTYPE3, AFCOMDP, + "FCOMDPP", LTYPE3, AFCOMDPP, + "FCOMF", LTYPE3, AFCOMF, + "FCOMFP", LTYPE3, AFCOMFP, + "FCOMI", LTYPE3, AFCOMI, + "FCOMIP", LTYPE3, AFCOMIP, + "FCOML", LTYPE3, AFCOML, + "FCOMLP", LTYPE3, AFCOMLP, + "FCOMW", LTYPE3, AFCOMW, + "FCOMWP", LTYPE3, AFCOMWP, + "FUCOM", LTYPE3, AFUCOM, + "FUCOMI", LTYPE3, AFUCOMI, + "FUCOMIP", LTYPE3, AFUCOMIP, + "FUCOMP", LTYPE3, AFUCOMP, + "FUCOMPP", LTYPE3, AFUCOMPP, + "FADDW", LTYPE3, AFADDW, + "FADDL", LTYPE3, AFADDL, + "FADDF", LTYPE3, AFADDF, + "FADDD", LTYPE3, AFADDD, + "FADDDP", LTYPE3, AFADDDP, + "FSUBDP", LTYPE3, AFSUBDP, + "FSUBW", LTYPE3, AFSUBW, + "FSUBL", LTYPE3, AFSUBL, + "FSUBF", LTYPE3, AFSUBF, + "FSUBD", LTYPE3, AFSUBD, + "FSUBRDP", LTYPE3, AFSUBRDP, + "FSUBRW", LTYPE3, AFSUBRW, + "FSUBRL", LTYPE3, AFSUBRL, + "FSUBRF", LTYPE3, AFSUBRF, + "FSUBRD", LTYPE3, AFSUBRD, + "FMULDP", LTYPE3, AFMULDP, + "FMULW", LTYPE3, AFMULW, + "FMULL", LTYPE3, AFMULL, + "FMULF", LTYPE3, AFMULF, + "FMULD", LTYPE3, AFMULD, + "FDIVDP", LTYPE3, AFDIVDP, + "FDIVW", LTYPE3, AFDIVW, + "FDIVL", LTYPE3, AFDIVL, + "FDIVF", LTYPE3, AFDIVF, + "FDIVD", LTYPE3, AFDIVD, + "FDIVRDP", LTYPE3, AFDIVRDP, + "FDIVRW", LTYPE3, AFDIVRW, + "FDIVRL", LTYPE3, AFDIVRL, + "FDIVRF", LTYPE3, AFDIVRF, + "FDIVRD", LTYPE3, AFDIVRD, + "FXCHD", LTYPE3, AFXCHD, + "FFREE", LTYPE1, AFFREE, + "FLDCW", LTYPE2, AFLDCW, + "FLDENV", LTYPE1, AFLDENV, + "FRSTOR", LTYPE2, AFRSTOR, + "FSAVE", LTYPE1, AFSAVE, + "FSTCW", LTYPE1, AFSTCW, + "FSTENV", LTYPE1, AFSTENV, + "FSTSW", LTYPE1, AFSTSW, + "F2XM1", LTYPE0, AF2XM1, + "FABS", LTYPE0, AFABS, + "FCHS", LTYPE0, AFCHS, + "FCLEX", LTYPE0, AFCLEX, + "FCOS", LTYPE0, AFCOS, + "FDECSTP", LTYPE0, AFDECSTP, + "FINCSTP", LTYPE0, AFINCSTP, + "FINIT", LTYPE0, AFINIT, + "FLD1", LTYPE0, AFLD1, + "FLDL2E", LTYPE0, AFLDL2E, + "FLDL2T", LTYPE0, AFLDL2T, + "FLDLG2", LTYPE0, AFLDLG2, + "FLDLN2", LTYPE0, AFLDLN2, + "FLDPI", LTYPE0, AFLDPI, + "FLDZ", LTYPE0, AFLDZ, + "FNOP", LTYPE0, AFNOP, + "FPATAN", LTYPE0, AFPATAN, + "FPREM", LTYPE0, AFPREM, + "FPREM1", LTYPE0, AFPREM1, + "FPTAN", LTYPE0, AFPTAN, + "FRNDINT", LTYPE0, AFRNDINT, + "FSCALE", LTYPE0, AFSCALE, + "FSIN", LTYPE0, AFSIN, + "FSINCOS", LTYPE0, AFSINCOS, + "FSQRT", LTYPE0, AFSQRT, + "FTST", LTYPE0, AFTST, + "FXAM", LTYPE0, AFXAM, + "FXTRACT", LTYPE0, AFXTRACT, + "FYL2X", LTYPE0, AFYL2X, + "FYL2XP1", LTYPE0, AFYL2XP1, + + 0 +}; + +void +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; + iofree = I; + peekc = IGN; + nhunk = 0; + for(i=0; i<NHASH; i++) + hash[i] = S; + for(i=0; itab[i].name; i++) { + s = slookup(itab[i].name); + if(s->type != LNAME) + yyerror("double initialization %s", itab[i].name); + 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 +checkscale(int scale) +{ + + switch(scale) { + case 1: + case 2: + case 4: + case 8: + return; + } + yyerror("scale must be 1248: %d", scale); +} + +void +syminit(Sym *s) +{ + + s->type = LNAME; + s->value = 0; +} + +void +cclean(void) +{ + Gen2 g2; + + g2.from = nullgen; + g2.to = nullgen; + outcode(AEND, &g2); + Bflush(&obuf); +} + +void +zname(char *n, int t, int s) +{ + + Bputc(&obuf, ANAME); /* as(2) */ + 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) +{ + 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; + Bputc(&obuf, l); + Bputc(&obuf, l>>8); + Bputc(&obuf, l>>16); + Bputc(&obuf, l>>24); + } + if(t & T_OFFSET2) { + l = a->offset2; + Bputc(&obuf, l); + Bputc(&obuf, l>>8); + Bputc(&obuf, l>>16); + Bputc(&obuf, l>>24); + } + if(t & T_SYM) /* implies sym */ + Bputc(&obuf, s); + if(t & T_FCONST) { + ieeedtod(&e, a->dval); + l = e.l; + Bputc(&obuf, l); + Bputc(&obuf, l>>8); + Bputc(&obuf, l>>16); + Bputc(&obuf, l>>24); + l = e.h; + Bputc(&obuf, l); + Bputc(&obuf, l>>8); + Bputc(&obuf, l>>16); + Bputc(&obuf, l>>24); + return; + } + if(t & T_SCONST) { + n = a->sval; + for(i=0; i<NSNAME; i++) { + Bputc(&obuf, *n); + n++; + } + return; + } + if(t & T_TYPE) + Bputc(&obuf, a->type); +} + +void +outcode(int a, Gen2 *g2) +{ + int sf, st, t; + Sym *s; + + 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; + } + Bputc(&obuf, a); + Bputc(&obuf, a>>8); + Bputc(&obuf, stmtline); + Bputc(&obuf, stmtline>>8); + Bputc(&obuf, stmtline>>16); + Bputc(&obuf, stmtline>>24); + zaddr(&g2->from, sf); + zaddr(&g2->to, st); + +out: + if(a != AGLOBL && a != ADATA) + pc++; +} + +void +outhist(void) +{ + Gen g; + Hist *h; + char *p, *q, *op, c; + int n; + + 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; + + Bputc(&obuf, AHISTORY); + Bputc(&obuf, AHISTORY>>8); + 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); + } +} + +#include "../cc/lexbody" +#include "../cc/macbody" |