1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231 |
- /* NCR53c8xx assembler */
- %{
- #include <lib9.h>
- #include <stdio.h>
- #include <ctype.h>
- #include "na.h"
- #define COND_WAIT (1L << 16)
- #define COND_TRUE (1L << 19)
- #define COND_INTFLY (1L << 20)
- #define COND_CARRY (1L << 21)
- #define COND_REL (1L << 23)
- #define COND_PHASE (1L << 17)
- #define COND_DATA (1L << 18)
- #define IO_REL (1L << 26)
- #define MOVE_MODE (1L << 27)
- int yylex(void);
- int yyparse(void);
- void assemble(void);
- void yyerror(char *, ...);
- void yywarn(char *, ...);
- void p2error(int line, char *);
- struct addr {
- int type; /* 0 - direct, 1 - indirect 2 - table indirect */
- unsigned long offset;
- };
- typedef enum Type { Const, Addr, Table, Extern, Reg, Unknown, Error } Type;
- struct sym {
- char *name;
- int set;
- Type t;
- long value;
- struct sym *next;
- };
- struct sym *findsym(char *name);
- struct sym *symlist;
- void newsym(struct sym *s, Type t, long v);
- struct binary {
- char len;
- unsigned long data[3];
- unsigned char patch[3];
- };
- #define MAXCPPOPTS 30
- #define MAX_PATCHES 1000
- struct na_patch patch[MAX_PATCHES];
- int patches;
- struct binary out;
- struct expval {
- Type t;
- long value;
- };
- struct expval eval(struct expval a, struct expval b, char op);
- int patchtype(Type t);
- void fixup(void);
- unsigned dot;
- unsigned externs;
- int errors, warnings;
- struct sym *externp[100];
- void regmove(unsigned char src_reg, unsigned char op,
- unsigned char dst_reg, struct expval *imm);
- void preprocess(char *in, FILE *out);
- int mk24bitssigned(long *l);
- long mkreladdr(long value, int len);
- long chkreladdr(int d, struct expval *e, int len, long relrv);
- int pass2;
- FILE *in_f;
- int yyline = 0;
- char yyfilename[200];
- char line[500];
- char *cppopts[MAXCPPOPTS];
- int ncppopts;
- int wflag;
- %}
- %union {
- long n;
- struct sym *s;
- struct expval e;
- }
- %token NUM MOVE WHEN SYMBOL SELECT WAIT DISCONNECT RESELECT SET CLEAR
- %token DATA_OUT DATA_IN COMMAND STATUS RESERVED_OUT RESERVED_IN MESSAGE_OUT
- %token MESSAGE_IN WITH ATN FAIL CARRY TARGET ACK COMMENT TO
- %token SCNTL0 SCNTL1 SCNTL2 SCNTL3 SCID SXFER SDID GPREG
- %token SFBR SOCL SSID SBCL DSTAT SSTAT0 SSTAT1 SSTAT2
- %token ISTAT CTEST0 CTEST1 CTEST2 CTEST3 TEMP DFIFO CTEST4 CTEST5 CTEST6
- %token DBC DCMD DNAD DSP DSPS DMODE DIEN DWT DCNTL ADDER
- %token SIEN0 SIEN1 SIST0 SIST1 SLPAR MACNTL GPCNTL STIME0 STIME1 RESPID
- %token STEST0 STEST1 STEST2 STEST3 SIDL SODL SBDL
- %token SHL SHR AND OR XOR ADD ADDC
- %token JUMP CALL RETURN INT INTFLY NOT ABSOLUTE MASK IF REL PTR
- %token TABLE FROM MEMORY NOP EXTERN
- %token SCRATCHA0 SCRATCHA1 SCRATCHA2 SCRATCHA3
- %token SCRATCHB0 SCRATCHB1 SCRATCHB2 SCRATCHB3
- %token SCRATCHC0 SCRATCHC1 SCRATCHC2 SCRATCHC3
- %token DSA0 DSA1 DSA2 DSA3
- %token DEFW
- %left '-' '+'
- %left '*' '/'
- %left NEG /* negation--unary minus */
- %right '^' /* exponentiation */
- %type <n> NUM phase .atn set_list set_bit regA reg
- %type <n> set_cmd .cond condsfbr condphase
- %type <n> jump_or_call .ptr
- %type <s> SYMBOL
- %type <e> exp byteexp regexp
- /* Grammar follows */
- %%
- input: /* empty string */
- | input line
- ;
- line: .label .opcode .comment '\n'
- {
- if (pass2) {
- int x;
- for (x = 0; x < out.len; x++) {
- printf("/* %.4x */ 0x%.8lxL,",
- dot, out.data[x]);
- if (x == 0) {
- printf(" /*\t");
- fwrite(line,
- strlen(line) - 1, 1, stdout);
- printf(" */");
- }
- printf("\n");
- if (out.patch[x]) {
- patch[patches].lwoff = dot / 4;
- patch[patches].type = out.patch[x];
- patches++;
- }
- dot += 4;
- }
- }
- else
- dot += 4 * out.len;
- }
- | ABSOLUTE SYMBOL '=' exp .comment '\n'
- {
- setsym($2, $4.t, $4.value);
- if (pass2) {
- printf("\t\t\t/*\t");
- fwrite(line, strlen(line) - 1, 1, stdout);
- printf(" */\n");
- }
- }
- | SYMBOL '=' exp .comment '\n'
- {
- setsym($1, $3.t, $3.value);
- if (pass2) {
- printf("\t\t\t/*\t");
- fwrite(line, strlen(line) - 1, 1, stdout);
- printf(" */\n");
- }
- }
- | EXTERN SYMBOL {
- if (pass2) {
- printf("\t\t\t/*\t");
- fwrite(line, strlen(line) - 1, 1, stdout);
- printf(" */\n");
- }
- else {
- if (!pass2)
- externp[externs] = $2;
- setsym($2, Extern, externs++);
- }
- }
- ;
- .comment: COMMENT
- | /* nothing */
- ;
- .label: SYMBOL ':' {
- if ($1->t != Unknown)
- {
- if (!pass2)
- yyerror("multiply defined symbol");
- }
- else {
- $1->t = Addr;
- $1->value = dot;
- }
- }
- | /* nothing */
- ;
- set_cmd: SET { $$ = 3; }
- | CLEAR { $$ = 4; }
- ;
- set_bit: CARRY { $$ = 0x400; }
- | TARGET { $$ = 0x200; }
- | ACK { $$ = 0x40; }
- | ATN { $$ = 0x8; }
- ;
-
- set_list: set_list ',' set_bit { $$ = $1 | $3; }
- | set_list AND set_bit { $$ = $1 | $3; }
- | set_bit { $$ = $1; }
- ;
- opcode: set_cmd set_list {
- out.len = 2;
- out.data[0] = (1L << 30) | ((long)$1 << 27) | $2;
- out.data[1] = 0;
- out.patch[0] = out.patch[1] = 0;
- }
- | DISCONNECT
- {
- out.len = 2;
- out.data[0] = 0x48020000L;
- out.data[1] = 0;
- out.patch[0] = out.patch[1] = 0;
- }
- | INT exp .cond {
- out.len = 2;
- out.data[0] = $3 | 0x98000000L;
- out.data[1] = $2.value;
- out.patch[0] = out.patch[1] = 0;
- }
- | INTFLY exp .cond {
- out.len = 2;
- out.data[0] = $3 | 0x98000000L | COND_INTFLY;
- out.data[1] = $2.value;
- out.patch[0] = out.patch[1] = 0;
- }
- | jump_or_call exp .cond {
- out.len = 2;
- out.data[0] = $1 | $3 | chkreladdr(1, &$2, 2, COND_REL);
- out.patch[0] = 0;
- }
- | jump_or_call REL '(' exp ')' .cond {
- out.len = 2;
- out.data[0] = $1 | $6 | COND_REL;
- out.data[1] = mkreladdr($4.value, 2);
- out.patch[0] = out.patch[1] = 0;
- }
- | MOVE exp ',' .ptr regexp ',' with_or_when phase {
- out.len = 2;
- out.data[0] = ($8 << 24) | $2.value | ($4 << 29) | MOVE_MODE;
- out.data[1] = $5.value;
- out.patch[0] = 0;
- out.patch[1] = patchtype($5.t);
- }
- | MOVE FROM exp ',' with_or_when phase {
- out.len = 2;
- out.data[0] = ($6 << 24) | (1L << 28) | MOVE_MODE;
- out.data[1] = $3.value;
- out.patch[0] = 0;
- out.patch[1] = patchtype($3.t);
- }
- | MOVE MEMORY exp ',' regexp ',' regexp {
- out.len = 3;
- out.data[0] = 0xc0000000L | $3.value;
- out.data[1] = $5.value;
- out.data[2] = $7.value;
- out.patch[0] = 0;
- out.patch[1] = patchtype($5.t);
- out.patch[2] = patchtype($7.t);
- }
- | MOVE regA TO regA { regmove($2, 2, $4, 0); } /* do reg to sfbr moves using or 0 */
- | MOVE exp TO regA { regmove($4, 0, $4, &$2); }
- | MOVE regA '|' exp TO regA { regmove($2, 2, $6, &$4); }
- | MOVE regA '&' exp TO regA { regmove($2, 4, $6, &$4); }
- | MOVE regA '+' exp TO regA { regmove($2, 6, $6, &$4); }
- | MOVE regA '-' exp TO regA { regmove($2, 6, $6, &$4); }
- | MOVE regA '+' exp TO regA WITH CARRY {
- regmove($2, 7, $6, &$4);
- }
- | MOVE regA '-' exp TO regA WITH CARRY {
- $4.value = -$4.value;
- regmove($2, 7, $6, &$4);
- }
- | MOVE regA SHL TO regA { regmove($2, 1, $5, 0); }
- | MOVE regA SHR TO regA { regmove($2, 5, $5, 0); }
- | MOVE regA XOR exp TO regA { regmove($2, 3, $6, &$4); }
- | NOP {
- out.len = 2;
- out.data[0] = 0x80000000L;
- out.data[1] = 0;
- out.patch[0] = out.patch[1] = 0;
- }
- | RESELECT exp ',' exp {
- out.len = 2;
- out.data[0] = 0x40000000L | ((long)$2.value << 16) | (1L << 9) | chkreladdr(1, &$4, 2, IO_REL);
- out.patch[0] = 0;
- }
- | RESELECT exp ',' REL '(' exp ')' {
- out.len = 2;
- out.data[0] = 0x40000000L | IO_REL
- | ((long)$2.value << 16) | (1L << 9);
- out.data[1] = mkreladdr($6.value, 2);
- out.patch[0] = out.patch[1] = 0;
- }
- | RESELECT FROM exp ',' exp {
- out.len = 2;
- out.data[0] = 0x40000000L | (1L << 25) | $3.value | chkreladdr(1, &$5, 2, IO_REL);
- out.patch[0] = 5;
- }
- | RESELECT FROM exp ',' REL '(' exp ')' {
- out.len = 2;
- out.data[0] = 0x40000000L | (1L << 25) | IO_REL | $3.value;
- out.patch[0] = 5;
- out.data[1] = mkreladdr($7.value, 2);
- out.patch[1] = 0;
- }
- | RETURN .cond {
-
- out.len = 2;
- out.data[0] = 0x90000000L | $2;
- out.data[1] = 0;
- out.patch[0] = out.patch[1] = 0;
- }
- | SELECT .atn exp ',' exp {
- out.len = 2;
- out.data[0] =
- 0x40000000L | ((long)$3.value << 16) | (1L << 9) | $2 | chkreladdr(1, &$5, 2, IO_REL);
- out.patch[0] = 0;
- }
- | SELECT .atn exp ',' REL '(' exp ')' {
- out.len = 2;
- out.data[0] = 0x40000000L | (1L << 26)
- | ((long)$3.value << 16) | (1L << 9) | $2;
- out.data[1] = mkreladdr($7.value, 2);
- out.patch[0] = out.patch[1] = 0;
- }
- | SELECT .atn FROM exp ',' exp {
- out.len = 2;
- out.data[0] = 0x40000000L | (1L << 25) | $4.value | $2 | chkreladdr(1, &$6, 2, IO_REL);
- out.patch[0] = 5;
- }
- | SELECT .atn FROM exp ',' REL '(' exp ')' {
- out.len = 2;
- out.data[0] = 0x40000000L | (1L << 25) | IO_REL | $4.value | $2;
- out.patch[0] = 5;
- out.data[1] = mkreladdr($8.value, 2);
- out.patch[1] = 0;
- }
- | WAIT DISCONNECT {
- out.len = 2;
- out.data[0] = 0x48000000L;
- out.data[1] = 0;
- out.patch[0] = out.patch[1] = 0;
- }
- | WAIT RESELECT exp {
- out.len = 2;
- out.data[0] = 0x50000000L | chkreladdr(1, &$3, 2, IO_REL);
- out.patch[0] = 0;
- }
- | WAIT RESELECT REL '(' exp ')' {
- out.len = 2;
- out.data[0] = 0x50000000L | (1L << 26);
- out.data[1] = mkreladdr($5.value, 2);
- out.patch[0] = out.patch[1] = 0;
- }
- | WAIT SELECT exp {
- out.len = 2;
- out.data[0] = 0x40000000L | (1L << 9) | chkreladdr(1, &$3, 2, IO_REL);
- out.patch[0] = 0;
- }
- | WAIT SELECT REL '(' exp ')' {
- out.len = 2;
- out.data[0] = 0x40000000L | (1L << 26) | (1L << 9);
- out.data[1] = mkreladdr($5.value, 2);
- out.patch[0] = out.patch[1] = 0;
- }
- | DEFW exp {
- out.len = 1;
- out.data[0] = $2.value;
- out.patch[0] = patchtype($2.t);
- }
- ;
- .ptr: PTR { $$ = 1; }
- | { $$ = 0; }
- ;
- with_or_when: WITH
- | WHEN
- ;
-
- jump_or_call: JUMP { $$ = 0x80000000L; }
- | CALL { $$ = 0x88000000L; }
- ;
- condsfbr: byteexp { $$ = $1.value | COND_DATA; }
- | byteexp AND MASK byteexp { $$ = ($4.value << 8) | $1.value | COND_DATA; }
- ;
- condphase: phase { $$ = ($1 << 24) | COND_PHASE; }
- .cond: ',' IF ATN { $$ = COND_TRUE; }
- | ',' IF condphase { $$ = $3 | COND_TRUE; }
- | ',' IF CARRY { $$ = COND_CARRY | COND_TRUE; }
- | ',' IF condsfbr { $$ = $3 | COND_TRUE; }
- | ',' IF ATN AND condsfbr { $$ = $5 | COND_TRUE; }
- | ',' IF condphase AND condsfbr { $$ = $3 | $5 | COND_TRUE; }
- | ',' WHEN condphase { $$ = $3 | COND_WAIT | COND_TRUE; }
- | ',' WHEN CARRY { $$ = COND_CARRY | COND_WAIT | COND_TRUE; }
- | ',' WHEN condsfbr { $$ = $3 | COND_WAIT | COND_TRUE; }
- | ',' WHEN condphase AND condsfbr { $$ = $3 | $5 | COND_WAIT | COND_TRUE; }
- | ',' IF NOT ATN { $$ = 0; }
- | ',' IF NOT condphase { $$ = $4; }
- | ',' IF NOT CARRY { $$ = COND_CARRY; }
- | ',' IF NOT condsfbr { $$ = $4; }
- | ',' IF NOT ATN OR condsfbr { $$ = $6; }
- | ',' IF NOT condphase OR condsfbr { $$ = $4 | $6; }
- | ',' WHEN NOT condphase { $$ = $4 | COND_WAIT; }
- | ',' WHEN NOT CARRY { $$ = COND_CARRY | COND_WAIT; }
- | ',' WHEN NOT condsfbr { $$ = $4 | COND_WAIT; }
- | ',' WHEN NOT condphase OR condsfbr { $$ = $4 | $6 | COND_WAIT; }
- | { $$ = COND_TRUE; }
- ;
- .opcode: opcode
- | { out.len = 0; }
- ;
- regA: reg
- | SFBR { $$ = 8; }
- ;
- reg: SCNTL0 { $$ = 0; }
- | SCNTL1 { $$ = 1; }
- | SCNTL2 { $$ = 2; }
- | SCNTL3 { $$ = 3; }
- | SCID { $$ = 4; }
- | SXFER { $$ = 5; }
- | SDID { $$ = 6; }
- | GPREG { $$ = 7; }
- | SOCL { $$ = 9; }
- | SSID { $$ = 0xa; }
- | SBCL { $$ = 0xb; }
- | DSTAT { $$ = 0xc; }
- | SSTAT0 { $$ = 0xd; }
- | SSTAT1 { $$ = 0xe; }
- | SSTAT2 { $$ = 0xf; }
- | DSA0 { $$ = 0x10; }
- | DSA1 { $$ = 0x11; }
- | DSA2 { $$ = 0x12; }
- | DSA3 { $$ = 0x13; }
- | ISTAT { $$ = 0x14; }
- | CTEST0 { $$ = 0x18; }
- | CTEST1 { $$ = 0x19; }
- | CTEST2 { $$ = 0x1a; }
- | CTEST3 { $$ = 0x1b; }
- | TEMP { $$ = 0x1c; }
- | DFIFO { $$ = 0x20; }
- | CTEST4 { $$ = 0x21; }
- | CTEST5 { $$ = 0x22; }
- | CTEST6 { $$ = 0x23; }
- | DBC { $$ = 0x24; }
- | DCMD { $$ = 0x27; }
- | DNAD { $$ = 0x28; }
- | DSP { $$ = 0x2c; }
- | DSPS { $$ = 0x30; }
- | SCRATCHA0 { $$ = 0x34; }
- | SCRATCHA1 { $$ = 0x35; }
- | SCRATCHA2 { $$ = 0x36; }
- | SCRATCHA3 { $$ = 0x37; }
- | DMODE { $$ = 0x38; }
- | DIEN { $$ = 0x39; }
- | DWT { $$ = 0x3a; }
- | DCNTL { $$ = 0x3b; }
- | ADDER { $$ = 0x3c; }
- | SIEN0 { $$ = 0x40; }
- | SIEN1 { $$ = 0x41; }
- | SIST0 { $$ = 0x42; }
- | SIST1 { $$ = 0x43; }
- | SLPAR { $$ = 0x44; }
- | MACNTL { $$ = 0x46; }
- | GPCNTL { $$ = 0x47; }
- | STIME0 { $$ = 0x48; }
- | STIME1 { $$ = 0x49; }
- | RESPID { $$ = 0x4a; }
- | STEST0 { $$ = 0x4c; }
- | STEST1 { $$ = 0x4d; }
- | STEST2 { $$ = 0x4e; }
- | STEST3 { $$ = 0x4f; }
- | SIDL { $$ = 0x50; }
- | SODL { $$ = 0x54; }
- | SBDL { $$ = 0x58; }
- | SCRATCHB0 { $$ = 0x5c; }
- | SCRATCHB1 { $$ = 0x5d; }
- | SCRATCHB2 { $$ = 0x5e; }
- | SCRATCHB3 { $$ = 0x5f; }
- | SCRATCHC0 { $$ = 0x60; }
- | SCRATCHC1 { $$ = 0x61; }
- | SCRATCHC2 { $$ = 0x62; }
- | SCRATCHC3 { $$ = 0x63; }
- ;
- .atn: ATN { $$ = (1 << 24); }
- | /* nothing */ { $$ = 0; }
- ;
- phase: DATA_OUT { $$ = 0; }
- | DATA_IN { $$ = 1; }
- | COMMAND { $$ = 2; }
- | STATUS { $$ = 3; }
- | RESERVED_OUT { $$ = 4; }
- | RESERVED_IN { $$ = 5; }
- | MESSAGE_OUT { $$ = 6; }
- | MESSAGE_IN { $$ = 7; }
- ;
- byteexp: exp
- {
- if (pass2 && ($1.value < 0 || $1.value > 255)) {
- if (wflag)
- yywarn("conversion causes truncation");
- $$.value = $1.value & 0xff;
- }
- else
- $$.value = $1.value;
- }
- ;
- regexp: exp
- | regA { $$.t = Reg; $$.value = $1; }
- ;
- exp: NUM { $$.t = Const; $$.value = $1; }
- | SYMBOL {
- $$.t = $1->t; $$.value = $1->value;
- if (pass2 && $1->t == Unknown)
- {
- yyerror("Undefined symbol %s", $1->name);
- $1->t = Error;
- $1->value = 0;
- $$.t = Error;
- $$.value = 0;
- }
- }
- | exp '+' exp { $$ = eval($1, $3, '+'); }
- | exp '-' exp { $$ = eval($1, $3, '-'); }
- | exp '*' exp { $$ = eval($1, $3, '*'); }
- | exp '/' exp { $$ = eval($1, $3, '/'); }
- | '-' exp %prec NEG { $$ = eval($2, $2, '_'); }
- | '(' exp ')' { $$ = $2; }
- | '~' exp %prec NEG { $$ = eval($2, $2, '~'); }
- ;
- %%
- struct {
- char *name;
- int tok;
- } toktab[] =
- {
- { "when", WHEN },
- { "data_out", DATA_OUT },
- { "data_in", DATA_IN },
- { "msg_out", MESSAGE_OUT },
- { "msg_in", MESSAGE_IN },
- { "cmd", COMMAND },
- { "command", COMMAND },
- { "status", STATUS },
- { "move", MOVE },
- { "select", SELECT },
- { "reselect", RESELECT },
- { "disconnect", DISCONNECT },
- { "wait", WAIT },
- { "set", SET },
- { "clear", CLEAR },
- { "with", WITH },
- { "atn", ATN },
- { "fail", FAIL },
- { "carry", CARRY },
- { "target", TARGET },
- { "ack", ACK },
- { "scntl0", SCNTL0 },
- { "scntl1", SCNTL1 },
- { "scntl2", SCNTL2 },
- { "scntl3", SCNTL3 },
- { "scid", SCID },
- { "sxfer", SXFER },
- { "sdid", SDID },
- { "gpreg", GPREG },
- { "sfbr", SFBR },
- { "socl", SOCL },
- { "ssid", SSID },
- { "sbcl", SBCL },
- { "dstat", DSTAT },
- { "sstat0", SSTAT0 },
- { "sstat1", SSTAT1 },
- { "sstat2", SSTAT2 },
- { "dsa", DSA0 },
- { "dsa0", DSA0 },
- { "dsa1", DSA1 },
- { "dsa2", DSA2 },
- { "dsa3", DSA3 },
- { "istat", ISTAT },
- { "ctest0", CTEST0 },
- { "ctest1", CTEST1 },
- { "ctest2", CTEST2 },
- { "ctest3", CTEST3 },
- { "temp", TEMP },
- { "dfifo", DFIFO },
- { "ctest4", CTEST4 },
- { "ctest5", CTEST5 },
- { "ctest6", CTEST6 },
- { "dbc", DBC },
- { "dcmd", DCMD },
- { "dnad", DNAD },
- { "dsp", DSP },
- { "dsps", DSPS },
- { "scratcha", SCRATCHA0 },
- { "scratcha0", SCRATCHA0 },
- { "scratcha1", SCRATCHA1 },
- { "scratcha2", SCRATCHA2 },
- { "scratcha3", SCRATCHA3 },
- { "dmode", DMODE },
- { "dien", DIEN },
- { "dwt", DWT },
- { "dcntl", DCNTL },
- { "adder", ADDER },
- { "sien0", SIEN0 },
- { "sien1", SIEN1 },
- { "sist0", SIST0 },
- { "sist1", SIST1 },
- { "slpar", SLPAR },
- { "macntl", MACNTL },
- { "gpcntl", GPCNTL },
- { "stime0", STIME0 },
- { "stime1", STIME1 },
- { "respid", RESPID },
- { "stest0", STEST0 },
- { "stest1", STEST1 },
- { "stest2", STEST2 },
- { "stest3", STEST3 },
- { "sidl", SIDL },
- { "sodl", SODL },
- { "sbdl", SBDL },
- { "scratchb", SCRATCHB0 },
- { "scratchb0", SCRATCHB0 },
- { "scratchb1", SCRATCHB1 },
- { "scratchb2", SCRATCHB2 },
- { "scratchb3", SCRATCHB3 },
- { "scratchc", SCRATCHC0 },
- { "scratchc0", SCRATCHC0 },
- { "scratchc1", SCRATCHC1 },
- { "scratchc2", SCRATCHC2 },
- { "scratchc3", SCRATCHC3 },
- { "add", ADD },
- { "addc", ADDC },
- { "and", AND },
- { "or", OR },
- { "xor", XOR },
- { "shl", SHL },
- { "shr", SHR },
- { "jump", JUMP },
- { "call", CALL },
- { "return", RETURN },
- { "int", INT },
- { "intfly", INTFLY },
- { "not", NOT },
- { "absolute", ABSOLUTE },
- { "mask", MASK },
- { "if", IF },
- { "rel", REL },
- { "ptr", PTR },
- { "table", TABLE },
- { "from", FROM },
- { "memory", MEMORY },
- { "to", TO },
- { "nop", NOP },
- { "extern", EXTERN },
- { "defw", DEFW },
- };
- #define TOKS (sizeof(toktab)/sizeof(toktab[0]))
- int lc;
- int ll;
- void
- yyrewind(void)
- {
- rewind(in_f);
- ll = lc = 0;
- yyline = 0;
- dot = 0;
- }
- int
- yygetc(void)
- {
- if (lc == ll)
- {
- next:
- if (fgets(line, 500, in_f) == 0)
- return EOF;
- /* do nasty check for #line directives */
- if (strncmp(line, "#line", 5) == 0) {
- /* #line n "filename" */
- sscanf(line, "#line %d \"%[^\"]", &yyline, yyfilename);
- yyline--;
- goto next;
- }
- yyline++;
- ll = strlen(line);
- lc = 0;
- }
- return line[lc++];
- }
- void
- yyungetc(void)
- {
- if (lc <= 0)
- exits("ungetc");
- lc--;
- }
- int
- yylex(void)
- {
- char token[100];
- int tl = 0;
- int c;
- while ((c = yygetc()) != EOF && (c == ' ' || c == '\t'))
- ;
- if (c == EOF)
- return 0;
- if(c == '/'){
- int x;
- x = yygetc();
- if(x != '/')
- yyungetc();
- else{
- lc -= 2;
- while(lc >= 0 && (line[lc-1]==' ' || line[lc-1]=='\t'))
- lc--;
- line[lc++] = '\n';
- line[lc] = 0;
- ll = lc;
- return '\n';
- }
- }
- if (isalpha(c) || c == '_')
- {
- int x;
- do {
- token[tl++] = c;
- } while ((c = yygetc()) != EOF && (isalnum(c) || c == '_'));
- if (c == EOF)
- return 0;
- yyungetc();
- token[tl] = 0;
- for (x = 0; x < TOKS; x++)
- if (strcmp(toktab[x].name, token) == 0)
- return toktab[x].tok;
- /* must be a symbol */
- yylval.s = findsym(token);
- return SYMBOL;
- }
- else if (isdigit(c))
- {
- /* accept 0x<digits> or 0b<digits> 0<digits> or <digits> */
- int prefix = c == '0';
- unsigned long n = c - '0';
- int base = 10;
- for (;;)
- {
- c = yygetc();
- if (c == EOF)
- return 0;
- if (prefix)
- {
- prefix = 0;
- if (c == 'x') {
- base = 16;
- continue;
- }
- else if (c == 'b')
- {
- base = 2;
- continue;
- }
- else
- base = 8;
- }
- if (isdigit(c))
- c -= '0';
- else if (isalpha(c) && base > 10)
- {
- if (isupper(c))
- c = tolower(c);
- c = c - 'a' + 10;
- }
- else {
- yyungetc();
- yylval.n = n;
- return NUM;
- }
- if (c >= base)
- yyerror("illegal format number");
- n = n * base + c;
- }
- }
- else if (c == ';') {
- /* skip to end of line */
- while ((c = yygetc()) != EOF && c != '\n')
- ;
- if (c != EOF)
- yyungetc();
- return COMMENT;
- }
- return c;
- }
- void
- yyerror(char *s, ...)
- {
- va_list ap;
- va_start(ap, s);
- fprintf(stderr, "%s: %d: ", yyfilename, yyline);
- vfprintf(stderr, s, ap);
- if (putc('\n', stderr) < 0)
- exits("io");
- errors++;
- va_end(ap);
- }
- void
- yywarn(char *s, ...)
- {
- va_list ap;
- va_start(ap, s);
- fprintf(stderr, "%s: %d: warning: ", yyfilename, yyline);
- vfprintf(stderr, s, ap);
- if (putc('\n', stderr) < 0)
- exits("io");
- warnings++;
- va_end(ap);
- }
- void
- p2error(int line, char *s)
- {
- USED(line);
- printf("/*\t%s */\n", s);
- }
- void
- main(int argc, char *argv[])
- {
- int a;
- for (a = 1; a < argc; a++)
- {
- if (argv[a][0] == '-')
- switch (argv[a][1]) {
- case 'D':
- /* #defines for cpp */
- if (ncppopts >= MAXCPPOPTS) {
- fprintf(stderr, "too many cpp options\n");
- exits("options");
- }
- cppopts[ncppopts++] = argv[a];
- break;
- default:
- fprintf(stderr, "unrecognised option %s\n",
- argv[a]);
- exits("options");
- }
- else
- break;
- }
- if (a != argc - 1)
- {
- fprintf(stderr, "usage: na [options] file\n");
- exits("options");
- }
- if (access(argv[a], 4) < 0) {
- fprintf(stderr, "can't read %s\n", argv[a]);
- exits("");
- }
- in_f = tmpfile();
- preprocess(argv[a], in_f);
- rewind(in_f);
- strcpy(yyfilename, argv[a]);
- yyparse();
- if (errors)
- exits("pass1");
- pass2 = 1;
- printf("unsigned long na_script[] = {\n");
- yyrewind();
- yyparse();
- printf("};\n");
- printf("\n");
- printf("#define NA_SCRIPT_SIZE %d\n", dot / 4);
- printf("\n");
- fixup();
- /*
- assemble();
- */
- exits(errors ? "pass2" : "");
- }
- void
- preprocess(char *in, FILE *out)
- {
- #ifdef USECPP
- Waitmsg *w;
- char **argv;
- if (fork() == 0) {
- /* child */
- dup(fileno(out), 1);
- argv = (char **)malloc(sizeof(char *) * (ncppopts + 5));
- argv[0] = "cpp";
- memcpy(&argv[1], cppopts, sizeof(char *) * ncppopts);
- argv[ncppopts + 1] = "-+";
- argv[ncppopts + 2] = "-N";
- argv[ncppopts + 3] = in;
- argv[ncppopts + 4] = 0;
- if (exec("/bin/cpp", argv) < 0) {
- fprintf(stderr, "failed to exec cpp (%R)\n");
- exits("exec");
- }
- exits("");
- }
- w = wait();
- free(w);
- #else
- FILE *fi;
- int c;
- fi = fopen(in, "r");
- if(fi == NULL){
- fprintf(stderr, "na: can't open %s\n", in);
- exits("open");
- }
- while((c = fgetc(fi)) != EOF)
- fputc(c, out);
- fclose(fi);
- #endif
- }
- struct sym *
- findsym(char *name)
- {
- struct sym *s;
- for (s = symlist; s; s = s->next)
- if (strcmp(name, s->name) == 0)
- return s;
- s = (struct sym *)malloc(sizeof(*s));
- s->name = strdup(name);
- s->t = Unknown;
- s->set = 0;
- s->next = symlist;
- symlist = s;
- return s;
- }
- void
- setsym(struct sym *s, Type t, long v)
- {
- if (pass2) {
- if (t == Unknown || t == Error)
- yyerror("can't resolve symbol");
- else {
- s->t = t;
- s->value = v;
- }
- }
- else {
- if (s->set)
- yyerror("multiply defined symbol");
- s->set = 1;
- s->t = t;
- s->value = v;
- }
- }
- int
- mk24bitssigned(long *l)
- {
- if (*l < 0) {
- if ((*l & 0xff800000L) != 0xff800000L) {
- *l = 0;
- return 0;
- }
- else
- *l = (*l) & 0xffffffL;
- }
- else if (*l > 0xffffffL) {
- *l = 0;
- return 0;
- }
- return 1;
- }
- static Type addresult[5][5] = {
- /* Const Addr Table Extern Reg */
- /* Const */ Const, Addr, Table, Error, Reg,
- /* Addr */ Addr, Error, Error, Error, Error,
- /* Table */ Table, Error, Error, Error, Error,
- /* Extern */ Error, Error, Error, Error, Error,
- /* Reg */ Reg, Error, Error, Error, Error,
- };
- static Type subresult[5][5] = {
- /* Const Addr Table Extern Reg */
- /* Const */ Const, Error, Error, Error, Error,
- /* Addr */ Addr, Const, Error, Error, Error,
- /* Table */ Table, Error, Const, Error, Error,
- /* Extern */ Error, Error, Error, Const, Error,
- /* Reg */ Error, Error, Error, Error, Error,
- };
- static Type muldivresult[5][5] = {
- /* Const Addr Table Extern */
- /* Const */ Const, Error, Error, Error, Error,
- /* Addr */ Error, Error, Error, Error, Error,
- /* Table */ Error, Error, Error, Error, Error,
- /* Extern */ Error, Error, Error, Error, Error,
- /* Reg */ Error, Error, Error, Error, Error,
- };
- static Type negresult[] = {
- /* Const */ Const,
- /* Addr */ Error,
- /* Table */ Error,
- /* Extern */ Error,
- /* Reg */ Error,
- };
- int
- patchtype(Type t)
- {
- switch (t) {
- case Addr:
- return 1;
- case Reg:
- return 2;
- case Extern:
- return 4;
- default:
- return 0;
- }
- }
- struct expval
- eval(struct expval a, struct expval b, char op)
- {
- struct expval c;
-
- if (a.t == Unknown || b.t == Unknown) {
- c.t = Unknown;
- c.value = 0;
- }
- else if (a.t == Error || b.t == Error) {
- c.t = Error;
- c.value = 0;
- }
- else {
- switch (op) {
- case '+':
- c.t = addresult[a.t][b.t];
- break;
- case '-':
- c.t = subresult[a.t][b.t];
- break;
- case '*':
- case '/':
- c.t = muldivresult[a.t][b.t];
- break;
- case '_':
- case '~':
- c.t = negresult[a.t];
- break;
- default:
- c.t = Error;
- break;
- }
- if (c.t == Error) {
- if (pass2)
- yyerror("type clash in evaluation");
- c.value = 0;
- }
- else {
- switch (op) {
- case '+':
- c.value = a.value + b.value;
- break;
- case '-':
- c.value = a.value - b.value;
- break;
- case '*':
- c.value = a.value * b.value;
- break;
- case '/':
- c.value = a.value / b.value;
- break;
- case '_':
- c.value = -a.value;
- break;
- case '~':
- c.value = ~a.value;
- break;
- }
- }
- }
- return c;
- }
- void
- regmove(unsigned char src_reg, unsigned char op,
- unsigned char dst_reg, struct expval *imm)
- {
- unsigned char func, reg;
- int immdata;
- out.len = 2;
- if (src_reg == 8) {
- func = 5;
- reg = dst_reg;
- }
- else if (dst_reg == 8) {
- func = 6;
- reg = src_reg;
- }
- else {
- if (pass2 && src_reg != dst_reg)
- yyerror("Registers must be the same");
- func = 7;
- reg = src_reg;
- }
- immdata = imm ? (imm->value & 0xff) : 0;
- out.data[0] = 0x40000000L
- | ((long)func << 27)
- | ((long)op << 24)
- | ((long)reg << 16)
- | ((long)(immdata) << 8);
- out.data[1] = 0;
- out.patch[0] = (imm && imm->t == Extern) ? 3 : 0;
- out.patch[1] = 0;
- }
- long
- mkreladdr(long addr, int len)
- {
- long rel;
- rel = addr - (dot + 4 * len);
- mk24bitssigned(&rel);
- return rel;
- }
- long
- chkreladdr(int d, struct expval *e, int len, long relrv)
- {
- if (e->t == Addr) {
- out.data[d] = mkreladdr(e->value, len);
- out.patch[d] = 0;
- return relrv;
- } else {
- out.data[d] = e->value;
- out.patch[d] = patchtype(e->t);
- return 0;
- }
- }
- void
- fixup(void)
- {
- struct sym *s;
- int p;
- printf("struct na_patch na_patches[] = {\n");
- for (p = 0; p < patches; p++) {
- printf("\t{ 0x%.4x, %d }, /* %.8lx */\n",
- patch[p].lwoff, patch[p].type, patch[p].lwoff * 4L);
- }
- if (patches == 0) {
- printf("\t{ 0, 0 },\n");
- }
- printf("};\n");
- printf("#define NA_PATCHES %d\n", patches);
- printf("\n");
- if (externs) {
- printf("enum na_external {\n");
- for (p = 0; p < externs; p++) {
- printf("\tX_%s,\n", externp[p]->name);
- }
- printf("};\n");
- }
- /* dump all labels (symbols of type Addr) as E_<Name> */
- for (s = symlist; s; s = s->next)
- if (s->t == Addr)
- break;
- if (s) {
- printf("\nenum {\n");
- while (s) {
- if (s->t == Addr)
- printf("\tE_%s = %ld,\n", s->name, s->value);
- s = s->next;
- }
- printf("};\n");
- }
- /* dump all Consts as #define A_<Name> value */
- for (s = symlist; s; s = s->next)
- if (s->t == Const)
- printf("#define A_%s %ld\n", s->name, s->value);
- }
|