Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

View File

@@ -0,0 +1,408 @@
/*
Copyright 1981
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include <stdio.h>
#include <klib.h>
#include "machine.h"
#include "ctype.h"
#ifdef PDP11
struct {
char lobyte;
char hibyte;
};
struct {
char *ptrw1;
char *ptrw2;
};
struct {
int wd1;
int wd2;
};
struct {
int swd1;
};
#endif
#ifdef MC68000
struct {
char hibyte;
char lobyte;
};
struct {
char *ptrw2;
};
struct {
int wd1;
int wd2;
};
struct {
int swd1;
};
#endif
#ifdef VAX
struct {
short wd2;
short wd1;
};
struct {
short swd1;
};
struct {
char lobyte;
char hibyte;
};
struct {
char *ptrw2;
};
#endif
/* format of a symbol entry in the main table*/
# define NAMELEN 8 /*length of name in symbol table*/
struct symtab {
char name[NAMELEN]; /*symbol name*/
short flags; /*bit flags*/
char *tlnk; /*table link*/
long vl1; /*symbol value*/
};
struct symtab *symtptr;
# define STESIZE (sizeof *symtptr) /*byte length of symbol table entry*/
/* flags for symbols*/
# define SYDF 0100000 /*defined*/
# define SYEQ 0040000 /*equated*/
# define SYGL 0020000 /*global - entry or external*/
# define SYER 0010000 /*equated register*/
# define SYXR 0004000 /*external reference*/
# define SYRA 0002000 /*DATA based relocatable*/
# define SYRO 0001000 /*TEXT based relocatable*/
# define SYBS 0000400 /*BSS based relocatable*/
# define SYIN 0000200 /*internal symbol -- opcode, directive or equ*/
# define SYPC 0000100 /*[vlh]equated using star '*' expression*/
# define SYRM 0000040 /*[vlh]register mask equate*/
/*flags for opcodes and directives*/
# define OPDR 0100000 /*0=>opcode, 1=>directive*/
# define OPFF 037 /*type of instruction (used as mask)*/
struct irts {
char *irle; /*ptr to last entry in chain*/
char *irfe; /*ptr to first entry in chain*/
};
long stlen; /*length of symbol table*/
/*
* intermediate text file
* format of the intermediate text for one statement:
*
* ******************************************************
* * it type = ITBS * # it entries * 0
* ******************************************************
* * absolute line number (long) *
* ******************************************************
* * it type = ITSY * instr length * 1
* ******************************************************
* * symbol table pointer for stmt label (long) *
* ******************************************************
* * it type = ITSY * instr mode length * 2
* ******************************************************
* * opcode ptr (long) *
* ******************************************************
* * it type = ITCN * relocation base * 3
* ******************************************************
* * location counter (pass 1) *
* ******************************************************
* * it type * relocation flag * 4 - oprnds
* ******************************************************
* * value (long) *
* ******************************************************
* .
*
* .
* ******************************************************
* * it type * relocation flag * n - oprnds
* ******************************************************
* * value (long) *
* ******************************************************
*/
#define ITOP1 4 /*first it entry for operands*/
/*
* it type meaning
* 0 beginning of statement
* 1 value is pointer to symbol table
* 2 value is a constant
* 3 value is a specal char
*
* relocation flag for opcode it entry is operand length:
* 'b' => byte
* 'w' => word
* 'l' => long
*/
struct it {
char itty; /*it type*/
char itrl; /*relocation flag or # it entries*/
long itop;
};
int mode; /*operand mode (byte, word, long)*/
int modelen; /*operand length per mode*/
#define BYTE 'b'
#define WORD 'w'
#define LONG 'l'
/* parameters that define the main table*/
#define SZMT 300 /*initial size of the main table */
/*must be large enough to initialize*/
#ifdef PDP11
#define ICRSZMT 10 /*add to main table when run out*/
#else
#define ICRSZMT 50 /*add to main table when run out*/
#endif
int cszmt; /*current size of main table*/
char *bmte; /*beginning of main table*/
char *emte; /*end of main table*/
/* intermediate text types*/
#define ITBS 0 /*beginning of statement*/
#define ITSY 1 /*pointer to symbol table*/
#define ITCN 2 /*constant*/
#define ITSP 3 /*special*/
#define ITRM 4 /*[vlh]register mask!*/
#define ITPC 5 /*[vlh]pc relative argument*/
# define ITBSZ 256 /*size of the it buffer*/
short itbuf[ITBSZ]; /*it buffer*/
#define STMAX 200 /*size of intermediate text buffer*/
struct it stbuf[STMAX]; /*holds it for one statement*/
char sbuf[512]; /*holds one block of source*/
/*initial reference table for symbols*/
# define SZIRT 128
char *sirt[SZIRT];
/*initial reference table to opcodes*/
char *oirt[SZIRT];
/*external symbol table*/
#define EXTSZ 512
char *extbl[EXTSZ];
int extindx; /*index to external symbol table*/
char **pexti; /*ptr to external symbol table*/
int absln; /*absolute line number*/
int p2absln; /*pass 2 line number*/
int fcflg; /*0=>passed an item. 1=>first char*/
int fchr; /*first char in term*/
int ifn; /*source file descriptor*/
short *pitix; /*ptr to it buffer*/
int itwc; /*number of words in it buffer*/
struct it *pitw; /*ptr to it buffer next entry*/
int itype; /*type of item*/
long ival; /*value of item*/
char *lblpt; /*label pointer*/
char lbt[NAMELEN]; /*holds label name*/
char *lmte; /*last entry in main table*/
long loctr; /*location counter*/
long savelc[4]; /*save relocation counters for 3 bases*/
int nite; /*number of entries in stbuf*/
struct it *pnite;
int lfn; /*loader output file descriptor*/
char *opcpt; /*pointer to opcode entry in main table*/
int p2flg; /*0=>pass 1 1=>pass 2*/
char **pirt; /*entry in initial reference table*/
int reloc; /*relocation value returned by expression evaluator (expr)*/
int rlflg; /*relocation value of current location counter*/
/*relocation values*/
# define ABS 0 /*absolute*/
# define DATA 1
# define TEXT 2
# define BSS 3
# define EXTRN 4 /*externally defined*/
#define EOLC '\n' /*end of line character*/
#define EOF 0 /*end of file indicator*/
#define NULL 0 /* [vlh] character null '\0' */
#define TRUE 1 /* [vlh] boolean values */
#define FALSE 0 /* [vlh] boolean values */
int format;
int sbuflen; /*number of chars in sbuf*/
char *psbuf; /*ptr into sbuf*/
int itfn; /*it file number*/
char itfnc; /*last char of it file name*/
int trbfn; /*temp for text relocation bits*/
char trbfnc; /*last char of text rb file*/
int dafn; /*file for data stuff*/
char dafnc; /*last char of data file*/
int drbfn; /*file for data relocation bits*/
char drbfnc; /*last char*/
int prtflg; /*print output flag*/
int undflg; /*make undefined symbols external flag*/
int starmul; /* * is multiply operator*/
char *endptr, *addptr;
char *orgptr;
char *subptr, *addiptr, *addqptr, *subiptr, *subqptr;
char *cmpptr, *addaptr, *cmpaptr, *subaptr, *cmpmptr;
char *equptr;
char *andptr, *andiptr, *eorptr, *eoriptr, *orptr, *oriptr;
char *cmpiptr;
char *moveptr, *moveqptr;
char *exgptr;
char *evenptr;
char *jsrptr, *bsrptr, *nopptr;
char peekc;
int numcon[2], numsym[2], indir[2], immed[2], numreg[2];
int plevel; /*parenthesis level counter*/
int opdix; /*operand index counter*/
int p1inlen; /*pass 1 instr length*/
int instrlen; /*pass 2 bytes in current instruction*/
/* effective address mode bits*/
#define DDIR 000
#define ADIR 010
#define INDIRECT 020
#define INDINC 030
#define DECIND 040
#define INDDISP 050
#define INDINX 060
#define SADDR 070
#define LADDR 071
#define IMM 074
#define AREGLO 8
#define AREGHI 15
/* relocation bit definitions:*/
#define RBMASK 07 /*tells type of relocation*/
#define INSABS 7 /*first word of instr -- absolute*/
#define DABS 0 /*data word absolute*/
#define TRELOC 2 /* TEXT relocatable*/
#define DRELOC 1 /* DATA relocatable*/
#define BRELOC 3 /* BSS relocatable*/
#define EXTVAR 4 /* ref to external variable*/
#define LUPPER 5 /* upper word of long*/
#define EXTREL 6 /* external relative mode*/
/* ptrs to ins[] and rlbits[]*/
int *pins;
int *prlb;
int ins[5]; /*holds instruction words*/
#define PRTCHLEN 128
char prtchars[PRTCHLEN]; /*line buffer for putchar*/
char *prtchidx; /*index for putchar*/
int extflg, extref; /*external in expr*/
#define CCR 16
#define SR 17
#define USP 18
#define MOVECCR 042300
#define MOVESR 043300
#define SRMOVE 040300
#define MOVEUSP 047140
struct op {
int ea; /* effective address bits*/
int len; /* effective address length in bytes*/
long con; /*constant or reloc part of operand*/
int drlc; /*reloc of con*/
int ext; /*external variable #*/
int idx; /*index register if any*/
int xmod; /*mode of index reg*/
} opnd[2];
#define OPSTLEN 10
#define TREELEN 20
struct buf{
int fildes;
int nunused;
char *xfree;
char buff[512];
};
struct buf lbuf;
struct buf tbuf;
struct buf dabuf;
struct buf drbuf;
int nerror; /*# of assembler errors*/
int in_err; /*[vlh] don't generate instrlen err if already err state*/
int shortadr; /*short addresses if set*/
#define CLRFOR 24
#define CLRVAL 041000
long itoffset;
#define LASTCHTFN *tfilptr
char *tfilptr; /* -> Changed filename character */
#define PC 22
int equflg; /*doing an equate stmt*/
#define ANDI 01000
#define AND 0140000
#define ORI 0
#define OR 0100000
#define EORI 05000
#define EOR 0130000
#define MOVE 0
long lseek();
char *sbrk();
char *lemt();
int refpc; /* * referenced in expr*/
#define SOH 1
/* Conditional Assembly variables and constants [vlh] */
#define LOW_CA 21 /* [vlh] */
#define HI_CA 30 /* [vlh] */
int ca_true; /* true unless in a false CA*/
int ca; /* depth of conditional assembly, none = 0*/
int ca_level; /* at what CA depth did CA go false?*/
/* pass 1 global variables */
int numops; /*number of operands*/
int inoffset; /*[vlh]offset directive*/
int didorg;
int initflg; /*initialize flag*/
/* defines */
#define igblk() while(fchr==' ') fchr=gchr()
#define ckein() ((pitw >= pnite))
/* is it an alterable operand */
#define memalt(ap) (memea(ap) && altea(ap))
#define dataalt(ap) (dataea(ap) && altea(ap))
#define altea(ap) ((((ap)->ea&070)!=SADDR || ((ap)->ea&6)==0))
/* is it the specific type of operand */
#define memea(ap) (((ap)->ea&070) >= INDIRECT)
#define dataea(ap) (((ap)->ea&070) != ADIR)
#define pcea(ap) ((ap)->ea==072 || (ap)->ea==073)
#define ckdreg(ap) ((ap)->ea>=0 && (ap)->ea<AREGLO)
#define ckareg(ap) ((ap)->ea>=AREGLO && (ap)->ea<=AREGHI)
/*
* DRI Listing Hacks:
*/
char *sfname; /* -> Source file name */
#define LPP 58 /* # lines / page */
int xline; /* Present line # */
int xpage; /* Present Page # */

View File

@@ -0,0 +1,222 @@
*/*
* Copyright 1981
* Alcyon Corporation
* 8716 Production Ave.
* San Diego, Ca. 92121
**/
R0: .equ 0,r
R1: .equ 1,r
R2: .equ 2,r
R3: .equ 3,r
R4: .equ 4,r
R5: .equ 5,r
R6: .equ 6,r
R7: .equ 7,r
R8: .equ 8,r
R9: .equ 9,r
R10: .equ 10,r
R11: .equ 11,r
R12: .equ 12,r
R13: .equ 13,r
R14: .equ 14,r
R15: .equ 15,r
D0: .equ 0,r
D1: .equ 1,r
D2: .equ 2,r
D3: .equ 3,r
D4: .equ 4,r
D5: .equ 5,r
D6: .equ 6,r
D7: .equ 7,r
A0: .equ @10,r
A1: .equ @11,r
A2: .equ @12,r
A3: .equ @13,r
A4: .equ @14,r
A5: .equ @15,r
A6: .equ @16,r
A7: .equ @17,r
USP: .equ 18,r
SP: .equ 15,r
CCR: .equ 16,r
SR: .equ 17,r
r0: .equ 0,r
r1: .equ 1,r
r2: .equ 2,r
r3: .equ 3,r
r4: .equ 4,r
r5: .equ 5,r
r6: .equ 6,r
r7: .equ 7,r
r8: .equ 8,r
r9: .equ 9,r
r10: .equ 10,r
r11: .equ 11,r
r12: .equ 12,r
r13: .equ 13,r
r14: .equ 14,r
r15: .equ 15,r
d0: .equ 0,r
d1: .equ 1,r
d2: .equ 2,r
d3: .equ 3,r
d4: .equ 4,r
d5: .equ 5,r
d6: .equ 6,r
d7: .equ 7,r
a0: .equ @10,r
a1: .equ @11,r
a2: .equ @12,r
a3: .equ @13,r
a4: .equ @14,r
a5: .equ @15,r
a6: .equ @16,r
a7: .equ @17,r
usp: .equ 18,r
sp: .equ 15,r
ccr: .equ 16,r
sr: .equ 17,r
.b: .equ 19,r
.B: .equ 19,r
.w: .equ 20,r
.W: .equ 20,r
.l: .equ 21,r
.L: .equ 21,r
pc: .equ 22,r
PC: .equ 22,r
abcd: .opd 4,@140400
add: .opd 1,@150000
adda: .opd 15,@150000
addi: .opd 2,@003000
addq: .opd 17,@050000
inc: .opd 16,@050000
addx: .opd 27,@150400
and: .opd 1,@140000
andi: .opd 2,@001000
asl: .opd 8,@160400
asr: .opd 8,@160000
bcc: .opd 6,@062000
bcs: .opd 6,@062400
beq: .opd 6,@063400
bze: .opd 6,@063400
bge: .opd 6,@066000
bgt: .opd 6,@067000
bhi: .opd 6,@061000
bhis: .opd 6,@062000
bhs: .opd 6,@062000
ble: .opd 6,@067400
blo: .opd 6,@062400
bls: .opd 6,@061400
blos: .opd 6,@061400
blt: .opd 6,@066400
bmi: .opd 6,@065400
bne: .opd 6,@063000
bnz: .opd 6,@063000
bpl: .opd 6,@065000
bvc: .opd 6,@064000
bvs: .opd 6,@064400
bchg: .opd 7,@000100
bclr: .opd 7,@000200
bra: .opd 6,@060000
bt: .opd 6,@060000
bset: .opd 7,@000300
bsr: .opd 6,@060400
btst: .opd 7,@000000
chk: .opd 26,@040600
clr: .opd 24,@041000
cmp: .opd 26,@130000
cmpa: .opd 15,@130000
cmpi: .opd 2,@006000
cmpm: .opd 10,@130410
dbcc: .opd 11,@052310
dbcs: .opd 11,@052710
dblo: .opd 11,@052710
dbeq: .opd 11,@053710
dbze: .opd 11,@053710
dbra: .opd 11,@050710
dbf: .opd 11,@050710
dbge: .opd 11,@056310
dbgt: .opd 11,@057310
dbhi: .opd 11,@051310
dbhs: .opd 11,@051310
dble: .opd 11,@057710
dbls: .opd 11,@051710
dblt: .opd 11,@056710
dbmi: .opd 11,@055710
dbne: .opd 11,@053310
dbnz: .opd 11,@053310
dbpl: .opd 11,@055310
dbt: .opd 11,@050310
dbvc: .opd 11,@054310
dbvs: .opd 11,@054710
divs: .opd 5,@100700
divu: .opd 5,@100300
eor: .opd 23,@130000
eori: .opd 2,@005000
exg: .opd 12,@140400
ext: .opd 13,@044000
jmp: .opd 9,@047300
jsr: .opd 9,@047200
illegal:.opd 0,@045374
lea: .opd 30,@040700
link: .opd 19,@047120
lsr: .opd 8,@160010
lsl: .opd 8,@160410
move: .opd 3,@000000
movea: .opd 3,@000100
movem: .opd 20,@044200
movep: .opd 21,@000010
moveq: .opd 22,@070000
muls: .opd 5,@140700
mulu: .opd 5,@140300
nbcd: .opd 25,@044000
neg: .opd 24,@042000
negx: .opd 24,@040000
nop: .opd 0,@047161
not: .opd 24,@043000
or: .opd 1,@100000
ori: .opd 2,@000000
pea: .opd 29,@044100
reset: .opd 0,@047160
rol: .opd 8,@160430
ror: .opd 8,@160030
roxl: .opd 8,@160420
roxr: .opd 8,@160020
rte: .opd 0,@047163
rtr: .opd 0,@047167
rts: .opd 0,@047165
sbcd: .opd 4,@100400
scc: .opd 25,@052300
shs: .opd 25,@052300
scs: .opd 25,@052700
slo: .opd 25,@052700
seq: .opd 25,@053700
sze: .opd 25,@053700
sf: .opd 25,@050700
sge: .opd 25,@056300
sgt: .opd 25,@057300
shi: .opd 25,@051300
sle: .opd 25,@057700
sls: .opd 25,@051700
slt: .opd 25,@056700
smi: .opd 25,@055700
sne: .opd 25,@053300
snz: .opd 25,@053300
spl: .opd 25,@055300
st: .opd 25,@050300
svc: .opd 25,@054300
svs: .opd 25,@054700
stop: .opd 14,@047162
sub: .opd 1,@110000
suba: .opd 15,@110000
subi: .opd 2,@002000
subq: .opd 17,@050400
dec: .opd 16,@050400
subx: .opd 27,@110400
swap: .opd 28,@044100
tas: .opd 25,@045300
trap: .opd 18,@047100
trapv: .opd 0,@047166
tst: .opd 24,@045000
unlk: .opd 13,@047130
.end

View File

@@ -0,0 +1,454 @@
/*
Copyright 1981
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "machine.h"
#include "ctype.h"
#ifdef PDP11
struct {
char lobyte;
char hibyte;
};
struct {
char *ptrw1;
char *ptrw2;
};
struct {
int wd1;
int wd2;
};
struct {
int swd1;
};
#endif
#ifdef MC68000
struct {
char hibyte;
char lobyte;
};
struct {
char *ptrw2;
};
struct {
int wd1;
int wd2;
};
struct {
int swd1;
};
#endif
#ifdef VAX
struct {
short wd2;
short wd1;
};
struct {
short swd1;
};
struct {
char lobyte;
char hibyte;
};
struct {
char *ptrw2;
};
#endif
/* format of a symbol entry in the main table*/
# define NAMELEN 8 /*length of name in symbol table*/
struct symtab {
char name[NAMELEN]; /*symbol name*/
int flags; /*bit flags*/
char *tlnk; /*table link*/
long vl1; /*symbol value*/
};
struct symtab *symtptr;
# define STESIZE (sizeof *symtptr) /*byte length of symbol table entry*/
/* flags for symbols*/
# define SYDF 0100000 /*defined*/
# define SYEQ 0040000 /*equated*/
# define SYGL 0020000 /*global - entry or external*/
# define SYER 0010000 /*equated register*/
# define SYXR 0004000 /*external reference*/
# define SYRA 0002000 /*DATA based relocatable*/
# define SYRO 0001000 /*TEXT based relocatable*/
# define SYBS 0000400 /*BSS based relocatable*/
# define SYIN 0000200 /*internal symbol -- opcode, directive or equ*/
# define SYPC 0000100 /*[vlh]equated using star '*' expression*/
# define SYRM 0000040 /*[vlh]register mask equate*/
/*flags for opcodes and directives*/
# define OPDR 0100000 /*0=>opcode, 1=>directive*/
# define OPFF 037 /*type of instruction (used as mask)*/
struct irts {
char *irle; /*ptr to last entry in chain*/
char *irfe; /*ptr to first entry in chain*/
};
long stlen; /*length of symbol table*/
/*
* intermediate text file
* format of the intermediate text for one statement:
*
* ******************************************************
* * it type = ITBS * # it entries * 0
* ******************************************************
* * absolute line number (long) *
* ******************************************************
* * it type = ITSY * instr length * 1
* ******************************************************
* * symbol table pointer for stmt label (long) *
* ******************************************************
* * it type = ITSY * instr mode length * 2
* ******************************************************
* * opcode ptr (long) *
* ******************************************************
* * it type = ITCN * relocation base * 3
* ******************************************************
* * location counter (pass 1) *
* ******************************************************
* * it type * relocation flag * 4 - oprnds
* ******************************************************
* * value (long) *
* ******************************************************
* .
* .
* .
* ******************************************************
* * it type * relocation flag * n - oprnds
* ******************************************************
* * value (long) *
* ******************************************************
*/
#define ITOP1 4 /*first it entry for operands*/
/*
* it type meaning
* 0 beginning of statement
* 1 value is pointer to symbol table
* 2 value is a constant
* 3 value is a specal char
*
* relocation flag for opcode it entry is operand length:
* 'b' => byte
* 'w' => word
* 'l' => long
*/
struct it {
char itty; /*it type*/
char itrl; /*relocation flag or # it entries*/
long itop;
};
int mode=0; /*operand mode (byte, word, long)*/
int modelen=0; /*operand length per mode*/
#define BYTE 'b'
#define WORD 'w'
#define LONG 'l'
/* parameters that define the main table*/
#define SZMT 300 /*initial size of the main table */
/*must be large enough to initialize*/
#ifdef PDP11
#define ICRSZMT 10 /*add to main table when run out*/
#else
#define ICRSZMT 50 /*add to main table when run out*/
#endif
int cszmt=0; /*current size of main table*/
char *bmte=0; /*beginning of main table*/
char *emte=0; /*end of main table*/
/* intermediate text types*/
#define ITBS 0 /*beginning of statement*/
#define ITSY 1 /*pointer to symbol table*/
#define ITCN 2 /*constant*/
#define ITSP 3 /*special*/
#define ITRM 4 /*[vlh]register mask!*/
#define ITPC 5 /*[vlh]pc relative argument*/
# define ITBSZ 256 /*size of the it buffer*/
int itbuf[ITBSZ]={0}; /*it buffer*/
#define STMAX 200 /*size of intermediate text buffer*/
struct it stbuf[STMAX]={0}; /*holds it for one statement*/
char sbuf[512]={0}; /*holds one block of source*/
/*initial reference table for symbols*/
# define SZIRT 128
char *sirt[SZIRT]={0};
/*initial reference table to opcodes*/
char *oirt[SZIRT]={0};
/*external symbol table*/
#define EXTSZ 512
char *extbl[EXTSZ]={0};
int extindx=0; /*index to external symbol table*/
char **pexti=0; /*ptr to external symbol table*/
int absln=0; /*absolute line number*/
int p2absln=0; /*pass 2 line number*/
int fcflg=0; /*0=>passed an item. 1=>first char*/
int fchr=0; /*first char in term*/
int ifn=0; /*source file descriptor*/
int *pitix=0; /*ptr to it buffer*/
int itwc=0; /*number of words in it buffer*/
struct it *pitw=0; /*ptr to it buffer next entry*/
int itype=0; /*type of item*/
long ival=0; /*value of item*/
char *lblpt=0; /*label pointer*/
char lbt[NAMELEN]={0}; /*holds label name*/
char *lmte=0; /*last entry in main table*/
long loctr=0; /*location counter*/
long savelc[4]={0}; /*save relocation counters for 3 bases*/
int nite=0; /*number of entries in stbuf*/
struct it *pnite=0;
int lfn=0; /*loader output file descriptor*/
char *opcpt=0; /*pointer to opcode entry in main table*/
int p2flg=0; /*0=>pass 1 1=>pass 2*/
char **pirt=0; /*entry in initial reference table*/
int reloc=0; /*relocation value returned by expression evaluator (expr)*/
int rlflg=0; /*relocation value of current location counter*/
/*relocation values*/
# define ABS 0 /*absolute*/
# define DATA 1
# define TEXT 2
# define BSS 3
# define EXTRN 4 /*externally defined*/
#define EOLC '\n' /*end of line character*/
#define EOF 0 /*end of file indicator*/
#define NULL 0 /* [vlh] character null '\0' */
#define TRUE 1 /* [vlh] boolean values */
#define FALSE 0 /* [vlh] boolean values */
int format=0;
int sbuflen=0; /*number of chars in sbuf*/
char *psbuf=0; /*ptr into sbuf*/
int itfn=0; /*it file number*/
char itfnc=0; /*last char of it file name*/
int trbfn=0; /*temp for text relocation bits*/
char trbfnc=0; /*last char of text rb file*/
int dafn=0; /*file for data stuff*/
char dafnc=0; /*last char of data file*/
int drbfn=0; /*file for data relocation bits*/
char drbfnc=0; /*last char*/
int prtflg=0; /*print output flag*/
int undflg=0; /*make undefined symbols external flag*/
int starmul=0; /* * is multiply operator*/
char *endptr=0, *addptr=0;
char *orgptr=0;
char *subptr=0, *addiptr=0, *addqptr=0, *subiptr=0, *subqptr=0;
char *cmpptr=0, *addaptr=0, *cmpaptr=0, *subaptr=0, *cmpmptr=0;
char *equptr=0;
char *andptr=0, *andiptr=0, *eorptr=0, *eoriptr=0, *orptr=0, *oriptr=0;
char *cmpiptr=0;
char *moveptr=0, *moveqptr=0;
char *exgptr=0;
char *evenptr=0;
char *jsrptr=0, *bsrptr=0, *nopptr=0;
char peekc=0;
int numcon[2]=0, numsym[2]=0, indir[2]=0, immed[2]=0, numreg[2]=0;
int plevel=0; /*parenthesis level counter*/
int opdix=0; /*operand index counter*/
int p1inlen=0; /*pass 1 instr length*/
int instrlen=0; /*pass 2 bytes in current instruction*/
/* effective address mode bits*/
#define DDIR 000
#define ADIR 010
#define INDIRECT 020
#define INDINC 030
#define DECIND 040
#define INDDISP 050
#define INDINX 060
#define SADDR 070
#define LADDR 071
#define IMM 074
#define AREGLO 8
#define AREGHI 15
/* relocation bit definitions:*/
#define RBMASK 07 /*tells type of relocation*/
#define INSABS 7 /*first word of instr -- absolute*/
#define DABS 0 /*data word absolute*/
#define TRELOC 2 /* TEXT relocatable*/
#define DRELOC 1 /* DATA relocatable*/
#define BRELOC 3 /* BSS relocatable*/
#define EXTVAR 4 /* ref to external variable*/
#define LUPPER 5 /* upper word of long*/
#define EXTREL 6 /* external relative mode*/
/* ptrs to ins[] and rlbits[]*/
int *pins=0;
int *prlb=0;
int ins[5]={0}; /*holds instruction words*/
#define PRTCHLEN 128
char prtchars[PRTCHLEN]={0}; /*line buffer for putchar*/
char *prtchidx=0; /*index for putchar*/
int extflg=0, extref=0; /*external in expr*/
#define CCR 16
#define SR 17
#define USP 18
#define MOVECCR 042300
#define MOVESR 043300
#define SRMOVE 040300
#define MOVEUSP 047140
struct op {
int ea; /* effective address bits*/
int len; /* effective address length in bytes*/
long con; /*constant or reloc part of operand*/
int drlc; /*reloc of con*/
int ext; /*external variable #*/
int idx; /*index register if any*/
int xmod; /*mode of index reg*/
} opnd[2]={0};
#define OPSTLEN 10
#define TREELEN 20
struct buf{
int fildes;
int nunused;
char *xfree;
char buff[512];
};
struct buf lbuf={0};
struct buf tbuf={0};
struct buf dabuf={0};
struct buf drbuf={0};
int nerror=0; /*# of assembler errors*/
int in_err=0; /*[vlh] don't generate instrlen err if already err state*/
int shortadr=0; /*short addresses if set*/
#define CLRFOR 24
#define CLRVAL 041000
long itoffset=0;
#define LASTCHTFN tfilname[11]
#define PC 22
int equflg=0; /*doing an equate stmt*/
#define ANDI 01000
#define AND 0140000
#define ORI 0
#define OR 0100000
#define EORI 05000
#define EOR 0130000
#define MOVE 0
long lseek();
char *sbrk();
char *lemt();
int refpc=0; /* * referenced in expr*/
#define SOH 1
/* Conditional Assembly variables and constants [vlh] */
#define LOW_CA 21 /* [vlh] */
#define HI_CA 30 /* [vlh] */
int ca_true=0; /* true unless in a false CA*/
int ca=0; /* depth of conditional assembly, none = 0*/
int ca_level=0; /* at what CA depth did CA go false?*/
/* pass 1 global variables */
int numops=0; /*number of operands*/
int inoffset=0; /*[vlh]offset directive*/
int didorg=0;
int initflg=0; /*initialize flag*/
/* defines */
#define igblk() while(fchr==' ') fchr=gchr()
#define ckein() ((pitw >= pnite))
/* is it an alterable operand */
#define memalt(ap) (memea(ap) && altea(ap))
#define dataalt(ap) (dataea(ap) && altea(ap))
#define altea(ap) ((((ap)->ea&070)!=SADDR || ((ap)->ea&6)==0))
/* is it the specific type of operand */
#define memea(ap) (((ap)->ea&070) >= INDIRECT)
#define dataea(ap) (((ap)->ea&070) != ADIR)
#define pcea(ap) ((ap)->ea==072 || (ap)->ea==073)
#define ckdreg(ap) ((ap)->ea>=0 && (ap)->ea<AREGLO)
#define ckareg(ap) ((ap)->ea>=AREGLO && (ap)->ea<=AREGHI)
/*
* DRI Listing Hacks:
*/
char *sfname=0; /* -> Source filename */
int xline=0; /* Current line number */
int xpage=0; /* Current page number */
/*
* More Initializations:
*/
char *tfilname[80] = {0}; /* Temp filename area */
char *initfnam[80] = {0}; /* Init filename area */
struct it exitm={0};
int prcnt=0;
int rval=0;
int lpflg=0;
int lastopr=0;
int rlbits[5]={0};
int pline=0;
int prsp=0;
int amode=0;
long stlen=0;
int udfct=0;
int errno=0;
int nitleft=0;
int hibytflg[4]={0};
int hibytw[4]={0};
struct it *piop=0;
struct it *pitr=0;
struct it opstk[OPSTLEN]={0};
struct it tree[TREELEN]={0};
int chmvq=0;
int explmod=0;
int ftudp=0;
int iop=0;
int itr=0;
char ldfn[40]={0};
int opcval=0;
int poslab=0;
int symcon=0;
char *tfilptr=0;
int tlab1=0;
#define HDSIZE (sizeof couthd) /**.o file header size*/
struct hdr {
short ch_magic; /*c.out magic number 060016 = $600E*/
long ch_tsize; /*text size*/
long ch_dsize; /*data size*/
long ch_bsize; /*bss size*/
long ch_ssize; /*symbol table size*/
long ch_stksize; /*stack size*/
long ch_entry; /*entry point*/
short ch_rlbflg; /*relocation bits suppressed flag*/
} couthd={0};
#define MAGIC 0x601a /* bra .+26 instruction*/

View File

@@ -0,0 +1,13 @@
#define HDSIZE (sizeof couthd) /**.o file header size*/
struct hdr {
short ch_magic; /*c.out magic number 060016 = $600E*/
long ch_tsize; /*text size*/
long ch_dsize; /*data size*/
long ch_bsize; /*bss size*/
long ch_ssize; /*symbol table size*/
long ch_stksize; /*stack size*/
long ch_entry; /*entry point*/
short ch_rlbflg; /*relocation bits suppressed flag*/
} couthd;
#define MAGIC 0x601a /* bra .+26 instruction*/

View File

@@ -0,0 +1,36 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*char *version "@(#)ctype - Aug 13, 1982";
Standard routines... */
#define isspace(c) ((c)==32 || (c)==9 || (c)==13 || (c)==10 ||(c)==12)
#define isupper(c) ((c)<='Z' && (c)>='A')
#define islower(c) ((c)<='z' && (c)>='a')
#define isalpha(c) (isupper((c)) || islower((c)))
#define isdigit(c) ((c)<='9' && (c)>='0')
#define isascii(c) ((c) < 0200 && (c) >= 0)
#define isalnum(c) (isalpha((c)) || isdigit((c)))
#define iscntrl(c) (((c) < 040 || (c) == 0177) && isascii((c)))
#define isprint(c) ((c) >= 040 && (c) < 0177)
#define ispunct(c) (!isalnum((c)) && isprint(c))
#define toupper(c) (islower((c)) ? (c) & ~32 : (c))
#define tolower(c) (isupper((c)) ? (c) | 32 : (c))
#define toascii(c) ((c) & 0177)

View File

@@ -0,0 +1,12 @@
$ set def drb0:[steve.cpm68k.v102a.al40.as68]
$ assign drb0:[steve.cpm68k.v102a.al40.oldas68] old
$ diff DIR.C old:DIR.C
$ diff EXPR.C old:EXPR.C
$ diff MAIN.C old:MAIN.C
$ diff MISC.C old:MISC.C
$ diff PASS1A.C old:PASS1A.C
$ diff PASS2.C old:PASS2.C
$ diff SYMT.C old:SYMT.C
$ diff VERSION.C old:VERSION.C
$ diff AS68.H old:AS68.H
$ diff COUT.H old:COUT.H

View File

@@ -0,0 +1,12 @@
$ set def drb0:[steve.cpm68k.v102a.al40.as68]
$ assign drb0:[steve.cpm68k.v102.as68] old
$ diff DIR.C old:DIR.C
$ diff EXPR.C old:EXPR.C
$ diff MAIN.C old:MAIN.C
$ diff MISC.C old:MISC.C
$ diff PASS1A.C old:PASS1A.C
$ diff PASS2.C old:PASS2.C
$ diff SYMT.C old:SYMT.C
$ diff VERSION.C old:VERSION.C
$ diff AS68.H old:AS68.H
$ diff COUT.H old:COUT.H

View File

@@ -0,0 +1,934 @@
/*
Copyright 1981
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/* Pass 1 and pass 2 directive handling routines */
/* code to handle conditional assembly directives */
#include "as68.h"
#include "cout.h"
long lseek();
int p1gi();
int p2gi();
int igrst();
/*directive to define an opcode*/
hopd()
{
if(!lbt[0]) {
xerr(4); /*no label*/
return;
}
setname(); /*move label into main table*/
if((lblpt=lemt(oirt,TRUE))!=lmte) {
xerr(5); /*opcode redefined*/
return;
}
mmte(); /*make main table entry*/
expr(&p1gi); /*get instruction format*/
if(itype!=ITCN || ival<0 || ival>OPFF) {
xerr(18); /*illegal format specifier*/
return;
}
lblpt->flags =| ival|SYIN; /*remember format*/
if(fchr != ',') { /*field separator*/
xerr(10);
return;
}
expr(&p1gi); /*get opcode value*/
if(itype != ITCN) {
xerr(17); /*not a constant*/
return;
}
lblpt->vl1 = ival; /*put value in main table*/
igrst(); /*ignore rest of statement-comment*/
}
/* equate directive*/
hequ()
{
if(lbt[0] == 0) {
xerr(4); /*no label*/
return;
}
setname();
if((lblpt=lemt(sirt,FALSE))!=lmte) { /*aready there*/
if(lbt[0] == '~') { /*local symbol*/
lblpt = lmte;
mmte();
}
}
else
mmte();
if(lblpt->flags&SYXR) {
xerr(29);
return;
}
lblpt->flags =| SYDF|SYEQ; /*defined & equate*/
equflg = 1;
modelen = 4;
expr(&p1gi);
equflg = 0;
if(itype == ITSY && ival.ptrw2->flags&SYER) {
lblpt->flags =| SYER; /*equated register*/
ival = ival.ptrw2->vl1;
}
else if(itype != ITCN) {
xerr(7); /*not a constant*/
return;
}
if (inoffset && reloc != ABS) { /* [vlh] */
xerr(11);
return;
}
if(initflg) /*doing symbol table initialization*/
lblpt->flags =| SYIN; /*internal symbol*/
lblpt->vl1 = ival;
if(reloc == DATA) /*check relocation*/
{
lblpt->flags =| SYRA; /*DATA relocatable*/
}
else if(reloc == TEXT)
lblpt->flags =| SYRO; /*TEXT relocatable*/
else if(reloc == BSS)
lblpt->flags =| SYBS; /*BSS relocatable*/
else if(fchr==',' && (fchr=gchr())=='r')
lblpt->flags =| SYER; /*equated register*/
if (refpc) /*[vlh] flag directive is pc relative */
lblpt->flags =| SYPC;
igrst();
}
/* process dsect directive*/
hdsect()
{
dorlst(DATA);
}
dorlst(xrtyp)
{
inoffset = 0; /* [vlh] offset mode terminated my sect directive */
chkeven(); /* May need to make pc even */
dlabl(); /*define label on old base if there is one*/
savelc[rlflg] = loctr; /*save old base relocation*/
rlflg = xrtyp;
loctr = savelc[xrtyp]; /*set new base relocation ctr*/
opitb();
stbuf[0].itrl = itwc;
wostb();
igrst();
}
/*process psect directive*/
hpsect()
{
dorlst(TEXT);
}
hbss()
{
dorlst(BSS);
}
/*make pc even*/
heven()
{
modelen = 2; /*Try to figure this one out...*/
if(loctr&1) { /*have to make it even*/
dorlst(rlflg);
}
else {
igrst();
}
}
/*process globl directive*/
hent()
{
while(1) {
gterm(TRUE); /*get entry symbol*/
if(itype!=ITSY) { /*error if not symbol*/
xerr(28);
return;
}
if((lblpt=lemt(sirt,FALSE)) == lmte) /*look up in main table*/
mmte(); /*not there, make new entry*/
else
if(lblpt->flags&SYER) /*already there*/
uerr(29);
lblpt->flags =| SYGL; /*symbol is an entry*/
if(lblpt->flags&SYXR) { /*been thru hext code*/
lblpt->flags =& ~(SYXR|SYDF); /*reset for init of .comm*/
}
if (inoffset && reloc != ABS) { /* [vlh] */
xerr(11);
return;
}
if(fchr == ',') /*skip ',' between entries*/
fchr = gchr();
else {
igrst(); /*statement finished*/
return;
}
}
}
/*process comm directive*/
hext()
{
gterm(TRUE); /*get external symbol*/
if(itype!=ITSY) { /*error if not symbol*/
xerr(28);
return;
}
if((lblpt=lemt(sirt,FALSE)) == lmte) /*look up in main table*/
mmte(); /*not there, make new entry*/
else
if(lblpt->flags&SYDF && (lblpt->flags&SYXR)==0) /*already there*/
uerr(29);
lblpt->flags =| SYXR | SYDF; /*symbol is an external*/
mkextidx(lblpt); /*put into external table*/
if(fchr == ',') { /*skip ',' between operands*/
fchr = gchr();
gterm(TRUE);
if(itype != ITCN) {
xerr(17);
return;
}
lblpt->vl1.wd1 = ival; /* # bytes of storage required*/
}
else
lblpt->vl1.wd1 = 1; /* default # bytes*/
igrst();
}
mkextidx(p)
struct symtab *p;
{
if(extindx >= EXTSZ) { /*check for overflow of external symbol tbl*/
rpterr("overflow of external table\n");
endit();
}
p->vl1.wd2 = pexti - extbl; /* external symbol index #*/
*pexti++ = p; /*save external in external table*/
extindx++;
}
/* end statement*/
hend()
{
register short i;
register int j;
inoffset = 0; /*[vlh] turn off inoffset mode*/
lblpt = 0; /*no label*/
opitb(); /*output beginning of statement*/
igrst(); /* [vlh] ignore operands */
stbuf[0].itrl = itwc; /*number of it entries*/
wostb(); /*write out statement buffer*/
for(i=0; i<ITBSZ; i++)
doitwr(0);
if(initflg) {
putsymtab();
printf("68000 assembler initialized\n");
endit();
}
if((fchr=gchr())!=EOF) {
rpterr("end statement not at end of source\n");
}
savelc[rlflg] = loctr; /*last location on current reloc base*/
fixunds(); /*make golbals and maybe undefineds external*/
if(!didorg) /*did not assign to location counter*/
pass1a(); /*resolve short branches*/
pass2(); /*assembler pass 2*/
}
/* define storage given number of bytes*/
hds()
{
dlabl(); /*define label maybe*/
if (!inoffset) /* [vlh] */
opitb(); /*output it for beginning of statement*/
refpc = 0;
expr(&p1gi);
if(itype!=ITCN) {
xerr(17); /*must be constant*/
return;
}
if(reloc != ABS) {
xerr(9); /*must be absolute*/
return;
}
if (!inoffset) { /* [vlh] don't generate it if in offset */
opitoo(); /*output one operand*/
stbuf[0].itrl = itwc;
wostb(); /*write out statement buffer*/
loctr =+ (ival*modelen);
}
igrst();
}
/* make pc even if necessary for .dc and .ds */
chkeven()
{
register char *pi;
if(modelen>1 && loctr&1) {
pi = opcpt;
opcpt = evenptr;
opitb();
stbuf[0].itrl = itwc;
wostb();
opcpt = pi;
loctr++;
}
}
/* define byte directive*/
hdc()
{
chkeven();
hdata(modelen);
}
/*
* define bytes or words of data
* call with:
* 1 => defining bytes
* 2 => defining words
* 4 => defining long words
*/
hdata(mul)
{
dlabl(); /*define label*/
opitb(); /*beginning of statement*/
numops = 0; /*initialize count for number of operands*/
opito(); /*output it for operands*/
stbuf[0].itrl = itwc; /* # of it entries*/
wostb(); /*write out statement buffer*/
loctr =+ numops*mul; /* count by bytes or words*/
}
/* handle org statement*/
horg()
{
register i;
if(rlflg==TEXT && loctr!=0)
didorg++; /*can't do branch optimization as separate pass now*/
expr(&p1gi); /*value of new relocation counter*/
if(reloc != rlflg && reloc != ABS) {
xerr(27);
return;
}
if(ival < loctr) {
xerr(40); /*trying to go backwards*/
return;
}
opcpt = orgptr; /*org directive for pass 2*/
opitb();
opitoo();
stbuf[0].itrl = itwc;
wostb();
loctr = ival;
dlabl(); /*define label*/
}
/* Assemble for mask2 (R9M), ignore... */
hmask2() /* [vlh] */
{
igrst();
}
/* Define register list */
hreg() /* [vlh] */
{
int mask;
if(lbt[0]==0) {
xerr(4); /*no label*/
return;
}
setname(); /*move label into main table*/
if((lblpt=lemt(sirt,FALSE))!=lmte) {
xerr(5); /*opcode redefined*/
return;
}
if (inoffset)
if (reloc != ABS) {
xerr(11);
return;
}
mmte(); /*make main table entry*/
if ((mask = mkmask()) == -1) {
xerr(6);
return;
}
lblpt->flags =| SYDF|SYEQ|SYRM; /* register mask, defined & equated */
lblpt->vl1 = mask;
igrst();
}
int regmsk[] {0100000,040000,020000,010000,04000,02000,01000,0400,0200,
0100,040,020,010,4,2,1};
/* make a register mask for the reg routine */
mkmask() /* [vlh] */
{
register int *p, i, j, mask;
p = &regmsk; mask = 0;
while ((i = chkreg()) != -1) {
if (fchr == '-') {
fchr = gchr();
if ((j = chkreg()) == -1) {
xerr(40);
return(-1);
}
while (i <= j)
mask =| p[i++];
}
else mask =| p[i];
if (fchr != '/' && fchr != ',') break; /*[vlh] Signetics fix*/
fchr = gchr();
}
return(mask);
}
/* get a register # from file, return -1 if none or illegal */
chkreg() /* [vlh] */
{
register int i, j;
i = j = 0;
if (fchr == 'a' || fchr == 'A')
i = 8;
else if (fchr != 'd' && fchr != 'r' && fchr != 'D' && fchr != 'R')
return(-1);
fchr = gchr();
do {
j = (j*10) + (fchr - '0');
fchr = gchr();
} while (isdigit(fchr));
if (j < 0 || j > AREGHI) return(-1);
i =+ j;
if (i >= 0 && i <= AREGHI) return(i);
else return(-1);
}
/* Define constant block */
hdcb() /* [vlh] */
{
chkeven(); /* on even boundary if not byte block. */
dlabl(); /* define label... */
opitb();
opito();
stbuf[0].itrl = itwc;
numops = stbuf[ITOP1].itop;
loctr =+ numops * modelen;
wostb(); /* write out statement buffer */
}
/* Command line, similar to ds.b */
hcomline() /* [vlh] */
{
dlabl(); /*define label maybe*/
modelen = 1; /* byte store... */
opitb(); /*output it for beginning of statement*/
refpc = 0;
expr(&p1gi);
if(itype!=ITCN) {
xerr(17); /*must be constant*/
return;
}
if(reloc != ABS) {
xerr(9); /*must be absolute*/
return;
}
opitoo(); /*output one operand*/
stbuf[0].itrl = itwc;
wostb(); /*write out statement buffer*/
loctr =+ ival;
igrst();
}
/* Relocateable id record, ignore */
hidnt() /* [vlh] */
{
igrst();
}
/* Define offsets */
hoffset() /* [vlh] */
{
inoffset = 1;
expr(&p1gi); /* get new location counter */
if (itype != ITCN) {
xerr(17); /* constant required */
return;
}
if (reloc != ABS) {
xerr(9); /* must be absolute */
return;
}
loctr = ival;
igrst();
}
/* define sections: map to bss, text and data */
hsection() /* [vlh] */
{
inoffset = 0; /* reseting section turns off offset mode */
dlabl(); /* define label on old base if there is one */
savelc[rlflg] = loctr; /* save old base relocation */
opitb(); /* intermediate table... */
expr(&p1gi); /* get section # */
if (itype != ITCN) {
xerr(17); /* must be a constant */
return;
}
if (ival > 15 || ival < 0) {
xerr(9); /* proper range 0..15 */
return;
}
if (ival==14) rlflg = DATA;
else if (ival==15) rlflg = BSS;
else rlflg = TEXT;
loctr = savelc[rlflg];
stbuf[3].itop = loctr; /* pass 1 location counter */
stbuf[3].itrl = rlflg; /* relocation base */
stbuf[0].itrl = itwc;
wostb();
igrst();
}
/* hopt -- ignore, set up assembler options */
hopt() /* vlh */
{
igrst();
}
/**** Second pass directive handling routines ****/
/* second pass end statement*/
send()
{
register int i;
savelc[rlflg] = loctr;
if(savelc[TEXT]&1) {
rlflg = TEXT;
outbyte(0,DABS);
savelc[TEXT]++;
}
if(savelc[DATA]&1) {
rlflg = DATA;
outbyte(0,DABS);
savelc[DATA]++;
}
if(savelc[BSS]&1) {
savelc[BSS]++;
}
ival = 0;
reloc = ABS;
ckeop(9);
print(0);
cpdata(); /*copy data to loader file*/
osymt(); /*output symbol table*/
myfflush(&tbuf); /*flush text relocation bits*/
cprlbits(); /*copy relocation bits*/
myfflush(&lbuf);
i = (sizeof couthd.ch_magic) + 3*(sizeof couthd.ch_tsize);
if((lseek(lfn,(long)i,0) == -1) || write(lfn,&stlen,4) != 4)
rpterr("I/O error on loader output file\n");
endit(); /*end*/
}
/*second pass define storage - ds*/
sds()
{
print(0);
if(rlflg == TEXT || rlflg==DATA) {
expr(&p2gi);
if(itype != ITCN) {
uerr(13);
return;
}
ival =* modelen;
while(ival) {
outbyte(0,DABS);
loctr++;
ival--;
}
}
else
loctr =+ stbuf[ITOP1].itop*modelen; /*reserve storage*/
}
/* second pass - define block storage, initialized */
sdcb() /* [vlh] */
{
register int pfg, i, hflg, len;
expr(&p2gi);
if (itype != ITCN || reloc != ABS) {
uerr(13); /* must be absolute constant */
return;
}
len = ival;
expr(&p2gi);
if (modelen==1 && (ival<-128 || ival>=256 || reloc != ABS)) {
uerr(20);
ival = 0;
reloc = ABS;
}
while (len--) {
if (modelen==1) {
if (!hflg) {
ins[i].hibyte = ival;
outbyte(ival.wd2,DABS);
hflg++;
}
else {
ins[i++].lobyte = ival;
outbyte(ival.wd2,DABS);
hflg=0;
}
goto sdbl2;
}
else if (modelen==2) {
sdbl1:
ins[i++] = ival.wd2;
outword(ival.wd2, reloc);
sdbl2:
if (i>3) {
instrlen = i*2;
print ((pfg++) ? 2 : 1);
loctr =+ instrlen;
i=0;
}
}
else { /* long word... */
ins[i++] = ival.wd1;
outword(ival.wd1,LUPPER);
goto sdbl1;
}
}
if (i) { /* more printing */
instrlen = i*2 - hflg;
print ((pfg) ? 2 : 1);
loctr =+ instrlen;
}
}
/*second pass data*/
sdsect()
{
savelc[rlflg] = loctr;
rlflg = DATA;
loctr = savelc[DATA];
print(0); /*print the new location counter*/
}
/*second pass text*/
spsect()
{
savelc[rlflg] = loctr;
rlflg = TEXT;
loctr = savelc[TEXT];
print(0); /*print the new location counter*/
}
sbss()
{
savelc[rlflg] = loctr;
rlflg = BSS;
loctr = savelc[BSS];
print(0); /*print the new location counter*/
}
/* make loctr even*/
seven()
{
if(loctr&1) {
if(rlflg==TEXT || rlflg==DATA)
outbyte(0,DABS);
loctr++;
}
print(0);
}
/* second pass org*/
sorg()
{
long l;
if(rlflg==TEXT || rlflg==DATA) { /*must put out zeros*/
l = stbuf[ITOP1].itop - loctr; /*# zeroes to output*/
ins[0] = 0;
print(1);
while(l > 0) {
outbyte(0,DABS);
loctr++;
l--;
}
}
else { /*BSS*/
loctr = stbuf[ITOP1].itop; /*new location counter*/
print(0);
}
}
/*
*second pass define data (words or bytes)
* call with
* 2 => defining words
* 1 => defining bytes
* 4 => defining long words
*/
sdata(dtyp)
{
register pfg,i;
register hflg;
hflg = i = pfg = 0;
while(1) {
expr(&p2gi); /*evaluate expression*/
if(pitw < pnite)
pitw--; /*expr passed a token*/
if(itype!=ITCN && reloc != EXTRN) { /*must be constant*/
uerr(13);
ival=0;
reloc = ABS;
}
if(reloc == EXTRN)
reloc = (extref<<3)|EXTVAR; /*gen extern reference*/
if(dtyp==1) { /*defining a byte*/
if(ival<-128 || ival>=256 || reloc!=ABS) { /*not a byte*/
uerr(20);
ival=0;
reloc = ABS;
}
if(!hflg) {
ins[i].hibyte = ival;
outbyte(ival.wd2,DABS);
hflg++;
}
else {
ins[i++].lobyte = ival;
hflg = 0;
outbyte(ival.wd2,DABS);
}
goto sdal2;
}
else if(dtyp == 2) { /*defining a word*/
sdal1:
ins[i++] = ival.wd2;
outword(ival.wd2, reloc);
sdal2:
if(i>3) {
instrlen = i*2;
print ((pfg++) ? 2 : 1);
loctr =+ instrlen;
i=0;
}
}
else { /*long words*/
ins[i++] = ival.wd1;
outword(ival.wd1,LUPPER);
goto sdal1;
}
if(!ckeop(15)) /*should be end of operand*/
return;
pitw++;
if(ckein()) {
if(hflg) {
ins[i++].lobyte = 0;
}
if(i) { /*more printing*/
instrlen = i*2 - hflg;
print ((pfg) ? 2 : 1);
loctr =+ instrlen;
}
return;
}
}
}
sdc()
{
sdata(modelen);
}
ssection() /* [vlh] */
{
int sect;
sect = stbuf[3].itrl;
if (sect==DATA) sdsect();
else if (sect==BSS) sbss();
else spsect();
}
/*define word statement*/
sdw()
{
sdata(0); /*defining words*/
}
/**** Conditional assembly directives ****/
hifeq() /* [vlh] */
{
if (!acok()) return;
if (ival) {
if (ca_true) ca_level = ca;
ca_true = 0;
}
ca++;
}
hifne() /* [vlh] */
{
if (!acok()) return;
if (!ival) {
if (ca_true) ca_level = ca;
ca_true = 0;
}
ca++;
}
hiflt() /* [vlh] */
{
if (!acok()) return;
if (ival >= 0) {
if (ca_true) ca_level = ca;
ca_true = 0;
}
ca++;
}
hifle() /* [vlh] */
{
if (!acok()) return;
if (ival > 0) {
if (ca_true) ca_level = ca;
ca_true = 0;
}
ca++;
}
hifgt() /* [vlh] */
{
if (!acok()) return;
if (ival <= 0) {
if (ca_true) ca_level = ca;
ca_true = 0;
}
ca++;
}
hifge() /* [vlh] */
{
if (!acok()) return;
if (ival < 0) {
if (ca_true) ca_level = ca;
ca_true = 0;
}
ca++;
}
hifc() /* [vlh] */
{
if (!cmp_ops()) {
if (ca_true) ca_level = ca;
ca_true = 0;
}
ca++;
}
hifnc() /* [vlh] */
{
if (cmp_ops()) {
if (ca_true) ca_level = ca;
ca_true = 0;
}
ca++;
}
hendc() /* [vlh] */
{
if (!ca) {
xerr(25); /* unexpected endc */
return;
}
ca--;
if (!ca_true)
if (ca_level == ca) ca_true = 1;
igrst();
}
hpage()
{
opitb(); /* Output beginning */
wostb(); /* Write out buffer */
igrst(); /* Ignore rest of line */
}
spage()
{
print(0); /* Print the directive */
xline = LPP; /* Force page on next print */
page();
}
acok()
{
expr(&p1gi);
if (itype != ITCN) {
xerr(7); /* must be a constant */
return(0);
}
if (reloc != ABS) {
xerr(11); /* must be absolute, no forward references */
return(0);
}
igrst();
return(1);
}
cmp_ops()
{
char str1[25], str2[25];
register int len1, len2;
if (fchr != '\'') { xerr(9); return(0); }
len1 = len2 = 0;
while (fchr = gchr()) {
if (fchr == '\'') break;
if (fchr == EOLC) return(0);
str1[len1++] = fchr;
}
if ((fchr=gchr()) != ',') { xerr(9); return; }
if ((fchr=gchr()) != '\'') { xerr(10); return;}
while (fchr = gchr()) {
if (fchr == '\'') break;
if (fchr == EOLC) return(0);
str2[len2++] = fchr;
}
igrst();
if (len1 != len2) return(0);
str1[len1] = str2[len2] = NULL;
if (strcmp(str1,str2) == 0) return(1);
return(0);
}
strcmp(s,t)
register char *s, *t;
{
for( ; *s == *t; s++, t++ )
if( *s == '\0' )
return(0);
return( *s - *t );
}

View File

@@ -0,0 +1,505 @@
/*
Copyright 1981
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/* Expression evaluator */
# include "as68.h"
/*precedence of operators*/
# define PAO 2 /*AND, OR*/
# define PPM 2 /*+ -*/
# define PMD 3 /** /*/
# define PLP 1 /* (*/
# define PRP 4 /* )*/
# define PEE 0 /* all other special chars*/
/*global integers for this package*/
struct it exitm; /*expression item*/
int prcnt; /*paren count*/
int rval; /*relocation value*/
int lpflg;
int lastopr; /*last token was operator when set*/
long gval(); /*get operand value*/
/*
* expression evaluator
* call with:
* address of function to get input
* returns:
* item type in itype
* item value in ival
* relocation flag in reloc:
* 0 => absolute
* 1 => data
* 2 => text
* 3 => bss
* 4 => external
*
* The only expressions involving externals which are legal are
* external+constant or external-constant
*/
struct it *piop, *pitr;
int iop, itr;
struct it opstk[OPSTLEN]; /*operator stack*/
struct it tree[TREELEN]; /*operand stack*/
expr(iploc)
int (*iploc)();
{
register int i, ipr;
extflg = starmul = iop = lpflg = 0;
piop = &opstk[0];
itr = -1; /*tree stack pointer*/
pitr = &tree[0];
pitr--;
/* form end of expression operator*/
opstk[0].itty = ITSP; /*special character*/
opstk[0].itop.wd2 = '?';
lastopr = 1;
/* get an input item*/
while(1) {
if(itr >= TREELEN-2) {
rpterr("expr tree overflow\n");
abort();
}
if(iop >= OPSTLEN-1) {
rpterr("expr opstk overflow\n");
abort();
}
(*iploc)(); /*get an input term*/
if (itype==ITPC) return;
starmul=0; /* * is location counter*/
/* special character*/
if(itype==ITSP) {
ipr = gprc(i=ival.wd2); /*get precedence of character*/
if(ipr==PEE) /*end of expression*/
break;
lastopr = 1;
if(ipr==PLP) { /*left paren*/
lpflg++;
prcnt++;
iop++; /*up stack pointer*/
piop++;
piop->swd1=exitm.swd1; /*put operator on stack*/
piop->itop=exitm.itop;
continue;
}
if(ipr==PRP) { /*right paren*/
if(lpflg) { exerr(1); return; }
starmul = 1; /* * is multiply*/
prcnt--; /*down one level*/
while (piop->itop != '(') { /* top stk is '(' */
itr++; /*up tree pointer*/
pitr++;
pitr->swd1 = piop->swd1; /*move operator*/
pitr->itop = piop->itop;
iop--; /*reduce operand stack*/
piop--;
}
iop--; /*remove stack*/
piop--;
continue;
}
while(ipr<=gprc(i=piop->itop.wd2)) { /* >= precedence */
itr++;
pitr++;
pitr->swd1 = piop->swd1; /*move operator*/
pitr->itop = piop->itop;
iop--; /*reduce operand stack*/
piop--;
}
iop++; /*up operator stack*/
piop++;
piop->swd1 = exitm.swd1; /*put in operator stack*/
piop->itop = exitm.itop;
continue;
}
/* symbol or constant*/
else {
lastopr = lpflg = 0; /*clear flag*/
itr++; /*up tree pointer*/
pitr++;
pitr->swd1 = exitm.swd1; /*put in tree*/
pitr->itop = exitm.itop;
starmul = 1; /* * is multiply*/
continue;
}
} /* end while(1)... */
/*output the rest of the operator stack to the tree*/
for(i=iop; i>=0; i--) {
itr++;
pitr++;
pitr->swd1 = piop->swd1; /*move operator*/
pitr->itop = piop->itop;
piop--;
}
collapse();
}
/* collapse the tree into one entry*/
collapse()
{
register int rv1, rv2, topr, i, bos;
register long tv1, tv2;
bos = 0;
exct1:
if(itr>=3) {
piop = &tree[bos];
iop = bos;
while (iop<=(itr-3+bos) && (piop->itty==ITSP ||
(piop+1)->itty==ITSP || (piop+2)->itty!=ITSP)) {
iop++;
piop++;
}
if (iop<=(itr-3+bos)) {
tv1 = gval(piop); /*get value of first operand*/
rv1 = rval; /*relocation value*/
tv2 = gval(piop+1);
rv2 = rval;
topr = (piop+2)->itop; /*operator*/
/* handle operators */
if (topr == '+') {
tv1=+ tv2;
rv1 = ckrl1(rv1,rv2); /*relocation*/
}
else if (topr == '-') {
tv1 =- tv2;
rv1 = ckrl2(rv1,rv2); /*relocation*/
}
else {
switch(topr) { /*operator*/
case '/': /* division */
tv1 =/ tv2; break;
case '*': /* multiplication */
tv1 =* tv2; break;
case '&': /* logical and */
tv1 =& tv2; break;
case '!': /* logical or */
tv1 =| tv2; break;
case '<': /* left shift */
tv1 =<< tv2.wd2; break;
case '>': /* right shift */
tv1 =>> tv2.wd2; break;
default: /*invalid operator*/
exerr(2); return;
}
rv1 = ckrl3(rv1,rv2); /* relocation */
}
/*put new value in tree*/
if (iop==bos) {
bos =+ 2;
iop = bos;
}
piop = &tree[iop];
piop->itty = ITCN; /*must be constant*/
piop->itop = tv1; /*value*/
piop->itrl = rv1; /*relocation value*/
if (iop != bos) { /* push up the rest of the tree... */
i = iop + 2 - bos;
pitr = piop+2;
for(; i<itr; i++) {
piop++;
pitr++;
piop->swd1 = pitr->swd1;
piop->itop = pitr->itop;
}
}
itr =- 2;
goto exct1;
}
}
/* check for unary minus and unary plus*/
if (tree[bos+1].itty!=ITSP && tree[bos].itop.wd2=='?')
{ exerr(3); return; }
if (tree[bos+1].itty!=ITSP || tree[bos].itty==ITSP) {
reloc = ABS;
ival = 0;
itype = ITCN;
return;
}
if(tree[bos+1].itop.wd2!='?') { /*end of statement*/
if(tree[bos+1].itop.wd2!='+') { /*ignore unary plus*/
if(tree[bos+1].itop.wd2!='-') { /* invalid operator */
exerr(4);
return;
}
tree[bos+1].itop = -gval(&tree[bos]);
tree[bos+1].itty = ITCN;
tree[bos+1].itrl = tree[bos].itrl;
bos++;
itr--;
goto exct1;
}
}
/* send results back to caller*/
if ((itype = tree[bos].itty)==ITCN)
ival = gval(&tree[bos]);
else {
ival = tree[bos].itop;
if(itype==ITSY && !(ival.ptrw2->flags&SYDF)) { /*undef symbol*/
reloc = ABS;
ival = 0;
itype = ITCN;
return;
}
}
get_val(tree[bos].itrl);
}
/*
*if defined symbol get value and say constant
* except for externals and equated registers
*/
get_val(reloc_val)
int reloc_val;
{
if(itype==ITSY && (ival.ptrw2->flags&(SYXR|SYER))==0) {
if(ival.ptrw2->flags&SYRA) /*get symbol relocation factor*/
reloc = DATA;
else if(ival.ptrw2->flags&SYRO)
reloc = TEXT;
else if(ival.ptrw2->flags&SYBS)
reloc = BSS;
else reloc = ABS;
ival = ival.ptrw2->vl1; /*symbol vaue*/
itype = ITCN; /*constant*/
}
else
if(itype == ITSY && ival.ptrw2->flags&SYXR) { /*external symbol*/
fixext(ival.ptrw2);
reloc = EXTRN;
}
else
reloc = reloc_val; /*relocation value of item*/
}
exerr(n) /* [vlh] */
int n;
{
uerr(6);
ival = 0;
itype = ITCN;
reloc = ABS;
}
/*
* get precedence of a operator
* call with
* operator
* returns
* precedence
*/
gprc(dprc)
{
switch(dprc) {
case '+':
case '-':
case '&': /* and*/
case '!': /* or*/
case '^': /*exclusive or*/
return(PPM);
case '/':
case '*':
case '<': /*left shift*/
case '>': /*right shift*/
return(PMD);
case '(':
if(lastopr)
return(PLP);
break;
case ')':
if(!prcnt) /*no left parens*/
break;
return(PRP);
}
return(PEE); /*end of expression*/
}
/*
* get value from an it format item
* call with
* address of it format item
* returns
* the value
* relocation value in rval
* calls uerr if it cant get a value
*/
long gval(avwrd)
struct it *avwrd;
{
register struct it *vwrd;
register struct symtab *p;
vwrd = avwrd;
if(vwrd->itty == ITCN) { /*constant*/
rval = vwrd->itrl;
return(vwrd->itop); /*value*/
}
if(vwrd->itty != ITSY) {
uerr(6);
rval = ABS;
return(0);
}
p = vwrd->itop.ptrw2;
if(p->flags&SYXR) { /*external reference*/
fixext(p);
return(0);
}
if((p->flags&SYDF) != SYDF || (p->flags&SYER)) {
uerr(6);
rval = ABS;
return(0);
}
rval = (p->flags&SYRA) ? DATA : (p->flags&SYRO) /* reloc of item */
? TEXT : (p->flags&SYBS) ? BSS : ABS;
return(p->vl1);
}
/*
* get items for expression evaluator (pass one)
* returns:
* item type in itype
* item value in ival
* item in it format in exitm
*/
p1gi()
{
if(fcflg) /*used item so must pass it*/
gterm(TRUE);
if(!fcflg && ckspc(fchr)==1) {
fcflg=1; /*just pass first character*/
itype=ITSP; /*special char*/
ival=fchr; /*value is the char*/
}
else { /*get a whole term*/
fcflg = 0;
gterm(TRUE); /*get a term*/
if(itype==ITSY) { /* got a symbol*/
ival.ptrw2=lemt(sirt,FALSE); /*look it up in main table*/
if(ival.ptrw2==lmte) /*not there before*/
mmte(); /*put it in table*/
}
else
if(itype == ITCN)
exitm.itrl = reloc;
}
exitm.itty = itype;
exitm.itop = ival;
}
/*
* get items for expression evaluator (pass 2)
* returns:
* item type in itype
* item value in ival
* item in it format in exitm
*/
p2gi()
{
if(pitw==pnite) { /*end of statement*/
itype = ITSP;
ival = ' '; /*blank*/
exitm.itty = itype;
exitm.itop = ival;
return;
}
if((itype = pitw->itty) == ITPC) { /*vlh*/
pitw->itop = loctr;
if (p2flg || format==6) itype = pitw->itty = ITCN;
}
ival = pitw->itop; /*value*/
exitm.swd1 = pitw->swd1;
exitm.itop = ival;
pitw++;
}
/*
*check for a special character
* call with
* character to check
* returns:
* 0 => character is number or letter
*/
ckspc(acksc)
{
register cksc;
cksc = acksc;
if (isalnum(cksc)) return(0);
return((index("_~*.@$%\'",cksc) != -1) ? 0 : 1); /*[vlh] compacted*/
}
/* generate new relocation for op + op*/
ckrl1(rv1,rv2)
{
if(rv1==rv2)
return(rv1);
if(rv1==ABS || rv2==ABS)
return(rv1+rv2); /*the one that is not ABS*/
uerr(27);
return(ABS);
}
/*generate new relocation for op - op*/
ckrl2(rv1,rv2)
{
if(rv2==EXTRN)
uerr(26);
if(rv1==rv2)
return(ABS);
if(rv2==ABS)
return(rv1+rv2);
uerr(27);
return(ABS);
}
/*generate new relocation for op /*&|<>^! op*/
ckrl3(rv1,rv2)
{
if(rv1!=ABS || rv2!=ABS)
uerr(27);
return(ABS);
}
fixext(p)
struct symtab *p;
{
if(extflg)
uerr(36); /*two externals in expr*/
extflg++;
extref = p->vl1.wd2; /*get external #*/
rval = EXTRN;
itype = ITCN;
ival = 0;
}

View File

@@ -0,0 +1,39 @@
$ num
AS68INIT.C
AS68INIT.lis
$ num
DIR.C
DIR.lis
$ num
EXPR.C
EXPR.lis
$ num
MAIN.C
MAIN.lis
$ num
MISC.C
MISC.lis
$ num
PASS1A.C
PASS1A.lis
$ num
PASS2.C
PASS2.lis
$ num
SYMT.C
SYMT.lis
$ num
VERSION.C
VERSION.lis
$ num
AS68.H
AS68.lst
$ num
COUT.H
COUT.lst
$ num
CTYPE.H
CTYPE.lst
$ num
MACHINE.H
MACHINE.lst

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
/*#define MC68000 1*/ /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
#define PDP11 1 /* PDP-11 Version*/
/*#define CPM 1*/ /* CP/M Operating System*/
#define UNIX 1 /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
#define MC68000 1 /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
#define CPM 1 /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
/*#define MC68000 1*/ /* 68000 version */
#define VAX 1 /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
/*#define CPM 1*/ /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
#define VMS 1 /* VMS Operating System*/

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
/*#define MC68000 1*/ /* 68000 version */
#define VAX 1 /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
/*#define CPM 1*/ /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
#define VMS 1 /* VMS Operating System*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
$1stat machine.h=rw
$1pip machine.h=machine.68k
$1cp68 -i 0$1 DIR.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
era $1x.i
era $1x.st
$1c168 $1x.ic DIR.s -L
$1as68 -f $1 -s 0$1 -l -u DIR.s
era dir.s
$1cp68 -i 0$1 EXPR.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
era $1x.i
era $1x.st
$1c168 $1x.ic EXPR.s -L
$1as68 -f $1 -s 0$1 -l -u EXPR.s
era expr.s
$1cp68 -i 0$1 MAIN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
era $1x.i
era $1x.st
$1c168 $1x.ic MAIN.s -L
$1as68 -f $1 -s 0$1 -l -u MAIN.s
era main.s
$1cp68 -i 0$1 misc.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
era $1x.i
era $1x.st
$1c168 $1x.ic MISC.s -L
$1as68 -f $1 -s 0$1 -l -u MISC.s
era misc.s
$1cp68 -i 0$1 PASS1A.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
era $1x.i
era $1x.st
$1c168 $1x.ic PASS1A.s -L
$1as68 -f $1 -s 0$1 -l -u PASS1A.s
era pass1a.s
$1cp68 -i 0$1 PASS2.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
era $1x.i
era $1x.st
$1c168 $1x.ic PASS2.s -L
$1as68 -f $1 -s 0$1 -l -u PASS2.s
era pass2.s
$1cp68 -i 0$1 STRNCMP.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
era $1x.i
era $1x.st
$1c168 $1x.ic STRNCMP.s -L
$1as68 -f $1 -s 0$1 -l -u STRNCMP.s
era strncmp.s
$1cp68 -i 0$1 SYMT.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
era $1x.i
era $1x.st
$1c168 $1x.ic SYMT.s -L
$1as68 -f $1 -s 0$1 -l -u SYMT.s
era symt.s
relink $1

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,109 @@
/*
Copyright 1981
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/* reduce long relative branches to short if possible*/
#include "as68.h"
int nitleft;
char tfilname[];
int p2gi();
long lseek();
pass1a()
{
register long reduced;
register int i, wsize;
register long oldpos,newpos; /* Old and new file seek pointers */
register j; /* temp */
pitix = itbuf;
nitleft = 0;
reduced = 0; itoffset = 0; stbuf[0].itrl = 0;
wsize = 3*sizeof stbuf[0]; /* [vlh] don't calculate many times */
close(itfn);
LASTCHTFN = itfnc;
itfn = openfi(tfilname,2,1); /*open it for update*/
while(ristb()) {
opcpt = stbuf[2].itop.ptrw2; /*ptr to opcode entry in main tab*/
if(!(opcpt->flags&OPDR)) { /*not a directive*/
format = (opcpt->flags)&OPFF;
p1inlen = stbuf[1].itrl; /*pass 1 instr length guess*/
if(((format==6 && p1inlen==4) || opcpt==jsrptr) &&
(rlflg=stbuf[3].itrl)==TEXT) {
nite = stbuf[0].itrl & 0377;/* # of it entries */
pnite = &stbuf[nite].itty; /*ptr to end of stmt*/
modelen = stbuf[2].itrl; /*instr mode length*/
opdix = ITOP1; /*first operand*/
pitw = &stbuf[ITOP1].itty; /*ptr to first operand*/
loctr = stbuf[3].itop - reduced;
expr(&p2gi);
ival =- loctr+2L;
if(itype==ITCN && !extflg && reloc!=ABS) {
if(format==9) { /*jsr*/
i = (ival>= -128 && ival<=127) ? p1inlen-2 :
(ival>= -32768 && ival<=32767) ? p1inlen-4 : 0;
if (!i)
continue;
stbuf[2].itop.ptrw2 = bsrptr; /*chng to bsr*/
}
else if(ival>= -128 && ival<=127) {
i = 2; /*[vlh]was 4 for ival=2*/
if (!ival) stbuf[2].itop.ptrw2 = nopptr;
}
else
continue;
fixsyadr(i);
reduced =+ i;
stbuf[1].itrl =- i; /*reduced somewhat*/
if(!stbuf[1].itrl)
stbuf[1].itrl = -1; /*ignore flag*/
oldpos=lseek(itfn,0L,1); /* Remember current position */
newpos= itoffset -
(stbuf[0].itrl*sizeof stbuf[0]);
if(lseek(itfn,newpos,0) < 0) {
rpterr("seek error on it file\n");
abort();
}
if(write(itfn,&stbuf[0],wsize) != wsize) {
rpterr("write error on it file\n");
abort();
}
lseek(itfn,oldpos,0);
}
}
}
else if(opcpt == endptr) {
savelc[TEXT] =- reduced;
return;
}
}
}
/* fix all symbol addresses that are text based and greater than loctr*/
/* fix means subtract 2 from them*/
fixsyadr(al)
{
register char **sx1, **sx2;
register l;
l = al;
/* loop thru symbol initial reference table*/
for(sx1= sirt; sx1<&sirt[SZIRT-1]; sx1 =+ 2) {
if(*(sx2 = sx1+1)==0) /* this chain is empty*/
continue;
/* symbols on one chain*/
sx2 = *sx2; /*first entry on this chain*/
while(1) {
if((sx2->flags&SYDF || sx2->flags&SYPC) && sx2->flags&SYRO &&
sx2->vl1 > loctr) /* [vlh] */
sx2->vl1 =- l;
if(sx2 == *sx1) /*end of chain*/
break;
sx2 = sx2->tlnk; /*next entry in chain*/
}
}
}

View File

@@ -0,0 +1,841 @@
/*
Copyright 1981
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*
* pass two for the 68000 assembler
* Bill Allen
* March 1980
*/
#include "as68.h"
#include "cout.h" /*c.out header definition & MAGIC*/
#define MOVEA 0100
int p2gi();
extern char tfilname[]; /*name of it file*/
extern char initfnam[]; /*name of the initilization file*/
int (*p2direct[])();
int opf1(), opf2(), opf3(), opf4(), opf5(), relbr(), opf7(), opf8();
int opf9(), opf11(), opf12(), opf13(), opf15(), opf17(), opf20();
int opf21(), opf22(), opf23();
int (*opfary[])() {
0, /*0*/
opf1, /*1*/
opf2, /*2*/
opf3, /*3*/
opf4, /*4*/
opf5, /*5*/
relbr, /*6*/
opf7, /*7*/
opf8, /*8*/
opf9, /*9*/
opf4, /*10*/
opf11, /*11*/
opf12, /*12*/
opf13, /*13*/
opf9, /*14*/
opf15, /*15*/
opf17, /*16*/
opf17, /*17*/
opf13, /*18*/
opf11, /*19*/
opf20, /*20*/
opf21, /*21*/
opf22, /*22*/
opf23, /*23*/
opf9, /*24*/
opf9, /*25*/
opf5, /*26*/ /* [vlh] cmp, chk, extention verification */
opf4, /*27*/ /* [vlh] addx, subx, extension verification */
opf13, /*28*/ /* [vlh] swap, extension verification */
opf9, /*29*/ /* [vlh] pea, extention verification */
opf15 /*30*/ /* [vlh] lea, extension verification */
};
#define LSTFRMT 30
int f1mode[] {0,0,0100,0,0200};
int f2mode[] {0,0,0100,0,0200};
int f3mode[] {0,010000,030000,0,020000};
int f15mode[] {0,0,0300,0,0700};
int f5mode[] {0,0,0100,0,0200};
int f5amode[] {0,0,0300,0,0700};
int f13mode[] {0,0,0200,0,0300};
int f23mode[] {0,0400,0500,0,0600};
int rlbits[5]; /*holds relocation bits for instr*/
int pline; /*number of last printed line*/
int brkln2 077777; /*pass 2 break line number for debugging*/
int prsp; /*special print alignment flag*/
int amode; /*addressing mode*/
int nitleft;
/*pass two driver*/
pass2()
{
register short *p;
register i;
register (*dirop)();
pitix = itbuf; /* This is init for doitrd*/
xline = LPP;
nitleft = 0;
lbuf.nunused = tbuf.nunused = dabuf.nunused = drbuf.nunused = 512;
lbuf.fildes = lfn; /*set buffered io for binary file*/
lbuf.xfree = &lbuf.buff[0];
tbuf.fildes = trbfn; /*set buffered io for text reloc bits file*/
tbuf.xfree = &tbuf.buff[0];
dabuf.fildes = dafn; /*set buffered io for data bytes*/
dabuf.xfree = &dabuf.buff[0];
drbuf.fildes = drbfn; /*set buffered io for data reloc bits*/
drbuf.xfree = &drbuf.buff[0];
couthd.ch_magic = MAGIC;/*c.out magic number*/
if(savelc[TEXT]&1)
savelc[TEXT]++; /*make it even*/
couthd.ch_tsize = savelc[TEXT]; /*text size*/
if(savelc[DATA]&1)
savelc[DATA]++; /*make it even*/
couthd.ch_dsize = savelc[DATA]; /*data size*/
couthd.ch_bsize = savelc[BSS]; /*bss size*/
/*symbol table size is not known now -- it is set at end of pass 2*/
/* entry point and stack size are zero for now*/
p = &couthd;
for(i=0; i<HDSIZE/2; i++) {
putw(*p++,&lbuf); /*write the file header words*/
}
savelc[0] = 0; savelc[1] = 0; savelc[2] = 0; savelc[3] = 0;
loctr = 0; /*location counter*/
rlflg = TEXT; /*TEXT relocatable*/
p2flg = 1; /*pass two*/
#ifdef UNIX
if (lseek(ifn,0L,0) == -1) { /*beginning of source*/
rpterr("seek error on source file\n");
abort();
}
#else
close(ifn); /* This way for goddamn Whitesmith's */
ifn=open(sfname,0,0); /* Re-open the fucking source file */
if(ifn < 0) /* Couldn't */
{
printf("Unable to open file %s\n",sfname);
abort();
}
#endif
close(itfn);
LASTCHTFN = itfnc;
itfn = openfi(tfilname,0); /*open it for reading*/
pline = 1; /*no lines printed*/
fchr=gchr(); /*get first char*/
while(ristb()) { /*pass 2 main loop*/
p2absln = stbuf[0].itop; /*line number*/
if(p2absln>=brkln2) /*for debugging the assembler*/
i=0;
opcpt = stbuf[2].itop.ptrw2; /*ptr to opcode entry in main tab*/
nite = stbuf[0].itrl & 0377; /*number of it entries*/
pnite = &stbuf[nite]; /*ptr to end of stmt*/
modelen = stbuf[2].itrl; /*instr mode length*/
p1inlen = stbuf[1].itrl; /*pass 1 instr length guess*/
opdix = ITOP1; /*first operand*/
pitw = &stbuf[ITOP1]; /*ptr to first operand*/
prsp = 0; /*special print flag off*/
instrlen = 2; /*default for print*/
if(opcpt->flags&OPDR) { /*opcode is a directive*/
i = opcpt->vl1; /*directive number*/
dirop = p2direct[i];
(*dirop)(); /*handle directive*/
}
else {
gcist(); /*generate code for one statement*/
}
}
}
/* generate code for an instruction*/
/* call with*/
/* intermediate text for instruction in stbuf*/
gcist()
{
register i,j;
if(stbuf[0].itty != ITBS) /*beginning of statement*/
abort();
format = (opcpt->flags)&OPFF;
in_err = 0; /*[vlh] no error this instruction, yet*/
ival = 0; /*initial value for possible operand*/
reloc = ABS;
instrlen = 2; /*at least 2 bytes*/
ins[0] = opcpt->vl1; /*opcode value*/
rlbits[0] = INSABS; /*instruction absolute*/
pins = &ins[1];
prlb = &rlbits[1];
if(nite>ITOP1) { /*operands*/
if(!format) {
uerr(9);
}
else if(format>LSTFRMT) /* [vlh] was a magic number... */
abort();
else {
(*opfary[format])();
}
}
if (!ckein() && !in_err) /* at end of statement ?? */
uerr(6);
print(1); /*print source*/
loctr =+ p1inlen;
if (!in_err && p1inlen != instrlen) /* [vlh] 2nd pass error recovery */
uerr(38);
outinstr(); /*write out instr binary*/
}
/* relative branches*/
relbr()
{
expr(&p2gi);
if(extflg) { /*external reference*/
instrlen =+ 2; /*long relative*/
*pins++ = ival; /*pass constant part*/
*prlb++ = (extref<<3)|EXTREL; /*ext ref*/
return;
}
ival =- (loctr+2); /*calc relative offset*/
if(itype!=ITCN || reloc != rlflg) {
uerr(22); /*invalid relative branch*/
ival = 0;
}
reloc = ABS;
if(p1inlen==4) { /*long displacement*/
if(ival< (-32768L) || ival > (32767L))
uerr(22);
instrlen =+ 2;
*pins++ = ival;
*prlb++ = DABS; /*data absolute*/
}
else { /*short displacement*/
if (ival>127 || ival<-128)
uerr(22);
ins[0] =| (ival.wd2&0377);
}
if (!ival) { /* make it a nop */
opcpt = nopptr;
ins[0] = opcpt->vl1.wd2;
pins = &ins[1];
if (modelen==4) {
*pins++ = opcpt->vl1.wd2;
rlbits[1] = INSABS;
}
}
in_err++; /* ignore extra eg. bra *+$d04(pc) vs. bra *+d04 */
}
/* format one -- add, sub, and, or, cmp, etc.*/
/* one operand must be a D reg (or A reg dest for add, sub, or cmp)*/
opf1()
{
register int *p;
if(get2ops())
return;
if (ins[0]==AND || ins[0]==OR)
if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
if (ins[0]==AND) opcpt = andiptr;
else opcpt = oriptr;
ins[0] = opcpt->vl1.wd2;
format = (opcpt->flags)&OPFF;
ccr_or_sr();
return;
}
p = f1mode;
if(ckdreg(&opnd[1])) { /*destn is D reg*/
if((opcpt==andptr||opcpt==orptr)&&ckareg(&opnd[0])) /*A source*/
uerr(20);
makef1(opnd[1].ea,p[modelen],&opnd[0]); /*make instr*/
return;
}
else if(ckdreg(&opnd[0]) && memalt(&opnd[1])) { /*source is D reg*/
if (pcea(&opnd[1])) uerr(10);
makef1(opnd[0].ea,p[modelen]+0400,&opnd[1]);
return;
}
else if(ckareg(&opnd[1])) { /*A reg is dstn*/
if(opcpt==addptr)
opcpt = addaptr;
else if(opcpt==cmpptr)
opcpt = cmpaptr;
else if(opcpt==subptr)
opcpt = subaptr;
else {
uerr(20);
return;
}
format = (opcpt->flags)&OPFF;
opnd[1].ea =& 07;
p = f15mode;
makef1(opnd[1].ea,p[modelen],&opnd[0]); /*make instr*/
return;
}
else if(!makeimm()) /*make an immediate instr*/
uerr(20);
}
/* format 2 -- addi, andi, subi, etc*/
opf2()
{
if(get2ops())
return;
if(ins[0]==ANDI || ins[0]==ORI || ins[0]==EORI) {
if(cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
ccr_or_sr();
return;
}
}
if(opnd[0].ea != IMM) {
uerr(9);
return;
}
if(!dataalt(&opnd[1]) || pcea(&opnd[1])) {
uerr(20);
return;
}
genimm();
}
/*format #3 -- move and movea*/
opf3()
{
register i,j,k;
if(get2ops())
return;
if(cksprg(&opnd[1],CCR)) {
ins[0] = MOVECCR;
opf3l1:
if (modelen==1 || modelen==4) uerr(34);
if(anysprg(&opnd[0]))
uerr(20);
ins[0] =| opnd[0].ea;
if(!dataea(&opnd[0]))
uerr(9);
doea(&opnd[0]);
return;
}
if(cksprg(&opnd[1],SR)) {
ins[0] = MOVESR;
goto opf3l1;
}
if(cksprg(&opnd[0],SR)) {
if (modelen==1 || modelen==4)
uerr(34);
if(anysprg(&opnd[1]))
uerr(20);
ins[0] = SRMOVE | opnd[1].ea;
if(!dataalt(&opnd[1]) || pcea(&opnd[1]))
uerr(10);
doea(&opnd[1]);
return;
}
if(cksprg(&opnd[0],USP)) {
if (modelen == 1)
uerr(34); /* default is word, can't test */
if (!ckareg(&opnd[1]))
uerr(33);
ins[0] = MOVEUSP|8|(opnd[1].ea&7);
return;
}
if(cksprg(&opnd[1],USP)) {
if (modelen == 1)
uerr(34); /* default is word, can't test */
if (!ckareg(&opnd[0]))
uerr(33);
ins[0] = MOVEUSP|(opnd[0].ea&7);
return;
}
k = ins[0];
ins[0] =| f3mode[modelen];
ckbytea();
ins[0] =| opnd[0].ea; /*source ea*/
doea(&opnd[0]);
ins[0] =| (opnd[1].ea&7)<<9; /*dest register*/
ins[0] =| (opnd[1].ea&070)<<3; /*dest mode*/
doea(&opnd[1]);
if(k==MOVEA) {
if(dataea(&opnd[1]))
uerr(20);
}
else if((pcea(&opnd[1]) && dataea(&opnd[1])) || opnd[1].ea==IMM)
uerr(20);
}
/* format 4 -- abcd, sbcd */
/* format 10 -- cmpm*/
/* format 27 -- addx, subx */
opf4()
{
if(get2ops())
return;
if (format==27) { /*addx,subx add in size bits*/
ins[0] =| f1mode[modelen];
}
else if(format==10) { /*cmpm*/
if((opnd[0].ea&070)!=INDINC || (opnd[1].ea&070)!=INDINC)
uerr(20);
ins[0] =| f1mode[modelen] | ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
return;
}
if(ckdreg(&opnd[0]) && ckdreg(&opnd[1])) {
ins[0] =| ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
return;
}
if((opnd[0].ea&070)==DECIND && (opnd[1].ea&070)==DECIND) {
ins[0] =| 010 | ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
return;
}
uerr(20);
}
/*format 5 -- div, mul*/
/*format 26 -- cmp, chk */
opf5()
{
if(get2ops())
return;
if(!ckdreg(&opnd[1])) {
if(opcpt==cmpptr) {
if(!dataea(&opnd[1])) /* [vlh] made define */
ins[0] =| f5amode[modelen]; /* was pumode */
else if(makeimm())
return;
else
uerr(20);
}
else
uerr(20);
}
if(opcpt==cmpptr) {
ins[0] =| f5mode[modelen]; /* was pumode */
ckbytea();
}
else if(!dataea(&opnd[0]))
uerr(20);
ins[0] =| (opnd[1].ea&7)<<9 | opnd[0].ea;
doea(&opnd[0]);
}
#define BTST 0000
/* format 7 -- bit instrs -- btst, bclr, bset, etc*/
opf7()
{
if(get2ops())
return;
if(opnd[1].ea==IMM||(ins[0]!=BTST&&pcea(&opnd[1]))||ckareg(&opnd[1]))
uerr(20);
if(ckdreg(&opnd[0])) {
ins[0] =| (opnd[0].ea<<9)|0400;
}
else { /*static bit #*/
if(opnd[0].con<0L || opnd[0].con>31 ||
(opnd[1].ea&INDIRECT&&opnd[0].con>7)) /* [vlh] */
uerr(23);
if(opnd[0].ea != IMM)
uerr(17);
ins[0] =| 04000;
dodisp(&opnd[0]);
}
if (modelen==1 && !(memea(&opnd[1]))) /*[vlh]*/
uerr(20);
else if (!(ckdreg(&opnd[1])) && modelen==4)
uerr(20);
ins[0] =| opnd[1].ea;
doea(&opnd[1]);
}
/* format 8 -- shifts and rotates*/
opf8()
{
register i;
getea(0); /*get first operand*/
if(pitw >= pnite) { /*end of all ops*/
if(ckdreg(&opnd[0])) { /*shift dreg one bit*/
cpop01(); /*copy opnd 0 to 1*/
opnd[0].ea = IMM;
opnd[0].con = 1L;
if (!ckdreg(&opnd[1])) uerr(20);
opf8l1:
if(opnd[0].con<1 || opnd[0].con>8) /*[vlh legal range 1..8*/
uerr(37);
ins[0] =| ((opnd[0].con.wd2&7)<<9)|f1mode[modelen]|opnd[1].ea;
return;
}
i = (ins[0]&077)<<6;
ins[0] =& 0177700;
ins[0] =| 0300|i|opnd[0].ea;
if(!memalt(&opnd[0]) || pcea(&opnd[0]) || modelen != 2)
uerr(20);
doea(&opnd[0]);
return;
}
if(!ckcomma()) {
uerr(10);
return;
}
getea(1); /*get second operand*/
if(!ckdreg(&opnd[1])) /* [vlh] second operand must be dreg */
uerr(20);
if(ckdreg(&opnd[0])) { /*first op is D reg*/
ins[0] =| (opnd[0].ea<<9)|040; /*reg # and reg bit*/
}
else {
if(opnd[0].ea != IMM)
uerr(20);
goto opf8l1;
}
ins[0] =| f1mode[modelen] | opnd[1].ea; /*put in size and reg #*/
}
/* format 9 -- jmp, jsr */
/* format 14 -- stop */
/* format 24 -- clr, neg, negx, not */
/* format 25 -- s?? */
/* format 29 -- pea */
/* one operand instructions -- jmp, clr, neg, not, sge, etc.*/
opf9()
{
getea(0);
if(format==24) { /*clr, not, etc*/
ins[0] =| f1mode[modelen]; /*add size bits*/
if(!dataalt(&opnd[0]) || pcea(&opnd[0]))
uerr(20);
}
else if(format==25) { /*tas,scc, etc*/
if(ckareg(&opnd[0]) || pcea(&opnd[0]) || opnd[0].ea==IMM)
uerr(20);
}
else if(format==14) { /*stop*/
if(modelen!=2 || opnd[0].ea!=IMM)
uerr(20);
doea(&opnd[0]);
return;
}
else if(!controlea(&opnd[0])) /*jmp, jsr, etc*/
uerr(20);
ins[0] =| opnd[0].ea;
doea(&opnd[0]);
}
/* format 11 -- dbcc*/
/* format 19 -- link*/
opf11()
{
if(get2ops())
return;
if(format==19) { /*link*/
if(!ckareg(&opnd[0]))
uerr(33);
if(opnd[1].ea != IMM)
uerr(17);
}
else {
if(!ckdreg(&opnd[0]))
uerr(33);
if(opnd[1].drlc!=rlflg) /*[vlh]don't chk opnd[1].ea!=LADDR||SADDR*/
uerr(22);
opnd[1].con =- (loctr+2L);
cksize(&opnd[1]);
opnd[1].drlc = ABS; /*not relocatable*/
}
ins[0] =| opnd[0].ea&7; /*put in reg #*/
dodisp(&opnd[1]);
}
/* format 12 -- exg*/
opf12()
{
register i;
if(get2ops())
return;
if(ckdreg(&opnd[0])) {
if(ckdreg(&opnd[1])) { /*exchange D regs*/
ins[0] =| 0100 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
return;
}
if(ckareg(&opnd[1])) { /*ins[0] <- A and D flag*/
ins[0] =| 0210 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
return;
}
}
if(ckareg(&opnd[0])) {
if(ckareg(&opnd[1])) { /*both a regs*/
ins[0] =| 0110 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
return;
}
if(ckdreg(&opnd[1])) { /*A and D regs*/
i = opnd[0].ea; /*exchg ea's*/
opnd[0].ea = opnd[1].ea;
opnd[1].ea = i;
ins[0] =| 0210 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
return;
}
}
uerr(20);
}
/* format 13 -- ext, unlk*/
/* format 18 -- trap*/
/* format 28 -- swap */
#define UNLK 047130
opf13()
{
getea(0);
if(format==18) { /*trap*/
if(opnd[0].con<0 || opnd[0].con>15)
uerr(15);
ins[0] =| opnd[0].con.wd2;
return;
}
if(ins[0]==UNLK) { /*unlk instr*/
if(!ckareg(&opnd[0]))
uerr(20);
}
else {
if(!ckdreg(&opnd[0]))
uerr(20);
if (format==13) /* ext */
ins[0] =| f13mode[modelen];
}
ins[0] =| opnd[0].ea&7;
}
/* format 15 -- adda, cmpa, suba*/
/* format 30 -- lea */
opf15()
{
register i;
if(get2ops())
return;
if(!ckareg(&opnd[1]))
uerr(33);
if(format==30) {
i = 0700;
if(!controlea(&opnd[0]))
uerr(20);
}
else
i = f15mode[modelen];
makef1(opnd[1].ea&7,i,&opnd[0]);
if (format==15 && opnd[0].ea != 071) cksize(&opnd[0]);
}
/*formats 16 and 17 -- addq, inc, subq, dec*/
opf17()
{
if(format==16) { /*inc or dec*/
clrea(&opnd[0]);
opnd[0].ea = IMM;
opnd[0].con = 1L;
opnd[0].drlc = ABS;
getea(1);
}
else {
if(get2ops())
return;
}
if(opnd[0].ea != IMM || !altea(&opnd[1]) || pcea(&opnd[1]))
uerr(20);
if(opnd[0].con<=0 || opnd[0].con>8)
uerr(15);
if(modelen==1 && !dataea(&opnd[1]))
uerr(34);
ins[0] =| f1mode[modelen]|((opnd[0].con.wd2&7)<<9)|opnd[1].ea;
doea(&opnd[1]);
}
/* format 20 -- movem */
int regmsk0[] {0100000,040000,020000,010000,04000,02000,01000,0400,0200,
0100,040,020,010,4,2,1};
int regmsk1[] {1,2,4,010,020,040,0100,0200,0400,01000,02000,04000,010000,
020000,040000,0100000};
opf20()
{
register dr;
register i,j;
dr = 0;
if(getreg() != -1 || pitw->itty == ITRM) { /*regs to memory*/
if (pitw->itty != ITRM) { /* [vlh] */
pitw--;
j = getrlist(regmsk0);
}
else {
j = pitw->itop;
pitw++;
}
if(!ckcomma())
uerr(10);
}
else
dr = 02000;
getea(0);
if(dr) {
if(!ckcomma())
uerr(10);
if (pitw->itty != ITRM) /* [vlh] */
j = getrlist(regmsk1); /*mem to regs*/
else {
j = pitw->itop;
j = fixmask(j);
pitw++;
}
}
else {
if(controlea(&opnd[0]))
j = fixmask(j);
}
i = opnd[0].ea&070;
if(!controlea(&opnd[0]) && i!=INDINC && i!=DECIND)
uerr(20);
if(modelen==4) /*long*/
ins[0] =| 0100;
ins[0] =| opnd[0].ea|dr;
*pins++ = j; /*reg mask*/
*prlb++ = DABS;
instrlen =+ 2;
doea(&opnd[0]);
if (!dr) { /* 1st argument (2nd is reg list) */
if (pcea(&opnd[0]) || (opnd[0].ea&070)==INDINC)
uerr(20); /* xx(pc), xx(pc,dx), -(ax) */
}
else /* 2nd argument (1st is reg list) */
if ((opnd[0].ea&070)==DECIND)
uerr(20); /* (ax)+ */
}
/*
* get a list of registers for the movem instr
* call with:
* ptr to reg-to-mem or mem-to-reg array of bits
*/
getrlist(ap)
int *ap;
{
register int *p,i,j;
register int mask;
p = ap;
mask = 0;
while((i=getreg()) != -1) {
if(ckitc(pitw,'-')) {
pitw++;
if((j=getreg()) == -1) {
uerr(40);
break;
}
while(i<=j)
mask =| p[i++];
}
else
mask =| p[i];
if(ckitc(pitw,'/'))
pitw++;
else
break;
}
if(!mask)
uerr(40);
return(mask);
}
/*reverse a movem register mask for control ea to memory*/
fixmask(msk)
{
register i,j,k;
k = (msk&1) ? 0100000 : 0;
i = 2;
j = 040000;
while(i) {
if(msk&i)
k =| j;
i =<< 1;
j =>> 1;
}
return(k);
}
/* format 21 -- movep*/
opf21()
{
register m,d;
register char *p;
if(get2ops())
return;
if(ckdreg(&opnd[0])) { /*d reg source*/
m = 0600;
d = opnd[0].ea;
p = &opnd[1];
}
else if(ckdreg(&opnd[1])) { /*d reg dest*/
m = 0400;
d = opnd[1].ea;
p = &opnd[0];
}
else {
uerr(20);
}
if((p->ea&070) != INDDISP)
uerr(20);
if(modelen == 4)
m =| 0100;
ins[0] =| (d<<9)|m|(p->ea&7);
*pins++ = p->con.wd2;
*prlb++ = p->drlc;
instrlen =+ 2;
}
/* format 22 -- moveq*/
opf22()
{
if(get2ops())
return;
if(opnd[0].ea != IMM)
uerr(17);
if(opnd[0].con>255L || opnd[0].con<-256L)
uerr(15);
if(!ckdreg(&opnd[1]))
uerr(33);
ins[0] =| (opnd[1].ea<<9) | (opnd[0].con.wd2&0377);
}
/* format 23 -- eor*/
opf23()
{
if(get2ops())
return;
if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
opcpt = eoriptr;
ins[0] = opcpt->vl1.wd2;
format = (opcpt->flags)&OPFF;
ccr_or_sr();
return;
}
if(!ckdreg(&opnd[0])) {
if(makeimm()) /*must be immediate*/
return;
uerr(20); /*or error*/
}
if(!dataalt(&opnd[1]) || pcea(&opnd[1]))
uerr(20);
ins[0] =| (opnd[0].ea<<9)|f23mode[modelen]|opnd[1].ea;
doea(&opnd[1]);
}

View File

@@ -0,0 +1,4 @@
$1lo68 -r -o as68.rel -f $1 -unofloat 0$1s.o dir.o expr.o main.o misc.o pass1a.o pass2.o strncmp.o symt.o 0$1lib6.a 0$1clib
era *.o
user 10!make $1

View File

@@ -0,0 +1,30 @@
/*********************************************************************
* STRNCMP - compares strings up to n chars
*
* WORD strncmp(s1,s2,n)
* BYTE *s1, *s2;
* UWORD n;
*
* 'strncmp' compares null terminated strings s1 and s2, and examines
* at most n chars.
* Always compares at least 1 char.
* n < 0 compares many, many characters.
* Returns:
* strncmp < 0 if s1<s2 (within n chars)
* strncmp = 0 if s1=s2 " " "
* strncmp > 0 if s1>s2 " " "
*********************************************************************/
#include <portab.h>
WORD strncmp(s1,s2,n)
REG BYTE *s1, *s2;
REG WORD n;
{
for( ; --n > 0 && (*s1 == *s2); s1++, s2++ )
{
if( *s1 == NULL )
return(0);
}
return(*s1 - *s2);
}

View File

@@ -0,0 +1,850 @@
/*
Copyright 1981
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "as68.h"
/* symbol table and misc routines*/
int errno;
char *ermsg[];
char tfilname[];
char initfnam[];
char ldfn[];
char tlab1[];
int stdofd;
int ftudp;
int poslab;
/*output it for beginning of statement*/
opitb()
{
stbuf[0].itty = ITBS; /*beginning of statement*/
stbuf[0].itop = (fchr!=EOLC) ? absln : absln-1;
stbuf[1].itty = ITSY; /*label entry*/
stbuf[1].itop.ptrw2 = lblpt; /*pointer to symbol or 0*/
/*put opcode in it buffer*/
stbuf[2].itty = ITSY;
stbuf[2].itrl = modelen; /*mode of instr(byte, word, long)*/
stbuf[2].itop.ptrw2 = opcpt; /*pointer to opcode in main table*/
stbuf[3].itty = ITCN;
stbuf[3].itrl = rlflg; /*relocation base*/
stbuf[3].itop = loctr; /*pass1 location counter*/
itwc = ITOP1; /*next available slot-currently 4*/
pitw = &stbuf[ITOP1].itty; /*init the pointer*/
}
/*
* get an input term (symbol, constant, or special character)
* call with:
* the first character in fchr
* returns:
* item type in itype
* item value in ival if item is a constant or special character
* if it is a symbol it is placed at the end of the main table
* meaning of state table:
* currently getting: symbol(0) constant(1) beginning(2)
* next char:
* digit(0) 0 1 1
* letter(3) 0 3 0
* special char(6) 3 3 3
* contents of the state table is the next state. processing stops when
* state 3 is encountered. state 2 is the beginning state.
*/
int sttbl[] {0,1,1,0,3,0,3,3,3}; /*state table for parser*/
gterm(constpc)
int constpc;
{
register smode, i;
register char *p;
register int tmode;
register char *j;
long num;
char istr[80];
/* if(fchr == '\'' || fchr == '"') */ /* Fucking Whitesmith's */
if(fchr == 047 || fchr == 042)
if(astring()) /*maybe ascii string*/
return;
smode = 2; /*beginning state*/
i = 0;
p = istr;
/*loop to put item on istr*/
while(fchr>=' ') { /*until a control char*/
if(smode==2 && fchr=='.')
tmode = 3;
else if(isalpha(fchr) || fchr=='~' || fchr=='_' || (fchr=='$'&&i))
tmode=3;
else if(isdigit(fchr))
tmode=0;
else
tmode = 6;
tmode = sttbl[tmode+smode]; /*new state*/
if(tmode==3) break; /*end of item*/
smode = tmode;
*p++ = fchr; /*save character*/
i++;
fchr=gchr();
}
/* end of item*/
switch(smode) {
case 0: /*symbol*/
*p = '\0'; /*end of symbol*/
itype = ITSY; /*symbol*/
pack(istr,lmte); /*put symbol at end of main table*/
j = lemt(sirt,FALSE);
if(istr[0]!='~' && !poslab && (j->flags&(SYEQ|SYER))==SYEQ) {
itype = (j->flags&SYRM) ? ITRM : ITCN; /* [vlh] */
ival = j->vl1;
reloc = ((j->flags)&SYRO) ? TEXT : ((j->flags)&SYRA) ? DATA :
((j->flags)&SYBS) ? BSS : ABS;
}
return;
case 1: /*constant*/
if(!constant(&num,istr,i)) {
uerr(17); /*illegal constant*/
num = 0;
}
ival = num;
itype = ITCN;
reloc = ABS;
return;
case 2: /*just a special char*/
switch(fchr) {
case '*': /*location counter*/
if(starmul) { /*multiply*/
starmul = 0;
goto specsy;
}
refpc++; /*referenced pgm ctr*/
reloc = rlflg; /*relocation of location counter*/
ival = loctr;
itype = (constpc) ? ITCN : ITPC;
break;
case '$': /*hex constant*/
oconst(16);
return;
case '@': /*octal const*/
oconst(8);
return;
case '%': /*binary const*/
oconst(2);
return;
case '#':
immed[opdix]++;
goto specsy;
case '(':
indir[opdix]++;
plevel++;
goto specsy;
case ')':
plevel--;
goto specsy;
default:
specsy:
itype = ITSP; /*return special char*/
ival = fchr;
}
if(fchr != EOLC)
fchr=gchr(); /*get next char*/
if((ival=='>' && fchr=='>') || (ival=='<' && fchr=='<'))
fchr=gchr(); /*shift op, ignore second char*/
return;
default:
abort(); /*not possible*/
}
}
/*check for an ascii string enclosed in single quotes*/
astring()
{
register char delim;
/* if(fchr != '\'' && fchr != '"') *//*valid delimiter*/
if(fchr != 047 && fchr != 042)
return;
delim = fchr;
if(equflg || (itype==ITSP && ival.wd2=='#')) { /*immediate operand*/
if(astr1(delim)) {
fchr = gchr();
if(fchr!=delim)
xerr(19);
fchr=gchr();
}
return((equflg) ? 1 : 0);
}
while(astr1(delim)) {
itype = ITSP;
ival = ','; /*separate by commas*/
reloc = ABS;
opitoo();
}
return(0);
}
astr1(adelim)
{
register delim,i,retv;
register long l;
delim = adelim;
i = 0; l = 0;
retv = 1;
while((fchr=gchr()) != EOF) {
if(fchr==delim) {
fchr = gchr();
if(fchr != delim) {
retv = 0; /*end of string*/
break;
}
}
if(fchr == EOLC) {
xerr(19);
retv = 0; /*end of string*/
break;
}
l = (l<<8) | fchr;
if(++i >= modelen) {
if((fchr=gchr()) == delim) {
fchr = gchr();
retv = 0; /*end of string*/
}
else
peekc = fchr; /*next char in string*/
break; /*filled one bucket*/
}
}
while(i < modelen) {
l =<< 8;
i++;
}
itype = ITCN;
ival = l;
reloc = ABS;
if(!equflg)
opitoo(); /*output one operand*/
return(retv);
}
/*get constant given radix*/
oconst(ardx)
{
register trdx,j;
register long i;
switch (ardx) { /* radix as power of 2 */
case 16 : trdx = 4; break;
case 8 : trdx = 3; break;
case 2 : trdx = 1; break;
default :
rpterr("invalid radix in oconst");
abort();
}
i=0;
while(1) {
fchr=gchr();
j=fchr;
if(isdigit(j))
j =- '0';
else if((j=tolower(j))>='a' && j<='f')
j = j-'a'+10;
else
break; /*not valid numeric char*/
if(j>=0 && j<ardx)
i = (i<<trdx)+j;
else
break;
}
ival = i;
itype = ITCN;
reloc = ABS;
}
/*convert ascii constant to binary*/
constant(pnum,pstr,idx)
long *pnum;
char *pstr;
{
register i,j;
register char *p;
register long l;
p = pstr;
l = 0;
for(i=0; i<idx; i++) {
j = *pstr++;
if(isdigit(j))
j =- '0';
if(j<0 || j>=10)
return(0);
l = (l<<3) + (l<<1) + j; /* l = l*10 + j*/
}
*pnum = l;
return(1);
}
/*
* method for looking up entries in the main table
*
* Note: The entry to be looked up must be placed at the end
* of the main table. The global cell 'lmte'(last main
* entry) points to the next available entry in the main
* table. The address of an initial reference table must
* also be provided.
*
* 1) Compute the hash code for the symbol and add it to the base address
* of the initial reference table given as input. Thus, two words are
* accessed which define the chain on which the symbol must be if it
* is in the table at all.
*
* 2) Alter the table link of the last symbol in the chain so that it
* points to the symbol being looked up. Note that the symbol to be
* looked up is always placed at the end of the main table before
* calling the lookup routine. This essentially adds one more element
* to the end of the chain, namely the symbol to be looked up.
*
* 3) Now start at the first symbol in the chain and follow the chain
* looking for a symbol equal to the smbol being looked up. It is
* guaranteed that such a symbol will be found because it is always
* the last symbol on the chain.
*
* 4) When the symbol is found, check to see if it is the last symbol
* on the chain. If not, the symbol being looked for is in the table
* and has been found. If it is the last symbol, the symbol being
* looked up is not in the table.
*
* 5) In the case the looked up symbol is not found, it is usually added
* to the end of the table. This is done simply b changing the
* initial reference table entry which points to the previous
* last symbol on the chain so that is now points to the symbol at the
* end of the main table. In case the symbol just looked up is not to
* be added to the main table then no action is needed . This means
* that the table link of the last symbol on a chain may point any-
* where.
*
* look up entry in the main table
* call with:
* address of initial reference table
* entry to be looked up at the end of the main table
* returns:
* a pointer to the entry. if this pointer is equal to
* lmte then the symbol was not previously in the table.
*/
char *lemt(airt,oplook)
char **airt;
int oplook; /* if true then looking in opcode table */
{
register char *mtpt;
register int *p1, *p2;
register int i, j;
if (oplook) { /* [vlh] get rid of preceding '.', to lowercase */
if (lmte->name[0]=='.') {
lmte->name[NAMELEN-1] = NULL; /* in case of '.' */
j = 1;
}
else j = 0;
for (i=0; j<NAMELEN; i++, j++)
lmte->name[i] = tolower(lmte->name[j]);
}
pirt = airt + hash(); /*hashed ptr to irt*/
mtpt = pirt->irfe; /*pointer to first entry in chain*/
if(!mtpt) /*empty chain*/
mtpt = lmte; /*start at end of main table*/
else
(pirt->irle)->tlnk = lmte; /*last entry in chain is new symbol*/
/*loop to locate entry in main table*/
lemtl:
p1 = &mtpt->name[0];
p2 = &lmte->name[0];
i = NAMELEN/(sizeof i);
while(i) {
if(*p1++ != *p2++) {
mtpt = mtpt->tlnk; /*go to next entry in chain*/
goto lemtl;
}
i--;
}
return(mtpt);
}
/* compute a hash code for the last entry in the main table*/
/* returns the hash code*/
hash()
{
register int i;
register ht1;
register char *p;
ht1 = 0;
p = &lmte->name[0];
for(i=0; i<NAMELEN; i++)
ht1 =+ *p++;
return(ht1&(SZIRT-2)); /*make hash code even and between 0 & SZIRT-2*/
}
/*
* Make an entry in the main table
* assumes :
* entry to be made is pointed at by lmte
* pirt points to the correct initial reference table entry.
*/
mmte()
{
pirt->irle = lmte; /*pointer to last entry in chain*/
if(pirt->irfe == 0) /*first entry in chain*/
pirt->irfe = lmte;
lmte =+ STESIZE; /*bump last main table entry pointer*/
if(lmte>=emte) { /*main table overflow*/
if(sbrk(STESIZE*ICRSZMT) == -1){ /*get more memory*/
rpterr("symbol table overflow\n");
endit();
}
else {
emte =+ STESIZE*ICRSZMT; /*move end of main table*/
cszmt =+ ICRSZMT;
}
}
}
/*
* make an entry in the main table for a directive
* call with:
* pointer to string containing directive name
* address of routine to handle directive in pass one
* address of routine to handle directive in pass two
*/
mdemt(mdstr,dirnum)
char *mdstr;
{
register char *mdept;
pack(mdstr,lmte); /*pack name at end of main table*/
mdept=lemt(oirt,TRUE); /*look up in opcode table*/
if(mdept != lmte) { /*best not be there already*/
uerr(5);
abort();
return;
}
mmte(); /*make main table entry*/
mdept->flags =| OPDR|SYIN; /*directive*/
mdept->vl1 = dirnum; /*directive #*/
}
/*
* pack a string into an entry in the main table
* call with:
* pointer to the string
* pointer to desired entry in the main table
*/
pack(apkstr,apkptr)
char *apkstr, *apkptr;
{
register i;
register char *pkstr, *pkptr;
pkstr = apkstr;
pkptr = apkptr;
i = NAMELEN;
while(*pkstr && i) {
*pkptr++ = *pkstr++;
i--;
}
while(i--)
*pkptr++ = '\0'; /*pad with nulls*/
}
/* function to get characters for source file*/
int xcol = 0; /* Column Counter */
int spcnt = 0; /* Space count for tab expansion */
gchr()
{
register chr1;
if(peekc) {
chr1 = peekc;
peekc = 0;
if(chr1 != SOH)
xcol--;
}
else if (spcnt)
{
spcnt--;
return(' ');
}
else
{
gchr1:
if(sbuflen<=0){ /*nothing on input buffer*/
sbuflen=read(ifn,sbuf,512); /*read in source*/
if(sbuflen<=0)
return(EOF); /*end of file*/
psbuf = sbuf;
}
chr1 = *psbuf++;
sbuflen--;
}
if (chr1 == SOH) /*preprocessor flag*/
goto gchr1; /*ignore it*/
if(chr1 == EOLC) { /*end of line*/
xcol = -1; /* Clear column counter */
if(!p2flg) /*pass 1 only*/
absln++;
}
if(chr1=='\t') /*convert tabs to spaces*/
{
spcnt += 7 - (xcol&7); /* This many spaces */
xcol += spcnt; /* New column number */
chr1 = ' ';
}
xcol++;
return(chr1);
}
/*
* write out intermediate text for one statement
* call with
* the it for the statement in stbuf
*/
wostb()
{
register int woix;
register short *itwo;
register int i;
if(stbuf[0].itty != ITBS) abort(); /*not beginning of stmt*/
itwo = &stbuf;
woix = stbuf[0].itrl & 0377; /*unsigned byte*/
while(woix--) {
for(i=0; i<(sizeof stbuf[0])/(sizeof *itwo); i++) {
doitwr(*itwo++);
}
}
/* debug(); //call debug package*/
}
doitwr(word)
short word;
{
short i;
if( pitix < itbuf || pitix > &itbuf[ITBSZ] ) {
printf("doitwr: it buffer botch\n");
endit();
}
if( pitix >= &itbuf[ITBSZ]) {
if(write(itfn,itbuf,ITBSZ*(sizeof i)) != ITBSZ*(sizeof i)) {
rpterr("it write error errno=%o\n",errno);
endit();
}
pitix = itbuf;
}
*pitix++ = word;
}
/*
* user source error
* call with:
* number to indicate reason for error
* types the error number and the line number on which
* the error occured.
*/
uerr(errn)
{
if(p2flg) { /*pass 2 gets two ampersands*/
in_err++; /* [vlh] instrlen <- pass1 estimation */
printf("&& %d: %s\n",p2absln,ermsg[errn-1]);
}
else
printf("& %d: %s\n",(fchr==EOLC)?absln-1:absln,ermsg[errn-1]);
nerror++;
}
/*
* user error that causes the statement to be abandoned
* call with:
* error number
*/
xerr(xern)
{
uerr(xern); /*type error message*/
if(!p2flg) /*pass one*/
igrst(); /*pass rest of source*/
}
/* abort the assembly*/
abort()
{
rpterr("as68 abort\n");
nerror++;
endit();
}
/*ignore rest of statement*/
igrst()
{
while(fchr!=EOLC && fchr!=EOF) /*until end of line*/
fchr=gchr();
while((fchr=gchr())==EOLC) ; /*ignore null lines*/
}
/*ignore blanks after a label*/
ligblk()
{
if(fchr == EOF) return;
igblk();
if(fchr==EOLC) {
fchr=gchr();
ligblk();
}
}
rubout()
{
nerror = -1;
endit();
}
/* exit from the assembler*/
endit()
{
LASTCHTFN = itfnc;
unlink(tfilname); /*delete temporary files*/
LASTCHTFN = trbfnc;
unlink(tfilname);
LASTCHTFN = dafnc;
unlink(tfilname);
LASTCHTFN = drbfnc;
unlink(tfilname);
if(nerror != -1) { /*not rubout*/
if(ftudp)
putchar('\n');
}
if(nerror > 0) {
fprintf(stderr,"& %d errors\n",nerror);
}
if (initflg)
unlink(ldfn); /* [vlh] get rid of empty .o file */
exit(nerror!=0);
}
/*
* open files
* call with:
* pointer to name of file to open
* flag for how to open
* 0 => read
* 1 => write
*/
openfi(pname,hflag)
char *pname;
{
register fd;
fd = (hflag==1) ? creat(pname,0666,1) : open(pname,hflag,1);
if(fd < 0) { /*open failed*/
rpterr("can't open %s errno=%o\n",pname,errno);
endit();
}
return(fd);
}
/* get a temp file for the intermediate text*/
char lastfile = 'A';
gettempf()
{
register i,j;
register char *p;
LASTCHTFN = lastfile++; /* Creat temp name */
if((j=creat(tfilname,0600,1)) >= 0)
return(j); /* File created OK */
rpterr("Unable to open temporary file\n");
endit();
}
/* move label name from lbt to main table entry pointed to by lmte*/
setname()
{
register i;
register int *p1, *p2;
p1 = &lmte->name[0];
for(p2 = &lbt[0]; p2 < &lbt[NAMELEN]; ) {
*p1++ = *p2;
*p2++ = 0;
}
}
/* get the initialized main table and initial reference tables from*/
/* the initialize file*/
getsymtab()
{
long j; /* length for read / write */
register char **p;
register struct symtab *p1;
register char *p2;
register fd,i;
if((fd=open(initfnam,0,1)) < 0) {
rerr:
printf("& Unable to read init file: %s\n", initfnam);
endit();
}
if(read(fd,sirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0])) {
goto rerr;
}
if(read(fd,oirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0]))
goto rerr;
if(read(fd,&j,(sizeof j)) != (sizeof j)) /* Read Count */
goto rerr; /* Y-U-K!!! */
if((i=read(fd,bmte,(int)j)) != j) /* Read table */
goto rerr;
if((i%STESIZE) != 0)
goto rerr;
lmte = bmte + i;
p2 = bmte-1;
for(p=sirt; p<&sirt[SZIRT]; p++) {
if(*p)
*p =+ (long)p2;
}
for(p=oirt; p<&oirt[SZIRT]; p++) {
if(*p)
*p =+ (long)p2;
}
for(p1=bmte; p1<lmte; p1++) {
if(p1->tlnk)
p1->tlnk =+ (long)p2;
}
close(fd);
}
/* write the initialization file*/
putsymtab()
{
long j;
register char **p;
register struct symtab *p1;
register char *p2;
register fd,i;
if((fd=creat(initfnam,0644,1))<0) {
printf("& Cannot create init: %s\n", initfnam);
return;
}
/*
* change all pointers so that they are relative to the beginning
* of the symbol table
*/
p2 = bmte-1;
for(p=sirt; p<&sirt[SZIRT]; p++) {
if(*p)
*p =- (long)p2;
}
for(p=oirt; p<&oirt[SZIRT]; p++) {
if(*p)
*p =- (long)p2;
}
for(p1=bmte; p1<lmte; p1++) {
if(p1->tlnk)
p1->tlnk =- (long)p2;
}
if(write(fd,sirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0])) {
goto werr;
}
if(write(fd,oirt,SZIRT*(sizeof oirt[0])) != SZIRT*(sizeof oirt[0]))
goto werr;
i = lmte - bmte; /*length of current main table*/
if((i % STESIZE) != 0) {
goto werr;
}
j = i;
if(write(fd,&j,(sizeof j)) != (sizeof j)) /* Y-U-K!! */
goto werr;
if(write(fd,bmte,i) != i) {
werr:
printf("& Write error on init file: %s\n",initfnam);
return;
}
close(fd);
}
/* print an error on file descriptor 2*/
/* used for errors with disasterous consequences*/
rpterr(ptch,x1,x2,x3,x4,x5,x6)
char *ptch;
{
if(prtflg==0) /* Check for paging output */
page(); /* Perform page checks */
fprintf(stderr,"& %d: ",absln);
fprintf(stderr,ptch,x1,x2,x3,x4,x5,x6);
}
/* set the file name for the relocatable object file (sourcefile.o)*/
setldfn(ap)
char *ap;
{
register char *p1,*p2;
p1 = ap;
p2 = ldfn;
while(*p1) {
*p2++ = *p1++;
}
if(*(p2-2) != '.') { /*not name.?*/
*p2++ = '.';
*p2++ = 'o';
}
else { /* is name.? */
*(p2-1) = 'o';
}
*p2 = '\0';
}
savelab()
{
register int *p1, *p2;
p2 = &lmte->name[0];
for(p1= &tlab1[0]; p1 < &tlab1[NAMELEN]; )
*p1++ = *p2++;
}

View File

@@ -0,0 +1,19 @@
e:vax DIR.C s
e:vax EXPR.C s
e:vax MAIN.C s
e:vax MISC.C s
e:vax PASS1A.C s
e:vax PASS2.C s
e:vax MAKE.SUB s
e:vax STRNCMP.C s
e:vax SYMT.C s
e:vax VERSION.C s
e:vax AS68.H s
e:vax COUT.H s
e:vax CTYPE.H s
e:vax MACHINE.H s
e:vax RELINK.SUB s
e:vax MACHINE.11 s
e:vax MACHINE.68K s
e:vax MACHINE.VAX s
e:vax AS68INIT. s

View File

@@ -0,0 +1 @@
char *version "@(#) Tue Nov 23 14:31";

View File

@@ -0,0 +1,15 @@
$ asm
$ !
$ ! as68 Version 2.3 make file for VMS
$ !
$ set noon
$ copy machine.vax machine.h
$ cx AS68INIT
$ cx DIR
$ cx EXPR
$ cx MAIN
$ cx MISC
$ cx PASS1A
$ cx PASS2
$ cx SYMT
$ @vrelink

View File

@@ -0,0 +1 @@
$ clink AS68INIT,DIR,EXPR,MAIN,PASS1A,PASS2,SYMT,MISC,lib:klib/lib as68

View File

@@ -0,0 +1,3 @@
c68 -L -e *.c -o c068.68 -l6
c68 -L -r -n -e *.c -o c068.st -l6
cc -f *.c -o c068.11 -lP -lx

View File

@@ -0,0 +1,968 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
#define DREG 0100 /*data loadable into D-register?*/
char dinfo[] {
0, /*TYPELESS=0*/
1|DREG, /*CHAR=1*/
2|DREG, /*SHORT=2*/
2|DREG, /*INT=3*/
4|DREG, /*LONG=4*/
1|DREG, /*UCHAR=5*/
2|DREG, /*USHORT=6*/
2|DREG, /*UNSIGNED=7*/
4|DREG, /*ULONG=8*/
4|DREG, /*FLOAT=9[vlh]*/
4|DREG, /*DOUBLE=10[vlh]*/
0, /*STRUCT=11*/
0, /*FRSTRUCT=12*/
0, /*LLABEL=13*/
0, /*INVALID=14*/
0, /*INVALID=15*/
};
char aregtab[] { AREG5, AREG4, AREG3, 0 };
char dregtab[] { DREG7, DREG6, DREG5, DREG4, DREG3, 0 };
int inittype;
/*
* doextdef - external definition syntax
* This is fairly complicated since you do not know if you are
* parsing a external function declaration or a real function
* until after you've already scanned the argument list for the
* function. Basically you start off scanning an external declaration
* or function in the same way by collecting attributes, scanning
* the declarator, then scanning the function arguments if a function.
* At that point you look at the next token and if its a '{', keyword
* proceed accordingly.
* The C Syntax handled by this routine is (roughly):
* external_definition:
* function_definition
* data_definition
* function_definition:
* type_specifier function_declarator function_body
* function_declarator:
* declarator ( parameter_list )
* data_definition:
* EXTERNAL type_specifier init_declarator_list ;
* STATIC type_specifier init_declarator_list ;
*/
doextdef() /* returns 0 for EOF or 1*/
{
register struct symbol *sp;
register int dflag;
int sc, type;
long size;
if(!next(SEMI)) {
opap = exprp = exprarea;
sc = EXTERNAL;
type = (xflag?LONG:INT);
dflag = gettype(&sc,&type,&size);
if(type==STRUCT) /* deal with forward ref structures */
chksyms();
while( dodecl(sc,type,0,size), (sp=dsp) != 0 ) {
if( !dflag && notfunction(sp->s_type) ) {
synerr("external definition syntax");
return;
}
if( !stypedef(sp) && sc != STATIC )
if (notfunction(sp->s_type)) /*[vlh] .globl ext. vars*/
outextdef(sp->s_symbol);
if( notfunction(sp->s_type) ) { /*not function, check init*/
if( !stypedef(sp) ) {
doinit(sp);
if (sc == STATIC)
chksyms();
}
}
else if( peek(RESWORD) || peek(LCURBR) ||
(peek(SYMBOL) && stypedef(csp)) ) {
if(!stypedef(sp) && sc!=STATIC) /*[vlh] .globl local proc*/
outextdef(sp->s_symbol);
funcbody(sp);
return;
}
dsp = 0;
if( !next(COMMA) )
break;
}
if( gettok() != SEMI )
synerr("external definition syntax");
}
}
/*
* gettype - get attribute types in attribute list
* Handles single word keywords, such as int, char, etc. and also
* handles the declarations of structures and unions.
*/
gettype(defsc,deftype,size) /* returns 0 for no type, 1 otherwise*/
int *defsc; /* default storage class*/
int *deftype; /* default data type*/
long *size; /* size of data element 3.4 int=>long*/
{
register int dtype, sc;
register int sflag, uflag, lflag, decflag;
register int token, stdflag, sbits;
long tsize;
register struct symbol *sp, *parent;
tdp = 0; tdflag = uflag = decflag = lflag = sflag = 0; tsize = 0L;
dtype = TYPELESS;
sc = *defsc;
for( ; ; decflag++ ) {
if( (token=gettok()) == SYMBOL && stypedef(csp) ) {
dtype = 0;
tdp = csp;
continue;
}
if( token != RESWORD )
break;
switch( cvalue ) {
case R_TYPEDEF:
if( tdflag )
error("invalid typedef statement");
tdflag++;
continue;
case R_STATIC:
if( sc && sc != STATIC && sc != EXTERNAL )
error("invalid storage class");
sc = STATIC;
continue;
case R_AUTO:
if( sc && sc != AUTO )
error("invalid storage class");
sc = AUTO;
continue;
case R_EXTERNAL:
if( sc && sc != EXTERNAL )
error("invalid storage class");
sc = EXTERNAL;
continue;
case R_REGISTER:
if( sc && sc != REGISTER && sc != PDECLIST )
error("invalid register specification");
sc = REGISTER;
continue;
case R_LONG:
lflag++;
continue;
case R_SHORT:
sflag++;
continue;
case R_UNSIGNED:
uflag++;
continue;
case R_STRUCT:
cvalue = STRUCT;
case R_UNION:
stdflag = tdflag;
tdflag = 0; sp = 0;
token = cvalue;
smember++;
if( next(SYMBOL) ) { /*struct [symbol] { ... }*/
sp = csp;
parent = csp;
strucptr[smember+instruct] = sp;
if( !sp->s_sc ) {
sp->s_attrib =| SDEFINED;
if(!infunc)
sp->s_attrib =| SGLOBAL;
sp->s_sc = STRPROTO;
sp->s_type = STRUCT;
sp->s_ssp = dalloc(0L);
}
if( sp->s_sc != STRPROTO )
error("redeclaration: %.8s",sp->s_symbol);
}
else parent = 0;
smember = 0;
if( next(LCURBR) ) {
instruct++;
strucptr[smember+instruct] = sp;
sbits = boffset;
boffset = 0;
tsize = dlist(token==STRUCT?STELCL:UNELCL);
boffset = sbits;
if(!next(RCURBR))
synerr("structure declaration syntax");
else if( sp ) {
if( dtab[sp->s_ssp] )
error("redeclaration: %.8s",sp->s_symbol);
dtab[sp->s_ssp] = tsize;
}
instruct--;
}
else if( !sp )
error("no structure name");
else if( sp->s_sc != STRPROTO )
error("invalid structure prototype: %.8s",sp->s_symbol);
else if( !dtab[sp->s_ssp] ) { /* FRSTRUCT */
token = FRSTRUCT;
if( ++frstp >= NFRSTR )
ferror("structure table overflow");
frstab[frstp] = sp;
}
else
tsize = dtab[sp->s_ssp];
tdflag = stdflag;
if( dtype != TYPELESS )
error("invalid type declaration");
dtype = (token == R_UNION) ? STRUCT : token;
continue;
case R_INT:
if( dtype != TYPELESS )
error("invalid type declaration");
dtype = INT;
continue;
case R_CHAR:
if( dtype != TYPELESS )
error("invalid type declaration");
dtype = CHAR;
continue;
case R_FLOAT: /*[vlh] ver. 3.4*/
case R_DOUBLE:
if( dtype != TYPELESS )
error("invalid type declaration");
dtype = FLOAT;
continue;
}
break;
}
pbtok(token);
if( dtype == TYPELESS )
dtype = INT;
if(!sc)
sc = AUTO;
if( lflag ) { /*allow: long float, long int*/
if( dtype == INT )
dtype = LONG;
/* else if( dtype == FLOAT ) */
/* dtype = DOUBLE; */
else
error("invalid long declaration");
}
if( sflag ) {
if( dtype != INT )
error("invalid short declaration");
}
if( uflag ) {
if( dtype != INT ) /*allow: unsigned int*/
error("invalid unsigned declaration");
else
dtype = UNSIGNED;
}
if( !sflag && xflag && dtype == INT )
dtype = LONG;
*defsc = sc;
*deftype = dtype;
*size = tsize;
if (dtype == STRUCT || dtype == FRSTRUCT)
csp->s_struc = parent;
return(decflag);
}
/*
* dodecl - process a single declarator
* This does all the grubby handling of a single declarator given
* the attributes for the declarator. Handles typedef attributes
* adjusts offsets for structure elements, allocates register
* variables, etc.
*/
long /* [vlh] 3.4 int => long */
dodecl(sc,type,offset,size) /* returns size of declarator*/
int sc; /* storage class*/
int type; /* data type*/
int offset; /* offset if in structure or union*/
long size; /* size of single data item 3.4 i=> l*/
{
register struct symbol *sp;
register int redecf, stype, dtype, i, j;
if( peek(SEMI) || peek(RPAREN) )
return(0);
if( instruct && next(COLON) ) { /*handle bit filler field*/
if(!(i=cexpr()))
size = salign(INT,offset);
else
size = falign(type,i);
}
else if( (type=|declarator(0)) >= 0 && (sp=dsp) != 0 ) {
if( tdp ) /*typedef name in declaration*/
type = addtdtype(tdp,type,sp->s_dp,&(sp->s_ssp));
else if( btype(type) == STRUCT ) {
if( size )
sp->s_ssp = dalloc(size);
else
error("invalid structure declaration: %.8s",sp->s_symbol);
}
else if( btype(type) == FRSTRUCT )
sp->s_ssp = frstp;
redecf = 0;
switch( sp->s_sc ) { /*check for redeclarations.*/
case 0:
break;
case PARMLIST:
if( sc != PDECLIST && sc != REGISTER )
goto redec;
break;
case BFIELDCL:
if( sc != STELCL && sc != UNELCL )
goto redec;
break;
case STELCL:
case UNELCL:
redecf++;
break; /* [vlh] get rid of redecf entirely ?? */
case EXTERNAL:
if (sp->s_type == type) {
if (sc == sp->s_sc) break;
if (sc == AUTO && suptype(type) == FUNCTION) {
sc = EXTERNAL;
break;
}
}
default:
redec:
error("redeclaration: %.8s",sp->s_symbol);
return(size);
}
sp->s_type = type;
dtype = suptype(type);
type = btype(type);
if( tdflag ) /*we are declaring typedef?*/
sp->s_attrib =| STYPEDEF;
if( instruct ) {
if( next(COLON) ) { /*handle bit field*/
sc = BFIELDCL;
i = cexpr();
j = (boffset<<8)|i;
if( redecf && sp->s_dp != j ) /* ??? */
goto redec;
sp->s_dp = j;
size = j = falign(type,i);
}
else
size = dsize(sp->s_type,sp->s_dp,sp->s_ssp) +
(j=salign(type,offset));
offset =+ j;
/* if( redecf && sp->s_offset != offset )
goto redec; */ /* [vlh] */
sp->s_offset = offset;
}
if( dtype == FUNCTION ) {
if( sc != AUTO && sc != EXTERNAL && sc != STATIC )
error("illegal function declaration");
if( sc != STATIC )
sc = EXTERNAL;
}
else if( sc == REGISTER ) {
if( !dtype ) {
if( !(dinfo[type]&DREG) ) { /* ignore reg specification */
/* error("illegal register specification"); */
sc = AUTO;
}
else if( !dregtab[ndregs] )
sc = AUTO;
else
sp->s_offset = dregtab[ndregs++];
}
else if( dtype != POINTER ) {
error("illegal register specification");
sc = AUTO; /*no more regs, make it auto*/
}
else if( !aregtab[naregs] )
sc = AUTO;
else
sp->s_offset = aregtab[naregs++];
}
if( sc == AUTO ) {
localsize =+ walign(dsize(sp->s_type,sp->s_dp,sp->s_ssp));
sp->s_offset = -localsize;
}
else if( sc == STATIC )
sp->s_offset = nextlabel++;
sp->s_sc = sc;
sp->s_attrib =| SDEFINED;
if(!infunc)
sp->s_attrib =| SGLOBAL;
}
return(size);
}
/*
* doinit - do external definition initialization
* Handles following C syntax:
* initializer:
* = constant_expression
* = { initializer_list }
* = { initializer_list , }
* initializer_list:
* constant_expression
* initializer_list , initializer_list
* { initializer_list }
*/
doinit(sp) /* returns number of elements init'ed*/
struct symbol *sp; /* pointer to symbol to init*/
{
register int type;
long isize, datasize, elsize;
type = sp->s_type;
datasize = dsize(type,sp->s_dp,sp->s_ssp);
if( peek(COMMA) || peek(SEMI) ) { /*no initialization*/
isize = walign(datasize);
if( sp->s_sc == EXTERNAL )
outcommon(sp->s_symbol,isize);
else {
outbss(); /*bss segment*/
outlab(sp->s_offset);
outresmem(isize);
outtext(); /*resume text segment*/
}
}
else {
next(ASSIGN); /*ignore '=' if there*/
if( type == LONG || pointer(type) )
outldata();
else if(type == DOUBLE || type == FLOAT) /*[vlh] 3.4*/
outfpdata();
else
outdata();
if( sp->s_sc == EXTERNAL )
outdlab(sp->s_symbol);
else
outlab(sp->s_offset);
isize = initlist(sp->s_type,sp->s_dp,sp->s_ssp);
if( isize < datasize ) {
outresmem(datasize-isize);
isize = datasize;
}
if( walign(isize) != isize )
outpad();
if( isize > datasize ) {
if( array(sp->s_type) ) {
for( type = sp->s_type; array(type); type = delsp(type) )
;
dtab[sp->s_dp] = isize / dsize(type,sp->s_dp,sp->s_ssp);
}
else
error("too many initializers");
}
if( sp->s_sc == STATIC )
outtext();
}
}
/*
* initlist - handles initializer lists
* This handles multi-level braces, and a character pointer pointing
* to a string. Most of the work is in keeping track of how many
* bytes are left on the current "row", and outputting padding if
* necessary.
*/
long
initlist(type,dp,sp) /* returns size of initializers in*/
/* bytes*/
int type; /* type of data*/
int dp; /* dimension pointer*/
int sp; /* structure pointer*/
{
register int nrows;
long datasize, i, elsize, nbleft, nbout; /* [vlh] 3.4 int=>long */
register int onetype;
for( onetype = type; array(onetype); onetype = delsp(onetype) )
;
nbout = 0;
datasize = dsize(type,dp,sp);
nbleft = 0; /*keep track of no. of bytes left*/
if( type == (ARRAY|CHAR) && next(STRING) ) {
nbout = cstrsize;
outstr();
if( datasize > nbout )
nbleft = datasize - nbout;
}
else if( array(type) || (btype(type)==STRUCT && notpointer(type)) ) {
elsize = datasize / dsize(delsp(type),dp+1,sp);
elsize = datasize / elsize;
if(!next(LCURBR))
error("missing { in initialization");
if( type == (ARRAY|CHAR) && next(STRING) ) {
nbout = cstrsize;
outstr();
if( datasize > nbout )
nbleft = datasize - nbout;
}
else {
do { /*in current row.*/
if( peek(SEMI) || peek(EOF) )
break;
if( peek(LCURBR) ) { /*recurse down one level?*/
if( nbleft ) {
outresmem(nbleft); /*pad rest of current row*/
nbout =+ nbleft;
nbleft = 0;
}
i = initlist(delsp(type),dp+1,sp);
if( i > elsize )
error("initializer list too long");
else if( i < elsize )
outresmem(elsize-i);
nbout =+ elsize;
}
else if( peek(RCURBR) )
break;
else {
i = oneinit(onetype);
nbout =+ i;
if(!nbleft)
nbleft = elsize;
if( i > nbleft )
error("initializer alignment");
nbleft = (i >= nbleft) ? 0 : nbleft - i;
}
} while( next(COMMA) );
}
if(!next(RCURBR))
synerr("missing }");
}
else {
i = next(LCURBR); /*pull of optional {*/
nbout = oneinit(onetype);
if( i && !next(RCURBR) )
synerr("missing }");
}
if( nbleft ) { /*pad current row*/
outresmem(nbleft);
nbout =+ nbleft;
}
return(nbout);
}
/*
* oneinit - get one initializer expression or constant
* This checks the type of the data item expected against the
* type obtained from expr. Note that there is no attempt to
* match structure initializations against the elements of the
* structure, hence, anything goes in a structure.
*/
oneinit(type) /* returns size of initializer*/
int type; /* type of initializer*/
{
register int op, value;
register struct tnode *tp;
commastop++;
tp = expr();
commastop--;
op = tp->t_op;
value = tp->t_value;
switch( alltype(type) ) {
case CHAR:
case ARRAY|CHAR:
if( op != CINT )
break;
outc(CHAR,value);
return(1);
case INT:
case ARRAY|INT:
if( op == CLONG || op == ADDR )
if (op == CLONG && clvalue == -32768) { /*[vlh] 4.0*/
op = CINT;
value = -32768;
}
else
break;
if( op == CINT )
outc(INT,value);
else
outinit(tp,inittype);
return(2);
case UNSIGNED: /* [vlh] 4.0 split from INT... */
case ARRAY|UNSIGNED:
if (op == ADDR)
break;
if( op == CLONG ) { /* get unsigned values > legit pos ints */
if (clvalue < 0L || clvalue > 65535L)
break;
op = CINT;
value = clvalue & 0x7fff;
if (clvalue > 32767)
value = -value;
}
else if (op == CINT && value < 0)
break;
if( op == CINT )
outc(INT,value);
else
outinit(tp,inittype);
return(2);
case LONG:
case ARRAY|LONG:
case POINTER|CHAR:
case POINTER|INT:
case POINTER|LONG:
case POINTER|STRUCT:
case POINTER|UNSIGNED:
if( op == CINT ) {
clvalue = value; /*[vlh] fix ??? MC ??? */
outlong(clvalue);
}
else if( op == CLONG )
outlong(clvalue);
else
outinit(tp,inittype);
return(4);
case DOUBLE: /* [vlh] 3.4 */
case FLOAT:
outfp(clvalue);
return(4);
case STRUCT:
case ARRAY|STRUCT:
if( op == CINT ) {
if( xflag ) {
clvalue = value;
outlong(clvalue);
return(4);
}
outc(INT,value);
return(2);
}
if( op == CLONG ) {
outlong(clvalue);
return(4);
}
outinit(tp,inittype);
if (xflag || op==ADDR)
return(4);
if ((op=tp->t_right->t_op)==ADDR || op==CLONG) /*[vlh]*/
return(4);
if ((op=tp->t_left->t_op)==ADDR || op==CLONG) /*[vlh]*/
return(4);
return(2);
}
error("invalid initializer");
return(0);
}
/*
* funcbody - do function body declaration
* Basically handles function after we have scanned the parameter
* list, which is now set up in fargs array. We now proceed to
* look for any declarations for the function arguments, then the
* function declaration list, followed by the function statement list.
* The C syntax is:
* function_body:
* type_decl_list function_statement
* function_statement:
* { declaration_list statement_list }
*/
funcbody(fsp)
struct symbol *fsp;
{
register int olddp;
register struct symbol *sp;
register struct farg *fp;
register int offset, toff;
infunc++;
sp = fsp;
opap = exprp;
frp = snalloc(delsp(sp->s_type),sp->s_sc,sp->s_type,sp->s_dp,
sp->s_ssp);
exprp = opap;
outtext();
outflab(sp->s_symbol);
olddp = cdp;
dlist(PDECLIST);
rlabel = nextlabel++;
if(!next(LCURBR))
synerr("function body syntax");
else {
localsize = 0; /*end of first auto offset from l.e.p.*/
offset = 8; /*first arg offset from l.e.p.*/
for( fp = &fargtab[0]; sp = fp->f_sp; fp++ ) {
toff = offset;
if( sp->s_type == CHAR ) /*char argument*/
toff++; /*offset of lower byte in word*/
if( sp->s_sc == REGISTER )
fp->f_offset = toff;
else {
fp->f_offset = 0; /*really is auto arg*/
sp->s_offset = toff;
sp->s_sc = AUTO;
}
if( array(sp->s_type) ) { /*change array ref to pointer*/
sp->s_type = addsp(delsp(sp->s_type),POINTER);
sp->s_dp++;
}
offset =+ walign(dsize(sp->s_type,sp->s_dp,sp->s_ssp));
}
dlist(0);
chksyms();
outbentry(localsize,ndregs,naregs);
copyargs(); /*copy args to registers where required*/
while(!next(RCURBR)) {
if( next(EOF) ) {
error("{ not matched by }");
break;
}
stmt();
}
}
outlab(rlabel);
outbexit(ndregs,naregs);
cdp = olddp;
infunc--;
freesyms();
}
/*
* copyargs - copy args to register where required
* fargtab has been set so that args declared to be registers have a
* non-zero offset value and the register number is in the symbol
* table pointed to by symbol.
*/
copyargs() /* returns - none*/
{
register struct symbol *sp;
register struct farg *fp;
for( fp = &fargtab[0]; sp = fp->f_sp; fp++ ) {
if( fp->f_offset ) /*was declared register*/
outassign(snalloc(sp->s_type,sp->s_sc,sp->s_offset,0,0),
snalloc(sp->s_type,AUTO,fp->f_offset,0,0));
}
}
/*
* dlist - declaration list
* Handles declaration lists in the following places:
* function parameter list declarations, structure or union member
* declarations and local declarations in functions.
*/
long
dlist(defsc) /* returns length of declarators*/
int defsc; /* default storage class*/
{
register int offset;
register struct symbol *sp;
register long i, ddsize;
long size; /* [vlh] 3.4 int => long */
int type, sc, isize;
offset = 0; ddsize = 0L;
do {
sc = defsc;
type = INT;
if( !gettype(&sc,&type,&size) )
break;
do {
i = dodecl(sc,type,offset,size);
if( defsc != UNELCL ) {
isize = i;
offset =+ isize;
ddsize =+ i;
}
else if( i > ddsize )
ddsize = i;
if( sc == STATIC && dsp && !stypedef(dsp) )
doinit(dsp); /*process any initializer*/
dsp = 0;
} while ( next(COMMA) );
if (next(ASSIGN)) {
synerr("auto initialization not implemented");
break;
}
if(!next(SEMI)) {
synerr("declaration syntax");
break;
}
} while( 1 );
isize = ddsize;
ddsize =+ salign(INT,isize);
return(ddsize);
}
/*
* declarator - get one declarator
* Basically uses getdecl, which returns the declaration types
* reversed in the type word.
*/
declarator(castflg) /* returns type or -1*/
int castflg;
{
register int type, t;
dsp = 0;
if( (type=getdecl(castflg)) >= 0 )
return( revsp(type) );
return(type);
}
/*
* getdecl - get one declarator, handling *, (), etc.
* The significance of the value returned by declarator is: the
* least significant two bits represent the values (POINTER,FUNCTION,
* ARRAY), these values are repeated through the word. For example,
* the declarations result in the following values for declarator:
* *x() => (POINTER,FUNCTION)
* (*x)() => (FUNCTION,POINTER)
* *(*x)() => (POINTER,FUNCTION,POINTER)
* The following C syntax is handled here:
* function_declarator:
* declarator ( parameter_list )
* declarator:
* identifier
* ( declarator )
* * declarator
* declarator [ constant-expression ]
*/
getdecl(castflg) /* returns special type of declarator*/
int castflg; /* casting flag, 1=>allow no declarator*/
{
register int type, i, value, sdp;
register struct symbol *sp, *tsp;
register struct farg *fp;
register char *p;
long lvalue;
type = 0;
if( next(LPAREN) ) { /*( declarator ) ...*/
type = getdecl(castflg);
if(!next(RPAREN))
goto baddec;
}
if( next(MULT) )
return(addsp(getdecl(castflg),POINTER));
sdp = cdp;
if( next(SYMBOL) ) {
sp = dsp = csp;
type = 0;
sp->s_dp = sdp;
}
while( 1 ) {
if( next(LPAREN) ) { /*declarator ( ... )*/
if(!infunc) {
ndregs = naregs = 0;
for( fp = &fargtab[0]; next(SYMBOL); ) {
p = csp;
if( p->s_attrib & SDEFINED )
error("redeclaration: %.8s",p->s_symbol);
else if( fp >= &fargtab[NFARGS-1] ) {
synerr("too many params");
break;
}
else {
p->s_attrib =| SDEFINED;
p->s_sc = PARMLIST;
p->s_type = INT; /*default to int*/
fp->f_sp = p;
fp++;
}
if(!next(COMMA))
break;
}
fp->f_sp = 0;
}
if(!next(RPAREN))
break;
type = addsp(type,FUNCTION);
continue;
}
if( next(LBRACK) ) { /*declarator [ cexpr ]*/
if( next(RBRACK) )
dalloc(1L);
else {
tsp = dsp; /* [vlh] 3.4 save in case of reset */
value = cexpr(); /* recurses on sizeof.... resets dsp */
dsp = tsp; /* [vlh] 3.4 */
lvalue = value; /* [vlh] 3.4 */
for( i = sdp; i < cdp; )
dtab[i++] =* lvalue;
dalloc(lvalue);
if( !next(RBRACK) )
break;
}
type = addsp(type,ARRAY);
continue;
}
if( castflg || dsp )
return(type);
break;
}
baddec:
synerr("invalid declarator");
return(-1);
}
/*
* addtdtype - add typedef info into declarator
* here we very carefully add in the dimensions for an array typedef
* declaration. Note that declarator has already allocated the
* declarator-specific dimensions, now we allocate the typedef
* dimensions and adjust the size of the declarator's dimensions.
* Note that this must be done before the dalloc for the structure,
* otherwise we would mix up array and structure sizes.
*/
addtdtype(tddp,type,dp,ssp) /* returns type*/
struct symbol *tddp;
int type;
int dp;
int *ssp;
{
register int ntype, t, i, tdf;
for( tdf = 0, t = tddp->s_type; suptype(t); t = delsp(t) )
if( array(t) ) {
tdf++;
break;
}
ntype = 0;
for( t = type, i = dp; suptype(t); t = delsp(t) ) {
ntype = addsp(ntype,t);
if( tdf && array(t) )
dtab[i++] =* dtab[tddp->s_dp];
}
for( t = tddp->s_type, i = tddp->s_dp; suptype(t); t = delsp(t) )
if( array(t) )
dalloc(dtab[i++]);
for( t = tddp->s_type; suptype(ntype); ntype = delsp(ntype) )
t = addsp(t,ntype);
if( (ntype=btype(t)) == STRUCT )
*ssp = tddp->s_ssp;
else if( ntype == FRSTRUCT )
*ssp = frstp;
return(t);
}

View File

@@ -0,0 +1,910 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
int opdontop;
int strassign;
/*
* expr - expression evaluator
* This handles all the expression syntax in C. This is a straight-
* forward operator-stack/oppri scheme for translating infix into
* a binary expression tree.
*/
char *expr() /* returns 0 or ptr to node*/
{
register char *p;
register char *opdsave, *oprsave;
register int token, op, oppri, i, opdotsave;
int type, sc;
long size;
opdsave = opdp;
strassign = 0;
oprsave = opp;
opdotsave = opdontop;
if( !opp || !opdp ) {
opp = opstack;
opdp = opdstack;
}
else
opp++;
opp->o_op = STACKEND;
opp->o_pri = STKPRI;
opap = exprp;
opdontop = 0;
while( (token=gettok()) != EOF ) {
switch( token ) {
/*
* the following are the terminal nodes of the expresion tree,
* note that when we see a terminal node, we push it and then go
* and get the next token. When we see an operator, we need to
* check the operator stack to see if we can do a reduction.
*/
case CINT:
if( doopd(cnalloc(INT,cvalue)) ) {
exprerr:
if( token == SEMI || token == RCURBR )
pbtok(token);
error("invalid expression");
opdp = opdsave;
opp = oprsave;
opdontop = opdotsave;
return(0);
}
continue;
case CFLOAT: /*[vlh] 3.4*/
if( doopd(fpcnalloc(FLOAT,clvalue)) )
goto exprerr;
continue;
case CLONG:
if( doopd(lcnalloc(LONG,clvalue)) )
goto exprerr;
continue;
case SYMBOL:
if( !((p=csp)->s_attrib&SDEFINED) ) {
if( peek(LPAREN) ) { /*assume function call*/
p->s_sc = EXTERNAL;
p->s_type = FUNCTION|INT;
}
else if( commastop ) /*in initialization?*/
p->s_sc = EXTERNAL;
else
error("undefined symbol: %.8s",p->s_symbol);
p->s_attrib =| SDEFINED;
}
if (p->s_sc==EXTERNAL || function(p->t_type)) {
if (!reducep || p->s_sc==EXTERNAL || peek(LPAREN)) {
p = enalloc(p);
p->t_sc = EXTERNAL;
}
else { /* [vlh] 3.4 if (main).... */
p = cnalloc(CINT,1); /* eval function name */
}
}
else
p=snalloc(p->s_type,p->s_sc,p->s_offset,p->s_dp,p->s_ssp);
if( doopd(p) )
goto exprerr;
continue;
case STRING:
outtstr(cvalue);
if( doopd(snalloc(ARRAY|CHAR,STATIC,cvalue,0,0)) )
goto exprerr;
continue;
/*
* do special checking for unary ops and operators that can be
* either unary or binary operators, such as -, &, *, etc.
*/
case RESWORD:
if( cvalue != R_SIZEOF ) {
goto exprerr;
}
token = SIZEOF;
case COMPL:
case NOT:
if( opdontop ) /*can't have: operand unary-op*/
goto exprerr;
break;
case LBRACK:
opdontop = 0;
break;
case RBRACK:
case RPAREN:
if( !opdontop ) /*can't be: operator )*/
goto exprerr;
break;
case PREINC:
if( opdontop ) /*assume its lvalue++*/
token = POSTINC;
break;
case PREDEC:
if( opdontop ) /*assume its lvalue--*/
token = POSTDEC;
break;
case SUB:
if(!opdontop) { /*if no operand, assume unary*/
if( peek(CINT) ) {
cvalue = -cvalue;
continue;
}
if( peek(CLONG) ) {
clvalue = -clvalue;
continue;
}
if( peek(CFLOAT) ) { /*[vlh] 3.4*/
if (!fflag) { /* IEEE format */
if (clvalue & 0x80000000)
clvalue =& 0x7fffffff;
else
clvalue =| 0x80000000;
}
else /* FFP format */
if (clvalue & 0x80)
clvalue =& 0xffffff7f;
else
clvalue =| 0x80;
continue;
}
token = UMINUS;
}
break;
case AND:
if(!opdontop)
token = ADDR;
break;
case MULT:
if( !opdontop )
token = INDR;
break;
/*
* for left parenthesis, we need to see if this is a casting operator.
*/
case LPAREN:
if( !opdontop ) { /*see if casting or abstract declarator*/
sc = type = 0;
if( gettype(&sc,&type,&size) ) {
sc = (type == STRUCT) ? dalloc(size) : cdp;
p = snalloc(type,STATIC,0,sc,sc);
p->t_type =| declarator(1);
if( !next(RPAREN) )
goto exprerr;
if( tdp )
p->t_type=addtdtype(tdp,p->t_type,p->t_dp,
&(p->t_ssp));
pushopd(p);
token = CAST;
if( opp->o_op == SIZEOF ) {
opdontop++;
continue;
}
}
}
else /*we've seen (), look for NACALL*/
token = (next(RPAREN)) ? MPARENS : CALL;
break;
case PERIOD:
case APTR:
smember++; /*next token needs to be struct membr*/
strucptr[smember+instruct] = csp->s_struc;
break;
}
/*
* we have seen an operator, get its info and then check the operator
* stack.
*/
if( binop(token) ) {
/*
* handle special binary operators, such as CAST and post-inc and
* post-dec.
*/
if(!opdontop) {
if( token != PREDEC && token != PREINC && token != CAST )
goto exprerr;
}
if( token != POSTDEC && token != POSTINC && token != MPARENS )
opdontop = 0; /*this fixes x++ op problem.*/
}
oppri = oppriority(token);
if( commastop && token == COMMA ) /*need to stop at comma(init)*/
oppri = COLPRI;
if( colonstop && token == COLON ) /*need to stop at colon(case)*/
oppri = COLPRI;
while( 1 ) {
if( oppri > opp->o_pri ||
(oppri == opp->o_pri && rasop(token)) ) {
/*
* we have encountered a higher priority (or right-associative)
* operator, hence we need to stack it.
*/
if( ++opp >= &opstack[OPSSIZE] )
ferror("expression too complex");
if( token == POSTINC || token == POSTDEC )
oppri = PSTPRI;
else if( token == LPAREN || token == LBRACK ||
token == CALL )
oppri = CALPRI;
opp->o_op = token;
opp->o_pri = oppri;
break;
}
/*
* we have encountered a lower priority operator, hence we need to
* do a reduction.
*/
op = opp->o_op;
opp--;
type = CINT;
switch( op ) {
case STACKEND: /*we accept the expression...*/
pbtok(token);
if (!strassign) {
if (!maketree(0))
goto exprerr;
}
if (!(p=popopd()))
goto exprerr;
opdp = opdsave;
opp = oprsave;
opdontop = opdotsave;
return(p);
case LPAREN: /*assure these have matching )*/
case CALL:
if( token != RPAREN )
goto exprerr;
break;
case MPARENS:
if( !maketree(NACALL) )
goto exprerr;
continue;
case LBRACK:
if( token != RBRACK )
goto exprerr;
if(!maketree(ADD)) /*array[index]->*(array+index)*/
goto exprerr;
op = INDR;
break;
case PREINC: /*turn these into binary operators*/
case POSTINC: /*which in reality they are...*/
case PREDEC:
case POSTDEC:
pushopd(cnalloc(INT,1));
default:
if(!maketree(op))
goto exprerr;
continue; /*see if we can reduce some more...*/
}
if( op != LPAREN && !maketree(op) )
goto exprerr;
break;
}
}
error("unexpected EOF");
return(0);
}
/* doopd - handle constant or symbol node operand*/
/* Pushes node onto operand stack and handles opdontop flag.*/
doopd(tp) /* returns 1 if syntax error, 0 for ok*/
struct tnode *tp; /* pointer to tree node*/
{
pushopd(tp);
if( opdontop )
return(1);
opdontop++;
return(0);
}
/*
* This indicates if a conversion operator is needed given the types
* of the two operands. The upper diagonal is applied ONLY if this
* is an assignment operator and the indexes are swapped so the lower
* diagonal is used otherwise.
*INT UNSN LONG DOUB PTR
*/
char cvmap[5][5] {
0, UNSN_INT, LONG_INT, DOUB_INT, PTR_INT,
INT_UNSN, 0, LONG_UNSN, DOUB_UNSN, PTR_UNSN,
INT_LONG, UNSN_LONG, 0, DOUB_LONG, PTR_LONG,
INT_DOUB, UNSN_DOUB, LONG_DOUB, 0, BADCONV,
INT_PTR, UNSN_PTR, LONG_PTR, BADCONV, PTR_PTR,
};
/*
* maketree - given operator, takes operands and builds up tree
* This takes the given operator, allocates a node for it
* and links up the subtrees on the operand stack. A lot of
* work is in inserting the proper conversions.
*/
maketree(op) /* returns success or failure */
int op; /* new root operator*/
{
register struct tnode *ltp, *rtp, *p;
register int type, ltype, rtype, lconv, conv, pconv, ilen, docast;
#ifdef DEBUG
printf("maketree op = %d\n",op);
#endif
if( binop(op) ) {
if(!(rtp=popopd()))
return(0);
rtype = (rtp=funcref(arrayref(rtp)))->t_type;
#ifdef DEBUG
putexpr("maketree r",rtp);
#endif
}
if(!(ltp=popopd()))
return(0);
#ifdef DEBUG
putexpr("maketree l",ltp);
#endif
if( op == SIZEOF ) { /* [vlh] 3.4 ilen */
ilen = dsize(ltp->t_type,ltp->t_dp,ltp->t_ssp);
pushopd(cnalloc(INT,ilen));
return(1);
}
if( op != ADDR ) {
ltp = arrayref(ltp);
if( op != CALL && op != NACALL )
ltp = funcref(ltp);
}
else { /* [vlh] 4.0 &p->array */
if (ltp->t_op == ADD) /* there must be a better way... */
if (ltp->t_left->t_op==SYMBOL && ltp->t_right->t_op==CINT) {
pushopd(ltp);
return(1);
}
}
if( specops(op,ltp,rtp) )
return( 1 );
ltype = ltp->t_type;
if( lintegral(op) )
integral(ltp,LONG);
if( rintegral(op) )
integral(rtp,LONG);
if( lvalop(op) && ltp->t_op != SYMBOL && ltp->t_op != INDR &&
ltp->t_op != BFIELD )
error("assignable operand required");
if( unaryop(op) ) {
if(!unopeval(op,ltp))
pushopd(tnalloc(op,ltype,ltp->t_dp,ltp->t_ssp,ltp,0L));
return;
}
if( ltype == STRUCT || rtype == STRUCT ) {
if (ltype==STRUCT && rtype==STRUCT && op==ASSIGN) { /*[vlh]*/
pushopd(ltp);
maketree(ADDR);
pushopd(rtp);
maketree(ADDR);
maketree(STASSIGN);
strassign = 1;
return(1);
}
ltype = rtype = INT;
error("illegal structure operation");
}
type = ltype;
if( rtype == TYPELESS ) {
rtp->t_type = rtype = INT;
lconv = conv = 0;
}
else {
lconv = ttoconv(ltype);
conv = ttoconv(rtype);
if (!asgop(op) && conv > lconv) {
conv = cvmap[conv][lconv];
lconv = 1;
type = rtype;
}
else {
conv = cvmap[lconv][conv];
lconv = 0;
}
}
if( asgop(op) ) {
if( (op == ASSIGN || op == FRETURN) && (conv == INT_PTR ||
conv == UNSN_PTR) && rtp->t_op != CINT )
error("short assigned to pointer");
if( op == ASSIGN || op == CAST ) {
switch( conv ) {
case INT_PTR:
case UNSN_PTR:
case PTR_PTR:
case PTR_LONG:
case LONG_PTR:
conv = 0;
break;
}
}
}
else if( op == COLON && suptype(ltype) != 0 && ltype == rtype )
conv = 0;
else if( relop(op) && conv == PTR_PTR )
conv = 0;
pconv = 0;
if ((relop(op) || op==FRETURN) && alltype(ltype) == (STRUCT | POINTER)
&& (conv == INT_PTR || conv == LONG_PTR)) /* [vlh] 3.4 */
conv = 0; /* int compare to struct pointer, no conversion */
if( conv == PTR_PTR ) {
conv = 0;
if( op == SUB ) {
type = LONG;
pconv++;
}
else if(op != FRETURN && ( (alltype(ltype) != alltype(rtype) ||
alltype(ltype) != (POINTER|CHAR)) ) )
conv = BADCONV;
}
docast=(ltp->t_type==CHAR && rtp->t_sc!=REGISTER && rtp->t_sc<=STATIC);
if( conv ) {
if( conv == BADCONV )
error("illegal type conversion");
else if( lconv )
ltp = cvopgen(ltp,type,conv,psize(rtp),op);
else
rtp = cvopgen(rtp,type,conv,psize(ltp),op);
}
if( op == CAST ) { /* [vlh] 4.0 */
if ( docast ) /* predefined to handle conv/cast ops */
rtp = tnalloc(TOCHAR,CHAR,0,0,rtp,0L);
else if ( rtp->t_type != CHAR && !conv ) {
rtp->t_type = ltp->t_type;
rtp->t_ssp = ltp->t_ssp; /* [vlh] 3.4 */
rtp->t_dp = ltp->t_dp; /* [vlh] 3.4 */
}
pushopd(rtp);
}
if( relop(op) )
type = INT;
if(op != CAST && !binopeval(op,ltp,rtp)) {
if( btype(ltype) == STRUCT || btype(rtype) != STRUCT )
p = ltp;
else
p = rtp;
pushopd(tnalloc(op,type,p->t_dp,p->t_ssp,ltp,rtp));
}
if( pconv && ltype != (POINTER|CHAR) ) {
if(!(ltp=popopd()))
return(0);
pushopd(cvopgen(ltp,LONG,PTR_LONG,psize(ltp->t_left),op));
}
return(1);
}
/* specops - handle special operators in building tree*/
specops(op,ltp,rtp) /* returns 1 if op special, 0 otherwise*/
int op; /* operator*/
struct tnode *ltp; /* left subtree pointer*/
struct tnode *rtp; /* right subtree pointer*/
{
register int type, sr_size, sl_size;
type = ltp->t_type;
#ifdef DEBUG
putexpr("specops l",ltp);
putexpr("specops r",rtp);
#endif
switch (op) {
case 0:
break;
default:
return(0);
case APTR: /*expr -> name*/
integral(ltp,LONG); /*we need to turn expr into a*/
ltp->t_type = POINTER|STRUCT; /*pointer to a struct, then use*/
pushopd(ltp); /*expr . name stuff*/
maketree(INDR);
ltp = popopd(); /*ltp cannot be 0*/
case PERIOD: /*expr . name*/
if( !(isstel(rtp)) )
error("invalid structure member name");
type = rtp->t_type;
if( array(type) ) {
type = delspchk(type);
rtp->t_dp++;
}
tadjust(ltp,type,rtp->t_dp,rtp->t_ssp);
pushopd(ltp);
maketree(ADDR);
pushopd(cnalloc(TYPELESS,rtp->t_offset));
maketree(ADD);
if( notarray(rtp->t_type) )
maketree(INDR);
ltp = popopd();
if( rtp->t_sc == BFIELDCL ) /*ltp cannot be 0*/
ltp = tnalloc(BFIELD,type,rtp->t_dp,rtp->t_ssp,ltp,0L);
break;
case QMARK:
if( rtp->t_op != COLON )
error("invalid ?: operator syntax");
if( ltp->t_op == CINT && rtp->t_left->t_op == CINT &&
rtp->t_right->t_op == CINT )
ltp->t_value = (ltp->t_value ? rtp->t_left->t_value :
rtp->t_right->t_value);
else
ltp = tnalloc(op,rtp->t_type,0,0,ltp,rtp);
break;
case LAND:
case LOR:
case COMMA: /*don't need conversions here*/
ltp = tnalloc(op,INT,0,0,ltp,rtp);
break;
case INDR:
if( ltp->t_op == ADDR ) /**& is null op*/
ltp = ltp->t_left;
else {
if( function(type) )
error("indirection on function invalid");
ltp = tnalloc(INDR,delspchk(type),ltp->t_dp,ltp->t_ssp,ltp,0L);
}
break;
case STASSIGN: /*[vlh]*/
sr_size = psize(rtp);
sl_size = psize(ltp);
if( sl_size >= sr_size )
ltp = tnalloc(STASSIGN,sr_size,0,0,ltp,rtp);
else
error("invalid structure assignment");
break;
case NACALL:
case CALL:
if( notfunction(type) )
error("illegal call");
ltp = tnalloc(op,delspchk(type),ltp->t_dp,ltp->t_ssp,ltp,rtp);
break;
case ADDR:
if( ltp->t_op == INDR ) { /*&* is null op*/
/* ltp->t_left->t_type = addsp(type,POINTER);*/
/* ltp->t_left->t_dp = ltp->t_dp;*/
/* ltp->t_left->t_ssp = ltp->t_ssp;*/
ltp = ltp->t_left;
}
else if( ltp->t_op == SYMBOL ) {
if( ltp->t_sc == REGISTER )
error("address of register");
ltp = tnalloc(ADDR,addsp(type,POINTER),ltp->t_dp,ltp->t_ssp,
ltp,0L);
}
else
error("& operator illegal");
break;
}
pushopd(ltp);
return(1);
}
/* cvopgen - generate a conversion operator*/
/* Generates conversions necessary for integers, pointers and longs.*/
char *cvopgen(tp,type,conv,len,op) /* returns pointer to conv node*/
struct tnode *tp; /* pointer to node to do conversion*/
int type; /* type to convert to*/
int conv; /* specified conversion*/
long len; /* object length [vlh] 3.4 i=>l */
int op; /* for cast operator*/
{
register struct tnode *rtp;
register int cop, ilen;
switch(conv) {
case INT_PTR:
case UNSN_PTR:
if (type == (POINTER|CHAR) && op == CAST ) { /* [vlh] 4.0 */
cop = INT2L;
break;
}
else
if( op == CAST || op == FRETURN ) {
cop = INT2L; /*of the ptd to objects length plus*/
if( len != 1L ) { /*an integer to long covnversion*/
ilen = len;
rtp = cnalloc(INT,ilen);
tp = tnalloc(MULT,type,0,0,tp,rtp);
}
break;
}
case PTR_LONG: /*need to generate mult or div*/
case LONG_PTR: /*of the ptd to objects length*/
if( len == 1 )
return(tp);
ilen = len;
cop = (conv == PTR_LONG ? DIV : MULT);
rtp = cnalloc(INT,ilen);
break;
case INT_LONG:
case UNSN_LONG:
cop = INT2L;
break;
case INT_DOUB: /*[vlh] 3.4*/
case UNSN_DOUB:
cop = INT2F;
break;
case LONG_DOUB: /*[vlh] 3.4*/
cop = LONG2F;
break;
case DOUB_LONG: /*[vlh] 3.4*/
cop = FLOAT2L;
break;
case DOUB_INT: /*[vlh] 3.4*/
case DOUB_UNSN:
cop = FLOAT2I;
break;
case LONG_INT:
case LONG_UNSN:
cop = LONG2I;
break;
default:
error("invalid conversion");
return(tp);
}
return( tnalloc(cop,type,0,0,tp,rtp) );
}
/* tadjust - expression tree type adjustment*/
/* Adjusts the types of subtrees to agree with the top of the tree.*/
tadjust(tp,type,dp,ssp) /* returns - none*/
struct tnode *tp; /* pointer to tree*/
int type; /* type to adjust to*/
int dp; /* dimension pointer or info*/
int ssp; /* structure pointer*/
{
register int op;
tp->t_type = type;
if( dp >= 0 ) {
tp->t_dp = dp;
tp->t_ssp = ssp;
}
if( (op=tp->t_op) == ADDR )
type = delspchk(type);
else if( op == INDR )
type = addsp(type,POINTER);
else if( op != ADD && op != SUB )
return;
tadjust(tp->t_left,type,dp,ssp);
}
/* funcref - handle tree function reference*/
/* Turns a reference to a function into the address of the function.*/
char *funcref(tp) /* returns pointer to node*/
struct tnode *tp; /* pointer to old node*/
{
if( function(tp->t_type) )
tp = tnalloc(ADDR,addsp(tp->t_type,POINTER),tp->t_dp,
tp->t_ssp,tp,0L);
return(tp);
}
/* arrayref - handle tree array reference*/
/* Turns a reference to an array into the address of the array.*/
char *arrayref(tp) /* returns pointer to tree node*/
struct tnode *tp; /* tree node pointer*/
{
if( array(tp->t_type) && !(isstel(tp)) ) {
tp->t_dp++;
pushopd(tp);
tadjust(tp,delspchk(tp->t_type),-1,0);
maketree(ADDR);
tp = popopd(); /*tp cannot be 0*/
}
return(tp);
}
/* integral - checks operand for integral type*/
/* This checks for needing an integral operand.*/
integral(tp,atype) /* returns - none*/
struct tnode *tp; /* pointer to tree node*/
int atype; /* alternate type allowable*/
{
register int type;
if( (type=tp->t_type) != INT && type != UNSIGNED && type != CHAR &&
!suptype(type) && type != atype )
error("invalid operand type");
}
/* ttoconv - maps normal type into conversion table type*/
ttoconv(type) /* returns conversion type*/
int type; /* type to convert*/
{
switch(type) {
case CHAR:
case INT:
return(0);
case UNSIGNED:
return(1);
case LONG:
return(2);
case FLOAT:
case DOUBLE:
return(3);
default:
return(4);
}
}
/* binopeval - does binary operator constant expression evaluation*/
/* Does the constant expression evaluation for binary operators.*/
binopeval(op,ltp,rtp) /* returns 1 if done, 0 if not*/
int op; /* operator to evaluate*/
struct tnode *ltp; /* pointer to left subtree*/
struct tnode *rtp; /* pointer to right subtree*/
{
register int lvalue, rvalue;
if( ltp->t_op != CINT )
return(0);
lvalue = ltp->t_value;
if( rtp->t_op != CINT )
return(0);
rvalue = rtp->t_value;
switch (op) {
case ADD:
lvalue =+ rvalue;
break;
case SUB:
lvalue =- rvalue;
break;
case MULT:
lvalue =* rvalue;
break;
case DIV:
lvalue =/ rvalue;
break;
case MOD:
lvalue =% rvalue;
break;
case AND:
lvalue =& rvalue;
break;
case OR:
lvalue =| rvalue;
break;
case XOR:
lvalue =^ rvalue;
break;
case LSH:
lvalue =<< rvalue;
break;
case RSH:
lvalue =>> rvalue;
break;
case EQUALS:
lvalue = (lvalue == rvalue);
break;
case NEQUALS:
lvalue = (lvalue != rvalue);
break;
case GREAT:
lvalue = (lvalue > rvalue);
break;
case LESS:
lvalue = (lvalue < rvalue);
break;
case GREATEQ:
lvalue = (lvalue >= rvalue);
break;
case LESSEQ:
lvalue = (lvalue <= rvalue);
break;
default:
return(0);
}
ltp->t_value = lvalue;
pushopd(ltp);
return(1);
}
/* unopeval - unary operator constant expression evaluation*/
/* Does constant expression evaluation for unary operators.*/
unopeval(op,tp) /* returns 1 if done, 0 otherwise*/
int op; /* operator to evaluate*/
struct tnode *tp; /* pointer to subexpression*/
{
register int value;
if( tp->t_op != CINT )
return(0);
value = tp->t_value;
switch( op ) {
case COMPL:
value = ~ value;
break;
case UMINUS:
value = - value;
break;
case NOT:
value = ! value;
break;
default:
return(0);
}
tp->t_value = value;
pushopd(tp);
return(1);
}
/* cexpr - evaluate a constant integer expression*/
/* Used in evaluating array bounds, bit field numbers, etc.*/
cexpr()
{
register struct tnode *tp;
register char *savep;
savep = exprp;
exprp = opap;
commastop++;
if( (tp=expr()) && tp->t_op != CINT )
error("constant required");
commastop--;
exprp = savep;
return( tp->t_value );
}

View File

@@ -0,0 +1,311 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
int bol 1;
int inittype;
int begseq;
/* int onepass; */
/*
This interfaces the Parser and the Code Generator, note that these
allow you to link together the Parser and the Code Generator.
*/
/* outbdata - set up for byte data*/
outbdata() /* returns - none*/
{
inittype = CHAR;
printf("\t.dc.b ");
}
/* outc - output a constant*/
outc(type,value) /* returns - none*/
int type;
int value;
{
if( type == CHAR )
outbdata();
else
outwdata();
printf("%d\n",value);
}
/* outwdata - set up for word data*/
outwdata() /* returns - none*/
{
inittype = INT;
printf("\t.dc.w ");
}
/* outdata - set up for data output*/
outdata() /* returns - none*/
{
inittype = INT;
printf("\t.data\n");
}
/* outldata - set up for long data output*/
outldata() /* returns - none*/
{
inittype = LONG;
printf("\t.data\n");
}
/* outfpdata - set up for floating point data output*/
outfpdata() /*[vlh] 3.4 returns - none*/
{
inittype = FLOAT;
printf("\t.data\n");
}
/* outbentry - outputs block/function entry code*/
outbentry(nlocs,nds,nas) /* returns - none*/
int nlocs; /* local size*/
int nds; /* number of D registers*/
int nas; /* number of A registers*/
{
if( !nds && !nas ) /* adjust for 1 arg*/
nlocs =+ 4;
printf("\tlink R14,#%d\n",-nlocs);
if( nds || nas ) {
printf("\tmovem.l R%d-R7",7-nds); /*7 for one arg*/
if( nas ) {
putchar('/');
printf("R%d-R13",14-nas);
}
printf(",-(sp)\n");
}
}
/* outbexit - output function exit code*/
outbexit(nds,nas) /* returns - none*/
int nds; /* number of D registers*/
int nas; /* number of A registers*/
{
if( nds || nas ) {
printf("\ttst.l (sp)+\n\tmovem.l (sp)+,"); /*1 arg stuff*/
if( nds ) {
printf("R%d-R7",8-nds);
if( nas )
putchar('/');
}
if( nas )
printf("R%d-R13",14-nas);
putchar('\n');
}
printf("\tunlk R14\n\trts\n");
}
/* outlocal - output local symbol for debugger*/
outlocal(type,sc,sym,val)
int type; /* local name type*/
int sc; /* storage type*/
char *sym; /* symbol name*/
int val;
{
switch( sc ) {
case STATIC:
if( notfunction(type) )
printf("\t~%.8s=L%d\n",sym,val);
break;
case REGISTER:
printf("\t~%.8s=R%d\n",sym,val);
break;
case AUTO:
printf("\t~%.8s=%d\n",sym,val);
break;
}
}
/* outswitch - output switch table info*/
outswitch(ncases,deflab,sp) /* returns - none*/
int ncases; /* number of cases in switch*/
int deflab; /* default label*/
struct swtch *sp; /* switch table pointer*/
{
register int vdif, val, hval, i, tlab;
register struct swtch *s;
val = sp->sw_value;
hval = sp[ncases-1].sw_value;
vdif = hval - val;
if( ncases <= 4 ) {
/*
*simple switch, do compares and brances, followed by branch to default
*/
for( s = sp; --ncases >= 0; s++ ) {
if( !s->sw_value )
printf("\ttst R0\n");
else
printf("\tcmp #%d,R0\n",s->sw_value);
printf("\tbeq L%d\n",s->sw_label);
}
outgoto(deflab);
}
else if( vdif > 0 && vdif <= ncases*3 ) {
/*jump switch, uses value in R0 to index into table of labels*/
if( val )
printf("\tsub #%d,R0\n",val);
tlab = nextlabel++;
printf("\tcmp #%d,R0\n\tbhi L%d\n",vdif,deflab); /*check for max*/
printf("\tasl #2,R0\n\tmove R0,R8\n\tadd.l #L%d,R8\n",tlab);
printf("\tmove.l (R8),R8\n\tjmp (R8)\n");
outdata();
outlab(tlab);
for( s = sp; val <= hval; val++ ) {
if( val == s->sw_value ) {
outclab(s->sw_label);
s++;
}
else
outclab(deflab);
}
outtext();
}
else {
/*
* direct switch, searches down table of values for match, if match
* found, branches to corresponding label in label table.
*/
tlab = nextlabel++;
printf("\text.l R0\n\tmove.l #L%d,R8\n\tmove #%d,R1\n",tlab,ncases);
i = nextlabel++;
outlab(i); /*loop label*/
printf("\tcmp.l (R8)+,R0\n\tdbeq R1,L%d\n",i);
printf("\tmove.l %d(R8),R8\n\tjmp (R8)\n",ncases*4);
outdata();
outlab(tlab);
for( s = sp, i = ncases; --i >= 0; s++ )
outlcon(s->sw_value);
outlcon(0); /* mark for default label*/
for( s = sp, i = ncases; --i >= 0; s++ )
outclab(s->sw_label);
outclab(deflab);
outtext();
}
}
outeof()
{
register int c;
v6flush(&sbuf);
v6flush(&obuf);
}
/* copysfile - copy string file to end of output file*/
copysfile(fname)
char *fname;
{
register int c;
close(sbuf.io_fd);
if( fopen(fname,&sbuf,0) < 0 ) /* 3rd arg for versados */
ferror("can't copy %s",fname);
while( (c=getc(&sbuf)) > 0 )
putc(c,&obuf);
v6flush(&obuf);
}
/* outword - output a word of data*/
outword(w) /* word expression*/
int w;
{
if( begseq )
putchar(',');
begseq++;
printf("%d",w);
}
/* outlong - output a long data*/
outlong(l) /* returns - none*/
long l; /* long data to output*/
{
outwdata();
outword(l.hiword);
outword(l.loword);
outendseq();
}
/* outfp - output floating point data*/
outfp(l) /*[vlh] 3.4 returns - none*/
long l; /* floating point data to output*/
{
outwdata();
outword(l.hiword);
outword(l.loword);
outendseq();
}
outendseq() /* returns - none*/
{
begseq = 0;
putchar('\n');
}
/*
* outtstr - output text string
* This outputs a string to the string file, this is used wherever
* you cannot output the string directly to data space, such as in
* the middle of expressions.
*/
outtstr(lab)
int lab;
{
char *savep;
int sbol;
savep = obp; /*save to restore later...*/
obp = &sbuf;
sbol = bol;
bol = 1;
printf("\tL%d:",lab);
outstr();
obp = savep;
bol = sbol;
}
/* outstr - output a string as a sequence of bytes*/
/* Outputs ".dc.b <byte1>,<byte2>,...,<0>*/
outstr()
{
register char *s;
register int i;
outbdata();
for( s = cstr, i = cstrsize; i > 0; i-- )
outword(*s++ & 0xff);
outendseq();
}
/*
* putchar - handle outputting to intermediate or error files
* This catches tabs to allow for the integration of the parser
* and code generator into one pass. By merely throwing away the
* tabs here, the output will be OK for the assembler.
*/
putchar(c)
char c;
{
if( !obp )
write(1,&c,1);
else if( c == '\t' ) {
if( bol ) /* not used && !onepass ) */
putc('(',obp); /*for code generator*/
}
else {
bol = (c == '\n');
putc(c,obp);
}
}

View File

@@ -0,0 +1,86 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
int bol;
outinit(tp,type) /* returns - none*/
struct tnode *tp;
{
outexpr(tnalloc(INIT,type,0,0,tp));
}
outcforreg(tp)
struct tnode *tp;
{
outexpr(tnalloc(CFORREG,tp->t_type,0,0,tp));
}
outifgoto(tp,dir,lab)
struct tnode *tp;
int dir;
int lab;
{
outexpr(tnalloc(IFGOTO,dir,lab,0,tp));
}
outexpr(tp)
struct tnode *tp;
{
if( !bol )
putchar('\n');
printf(".%x\n",lineno);
outtree(tp);
}
outtree(tp)
struct tnode *tp;
{
if( !tp )
return;
printf("%x.%x",tp->t_op,tp->t_type);
switch( tp->t_op ) {
case CINT:
printf(".%x\n",tp->t_value);
break;
case CLONG:
printf(".%x.%x\n",tp->t_lvalue.hiword,tp->t_lvalue.loword);
break;
case CFLOAT: /*[vlh] 3.4*/
printf(".%x.%x\n",tp->t_lvalue.hiword,tp->t_lvalue.loword);
break;
case SYMBOL:
printf(".%x",tp->t_sc);
if( tp->t_sc == EXTERNAL )
printf(".%.8s\n",tp->t_symbol);
else
printf(".%x\n",tp->t_offset);
break;
case 0:
putchar('\n');
break;
case IFGOTO:
case BFIELD:
printf(".%x\n",tp->t_dp);
outtree(tp->t_left);
break;
default:
putchar('\n');
outtree(tp->t_left);
if( binop(tp->t_op) )
outtree(tp->t_right);
break;
}
}

View File

@@ -0,0 +1,830 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
#define SOI '\01'
#define STEL HSIZE/2
/*
* the following are the cases within gettok, all other cases are
* single character unambiguous tokens. Note that we need to take
* special care not to interfere with the single character unambiguous
* operators, this is why there is a gap between WHITSP and EXCLAM.
*/
#define BADC 0 /*bad character*/
#define WHITSP 101 /*white space*/
#define EXCLAM 102 /*exlamation point*/
#define DQUOTE 103 /*double quote*/
#define PERCNT 104 /*percent sign*/
#define AMPER 105 /*ampersand*/
#define SQUOTE 106 /*single quote*/
#define STAR 107 /*asterisk or mult sign*/
#define PLUS 108 /*plus sign*/
#define MINUS 109 /*minus sign*/
#define SLASH 110 /*divide sign*/
#define DIGIT 111 /*0..9*/
#define LCAROT 112 /*less than sign*/
#define EQUAL 113 /*equals sign*/
#define RCAROT 114 /*greater than*/
#define ALPHA 115 /*a..z,A..Z and underbar*/
#define CAROT 116 /*^*/
#define BAR 117 /*vertical bar*/
char ctype[] {
BADC, BADC, BADC, BADC, BADC, BADC, BADC, BADC,
BADC, WHITSP, WHITSP, WHITSP, WHITSP, BADC, BADC, BADC,
BADC, BADC, BADC, BADC, WHITSP, BADC, BADC, BADC,
BADC, BADC, BADC, BADC, BADC, BADC, BADC, BADC,
WHITSP, EXCLAM, DQUOTE, BADC, BADC, PERCNT, AMPER, SQUOTE,
LPAREN, RPAREN, STAR, PLUS, COMMA, MINUS, PERIOD, SLASH,
DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
DIGIT, DIGIT, COLON, SEMI, LCAROT, EQUAL, RCAROT, QMARK,
BADC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, LBRACK, BADC, RBRACK, CAROT, ALPHA,
BADC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, LCURBR, BAR, RCURBR, COMPL, BADC
};
/*key word table*/
struct resword {
char *r_name;
int r_value;
} reswords[] {
"auto", R_AUTO,
"break", R_BREAK,
"case", R_CASE,
"char", R_CHAR,
"continue", R_CONTINUE,
"do", R_DO,
"default", R_DEFAULT,
"double", R_DOUBLE,
"goto", R_GOTO,
"else", R_ELSE,
"extern", R_EXTERNAL,
"float", R_FLOAT,
"for", R_FOR,
"if", R_IF,
"int", R_INT,
"long", R_LONG,
"register", R_REGISTER,
"return", R_RETURN,
"short", R_SHORT,
"sizeof", R_SIZEOF,
"static", R_STATIC,
"struct", R_STRUCT,
"switch", R_SWITCH,
"typedef", R_TYPEDEF,
"union", R_UNION,
"unsigned", R_UNSIGNED,
"while", R_WHILE,
0,
};
#define SELFMOD 0200
#define ASMASK 0177
/*
* this table is used to check for an operator after an equals sign.
* note that =-, =* and =& may all have an ambiguous meaning if not
* followed by a space, this is checked for in gettok.
*/
char asmap[] {
EQUALS, /*==*/
EQADD, /*=+*/
EQSUB|SELFMOD, /*=-*/
EQMULT|SELFMOD, /*=**/
EQDIV, /*=/*/
EQOR, /*=|*/
EQAND|SELFMOD, /*=&*/
EQXOR, /*=^*/
EQMOD, /*=%*/
};
char escmap[] "\b\n\r\t";
int pbchar; /*pushed back character*/
struct symbol *symtab[HSIZE]; /*hash table*/
struct symbol *symbols; /*pointer to next avail symbol buf*/
int nsyms; /*number of symbol bufs in memory*/
/*
* getdec - get a decimal number
* Uses Horner's method to get decimal number. Note that
* multiplication by 10 is cleverly programmed as two shifts and two
* adds. This is because long multiplies are painful on both the
* PDP-11 and 68000.
*/
long getdec() /* returns number*/
{
register long value;
register char c;
for( value = 0; (c=ngetch()) >= '0' && c <= '9'; ) {
value =<< 1; /*value = value*2*/
value =+ value << 2; /*value*2 + value*8 = value*10*/
value =+ (c-'0');
}
putback(c);
return(value);
}
#define BIAS 127L
#define EXPSIZ 4
#define FRACSIZ 20
long toieee();
long toffp();
float power10();
/*
* getfp - get a floating point constant
* we've already gotten the significant digits, now build a
* floating point number with possible decimal digits and an
* exponent, yields an ieee formated floating point number,
* unless the fflag is on, then a ffp constant is generated.
*/
long
getfp(significant)
long significant;
{
register char c;
register long places; /* decimal places */
int esign;
float exp, fraction, fp;
places = 0L; esign = 0; fraction = significant; exp = 0.0;
if ((c = ngetch()) == '.') /* get decimal places */
for( ; (c=ngetch()) >= '0' && c <= '9';) {
fraction = fraction * 10.0;
fraction = fraction + (c - '0');
places++;
}
if (c=='e' || c=='E') { /* exponent exists */
esign = (peekis('-')) ? 1 : (peekis('+')) ? 0 : 0;
for( ; (c=ngetch()) >= '0' && c <= '9'; ) {
exp = exp * 10.0;
exp = exp + (c - '0');
}
}
putback(c);
if (esign)
exp = -exp;
places = exp - places;
fp = fraction * power10(places);
if (fflag)
return( toffp(fp) );
else
return ( toieee(fp) );
}
float
power10(pwr) /* used by getfp, 10^pwr */
long pwr;
{
float f;
if (pwr < 0L) /* negative power */
for (f = 1.0; pwr < 0L; pwr++)
f = f / 10.0;
else /* positive power */
for (f = 1.0; pwr > 0L; pwr--)
f = f * 10.0;
return(f);
}
long
toffp(f) /* converts current machine float to ffp rep */
float f;
{
register long exp;
register int sign, count;
long l;
if (f == 0.0)
return(0L);
if (f < 0.0) {
sign = 1;
f = -f;
}
else
sign = 0;
exp = 0L;
for( ; f >= 1.0; f = f / 2.0)
exp++;
for( ; f < 0.5; f = f * 2.0)
exp--;
f = f * 16777216.0; /* 2 ^ 24 */
l = f;
l =<< 8;
if (sign)
l =| 0x80;
exp =+ 0x40;
l =| (exp & 0x7f);
return(l);
}
long
toieee(f) /* converts current machine float to ieee rep */
float f;
{
register long exp;
register int sign, count;
long l;
if (f == 0.0)
return(0L);
if (f < 0.0) {
sign = 1;
f = -f;
}
else
sign = 0;
exp = 0L;
for( ; f >= 2.0; f = f / 2.0)
exp++;
for( ; f < 1.0; f = f * 2.0)
exp--;
f = f - 1.0;
f = f * 8388608.0; /* 2 ^ 23 */
l = f;
if (sign)
l =| 0x80000000;
exp = (exp + BIAS)<<23;
l =| (exp & 0x7f800000);
return(l);
}
#define toupper(c) ((c) & ~32)
/* gethex - get an hexidecimal number*/
/* Uses Horner's method to get hexidecimal number*/
long gethex() /* returns number*/
{
register long value;
register char c, ch;
value = 0;
while( 1 ) {
if( (c=ngetch()) >= '0' && c <= '9' )
c =- '0';
else if((ch=toupper(c)) >= 'A' && ch <= 'F' ) /* [vlh] */
c = ch - ('A'-10);
else
break;
value = (value<<4) + c;
}
putback(c);
return(value);
}
/* getoct - get an octal number*/
/* Uses Horner's method to get octal number*/
long getoct(flag) /* returns number*/
int flag; /* string flag 1=>in string, else 0*/
{
register long value;
register char c;
register int count;
count = 0;
for( value = 0; (c=ngetch()) >= '0' && c <= '7'; ) {
if( flag && ++count > 3 )
break;
value = (value<<3) + (c-'0');
}
putback(c);
return(value);
}
/*
* gettok - get next token from input
* Checks pushed-packed token buffer, supresses / * * / comments,
* folds multiple character special symbols into single word token.
*/
gettok() /* returns token type*/
{
register int c, nextc, i;
register char *p;
register long value;
char sym[SSIZE];
if( peektok ) {
i = peektok;
peektok = 0;
return(i);
}
while( (c=ngetch()) != EOF ) {
switch(ctype[c]) {
case BADC: /*bad character*/
error("invalid character");
break;
case SEMI:
cvalue = 0; /* [vlh] not reserved word... */
default:
return( ctype[c] );
case WHITSP: /*skip all white space*/
break;
case EXCLAM: /*!= or !*/
return( peekis('=') ? NEQUALS : NOT );
case DQUOTE: /*quoted string*/
getstr(cstr,STRSIZE,'"');
cvalue = nextlabel++;
return(STRING);
case PERCNT: /*%= or %*/
return( peekis('=') ? EQMOD : MOD );
case AMPER: /*&=, && or &*/
return( peekis('=') ? EQAND : peekis('&') ? LAND : AND );
case SQUOTE: /*character constant*/
getstr(cstr,STRSIZE,'\'');
if( cstrsize > CHRSPWORD+1 ) {
error("character constant too long");
cstrsize = CHRSPWORD + 1;
}
cvalue = 0;
for( p = cstr; --cstrsize > 0; ) {
cvalue =<< BITSPCHAR;
cvalue =| (*p++ & 0377);
}
return(CINT);
case STAR: /**= or **/
return( peekis('=') ? EQMULT : MULT );
case PLUS: /*+=, ++ or +*/
return( peekis('=') ? EQADD : peekis('+') ? PREINC : ADD );
case MINUS: /*-=, --, -> or -*/
return( peekis('=') ? EQSUB : peekis('-') ? PREDEC :
peekis('>') ? APTR : SUB );
case SLASH: /*/ *..* /, //..., /= or /*/
if( peekis('*') ) {
while( (c=ngetch()) != EOF )
if( c == '*' && peekis('/') )
break;
if( c == EOF ) {
error("no */ before EOF");
return(EOF);
}
continue;
}
if( peekis('/') ) {
while( (c=ngetch()) != EOF && c != EOLC )
;
continue;
}
return( peekis('=') ? EQDIV : DIV );
case DIGIT: /*number constant (long or reg)*/
i = 0; /*flags if long constant*/
if( c != '0' ) {
putback(c);
dofp:
value = getdec();
if ((c=ngetch())=='.' || c=='e' || c=='E') { /*[vlh] 3.4 */
putback(c);
clvalue = getfp(value);
return(CFLOAT);
}
putback(c);
if( value > 32767 || value < -32768 )
i++;
}
else if( peekis('x') || peekis('X') ) {
value = gethex();
if( value < 0 || value >= 0x10000L )
i++;
}
else {
if (peekis('.')) {
putback('.');
goto dofp;
}
value = getoct(0);
if( value < 0 || value >= 0x10000L )
i++;
}
if( peekis('l') || peekis('L') || i ) {
clvalue = value;
return(CLONG);
}
cvalue = value;
return(CINT);
case LCAROT: /*<=, <<, <<= or <*/
return( peekis('=') ? LESSEQ : peekis('<') ?
(peekis('=') ? EQLSH : LSH) : LESS );
case EQUAL: /*==, =<<, =>>, =+, ..., =*/
if( peekis('<') ) {
if( peekis('<') )
return(EQLSH);
}
else if( peekis('>') ) {
if( peekis('>') )
return(EQRSH);
}
else if( (i=index("=+-*/|&^%",(c=ngetch()))) >= 0 ) {
i = asmap[i];
if( i & SELFMOD ) {
if( (nextc=ngetch()) != ' ' )
if (!wflag) /*[vlh] old fashion initialization*/
error("=%c assumed",c);
putback(nextc);
}
return( i & ASMASK );
}
else
putback(c);
return(ASSIGN);
case RCAROT: /*>=, >>, >>= or >*/
return( peekis('=') ? GREATEQ : peekis('>') ?
(peekis('=') ? EQRSH : RSH) : GREAT );
case ALPHA: /*[A-Za-z][A-Za-z0-9]**/
p = &sym[0];
i = SSIZE;
for(; ctype[c] == ALPHA || ctype[c] == DIGIT; c=ngetch(),i-- )
if( i > 0 )
*p++ = c;
if( i > 0 )
*p = '\0';
putback(c);
csp = lookup(sym);
if( csp->s_attrib & SRESWORD ) {
cvalue = csp->s_offset;
return(RESWORD);
}
smember = 0;
return(SYMBOL);
case CAROT: /*^= or ^*/
return( peekis('=') ? EQXOR : XOR );
case BAR: /*|=, || or |*/
return( peekis('=') ? EQOR : peekis('|') ? LOR : OR );
}
}
return(EOF);
}
/*
* peekis - peeks at next character for specific character
* Gets next (possibly pushed back) character, if it matches
* the given character 1 is returned, otherwise the character
* is put back.
*/
peekis(tc) /* returns 1 if match, 0 otherwise*/
int tc; /* test character*/
{
register int c;
if( (c=ngetch()) == tc )
return(1);
putback(c);
return(0);
}
/* ngetch - get a possibly pushed back character*/
/* Checks pbchar variable, returns it if non-zero, handles counting*/
/* of new lines and whether you are in an include or not.*/
ngetch() /* returns character read or EOF*/
{
register int c;
register char *ifile;
if( pbchar ) {
c = pbchar;
pbchar = 0;
}
else if( (c=getc(&ibuf)) == EOLC ) {
if( inclflag )
inclflag = 0;
else
lineno++;
}
else if( c == SOI) { /*[vlh]add incl filename & line # */
inclflag++;
ifile = &inclfile;
while ((c=getc(&ibuf)) != SOI)
*ifile++ = c&0377;
*ifile = 0;
inclline = getdec() & 077777;
c = ' ';
}
else if( c < 0 )
c = EOF;
return(c);
}
/*
* peekc - peek at the next non-whitespace character after token
* This allows for the problem of having to look at two tokens
* at once. The second token is always a semi-colon or colon,
* so we only look at the single character, rather than going
* thru gettok.
*/
peekc(tc) /* returns 1 if match, 0 otherwise*/
int tc; /* character to look for*/
{
register int c;
while( ctype[(c=ngetch())] == WHITSP) ;
if( c == tc )
return(1);
putback(c);
return(0);
}
/* putback - puts back a single character*/
/* Checks pbchar for error condition.*/
putback(c) /* returns - none*/
int c;
{
if( pbchar )
error("too many chars pushed back");
else
pbchar = c;
}
/* getstr - get a quoted (single or double) character string*/
/* Gets specified number of characters, handling escapes.*/
getstr(str,nchars,endc) /* returns - none*/
char *str; /* pointer to string buffer*/
int nchars; /* max number of characters*/
char endc; /* ending string character*/
{
register char *p;
register int i;
register int c;
register int j;
cstrsize = 1;
p = str;
for( i = nchars; (c=ngetch()) != endc; i-- ) {
if( c == EOF || c == EOLC ) {
error("string cannot cross line");
break;
}
if( c == '\\' ) {
if( (c=ngetch()) >= '0' && c <= '7' ) {
putback(c);
if( (c=getoct(1)) < 0 || c > 255 ) {
error("bad character constant");
continue;
}
}
else if( (j=index("bnrt",c)) >= 0 )
c = escmap[j];
else if( c == EOLC ) /*escape followed by nl->ignore*/
continue;
}
if( i > 0 ) { /*room left in string?*/
cstrsize++;
*p++ = c;
}
else if( !i ) /*only say error once...*/
error("string too long");
}
if( i <= 0 ) /*string overflow?*/
p--;
*p = '\0';
}
/* syminit - initialize the symbol table, install reswords*/
/* Goes thru the resword table and installs them into the symbol*/
/* table.*/
syminit() /* returns - none*/
{
register struct resword *rp;
for( rp = &reswords[0]; rp->r_name != 0; rp++ )
install(rp->r_name,SRESWORD|SDEFINED,rp->r_value);
}
/* install - install a symbol in the symbol table*/
/* Allocates a symbol entry, copies info into it and links it*/
/* into the hash table chain.*/
char *
install(sym,attrib,offset) /* returns pointer to symbol struct*/
char *sym; /* symbol to install*/
int attrib; /* attribues of symbol*/
int offset; /* symbol offset (resword value)*/
{
register struct symbol *sp;
register int i;
while( (sp=symbols) <= 0 ) {
if( (sp=sbrk(SYMSIZE)) <= 0 )
ferror("symbol table overflow");
for( i = SYMSIZE/(sizeof *symbols); --i >= 0; ) {
if (sp <= 0)
ferror("bad symbol table");
sp->s_next = symbols;
symbols = sp++;
}
}
symbols = sp->s_next;
sp->s_attrib = attrib;
sp->s_sc = 0; sp->s_type = 0; sp->s_dp = 0; sp->s_ssp = 0;
sp->s_offset = offset;
sp->s_struc = (instruct) ? strucptr[smember+instruct] : 0;
symcopy(sym,sp->s_symbol); /*copy symbol to symbol struct*/
i = symhash(sym,instruct|smember); /*link into chain list*/
sp->s_next = symtab[i];
symtab[i] = sp;
return(sp);
}
/* lookup - looks up a symbol in symbol table*/
/* Hashes symbol, then goes thru chain, if not found, then*/
/* installs the symbol.*/
char *lookup(sym) /* returns pointer to symbol buffer*/
char *sym; /* pointer to symbol*/
{
register struct symbol *sp, *hold;
register char *p;
int exact; /* same name, diff type or offset */
p = sym;
for( sp = symtab[symhash(p,0)]; sp != 0; sp = sp->s_next )
if((sp->s_attrib&(SRESWORD|STYPEDEF)) && symequal(p,sp->s_symbol))
return(sp);
if (!(smember|instruct)) { /*[vlh]*/
for( sp=symtab[symhash(p,0)]; sp!=0; sp=sp->s_next )
if( symequal(p,sp->s_symbol) ) return(sp);
}
else { /* doing a declaration or an expression */
hold = 0; exact = 0;
for( sp=symtab[symhash(p,instruct|smember)]; sp!=0; sp=sp->s_next )
if( symequal(p,sp->s_symbol) )
if (symsame(sp,hold,&exact)) return(sp);
else if (!hold && !exact) hold = sp;
if (hold && !exact) return(hold);
}
return(install(p,0,0));
}
/* freesyms - frees all local symbols at end of function declaration*/
/* Searches thru symbol table, deleting all symbols marked as locals*/
freesyms() /* returns - none*/
{
register int i, tinfo;
register struct symbol *sp, *tp, *nextp, **htp;
for( htp = &symtab[0], i = HSIZE; --i >= 0; htp++ )
for( tp = 0, sp = *htp; sp != 0; sp = nextp ) {
nextp = sp->s_next;
if( !(sp->s_attrib&SDEFINED) ) {
error("undefined label: %.8s",sp->s_symbol);
sp->s_attrib =| SDEFINED;
}
if( sp->s_attrib & (SGLOBAL|SRESWORD) )
tp = sp;
else {
if( tp )
tp->s_next = sp->s_next;
else
*htp = sp->s_next;
sp->s_next = symbols;
symbols = sp;
}
}
}
/* chksyms - checks symbol table for undefined symbols, etc.*/
/* Goes thru the symbol table checking for undeclared forward*/
/* referenced structures, and outputs local symbols for debugger.*/
chksyms() /* returns - none*/
{
register struct symbol **htp, *sp;
register int i, sc;
for( htp = &symtab[0], i = HSIZE; --i >= 0; htp++ )
for( sp = *htp; sp != 0; sp = sp->s_next ) {
sc = sp->s_sc;
if(sc!=0 && sp->s_ssp>=0 && (btype(sp->s_type))==FRSTRUCT) {
sp->s_ssp = frstab[sp->s_ssp]->s_ssp; /* 3.4 ssp>0 */
sp->s_type = (sp->s_type&~TYPE) | STRUCT;
}
if( sc == PDECLIST ) {
error("not in parameter list: %.8s",sp->s_symbol);
sp->s_sc = AUTO;
}
if( infunc )
outlocal(sp->s_type,sp->s_sc,sp->s_symbol,sp->s_offset);
}
}
/* symhash - compute hash value for symbol*/
/* Sums the symbols characters and takes that modulus the hash table*/
/* size.*/
symhash(sym,stel) /* returns hash value for symbol*/
char *sym; /* pointer to symbol*/
int stel; /* structure element flag*/
{
register char *p;
register int hashval, i;
hashval = (stel ? STEL : 0 );
for( p = sym, i = SSIZE; *p != '\0' && i > 0; i-- )
hashval =+ *p++;
return( hashval % HSIZE );
}
/* symequal - check for symbol equality*/
/* Does comparison between two symbols.*/
symequal(sym1,sym2) /* returns 1 if equal, 0 otherwise*/
char *sym1; /* pointer to first symbol*/
char *sym2; /* pointer to second symbol*/
{
register char *p, *q;
register int i;
for( p = sym1, q = sym2, i = SSIZE; *p == *q++; )
if( *p++ == '\0' || --i == 0 )
return(1);
return(0);
}
/* symsame - symbol member same as declared */
symsame(sp,hold,exact) /* [vlh] */
struct symbol *sp, *hold;
int *exact;
{
if (strucptr[smember+instruct])
if (strucptr[smember+instruct]==sp->s_struc) return(1);
if (hold)
if (sp->s_type != hold->s_type || sp->s_offset != hold->s_offset)
*exact = 1;
return(0);
}
/* symcopy - symbol copy*/
/* Copies one symbol to another.*/
symcopy(sym1,sym2) /* returns - none*/
char *sym1; /* pointer to symbol to copy*/
char *sym2; /* pointer to area to copy to*/
{
register char *p, *q;
register int i;
for( p = sym1, q = sym2, i = SSIZE; --i >= 0; )
*q++ = ( *p ? *p++ : '\0');
}
/* index - find the index of a character in a string*/
/* This is identical to Software Tools index.*/
index(str,chr) /* returns index of c in str or -1*/
char *str; /* pointer to string to search*/
char chr; /* character to search for*/
{
register char *s;
register int i;
for( s = str, i = 0; *s != '\0'; i++ )
if( *s++ == chr )
return(i);
return(-1);
}
/* next - if next token matches given token, skip and return success*/
/* This allows for clean parsing of declarations.*/
next(tok) /* returns 1 if matched, 0 otherwise*/
int tok;
{
register int token;
if( (token=gettok()) == tok )
return(1);
peektok = token;
return(0);
}
/* pbtok - put back the given token*/
/* This merely sets the peektok variable*/
pbtok(tok) /* returns - none*/
int tok;
{
if( peektok )
error("too many tokens pushed back");
peektok = tok;
}

View File

@@ -0,0 +1,159 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char *version "@(#) c068 parser 4.0 - Mar 18, 1983";
/*
ALCYON C Compiler for the Motorola 68000 - Parser
Called from c68:
c068 source icode strings
source: input source code, preprocessed with comments stripped
icode: contains the intermediate code for the code generator,
for a detailed explanaion see ../doc/icode.
strings: contains all the string constants.
The basic structure of the parser is as follows:
main main driver for parser
syminit initializes symbol table
doextdef external definition syntax
getatt get type attributes
dlist declaration list for structures/unions
getatt recursive gettype call
dodecl do one declaration
declarator handle declarator syntax
dodecl do one external declaraion
initlist external initialization list
cexpr constant expressions
expr arithmetic expressions
maketree build operator tree
funcbody function body
dlist declaration list
stmt function statements
stmt recursive stmt call
expr arithmetic expressions
*/
#include "parser.h"
int nextlabel 1;
int lineno;
char *exprp &exprarea[0];
/*
* main - main routine for parser
* Checks arguments, opens input and output files, does main loop
* for external declarations and blocks.
*/
main(argc,argv) /* returns - none*/
int argc; /* argument count*/
char *argv[]; /* argument pointers*/
{
register char *q;
register int i;
for( i = 4; i < argc; i++ ) {
q = argv[i];
if( *q++ != '-' )
usage();
while( 1 ) {
switch( *q++ ) {
case 'f':
fflag++;
continue;
case 'e':
eflag++;
continue;
case 'w':
wflag++;
continue;
case '\0':
break;
default:
usage();
}
break;
}
}
if( argc < 4 )
usage();
if( fopen(argv[1],&ibuf,0) < 0 ) /* 3rd arg for versados */
ferror("can't open %s",argv[i]);
if( fcreat(argv[2],&obuf,0) < 0 || fcreat(argv[3],&sbuf,0) < 0 )
ferror("temp creation error");
obp = &obuf;
lineno++;
frstp = -1; /* [vlh] 3.4 - initialize only once */
syminit();
while( !peek(EOF) )
doextdef();
outeof();
outdata();
copysfile(argv[3]);
exit(errcnt!=0);
}
/* usage - output usage error message and die*/
usage()
{
ferror("usage: c068 source icode str [-e] [-f] [-w]");
}
/* error - report an error message*/
/* outputs current line number and error message*/
error(s,x1,x2,x3,x4,x5,x6) /* returns - none*/
char *s; /* error message*/
int x1, x2, x3, x4, x5, x6; /* args for printf*/
{
register char *savep;
savep = obp;
obp = 0;
errcnt++;
if (!inclflag) {
if( lineno )
printf("* %d: ",lineno);
}
else /*[vlh] generate filename and approp line #*/
printf("%s: * %d: ",inclfile,inclline);
printf(s,x1,x2,x3,x4,x5,x6);
printf("\n");
obp = savep;
}
/* ferror - fatal error*/
/* Outputs error message and exits*/
ferror(s,x1,x2,x3,x4,x5,x6) /* returns - none*/
char *s; /* error message*/
int x1, x2, x3, x4, x5, x6; /* args for printf*/
{
error(s,x1,x2,x3,x4,x5,x6);
exit(1);
}
v6flush(v6buf)
struct iobuf *v6buf;
{
register i;
i = BLEN - v6buf->nunused;
v6buf->nunused = BLEN;
v6buf->xfree = &(v6buf->buff[0]);
if(write(v6buf->fildes,v6buf->xfree,i) != i)
return(-1);
return(0);
}

View File

@@ -0,0 +1,168 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/* alignment, node type altering routines, dimension table allocating */
/* routine, and routines to determine elements actual size */
#include "parser.h"
#define DTSIZE 077 /*data size in bytes*/
char dinfo[];
/* dalloc - dimension table allocation*/
/* Allocates an entry in the dimension table.*/
dalloc(dimsize) /* returns ptr to dimension allocated*/
long dimsize; /* dimension size [vlh] 3.4 i=>l*/
{
register int i;
if( (i=cdp++) >= DSIZE-1 )
ferror("dimension table overflow");
dtab[i] = dimsize;
return(i);
}
/* addsp - add special type to special type info*/
/* Takes given special type and adds it into the special type field.*/
addsp(type,nsptype) /* returns resulting type*/
int type; /* old type field*/
int nsptype; /* special type to be added*/
{
register int dtype;
dtype = btype(type);
type =& (~TYPE);
return( (type<<SUTYPLEN) | suptype(nsptype) | dtype );
}
/* delsp - delete one special type info field from special type info*/
/* Takes given special type field and deletes least sign.*/
delsp(type) /* returns resulting type*/
int type; /* old special type*/
{
register int dtype;
dtype = btype(type);
type =& (~(ALLTYPE));
return( (type>>SUTYPLEN) | dtype );
}
/*
* revsp - reverse special type info
* This allows for the processing of the super-type info in
* the reverse order, which is necessary for initializations.
*/
revsp(type) /* returns reversed type info*/
int type; /* type to reverse*/
{
register int t;
for( t = btype(type); suptype(type) != 0; type = delsp(type) )
t = addsp(t,type);
return(t);
}
/* falign - handle bit field alignments*/
falign(type,flen) /* returns number of bytes padded*/
int type; /* data type*/
int flen; /* field length*/
{
register int off;
off = 0;
if( flen <= 0 ) {
error("invalid field size");
flen = 0;
}
switch( type ) {
case INT:
case UNSIGNED:
if( flen > BITSPWORD )
error("field overflows word");
if( flen + boffset > BITSPWORD )
off = CHRSPWORD;
break;
case CHAR:
if( flen > BITSPCHAR )
error("field overflows byte");
if( flen + boffset > BITSPCHAR )
off = 1;
break;
default:
error("invalid field type description");
return(0);
}
if( off )
boffset = 0;
boffset =+ flen;
return(off);
}
/* salign - structure alignment*/
salign(type,offset) /* returns bytes of padding*/
int type; /* data type to align*/
int offset; /* current structure offset*/
{
register int off;
off = offset;
if( boffset ) { /*remaining bit fields, flush 'em*/
off =+ (boffset+(BITSPCHAR-1))/BITSPCHAR;
boffset = 0;
}
while( array(type) ) /*get base type*/
type = delsp(type);
if( type != CHAR ) /*need word boundary*/
off = walign(off);
return( off - offset );
}
/* delspchk - delete one special reference and check if non-zero*/
delspchk(type) /*returns new special type*/
int type; /* type to modify*/
{
if(!(suptype(type)))
error("bad indirection");
return( delsp(type) );
}
/* psize - return size of object ptd at by pointer*/
long /* [vlh] 3.4 int => long */
psize(tp) /* returns size of object in bytes*/
struct tnode *tp; /* pointer to tree node*/
{
if ( !(suptype(tp->t_type)) ) /* what case ??? */
return(1);
return( dsize(delsp(tp->t_type),tp->t_dp,tp->t_ssp) );
}
/* dsize - returns size of data object in bytes*/
long /* [vlh] 3.4 */
dsize(type,dp,sp) /* returns number of bytes*/
int type; /* type of node*/
int dp; /* dimension pointer*/
int sp; /* size pointer if structure*/
{
register long nel, size;
nel = 1;
for( ; array(type); type = delsp(type) )
nel = dtab[dp];
if( function(type) )
return(0);
size = (pointer(type)) ? PTRSIZE : (type == STRUCT) ?
dtab[sp] : dinfo[type]&DTSIZE;
if(!size)
error("invalid data type");
return( size * nel );
}

View File

@@ -0,0 +1,165 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/* node allocation, node stack manipulation routines */
#include "parser.h"
int opdontop;
int strassign;
/* talloc - expression area tree node allocation
* Allocates area and checks for overflow.*/
char *talloc(size) /* returns pointer to node*/
int size; /* size of node to alloc*/
{
register char *p;
p = opap;
if( p + size >= &exprarea[EXPSIZE] )
ferror("expression too complex");
opap = p + size;
return(p);
}
/*
* enalloc - external name alloc
* Allocates an expression tree node for an external name and
* copies symbol table info and symbol into tree node.
*/
char *enalloc(sp) /* returns - none*/
struct symbol *sp; /* pointer to symbol table entry*/
{
register struct extnode *ep;
ep = talloc(sizeof(*ep));
ep->t_op = SYMBOL;
ep->t_sc = sp->s_sc;
ep->t_type = sp->s_type;
ep->t_dp = sp->s_dp;
ep->t_ssp = sp->s_ssp;
ep->t_offset = sp->s_offset;
symcopy(sp->s_symbol,ep->t_symbol);
return(ep);
}
/* cnalloc - constant node allocation
* Allocates a constant tree node and fills the info fields.*/
char *cnalloc(type,value) /* returns pointer to node*/
int type; /* data type*/
int value; /* constant value*/
{
register struct conode *cp;
cp = talloc(sizeof(*cp));
cp->t_op = CINT;
cp->t_type = type;
cp->t_dp = 0;
cp->t_ssp = 0;
cp->t_value = value;
return(cp);
}
/* lcnalloc - long constant node allocation*/
/* Allocates a constant tree node and fills the info fields.*/
char *lcnalloc(type,value) /* returns pointer to node*/
int type; /* data type*/
long value; /* constant value*/
{
register struct lconode *cp;
cp = talloc(sizeof(*cp));
cp->t_op = CLONG;
cp->t_type = type;
cp->t_dp = 0;
cp->t_ssp = 0;
cp->t_lvalue = value;
return(cp);
}
/* fpcnalloc - floating point constant node allocation*/
/* Allocates a constant tree node and fills the info fields.*/
char *fpcnalloc(type,value) /*[vlh] 3.4 returns pointer to node*/
int type; /* data type*/
long value; /* constant value*/
{
register struct lconode *cp;
cp = talloc(sizeof(*cp));
cp->t_op = CFLOAT;
cp->t_type = type;
cp->t_dp = 0;
cp->t_ssp = 0;
cp->t_lvalue = value;
return(cp);
}
/* tnalloc - tree node allocation*/
/* Allocates an operator tree node and fills the info fields*/
char *tnalloc(op,type,dp,ssp,left,right) /* returns pointer to node*/
int op; /* operator*/
int type; /* operator type*/
int dp; /* dimension pointer or other info*/
int ssp; /* structure length pointer*/
char *left; /* left subtree*/
char *right; /* right subtree*/
{
register struct tnode *tp;
tp = talloc(sizeof(*tp));
tp->t_op = op;
tp->t_type = type;
tp->t_dp = dp;
tp->t_ssp = ssp;
tp->t_left = left;
tp->t_right = right;
return(tp);
}
/* snalloc - symbol node allocation*/
/* Allocates a tree symbol node and sets the info in it*/
char *snalloc(type,sc,off,dp,ssp) /* returns pointer to node alloc'ed*/
int type; /* symbol type*/
int sc; /* storage class*/
int off; /* offset*/
int dp; /* dimension pointer or other info*/
int ssp; /* structure size pointer*/
{
register struct symnode *snp;
snp = talloc(sizeof(*snp));
snp->t_op = SYMBOL;
snp->t_sc = sc;
snp->t_type = type;
snp->t_dp = dp;
snp->t_ssp = ssp;
snp->t_offset = off;
return(snp);
}
/* pushopd - put operand node onto operand stack*/
/* Checks for operand stack overflow.*/
pushopd(tp) /* returns - none*/
struct tnode *tp; /* pointer to tree node to push*/
{
if( opdp >= &opdstack[OPDSIZE] )
ferror("expression too complex");
*opdp++ = tp;
}
/* popopd - pop operand stack*/
/* Checks for stack underflow*/
char *popopd() /* returns ptr to top operand*/
{
register struct tnode *tp;
if( opdp <= &opdstack[0] )
return(0);
tp = *--opdp;
return(tp);
}

View File

@@ -0,0 +1,316 @@
/*#define DEBUG 1*/
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*
C68 Parser - include file
*/
#include "../icode.h"
/*symbol attribute fields*/
#define SRESWORD 001 /*is symbol a reserved word?*/
#define SGLOBAL 002 /*is symbol global?*/
#define STYPEDEF 004 /*typedef declaration?*/
#define SDEFINED 010 /*symbol defined?*/
/*reserved words*/
#define R_AUTO 1
#define R_BREAK 2
#define R_CASE 3
#define R_CHAR 4
#define R_CONTINUE 5
#define R_DO 6
#define R_DEFAULT 7
#define R_DOUBLE 8
#define R_GOTO 9
#define R_ELSE 10
#define R_EXTERNAL 11
#define R_FLOAT 12
#define R_FOR 13
#define R_IF 14
#define R_INT 15
#define R_LONG 16
#define R_REGISTER 17
#define R_RETURN 18
#define R_SHORT 19
#define R_SIZEOF 20
#define R_STATIC 21
#define R_STRUCT 22
#define R_SWITCH 23
#define R_TYPEDEF 24
#define R_UNION 25
#define R_UNSIGNED 26
#define R_WHILE 27
/*
* mixed-mode conversions, entries in 2-d array indexed by:
* (int,unsn,long,doub,ptr)
*/
#define INT_CHAR 1
#define UNSN_CHAR 1
#define LONG_CHAR 1
#define DOUB_CHAR 1
#define PTR_CHAR 1
#define INT_UNSN 0 /*no conversion is generated*/
#define INT_LONG 2
#define INT_DOUB 3
#define INT_PTR 4
#define UNSN_INT 0 /*no conversion is generated*/
#define UNSN_LONG 6
#define UNSN_DOUB 7
#define UNSN_PTR 8
#define LONG_INT 9
#define LONG_UNSN 10
#define LONG_DOUB 11
#define LONG_PTR 12
#define DOUB_INT 13
#define DOUB_UNSN 14
#define DOUB_LONG 15
#define PTR_INT 16
#define PTR_UNSN 17
#define PTR_LONG 18
#define PTR_PTR 19
#define BADCONV 20
/* miscellaneous constants */
#define OPSSIZE 40 /*operator stack size*/
#define OPDSIZE 80 /*operand stack size*/
#define HSIZE 517 /*hash table size, 3.4 made prime */
/* [vlh] 4.1 was 1024, but 1144 is divisible evenly on the 11 and 68000 */
#define SYMSIZE 1144 /*size to alloc for symbol structures*/
#define SWSIZE 256 /*max no. of cases in a switch*/
#define DSIZE 1000 /*dimension table size*/
#define BITSPWORD 16 /*bits per word*/
#define AREGLO 010 /*A reg flag*/
#define HICREG 2 /*highest reg # used for code generation*/
#define BITSPCHAR 8 /*bits per char*/
#define CHRSPWORD 2 /*chars per word*/
#define STRSIZE 300 /*max string length*/
#define NFARGS 40 /*max no. of args to function*/
#define NFRSTR 20 /*max no. of forward ref struct proto*/
/*symbol table node*/
struct symbol {
char s_attrib; /* defined, resword, global, typedef */
char s_sc; /* auto, static, external, register */
int s_type; /* 4bits specified, 2 bit fields for ptr... */
int s_dp; /* index into dimension table */
int s_ssp; /* dimension table/function arg table */
int s_offset; /* offset inside of structure */
char s_symbol[SSIZE]; /* symbol identifier, to SSIZE chars */
struct symbol *s_struc; /* if struct, ptr to parent (sys III) */
struct symbol *s_next; /* next symbol table entry */
};
/*expression tree operator node*/
struct tnode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
struct tnode *t_left;
struct tnode *t_right;
};
/*expression tree node for symbol - only keeps location*/
struct symnode {
int t_op;
int t_type; /*data type of symbol*/
int t_dp; /*dimension pointer of symbol*/
int t_ssp; /*structure size index to dtab*/
int t_sc; /*storage class of symbol*/
int t_offset; /*offset of symbol*/
int t_label;
};
/*expressioon tree node for external symbol - need to keep name*/
struct extnode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
int t_sc;
int t_offset;
int t_reg;
int t_symbol[SSIZE]; /*symbol name*/
};
/*expression tree node for integer constant*/
struct conode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
int t_value; /*constant value*/
};
struct lconode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
long t_lvalue; /*constant value*/
};
struct swtch {
int sw_label;
int sw_value;
} swtab[SWSIZE];
/*operator and operand stack used by expr*/
struct ops { /*operator stack*/
int o_op; /*operator*/
int o_pri; /*priority*/
} opstack[OPSSIZE], *opp;
char *opdstack[OPDSIZE]; /*operand stack*/
char **opdp; /*operand stack pointer*/
char *opap; /*ptr to next available loc in exprarea*/
char *exprp; /*place to start building expression*/
int opinfo[]; /*operator info table*/
struct tnode *frp; /*pointer to function return info node*/
int swp; /*current entry in switch table*/
int cswp; /*current low switch table index*/
int nextlabel; /*generates unique label numbers*/
int clabel; /*continue label*/
int blabel; /*break label*/
int rlabel; /*return label*/
int dlabel; /*default label*/
int lineno; /*current line number of input*/
int errcnt; /*count of errors*/
int inclflag; /*in include file, don't incr line #'s*/
int inclline; /*[vlh]line# in incl file for err rpting*/
char inclfile[13]; /*[vlh]include filename for err rpting*/
int equalstop; /*stop lex at '=', used for external init*/
int commastop; /*stop parse @ comma(used for const expr)*/
int colonstop; /*stop parse @ colon(used for case value)*/
int instruct; /*set when in structure declaration*/
int smember; /*set when seen . or ->*/
int infunc; /*set when in function body*/
int tdflag; /*declaration is a typedef proto*/
char *tdp; /*points to typedef prototype*/
int localsize; /*length of local variables*/
int naregs; /*keeps track of ptr registers alloc'd*/
int ndregs; /*keep track of data registers alloc'd*/
int loadreg; /*need to load registers...*/
int boffset; /*current bit offset in structure*/
int eflag; /*[vlh] 3.4 IEEE floats */
int fflag; /*[vlh] 3.4 FFP floats */
int xflag; /*translate int's to long's*/
int wflag; /*[vlh] don't generate warning mesgs*/
int reducep; /*[vlh] if(procid); reduction*/
int peektok; /*peeked at token*/
/*dimension table*/
long dtab[DSIZE]; /* [vlh] 3.4 int => long */
int cdp; /*next entry in dtab to alloc*/
/*lexical analyzer values*/
int cvalue; /*current token value if keyword or CINT*/
int cstrsize; /*current string size*/
long clvalue; /*current token value if long constant*/
struct symbol *csp; /*current token symbol ptr if SYMBOL*/
char cstr[STRSIZE]; /*current token value if CSTRING*/
struct symbol *dsp; /*declarator symbol pointer*/
/* -1 -> not instruct, 0 -> unnamed struct */
struct symbol *strucptr[10]; /*[vlh] ptrs to struc symbols*/
/*function argument table, used to collect function parameters*/
struct farg {
struct symbol *f_sp;
int f_offset;
} fargtab[NFARGS];
/*forward referenced structure prototype names*/
struct symbol *frstab[NFRSTR];
int frstp;
/*output buffers for intermediate code and strings*/
struct io_buf obuf, sbuf, ibuf, *obp;
#define stypedef(sp) (sp->s_attrib&STYPEDEF)
#define walign(add) ((add+1)&(~1))
#define array(type) ((type&SUPTYP)==ARRAY)
#define function(type) ((type&SUPTYP)==FUNCTION)
#define pointer(type) ((type&SUPTYP)==POINTER)
#define notarray(type) ((type&SUPTYP)!=ARRAY)
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
#define notpointer(type) ((type&SUPTYP)!=POINTER)
#define btype(type) (type&TYPE)
#define suptype(type) (type&SUPTYP)
#define alltype(type) (type&(SUPTYP|TYPE))
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
#define relop(op) ((opinfo[op]&OPREL)!=0)
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
#define binop(op) ((opinfo[op]&OPBIN)!=0)
#define unaryop(op) ((opinfo[op]&OPBIN)==0)
#define leaf(op) ((opinfo[op]&OPTERM)!=0)
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
#define oppriority(op) (opinfo[op]&OPPRI)
#define makeiop(op) (op|(0254<<8))
/* checks for symbol with structure element storage class */
#define isstel(tp) (tp->t_op==SYMBOL && (sesc(tp)))
#define sesc(t) (t->t_sc==STELCL||t->t_sc==UNELCL||t->t_sc==BFIELDCL)
/* peek at next token, if not read token put back, else delete */
/* 1 if matched, 0 otherwise */
#define peek(tok) ( (peektok=gettok()) == tok )
#define outcommon(sym,size) printf("\t.comm _%.8s,%ld\n",sym,size)
#define outgoto(lab) if( lab > 0 ) printf("\tbra L%d\n",lab)
/* change to text segment */
#define outtext() printf("\t.text\n")
/* change segment to bss */
#define outbss() printf("\t.bss\n")
/* output global symbol references */
#define outextdef(sym) printf("\t.globl _%.8s\n",sym)
/* outputs reserved memory [vlh] 3.4 %d => %ld */
#define outresmem(size) printf("\t.ds.b %ld\n",size)
/* output padding for word alignments */
#define outpad() printf("\t.even\n")
/* output long constant to assembler */
#define outlcon(val) printf("\t.dc.l %d\n",val)
/* output label constant */
#define outclab(lab) printf("\t.dc.l L%d\n",lab)
/* output a label */
#define outlab(lab) printf("\tL%d:",lab)
/* output function label */
#define outflab(sym) printf("\t_%.8s:\n\t~~%.8s:\n",sym,sym)
/* output data label */
#define outdlab(sym) printf("\t_%.8s:\n",sym)
/*functions returning pointers*/
char *expr();
char *talloc();
char *tnalloc();
char *enalloc();
char *snalloc();
char *cnalloc();
char *lcnalloc();
char *fpcnalloc();
char *popopd();
char *cvopgen();
char *arrayref();
char *funcref();
char *install();
char *lookup();
char *balpar();
char *sbrk();
long initlist();
long dsize();
long psize();
long dodecl();
long dlist();
long getdec();
long gethex();
long getoct();
long getfp();
long toieee();
long toffp();

View File

@@ -0,0 +1,255 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
#ifdef DEBUG
char invalid[] "INVALID";
char *opname[] {
invalid, /*0*/
"+", /*1*/
"-", /*2*/
"*", /*3*/
"/", /*4*/
"%", /*5*/
">>", /*6*/
"<<", /*7*/
"&", /*8*/
"|", /*9*/
"^", /*10*/
"!", /*11*/
"U-", /*12*/
"~", /*13*/
"--p", /*14*/
"++p", /*15*/
"p--", /*16*/
"p++", /*17*/
"=", /*18*/
"+=", /*19*/
"-=", /*20*/
"*=", /*21*/
"/=", /*22*/
"%=", /*23*/
">>=", /*24*/
"<<=", /*25*/
"&=", /*26*/
"|=", /*27*/
"^=", /*28*/
"jsr", /*29*/
"==", /*30*/
"!=", /*31*/
">", /*32*/
">=", /*33*/
"<", /*34*/
"<=", /*35*/
"int->long", /*36*/
"long->int", /*37*/
"btst", /*38*/
"load", /*39*/
"long*", /*40*/
"long/", /*41*/
"long%", /*42*/
"long*=", /*43*/
"long/=", /*44*/
"long%=", /*45*/
"=addr", /*46*/
"=not", /*47*/
"=neg", /*48*/
"docast", /*49*/
"st=", /*50*/
"ltof", /*51*/
"ftol", /*52*/
"itof", /*53*/
"ftoi", /*54*/
"tochar", /*55*/
invalid, /*56*/
invalid, /*57*/
invalid, /*58*/
invalid, /*59*/
"U&", /*60*/
"U*", /*61*/
"&&", /*62*/
"||", /*63*/
"?", /*64*/
":", /*65*/
",", /*66*/
"cint", /*67*/
"clong", /*68*/
"symbol", /*69*/
"++a", /*70*/
"a--", /*71*/
"call", /*72*/
"call()", /*73*/
"bitfield", /*74*/
"if", /*75*/
"init", /*76*/
"loadR0", /*77*/
"divlong", /*78*/
};
char *types[] {
invalid, /*0=TYPELESS*/
"char", /*1=CHAR*/
invalid, /*2=SHORT*/
"int", /*3=INT*/
"long", /*4=LONG*/
invalid, /*5=UCHAR*/
invalid, /*6=USHORT*/
"uint", /*7=UINT*/
invalid, /*8=ULONG*/
"float", /*9=FLOAT*/
invalid, /*10=DOUBLE*/
"struct", /*11=STRUCT*/
invalid, /*12=undefined*/
invalid, /*13=undefined*/
invalid, /*14=undefined*/
invalid, /*15=undefined*/
};
char *suvals[] {
"zero",
"one",
"quick",
"small",
"constant",
"Areg",
"Dreg",
"addressable",
"loadable",
"easy",
"hard",
"veryhard",
};
int level;
putexpr(name,tp)
char *name;
struct tnode *tp;
{
printf("%s\n",name);
putsexpr(tp);
}
putsexpr(tp)
struct tnode *tp;
{
register struct tnode *ltp;
level++;
ltp = tp->t_left;
outlevel();
printf("%s ",opname[tp->t_op]);
puttsu(tp);
if (tp->t_op < 0 || tp->t_op > 78) {
printf("INVALID op\n");
return;
}
switch( tp->t_op ) {
case DCLONG:
case CLONG:
case CFLOAT: /*[vlh] 3.4 */
printf(" %x.%x\n",tp->t_lvalue.hiword,tp->t_lvalue.loword);
break;
case CINT:
printf(" %d\n",tp->t_value);
break;
case AUTODEC:
case AUTOINC:
printf("Autodec or Autoinc");
break;
case SYMBOL:
switch( tp->t_sc ) {
case REGISTER:
printf(" Register");
break;
case CINDR:
printf(" %d\n",tp->t_offset);
break;
case CLINDR:
case CFINDR: /* [vlh] 3.4 */
printf(" %x.%x\n",tp->t_offset,tp->t_ssp);
break;
case REGOFF:
printf(" Regoffset");
break;
case EXTERNAL:
case EXTOFF:
printf(" %s+%d",tp->t_symbol,tp->t_offset);
if( tp->t_sc == EXTOFF )
printf("Ext offset");
break;
case STATIC:
case STATOFF:
printf(" STATIC or STATOFF");
if( tp->t_sc == STATOFF )
printf("STATOFF");
break;
case INDEXED:
printf(" %d indexed",tp->t_offset);
break;
}
putchar('\n');
break;
case IFGOTO:
putsexpr(tp->t_left);
break;
default:
putchar('\n');
putsexpr(tp->t_left);
if( binop(tp->t_op) )
putsexpr(tp->t_right);
break;
}
level--;
}
outlevel()
{
register int i;
for( i = 0; i < level; i++ )
printf(" ");
}
puttsu(tp)
struct tnode *tp;
{
register int i;
switch( suptype(tp->t_type) ) {
case FUNCTION:
printf("()");
break;
case ARRAY:
printf("[]");
break;
case POINTER:
printf("*");
break;
}
printf("%s ",types[btype(tp->t_type)]);
}
#endif

View File

@@ -0,0 +1,524 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
#define labgen(l,sl) sl=l;l=nextlabel++
int swp -1;
/* stmt - process a single statement*/
stmt() /* returns - none*/
{
register int token, lab, i;
register struct tnode *tp;
register char *p;
while( 1 ) {
switch(token=gettok()) {
case LCURBR: /*handle { ... }*/
while( !next(EOF) ) {
if( next(RCURBR) )
return;
stmt();
}
case EOF:
error("{ not matched by }");
case SEMI: /*null statement*/
return;
case RCURBR:
pbtok(token);
return;
case SYMBOL: /*symbol: statement*/
if( peekc(':') ) {
dolabel();
continue;
}
default: /*anything else...*/
pbtok(token);
outexpr(expr());
break;
case RESWORD:
switch(cvalue) {
case R_BREAK:
lab = brklabel();
outgoto(lab); /*branch to break label*/
break;
case R_CASE:
docase();
continue;
case R_CONTINUE:
lab = contlabel(); /*branch to continue label*/
outgoto(lab);
break;
case R_DEFAULT:
dodefault();
continue;
case R_DO:
dodo();
break;
case R_FOR:
dofor();
return;
case R_GOTO:
lab = gotolabel();
outgoto(lab);
break;
case R_IF:
doif();
return;
case R_RETURN:
doreturn();
break;
case R_SWITCH:
doswitch();
return;
case R_WHILE:
dowhile();
return;
default:
synerr("invalid keyword");
return;
}
}
if( !next(SEMI) )
synerr("missing semicolon");
return;
}
}
/* balpar - handle expression within parenthesis for while and if*/
/* Merely checks for left and right parens and builds expression.*/
char *balpar() /* returns pointer to expression*/
{
register struct tnode *tp;
if( next(LPAREN) ) {
reducep = 1;
tp = expr();
reducep = 0;
if( next(RPAREN) )
return(tp);
}
synerr("parenthesized expression syntax");
return(0);
}
/* synerr - syntax error*/
/* Outputs error message and tries to resyncronize input.*/
synerr(s,x1,x2,x3,x4,x5,x6) /* returns - none*/
char *s; /* printf format string*/
int x1, x2, x3, x4, x5, x6; /* printf arguments*/
{
register int token;
error(s,x1,x2,x3,x4,x5,x6);
while( (token=gettok()) != SEMI && token != EOF && token != LCURBR &&
token != RCURBR )
;
pbtok(token);
}
/* gotolabel - gets label id for goto*/
/* This is used for both: goto symbol and if(...)goto symbol*/
gotolabel() /* returns 0 if not, else label id*/
{
register struct symbol *sp;
if( !next(SYMBOL) )
synerr("expected label");
else {
sp = csp;
if( !(sp->s_sc) ) {
sp->s_type = LLABEL;
if( !sp->s_offset )
sp->s_offset = nextlabel++;
}
if( (!sp->s_sc || sp->s_sc == STATIC ) && sp->s_type == LLABEL )
return(sp->s_offset);
synerr("invalid label");
}
return(0);
}
/* dolabel - do statement label*/
/* Checks current symbol for already being defined, then sets*/
/* symbol attributes for label.*/
dolabel() /* returns - none*/
{
register struct symbol *sp;
sp = csp;
if( sp->s_sc )
error("label redeclaration: %.8s",sp->s_symbol);
else {
sp->s_attrib =| SDEFINED;
sp->s_sc = STATIC;
sp->s_type = LLABEL;
if( !sp->s_offset )
sp->s_offset = nextlabel++;
outlab(sp->s_offset);
}
}
/* brklabel - generate break label*/
/* Checks if break label is undefined, and if so, generates message*/
brklabel() /* returns label number*/
{
if( !blabel )
error("invalid break statement");
return(blabel);
}
/* contlabel - generate continue label*/
/* Checks if continue label is undefined, and if so, generates message*/
contlabel() /* returns label number*/
{
if( !clabel )
error("invalid continue statement");
return(clabel);
}
/* docase - handles: case constant : statement*/
/* Checks for being in a switch statement, adds entry to switch table*/
docase() /* returns - none*/
{
register int value, lab;
colonstop++;
value = cexpr(); /*get case value*/
colonstop--;
if( !next(COLON) ) /*check for colon*/
synerr("missing colon");
if( swp < 0 )
error("case not inside a switch block");
else if( swp >= (SWSIZE-1) )
error("too many cases in switch");
else {
addswitch(&swtab[cswp],swp-cswp,value,lab=nextlabel++);
outlab(lab);
swp++;
}
}
/* dodefault - handles: default : statement*/
/* Checks for colon and being in a switch statement*/
dodefault() /* returns - none*/
{
if( !next(COLON) )
error("missing colon");
if( swp < 0 )
error("default not inside a switch block");
else {
dlabel = nextlabel++; /*allocate default label*/
outlab(dlabel); /*output default label*/
}
}
/* dodo - handles: do statement while ( expression )*/
dodo() /* returns - none*/
{
register int lab, saveblab, saveclab;
labgen(blabel,saveblab);
labgen(clabel,saveclab);
lab = nextlabel++;
outlab(lab); /*branch back to here*/
stmt(); /*do statement*/
outlab(clabel); /*continue label*/
if( !nextrw(R_WHILE) ) {
error("missing while"); /*only advisory...*/
outgoto(lab);
}
else
outifgoto(balpar(),TRUE,lab); /*while expression*/
outlab(blabel); /*break label*/
blabel = saveblab; /*restore labels*/
clabel = saveclab;
}
#define dobody(l) stmt();outlab((l));clno=lineno;lineno=rinit
/*
* dofor - handle: for ( expression ; expression ; expression ) statement
* Hard part is handling re-initialization expression, which is
* parsed and saved, then the statement is parsed, then the reinit
* clause expression tree is output.
*/
dofor() /* returns - none*/
{ /* [vlh] 4.0 reordered */
register int testlab, stmtlab, saveblab, saveclab;
register struct tnode *rip, *cp;
register char *savep;
int rinit, clno, iscond;
labgen(blabel,saveblab);
labgen(clabel,saveclab);
if( !next(LPAREN) ) {
forerr:
synerr("invalid for statement");
return;
}
if( !next(SEMI) ) { /*do init expression*/
outexpr(expr());
if( !next(SEMI) )
goto forerr;
}
savep = exprp; /* save ptr to exprarea */
if( !next(SEMI) ) { /* do for condition */
testlab = nextlabel++; /* if condition, get a label */
outgoto(testlab); /* only goto cond expr if exists*/
iscond = 1;
cp = expr();
exprp = opap;
if( !next(SEMI) )
goto forerr;
}
else
iscond = 0;
stmtlab = nextlabel++;
outlab(stmtlab); /* branch back to here */
rinit = lineno;
if( next(RPAREN) ) { /*no re-init - easy case*/
dobody(clabel); /*output statement*/
}
else { /*there is a re-init clause*/
rip = expr(); /*save re-init tree until done*/
exprp = opap;
if( !next(RPAREN) )
goto forerr;
dobody(clabel); /*do statment*/
outexpr(rip); /*output re-init clause*/
}
if (iscond) {
outlab(testlab); /* branch for test */
outifgoto(cp,TRUE,stmtlab);
}
else
outgoto(stmtlab); /* unconditional branch */
exprp = savep;
lineno = clno;
outlab(blabel); /* break label */
blabel = saveblab;
clabel = saveclab; /*restore labels*/
}
/* doif - handles: if ( expression ) statement [ else statement ]*/
/* Handles special cases for goto, break, continue and return.*/
doif() /* returns - none*/
{
register struct tnode *tp;
register int elselab, exitlab;
tp = balpar(); /*if( expr )...*/
exitlab = 0;
if( nextrw(R_GOTO) )
exitlab = gotolabel();
else if( nextrw(R_BREAK) )
exitlab = brklabel();
else if( nextrw(R_CONTINUE) )
exitlab = contlabel();
else if( nextrw(R_RETURN) ) {
if( peekc(';') ) {
exitlab = rlabel;
putback(';');
}
else
pbtok(RESWORD);
}
if( exitlab ) { /*easy goto, do branch if true*/
outifgoto(tp,TRUE,exitlab);
if( !next(SEMI) )
synerr("missing semicolon");
if( nextrw(R_ELSE) ) /*else clause, just output it*/
stmt();
}
else { /*hard goto, branch over statement*/
elselab = nextlabel++;
outifgoto(tp,FALSE,elselab);
stmt();
if( nextrw(R_ELSE) ) {
exitlab = nextlabel++; /*branches over else clause*/
outgoto(exitlab); /*branch out of then clause*/
outlab(elselab); /*label to start else clause*/
stmt(); /*else statement*/
outlab(exitlab);
}
else
outlab(elselab); /*no else, just branch out*/
}
}
/*
* doreturn - handles: return [ expression ] ;
* Expression is the hard part, must create an assignment expression
* to assign expression to the type of the function, then get it
* loaded into a specific register.
*/
doreturn() /* returns - none*/
{
register struct tnode *tp;
if( !peekc(';') ) /*need to compute return?*/
outforreg(FRETURN,frp,expr());
else
putback(';');
outgoto(rlabel); /*branch to the return label*/
}
/*
* doswitch - handles: switch ( expression ) statement
* Evaluates the expression, forces the result into a known register
* collects the case statements in swtab, then outputs the switch
* operator and switch cases.
*/
doswitch() /* returns - none*/
{
register int saveblab, swlab, savedlab, saveswp, i;
register struct tnode *tp;
labgen(blabel,saveblab);
tp = balpar();
integral(tp,-1); /*must be integral type result*/
outforreg(ASSIGN,snalloc(INT,AUTO,0,0,0),tp);
saveswp = swp; /*remember old switch pointer*/
if( saveswp < 0 )
swp++;
i = cswp;
cswp = swp; /*remember real first entry*/
swlab = nextlabel++;
outgoto(swlab); /*branch to switch code*/
savedlab = dlabel;
dlabel = 0;
stmt(); /*do switch statement*/
outgoto(blabel); /*output branch just in case*/
outlab(swlab); /*here we now do the switch code*/
if( !dlabel )
dlabel = blabel;
outswitch(swp-cswp,dlabel,&swtab[cswp]);
outlab(blabel); /*break to here*/
cswp = i;
swp = saveswp;
blabel = saveblab;
dlabel = savedlab;
}
/* dowhile - handles: while ( expression ) statement*/
/* This is fairly straight-forward.*/
dowhile() /* returns - none*/
{ /* [vlh] 4.0 reworked */
register int saveclab, saveblab, lab;
register char *savep;
register struct tnode *tp;
labgen(blabel,saveblab);
labgen(clabel,saveclab);
labgen(clabel,lab);
savep = exprp;
if((tp = balpar()) != 0) /*get condition clause*/
outgoto(clabel); /*condition label*/
exprp = opap;
outlab(lab);
stmt(); /*statement*/
outlab(clabel); /*condition test*/
outifgoto(tp,TRUE,lab); /* branch back to top of loop */
outlab(blabel); /*break to here*/
exprp = savep;
blabel = saveblab;
clabel = saveclab; /*restore labels*/
}
/* nextrw - is next token the specified reserved word?*/
nextrw(rw) /* returns 1 if match, 0 otherwise*/
int rw; /* reserved word to match*/
{
register int token;
if( (token=gettok()) != RESWORD || cvalue != rw ) {
pbtok(token);
return(0);
}
return(1);
}
/*
* addswitch - add an entry into current switch table, bubble sorting
* This makes it easier on the code generator and also checks for
* duplicate labels at the "right" time.
*/
addswitch(sp,ncases,nval,nlab) /* returns - none*/
struct swtch *sp; /* switch table pointer*/
int ncases; /* number of cases in switch*/
int nval; /* new value*/
int nlab; /* new label*/
{
register struct swtch *nswp, *s;
register int temp, i;
nswp = &sp[ncases];
nswp->sw_value = nval;
nswp->sw_label = nlab;
s = nswp--;
for( ; --ncases >= 0; s--, nswp-- ) {
if( s->sw_value == nswp->sw_value )
error("duplicate case value");
if( s->sw_value < nswp->sw_value ) {
temp = s->sw_value;
s->sw_value = nswp->sw_value;
nswp->sw_value = temp;
temp = s->sw_label;
s->sw_label = nswp->sw_label;
nswp->sw_label = temp;
}
}
}
/* outforreg - generate assignment for switch and return*/
outforreg(op,ltp,rtp) /*returns - none*/
int op; /*operator for build tree*/
struct tnode *ltp; /*left expression tree*/
struct tnode *rtp; /*right expression tree*/
{
register struct tnode *tp;
opp = opstack;
opdp = opdstack;
pushopd(ltp);
pushopd(rtp);
maketree(op);
if( tp = popopd() )
outcforreg(tp->t_right);
opp = opdp = 0;
}
/* outassign - generate assignment for function args*/
outassign(ltp,rtp) /*returns - none*/
struct tnode *ltp; /*left expression tree*/
struct tnode *rtp; /*right expression tree*/
{
opp = opstack;
opdp = opdstack;
pushopd(ltp);
pushopd(rtp);
maketree(ASSIGN);
outexpr(popopd());
opp = opdp = 0;
}

View File

@@ -0,0 +1,119 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
#define ASGOP OPRAS|OPASSIGN|OPLVAL|OPBIN
/*info on operators:*/
/*000077-- OPPRI - priority*/
/*000100-- OPBIN - binary operator*/
/*000200-- OPLVAL - left operand must be lvalue*/
/*000400-- OPREL - relational operator*/
/*001000-- OPASSIGN - assignment operator*/
/*002000-- OPLWORD - int required on left*/
/*004000-- OPRWORD - int required on right*/
/*010000-- OPCOM commutative*/
/*020000-- OPRAS - right associative*/
/*040000-- OPTERM - termination node*/
/*100000 - OPCONVS - conversion operator*/
int opinfo[] {
TRMPRI, /*EOF*/
ADDPRI|OPCOM|OPBIN, /*ADD - expr + expr*/
ADDPRI|OPBIN, /*SUB - expr - expr*/
MULPRI|OPCOM|OPBIN, /*MULT - expr * expr*/
MULPRI|OPBIN, /*DIV - expr / expr*/
MULPRI|OPBIN, /*MOD - expr % expr*/
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*RSH - expr >> expr*/
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*LSH - expr << expr*/
ANDPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*AND - expr & expr*/
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*OR - expr | expr*/
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*XOR - expr ^ expr*/
UNOPRI|OPRAS|OPLWORD, /*NOT - ! expr*/
UNOPRI|OPRAS, /*UMINUS - - expr*/
UNOPRI|OPRAS|OPLWORD, /*COMPL - ~ expr*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREDEC - --lvalue*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREINC - ++lvalue*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTDEC - lvalue--*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTINC - lvalue++*/
ASGPRI|ASGOP, /*ASSIGN - lvalue = expr*/
ASGPRI|ASGOP, /*EQADD - lvalue += expr*/
ASGPRI|ASGOP, /*EQSUB - lvalue -= expr*/
ASGPRI|ASGOP, /*EQMULT - lvalue *= expr*/
ASGPRI|ASGOP, /*EQDIV - lvalue /= expr*/
ASGPRI|ASGOP, /*EQMOD - lvalue %= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQRSH - lvalue >>= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQLSH - lvalue <<= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQAND - lvalue &= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQOR - lvalue |= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQXOR - lvalue ^= expr*/
TRMPRI, /*FJSR - generate function jsr*/
EQLPRI|OPREL|OPBIN, /*EQUALS - expr == expr*/
EQLPRI|OPREL|OPBIN, /*NEQUALS - expr != expr*/
RELPRI|OPREL|OPBIN, /*GREAT - expr > expr*/
RELPRI|OPREL|OPBIN, /*GREATEQ - expr >= expr*/
RELPRI|OPREL|OPBIN, /*LESS - expr < expr*/
RELPRI|OPREL|OPBIN, /*LESSEQ - expr <= expr*/
TRMPRI|OPCONVS, /*INT2L*/
TRMPRI|OPCONVS, /*LONG2I*/
TRMPRI|OPBIN, /*BTST*/
TRMPRI, /*LOAD*/
TRMPRI|OPBIN, /*LMULT*/
TRMPRI|OPBIN, /*LDIV*/
TRMPRI|OPBIN, /*LMOD*/
TRMPRI|OPBIN, /*LEQMULT*/
TRMPRI|OPBIN, /*LEQDIV*/
TRMPRI|OPBIN, /*LEQMOD*/
TRMPRI|ASGOP, /*EQADDR*/
TRMPRI, /*EQNOT*/
TRMPRI, /*EQNEG*/
TRMPRI|OPBIN, /*DOCAST*/
ASGPRI|ASGOP, /*STASSIGN [vlh]*/
TRMPRI|OPCONVS, /*LONG2F [vlh] 3.4*/
TRMPRI|OPCONVS, /*FLOAT2L [vlh] 3.4*/
TRMPRI|OPCONVS, /*INT2F [vlh] 3.4*/
TRMPRI|OPCONVS, /*FLOAT2I [vlh] 3.4*/
UNOPRI|OPRAS, /*TOCHAR [vlh] 4.0*/
TRMPRI, /*unused - 56*/
TRMPRI, /*unused - 57*/
TRMPRI, /*unused - 58*/
TRMPRI, /*unused - 59*/
UNOPRI|OPRAS|OPLVAL, /*ADDR - & expr*/
UNOPRI|OPRAS|OPLWORD, /*INDR - * expr*/
LNDPRI|OPBIN, /*LAND - expr && expr*/
LORPRI|OPBIN, /*LOR - expr || expr*/
QMKPRI|OPRAS|OPBIN, /*QMARK - expr ? expr : expr*/
QMKPRI|OPRAS|OPBIN, /*COLON*/
COMPRI|OPBIN, /*COMMA*/
TRMPRI|OPTERM, /*CINT*/
TRMPRI|OPTERM, /*CLONG*/
TRMPRI|OPTERM, /*SYMBOL*/
TRMPRI|OPTERM, /*AUTOINC*/
TRMPRI|OPTERM, /*AUTODEC*/
LPNPRI|OPBIN, /*CALL - call with arguments*/
LPNPRI, /*NACALL - no argument call*/
TRMPRI, /*BFIELD - field selection*/
TRMPRI, /*IFGOTO*/
TRMPRI, /*INIT*/
TRMPRI, /*CFORREG*/
TRMPRI, /*unused - 78*/
TRMPRI|OPTERM, /*CFLOAT [vlh] 3.4*/
UNOPRI|OPRAS|OPASSIGN|OPBIN, /*CAST*/
TRMPRI, /*SEMI*/
TRMPRI, /*LCURBR - {*/
TRMPRI, /*RCURBR - }*/
LPNPRI, /*LBRACK - [*/
RPNPRI, /*RBRACK - ]*/
LPNPRI, /*LPAREN - )*/
RPNPRI, /*RPAREN - )*/
TRMPRI|OPTERM, /*STRING*/
TRMPRI, /*RESWORD*/
LPNPRI|OPBIN, /*APTR - expr -> symbol*/
LPNPRI|OPBIN, /*PERIOD - expr . symbol*/
UNOPRI|OPRAS, /*SIZEOF - sizeof expr*/
LPNPRI|OPBIN, /*MPARENS - matching parens ()*/
UNOPRI|OPRAS|OPASSIGN|OPBIN, /*FRETURN*/
};

View File

@@ -0,0 +1 @@
char *compiled "@(#) parser - Fri Mar 18 11:33 1983";

View File

@@ -0,0 +1,3 @@
c68 -L *.c -n -o c168.st -l6 ; setstack c168.st 8192 8192
c68 -L *.c -o c168.68 -l6 ; setstack c168.68 8192 8192
cc *.c -o c168.11 -lx

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,191 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "../icode.h"
//#define NODEBUG 0
//#define VERSADOS
char brtab[][2];
int invrel[];
int swaprel[];
char *strtab[];
char null[];
/*operator tree node for unary and binary operators*/
struct tnode {
int t_op; /*operator*/
int t_type; /*data type of result*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
struct tnode *t_left; /*left sub-tree*/
struct tnode *t_right; /*right sub-tree (undefined if unary)*/
};
/*constant terminal node*/
struct conode {
int t_op; /*operator*/
int t_type; /*type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_value; /*value or label number*/
};
struct lconode {
int t_op; /*operator*/
int t_type; /*type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
long t_lvalue; /*value or label number*/
};
/*local symbol terminal node*/
struct symnode {
int t_op; /*operator*/
int t_type; /*symbol data type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_sc; /*storage class*/
int t_offset; /*register offset*/
int t_reg; /*register number*/
int t_label; /*label number if static*/
};
/*external symbol reference node*/
struct extnode {
int t_op; /*operator*/
int t_type; /*symbol data type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_sc; /*storage class*/
int t_offset; /*register offset*/
int t_reg; /*register number*/
char t_symbol[SSIZE]; /*symbol name*/
};
/*68000 special - indexed symbol node*/
/*this is used to generate a An(off,Xn.type) address*/
struct indexnode {
int t_op;
int t_type;
int t_su;
int t_ssp;
int t_sc;
int t_offset;
int t_reg;
int t_xreg;
int t_xtype;
};
int lflag;
int dflag;
int mflag;
int cflag;
int eflag;
int fflag;
int oflag;
struct io_buf ibuf, obuf;
int lineno;
int naregs;
int ndregs;
int errcnt;
int opinfo[];
int nextlabel;
char null[];
char optab[][6];
char *mnemonics[];
char *codeskels[];
int stacksize;
char *tnalloc();
char *snalloc();
char *cenalloc();
char *xnalloc();
char *talloc();
char *cnalloc();
char *lcnalloc();
char *fpcnalloc();
char *canon();
char *commute();
char *constant();
char *match();
char *addptree();
char *fixbfield();
char *coffset();
char *tcopy();
#define wallign(add) ((add+1)&(~1))
#define array(type) ((type&SUPTYP)==ARRAY)
#define function(type) ((type&SUPTYP)==FUNCTION)
#define pointer(type) ((type&SUPTYP)==POINTER)
#define notarray(type) ((type&SUPTYP)!=ARRAY)
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
#define notpointer(type) ((type&SUPTYP)!=POINTER)
#define isfloat(type) (type==FLOAT)
#define btype(type) (type&TYPE)
#define suptype(type) (type&SUPTYP)
#define alltype(type) (type&(SUPTYP|TYPE))
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
#define relop(op) ((opinfo[op]&OPREL)!=0)
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
#define binop(op) ((opinfo[op]&OPBIN)!=0)
#define unaryop(op) ((opinfo[op]&(OPBIN|OPTERM))==0)
#define leafop(op) ((opinfo[op]&OPTERM)!=0)
#define notleafop(op) ((opinfo[op]&OPTERM)==0)
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
#define oppriority(op) (opinfo[op]&OPPRI)
#define commop(op) ((opinfo[op]&OPCOM)!=0)
#define convop(op) ((opinfo[op]&OPCONVS)!=0)
#define notconvop(op) ((opinfo[op]&OPCONVS)==0)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define QUICKVAL 8
#define LEP 14
#define FORCC 1
#define FOREFF 2
#define FORSTACK 3
#define FORCREG 4
#define FORSP 5
#define FORREG 4
#define HICREG 2
#define NCREGS 3
#define AREGLO 8
#define IMMED 1
#define NOTIMMED 0
#define NOTLOFFSET 0
/* one line routines turned into defines [vlh] for speed */
/*outgoto - output "bra L[labno]"*/
#define outgoto(lab) if (lab>0) printf("bra L%d\n",lab)
/*outlab - output "L[labno]:"*/
#define outlab(lab) if (lab>0) printf("L%d:",lab)
/*outext - output register sign extension*/
#define outext(reg) printf("ext.l R%d\n",reg)
/*outuext - output unsigned to long register extension*/
#define outuext(reg) printf("swap R%d\nclr R%d\nswap R%d\n",reg,reg,reg)
/*outswap - output swap register instruction*/
#define outswap(reg) printf("swap R%d\n",reg)
/*outaddr - output "add [type] R1 R2" instruction*/
#define outaddr(r1,r2,tp) outrr("add",r1,r2,(tp))
/*outccsave - ouput instruction to move cc's to register*/
#define outccsave(reg) printf("move sr,R%d\n",reg)
/*outccrestore - output instruction to restore cc's from register*/
#define outccrestore(reg) printf("move R%d,ccr\n",reg)
/*basetype - get the btype info sans unsigned*/
#define basetype(type) ((type==UNSIGNED) ? INT : type)
#define unsign(type) ((type) == UNSIGNED)
#define longorptr(type) (type==LONG || (type&SUPTYP))
#define unorptr(type) (type==UNSIGNED || (type&SUPTYP))
#define dreg(reg) ((reg) & (~AREGLO))
#define areg(reg) ((reg) | AREGLO)
#define isareg(reg) ((reg) >= AREGLO)
#define isdreg(reg) ((reg) < AREGLO)
#define isreg(tp) ((tp)->t_op == SYMBOL && (tp)->t_sc == REGISTER)

View File

@@ -0,0 +1,756 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
#include "cskel.h"
/* scodegen - over-all code generation for expression*/
/* Picks off post-fix ++, --.*/
scodegen(tp,cookie,reg) /* returns register result is in*/
struct tnode *tp;
int cookie;
int reg;
{
struct tnode *clist[20];
struct tnode **clp;
register struct tnode **cp;
register int r;
register int ccflag;
register struct tnode *rtp;
if( tp->t_op == COMMA ) {
scodegen(tp->t_left,FOREFF,reg);
return(scodegen(tp->t_right,cookie,reg));
}
ccflag = 0;
clp = clist;
tp = addptree(tp,&clp);
if( clp > clist ) {
/*
* post ++, -- in tree. We need to compile the tree post operators
* then generate code to do the post operators, then do any fix up of
* condition codes since the Stupid 68000 architect was a nimnul.
*/
if( cookie == FORCC ) {
/*
* here we make the observation that if we are comparing something with
* zero OR the top operator of the tree is not a comparison operator,
* we can compile the tree to a register, and then set the condition
* codes OK with a tst instruction at the end.
*/
if( relop(tp->t_op) ) {
if( (rtp=constant(tp->t_right)) && !rtp->t_value ) {
ccflag = 1;
tp = tp->t_left;
cookie = FORREG;
}
else
ccflag = 2;
}
else {
ccflag = 1;
cookie = FORREG;
}
}
}
r = codegen(tp,cookie,reg);
if( clp > clist ) {
if( ccflag == 2 )
outccsave(r);
for( cp = clist; cp < clp; cp++ )
codegen(*cp,FOREFF,r+1);
if( ccflag == 1 )
outcmp0(r,tp);
else if( ccflag == 2 )
outccrestore(r);
}
return(r);
}
/* addptree - prune off postfix ++, -- from expression tree*/
/* This prunes off ++, -- and collects those expressions for*/
/* scodegen.*/
char *addptree(tp,clp) /* returns pointer to pruned tree*/
struct tnode *tp;
struct tnode ***clp;
{
register int op;
op = tp->t_op;
if( leafop(op) || op == QMARK ) /* [vlh] 4.0 QMARK... */
return(tp);
if( op == POSTINC || op == POSTDEC ) {
*(*clp)++ = tp;
return( tcopy(tp->t_left) );
}
if( binop(op) )
tp->t_right = addptree(tp->t_right,clp);
tp->t_left = addptree(tp->t_left,clp);
return(tp);
}
/* codegen - generate code for expression*/
/* This calls up rcodegen, which prunes off any special register*/
/* optimization code, then calls ucodegen (unrecursive) code*/
/* generation.*/
codegen(tp,cookie,reg) /* returns reg result is in*/
struct tnode *tp; /* tree pointer*/
int cookie; /* code generation goals*/
int reg; /* first available register*/
{
register int size, savestk, ssize, r, i, scookie;
register struct tnode *rtp;
#ifndef NODEBUG
if( cflag )
printf("codegen op=%d cookie=%d reg=%d\n",tp->t_op,cookie,reg);
#endif
switch( tp->t_op ) {
case CALL:
case NACALL:
ssize = 0;
savestk = stacksize;
if( tp->t_left->t_op != SYMBOL )
stacksize++;
if( tp->t_op == CALL ) {
rtp = tp->t_right;
while( rtp->t_op == COMMA ) {
ssize =+ dofarg(rtp->t_right);
rtp = rtp->t_left;
}
ssize =+ dofarg(rtp);
}
tp->t_op = FJSR; /*generate JSR (unary op)*/
codegen(tp,FORREG,reg);
popstack(ssize);
stacksize = savestk;
fixresult(tp,cookie,0);
return(0); /*result in R0*/
case COMMA:
codegen(tp->t_left,FOREFF,reg);
return(codegen(tp->t_right,cookie,reg));
case AND:
if( cookie == FORCC && (i=isonebit(tp->t_right)) >= 0 &&
(i=dobitadd(tp->t_left,i)) >= 0 ) {
if( convop(tp->t_right->t_op) )
tp->t_right = tp->t_right->t_left;
tp->t_right->t_value = i;
tp->t_op = BTST;
tp = canon(tp);
sucomp(tp,reg,1);
}
break;
}
if( rcodegen(&tp,cookie,reg) ) {
if( cookie == FORCC && tp->t_op == SYMBOL && tp->t_sc == REGISTER
&& isdreg(tp->t_reg))
return(reg);
}
r = ucodegen(tp,cookie,reg);
return(r);
}
/* fixresult - fix result of code generation*/
fixresult(tp,cookie,reg) /* returns - none*/
struct tnode *tp;
int cookie; /* wanted this cookie*/
int reg;
{
#ifndef NODEBUG
if (cflag)
printf("fixresult cookie=%d reg=%d op=%d\n",cookie,reg,tp->t_op);
#endif
switch( cookie ) {
case FORCC:
outcmp0(reg,tp);
break;
case FORSP:
case FORSTACK:
stacksize++;
outrpush(reg,tp,cookie==FORSTACK);
break;
}
return(reg);
}
/* ucodegen - generate code for tree given cookie and starting register*/
/* Handles the matching of the expression tree node with the*/
/* corresponding code generation table. When a match is found,*/
/* expand is called to expand the code skeleton macro.*/
ucodegen(tp,cookie,reg) /* returns reg result is in*/
struct tnode *tp; /* pointer to expression tree*/
int cookie; /* (FORCC,FOREFF,FORREG,FORSTACK)*/
int reg; /* first available register*/
{
register int r;
register char *p;
#ifndef NODEBUG
if(cflag)
putexpr("ucodegen",tp);
#endif
switch( tp->t_op ) {
case STASSIGN: /*[vlh]*/
outstrcpy(codegen(tp->t_left,FORREG,areg(reg)),
codegen(tp->t_right,FORREG,areg(reg+1)), tp->t_type);
return(reg);
break;
case SYMBOL:
if( cookie == FOREFF )
return(reg);
break;
case LSH:
if( (isareg(reg)) && (p=constant(tp->t_right)) &&
!(unsign(tp->t_left->t_type)) &&
(p->t_value == 1 || p->t_value == 2) ) {
r = codegen(tp->t_left,FORREG,reg);
outmovr(r,reg,tp->t_left);
if( p->t_value == 2 )
outaddr(reg,reg,tp);
outaddr(reg,reg,tp);
fixresult(tp,cookie,reg);
return(reg);
}
break;
case EQMULT:
case EQDIV:
case LEQMULT:
case LEQDIV:
case EQMOD:
case LEQMOD:
case EQRSH:
case EQLSH:
case EQAND:
case EQOR:
case EQXOR:
if( indexreg(tp->t_left) ) {
reg = dreg(reg);
outmovr(r=tp->t_left->t_reg,reg,tp);
tp->t_left->t_reg = reg;
codegen(tp,cookie,reg+1);
outmovr(reg,r,tp);
return(reg);
}
break;
case ADD:
case EQADD:
if( (p=constant(tp->t_right)) && p->t_value < 0 &&
p->t_value >= -QUICKVAL ) {
p->t_value = - p->t_value;
tp->t_op =+ (SUB-ADD);
}
break;
}
sucomp(tp,reg,1);
if( (r=loadexpr(tp,cookie,reg)) >= 0 )
return(r);
if( (r=cqmark(tp,cookie,reg)) >= 0 )
return(r);
if( (r=hardrel(tp,cookie,reg)) >= 0 )
return(r);
if( cookie == FORCC && (p=match(tp,FOREFF,reg)) != 0 ) {
r = expand(tp,FOREFF,reg,p);
if( asgop(tp->t_op) && indexreg(tp->t_left) )
outcmp0(tp->t_left->t_reg,tp->t_left);
}
else if( p = match(tp,cookie,reg) )
r = expand(tp,cookie,reg,p);
else if( cookie != FORREG )
r = fixresult(tp,cookie,ucodegen(tp,FORREG,reg));
else
error("no code table for %d",tp->t_op);
return(r);
}
/* outstrcpy - output structure copy */
outstrcpy(lr,rr,size) /*[vlh]*/
int lr, rr; /* left register, right register */
int size; /* structure size to copy */
{
register int lab;
lab = nextlabel++;
printf("move #%d,r%d\n",(size/2)-1,dreg(lr));
outlab(lab);
printf("move (r%d)+,(r%d)+\ndbra r%d,L%d\n",rr,lr,dreg(lr),lab);
}
/* loadexpr - load an addressable expression into a register*/
/* This checks for any possible usage of the register indexed*/
/* addressing mode. Note that this relies on the good graces of the*/
/* load code skeletons not to muck up the compiler registers before*/
/* loading an addressable expression...*/
loadexpr(tp,cookie,reg) /* returns register loaded or -1*/
struct tnode *tp; /* pointer to expression tree*/
int reg; /* register to load*/
{
register struct tnode *rtp, *ltp, *xtp, *atp;
register int off, r, type, nr, ar, xr, xt;
if( tp->t_op == INDR || LOADABLE(tp) ) {
type = tp->t_type;
if( tp->t_op == INDR && (ltp=tp->t_left)->t_op == ADD ) {
rtp = ltp->t_right;
ltp = ltp->t_left;
off = 0;
if( rtp->t_op == CINT && ((off=rtp->t_value) < -128 ||
off > 127 || ltp->t_op != ADD ) ) {
tp = snalloc(type,AUTO,off,0,0);
if( indexreg(ltp) )
tp->t_reg = ltp->t_reg;
else {
r = codegen(ltp,FORREG,areg(reg));
if( isdreg(r) )
outmovr(r,areg(r),ltp);
tp->t_reg = areg(r);
}
}
else {
if( rtp->t_op == CINT ) {
rtp = ltp->t_right;
ltp = ltp->t_left;
}
if(indexreg(rtp) || (!(indexreg(ltp)) && (isreg(rtp)))) {
xtp = ltp;
ltp = rtp;
rtp = xtp;
}
xtp = atp = 0;
if( indexreg(ltp) ) {
ar = ltp->t_reg;
if( (isreg(rtp)) && rtp->t_type != CHAR ) {
xr = rtp->t_reg;
xt = rtp->t_type;
}
else
xtp = rtp;
}
else if( (isreg(ltp)) && ltp->t_type != CHAR &&
(lflag || rtp->t_op != ADDR) ) {
xr = ltp->t_reg;
xt = ltp->t_type;
atp = rtp;
}
else if( rtp->t_op == ADDR ) {
atp = ltp;
xtp = rtp;
}
else {
atp = rtp;
xtp = ltp;
}
nr = 0;
if( atp )
nr++;
if( xtp && (xtp->t_op != ADDR || lflag ) )
nr++;
if( dreg(nr+reg) <= HICREG ) {
r = reg;
if( atp ) {
ar = codegen(atp,FORREG,areg(r));
if( isdreg(ar) ) {
outmovr(ar,areg(ar),atp);
ar = areg(ar);
}
r++;
}
if( xtp && xtp->t_op == ADDR && !lflag ) {
tp = xtp->t_left;
tp->t_sc =+ (EXTOFF-EXTERNAL);
tp->t_offset =+ off;
tp->t_reg = ar;
}
else {
if( xtp ) {
xr = codegen(xtp,FORREG,areg(r));
xt = xtp->t_type;
}
tp = xnalloc(type,ar,off,xr,xt);
}
}
}
}
if( (isareg(reg)) && tp->t_type == CHAR )
reg = dreg(reg);
tp = tnalloc(LOAD,tp->t_type,SU_EASY,0,tp,null);
return( codegen(tp,cookie,reg) );
}
return(-1);
}
/* coffset - check offset for addressable node*/
char *coffset(tp) /* returns ptr to const off node*/
struct tnode *tp; /* pointer to node*/
{
register struct tnode *rtp;
if( tp->t_op == ADD ) {
rtp = tp->t_right;
if( rtp->t_op == CINT )
return(rtp);
if(!lflag) {
if( rtp->t_op == ADDR )
return(rtp->t_left);
rtp = tp->t_left;
if( rtp->t_op == ADDR ) {
tp->t_left = tp->t_right;
tp->t_right = rtp;
return(rtp->t_left);
}
}
}
return(0);
}
/* hardrel - do relationals returning a value*/
hardrel(tp,cookie,reg) /* returns reg or -1*/
struct tnode *tp; /* pointer to tree*/
int cookie; /* cookie for code generation*/
int reg; /* low register*/
{
char *p;
int op, lab1, lab2;
if( cookie != FORCC && (relop(op=tp->t_op) || op == LOR ||
op == LAND || op == NOT) ) {
lab1 = nextlabel++;
condbr(tp,TRUE,lab1,reg);
p = canon(cnalloc(INT,0));
codegen(p,cookie,reg);
lab2 = nextlabel++;
outgoto(lab2);
outlab(lab1);
p = canon(cnalloc(INT,1));
codegen(p,cookie,reg);
outlab(lab2);
return(reg);
}
return(-1);
}
/* cqmark - compile question mark operator*/
/* This does the compilation of the question mark operator.*/
cqmark(tp,cookie,reg) /* returns reg or -1*/
struct tnode *tp;
int cookie;
int reg;
{
register int lab1, lab2, savestk, r;
if( tp->t_op == QMARK && cookie != FORCC ) {
lab1 = nextlabel++;
condbr(tp->t_left,FALSE,lab1,reg);
savestk = stacksize;
r = scodegen(tp->t_right->t_left,cookie,reg); /* [mc] 4.0 */
outmovr(r,reg,tp);
stacksize = savestk;
outgoto(lab2=nextlabel++);
outlab(lab1);
r = scodegen(tp->t_right->t_right,cookie,reg); /* [mc] 4.0 */
outmovr(r,reg,tp);
outlab(lab2);
return(reg);
}
return(-1);
}
/* condbr - handle conditional branch code generation*/
/* This handles the conditional branch code generation, handling*/
/* the special cases for constants, ||, &&, ! and generating the*/
/* correct conditional branch instruction.*/
condbr(tp,dir,lab,reg)
struct tnode *tp;
int dir;
int lab;
int reg;
{
register struct tnode *ltp, *rtp;
register int lab1, optype, op, subdir;
ltp = tp->t_left;
if( binop(op=tp->t_op) )
rtp = tp->t_right;
subdir = dir; /*set up for LOR*/
switch( op ) {
case CINT:
if( !tp->t_value ) {
if( dir == FALSE )
outgoto(lab);
}
else if( dir != FALSE )
outgoto(lab);
break;
case NOT:
condbr(ltp,!dir,lab,reg);
break;
case LAND:
dir = !dir;
case LOR:
if( dir == FALSE ) {
lab1 = nextlabel++;
condbr(ltp,!subdir,lab1,reg);
condbr(rtp,subdir,lab,reg);
outlab(lab1);
}
else {
condbr(ltp,subdir,lab,reg);
condbr(rtp,subdir,lab,reg);
}
break;
case COMMA:
scodegen(tp->t_left,FOREFF,reg);
condbr(tp->t_right,dir,lab,reg);
break;
default:
if( op == NEQUALS && ltp->t_op == PREDEC &&
isdreg(ltp->t_left->t_reg) && ltp->t_left->t_type == INT &&
rtp->t_op == CINT && rtp->t_value == -1 ) {
outdbra(ltp->t_left->t_reg,lab);
break;
}
if( relop(op) && ltp->t_op == AUTOINC && rtp->t_op == AUTOINC &&
ltp->t_type == rtp->t_type )
outcmpm(tp);
else
scodegen(tp,FORCC,reg);
optype = 0;
if( relop(op) ) {
if( unorptr(ltp->t_type) || unorptr(rtp->t_type) )
optype =+ 1;
}
else
op = NEQUALS;
if(!dir)
op = invrel[op-EQUALS];
optype = brtab[op-EQUALS][optype];
printf("%s L%d\n",mnemonics[optype],lab);
break;
}
}
rcodegen(tpp,cookie,reg) /* returns changed flag*/
struct tnode **tpp; /* pointer to tree*/
int cookie; /* code generation cookie*/
int reg; /* register to use for code*/
{
register int change, op;
register struct tnode *tp;
tp = *tpp;
op = tp->t_op;
change = 0;
if( notleafop(op) && op != COMMA ) {
change =+ rcodegen(&tp->t_left,cookie,reg);
if( binop(op) )
change =+ rcodegen(&tp->t_right,cookie,reg);
change =+ rcgen(tpp,cookie,reg);
}
if( change )
*tpp = canon(*tpp);
return(change);
}
rcgen(tpp,cookie,reg) /* returns changed flag*/
struct tnode **tpp; /* pointer to tree*/
int cookie; /* code generation goals*/
int reg; /* register to use*/
{
register struct tnode *tp, *p, *ltp, *rtp;
register int op, change;
change = 0;
for( tp = *tpp ; binop(op=tp->t_op); *tpp=tp=canon(tp), change++ ) {
ltp = tp->t_left;
if( ltp->t_op != SYMBOL )
break;
rtp = tp->t_right;
switch( op ) {
case ASSIGN:
if( ltp->t_sc != REGISTER )
return(change);
switch( rtp->t_op ) {
case MULT:
case DIV:
case MOD:
case AND:
case OR:
case XOR:
case LSH:
case RSH:
if( isareg(ltp->t_reg) )
return(change);
case ADD:
case SUB:
p = rtp->t_right;
if(NOTADDRESSABLE(ltp) || !noref(rtp->t_right,ltp->t_reg))
return(change);
p = rtp->t_left;
if( p->t_op != SYMBOL || p->t_sc != REGISTER ||
p->t_reg != ltp->t_reg ) {
tp->t_right = p;
#ifndef NODEBUG
if( cflag > 1 )
putexpr("rcgen",tp);
#endif
codegen(tp,FOREFF,reg);
}
tp->t_right = rtp->t_right;
tp->t_op = rtp->t_op + (EQADD-ADD);
continue;
}
case EQLSH:
case EQRSH:
if( ltp->t_sc != REGISTER )
return(change);
case EQADD:
case EQSUB:
case EQAND:
case EQOR:
case EQXOR:
if( ltp->t_type == CHAR )
return(change);
#ifndef NODEBUG
if( cflag > 1 )
putexpr("rcgen",tp);
#endif
ucodegen(tp,FOREFF,reg);
tp = ltp;
continue;
case PREDEC:
case PREINC:
if( cookie == FORCC || ltp->t_type == CHAR )
return(change);
ucodegen(tp,FOREFF,reg);
tp = ltp;
continue;
}
break;
}
return(change);
}
noref(tp,reg) /* 4.0 change */
struct tnode *tp; /* returns 1 if no reference in tree to reg */
int reg;
{
if ( leafop(tp->t_op) ) {
if (tp->t_op == SYMBOL && tp->t_sc == REGISTER && tp->t_reg == reg)
return(0);
return(1);
}
if ( !noref(tp->t_left,reg) )
return(0);
if (binop(tp->t_op))
return( noref(tp->t_right,reg) );
return(1);
}
/* cdsize - compute size of data item*/
cdsize(tp) /* returns data size in bytes*/
struct tnode *tp;
{
register int type;
type = tp->t_type;
if( suptype(type) )
return(PTRSIZE);
switch( type ) {
case CHAR:
case INT:
case UNSIGNED:
return(INTSIZE);
case LONG:
case FLOAT: /* [vlh] 3.4 */
return(LONGSIZE);
}
error("cdsize: invalid type %d",type);
return(0);
}
dofarg(tp) /* returns number of bytes pushed*/
struct tnode *tp; /* pointer to expression tree*/
{
register int nb;
nb = 0;
if( tp->t_op == SYMBOL && tp->t_sc == STRUCT )
error("structure operation not implemented");
else if( stacksize ) {
codegen(tp,FORSTACK,0);
nb = cdsize(tp);
}
else
codegen(tp,FORSP,0);
return( nb );
}
/* dobitadd - do bit operation address checking and fixup*/
dobitadd(tp,bitno) /* returns -1 if can't or bitno*/
struct tnode *tp;
int bitno;
{
register int offset;
if( tp->t_type == CHAR )
offset = 0;
else
offset = cdsize(tp) - (bitno/BITSPBYTE) - 1;
if( tp->t_op == SYMBOL ) {
switch( tp->t_sc ) {
case REGISTER:
if( isdreg(tp->t_reg) )
return(bitno);
default:
return(-1);
case EXTERNAL:
case STATIC:
case REGOFF:
case STATOFF:
case EXTOFF:
tp->t_offset =+ offset;
return( bitno % BITSPBYTE );
}
}
else if( tp->t_op == INDR ) {
tp->t_left = tnalloc(ADD,tp->t_left->t_type,0,0,tp->t_left,
cnalloc(INT,offset));
return( bitno % BITSPBYTE );
}
return(-1);
}
isonebit(tp) /* returns -1 if not 1 bit, else bitno*/
struct tnode *tp; /* pointer to tree*/
{
if( tp = constant(tp) )
return( onebit(tp->t_value) );
return(-1);
}

View File

@@ -0,0 +1,92 @@
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
/*built-in literals*/
#define MOV 128
#define MOVL 129
#define JSR 130
#define CLR 131
#define CLRL 132
#define EXTW 133
#define EXTL 134
#define LEA 135
#define STK 136
/*built-in macros*/
#define TREE 141
#define LEFT 142
#define RIGHT 143
#define LOFFSET 144
#define ROFFSET 145
#define LADDR 146
#define RADDR 147
#define CR 148
#define NR 149
#define CAR 150
#define NAR 151
#define TLEFT 152
#define TRIGHT 153
#define TEITHER 154
#define TLEFTL 155
#define OP 156
#define AOP 157
#define MODSWAP 158
#define EXL 159
#define EXLR 160
#define EXLRN 161
#define EXRL 162
#define EXRLN 163
#define PSH 164
#define POP 165
#define POP8 166
#define OPCALL 167
#define POP4 169
#define LADDRP 168
/*modifiers for compiling sub-trees*/
#define S_INDR 1 /*indirection*/
#define S_STACK 2 /*onto stack*/
#define S_FORCC 4 /*set condition codes*/
#define S_NEXT 8 /*into next register*/
/*Sethy-Ullman values*/
#define SU_ZERO 0x000 /*zero*/
#define SU_ONE 0x100 /*one*/
#define SU_SMALL 0x200 /*constant between 1 and 8*/
#define SU_QUICK 0x300 /*quick constant between -128 and 127*/
#define SU_CONST 0x400 /*any constant*/
#define SU_AREG 0x500 /*A register*/
#define SU_REG 0x600 /*register*/
#define SU_ADDR 0x700 /*addressable*/
#define SU_XREG 0x800 /*A register used as data...*/
#define SU_EASY 0x900 /*easy*/
#define SU_HARD 0xa00 /*hard*/
#define SU_VHARD 0xb00 /*very hard ... function calls, etc.*/
#define SU_ANY 0xf00 /*anything*/
#define ADDRESSABLE(x) (x->t_su<=SU_ADDR)
#define NOTADDRESSABLE(x) (x->t_su>SU_ADDR)
#define LOADABLE(x) (x->t_su<=SU_XREG)
/*flag byte (operand type):*/
#define T_CHAR 1 /*char only*/
#define T_SHORT 2 /*short*/
#define T_INT 3 /*int only*/
#define T_LONG 4 /*long*/
#define T_UCHAR 5 /*unsigned char*/
#define T_USHORT 6 /*unsigned short*/
#define T_UNSN 7 /*unsigned int*/
#define T_ULONG 8 /*unsigned long*/
#define T_FLOAT 9 /*float*/
#define T_DOUB 10 /*double*/
#define T_ANY 11 /*int or word (implied)*/
#define T_INDR 0x10 /*pointer type (bit)*/
struct skeleton {
int sk_left;
int sk_right;
char *sk_def;
};

View File

@@ -0,0 +1,134 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
int bol;
int onepass;
/* outexpr - output expression*/
outexpr(tp) /* returns - none*/
struct tnode *tp; /* pointer to tree node*/
{
if( dflag )
outline();
if( exprok(tp) )
scodegen(canon(tp),FOREFF,0);
}
outifgoto(tp,dir,lab)
struct tnode *tp;
int dir;
int lab;
{
if( dflag )
outline();
if( exprok(tp) )
condbr(canon(tp),dir,lab,0);
}
outcforreg(tp)
struct tnode *tp;
{
if( dflag )
outline();
if( exprok(tp) )
outmovr(scodegen(canon(tp),FORREG,0),0,tp);
}
outinit(tp) /* returns - none*/
struct tnode *tp;
{
register int typeout;
if( dflag )
outline();
if( exprok(tp) ) {
typeout = tp->t_type;
tp = canon(tp);
if( tp->t_op == ADDR )
tp = tp->t_left;
if( tp->t_op == CINT || tp->t_op == SYMBOL ) {
if( tp->t_op != CINT )
printf(".dc.l ");
else {
printf(".dc");
outtype(typeout);
putchar(' ');
}
outaexpr(tp,NOTIMMED); /* [vlh] 4.0 not immed... */
}
else
error("invalid initialization");
putchar('\n');
}
}
/* snalloc - code generator symbol node allocation*/
/* This might be coalesced into parser snalloc.*/
char *snalloc(type,sc,offset,dp,ssp) /* returns ptr to node alloced*/
int type; /* type of symbol*/
int sc; /* storage class*/
int offset; /* offset from Local Environment Ptr*/
int dp; /*for compatability with parser*/
int ssp; /*for compatability with parser*/
{
register struct symnode *sp;
sp = talloc(sizeof(*sp));
sp->t_op = SYMBOL;
sp->t_type = type;
sp->t_su = dp;
sp->t_ssp = ssp;
sp->t_sc = sc;
switch( sc ) {
case STATIC:
sp->t_offset = 0;
sp->t_reg = 0;
sp->t_label = offset;
break;
case REGISTER:
sp->t_offset = 0;
sp->t_reg = offset;
sp->t_label = 0;
break;
case AUTO:
sp->t_sc = REGOFF;
sp->t_offset = offset;
sp->t_reg = LEP;
sp->t_label = 0;
break;
default:
sp->t_offset = offset;
sp->t_reg = 0;
sp->t_label = 0;
break;
}
return(sp);
}
exprok(tp)
struct tnode *tp;
{
if( tp < exprarea || tp > &exprarea[EXPSIZE] )
return(0);
if( leafop(tp->t_op) )
return(1);
if( binop(tp->t_op) && !exprok(tp->t_right) )
return(0);
return( exprok(tp->t_left) );
}
outline()
{
if( onepass && !bol )
putchar('\n');
printf("*line %d\n",lineno);
}

View File

@@ -0,0 +1,401 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char *version "@(#) c168 code generator 4.0 - Mar 18, 1983";
#include "cgen.h"
#include "cskel.h"
char *opap;
int errflg;
int nextlabel 10000;
char *readtree();
char *readsym();
/* main - main routine, handles arguments and files*/
main(argc,argv) /* returns - none*/
int argc; /* arg count*/
char **argv; /* arg pointers*/
{
register char *q;
register int i;
#ifdef VERSADOS
lflag++;
#endif
for( i = 3; i < argc; i++ ) {
q = argv[i];
if( *q++ != '-' )
usage(argc,argv,1);
while( 1 ) {
switch( *q++ ) {
case 'D':
dflag++;
continue;
case 'L':
lflag++;
continue;
case 'e':
eflag++;
continue;
case 'f':
fflag++;
continue;
case 'm':
mflag++;
continue;
case 'o':
oflag++;
continue;
case 'c':
cflag++;
continue;
case '\0':
break;
default:
usage(argc,argv,2);
}
break;
}
}
if( argc < 3 )
usage(argc,argv,3);
if( fopen(argv[1],&ibuf,0) < 0 ) /* 3rd arg for versados */
ferror("can't open %s\n",argv[1]);
if( fcreat(argv[2],&obuf,0) < 0 ) /* 3rd arg for versados */
ferror("can't create %s\n",argv[2]);
readicode();
v6flush(&obuf);
exit(errcnt!=0);
}
/* readicode - read intermediate code and dispatch output*/
/* This copies assembler lines beginning with '(' to assembler*/
/* output and builds trees starting with '.' line.*/
readicode() /*returns - none*/
{
register int c;
register struct tnode *tp;
while( (c=getc(&ibuf)) > 0 ) {
switch(c) {
case '.':
lineno = readint();
opap = exprarea;
if( tp = readtree() ) {
#ifndef NODEBUG
if( cflag )
putexpr("readicode",tp);
#endif
switch( tp->t_op ) {
case INIT:
outinit(tp->t_left);
break;
case CFORREG:
outcforreg(tp->t_left);
break;
case IFGOTO:
outifgoto(tp->t_left,tp->t_type,tp->t_su);
break;
default:
outexpr(tp);
break;
}
}
break;
case '(':
while( (c=getc(&ibuf)) != '\n' )
putchar(c);
putchar(c);
break;
default:
error("intermediate code error %c,%d",c,c);
break;
}
}
}
/* readtree - recursive intermediate code tree read*/
char *readtree() /* returns ptr to expression tree*/
{
register int op, type, sc;
register struct tnode *tp, *rtp;
char sym[SSIZE];
long l;
if( (op=readint()) <= 0 )
return(0);
type = readint();
switch( op ) {
case SYMBOL:
if( (sc=readint()) == EXTERNAL )
tp = cenalloc(type,sc,readsym(sym));
else
tp = snalloc(type,sc,readint(),0,0);
break;
case CINT:
tp = cnalloc(type,readint());
break;
case CLONG:
l.hiword = readint();
l.loword = readint();
tp = lcnalloc(type,l);
break;
case CFLOAT: /* [vlh] 3.4 */
l.hiword = readint();
l.loword = readint();
tp = fpcnalloc(type,l);
break;
case IFGOTO:
case BFIELD:
sc = readint();
if( tp = readtree() )
tp = tnalloc(op,type,sc,0,tp,null);
break;
default:
if( binop(op) ) {
if( !(tp=readtree()) )
return(0);
if( !(rtp=readtree()) )
return(0);
tp = tnalloc(op,type,0,0,tp,rtp);
}
else if( tp = readtree() )
tp = tnalloc(op,type,0,0,tp,null);
break;
}
return(tp);
}
/* readint - reads an integer value from intermediate code*/
readint()
{
register int i, c;
i = 0;
while(1) {
switch( c = getc(&ibuf) ) {
case '.':
case '\n':
return(i);
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
i =<< 4;
i =+ (c-'0');
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
i =<< 4;
i =+ (c-('a'-10));
break;
default:
error("intermediate code error - %c,%d",c,c);
}
}
}
/* readsym - read a symbol from intermediate code*/
char *readsym(sym)
char *sym;
{
register int i, c;
register char *s;
for( i = SSIZE, s = sym; (c=getc(&ibuf)) != '\n'; )
if( --i >= 0 )
*s++ = c;
if( i > 0 )
*s = '\0';
return(sym);
}
/* error - output an error message*/
error(s,x1,x2,x3,x4,x5,x6)
char *s;
int x1, x2, x3, x4, x5, x6;
{
errcnt++;
errflg++;
if( lineno != 0 )
printf("** %d: ",lineno);
printf(s,x1,x2,x3,x4,x5,x6);
putchar('\n');
errflg--;
}
/* ferror - output error message and die*/
ferror(s,x1,x2,x3,x4,x5,x6)
char *s;
int x1, x2, x3, x4, x5, x6;
{
error(s,x1,x2,x3,x4,x5,x6);
exit(1);
}
/* tnalloc - allocate binary expression tree node*/
/* returns ptr to node made.*/
char *tnalloc(op,type,info,dummy,left,right)
int op; /* operator*/
int type; /* resultant node type*/
int info; /* info field*/
int dummy; /* dummy field - used to match pass1 args*/
struct tnode *left; /* left sub-tree*/
struct tnode *right; /* righst sub-tree*/
{
register struct tnode *tp;
tp = talloc(sizeof(*tp));
tp->t_op = op;
tp->t_type = type;
tp->t_su = info; /* info for bit-field & condbr's*/
tp->t_left = left;
tp->t_right = right;
return(tp);
}
/* cnalloc - allocate constant expression tree node*/
char *cnalloc(type,value) /* returns pointer to node alloced*/
int type; /* type of constant*/
int value; /* value of constant*/
{
register struct conode *cp;
cp = talloc(sizeof(*cp));
cp->t_op = CINT;
cp->t_type = type;
cp->t_value = value;
return(cp);
}
/* lcnalloc - allocate constant expression tree node*/
char *lcnalloc(type,value) /* returns pointer to node alloced*/
int type; /* type of constant*/
long value; /* value of constant*/
{
register struct lconode *cp;
cp = talloc(sizeof(*cp));
cp->t_op = CLONG;
cp->t_type = type;
cp->t_lvalue = value;
return(cp);
}
/* fpcnalloc - allocate constant expression tree node*/
char *fpcnalloc(type,value) /* returns pointer to node alloced*/
int type; /* type of constant*/
long value; /* value of constant*/
{ /* [vlh] 3.4 */
register struct lconode *cp;
cp = talloc(sizeof(*cp));
cp->t_op = CFLOAT;
cp->t_type = type;
cp->t_lvalue = value;
return(cp);
}
/* talloc - allocate expression tree area*/
char *talloc(size) /* returns pointer to area alloced*/
int size; /* number of bytes to alloc*/
{
register char *p;
p = opap;
if( p + size >= &exprarea[EXPSIZE] )
ferror("expression too complex");
opap = p + size;
return(p);
}
/* symcopy - copy symbol*/
symcopy(sym1,sym2) /* returns - none*/
char *sym1; /* from symbol*/
char *sym2; /* to symbol*/
{
register char *p, *q;
register int i;
for( p = sym1, q = sym2, i = SSIZE; --i >= 0; )
*q++ = (*p ? *p++ : '\0');
}
/* usage - ouput usage message*/
usage(argc,argv,n)
char *argv[];
{
register int i;
error("usage call #%d:\n",n);
for (i=0; i<argc; i++) error(" argv[%d] = %s\n",i,argv[i]);
ferror("usage: c168 icode asm [-DLmec]");
}
/* putchar - special version*/
/* This allows the use of printf for error messages, debugging*/
/* output and normal output.*/
putchar(c) /* returns - none*/
char c; /* character to output*/
{
if( errflg ) /*error message?*/
write(1,&c,1); /*write to standard output*/
else {
if( dflag > 1 )
write(1,&c,1); /*to standard output*/
putc(c,&obuf); /*put to assembler file*/
}
}
v6flush(v6b)
struct iobuf *v6b;
{
register i;
i = BLEN - v6b->nunused;
v6b->nunused = BLEN;
v6b->xfree = &(v6b->buff[0]);
if(write(v6b->fildes,v6b->xfree,i) != i)
return(-1);
return(0);
}

View File

@@ -0,0 +1,322 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
#define I_NULL 0
#define I_ADD 1
#define I_INC 2
#define I_SUB 3
#define I_DEC 4
#define I_MULS 5
#define I_MULU 6
#define I_DIVS 7
#define I_DIVU 8
#define I_ASR 9
#define I_LSR 10
#define I_ASL 11
#define I_LSL 12
#define I_AND 13
#define I_OR 14
#define I_EOR 15
#define I_NEG 16
#define I_NOT 17
#define I_MOVE 18
#define I_CLR 19
#define I_CMP 20
#define I_TST 21
#define I_LMUL 22
#define I_LDIV 23
#define I_LREM 24
#define I_LEML 25
#define I_LERM 27
#define I_BEQ 28
#define I_BNE 29
#define I_BGT 30
#define I_BGE 31
#define I_BLT 32
#define I_BLE 33
#define I_BLS 34
#define I_BLO 35
#define I_BCC 36
#define I_BHI 37
#define I_BRA 38
#define I_NOP 39
#define I_BTST 40
char *mnemonics[] {
"",
"add",
"inc",
"sub",
"dec",
"muls",
"mulu",
"divs",
"divu",
"asr",
"lsr",
"asl",
"lsl",
"and",
"or",
"eor",
"neg",
"not",
"move",
"clr",
"cmp",
"tst",
"lmul",
"_ldiv",
"lrem",
"almul",
"aldiv",
"alrem",
"beq",
"bne",
"bgt",
"bge",
"blt",
"ble",
"bls",
"blo",
"bcc",
"bhi",
"jmp",
"*nop",
"btst",
};
#define FE_EQOP 1
#define FE_ASSIGN 2
#define FE_EQSHFT 3
#define FE_EQXOR 4
#define FE_EQADDR 5
#define FC_FIX 6
#define FC_REL 7
#define FC_BTST 8
#define FS_OP 9
#define FS_ITL 10
#define FS_LD 11
#define FR_ADD 12
#define FR_MULT 13
#define FR_DIV 14
#define FR_SHFT 15
#define FR_XOR 16
#define FR_NEG 17
#define FR_EQOP 18
#define FR_POSTOP 19
#define FR_ASSIGN 20
#define FR_EQMULT 21
#define FR_EQDIV 22
#define FR_EQSHFT 23
#define FR_EQXOR 24
#define FR_CALL 25
#define FR_ITL 26
#define FR_LTI 27
#define FR_LD 28
#define FR_EQADDR 29
#define FR_EQNOT 30
#define FE_EQNOT 31
#define FR_DOCAST 32
#define FS_DOCAST 33
#define FR_FTOL 34
#define FR_LTOF 35
#define FR_FTOI 36
#define FR_ITOF 37
#define FE_EQMULT 38
#define FE_EQDIV 39
#define FE_EQMOD 40
#define FR_TOCHAR 41
char
fe_eqop[], /* 1=FE_EQOP */
fe_assign[], /* 2=FE_ASSIGN */
fe_eqshft[], /* 3=FE_EQSHFT */
fe_eqxor[], /* 4=FE_EQXOR */
fe_eqaddr[], /* 5=FE_EQADDR */
fc_fix[], /* 6=FC_FIX */
fc_rel[], /* 7=FC_REL */
fc_btst[], /* 8=FC_BTST */
fs_op[], /* 9=FS_OP */
fs_itl[], /* 10=FS_ITL */
fs_ld[], /* 11=FS_LD */
fr_op[], /* 12=FR_OP */
fr_mult[], /* 13=FR_MULT */
fr_div[], /* 14=FR_DIV */
fr_shft[], /* 15=FR_SHFT */
fr_xor[], /* 16=FR_XOR */
fr_neg[], /* 17=FR_NEG */
fr_eqop[], /* 18=FR_EQOP */
fr_postop[], /* 19=FR_POSTOP */
fr_assign[], /* 20=FR_ASSIGN */
fr_eqmult[], /* 21=FR_EQMULT */
fr_eqdiv[], /* 22=FR_EQDIV */
fr_eqshft[], /* 23=FR_EQSHFT */
fr_eqxor[], /* 23=FR_EQXOR */
fr_call[], /* 24=FR_CALL */
fr_itl[], /* 25=FR_ITL */
fr_lti[], /* 26=FR_LTI */
fr_ld[], /* 27=FR_LD */
fr_eqaddr[], /* 28=FR_EQADDR */
fr_eqnot[], /* 29=FR_EQNOT */
fe_eqnot[], /* 30=FE_EQNOT */
fr_docast[], /* 31=FR_DOCAST */
fs_docast[], /* 32=FS_DOCAST */
fr_ftol[], /* 34=FE_FTOL */
fr_ltof[], /* 35=FE_LTOF */
fr_ftoi[], /* 36=FE_FTOI */
fr_itof[], /* 37=FE_ITOF */
fe_eqmult[], /* 38=FE_EQMULT */
fe_eqdiv[], /* 39=FE_EQDIV */
fe_eqmod[], /* 40=FE_EQMOD */
fr_tochar[]; /* 41=FR_TOCHAR */
char *codeskels[] {
0, /*NULL*/
fe_eqop, /*1=FE_EQOP*/
fe_assign, /*2=FE_ASSIGN*/
fe_eqshft, /*3=FE_EQSHFT*/
fe_eqxor, /*4=FE_EQXOR*/
fe_eqaddr, /*5=FE_EQADDR*/
fc_fix, /*6=FC_FIX*/
fc_rel, /*7=FC_REL*/
fc_btst, /*8=FC_BTST*/
fs_op, /*9=FS_OP*/
fs_itl, /*10=FS_ITL*/
fs_ld, /*11=FS_LD*/
fr_op, /*12=FR_OP*/
fr_mult, /*13=FR_MULT*/
fr_div, /*14=FR_DIV*/
fr_shft, /*15=FR_SHFT*/
fr_xor, /*16=FR_XOR*/
fr_neg, /*17=FR_NEG*/
fr_eqop, /*18=FR_EQOP*/
fr_postop, /*19=FR_POSTOP*/
fr_assign, /*20=FR_ASSIGN*/
fr_eqmult, /*21=FR_EQMULT*/
fr_eqdiv, /*22=FR_EQDIV*/
fr_eqshft, /*23=FR_EQSHFT*/
fr_eqxor, /*24=FR_EQXOR*/
fr_call, /*25=FR_CALL*/
fr_itl, /*26=FR_ITL*/
fr_lti, /*27=FR_LTI*/
fr_ld, /*28=FE_LD*/
fr_eqaddr, /*29=FE_EQADDR*/
fr_eqnot, /*30=FE_EQNOT*/
fe_eqnot, /*31=FE_EQNOT*/
fr_docast, /*32=FE_DOCAST*/
fs_docast, /*33=FS_DOCAST*/
fr_ftol, /*34=FE_FTOL*/
fr_ltof, /*35=FE_LTOF*/
fr_ftoi, /*36=FE_FTOI*/
fr_itof, /*37=FE_ITOF*/
fe_eqmult, /*38=FE_EQMULT*/
fe_eqdiv, /*39=FE_EQDIV*/
fe_eqmod, /*40=FE_EQMOD*/
fr_tochar, /*41=FR_TOCHAR*/
};
/*
*This is the major table directing the code generation process.
*It is indexed by an O_op operator, which is obtained from the
*opinfo table for an intermediate code operator. The actual
*code skeleton macros are in cskels.c, which are in a linked
*list in order of decreasing order of difficulty.
*/
char optab[][6] {
/* I I2 effect cc's stack register*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*0=NULL*/
I_ADD, I_INC, I_NULL, FC_FIX, FS_OP, FR_ADD, /*1=ADD*/
I_SUB, I_DEC, I_NULL, FC_FIX, FS_OP, FR_ADD, /*2=SUB*/
I_MULS, I_MULU, I_NULL, FC_FIX, I_NULL, FR_MULT, /*3=MULT*/
I_DIVS, I_DIVU, I_NULL, FC_FIX, I_NULL, FR_DIV, /*4=DIV*/
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*5=MOD*/
I_ASR, I_LSR, I_NULL, FC_FIX, I_NULL, FR_SHFT, /*6=RSH*/
I_ASL, I_LSL, I_NULL, FC_FIX, I_NULL, FR_SHFT, /*7=LSH*/
I_AND, I_AND, I_NULL, FC_FIX, FS_OP, FR_ADD, /*8=AND*/
I_OR, I_OR, I_NULL, FC_FIX, FS_OP, FR_ADD, /*9=OR*/
I_EOR, I_EOR, I_NULL, FC_FIX, I_NULL, FR_XOR, /*10=XOR*/
I_NULL, I_NULL, I_NULL, FC_FIX, I_NULL, I_NULL, /*11=NOT*/
I_NEG, I_NEG, I_NULL, FC_FIX, I_NULL, FR_NEG, /*12=NEG*/
I_NOT, I_NOT, I_NULL, I_NULL, I_NULL, FR_NEG, /*13=COMPL*/
I_SUB, I_DEC, FE_EQOP, FC_FIX, I_NULL, FR_EQOP, /*14=PREDEC*/
I_ADD, I_INC, FE_EQOP, FC_FIX, I_NULL, FR_EQOP, /*15=PREINC*/
I_SUB, I_DEC, FE_EQOP, I_NULL, I_NULL, FR_POSTOP, /*16=POSTDEC*/
I_ADD, I_INC, FE_EQOP, I_NULL, I_NULL, FR_POSTOP, /*17=POSTINC*/
I_MOVE, I_CLR, FE_ASSIGN, I_NULL, I_NULL, FR_ASSIGN, /*18=ASSIGN*/
I_ADD, I_INC, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*19=EQADD*/
I_SUB, I_DEC, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*20=EQSUB*/
I_MULS, I_MULU, FE_EQMULT, FC_FIX, I_NULL, FR_EQMULT, /*21=EQMULT*/
I_DIVS, I_DIVU, FE_EQDIV, FC_FIX, I_NULL, FR_EQDIV, /*22=EQDIV*/
I_DIVS, I_DIVU, FE_EQMOD, I_NULL, I_NULL, FR_EQDIV, /*23=EQMOD*/
I_ASR, I_LSR, FE_EQSHFT, I_NULL, I_NULL, FR_EQSHFT, /*24=EQRSH*/
I_ASL, I_LSL, FE_EQSHFT, I_NULL, I_NULL, FR_EQSHFT, /*25=EQLSH*/
I_AND, I_AND, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*26=EQAND*/
I_OR, I_OR, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*27=EQOR*/
I_EOR, I_EOR, FE_EQXOR, FC_FIX, I_NULL, FR_EQXOR, /*28=EQXOR*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_CALL, /*29=FJSR*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*30=EQUALS*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*31=NEQUALS*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*32=GREAT*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*33=GREATEQ*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*34=LESS*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*35=LESSEQ*/
I_NULL, I_NULL, I_NULL, I_NULL, FS_ITL, FR_ITL, /*36=INT2L*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_LTI, /*37=LONG2I*/
I_BTST, I_BTST, I_NULL, FC_BTST, I_NULL, I_NULL, /*38=BTST*/
I_CMP, I_TST, I_NULL, FC_REL, FS_LD, FR_LD, /*39=LOAD*/
I_MULS, I_MULU, I_NULL, I_NULL, I_NULL, FR_MULT, /*40=LMULT*/
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*41=LDIV*/
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*42=LMOD*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*43=NULL*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*44=NULL*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*45=NULL*/
I_NULL, I_NULL, FE_EQADDR, I_NULL, I_NULL, FR_EQADDR, /*46=EQADDR*/
I_NOT, I_NOT, FE_EQNOT, I_NULL, I_NULL, FR_EQNOT, /*47=EQNOT*/
I_NEG, I_NEG, FE_EQNOT, I_NULL, I_NULL, FR_EQNOT, /*48=EQNEG*/
I_NULL, I_NULL, I_NULL, I_NULL, FS_DOCAST, FR_DOCAST, /*49=DOCAST*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*50=STASSIGN*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_LTOF, /*51=LONG2F*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_FTOL, /*52=FLOAT2L*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_ITOF, /*53=INT2F*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_FTOI, /*54=FLOAT2I*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_TOCHAR, /*55=TOCHAR*/
};
/*this maps comparison operators and comparison types into the*/
/*actual branch opcode used.*/
char brtab[][2] {
I_BEQ, I_BEQ, /*EQUALS*/
I_BNE, I_BNE, /*NEQUALS*/
I_BGT, I_BHI, /*GREAT*/
I_BGE, I_BCC, /*GREATEQ*/
I_BLT, I_BLO, /*LESS*/
I_BLE, I_BLS, /*LESSEQ*/
};
/*turns !x>y into x<=y*/
int invrel[] { NEQUALS, EQUALS, LESSEQ, LESS, GREATEQ, GREAT };
/*turns x>y into y<=x*/
int swaprel[] { EQUALS, NEQUALS, LESS, LESSEQ, GREAT, GREATEQ };
/*code skeleton built-in strings*/
char *strtab[] {
"move", /*MOV*/
"move.l", /*MOVL*/
"jsr", /*JSR*/
"clr", /*CLR*/
"clr.l", /*CLRL*/
"ext.w", /*EXTW*/
"ext.l", /*EXTL*/
"lea", /*LEA*/
"(sp)", /*STK*/
};

View File

@@ -0,0 +1,255 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
#ifndef NODEBUG
char invalid[] "INVALID";
char *opname[] {
invalid, /*0*/
"+", /*1*/
"-", /*2*/
"*", /*3*/
"/", /*4*/
"%", /*5*/
">>", /*6*/
"<<", /*7*/
"&", /*8*/
"|", /*9*/
"^", /*10*/
"!", /*11*/
"U-", /*12*/
"~", /*13*/
"--p", /*14*/
"++p", /*15*/
"p--", /*16*/
"p++", /*17*/
"=", /*18*/
"+=", /*19*/
"-=", /*20*/
"*=", /*21*/
"/=", /*22*/
"%=", /*23*/
">>=", /*24*/
"<<=", /*25*/
"&=", /*26*/
"|=", /*27*/
"^=", /*28*/
"jsr", /*29*/
"==", /*30*/
"!=", /*31*/
">", /*32*/
">=", /*33*/
"<", /*34*/
"<=", /*35*/
"int->long", /*36*/
"long->int", /*37*/
"btst", /*38*/
"load", /*39*/
"long*", /*40*/
"long/", /*41*/
"long%", /*42*/
"long*=", /*43*/
"long/=", /*44*/
"long%=", /*45*/
"=addr", /*46*/
"=not", /*47*/
"=neg", /*48*/
"docast", /*49*/
"st=", /*50*/
"long->float", /*51*/
"float->long", /*52*/
"int->float", /*53*/
"float->int", /*54*/
"tochar", /*55*/
invalid, /*56*/
invalid, /*57*/
invalid, /*58*/
invalid, /*59*/
"U&", /*60*/
"U*", /*61*/
"&&", /*62*/
"||", /*63*/
"?", /*64*/
":", /*65*/
",", /*66*/
"cint", /*67*/
"clong", /*68*/
"symbol", /*69*/
"++a", /*70*/
"a--", /*71*/
"call", /*72*/
"call()", /*73*/
"bitfield", /*74*/
"if", /*75*/
"init", /*76*/
"loadR0", /*77*/
"divlong", /*78*/
};
char *types[] {
invalid, /*0=TYPELESS*/
"char", /*1=CHAR*/
invalid, /*2=SHORT*/
"int", /*3=INT*/
"long", /*4=LONG*/
invalid, /*5=UCHAR*/
invalid, /*6=USHORT*/
"uint", /*7=UINT*/
invalid, /*8=ULONG*/
"float", /*9=FLOAT*/
invalid, /*10=DOUBLE*/
"struct", /*11=STRUCT*/
invalid, /*12=undefined*/
invalid, /*13=undefined*/
invalid, /*14=undefined*/
invalid, /*15=undefined*/
};
char *suvals[] {
"zero",
"one",
"quick",
"small",
"constant",
"Areg",
"Dreg",
"addressable",
"loadable",
"easy",
"hard",
"veryhard",
};
int level;
putexpr(name,tp)
char *name;
struct tnode *tp;
{
printf("%s\n",name);
putsexpr(tp);
}
putsexpr(tp)
struct tnode *tp;
{
register struct tnode *ltp;
level++;
ltp = tp->t_left;
outlevel();
printf("%s ",opname[tp->t_op]);
if( tp->t_op == BFIELD || tp->t_op == IFGOTO ) {
if( tp->t_op == BFIELD )
printf("off=%d len=%d\n",(tp->t_su>>8)&0377,tp->t_su&0377);
else
printf("%s goto L%d\n",tp->t_type?"TRUE":"FALSE",tp->t_su);
putsexpr(tp->t_left);
level--;
return;
}
puttsu(tp);
switch( tp->t_op ) {
case DCLONG:
case CLONG:
case CFLOAT: /*[vlh] 3.4 */
printf(" %x.%x\n",tp->t_lvalue.hiword,tp->t_lvalue.loword);
break;
case CINT:
printf(" %d\n",tp->t_value);
break;
case AUTODEC:
case AUTOINC:
printf(" R%d\n",tp->t_reg);
break;
case SYMBOL:
switch( tp->t_sc ) {
case REGISTER:
printf(" R%d",tp->t_reg);
break;
case CINDR:
printf(" %d\n",tp->t_offset);
break;
case CLINDR:
case CFINDR: /* [vlh] 3.4 */
printf(" %x.%x\n",tp->t_offset,tp->t_ssp);
break;
case REGOFF:
printf(" %d(R%d)",tp->t_offset,tp->t_reg);
break;
case EXTERNAL:
case EXTOFF:
printf(" %s+%d",tp->t_symbol,tp->t_offset);
if( tp->t_sc == EXTOFF )
printf("(R%d)",tp->t_reg);
break;
case STATIC:
case STATOFF:
printf(" L%d+%d",tp->t_label,tp->t_offset);
if( tp->t_sc == STATOFF )
printf("(R%d)",tp->t_reg);
break;
case INDEXED:
printf(" %d(R%d,R%d)",tp->t_offset,tp->t_reg,tp->t_xreg);
break;
}
putchar('\n');
break;
case IFGOTO:
putsexpr(tp->t_left);
break;
default:
putchar('\n');
putsexpr(tp->t_left);
if( binop(tp->t_op) )
putsexpr(tp->t_right);
break;
}
level--;
}
outlevel()
{
register int i;
for( i = 0; i < level; i++ )
putchar('\t');
}
puttsu(tp)
struct tnode *tp;
{
register int i;
if( suptype(tp->t_type) )
putchar('*');
printf("%s ",types[btype(tp->t_type)]);
if( tp->t_su != 0 || (tp->t_op == CINT && tp->t_value == 0) ) {
i = tp->t_su >> 8;
if( i > 15 || i < 0 )
printf("INVALID");
else
printf("%s",suvals[tp->t_su>>8]);
}
}
#endif

View File

@@ -0,0 +1,514 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/* Code Skeleton expansion and matching */
#include "cgen.h"
#include "cskel.h"
#define SK_TYPE(x) (x&017)
/* expand - code skeleton expansion*/
/* Handles the expansion of code skeleton macros.*/
expand(tp,cookie,freg,skp) /* returns register result is in*/
struct tnode *tp; /* pointer to expression tree*/
int cookie; /* goal of expression tree*/
int freg; /* register to leave results in*/
struct skeleton *skp; /* pointer to code skeleton*/
{
register int op, nreg, reg;
register int c;
register int extf, i2f;
register struct tnode *ltp, *rtp;
register char *p;
register int i, inaddreg, sreg, flag, subtrees, scookie;
register char *macro;
#ifndef NODEBUG
if( eflag )
printf("expand op=%d left=%x right=%x skp=%o\n",tp->t_op,
skp->sk_left,skp->sk_right,skp);
#endif
if( ((op=tp->t_op) >= MULT && op <= XOR) || tp->t_type == CHAR )
freg = dreg(freg);
macro = skp->sk_def;
extf = 0;
i2f = 0;
rtp = ltp = tp->t_left;
subtrees = 1;
if( binop(op) ) {
subtrees++;
rtp = tp->t_right;
if( (longorptr(tp->t_type)) && (op == DIV || op == MOD ||
(op != MULT && (isdreg(freg)) &&
!(longorptr(ltp->t_type)) && !(longorptr(rtp->t_type)))) )
extf++;
switch( op ) {
case RSH:
case LSH:
case EQLSH:
case EQRSH:
if( unsign(ltp->t_type) )
i2f++;
break;
case MULT:
case EQMULT:
case DIV:
case MOD:
case EQDIV:
case EQMOD:
if( unsign(ltp->t_type) || unsign(rtp->t_type) )
i2f++;
break;
}
}
nreg = freg + 1;
while( c = *macro++ ) {
c =& 0xff;
switch( c ) {
default:
putchar(c);
break;
case POP:
stacksize--;
printf("(sp)+");
break;
case POP4:
stacksize--;
popstack(4);
break;
case POP8:
stacksize =- 2;
popstack(8);
break;
case PSH:
if( cookie == FORSP ) /*don't affect sp*/
printf("(sp)");
else
printf("-(sp)");
stacksize++;
break;
case MOV:
case MOVL:
case JSR:
case CLR:
case CLRL:
case EXTW:
case EXTL:
case LEA:
case STK:
printf("%s",strtab[c-128]);
break;
case OPCALL:
if( isfloat(tp->t_type) || isfloat(ltp->t_type) ) {
switch( op ) {
case ADD:
case EQADD:
printf("_fpadd");
break;
case SUB:
case EQSUB:
printf("_fpsub");
break;
case MULT:
case EQMULT:
printf("_fpmult");
break;
case DIV:
case EQDIV:
printf("_fpdiv");
break;
case UMINUS:
case EQNEG:
printf("_fpneg");
break;
case FLOAT2L:
case FLOAT2I:
printf("_fpftol");
break;
case LONG2F:
case INT2F:
printf("_fpltof");
break;
case EQUALS:
case NEQUALS:
case GREAT:
case GREATEQ:
case LESS:
case LESSEQ:
printf("_fpcmp");
break;
default:
error("invalid floating op %d\n",op);
break;
}
}
else {
switch( op ) {
case MULT:
case LMULT:
printf("lmul");
break;
case DIV:
case LDIV:
printf("ldiv");
break;
case MOD:
case LMOD:
printf("lrem");
break;
default:
error("opcall bad op %d",op);
break;
}
}
break;
case TLEFT:
outtype( leafop(op) ? tp->t_type : ltp->t_type );
break;
case TLEFTL:
outatype( leafop(op) ? tp->t_type : ltp->t_type );
break;
case TEITHER:
if( longorptr(rtp->t_type) || longorptr(ltp->t_type) )
outtype(LONG);
break;
case TRIGHT:
outtype(rtp->t_type);
break;
case OP:
case AOP:
if( c == AOP || i2f )
i = optab[op][1];
else
i = optab[op][0];
printf(mnemonics[i]);
break;
case LADDR:
case RADDR:
p = (c==RADDR?rtp:ltp);
outaexpr(p,IMMED);
break;
case CR:
outcreg(freg);
break;
case NR:
outcreg(nreg);
break;
case CAR:
outcreg(areg(freg));
break;
case NAR:
outcreg(areg(nreg));
break;
case EXL:
outextend(ltp,LONG,freg);
break;
case EXRL:
case EXRLN:
outextend(rtp,ltp->t_type,c==EXRL?freg:nreg);
break;
case EXLR:
case EXLRN:
outextend(ltp,rtp->t_type,c==EXLR?freg:nreg);
break;
case LEFT:
case RIGHT:
subtrees--;
case TREE:
p = (c==LEFT?ltp:c==RIGHT?rtp:tp);
flag = *macro++;
scookie = FORREG;
if( flag & S_STACK ) {
if( cookie == FORSP )
scookie = FORSP;
else
scookie = FORSTACK;
}
else if( flag & S_FORCC )
scookie = FORCC;
if( flag & S_NEXT )
reg = nreg;
else
reg = freg;
if( flag & S_INDR ) {
if( p->t_op != INDR )
error("code skeleton error: %d\n",op);
p = p->t_left; /*skip INDR*/
if( coffset(p) )
p = p->t_left;
reg = areg(reg);
}
sreg = codegen(p,scookie,reg); /*code for subtree*/
if( scookie == FORREG ) {
if( flag & S_INDR ) {
if( isdreg(sreg) )
outmovr(sreg,areg(reg),p);
}
else if( flag & S_NEXT )
nreg = sreg;
else if( sreg != reg ) {
/*
* result was not in expected register, if remaining sub-tree can be
* compiled using the remaining registers, update current and next
* registers, saving us the trouble of moving the register.
*/
if( c == TREE || ((isdreg(sreg)) && subtrees > 0 &&
((c == LEFT &&
sucomp(rtp,sreg,0) <= skp->sk_right &&
sucomp(rtp,sreg,1) <= SU_ANY) ||
( c == RIGHT &&
sucomp(ltp,sreg,0) <= skp->sk_left &&
sucomp(ltp,sreg,1) <= SU_ANY))) ) {
freg = dreg(sreg);
nreg = freg + 1;
}
else
outmovr(sreg,dreg(freg),p);
}
}
break;
case LOFFSET:
case ROFFSET:
p = (c==LOFFSET) ? ltp->t_left : rtp->t_left;
if((p=coffset(p)) != 0 && (p->t_op != CINT || p->t_value != 0))
outaexpr(p,NOTIMMED);
break;
case MODSWAP:
switch( op ) {
case MOD:
case EQMOD:
case LMOD:
case LEQMOD:
outswap(freg);
}
break;
}
}
if( extf && cookie == FORREG && (isdreg(freg)) ) {
if( unsign(ltp->t_type) || unsign(rtp->t_type) )
outuext(freg);
else
outext(freg);
}
#ifndef NODEBUG
if( eflag )
printf("ending expand skp=%o\n",skp);
#endif
return(freg);
}
/*
* match - try to match expression tree with code skeleton
* Given the expression tree, tries to match the given tree with
* the appropriate code skeleton. The code skeleton list is
* gotten from the root operator and the cookie value. The code
* skeleton list is then searched, checking the Sethy-Ullman numbers
* of the sub-trees against the Sethy-Ullman numbers in the code
* skeleton list. If the Sethy-Ullman numbers are OK, then the
* left and right sub-trees are checked for compatability, e.g.
* integer pointers, etc. If a match is found, the code skeleton
* list pointer is returned.
*/
char *match(tp,cookie,reg) /* returns ptr to code skeleton*/
/* or 0 if no skeleton*/
struct tnode *tp; /* pointer to tree*/
int cookie; /* goal for code expansion*/
int reg; /* register to use*/
{
register struct skeleton *skp;
register int op, bop, opndx;
int i;
register struct tnode *ltp, *rtp;
#ifndef NODEBUG
if( mflag )
printf("match op=%d cookie=%d reg=%d\n",tp->t_op,cookie,reg);
#endif
if( (op=tp->t_op) >= LCGENOP )
return(0);
if( leafop(op) )
ltp = tp;
else
ltp = tp->t_left;
if( (bop=binop(op)) ) {
rtp = tp->t_right;
if( convop(ltp->t_op) ) {
if( op != LSH && notconvop(rtp->t_op) ) {
if( !(unsign(ltp->t_left->t_type)) || op == ASSIGN ) {
tp->t_left = ltp->t_left;
if( (skp=match(tp,cookie,reg)) != 0 )
return(skp);
tp->t_left = ltp;
}
}
}
else if( convop(rtp->t_op) ) {
if( !(unsign(rtp->t_left->t_type)) || op == ASSIGN ) {
tp->t_right = rtp->t_left;
if( (skp=match(tp,cookie,reg)) != 0 )
return(skp);
tp->t_right = rtp;
}
}
}
switch( cookie ) {
case FORCC:
i = 3;
break;
case FOREFF:
i = 2;
break;
case FORSTACK:
case FORSP:
i = 4;
break;
case FORREG:
i = 5;
break;
default:
error("match cookie=%d\n",cookie);
return(0);
}
#ifndef NODEBUG
if( mflag )
printf("match op=%d i=%d ",op,i);
#endif
if( !(i=optab[op][i]) )
return(0);
skp = codeskels[i];
#ifndef NODEBUG
if( mflag )
printf("codeskels[%d]=%o\n",i,skp);
#endif
#ifndef NODEBUG
if(mflag) {
printf("match LEFT ");
puttsu(ltp);
if(bop) {
printf(" RIGHT ");
puttsu(rtp);
}
putchar('\n');
}
#endif
for( ; skp->sk_left != 0; skp++ ) {
#ifndef NODEBUG
if( mflag > 1 )
printf("sk_left=%x sk_right=%x\n",skp->sk_left,skp->sk_right);
#endif
if( !(skelmatch(ltp,skp->sk_left)) )
continue;
if( bop && !(skelmatch(rtp,skp->sk_right)) )
continue;
#ifndef NODEBUG
if( mflag )
printf("match found skp=%o left=%x right=%x\n",skp,
skp->sk_left,skp->sk_right);
#endif
return(skp);
}
return(0);
}
/* skelmatch - sub-tree type matching for match*/
/* This checks a subtree for type compatability in match.*/
skelmatch(tp,skinfo) /* returns 1 if matched, else 0*/
struct tnode *tp; /* pointer to expression tree*/
int skinfo;
{
register int type, unsignf, const, stype;
if( tp->t_su > skinfo || ((skinfo&T_INDR) && tp->t_op != INDR) )
return(0);
stype = SK_TYPE(skinfo);
type = tp->t_type;
if( function(type) )
type = btype(type);
if( unsignf = unsign(type) )
type = basetype(type);
const = 0;
switch( tp->t_op ) {
case CFLOAT: /* [vlh] 3.4 */
case CLONG:
if( tp->t_su > SU_CONST )
break;
case CINT:
const++;
break;
}
switch( stype ) {
case T_CHAR:
return( type == CHAR );
case T_ANY: /*either int or char*/
if( type == CHAR )
return(1);
case T_INT:
return( type == INT || const );
case T_UNSN:
return( unsignf );
case T_LONG:
return( longorptr(type) );
case T_FLOAT:
return( isfloat(type) );
default:
error("skelmatch type: %x",stype);
return(0);
}
}

View File

@@ -0,0 +1,110 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
#include "cskel.h"
/* sucomp - Sethy-Ullman expression complexity measure computation*/
/* This is a heuristic computation of the Sethy-Ullman numbers*/
/* for expressions. This gives an approximation of the complexity*/
/* of the expression. The code generation scheme works best if*/
/* the most complex expressions are done first.*/
sucomp(tp,nregs,flag) /* returns - none*/
struct tnode *tp; /* pointer to tree*/
int nregs; /* number of registers left*/
int flag; /* 1=>set values in tree, 0=>return*/
{
register int su, sur, op, i;
register struct tnode *ltp, *rtp;
nregs = dreg(nregs);
if( binop(op=tp->t_op) ) {
ltp = tp->t_left;
rtp = tp->t_right;
}
else if( unaryop(op) )
ltp = tp->t_left;
switch( op ) {
case CLONG:
if( tp->t_lvalue >= 0x8000L || tp->t_lvalue <= 0xffff8000L ) {
su = SU_ADDR;
break;
}
i = tp->t_lvalue;
case CINT:
if( op == CINT )
i = tp->t_value;
if( i == 0 )
su = SU_ZERO;
else if( i == 1 )
su = SU_ONE;
else if( i >= 1 && i <= QUICKVAL )
su = SU_SMALL;
else if( i >= -128 && i <= 127 )
su = SU_QUICK;
else
su = SU_CONST;
break;
case COMMA:
su = max(sucomp(rtp,nregs,flag),sucomp(ltp,nregs,flag));
su = max(su,SU_EASY);
break;
case ADDR:
su = sucomp(ltp,nregs,flag);
break;
case CFLOAT:
case DCLONG:
case AUTOINC:
case AUTODEC:
su = SU_ADDR;
break;
case SYMBOL:
if( tp->t_sc != REGISTER )
su = SU_ADDR;
else if( isdreg(tp->t_reg) )
su = SU_REG;
else
su = SU_AREG;
break;
case LDIV:
case LMOD:
case LMULT:
case CALL:
sucomp(rtp,nregs,flag);
case NACALL:
sucomp(ltp,nregs,flag);
su = SU_VHARD; /*very hard*/
break;
default:
su = sucomp(ltp,nregs,flag);
if( binop(op) ) {
if( su <= SU_ADDR )
su = max(su,sucomp(rtp,nregs,flag));
else {
sur = sucomp(rtp,nregs+1,flag);
if( sur > SU_ADDR && nregs > HICREG )
su = max(su,SU_HARD);
}
su = max(SU_EASY,su);
}
else if( su <= SU_XREG )
su = max(SU_EASY,su);
if( isfloat(tp->t_type) )
su = SU_VHARD;
break;
}
if( flag )
tp->t_su = su;
return(su);
}

View File

@@ -0,0 +1,118 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
#define ASGOP OPRAS|OPASSIGN|OPLVAL|OPBIN
/*info on operators:*/
/*000077-- OPPRI - priority*/
/*000100-- OPBIN - binary operator*/
/*000200-- OPLVAL - left operand must be lvalue*/
/*000400-- OPREL - relational operator*/
/*001000-- OPASSIGN - assignment operator*/
/*002000-- OPLWORD - int required on left*/
/*004000-- OPRWORD - int required on right*/
/*010000-- OPCOM commutative*/
/*020000-- OPRAS - right associative*/
/*040000-- OPTERM - termination node*/
/*100000 - OPCONVS - conversion operator*/
int opinfo[] {
TRMPRI, /*EOF*/
ADDPRI|OPCOM|OPBIN, /*ADD - expr + expr*/
ADDPRI|OPBIN, /*SUB - expr - expr*/
MULPRI|OPCOM|OPBIN, /*MULT - expr * expr*/
MULPRI|OPBIN, /*DIV - expr / expr*/
MULPRI|OPBIN, /*MOD - expr % expr*/
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*RSH - expr >> expr*/
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*LSH - expr << expr*/
ANDPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*AND - expr & expr*/
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*OR - expr | expr*/
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*XOR - expr ^ expr*/
UNOPRI|OPRAS|OPLWORD, /*NOT - ! expr*/
UNOPRI|OPRAS, /*UMINUS - - expr*/
UNOPRI|OPRAS|OPLWORD, /*COMPL - ~ expr*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREDEC - --lvalue*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREINC - ++lvalue*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTDEC - lvalue--*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTINC - lvalue++*/
ASGPRI|ASGOP, /*ASSIGN - lvalue = expr*/
ASGPRI|ASGOP, /*EQADD - lvalue += expr*/
ASGPRI|ASGOP, /*EQSUB - lvalue -= expr*/
ASGPRI|ASGOP, /*EQMULT - lvalue *= expr*/
ASGPRI|ASGOP, /*EQDIV - lvalue /= expr*/
ASGPRI|ASGOP, /*EQMOD - lvalue %= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQRSH - lvalue >>= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQLSH - lvalue <<= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQAND - lvalue &= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQOR - lvalue |= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQXOR - lvalue ^= expr*/
TRMPRI, /*FJSR - generate function jsr*/
EQLPRI|OPREL|OPBIN, /*EQUALS - expr == expr*/
EQLPRI|OPREL|OPBIN, /*NEQUALS - expr != expr*/
RELPRI|OPREL|OPBIN, /*GREAT - expr > expr*/
RELPRI|OPREL|OPBIN, /*GREATEQ - expr >= expr*/
RELPRI|OPREL|OPBIN, /*LESS - expr < expr*/
RELPRI|OPREL|OPBIN, /*LESSEQ - expr <= expr*/
TRMPRI|OPCONVS, /*INT2L*/
TRMPRI|OPCONVS, /*LONG2I*/
TRMPRI|OPBIN, /*BTST*/
TRMPRI, /*LOAD*/
TRMPRI|OPBIN, /*LMULT*/
TRMPRI|OPBIN, /*LDIV*/
TRMPRI|OPBIN, /*LMOD*/
TRMPRI|OPBIN, /*LEQMULT*/
TRMPRI|OPBIN, /*LEQDIV*/
TRMPRI|OPBIN, /*LEQMOD*/
TRMPRI|ASGOP, /*EQADDR*/
TRMPRI, /*EQNOT*/
TRMPRI, /*EQNEG*/
TRMPRI|OPBIN, /*DOCAST*/
ASGPRI|ASGOP, /*STASSIGN [vlh]*/
TRMPRI|OPCONVS, /*LONG2F [vlh] 3.4*/
TRMPRI|OPCONVS, /*FLOAT2L [vlh] 3.4*/
TRMPRI|OPCONVS, /*INT2F [vlh] 3.4*/
TRMPRI|OPCONVS, /*FLOAT2I [vlh] 3.4*/
UNOPRI|OPRAS, /*TOCHAR [vlh] 4.0*/
TRMPRI, /*unused - 56*/
TRMPRI, /*unused - 57*/
TRMPRI, /*unused - 58*/
TRMPRI, /*unused - 59*/
UNOPRI|OPRAS|OPLVAL, /*ADDR - & expr*/
UNOPRI|OPRAS|OPLWORD, /*INDR - * expr*/
LNDPRI|OPBIN, /*LAND - expr && expr*/
LORPRI|OPBIN, /*LOR - expr || expr*/
QMKPRI|OPRAS|OPBIN, /*QMARK - expr ? expr : expr*/
QMKPRI|OPRAS|OPBIN, /*COLON*/
COMPRI|OPBIN, /*COMMA*/
TRMPRI|OPTERM, /*CINT*/
TRMPRI|OPTERM, /*CLONG*/
TRMPRI|OPTERM, /*SYMBOL*/
TRMPRI|OPTERM, /*AUTOINC*/
TRMPRI|OPTERM, /*AUTODEC*/
LPNPRI|OPBIN, /*CALL - call with arguments*/
LPNPRI, /*NACALL - no argument call*/
TRMPRI, /*BFIELD - field selection*/
TRMPRI, /*CONDBR*/
TRMPRI, /*INIT*/
TRMPRI, /*LOADREG*/
TRMPRI|OPTERM, /*DCLONG - divide const long*/
TRMPRI|OPTERM, /*CFLOAT [vlh] 3.4*/
UNOPRI|OPRAS|OPASSIGN|OPBIN, /*CAST*/
TRMPRI, /*SEMI*/
TRMPRI, /*LCURBR - {*/
TRMPRI, /*RCURBR - }*/
LPNPRI, /*LBRACK - [*/
RPNPRI, /*RBRACK - ]*/
LPNPRI, /*LPAREN - )*/
RPNPRI, /*RPAREN - )*/
TRMPRI|OPTERM, /*STRING*/
TRMPRI, /*RESWORD*/
LPNPRI|OPBIN, /*APTR - expr -> symbol*/
LPNPRI|OPBIN, /*PERIOD - expr . symbol*/
UNOPRI|OPRAS, /*SIZEOF - sizeof expr*/
LPNPRI|OPBIN, /*MPARENS - matching parens ()*/
};

View File

@@ -0,0 +1,357 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
#include "cskel.h"
/* xnalloc - allocate address-indexed node*/
char *xnalloc(type,ar,off,xr,xt) /* returns ptr to node alloced*/
int type; /* data type*/
int ar; /* address register*/
int off; /* 8-bit offset*/
int xr; /* index register*/
int xt; /* index register type*/
{
register struct indexnode *xp;
xp = talloc(sizeof(*xp));
xp->t_op = SYMBOL;
xp->t_type = type;
xp->t_sc = INDEXED;
xp->t_reg = ar;
xp->t_su = SU_ADDR;
xp->t_offset = off;
xp->t_xreg = xr;
xp->t_xtype = xt;
return(xp);
}
/* tcopy - expression tree copy*/
char *tcopy(tp) /* returns ptr to copied tree*/
struct tnode *tp;
{
register char *p;
switch( tp->t_op ) {
case SYMBOL:
if( tp->t_sc == EXTERNAL || tp->t_sc == EXTOFF )
p = cenalloc(tp->t_type,tp->t_sc,tp->t_symbol);
else {
p = snalloc(tp->t_type,tp->t_sc,tp->t_offset,0,0);
p->t_label = tp->t_label;
}
p->t_offset = tp->t_offset;
p->t_reg = tp->t_reg;
return(p);
case CINT:
return(cnalloc(tp->t_type,tp->t_value));
case CLONG:
return(lcnalloc(tp->t_type,tp->t_lvalue));
case CFLOAT: /*[vlh] 3.4 */
return(fpcnalloc(tp->t_type,tp->t_lvalue));
case DCLONG:
p = lcnalloc(tp->t_type,tp->t_lvalue);
p->t_op = DCLONG;
return(p);
default:
if( binop(tp->t_op) )
return(tnalloc(tp->t_op,tp->t_type,0,0,tcopy(tp->t_left),
tcopy(tp->t_right)));
if( unaryop(tp->t_op) )
return(tnalloc(tp->t_op,tp->t_type,0,0,tcopy(tp->t_left),
null));
error("tcopy op=%d",tp->t_op);
return(tp);
}
}
/* outaexpr - output address expression*/
outaexpr(tp,flags) /* returns - none*/
struct tnode *tp; /* pointer to tree*/
int flags; /* flags (IMMED,LOFFSET,...)*/
{
register int off, reg, lab;
long l;
if( tp->t_op == ADDR ) {
tp = tp->t_left;
putchar('#');
}
off = tp->t_offset;
reg = tp->t_reg;
lab = tp->t_label;
switch( tp->t_op ) {
case AUTOINC:
printf("(R%d)+",reg);
break;
case AUTODEC:
printf("-(R%d)",reg);
break;
case CINT:
if( flags & IMMED )
putchar('#');
printf("%d",tp->t_value);
break;
case DCLONG:
case CLONG:
case CFLOAT: /*[vlh] 3.4 */
if( flags & IMMED )
putchar('#');
outlval(tp->t_lvalue);
break;
case SYMBOL:
if( off ) {
switch( tp->t_sc ) {
default:
printf("%d+",off);
break;
case REGOFF:
printf("%d",off);
case CINDR:
case CLINDR:
case CFINDR: /* [vlh] 3.4 */
case INDEXED:
break;
case REGISTER:
error("invalid register expression");
break;
}
}
switch( tp->t_sc ) {
case REGISTER:
printf("R%d",reg);
break;
case REGOFF:
printf("(R%d)",reg);
break;
case EXTERNAL:
printf("_%.8s",tp->t_symbol);
break;
case EXTOFF:
printf("_%.8s(R%d)",tp->t_symbol,reg);
break;
case STATIC:
printf("L%d",lab);
break;
case STATOFF:
printf("L%d(R%d)",lab,reg);
break;
case INDEXED:
printf("%d(R%d,R%d",off,reg,tp->t_xreg);
outatype(tp->t_xtype);
putchar(')');
break;
case CINDR:
printf("%d",off);
break;
/*
* the following will work on: PDP-11, 68000, IBM-360, VAX, etc.
* it will not work on word machines or on machines where either
* longs two ints or two shorts.
*/
case CLINDR:
case CFINDR: /* [vlh] 3.4 */
l.hiword = tp->t_offset;
l.loword = tp->t_ssp;
outlval(l);
break;
default:
error("invalid storage class %d\n",tp->t_sc);
break;
}
break;
default:
error("invalid operator %d\n",tp->t_op);
break;
}
}
/* outlval - output long value*/
/* This is a big pain because the PDP-11 doesn't do long divides*/
/* in hardware.*/
outlval(lval)
long lval;
{
char digs[8];
register int i, c;
i = 0;
do {
digs[i++] = lval & 0xf;
lval =>> 4;
lval =& 0xfffffff;
} while ( lval );
putchar('$');
while( --i >= 0 ) {
c = digs[i];
putchar(c>=10?c+('a'-10):c+'0');
}
}
/* outtype - output 68000 type (null, .b, .l) depending on data type*/
outtype(type)
int type;
{
if( isfloat(type) )
printf(".l");
else if( longorptr(type) )
printf(".l");
else if( type == CHAR )
printf(".b");
}
/* outatype - output address type (.l or null) depending on data type*/
outatype(type)
int type;
{
if( longorptr(type) || isfloat(type) )
printf(".l");
}
/* outextend - output register extension to long depending on type*/
outextend(tp,type,reg) /* returns - none*/
struct tnode *tp; /* tree to convert from*/
int type; /* type to convert to*/
int reg; /* register to convert*/
{
if( (isdreg(reg)) && !(longorptr(tp->t_type)) && (longorptr(type)) ) {
if( unsign(tp->t_type) )
outuext(reg);
else
outext(reg);
}
}
/* outrr - output register to register instruction*/
outrr(ins,r1,r2,tp)
char *ins;
int r1;
int r2;
struct tnode *tp;
{
printf("%s",ins);
if( isareg(r1) || isareg(r2) )
outatype(tp->t_type);
else
outtype(tp->t_type);
printf(" R%d,R%d\n",r1,r2);
}
/* outmovr - output "move[type] R1,R2" instruction*/
outmovr(r1,r2,tp)
int r1;
int r2;
struct tnode *tp;
{
if( r1 != r2 )
outrr("move",r1,r2,tp);
}
/* outcmpm - output "cmpm[type] (R1)+,(R2)+"*/
outcmpm(tp)
struct tnode *tp;
{
printf("cmpm");
outtype(tp->t_left->t_type);
printf(" (R%d)+,(R%d)+\n",tp->t_left->t_reg,tp->t_right->t_reg);
}
/* outcreg - output reference to compiler temp register*/
outcreg(reg)
int reg;
{
if( (dreg(reg)) > HICREG )
error("expression too complex");
printf("R%d",reg);
}
/* outcmp0 - output a compare with 0, special for address register*/
outcmp0(reg,tp)
int reg;
struct tnode *tp;
{
if( isareg(reg) ) {
printf("cmp");
outatype(tp->t_type);
printf(" #0,R%d\n",reg);
}
else {
printf("tst");
outtype(tp->t_type);
printf(" R%d\n",reg);
}
}
/* outrpush - output "move[type] R1,[-](sp)"*/
outrpush(reg,tp,pflag)
int reg;
struct tnode *tp;
int pflag;
{
printf("move");
outatype(tp->t_type);
printf(" R%d,%c(sp)\n",reg,pflag?'-':'\0');
}
outdbra(reg,lab)
int reg;
int lab;
{
printf("dbra R%d,L%d\n",reg,lab);
}
/* cenalloc - code generator external node allocation*/
/* This may be coalesced into enalloc in parser.*/
char *cenalloc(type,sc,sym) /* returns ptr to node alloced*/
int type; /* type of symbol*/
int sc; /* storage class*/
char *sym; /* symbol name*/
{
register struct extnode *ep;
ep = talloc(sizeof(*ep));
ep->t_op = SYMBOL;
ep->t_type = type;
ep->t_sc = sc;
ep->t_su = 0;
ep->t_offset = 0;
symcopy(sym,ep->t_symbol);
return(ep);
}
/*popstack - clear off the stack after a call if necessary */
popstack(nb)
{
if (nb > 0 && nb <= 8)
printf("addq.l #%d,sp\n",nb);
else if (nb > 0)
printf("adda.l #%d,sp\n",nb);
}

View File

@@ -0,0 +1 @@
char *compiled "@(#) code generator - Fri Mar 18 12:02 1983";

View File

@@ -0,0 +1,3 @@
mkver; c68 -r -L *.c -o c68.68 -l6 ; setstack68 c68.68 8192 8192
mkver; c68 -r -L -n *.c -o c68.st -l6 ; setstack68 c68.st 8192 8192
mkver; cc -n *.c -o c68.11 -lx

View File

@@ -0,0 +1,340 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "preproc.h"
#define OPPRI 077
#define OPBIN 0100
#define STKLEN 64
int oprstk[STKLEN]; /*operator stack*/
int opnstk[STKLEN]; /*operand stack*/
int pristk[STKLEN]; /*operator priority stack*/
int *oprptr; /*pointer to operator stack*/
int *opnptr; /*pointer to operand stack*/
int *priptr; /*pointer to priority stack*/
int cvalue;
int opinfo[] {
0, /*EOF=0*/
16|OPBIN, /*SUB=1*/
16|OPBIN, /*ADD=2*/
20, /*NOT=3*/
20, /*NEG=4*/
22, /*LPAREN=5*/
2, /*RPAREN=6*/
6|OPBIN, /*QMARK=7*/
6|OPBIN, /*COLON=8*/
8|OPBIN, /*OR=9*/
10|OPBIN, /*AND=10*/
8|OPBIN, /*XOR=11*/
12|OPBIN, /*EQUAL=12*/
12|OPBIN, /*NEQUAL=13*/
14|OPBIN, /*LESS=14*/
14|OPBIN, /*LSEQUAL=15*/
14|OPBIN, /*GREAT=16*/
14|OPBIN, /*GREQUAL=17*/
4|OPBIN, /*LSHIFT=18*/
4|OPBIN, /*RSHIFT=19*/
18|OPBIN, /*MULT=20*/
18|OPBIN, /*DIV=21*/
18|OPBIN, /*MOD=22*/
20, /*COMPL=23*/
};
/* cexpr - constant expression evaluation*/
/* Does priority-driven operator/operand stack evaluation of*/
/* constant expressions.*/
cexpr() /* returns constant evaluated*/
{
register int lop, type;
oprptr = &oprstk[0];
opnptr = &opnstk[0];
priptr = &pristk[0];
*priptr = 0;
lop = -1;
while(1) {
switch( type = getctok() ) {
case CONST:
if( !lop ) /*last was not operator*/
goto syntax;
if( opnptr >= &opnstk[STKLEN] ) {
error("expression stack overflow");
cexit();
}
lop = FALSE;
*++opnptr = cvalue;
continue;
case SUB:
if( lop )
type = NEG; /*unary minus*/
break;
case ADD:
if( lop )
continue; /*ignore unary +*/
break;
case COMPL:
case LPAREN:
case NOT:
if( !lop )
goto syntax;
break;
case RPAREN:
if( lop )
goto syntax;
lop = FALSE;
if( !stkop(type) )
goto syntax;
continue;
case NEWL:
case EOF:
if( lop || !stkop(EOF) || opnptr != &opnstk[1] )
goto syntax;
type = opnstk[1];
putback('\n');
return(type);
default:
if( lop || type > LASTOP )
goto syntax;
break;
}
lop = TRUE;
if( !stkop(type) )
goto syntax;
}
syntax:
error("expression syntax");
if( type == NEWL )
putback('\n');
return(0);
}
/* getctok - get a constant expression token*/
/* Handles conversion of quoted character strings and numbers.*/
getctok()
{
register int type, c, count;
register char *p;
char token[TOKSIZE];
while( 1 ) {
switch( type = getntok(token) ) {
case DIGIT:
cvalue = const(token);
return(CONST);
case SQUOTE:
for( cvalue = 0, p = &token[1], count = 2; --count >= 0; ) {
if( (c= *p++) == '\'' )
break;
if( c == '\\' ) {
if( *p >= '0' && *p <= '7' ) {
for( c = 0; *p >= '0' && *p <= '7'; )
c = (c<<3) + (*p++ - '0');
}
else switch( c = *p++ ) {
case 'n':
c = '\n';
break;
case 't':
c = '\t';
break;
case 'b':
c = '\b';
break;
case 'r':
c = '\r';
break;
case 'f':
c = '\f';
break;
}
}
cvalue = (cvalue<<8) | c;
}
return(CONST);
case ALPHA:
if( p = lookup(token) )
expand(p);
else
return(ALPHA);
break;
default:
return(type);
}
}
}
/* stkop - stack an operator on the operand stack*/
/* Unstack all operators of lower priority, evaluating them as*/
/* they are unstacked.*/
stkop(opr) /* returns 1 if ok, 0 otherwise*/
int opr; /* operator to stack*/
{
register int i, j, op1, op2, pri;
for( pri = opinfo[opr]&OPPRI; pri < *priptr; ) {
if( *oprptr == LPAREN ) {
if( opr == RPAREN ) {
oprptr--;
priptr--;
return(1);
}
break;
}
op1 = *opnptr;
if( (i=opinfo[*oprptr]) & OPBIN ) {
op2 = op1;
op1 = *--opnptr;
}
switch(*oprptr) { /*operator*/
case ADD:
op1 =+ op2;
break;
case SUB:
op1 =- op2;
break;
case COLON:
priptr--;
if( *--oprptr != QMARK )
return(0);
op1 = (*--opnptr ? op1 : op2);
break;
case QMARK:
return(0);
case XOR:
op1 =^ op2;
break;
case OR:
op1 =| op2;
break;
case AND:
op1 =& op2;
break;
case EQUAL:
op1 = (op1 == op2);
break;
case NEQUAL:
op1 = (op1 != op2);
break;
case LESS:
op1 = (op1 < op2);
break;
case LSEQUAL:
op1 = (op1 <= op2);
break;
case GREAT:
op1 = (op1 > op2);
break;
case GREQUAL:
op1 = (op1 >= op2);
break;
case LSHIFT:
op1 = (op1 << op2);
break;
case RSHIFT:
op1 = (op1 >> op2);
break;
case NEG:
op1 = -op1;
break;
case NOT:
op1 = !op1;
break;
case COMPL:
op1 = ~ op1;
break;
case MULT:
op1 =* op2;
break;
case DIV:
op1 =/ op2;
break;
case MOD:
op1 =% op2;
break;
}
*opnptr = op1;
priptr--;
oprptr--;
}
if( priptr >= &pristk[STKLEN-1] ) {
error("expression operator stack overflow");
cexit();
}
*++oprptr = opr; /*operator value*/
*++priptr = pri; /*operator priority*/
return(1);
}
#define toupper(c) ((c) & ~32)
/* const - alpha to int conversion, handles octal and hexidecimal*/
/* Uses Horner's method to evaluate number.*/
const(str) /* returns number evaluated*/
char *str; /* pointer to string to convert*/
{
register int c, ch, i, radix;
i = 0;
radix = 10;
if( *str == '0' ) {
radix = 8;
if( *++str == 'x' || *str == 'X' ) {
radix = 16;
str++;
}
}
while( c = *str++ ) {
if( (ch=toupper(c)) >= 'A' && ch <= 'F' )
c = ch - ('A'-10);
else if( c >= '0' && c <= '9' )
c =- '0';
else
break;
if( c >= radix )
break;
i = i*radix + c;
}
return(i);
}

View File

@@ -0,0 +1,353 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "preproc.h"
int Eflag;
char null[] "";
char ctype[] {
EOF, ANYC, ANYC, ANYC, ANYC, ANYC, ANYC, ANYC,
ANYC, WHITE, NEWL, ANYC, ANYC, ANYC, ANYC, ANYC,
ANYC, ANYC, ANYC, ANYC, NEWL, ANYC, ANYC, ANYC,
ANYC, ANYC, ANYC, ANYC, ANYC, ANYC, ANYC, ANYC,
WHITE, NOT, DQUOTE, POUND, ANYC, MOD, AND, SQUOTE,
LPAREN, RPAREN, MULT, ADD, COMMA, SUB, ANYC, DIV,
DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
DIGIT, DIGIT, COLON, ANYC, LESS, EQUAL, GREAT, QMARK,
ANYC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ANYC, BSLASH, ANYC, XOR, ALPHA,
ANYC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ANYC, OR, ANYC, COMPL, ANYC
}; /* BUG2 - ANYC */
/* symhash - compute hash value for symbol*/
/* Sums the symbols characters and takes that modulus the hash table*/
/* size.*/
symhash(sym) /* returns hash value for symbol*/
char *sym; /* pointer to symbol*/
{
register char *p;
register int hashval, i;
for( p = sym, i = SSIZE, hashval = 0; *p != '\0' && i > 0; i-- )
hashval =+ *p++;
return( hashval % HSIZE );
}
/* symequal - check for symbol equality*/
/* Does comparison between two symbols.*/
symequal(sym1,sym2) /* returns 1 if equal, 0 otherwise*/
char *sym1; /* pointer to first symbol*/
char *sym2; /* pointer to second symbol*/
{
register char *p, *q;
register int i;
q = sym2;
i = SSIZE;
for( p = sym1; *p == *q++; )
if( *p++ == '\0' || --i == 0 )
return(1);
return(0);
}
/* symcopy - symbol copy*/
/* Copies one symbol to another.*/
symcopy(sym1,sym2) /* returns - none*/
char *sym1; /* pointer to symbol to copy*/
char *sym2; /* pointer to area to copy to*/
{
register char *p, *q;
register int i;
for( p = sym1, q = sym2, i = SSIZE; --i >= 0; )
if( *p )
*q++ = *p++;
else
*q++ = '\0';
}
/* error - output error message*/
/* Outputs line number and error message and keeps track of errors.*/
error(s,x1,x2,x3,x4,x5,x6) /* returns - none*/
char *s; /* printf string*/
int x1, x2, x3, x4, x5, x6; /* printf args*/
{
if (filep == &filestack[0]) /* [vlh] 3.4 not in include */
printf("# %d: ",lineno);
else
printf("%s : # %d: ",(filep-1)->ifile,(filep-1)->lineno);
printf(s,x1,x2,x3,x4,x5,x6);
putchar('\n');
mfail++;
}
/* putback - puts back a single character*/
/* Checks for push back buffer overflow.*/
putback(c)
int c;
{
if( pbp >= &pbbuf[PBSIZE] ) {
error("too many characters pushed back");
cexit();
}
*pbp++ = c;
}
/* pbtok - push back a token*/
/* Reverses token as its pushing it back.*/
pbtok(s)
char *s;
{
register char *p;
for( p = s + strlen(s); p > s ; )
putback(*--p);
}
/* ngetch - get a (possibly) pushed back character*/
/* This handles the include file stack and incrementing the line*/
/* number for the lowest level file.*/
ngetch() /* returns character or EOF*/
{
register int c, i;
register char *p, *q;
if( pbp > &pbbuf[0] )
return(*--pbp);
pbflag = 0;
while( (c=getc(&inbuf)) < 0 ) {
if( filep == &filestack[0] )
return(EOF);
close(inbuf.fd);
filep--;
#ifdef NONEST
inbuf.fd = holdbuf.fd;
inbuf.nc = holdbuf.nc;
inbuf.bp = holdbuf.bp;
p = &inbuf.buffer[0];
q = &holdbuf.buffer[0];
for(i = 0; i<BUFSIZE; i++)
*p++ = *q++;
#else
inbuf.fd = filep->ifd;
inbuf.nc = 0;
inbuf.bp = &inbuf.buffer[0];
#endif
if( filep == &filestack[0] ) { /*need line for #include...*/
doputc('\n',&outbuf);
lineno++;
}
}
return( c );
}
/* getsp - get symbol pointer*/
/* Calculates the symbol table pointer for a given symbol, if symbol*/
/* is not defined, will point to appropriate place to insert symbol.*/
struct symbol *getsp(name)
char *name;
{
register int wrap;
register struct symbol *sp, *asp;
wrap = 0;
asp = 0;
for( sp = &symtab[symhash(name)]; sp->s_def != null; ) {
if( symequal(sp->s_name,name) )
return(sp);
if( !asp && sp->s_def == null )
asp = sp;
if( ++sp >= &symtab[HSIZE] ) {
if( wrap++ ) {
error("symbol table overflow");
cexit();
}
sp = &symtab[0];
}
}
return( asp ? asp : sp );
}
/* lookup - looks up a symbol to see if it is defined*/
/* Returns pointer to definition if found.*/
char *lookup(name) /* returns 0 or ptr to symbol*/
char *name; /* symbol name*/
{
register struct symbol *sp;
sp = getsp(name);
if( sp->s_def == 0 || sp->s_def == null )
return(0);
return(sp);
}
/* gettok - gets next token from input*/
/* Collects character string in token and handles special tokens for*/
/* the expression evaluator.*/
gettok(token) /* returns token type*/
char *token;
{
register char *p, c;
register int type, count, t, l;
p = token;
c = ngetch();
*p++ = c;
switch( type = ctype[c] ) {
case SQUOTE:
case DQUOTE:
getstr(token,TOKSIZE,c);
return(type);
case DIGIT:
case ALPHA:
for( ; p < &token[TOKSIZE]; p++ ) {
*p = ngetch();
if( (t=ctype[*p]) != ALPHA && t != DIGIT )
break;
}
putback(*p);
break;
case NOT:
if( peekis('=') ) {
type = NEQUAL;
*p++ = '=';
}
break;
case GREAT:
if( peekis('>') ) {
type = RSHIFT;
*p++ = '>';
}
else if( peekis('=') ) {
type = GREQUAL;
*p++ = '=';
}
break;
case LESS:
if( peekis('<') ) {
type = LSHIFT;
*p++ = '<';
}
else if( peekis('=') ) {
type = LSEQUAL;
*p++ = '=';
}
break;
case EQUAL:
if( peekis('=') )
*p++ = '=';
else
type = ANYC;
break;
case DIV:
if( peekis('*') ) {
l = lineno;
while( (c=ngetch()) != EOF )
if( c == '\n' ) {
if( filep == &filestack[0] && pbp == &pbbuf[0] ) {
lineno++;
doputc('\n',&outbuf);
}
}
else if( c == '*' && peekis('/') )
break;
if( c == EOF ) {
lineno = l;
error("no */ before EOF");
}
type = WHITE;
token[0] = ' ';
}
else if( peekis('/') ) {
while( (c=ngetch()) != EOF && c != '\n' )
;
type = NEWL;
token[0] = '\n';
}
break;
case BADC:
error("bad character 0%o",c);
break;
}
*p = '\0';
return(type);
}
/* getstr - get a quoted (single or double) character string*/
/* Gets specified number of characters, handling escapes.*/
getstr(str,nchars,endc) /* returns - none*/
char *str; /* pointer to string buffer*/
int nchars; /* max number of characters*/
char endc; /* ending string character*/
{
register char *p;
register int i;
register int c;
register int j;
p = str;
*p++ = endc;
for( i = nchars-2; (c=ngetch()) != endc; ) {
if( c == EOF || c == '\n' ) {
error("string cannot cross line");
break;
}
if( --i > 0 ) /*BUG 1*/
*p++ = c;
else if( !i )
error("string too long");
if( c == '\\' ) {
c = ngetch();
if( --i > 0 ) /*BUG 1*/
*p++ = c;
else if( !i )
error("string too long");
}
}
*p++ = endc;
*p = '\0';
}
/* peekis - peeks at next character for specific character*/
/* Gets next (possibly pushed back) character, if it matches*/
/* the given character 1 is returned, otherwise the character*/
/* is put back.*/
peekis(tc) /* returns 1 if match, 0 otherwise*/
int tc; /* test character*/
{
register int c;
if( (c=ngetch()) == tc )
return(1);
putback(c);
return(0);
}
doputc(ch,buffer)
char ch;
struct ibuf *buffer;
{
if (!Eflag)
putc(ch,buffer);
else
putchar(ch);
}

View File

@@ -0,0 +1,743 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "preproc.h"
#define CSTKSIZE 20
#define FILESEP '/'
#define NINCL 10
char *stdincl "/usr/include/"; /*standard include directory*/
int clabel 1000;
int nlabel 1001;
int nincl;
int literal; /*[vlh] 4.0 lnum and file name specified using #line */
char *incl[10];
char tmp[6];
char ctype[];
struct builtin {
char *b_name;
int b_type;
} btab[] {
"define", DEFINE,
"include", INCLUDE,
"undef", UNDEF,
"ifdef", IFDEF,
"ifndef", IFNDEF,
"else", ELSE,
"endif", ENDIF,
"if", IF,
"line", LINE,
0,
};
char *getinclude();
char cstack[CSTKSIZE];
char *cstkptr, inclname[TOKSIZE];
/* domacro - do macro processing*/
/* Does the macro pre-processing on the input file and leaves the*/
/* result on the output file.*/
domacro(infile,outfile,nd) /* returns 1 if ok, 0 otherwise*/
char *infile; /* input file name*/
char *outfile; /* output file name*/
int nd; /* number of defines*/
{
register struct builtin *bp;
register char *l;
register struct symbol *sp;
register int x, nonewline; /* handle empty new lines with SOH */
register char *p;
filep = &filestack[0]; /* [vlh] 4.0 moved for error msgs */
lineno = 1; /* [vlh] 4.0 moved for error msgs */
if( fopen(infile,&inbuf,0) < 0 ) { /* 3rd arg for versados */
error("can't open source file %s\n",infile);
return(0);
}
if( fcreat(outfile,&outbuf,0) < 0 ) { /* 3rd arg for versados */
error("can't creat %s\n",outfile);
return(0);
}
for (sp= &symtab[0]; sp<= &symtab[HSIZE-1]; sp++) /*3.4*/
sp->s_def = null; /* clear out symbol table */
if( !defap ) {
defp = defap = sbrk(1024);
defmax = defcount = 1024;
}
else { /* multiple files, define area already exists */
defcount = defmax;
for (x = defmax, defp = defap; x>0; x--)
*defp++ = 0;
defp = defap;
}
nonewline = defused = mfail = 0;
pbp = &pbbuf[0];
cstkptr = &cstack[0];
install("Newlabel",NEWLABEL);
install("Label",LABEL);
while( --nd >= 0 )
dinstall(defs[nd].ptr,defs[nd].value);
while( getline(infile) ) {
l = line;
if( filep == &filestack[0] && pbp == &pbbuf[0] )
lineno++;
else if ( !pflag && !asflag && !literal ) { /*[vlh] include file*/
if (*l) {
putid((filep-1)->ifile,(filep-1)->lineno); /* 4.0 */
if (!(*l)) doputc(' ',&outbuf);
}
else nonewline++;
(filep-1)->lineno++;
}
while( *l )
doputc(*l++,&outbuf);
if (!nonewline) doputc('\n',&outbuf);
else nonewline = 0;
literal = 0;
}
if( cstkptr != &cstack[0] )
error("unmatched conditional");
if( defused > defmax )
defmax = defused;
v6flush(&outbuf);
close(outbuf.fd);
close(inbuf.fd);
return(mfail==0);
}
putid(fname,lnum) /* [vlh] 4.0 SOH line header */
char *fname;
int lnum;
{
register char *p;
if (asflag || pflag)
return;
doputc(SOH,&outbuf);
for (p = fname; *p; p++)
doputc(*p,&outbuf);
doputc(SOH,&outbuf);
itoa(lnum,tmp,5);
for (p = tmp; *p==' '; ) p++;
for ( ; *p; p++)
doputc(*p,&outbuf);
doputc(' ',&outbuf);
}
install(name,def)
char *name;
int def;
{
register struct symbol *sp;
sp = getsp(name);
symcopy(name,sp->s_name);
sp->s_def = defp;
putd(def);
putd('\0');
}
dinstall(name,def) /* returns - none*/
char *name; /* macro name*/
char *def; /* pointer to definition*/
{
register struct symbol *sp;
sp = getsp(name);
symcopy(name,sp->s_name);
sp->s_def = defp;
putd(NOARGS);
if (def) /* [vlh] character strings... */
while(*def) putd(*def++);
else putd('1'); /* [vlh] default define value */
putd('\0');
}
/* kwlook - look up the macro built-in names*/
/* Searches thru the built-in table for the name.*/
kwlook(name) /* returns keyword index or 0*/
char *name; /* keyword name to lookup*/
{
register struct builtin *bp;
for( bp = &btab[0]; bp->b_name; bp++ )
if( strcmp(bp->b_name,name) == 0 )
return(bp->b_type);
return(0);
}
/*
* getline - get input line handling macro statements
* Checks for a preprocessor statement on the line and if there
* is one there, it processes it. Note that most of the work is
* in determining whether we need to skip the current line or not.
* This is all handled with the condition stack and the skip variable.
* The skip variable is non-zero if any condition on the condition
* stack is SKIP.
*/
getline(infile) /* returns 0 for EOF, 1 otherwise*/
char *infile; /* [vlh] for quoted include files */
{
char token[TOKSIZE];
register int type, i;
register char *p;
initl();
if( (type=gettok(token)) == EOF )
return(0);
if( type == POUND ) {
if( (type=getntok(token)) == NEWL )
return(1);
switch( kwlook(token) ) {
case IFDEF:
if( getntok(token) == ALPHA && lookup(token) )
push(NOSKIP);
else {
push(SKIP);
skip++;
}
break;
case IFNDEF:
if( getntok(token) == ALPHA && lookup(token) ) {
push(SKIP);
skip++;
}
else
push(NOSKIP);
break;
case ENDIF:
if( (i=pop()) == SKIP )
skip--;
else if( i != NOSKIP )
error("invalid #endif");
break;
case ELSE:
if( (i=pop()) == SKIP ) {
skip--;
push(NOSKIP);
}
else if( i == NOSKIP ) {
skip++;
push(SKIP);
}
else
error("invalid #else");
break;
case DEFINE:
if( !skip ) /*if in skip, don't do define*/
dodefine();
break;
case UNDEF:
if( !skip ) { /*if in skip, don't undef*/
if( (type=getntok(token)) == ALPHA )
undefine(token);
}
break;
case INCLUDE:
if( !skip ) /*if in skip, don't do include*/
doinclude(infile);
break;
case IF:
if( cexpr() ) /*evaluate constant expression*/
push(NOSKIP); /*non-zero, so don't skip*/
else {
push(SKIP);
skip++;
}
break;
case LINE: /* [vlh] 4.0 */
doline(infile);
break;
default:
error("invalid preprocessor command");
break;
}
eatup();
}
else if( type == NEWL )
;
else if( skip ) {
eatup();
}
else {
for( ; type != NEWL && type != EOF ; type = gettok(token) ) {
if( type == ALPHA && (p=lookup(token)) )
expand(p);
else {
for( p = token; *p ; )
putl(*p++);
}
}
}
putl('\0');
return(1);
}
/* eatup - eat up the rest of the input line until a newline or EOF*/
/* Does gettok calls.*/
eatup() /* returns - none*/
{
register int type;
char etoken[TOKSIZE];
while( (type=gettok(etoken)) != NEWL && type != EOF )
;
}
/* putl - put a character to the current output line*/
/* Checks for line overflow.*/
putl(c) /* returns - none*/
int c; /* character to put on line*/
{
if( linep < &line[LINESIZE] )
*linep++ = c;
else if ( !loverflow ) {
loverflow++;
error("line overflow");
}
}
/* initl - initialize current line*/
/* Sets the line pointer and the line overflow flag.*/
initl() /* returns - none*/
{
*(linep= &line[0]) = '\0';
loverflow = 0;
}
/* putd - put a character to the define buffer*/
/* Does dynamic allocation for define buffer*/
putd(c) /* returns - none*/
int c; /* character to put in buffer*/
{
if( !defcount ) {
if( sbrk(DEFSIZE) == -1 ) {
error("define table overflow");
cexit();
}
defcount = DEFSIZE;
}
defused++;
defcount--;
*defp++ = c;
}
/* undefine - does undef command*/
/* Sets the symbols definition to the null pointer*/
undefine(name) /* returns - none*/
char *name; /* pointer to name to undef*/
{
register struct symbol *sp;
sp = getsp(name);
if( sp->s_def )
sp->s_def = null;
}
/* dodefine - do #define processing*/
/* Checks the define name, collects formal arguements and saves*/
/* macro definition, substituting for formal arguments as it goes.*/
dodefine() /* returns - none*/
{
char token[TOKSIZE], *args[MAXARGS], argbuf[ARGBSIZE];
register char *abp, *p;
register int type, nargs, i;
register struct symbol *sp;
if( (type=getntok(token)) != ALPHA ) {
error("bad define name: %s",token);
return;
}
sp = getsp(token);
symcopy(token,sp->s_name);
sp->s_def = defp;
nargs = 0;
abp = argbuf;
if( (type=gettok(token)) == LPAREN ) {
for( ; (type=getfarg(token)) != RPAREN; nargs++ ) {
if( nargs >= MAXARGS ) {
error("too many arguments");
break;
}
args[nargs] = abp;
for( p = token; *abp++ = *p++; ) {
if( abp >= &argbuf[ARGBSIZE] ) {
error("argument buffer overflow");
break;
}
}
}
putd(nargs);
}
else {
pbtok(token);
putd(NOARGS);
}
type = getntok(token); /*get next non-white token*/
for( ; type != NEWL && type != EOF; type = gettok(token) ) {
if( type == ALPHA ) {
for( i = 0; i < nargs; i++ ) {
if( strcmp(args[i],token) == 0 )
break;
}
if( i < nargs ) { /*sub ARG marker for formal arg*/
putd(i+1);
putd(ARG);
continue;
}
}
else if( type == BSLASH ) {
if( (i=ngetch()) == '\n' ) { /*multi-line macro?*/
if( filep == &filestack[0] && pbp == &pbbuf[0] ) {
lineno++;
doputc('\n',&outbuf);
}
}
putd(i);
continue;
}
for( p = token; *p ; )
putd(*p++);
}
pbtok(token);
putd('\0');
}
/* expand - expands the macro definition*/
/* Checks for define recursion and #define x x problems, collects*/
/* the actual arguments using getaarg, and then expands the macro*/
/* by pushing it onto the push back buffer, substituting arguments*/
/* as it goes.*/
expand(sp) /* returns - none*/
struct symbol *sp; /* pointer to macro to expand*/
{
char argbuf[ARGBSIZE], *args[MAXARGS], token[TOKSIZE];
register char *p, *abp, *mdef;
register int i, j, nargs, type;
if( pbflag++ > 100 ) {
error("define recursion");
return;
}
if( strcmp(sp->s_name,mdef=sp->s_def) == 0 ) { /*handle #define x x*/
while( *mdef )
putl(*mdef++);
return;
}
nargs = 0;
if( *mdef == NOARGS ) /*suppress grabbing of args*/
;
else if( gettok(token) != LPAREN )
pbtok(token);
else {
abp = &argbuf[0];
while( (type=getaarg(token)) != EOF ) {
if( nargs >= MAXARGS ) {
error("too many arguments");
return;
}
args[nargs++] = abp;
for( p = token; *abp++ = *p++; ) {
if( abp >= &argbuf[ARGBSIZE] ) {
error("argument buffer overflow");
return;
}
}
if( type == RPAREN )
break;
}
}
if( *mdef == NEWLABEL ) {
clabel = nlabel;
if( !nargs )
nlabel++;
else
nlabel =+ atoi(args[0]);
}
else if( *mdef == LABEL ) {
if( !nargs )
i = clabel;
else
i = clabel + atoi(args[0]);
pbnum(i);
pbtok("_L");
}
else {
mdef++; /*skip no. of args*/
for( p = mdef + strlen(mdef) - 1; p >= mdef; p-- ) {
if( *p == ARG ) {
if( (j= *--p) <= nargs )
pbtok(args[j-1]);
}
else
putback(*p);
}
}
}
/* getfarg - get macro formal parameters*/
/* Skips blanks and handles "," and ")".*/
getfarg(token) /* returns token type*/
char *token; /* token returned*/
{
register int type;
if( (type=getntok(token)) == RPAREN || type == ALPHA )
return(type);
if( type != COMMA || (type=getntok(token)) != ALPHA )
error("bad argument:%s",token);
return(type);
}
/* getntok - get next token, suppressing white space*/
/* Merely gettok's until non-white space is there*/
getntok(token) /* returns token type*/
char *token; /* token returned*/
{
register int type;
while( (type=gettok(token)) == WHITE )
;
return(type);
}
/* getaarg - get macro actual argument*/
/* This handles the collecting of the macro's call arguments.*/
/* Note that you may have parenthesis as part of the macro argument,*/
/* hence you need to keep track of them.*/
getaarg(argp) /* returns token type*/
char *argp; /* argument returned*/
{
int type, plevel, i;
register char *p, *ap;
char token[TOKSIZE];
ap = argp;
*ap = '\0';
plevel = 0;
i = TOKSIZE;
while( ((type=gettok(token)) != COMMA && type != RPAREN) || plevel ) {
for( p = token; *ap = *p++; ap++ )
if( --i <= 0 ) {
error("macro argument too long");
return(EOF);
}
if( type == LPAREN )
plevel++;
else if( type == RPAREN )
plevel--;
else if( type == EOF ) {
error("unexpected EOF");
cexit();
}
}
if( ap == argp )
type = EOF;
return(type);
}
/* push - push a #ifdef condition value on condition stack*/
/* Checks for stack overflow.*/
push(val) /* returns - none*/
int val; /* value to push*/
{
if( cstkptr >= &cstack[CSTKSIZE] ) {
error("condition stack overflow");
cexit();
}
*cstkptr++ = val;
}
/* pop - pop the #ifdef, etc. condition stack*/
/* Checks for stack undeflow.*/
pop() /* returns - top of condition stack*/
{
if( cstkptr <= &cstack[0] )
return(-1);
return( *--cstkptr );
}
/* doinclude - handle #include command*/
/* Checks for file name or library file name and pushes file on*/
/* include file stack.*/
doinclude(infile) /* returns - none*/
char *infile; /* [vlh] for quoted include files */
{
register int type, fd;
char token[TOKSIZE], fname[TOKSIZE];
register char *p, *q, c, *ptr1, *ptr2;
int i, j;
p = fname;
if( (type=getntok(token)) == SQUOTE || type == DQUOTE ) {
for( c = token[0], q = &token[1]; *q != c; )
*p++ = *q++;
*p = '\0';
p = getinclude(fname,infile);
}
else if( type != LESS ) {
error("bad include file");
return;
}
else {
while( (type=gettok(token))!=GREAT && type!=NEWL && type!=EOF )
for( q = token; *p = *q++; p++ )
;
if( type != GREAT ) {
error("bad include file name");
pbtok(token);
return;
}
p = getinclude(fname,0L);
}
eatup(); /*need here...*/
if( filep >= &filestack[FSTACK] )
error("includes nested too deeply");
else {
#ifdef NONEST
if (filep != &filestack[0]) { /* in main file ?? */
error("can not nest include files");
putback('\n');
return;
}
holdbuf.fd = inbuf.fd;
holdbuf.nc = inbuf.nc;
holdbuf.bp = inbuf.bp;
ptr1 = &holdbuf.buffer[0];
ptr2 = &inbuf.buffer[0];
for(i=0; i<BUFSIZE; i++)
*ptr1++ = *ptr2++;
#else
fd = inbuf.fd;
seek(fd,-inbuf.nc,1); /*back up file ptr*/
#endif
inbuf.nc = 0;
if( fopen(p,&inbuf,0) < 0 ) /* 3rd arg for versados */
error("can't open include file %s\n",p);
else {
filep->ifd = fd;
filep->lineno = 0; /* [vlh] */
doifile(p);
filep++;
}
}
putback('\n'); /*for eatup in domacro*/
}
doifile(p) /* [vlh] */
char *p;
{
register char *iptr;
register int ndx;
while ((ndx = index(p,FILESEP)) >= 0) p =+ ndx+1;
for( iptr = filep->ifile; *p; ) *iptr++ = *p++;
*iptr = 0;
}
/* getinclude - get include file full pathname */
char *
getinclude(fname,parent) /* [vlh] */
char *fname;
char *parent; /* search parent-file home directory ? */
{
register char *q, *t;
register int i, fd, ndx;
if (parent) { /* include filename surrounded by quotes */
q = (filep == &filestack[0]) ? parent : (filep-1)->ifile;
t = &inclname;
while ((ndx = index(q,FILESEP)) >= 0) {
ndx++;
while (ndx--) *t++ = *q++;
}
for (q=fname; *t++ = *q++; );
*t = 0;
if ((fd = open(inclname,0)) >= 0) { /* found it */
close(fd);
return(&inclname);
}
}
for (i=0; i<nincl; i++) {
for(t=inclname, q=incl[i]; *t++ = *q++; ) ;
for(q=fname, --t; *t++ = *q++; ) ;
*t = 0;
if ((fd = open(inclname,0)) >= 0) {
close(fd);
return(&inclname);
}
}
for(t=inclname, q=stdincl; *t++ = *q++; ) ;
for(q=fname, --t; *t++ = *q++; ) ;
*t = 0;
return(&inclname);
}
doline(infile) /* [vlh] 4.0 : returns - none */
char *infile;
{
register char *ptr;
char token[TOKSIZE];
register int ch, lnum, type;
while ((type = gettok(token)) == WHITE); /* skip white space */
if (type != DIGIT) {
error("invalid #line args");
return;
}
lnum = atoi(token);
do {
ch = ngetch();
} while (ctype[ch] == WHITE);
if (ctype[ch] != NEWL && ctype[ch] != EOF) {
ptr = &token;
do {
*ptr++ = ch;
ch = ngetch();
} while (ctype[ch]!=NEWL && ctype[ch]!=EOF && ctype[ch]!=WHITE);
*ptr = 0;
putid(token,lnum);
}
else {
if (filep == &filestack[0] && pbp == &pbbuf[0])
putid(infile,lnum);
else
putid((filep-1)->ifile,lnum);
}
literal = 1;
for( ; ctype[ch]!=NEWL && ctype[ch]!=EOF; )
ch = ngetch();
if (ctype[ch] != EOF)
while ( ctype[ ch = ngetch() ] != NEWL && ctype[ch] != EOF)
putl(ch);
putback('\n');
}
pbnum(num) /* returns - none*/
int num;
{
register int digit;
do {
digit = num % 10;
num =/ 10;
putback(digit+'0');
} while( num > 0 );
}

View File

@@ -0,0 +1,659 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char *version "@(#) c68 preprocessor 4.0 - Mar 18, 1983";
#include "preproc.h"
#define NARGS 64
#define NINCL 10
#define ARGSIZE 1024
#define ICODE 0
#define STRINGS 1
#define MTEMP 2
#define ASTEMP 3
#define NTEMPS 4
char *fargs[NARGS+1];
char **fargp;
char argbuf[ARGSIZE];
char *cfiles[NARGS+1];
char *loadargs[NARGS+1];
char *fns[NTEMPS];
char *tfns[NTEMPS];
int ndefs;
char *incl[NINCL];
int nincl;
char *argp &argbuf[0];
int cflag;
int nflag;
int fflag; /* [vlh] 3.4 fast floating point format and library */
int eflag; /* [vlh] 3.4 ieee floating point format and library */
int lflag;
int oflag;
int pflag;
int Eflag; /* [vlh] 4.0 flag, Preprocessor only to stdout */
int sflag;
int wflag; /* [vlh] turn on warning messages */
int verbose; /* [vlh] 3.4 force printing of file being processed */
int xflag;
int v6flag; /* [vlh] 3.4 compile for version 6 */
int v7flag; /* [vlh] 3.4 */
int s3flag; /* [vlh] 3.4 */
int s5flag; /* [vlh] 3.4 */
int optimize; /* [vlh] 3.4 recognize optimization flag '-O' */
int status;
int oneflag;
int errno;
char *cptrone 1;
char *parser "/lib/c068";
char *cgen "/lib/c168";
char *onepass "/lib/c0168";
char *pref "/lib/c680.o";
char *loader "/bin/lo68";
char *asmprog "/bin/as68";
char *deflib "/lib/lib7.a";
char *deflibfp "/lib/libF.a"; /* [vlh] 3.4 */
char *deflibep "/lib/libE.a"; /* [vlh] 3.4 */
char *v6lib "/lib/libv6.a"; /* [vlh] 3.4 */
char *v7lib "/lib/libv7.a"; /* [vlh] 3.4 */
char *s3lib "/lib/libs3.a"; /* [vlh] 3.4 */
char *s5lib "/lib/libs5.a"; /* [vlh] 3.4 */
char *v6incl "/usr/include/v6/\0"; /* [vlh] 3.4 */
char *v7incl "/usr/include/v7/\0"; /* [vlh] 3.4 */
char *s3incl "/usr/include/sys3/\0"; /* [vlh] 3.4 */
char *s5incl "/usr/include/sys5/\0"; /* [vlh] 3.4 */
char *ldflg "-r";
int mmuflag; /*[vlh]replace nommu #ifdef'd var*/
/* cexit - exit from C compiler driver*/
/* This deletes any existing temps and exits with the error status.*/
cexit() /* returns - none*/
{
register int i;
if( !pflag )
for( i = 0; i < NTEMPS; i++ )
if( fns[i] )
unlink(fns[i]);
exit(status);
}
/*
* main - main routine for c68 Compiler system
* Handles the C68 arguments. For each C file given, the macro
* pre-processor is called, then the parser, code generator and
* assember are fexec'd. The loader arguments are collected and
* the loader is fexec'd.
*/
main(argc,argv)
int argc;
char **argv;
{
register char *arg, **p, **cfilep, **loadp, *sp;
register int nloadfiles, c, i, j, x;
#ifdef NOFORKS
if (argc != 3) {
error("usage: c68 inputfile outputfile");
exit(-1);
}
pflag++;
domacro(argv[1],argv[2],ndefs);
#else
cfilep = &cfiles[0];
loadp = &loadargs[0];
nloadfiles = 0;
sysinfo(0,&mmuflag); /*[vlh] mmu system ??*/
if (!mmuflag) { /*[vlh] default args*/
*loadp = ldflg;
lflag++;
}
for( p = argv, j = argc; --j > 0; ) { /*process arguments*/
if( *(arg= *++p) == '-' ) {
arg++;
for( i = 0; c = *arg++; i++ ) {
switch( c ) {
case 'c':
cflag++;
continue;
case '1':
oneflag++;
parser = onepass;
continue;
case 'D':
defs[ndefs].ptr = arg;
if ((x=index(arg,'=')) != -1) {
defs[ndefs++].value = (arg+x+1);
arg[x] = 0; /* get rid of value */
}
else defs[ndefs++].value = 0;
i++;
break;
case 'I':
incl[nincl++] = arg;
i++;
break;
case 'N':
nflag++;
continue;
case 'e': /* [vlh] 3.4 */
eflag++;
if (fflag)
ferror("incompatible flags : '-f' and '-e'");
continue;
case 'f': /* [vlh] 3.4 */
fflag++;
if (eflag)
ferror("incompatible flags : '-f' and '-e'");
continue;
case 'L':
lflag++;
continue;
case 'o':
if( --j <= 0 )
ferror("bad -o option");
*loadp++ = *p++;
if( strend(*p,".c") || strend(*p,".s") ||
strend(*p,".o") ) {
sp = makecopy(*p);
sp[strlen(sp)-2] = '\0';
*loadp++ = sp;
*loadp++ = setend(*p,'o');
nloadfiles++;
if( !strend(*p,".o") )
*cfilep++ = *p;
}
else
*loadp++ = *p;
continue;
case 'E': /* [vlh] 4.0 Preprocessor to stdout */
Eflag++;
case 'P':
pflag++;
cflag++;
continue;
case 'S':
sflag++;
cflag++;
nflag++;
continue;
case 't':
if( (c= *arg++) == '0' )
parser = "/usr/c68/c068";
else if( c == '1' )
cgen = "/usr/c68/c168";
else if( c == '\0' )
arg--;
continue;
case 'w': /* [vlh] */
wflag++;
continue;
case 'O': /* [vlh] 3.4 */
optimize++;
continue;
case 'v': /* [vlh] 3.4 print file name */
verbose++;
continue;
case '6': /* [vlh] 3.4 v6 compatibility */
v6flag++;
incl[nincl++] = v6incl;
continue;
case '7': /* [vlh] 3.4 v7 compatibility */
v7flag++;
incl[nincl++] = v7incl;
continue;
case '3': /* [vlh] 3.4 s3 compatibility */
s3flag++;
incl[nincl++] = s3incl;
continue;
case '5': /* [vlh] 3.4 s5 compatiblity */
s5flag++;
incl[nincl++] = s5incl;
continue;
default:
if( loadp >= &loadargs[NARGS] )
ferror("too many loader args");
*loadp++ = *p;
i++;
break;
}
break;
}
if( i )
continue;
}
if( strend(arg,".c") || strend(arg,".s") ) {
/*C or Assembler files to process*/
if( cfilep >= &cfiles[NARGS] )
ferror("too many files");
*cfilep++ = arg;
nloadfiles++;
if( !chkdup(arg) ) {
if( loadp >= &loadargs[NARGS] )
ferror("too many loader args");
*loadp++ = setend(arg,'o');
}
}
else if( !chkdup(arg) ) { /*check for loader args*/
if( loadp >= &loadargs[NARGS] )
ferror("too many loader args");
*loadp++ = arg;
if( strend(arg,".o") )
nloadfiles++;
}
}
if( cfilep != &cfiles[0] ) { /*had a C file?*/
if( signal(2,cexit) == cptrone ) /*catch rubouts, check ignore*/
signal(2,cptrone);
for( i = 0; i < NTEMPS; i++ ) /*allocate temps*/
fns[i] = maketemp(i);
for( p = &cfiles[0]; arg = *p++; ) { /*handle each C file*/
for( i = 0; i < NTEMPS; i++ )
tfns[i] = fns[i];
if( cfilep != &cfiles[1] || verbose )
printf("%s:\n",arg);
/*
* the following sets things up for the parser, the macro pre-processor
* is called (not forked), then the parser is fexec'd.
*/
asflag = strend(arg,".s");
if( pflag || asflag )
tfns[MTEMP] = setend(arg,'i');
if( domacro(arg,tfns[MTEMP],ndefs) == 0 || pflag ) {
cflag++;
status =+ mfail; /* preprocessor failure */
continue;
}
if( !asflag ) {
tfns[ASTEMP] = setend(arg,'s');
initfargs();
addfarg(parser);
addfarg(tfns[MTEMP]);
if( oneflag ) {
addfarg(tfns[ASTEMP]);
addfarg(tfns[STRINGS]);
if( lflag )
addfarg("-L");
if( sflag || nflag )
addfarg("-D");
addfarg("-1");
}
else {
addfarg(tfns[ICODE]);
addfarg(tfns[STRINGS]);
if ( fflag ) /* [vlh] 3.4 */
addfarg("-f");
else if ( eflag ) /* [vlh] 3.4 */
addfarg("-e");
if ( wflag )
addfarg("-w");
}
endfargs();
if( fexec(parser,fargs) ) {
status++;
cflag++;
continue;
}
/*this sets things up for the code generator*/
if( !oneflag ) {
initfargs();
addfarg(cgen);
addfarg(tfns[ICODE]);
addfarg(tfns[ASTEMP]);
if( !sflag )
fns[ASTEMP] = tfns[ASTEMP];
if( lflag )
addfarg("-L");
if( nflag || sflag )
addfarg("-D");
endfargs();
if( fexec(cgen,fargs) ) {
status++;
cflag++;
continue;
}
}
if( sflag )
continue;
}
else
tfns[ASTEMP] = tfns[MTEMP];
/*this sets things up for the assembler*/
initfargs();
addfarg(asmprog);
if( !asflag )
addfarg("-u");
if( lflag )
addfarg("-L");
addfarg(tfns[ASTEMP]);
endfargs();
if( fexec(asmprog,fargs) ) {
cflag++;
status++;
}
unlink(tfns[ASTEMP]);
}
}
if( !cflag && (loadp != &loadargs[0] || cfilep != &cfiles[0] )) {
/*
* set things up for the loader, this means that we need to add the
* C preface at the beginning of the program which has the jsr to
* main and then exits after return from main.
*/
initfargs();
addfarg(loader);
addfarg("-X");
i = 1;
for( p = loadargs; *p ; p++ ) {
if( i && strend(*p,".o") ) { //insert pref before 1st .o
i = 0;
addfarg(pref);
}
addfarg(*p);
}
if (fflag) /* [vlh] 3.4 */
addfarg(deflibfp);
if (eflag) /* [vlh] 3.4 */
addfarg(deflibep);
if (v6flag) /* [vlh] 3.4 */
addfarg(v6lib);
if (v7flag) /* [vlh] 3.4 */
addfarg(v7lib);
if (s3flag) /* [vlh] 3.4 */
addfarg(s3lib);
if (s5flag) /* [vlh] 3.4 */
addfarg(s5lib);
addfarg(deflib);
endfargs();
status =| fexec(loader,fargs);
/*
* if we were given one C file and there is one ".o" file, we remove
* the ".o" file.
*/
if( cfilep == &cfiles[1] && nloadfiles == 1 )
unlink(setend(cfiles[0],'o'));
}
#endif
cexit();
}
/* fexec - fork and exec*/
/* This forks a new task, then does an execv to execute the given*/
/* program with the given arguements.*/
fexec(fname,args) /* returns 1 if error, 0 otherwise*/
char *fname; /* file to execute*/
char **args; /* arguments to pass*/
{
register int pid, i;
int fstat;
/* if( (pid=fork()) == 0 ) { //child process*/
/* execv(fname,args);*/
/* printf("can't execv %s errno=%d\n",fname,errno);*/
/* exit(1);*/
/* }*/
pid = maketask(fname,0,0,args); /*do fork & exec*/
if( pid < 0 ) {
printf("can't maketask %s err=%o\n",fname,errno);
return(1);
}
while( pid != wait(&fstat) ) /*wait for child*/
;
if( (i=fstat&0377) != 0 && i != 14 ) {
if( i != 2 )
printf("%s error terminated, status $%x\n",fname,i);
status++;
cexit();
}
return( (fstat>>8) & 0377 );
}
/* setend - set the end character of a string*/
/* This grabs a copy of the string and sets the last character to*/
/* the given character. This is used to generate ".o", ".i" and*/
/* ".s" file names.*/
char *setend(s,c) /* returns pointer to string*/
char *s; /* pointer to old string*/
int c; /* character to end string with*/
{
register char *p;
p = makecopy(s);
p[strlen(p)-1] = c;
return(p);
}
/* chkdup - checks for duplicate ".o" files in file list*/
/* Goes thru the loader argument list checking for the given*/
/* ".o" file name.*/
chkdup(s) /* returns 1 if found, 0 otherwise*/
char *s; /* pointer to argument*/
{
register char **l;
if( strend(s,".o") ) {
for( l = &loadargs[0]; *l; )
if( !strcmp(*l++,s) )
return(1);
}
return(0);
}
/* makecopy - makes a copy of a string*/
/* This allows for manipulating the file name, while allowing the*/
/* saving of the old file name.*/
char *makecopy(s) /* returns pointer to string*/
char *s; /* string to copy*/
{
register char *p;
register int ndx;
if (strncmp("/tmp/",s,5) != 0) /* don't truncate tmp file names */
while ((ndx = index(s,'/')) != -1) s =+ ndx+1; /* [vlh] */
for( p = argp; *argp++ = *s++; )
;
return(p);
}
/* initfargs - initialize fexec arg block*/
/* This sets the arg block pointer to the beginning of the block.*/
initfargs() /* returns - none*/
{
fargp = &fargs[0];
}
/* addfarg - add fexec argument*/
/* This takes the given arguement and adds it to the argment block*/
addfarg(s)
char *s;
{
if( fargp >= &fargs[NARGS] )
ferror("too many args");
*fargp++ = s;
}
/* endfargs - end fexec argument block*/
/* This ends the argument block with a zero pointer.*/
endfargs() /* returns - none*/
{
*fargp = 0;
}
/* ferror - fatal error*/
/* Outputs error message and exits with error status.*/
ferror(s,x1,x2,x3,x4,x5,x6) /* returns - none*/
char *s; /* printf string*/
int x1, x2, x3, x4, x5, x6; /* printf args*/
{
printf(s,x1,x2,x3,x4,x5,x6);
printf("\n");
status++;
cexit();
}
/* maketemp - make a temporary file name*/
/* Generates unique file name with process id*/
char *maketemp(arb) /* returns file name*/
int arb; /* arbitrary number*/
{
#ifndef NOFORKS
char *p, tmp[6];
p = makecopy("/tmp/ct6");
argp--;
itoa(getpid(),tmp,1);
makecopy(tmp);
argp--;
makecopy(".");
argp--;
itoa(arb,tmp,1);
makecopy(tmp);
return(p);
#endif
}
/* strcmp - string comparison*/
/* Compares two strings for equality, less or greater.*/
strcmp(s,t) /* returns 0 for equality,*/
/* neg for < and pos for >.*/
char *s; /* first string*/
char *t; /* second string*/
{
for( ; *s == *t; s++, t++ )
if( *s == '\0' )
return(0);
return( *s - *t );
}
/* strncmp - string comparison*/
/* Compares two strings for equality, less or greater.*/
strncmp(s,t,n) /* neg for < and pos for >.*/
char *s; /* first string*/
char *t; /* second string*/
{
for( ; *s == *t && n; s++, t++, n--)
if( *s == '\0' )
return(0);
return((n) ? *s - *t : 0);
}
/* strlen - string length*/
/* Computes number of bytes in string.*/
strlen(s) /* returns string length*/
char *s; /* string to compute length*/
{
register int n;
for( n = 0; *s++ != '\0'; )
n++;
return(n);
}
/* itoa - integer to ASCII conversion*/
/* Converts integer to ASCII string, handles '-'.*/
itoa(n,s,w) /* returns - none*/
int n; /* number to convert*/
char *s; /* resulting string*/
int w; /* minimum width of string*/
{
register char *tp;
register int sign, i;
char temp[6];
if( (sign=n) < 0 )
n = -n;
i = 0;
tp = &temp;
do {
i++;
*tp++ = n % 10 + '0';
} while( (n =/ 10) > 0 );
if( sign < 0 ) {
i++;
*tp++ = '-';
}
while( --w >= i ) /*pad on left with blanks*/
*s++ = ' ';
while( --i >= 0 ) /*move chars reversed*/
*s++ = *--tp;
*s = '\0';
}
/* strend - set string end*/
/* This is used to compare the endings of file names for ".c", etc.*/
strend(s,t) /* returns 1 if match, 0 otherwise*/
char *s; /* string to compare*/
char *t; /* string ending*/
{
int ls, lt;
if( (ls=strlen(s)) < (lt=strlen(t)) )
return(0);
if( !strcmp(&s[ls-lt],t) )
return(1);
return(0);
}
v6flush(v6buf)
struct iobuf *v6buf;
{
register i;
i = BLEN - v6buf->nunused;
v6buf->nunused = BLEN;
v6buf->xfree = &(v6buf->buff[0]);
if(write(v6buf->fildes,v6buf->xfree,i) != i)
return(-1);
return(0);
}
/* index - find the index of a character in a string*/
/* This is identical to Software Tools index.*/
index(str,chr) /* returns index of c in str or -1*/
char *str; /* pointer to string to search*/
char chr; /* character to search for*/
{
register char *s;
register int i;
for( s = str, i = 0; *s != '\0'; i++ )
if( *s++ == chr )
return(i);
return(-1);
}

View File

@@ -0,0 +1,26 @@
// maketask call for unix
int maketask(fname,flags,priority,argptrs)
char *fname;
int flags,priority;
char **argptrs;
{
register int pid;
if(flags==0) { //fork and exec
if((pid=fork()) == 0) { //child process
doexecv:
execv(fname,argptrs);
printf("execv failed\n");
exit(-1);
}
return(pid); //return child process id
}
if(flags==2) { //fork only
return(fork());
}
if(flags==4) { //exec only
goto doexecv;
}
return(-1);
}

View File

@@ -0,0 +1,147 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "../icode.h"
/*cexpr operators*/
#define EOF 0
#define SUB 1
#define ADD 2
#define NOT 3
#define NEG 4
#define LPAREN 5
#define RPAREN 6
#define QMARK 7
#define COLON 8
#define OR 9
#define AND 10
#define XOR 11
#define EQUAL 12
#define NEQUAL 13
#define LESS 14
#define LSEQUAL 15
#define GREAT 16
#define GREQUAL 17
#define LSHIFT 18
#define RSHIFT 19
#define MULT 20
#define DIV 21
#define MOD 22
#define COMPL 23
#define CONST 24
#define LASTOP COMPL /*up to here used by cexpr*/
#define SQUOTE 25
#define DQUOTE 26
#define ANYC 27
#define BADC 28
#define COMMA 29
#define NEWL 30
#define POUND 31
#define ALPHA 32
#define DIGIT 33
#define BSLASH 34
#define WHITE 35
#define BUFSIZE 512
#define LINESIZE 512
#define ARG -1
#define NEWLABEL -2
#define LABEL -3
#define NOARGS -4
#define MAXARGS 60
#define ARGBSIZE 1000
#define TOKSIZE 300 /*BUG 4/20/82 was 128*/
#define DEFSIZE 1024
#define PBSIZE 1000
#define DEFINE 1
#define UNDEF 2
#define INCLUDE 3
#define IFDEF 4
#define IFNDEF 5
#define ELSE 6
#define ENDIF 7
#define IF 8
#define LINE 9
#define SKIP 0
#define NOSKIP 1
#define SOH '\01'
#define SSIZE 8
#define HSIZE 517 /* 3.4 made prime */
#define FSTACK 10
#define TRUE 1
#define FALSE 0
#define NDEFS 20
struct symbol {
char s_name[SSIZE];
char *s_def;
} symtab[HSIZE];
/*buffered I/O structure*/
struct ibuf {
int fd;
int nc;
char *bp;
char buffer[BUFSIZE];
} inbuf, outbuf;
/* command line define structure */
struct defstruc {
char *ptr;
char *value;
} defs[NDEFS];
struct stackstruc { /* [vlh] */
int ifd;
char ifile[13];
int lineno;
} filestack[FSTACK], *filep; /* stack of incl files, ptr to... */
#ifdef VERSADOS
#define NONEST 1
#define NOFORKS 1
#endif
#ifdef VMS
#define NONEST 1
#endif
#ifdef NONEST
struct ibuf holdbuf; /* alternate buffer, hold main file info */
#endif
int mfail; /*macro error flag*/
int skip; /*skipping current line*/
char *defap; /*pointer to available define area*/
char *defp; /*pointer to next avail define byte*/
int defcount; /*bytes left in define area*/
int defused; /*number of bytes used in define area*/
int defmax; /*maximum define area used*/
int pflag;
int asflag;
/*line to output after macro substitution*/
char line[LINESIZE+2]; /*line buffer*/
char *linep; /*current line pointer*/
int loverflow; /*line overflow flag*/
int lineno;
/*push back buffer*/
char pbbuf[PBSIZE]; /*push back buffer*/
char *pbp; /*push back pointer*/
int pbflag; /*checks for recursive definition*/
char null[]; /*used for undef'd symbols*/
char *lookup();
char *setend();
char *makecopy();
char *makecopy();
char *maketemp();
char *sbrk();
struct symbol *getsp();

View File

@@ -0,0 +1,6 @@
/* fake sysinfo call for PDP-11, returns as if MMU system */
sysinfo(flag,addr)
int flag, *addr;
{
*addr = 1;
}

View File

@@ -0,0 +1,16 @@
atoi(as)
char *as;
{
register int n, sign;
register char *s;
s = as;
while( *s==' ' || *s=='\n' || *s == '\t')
s++;
sign = 1;
if( *s == '+' || *s == '-' )
sign = (*s++=='+') ? 1 : -1;
for( n = 0; *s >= '0' && *s <= '9'; s++ )
n = (n * 10) + (*s - '0');
return( sign * n );
}

View File

@@ -0,0 +1 @@
char *compiled "@(#) preprocessor - Fri Mar 18 12:37 1983";

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
$ diff DECL.c drb0:[steve.cpm68k.c.fparser]DECL.c
$ diff EXPR.c drb0:[steve.cpm68k.c.fparser]EXPR.c
$ diff ICODE.c drb0:[steve.cpm68k.c.fparser]ICODE.c
$ diff INIT.c drb0:[steve.cpm68k.c.fparser]INIT.c
$ diff INTERF.c drb0:[steve.cpm68k.c.fparser]INTERF.c
$ diff LEX.c drb0:[steve.cpm68k.c.fparser]LEX.c
$ diff MAIN.c drb0:[steve.cpm68k.c.fparser]MAIN.c
$ diff STMT.c drb0:[steve.cpm68k.c.fparser]STMT.c
$ diff TABL.c drb0:[steve.cpm68k.c.fparser]TABL.c
$ diff VERSION.c drb0:[steve.cpm68k.c.fparser]VERSION.c

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,311 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
int bol 1;
int inittype;
int begseq;
/* int onepass; */
/*
This interfaces the Parser and the Code Generator, note that these
allow you to link together the Parser and the Code Generator.
*/
/* outbdata - set up for byte data*/
outbdata() /* returns - none*/
{
inittype = CHAR;
printf("\t.dc.b ");
}
/* outc - output a constant*/
outc(type,value) /* returns - none*/
int type;
int value;
{
if( type == CHAR )
outbdata();
else
outwdata();
printf("%d\n",value);
}
/* outwdata - set up for word data*/
outwdata() /* returns - none*/
{
inittype = INT;
printf("\t.dc.w ");
}
/* outdata - set up for data output*/
outdata() /* returns - none*/
{
inittype = INT;
printf("\t.data\n");
}
/* outldata - set up for long data output*/
outldata() /* returns - none*/
{
inittype = LONG;
printf("\t.data\n");
}
/* outfpdata - set up for floating point data output*/
outfpdata() /*[vlh] 3.4 returns - none*/
{
inittype = FLOAT;
printf("\t.data\n");
}
/* outbentry - outputs block/function entry code*/
outbentry(nlocs,nds,nas) /* returns - none*/
int nlocs; /* local size*/
int nds; /* number of D registers*/
int nas; /* number of A registers*/
{
if( !nds && !nas ) /* adjust for 1 arg*/
nlocs =+ 4;
printf("\tlink R14,#%d\n",-nlocs);
if( nds || nas ) {
printf("\tmovem.l R%d-R7",7-nds); /*7 for one arg*/
if( nas ) {
putchar('/');
printf("R%d-R13",14-nas);
}
printf(",-(sp)\n");
}
}
/* outbexit - output function exit code*/
outbexit(nds,nas) /* returns - none*/
int nds; /* number of D registers*/
int nas; /* number of A registers*/
{
if( nds || nas ) {
printf("\ttst.l (sp)+\n\tmovem.l (sp)+,"); /*1 arg stuff*/
if( nds ) {
printf("R%d-R7",8-nds);
if( nas )
putchar('/');
}
if( nas )
printf("R%d-R13",14-nas);
putchar('\n');
}
printf("\tunlk R14\n\trts\n");
}
/* outlocal - output local symbol for debugger*/
outlocal(type,sc,sym,val)
int type; /* local name type*/
int sc; /* storage type*/
char *sym; /* symbol name*/
int val;
{
switch( sc ) {
case STATIC:
if( notfunction(type) )
printf("\t~%.8s=L%d\n",sym,val);
break;
case REGISTER:
printf("\t~%.8s=R%d\n",sym,val);
break;
case AUTO:
printf("\t~%.8s=%d\n",sym,val);
break;
}
}
/* outswitch - output switch table info*/
outswitch(ncases,deflab,sp) /* returns - none*/
int ncases; /* number of cases in switch*/
int deflab; /* default label*/
struct swtch *sp; /* switch table pointer*/
{
register int vdif, val, hval, i, tlab;
register struct swtch *s;
val = sp->sw_value;
hval = sp[ncases-1].sw_value;
vdif = hval - val;
if( ncases <= 4 ) {
/*
*simple switch, do compares and brances, followed by branch to default
*/
for( s = sp; --ncases >= 0; s++ ) {
if( !s->sw_value )
printf("\ttst R0\n");
else
printf("\tcmp #%d,R0\n",s->sw_value);
printf("\tbeq L%d\n",s->sw_label);
}
outgoto(deflab);
}
else if( vdif > 0 && vdif <= ncases*3 ) {
/*jump switch, uses value in R0 to index into table of labels*/
if( val )
printf("\tsub #%d,R0\n",val);
tlab = nextlabel++;
printf("\tcmp #%d,R0\n\tbhi L%d\n",vdif,deflab); /*check for max*/
printf("\tasl #2,R0\n\tmove R0,R8\n\tadd.l #L%d,R8\n",tlab);
printf("\tmove.l (R8),R8\n\tjmp (R8)\n");
outdata();
outlab(tlab);
for( s = sp; val <= hval; val++ ) {
if( val == s->sw_value ) {
outclab(s->sw_label);
s++;
}
else
outclab(deflab);
}
outtext();
}
else {
/*
* direct switch, searches down table of values for match, if match
* found, branches to corresponding label in label table.
*/
tlab = nextlabel++;
printf("\text.l R0\n\tmove.l #L%d,R8\n\tmove #%d,R1\n",tlab,ncases);
i = nextlabel++;
outlab(i); /*loop label*/
printf("\tcmp.l (R8)+,R0\n\tdbeq R1,L%d\n",i);
printf("\tmove.l %d(R8),R8\n\tjmp (R8)\n",ncases*4);
outdata();
outlab(tlab);
for( s = sp, i = ncases; --i >= 0; s++ )
outlcon(s->sw_value);
outlcon(0); /* mark for default label*/
for( s = sp, i = ncases; --i >= 0; s++ )
outclab(s->sw_label);
outclab(deflab);
outtext();
}
}
outeof()
{
register int c;
v6flush(&sbuf);
v6flush(&obuf);
}
/* copysfile - copy string file to end of output file*/
copysfile(fname)
char *fname;
{
register int c;
close(sbuf.io_fd);
if( fopen(fname,&sbuf,0) < 0 ) /* 3rd arg for versados */
ferror("can't copy %s",fname);
while( (c=getc(&sbuf)) > 0 )
putc(c,&obuf);
v6flush(&obuf);
}
/* outword - output a word of data*/
outword(w) /* word expression*/
int w;
{
if( begseq )
putchar(',');
begseq++;
printf("%d",w);
}
/* outlong - output a long data*/
outlong(l) /* returns - none*/
long l; /* long data to output*/
{
outwdata();
outword(l.hiword);
outword(l.loword);
outendseq();
}
/* outfp - output floating point data*/
outfp(l) /*[vlh] 3.4 returns - none*/
long l; /* floating point data to output*/
{
outwdata();
outword(l.hiword);
outword(l.loword);
outendseq();
}
outendseq() /* returns - none*/
{
begseq = 0;
putchar('\n');
}
/*
* outtstr - output text string
* This outputs a string to the string file, this is used wherever
* you cannot output the string directly to data space, such as in
* the middle of expressions.
*/
outtstr(lab)
int lab;
{
char *savep;
int sbol;
savep = obp; /*save to restore later...*/
obp = &sbuf;
sbol = bol;
bol = 1;
printf("\tL%d:",lab);
outstr();
obp = savep;
bol = sbol;
}
/* outstr - output a string as a sequence of bytes*/
/* Outputs ".dc.b <byte1>,<byte2>,...,<0>*/
outstr()
{
register char *s;
register int i;
outbdata();
for( s = cstr, i = cstrsize; i > 0; i-- )
outword(*s++ & 0xff);
outendseq();
}
/*
* putchar - handle outputting to intermediate or error files
* This catches tabs to allow for the integration of the parser
* and code generator into one pass. By merely throwing away the
* tabs here, the output will be OK for the assembler.
*/
putchar(c)
char c;
{
if( !obp )
write(1,&c,1);
else if( c == '\t' ) {
if( bol ) /* not used && !onepass ) */
putc('(',obp); /*for code generator*/
}
else {
bol = (c == '\n');
putc(c,obp);
}
}

View File

@@ -0,0 +1,251 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "machine.h"
/*
* intermediate code operators
* 0=>EOF, special operator
*/
#define EOF 0
/*1-59=>operators that generate code (entries in code gen optab)*/
#define ADD 1
#define SUB 2
#define MULT 3
#define DIV 4
#define MOD 5
#define RSH 6
#define LSH 7
#define AND 8
#define OR 9
#define XOR 10
#define NOT 11
#define UMINUS 12
#define COMPL 13
#define PREDEC 14
#define PREINC 15
#define POSTDEC 16
#define POSTINC 17
#define ASSIGN 18
#define EQADD 19
#define EQSUB 20
#define EQMULT 21
#define EQDIV 22
#define EQMOD 23
#define EQRSH 24
#define EQLSH 25
#define EQAND 26
#define EQOR 27
#define EQXOR 28
#define FJSR 29
#define EQUALS 30
#define NEQUALS 31
#define GREAT 32
#define GREATEQ 33
#define LESS 34
#define LESSEQ 35
#define INT2L 36
#define LONG2I 37
/*machine dependent operators that generate code*/
#define BTST 38
#define LOAD 39
#define LMULT 40
#define LDIV 41
#define LMOD 42
#define LEQMULT 43
#define LEQDIV 44
#define LEQMOD 45
#define EQADDR 46
#define EQNOT 47
#define EQNEG 48
#define DOCAST 49
#define STASSIGN 50 /*[vlh]*/
#define LONG2F 51 /*[vlh] 3.4*/
#define FLOAT2L 52 /*[vlh] 3.4*/
#define INT2F 53 /*[vlh] 3.4*/
#define FLOAT2I 54 /*[vlh] 3.4*/
#define LCGENOP 55 /*change if adding more operators...*/
/*intermediate code operators that do not generate code*/
#define ADDR 60
#define INDR 61
#define LAND 62
#define LOR 63
#define QMARK 64
#define COLON 65
#define COMMA 66
#define CINT 67
#define CLONG 68
#define SYMBOL 69
#define AUTOINC 70
#define AUTODEC 71
#define CALL 72
#define NACALL 73
#define BFIELD 74
#define IFGOTO 75
#define INIT 76
#define CFORREG 77
#define DCLONG 78
#define CFLOAT 79 /*[vlh] 3.4*/
/*operators local to parser*/
#define CAST 80
#define SEMI 81
#define LCURBR 82
#define RCURBR 83
#define LBRACK 84
#define RBRACK 85
#define LPAREN 86
#define RPAREN 87
#define STRING 88
#define RESWORD 89
#define APTR 90
#define PERIOD 91
#define SIZEOF 92
#define MPARENS 93
#define FRETURN 94
#define STACKEND 100
/*data types*/
#define TYPELESS 0
#define CHAR 1
#define SHORT 2
#define INT 3
#define LONG 4
#define UCHAR 5
#define USHORT 6
#define UNSIGNED 7
#define ULONG 8
#define FLOAT 9
#define DOUBLE 10
/*data types local to parser*/
#define STRUCT 11
#define FRSTRUCT 12
#define LLABEL 13
/*type flags and definitions*/
#define TYPE 017
#define SUPTYP 060
#define ALLTYPE 077
#define POINTER 020
#define FUNCTION 040
#define ARRAY 060
#define SUTYPLEN 2
/*data registers*/
#define DREG0 0
#define DREG2 2
#define DREG3 3
#define DREG4 4
#define DREG5 5
#define DREG6 6
#define DREG7 7
#define AREG3 11
#define AREG4 12
#define AREG5 13
/*storage classes*/
#define AUTO 1
#define REGISTER 2
#define EXTERNAL 3
#define STATIC 4
#define REGOFF 5
#define EXTOFF 6
#define STATOFF 7
#define INDEXED 8
/*exclusively code generator storage classes*/
#define CINDR 9
#define CLINDR 10
#define CFINDR 11 /* [vlh] 3.4 */
/*exclusively parser storage classes*/
#define STRPROTO 9
#define PDECLIST 10
#define PARMLIST 11
#define BFIELDCL 12
#define UNELCL 13
#define STELCL 14
/*opinfo table bits*/
#define OPPRI 077
#define OPBIN 0100
#define OPLVAL 0200
#define OPREL 0400
#define OPASSIGN 01000
#define OPLWORD 02000
#define OPRWORD 04000
#define OPCOM 010000
#define OPRAS 020000
#define OPTERM 040000
#define OPCONVS 0100000
/*68000 definitions*/
#define PTRSIZE 4
#define INTSIZE 2
#define LONGSIZE 4
#define SSIZE 8 /* chars per symbol */
#define TRUE 1
#define FALSE 0
#define TABC '\t' /* tab character */
#define EOLC '\n' /* end of line character */
#define BITSPBYTE 8
/*operator class priorities*/
#define TRMPRI 0 /* terminal nodes */
#define RPNPRI 1 /* ) and ] */
#define CALPRI 2 /* in-stack call, ( or [ */
#define COLPRI 3 /* init or case priority for : or , */
#define STKPRI 4 /* priority of end of stack */
#define COMPRI 5 /* normal priority for , */
#define ASGPRI 6 /* =, +=, -=, *=, /=, %=, ... */
#define QMKPRI 7 /* ?: */
#define LORPRI 8 /* || */
#define LNDPRI 9 /* && */
#define ORPRI 10 /* |, ! */
#define ANDPRI 11 /* & */
#define EQLPRI 12 /* ==, != */
#define RELPRI 13 /* >, <, >=, <= */
#define SHFPRI 14 /* <<, >> */
#define ADDPRI 15 /* +, - */
#define MULPRI 16 /* *, /, % */
#define UNOPRI 17 /* ++, --, &, *, -, ~, sizeof */
#define LPNPRI 18 /* ., ->, [, (, function call */
#define PSTPRI 19 /* in-stack post--, post++ */
struct io_buf {
int io_fd;
int io_nc;
char *io_p;
char io_b[512];
};
#ifdef PDP11
struct { short hiword; short loword; };
#endif
#ifdef MC68000
struct { short hiword; short loword; };
#endif
#ifdef VAX
struct { short loword; short hiword; };
#endif
#define EXPSIZE 1024
int exprarea[EXPSIZE];
/* v6io buffer declaration */
#define BLEN 512
struct iobuf{
int fildes;
int nunused;
char *xfree;
char buff[BLEN];
};

View File

@@ -0,0 +1,323 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*
C68 Parser - include file
*/
#include "icode.h"
/*symbol attribute fields*/
#define SRESWORD 001 /*is symbol a reserved word?*/
#define SGLOBAL 002 /*is symbol global?*/
#define STYPEDEF 004 /*typedef declaration?*/
#define SDEFINED 010 /*symbol defined?*/
/*reserved words*/
#define R_AUTO 1
#define R_BREAK 2
#define R_CASE 3
#define R_CHAR 4
#define R_CONTINUE 5
#define R_DO 6
#define R_DEFAULT 7
#define R_DOUBLE 8
#define R_GOTO 9
#define R_ELSE 10
#define R_EXTERNAL 11
#define R_FLOAT 12
#define R_FOR 13
#define R_IF 14
#define R_INT 15
#define R_LONG 16
#define R_REGISTER 17
#define R_RETURN 18
#define R_SHORT 19
#define R_SIZEOF 20
#define R_STATIC 21
#define R_STRUCT 22
#define R_SWITCH 23
#define R_TYPEDEF 24
#define R_UNION 25
#define R_UNSIGNED 26
#define R_WHILE 27
/*
* mixed-mode conversions, entries in 2-d array indexed by:
* (int,unsn,long,doub,ptr)
*/
#define INT_CHAR 1
#define UNSN_CHAR 1
#define LONG_CHAR 1
#define DOUB_CHAR 1
#define PTR_CHAR 1
#define INT_UNSN 0 /*no conversion is generated*/
#define INT_LONG 2
#define INT_DOUB 3
#define INT_PTR 4
#define UNSN_INT 0 /*no conversion is generated*/
#define UNSN_LONG 6
#define UNSN_DOUB 7
#define UNSN_PTR 8
#define LONG_INT 9
#define LONG_UNSN 10
#define LONG_DOUB 11
#define LONG_PTR 12
#define DOUB_INT 13
#define DOUB_UNSN 14
#define DOUB_LONG 15
#define PTR_INT 16
#define PTR_UNSN 17
#define PTR_LONG 18
#define PTR_PTR 19
#define BADCONV 20
/* miscellaneous constants */
#define OPSSIZE 40 /*operator stack size*/
#define OPDSIZE 80 /*operand stack size*/
#define HSIZE 517 /*hash table size, 3.4 made prime */
#define SYMSIZE 1024 /*size to alloc for symbol structures*/
#define SWSIZE 256 /*max no. of cases in a switch*/
#define DSIZE 1000 /*dimension table size*/
#define BITSPWORD 16 /*bits per word*/
#define AREGLO 010 /*A reg flag*/
#define HICREG 2 /*highest reg # used for code generation*/
#define BITSPCHAR 8 /*bits per char*/
#define CHRSPWORD 2 /*chars per word*/
#define STRSIZE 300 /*max string length*/
#define NFARGS 40 /*max no. of args to function*/
#define NFRSTR 20 /*max no. of forward ref struct proto*/
/*symbol table node*/
struct symbol {
char s_attrib; /* defined, resword, global, typedef */
char s_sc; /* auto, static, external, register */
int s_type; /* 4bits specified, 2 bit fields for ptr... */
int s_dp; /* index into dimension table */
int s_ssp; /* dimension table/function arg table */
int s_offset; /* offset inside of structure */
char s_symbol[SSIZE]; /* symbol identifier, to SSIZE chars */
struct symbol *s_struc; /* if struct, ptr to parent (sys III) */
struct symbol *s_next; /* next symbol table entry */
};
/*expression tree operator node*/
struct tnode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
struct tnode *t_left;
struct tnode *t_right;
};
/*expression tree node for symbol - only keeps location*/
struct symnode {
int t_op;
int t_type; /*data type of symbol*/
int t_dp; /*dimension pointer of symbol*/
int t_ssp; /*structure size index to dtab*/
int t_sc; /*storage class of symbol*/
int t_offset; /*offset of symbol*/
int t_label;
};
/*expressioon tree node for external symbol - need to keep name*/
struct extnode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
int t_sc;
int t_offset;
int t_reg;
int t_symbol[SSIZE]; /*symbol name*/
};
/*expression tree node for integer constant*/
struct conode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
int t_value; /*constant value*/
};
struct lconode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
long t_lvalue; /*constant value*/
};
struct swtch {
int sw_label;
int sw_value;
} swtab[SWSIZE]=0;
/*operator and operand stack used by expr*/
struct ops { /*operator stack*/
int o_op; /*operator*/
int o_pri; /*priority*/
} opstack[OPSSIZE]=0, *opp=0;
char *opdstack[OPDSIZE]=0; /*operand stack*/
char **opdp=0; /*operand stack pointer*/
char *opap=0; /*ptr to next available loc in exprarea*/
struct tnode *frp=0; /*pointer to function return info node*/
int cswp=0; /*current low switch table index*/
int clabel=0; /*continue label*/
int blabel=0; /*break label*/
int rlabel=0; /*return label*/
int dlabel=0; /*default label*/
int lineno=0; /*current line number of input*/
int errcnt=0; /*count of errors*/
int inclflag=0; /*in include file, don't incr line #'s*/
int inclline=0; /*[vlh]line# in incl file for err rpting*/
char inclfile[13]=0; /*[vlh]include filename for err rpting*/
int equalstop=0; /*stop lex at '=', used for external init*/
int commastop=0; /*stop parse @ comma(used for const expr)*/
int colonstop=0; /*stop parse @ colon(used for case value)*/
int instruct=0; /*set when in structure declaration*/
int smember=0; /*set when seen . or ->*/
int infunc=0; /*set when in function body*/
int tdflag=0; /*declaration is a typedef proto*/
char *tdp=0; /*points to typedef prototype*/
int localsize=0; /*length of local variables*/
int naregs=0; /*keeps track of ptr registers alloc'd*/
int ndregs=0; /*keep track of data registers alloc'd*/
int loadreg=0; /*need to load registers...*/
int boffset=0; /*current bit offset in structure*/
int eflag=0; /*[vlh] 3.4 IEEE floats */
int fflag=0; /*[vlh] 3.4 FFP floats */
int xflag=0; /*translate int's to long's*/
int wflag=0; /*[vlh] don't generate warning mesgs*/
int reducep=0; /*[vlh] if(procid); reduction*/
int peektok=0; /*peeked at token*/
/*dimension table*/
long dtab[DSIZE]=0; /* [vlh] 3.4 int => long */
int cdp=0; /*next entry in dtab to alloc*/
/*lexical analyzer values*/
int cvalue=0; /*current token value if keyword or CINT*/
int cstrsize=0; /*current string size*/
long clvalue=0; /*current token value if long constant*/
struct symbol *csp=0; /*current token symbol ptr if SYMBOL*/
char cstr[STRSIZE]=0; /*current token value if CSTRING*/
struct symbol *dsp=0; /*declarator symbol pointer*/
/* -1 -> not instruct, 0 -> unnamed struct */
struct symbol *strucptr[10]=0; /*[vlh] ptrs to struc symbols*/
/*function argument table, used to collect function parameters*/
struct farg {
struct symbol *f_sp;
int f_offset;
} fargtab[NFARGS]=0;
/*forward referenced structure prototype names*/
struct symbol *frstab[NFRSTR]=0;
int frstp=0;
/*output buffers for intermediate code and strings*/
struct io_buf obuf=0, sbuf=0, ibuf=0, *obp=0;
#define stypedef(sp) (sp->s_attrib&STYPEDEF)
#define walign(add) ((add+1)&(~1))
#define array(type) ((type&SUPTYP)==ARRAY)
#define function(type) ((type&SUPTYP)==FUNCTION)
#define pointer(type) ((type&SUPTYP)==POINTER)
#define notarray(type) ((type&SUPTYP)!=ARRAY)
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
#define notpointer(type) ((type&SUPTYP)!=POINTER)
#define btype(type) (type&TYPE)
#define suptype(type) (type&SUPTYP)
#define alltype(type) (type&(SUPTYP|TYPE))
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
#define relop(op) ((opinfo[op]&OPREL)!=0)
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
#define binop(op) ((opinfo[op]&OPBIN)!=0)
#define unaryop(op) ((opinfo[op]&OPBIN)==0)
#define leaf(op) ((opinfo[op]&OPTERM)!=0)
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
#define oppriority(op) (opinfo[op]&OPPRI)
#define makeiop(op) (op|(0254<<8))
/* checks for symbol with structure element storage class */
#define isstel(tp) (tp->t_op==SYMBOL && (sesc(tp)))
#define sesc(t) (t->t_sc==STELCL||t->t_sc==UNELCL||t->t_sc==BFIELDCL)
/* peek at next token, if not read token put back, else delete */
/* 1 if matched, 0 otherwise */
#define peek(tok) ( (peektok=gettok()) == tok )
#define outcommon(sym,size) printf("\t.comm _%.8s,%ld\n",sym,size)
#define outgoto(lab) if( lab > 0 ) printf("\tbra L%d\n",lab)
/* change to text segment */
#define outtext() printf("\t.text\n")
/* change segment to bss */
#define outbss() printf("\t.bss\n")
/* output global symbol references */
#define outextdef(sym) printf("\t.globl _%.8s\n",sym)
/* outputs reserved memory [vlh] 3.4 %d => %ld */
#define outresmem(size) printf("\t.ds.b %ld\n",size)
/* output padding for word alignments */
#define outpad() printf("\t.even\n")
/* output long constant to assembler */
#define outlcon(val) printf("\t.dc.l %d\n",val)
/* output label constant */
#define outclab(lab) printf("\t.dc.l L%d\n",lab)
/* output a label */
#define outlab(lab) printf("\tL%d:",lab)
/* output function label */
#define outflab(sym) printf("\t_%.8s:\n\t~~%.8s:\n",sym,sym)
/* output data label */
#define outdlab(sym) printf("\t_%.8s:\n",sym)
/*functions returning pointers*/
char *expr();
char *talloc();
char *tnalloc();
char *enalloc();
char *snalloc();
char *cnalloc();
char *lcnalloc();
char *fpcnalloc();
char *popopd();
char *cvopgen();
char *arrayref();
char *funcref();
char *install();
char *lookup();
char *balpar();
char *sbrk();
long initlist();
long dsize();
long psize();
long dodecl();
long dlist();
long getdec();
long gethex();
long getoct();
long getfp();
long toieee();
long toffp();
int inittype=0;
int strassign=0;
int begseq=0;
#define EXPSIZE 1024
int exprarea[EXPSIZE]=0;
int opdontop=0;
int pbchar=0;
struct symbol *symbols=0;
struct symbol *symtab[HSIZE]=0;

View File

@@ -0,0 +1,106 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
int bol;
outinit(tp,type) /* returns - none*/
struct tnode *tp;
{
outexpr(tnalloc(INIT,type,0,0,tp));
}
outcforreg(tp)
struct tnode *tp;
{
outexpr(tnalloc(CFORREG,tp->t_type,0,0,tp));
}
outifgoto(tp,dir,lab)
struct tnode *tp;
int dir;
int lab;
{
outexpr(tnalloc(IFGOTO,dir,lab,0,tp));
}
outexpr(tp)
struct tnode *tp;
{
if( !bol )
putchar('\n');
printf(".%x\n",lineno);
outtree(tp);
}
outtree(tp)
struct tnode *tp;
{
if( !tp )
return;
printf("%x.%x",tp->t_op,tp->t_type);
switch( tp->t_op ) {
case CINT:
printf(".%x\n",tp->t_value);
break;
case CLONG:
printf(".%x.%x\n",tp->t_lvalue.hiword,tp->t_lvalue.loword);
break;
case CFLOAT: /*[vlh] 3.4*/
printf(".%x.%x\n",tp->t_lvalue.hiword,tp->t_lvalue.loword);
break;
case SYMBOL:
printf(".%x",tp->t_sc);
if( tp->t_sc == EXTERNAL )
printf(".%.8s\n",tp->t_symbol);
else
printf(".%x\n",tp->t_offset);
break;
case 0:
putchar('\n');
break;
case IFGOTO:
case BFIELD:
printf(".%x\n",tp->t_dp);
outtree(tp->t_left);
break;
default:
putchar('\n');
outtree(tp->t_left);
if( binop(tp->t_op) )
outtree(tp->t_right);
break;
}
}
/* snalloc - symbol node allocation*/
/* Allocates a tree symbol node and sets the info in it*/
char *snalloc(type,sc,off,dp,ssp) /* returns pointer to node alloc'ed*/
int type; /* symbol type*/
int sc; /* storage class*/
int off; /* offset*/
int dp; /* dimension pointer or other info*/
int ssp; /* structure size pointer*/
{
register struct symnode *snp;
snp = talloc(sizeof(*snp));
snp->t_op = SYMBOL;
snp->t_sc = sc;
snp->t_type = type;
snp->t_dp = dp;
snp->t_ssp = ssp;
snp->t_offset = off;
return(snp);
}

View File

@@ -0,0 +1,827 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
#define SOI '\01'
#define STEL HSIZE/2
/*
* the following are the cases within gettok, all other cases are
* single character unambiguous tokens. Note that we need to take
* special care not to interfere with the single character unambiguous
* operators, this is why there is a gap between WHITSP and EXCLAM.
*/
#define BADC 0 /*bad character*/
#define WHITSP 101 /*white space*/
#define EXCLAM 102 /*exlamation point*/
#define DQUOTE 103 /*double quote*/
#define PERCNT 104 /*percent sign*/
#define AMPER 105 /*ampersand*/
#define SQUOTE 106 /*single quote*/
#define STAR 107 /*asterisk or mult sign*/
#define PLUS 108 /*plus sign*/
#define MINUS 109 /*minus sign*/
#define SLASH 110 /*divide sign*/
#define DIGIT 111 /*0..9*/
#define LCAROT 112 /*less than sign*/
#define EQUAL 113 /*equals sign*/
#define RCAROT 114 /*greater than*/
#define ALPHA 115 /*a..z,A..Z and underbar*/
#define CAROT 116 /*^*/
#define BAR 117 /*vertical bar*/
char ctype[] {
BADC, BADC, BADC, BADC, BADC, BADC, BADC, BADC,
BADC, WHITSP, WHITSP, WHITSP, WHITSP, WHITSP, BADC, BADC,
BADC, BADC, BADC, BADC, WHITSP, BADC, BADC, BADC,
BADC, BADC, BADC, BADC, BADC, BADC, BADC, BADC,
WHITSP, EXCLAM, DQUOTE, BADC, BADC, PERCNT, AMPER, SQUOTE,
LPAREN, RPAREN, STAR, PLUS, COMMA, MINUS, PERIOD, SLASH,
DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
DIGIT, DIGIT, COLON, SEMI, LCAROT, EQUAL, RCAROT, QMARK,
BADC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, LBRACK, BADC, RBRACK, CAROT, ALPHA,
BADC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, LCURBR, BAR, RCURBR, COMPL, BADC
};
/*key word table*/
struct resword {
char *r_name;
int r_value;
} reswords[] {
"auto", R_AUTO,
"break", R_BREAK,
"case", R_CASE,
"char", R_CHAR,
"continue", R_CONTINUE,
"do", R_DO,
"default", R_DEFAULT,
"double", R_DOUBLE,
"goto", R_GOTO,
"else", R_ELSE,
"extern", R_EXTERNAL,
"float", R_FLOAT,
"for", R_FOR,
"if", R_IF,
"int", R_INT,
"long", R_LONG,
"register", R_REGISTER,
"return", R_RETURN,
"short", R_SHORT,
"sizeof", R_SIZEOF,
"static", R_STATIC,
"struct", R_STRUCT,
"switch", R_SWITCH,
"typedef", R_TYPEDEF,
"union", R_UNION,
"unsigned", R_UNSIGNED,
"while", R_WHILE,
0,
};
#define SELFMOD 0200
#define ASMASK 0177
/*
* this table is used to check for an operator after an equals sign.
* note that =-, =* and =& may all have an ambiguous meaning if not
* followed by a space, this is checked for in gettok.
*/
char asmap[] {
EQUALS, /*==*/
EQADD, /*=+*/
EQSUB|SELFMOD, /*=-*/
EQMULT|SELFMOD, /*=**/
EQDIV, /*=/*/
EQOR, /*=|*/
EQAND|SELFMOD, /*=&*/
EQXOR, /*=^*/
EQMOD, /*=%*/
};
char escmap[] "\b\n\r\t";
int pbchar; /*pushed back character*/
struct symbol *symtab[HSIZE]; /*hash table*/
struct symbol *symbols; /*pointer to next avail symbol buf*/
int nsyms; /*number of symbol bufs in memory*/
/*
* getdec - get a decimal number
* Uses Horner's method to get decimal number. Note that
* multiplication by 10 is cleverly programmed as two shifts and two
* adds. This is because long multiplies are painful on both the
* PDP-11 and 68000.
*/
long getdec() /* returns number*/
{
register long value;
register char c;
for( value = 0; (c=ngetch()) >= '0' && c <= '9'; ) {
value =<< 1; /*value = value*2*/
value =+ value << 2; /*value*2 + value*8 = value*10*/
value =+ (c-'0');
}
putback(c);
return(value);
}
#define BIAS 127L
#define EXPSIZ 4
#define FRACSIZ 20
long toieee();
long toffp();
float power10();
/*
* getfp - get a floating point constant
* we've already gotten the significant digits, now build a
* floating point number with possible decimal digits and an
* exponent, yields an ieee formated floating point number,
* unless the fflag is on, then a ffp constant is generated.
*/
long
getfp(significant)
long significant;
{
register char c;
register long places; /* decimal places */
int esign;
float exp, fraction, fp;
places = 0L; esign = 0; fraction = significant; exp = 0.0;
if ((c = ngetch()) == '.') /* get decimal places */
for( ; (c=ngetch()) >= '0' && c <= '9';) {
fraction = fraction * 10.0;
fraction = fraction + (c - '0');
places++;
}
if (c=='e' || c=='E') { /* exponent exists */
esign = (peekis('-')) ? 1 : (peekis('+')) ? 0 : 0;
for( ; (c=ngetch()) >= '0' && c <= '9'; ) {
exp = exp * 10.0;
exp = exp + (c - '0');
}
}
putback(c);
if (esign)
exp = -exp;
places = exp - places;
fp = fraction * power10(places);
if (fflag)
return( toffp(fp) );
else
return ( toieee(fp) );
}
float
power10(pwr) /* used by getfp, 10^pwr */
long pwr;
{
float f;
if (pwr < 0L) /* negative power */
for (f = 1.0; pwr < 0L; pwr++)
f = f / 10.0;
else /* positive power */
for (f = 1.0; pwr > 0L; pwr--)
f = f * 10.0;
return(f);
}
long
toffp(f) /* converts current machine float to ffp rep */
float f;
{
register long exp;
register int sign, count;
long l;
if (f == 0.0)
return(0L);
if (f < 0.0) {
sign = 1;
f = -f;
}
else
sign = 0;
exp = 0L;
for( ; f >= 1.0; f = f / 2.0)
exp++;
for( ; f < 0.5; f = f * 2.0)
exp--;
f = f * 16777216.0; /* 2 ^ 24 */
l = f;
l =<< 8;
if (sign)
l =| 0x80;
exp =+ 0x40;
l =| (exp & 0x7f);
return(l);
}
long
toieee(f) /* converts current machine float to ieee rep */
float f;
{
register long exp;
register int sign, count;
long l;
if (f == 0.0)
return(0L);
if (f < 0.0) {
sign = 1;
f = -f;
}
else
sign = 0;
exp = 0L;
for( ; f >= 2.0; f = f / 2.0)
exp++;
for( ; f < 1.0; f = f * 2.0)
exp--;
f = f - 1.0;
f = f * 8388608.0; /* 2 ^ 23 */
l = f;
if (sign)
l =| 0x80000000;
exp = (exp + BIAS)<<23;
l =| (exp & 0x7f800000);
return(l);
}
#define toupper(c) ((c) & ~32)
/* gethex - get an hexidecimal number*/
/* Uses Horner's method to get hexidecimal number*/
long gethex() /* returns number*/
{
register long value;
register char c, ch;
value = 0;
while( 1 ) {
if( (c=ngetch()) >= '0' && c <= '9' )
c =- '0';
else if((ch=toupper(c)) >= 'A' && ch <= 'F' ) /* [vlh] */
c = ch - ('A'-10);
else
break;
value = (value<<4) + c;
}
putback(c);
return(value);
}
/* getoct - get an octal number*/
/* Uses Horner's method to get octal number*/
long getoct(flag) /* returns number*/
int flag; /* string flag 1=>in string, else 0*/
{
register long value;
register char c;
register int count;
count = 0;
for( value = 0; (c=ngetch()) >= '0' && c <= '7'; ) {
if( flag && ++count > 3 )
break;
value = (value<<3) + (c-'0');
}
putback(c);
return(value);
}
/*
* gettok - get next token from input
* Checks pushed-packed token buffer, supresses / * * / comments,
* folds multiple character special symbols into single word token.
*/
gettok() /* returns token type*/
{
register int c, nextc, i;
register char *p;
register long value;
char sym[SSIZE];
if( peektok ) {
i = peektok;
peektok = 0;
return(i);
}
while( (c=ngetch()) != EOF ) {
switch(ctype[c]) {
case BADC: /*bad character*/
error("invalid character");
break;
case SEMI:
cvalue = 0; /* [vlh] not reserved word... */
default:
return( ctype[c] );
case WHITSP: /*skip all white space*/
break;
case EXCLAM: /*!= or !*/
return( peekis('=') ? NEQUALS : NOT );
case DQUOTE: /*quoted string*/
getstr(cstr,STRSIZE,'"');
cvalue = nextlabel++;
return(STRING);
case PERCNT: /*%= or %*/
return( peekis('=') ? EQMOD : MOD );
case AMPER: /*&=, && or &*/
return( peekis('=') ? EQAND : peekis('&') ? LAND : AND );
case SQUOTE: /*character constant*/
getstr(cstr,STRSIZE,'\'');
if( cstrsize > CHRSPWORD+1 ) {
error("character constant too long");
cstrsize = CHRSPWORD + 1;
}
cvalue = 0;
for( p = cstr; --cstrsize > 0; ) {
cvalue =<< BITSPCHAR;
cvalue =| (*p++ & 0377);
}
return(CINT);
case STAR: /**= or **/
return( peekis('=') ? EQMULT : MULT );
case PLUS: /*+=, ++ or +*/
return( peekis('=') ? EQADD : peekis('+') ? PREINC : ADD );
case MINUS: /*-=, --, -> or -*/
return( peekis('=') ? EQSUB : peekis('-') ? PREDEC :
peekis('>') ? APTR : SUB );
case SLASH: /*/ *..* /, //..., /= or /*/
if( peekis('*') ) {
while( (c=ngetch()) != EOF )
if( c == '*' && peekis('/') )
break;
if( c == EOF ) {
error("no */ before EOF");
return(EOF);
}
continue;
}
if( peekis('/') ) {
while( (c=ngetch()) != EOF && c != EOLC )
;
continue;
}
return( peekis('=') ? EQDIV : DIV );
case DIGIT: /*number constant (long or reg)*/
i = 0; /*flags if long constant*/
if( c != '0' ) {
putback(c);
dofp:
value = getdec();
if ((c=ngetch())=='.' || c=='e' || c=='E') { /*[vlh] 3.4 */
putback(c);
clvalue = getfp(value);
return(CFLOAT);
}
putback(c);
if( value > 32767 || value < -32768 )
i++;
}
else if( peekis('x') || peekis('X') ) {
value = gethex();
if( value < 0 || value >= 0x10000L )
i++;
}
else {
if (peekis('.')) {
putback('.');
goto dofp;
}
value = getoct(0);
if( value < 0 || value >= 0x10000L )
i++;
}
if( peekis('l') || peekis('L') || i ) {
clvalue = value;
return(CLONG);
}
cvalue = value;
return(CINT);
case LCAROT: /*<=, <<, <<= or <*/
return( peekis('=') ? LESSEQ : peekis('<') ?
(peekis('=') ? EQLSH : LSH) : LESS );
case EQUAL: /*==, =<<, =>>, =+, ..., =*/
if( peekis('<') ) {
if( peekis('<') )
return(EQLSH);
}
else if( peekis('>') ) {
if( peekis('>') )
return(EQRSH);
}
else if( (i=index("=+-*/|&^%",(c=ngetch()))) >= 0 ) {
i = asmap[i];
if( i & SELFMOD ) {
if( (nextc=ngetch()) != ' ' )
if (!wflag) /*[vlh] old fashion initialization*/
error("=%c assumed",c);
putback(nextc);
}
return( i & ASMASK );
}
else
putback(c);
return(ASSIGN);
case RCAROT: /*>=, >>, >>= or >*/
return( peekis('=') ? GREATEQ : peekis('>') ?
(peekis('=') ? EQRSH : RSH) : GREAT );
case ALPHA: /*[A-Za-z][A-Za-z0-9]**/
p = &sym[0];
i = SSIZE;
for(; ctype[c] == ALPHA || ctype[c] == DIGIT; c=ngetch(),i-- )
if( i > 0 )
*p++ = c;
if( i > 0 )
*p = '\0';
putback(c);
csp = lookup(sym);
if( csp->s_attrib & SRESWORD ) {
cvalue = csp->s_offset;
return(RESWORD);
}
smember = 0;
return(SYMBOL);
case CAROT: /*^= or ^*/
return( peekis('=') ? EQXOR : XOR );
case BAR: /*|=, || or |*/
return( peekis('=') ? EQOR : peekis('|') ? LOR : OR );
}
}
return(EOF);
}
/*
* peekis - peeks at next character for specific character
* Gets next (possibly pushed back) character, if it matches
* the given character 1 is returned, otherwise the character
* is put back.
*/
peekis(tc) /* returns 1 if match, 0 otherwise*/
int tc; /* test character*/
{
register int c;
if( (c=ngetch()) == tc )
return(1);
putback(c);
return(0);
}
/* ngetch - get a possibly pushed back character*/
/* Checks pbchar variable, returns it if non-zero, handles counting*/
/* of new lines and whether you are in an include or not.*/
ngetch() /* returns character read or EOF*/
{
register int c;
register char *ifile;
if( pbchar ) {
c = pbchar;
pbchar = 0;
}
else if( (c=getc(&ibuf)) == EOLC ) {
if( inclflag )
inclflag = 0;
else
lineno++;
}
else if( c == SOI) { /*[vlh]add incl filename & line # */
inclflag++;
ifile = &inclfile;
while ((c=getc(&ibuf)) != SOI)
*ifile++ = c&0377;
*ifile = 0;
inclline = getdec() & 077777;
c = ' ';
}
else if( c < 0 )
c = EOF;
return(c);
}
/*
* peekc - peek at the next non-whitespace character after token
* This allows for the problem of having to look at two tokens
* at once. The second token is always a semi-colon or colon,
* so we only look at the single character, rather than going
* thru gettok.
*/
peekc(tc) /* returns 1 if match, 0 otherwise*/
int tc; /* character to look for*/
{
register int c;
while( ctype[(c=ngetch())] == WHITSP) ;
if( c == tc )
return(1);
putback(c);
return(0);
}
/* putback - puts back a single character*/
/* Checks pbchar for error condition.*/
putback(c) /* returns - none*/
int c;
{
if( pbchar )
error("too many chars pushed back");
else
pbchar = c;
}
/* getstr - get a quoted (single or double) character string*/
/* Gets specified number of characters, handling escapes.*/
getstr(str,nchars,endc) /* returns - none*/
char *str; /* pointer to string buffer*/
int nchars; /* max number of characters*/
char endc; /* ending string character*/
{
register char *p;
register int i;
register int c;
register int j;
cstrsize = 1;
p = str;
for( i = nchars; (c=ngetch()) != endc; i-- ) {
if( c == EOF || c == EOLC ) {
error("string cannot cross line");
break;
}
if( c == '\\' ) {
if( (c=ngetch()) >= '0' && c <= '7' ) {
putback(c);
if( (c=getoct(1)) < 0 || c > 255 ) {
error("bad character constant");
continue;
}
}
else if( (j=index("bnrt",c)) >= 0 )
c = escmap[j];
else if( c == EOLC ) /*escape followed by nl->ignore*/
continue;
}
if( i > 0 ) { /*room left in string?*/
cstrsize++;
*p++ = c;
}
else if( !i ) /*only say error once...*/
error("string too long");
}
if( i <= 0 ) /*string overflow?*/
p--;
*p = '\0';
}
/* syminit - initialize the symbol table, install reswords*/
/* Goes thru the resword table and installs them into the symbol*/
/* table.*/
syminit() /* returns - none*/
{
register struct resword *rp;
for( rp = &reswords[0]; rp->r_name != 0; rp++ )
install(rp->r_name,SRESWORD|SDEFINED,rp->r_value);
}
/* install - install a symbol in the symbol table*/
/* Allocates a symbol entry, copies info into it and links it*/
/* into the hash table chain.*/
char *install(sym,attrib,offset) /* returns pointer to symbol struct*/
char *sym; /* symbol to install*/
int attrib; /* attribues of symbol*/
int offset; /* symbol offset (resword value)*/
{
register struct symbol *sp;
register int i;
while( !(sp=symbols) ) {
if( !(sp=sbrk(SYMSIZE)) )
ferror("symbol table overflow");
for( i = SYMSIZE/(sizeof *symbols); --i >= 0; ) {
sp->s_next = symbols;
symbols = sp++;
}
}
symbols = sp->s_next;
sp->s_attrib = attrib;
sp->s_sc = 0; sp->s_type = 0; sp->s_dp = 0; sp->s_ssp = 0;
sp->s_offset = offset;
sp->s_struc = (instruct) ? strucptr[smember+instruct] : 0;
symcopy(sym,sp->s_symbol); /*copy symbol to symbol struct*/
i = symhash(sym,instruct|smember); /*link into chain list*/
sp->s_next = symtab[i];
symtab[i] = sp;
return(sp);
}
/* lookup - looks up a symbol in symbol table*/
/* Hashes symbol, then goes thru chain, if not found, then*/
/* installs the symbol.*/
char *lookup(sym) /* returns pointer to symbol buffer*/
char *sym; /* pointer to symbol*/
{
register struct symbol *sp, *hold;
register char *p;
int exact; /* same name, diff type or offset */
p = sym;
for( sp = symtab[symhash(p,0)]; sp != 0; sp = sp->s_next )
if((sp->s_attrib&(SRESWORD|STYPEDEF)) && symequal(p,sp->s_symbol))
return(sp);
if (!(smember|instruct)) { /*[vlh]*/
for( sp=symtab[symhash(p,0)]; sp!=0; sp=sp->s_next )
if( symequal(p,sp->s_symbol) ) return(sp);
}
else { /* doing a declaration or an expression */
hold = 0; exact = 0;
for( sp=symtab[symhash(p,instruct|smember)]; sp!=0; sp=sp->s_next )
if( symequal(p,sp->s_symbol) )
if (symsame(sp,hold,&exact)) return(sp);
else if (!hold && !exact) hold = sp;
if (hold && !exact) return(hold);
}
return(install(p,0,0));
}
/* freesyms - frees all local symbols at end of function declaration*/
/* Searches thru symbol table, deleting all symbols marked as locals*/
freesyms() /* returns - none*/
{
register int i, tinfo;
register struct symbol *sp, *tp, *nextp, **htp;
for( htp = &symtab[0], i = HSIZE; --i >= 0; htp++ )
for( tp = 0, sp = *htp; sp != 0; sp = nextp ) {
nextp = sp->s_next;
if( !(sp->s_attrib&SDEFINED) ) {
error("undefined label: %.8s",sp->s_symbol);
sp->s_attrib =| SDEFINED;
}
if( sp->s_attrib & (SGLOBAL|SRESWORD) )
tp = sp;
else {
if( tp )
tp->s_next = sp->s_next;
else
*htp = sp->s_next;
sp->s_next = symbols;
symbols = sp;
}
}
}
/* chksyms - checks symbol table for undefined symbols, etc.*/
/* Goes thru the symbol table checking for undeclared forward*/
/* referenced structures, and outputs local symbols for debugger.*/
chksyms() /* returns - none*/
{
register struct symbol **htp, *sp;
register int i, sc;
for( htp = &symtab[0], i = HSIZE; --i >= 0; htp++ )
for( sp = *htp; sp != 0; sp = sp->s_next ) {
sc = sp->s_sc;
if(sc!=0 && sp->s_ssp>=0 && (btype(sp->s_type))==FRSTRUCT) {
sp->s_ssp = frstab[sp->s_ssp]->s_ssp; /* 3.4 ssp>0 */
sp->s_type = (sp->s_type&~TYPE) | STRUCT;
}
if( sc == PDECLIST ) {
error("not in parameter list: %.8s",sp->s_symbol);
sp->s_sc = AUTO;
}
if( infunc )
outlocal(sp->s_type,sp->s_sc,sp->s_symbol,sp->s_offset);
}
}
/* symhash - compute hash value for symbol*/
/* Sums the symbols characters and takes that modulus the hash table*/
/* size.*/
symhash(sym,stel) /* returns hash value for symbol*/
char *sym; /* pointer to symbol*/
int stel; /* structure element flag*/
{
register char *p;
register int hashval, i;
hashval = (stel ? STEL : 0 );
for( p = sym, i = SSIZE; *p != '\0' && i > 0; i-- )
hashval =+ *p++;
return( hashval % HSIZE );
}
/* symequal - check for symbol equality*/
/* Does comparison between two symbols.*/
symequal(sym1,sym2) /* returns 1 if equal, 0 otherwise*/
char *sym1; /* pointer to first symbol*/
char *sym2; /* pointer to second symbol*/
{
register char *p, *q;
register int i;
for( p = sym1, q = sym2, i = SSIZE; *p == *q++; )
if( *p++ == '\0' || --i == 0 )
return(1);
return(0);
}
/* symsame - symbol member same as declared */
symsame(sp,hold,exact) /* [vlh] */
struct symbol *sp, *hold;
int *exact;
{
if (strucptr[smember+instruct])
if (strucptr[smember+instruct]==sp->s_struc) return(1);
if (hold)
if (sp->s_type != hold->s_type || sp->s_offset != hold->s_offset)
*exact = 1;
return(0);
}
/* symcopy - symbol copy*/
/* Copies one symbol to another.*/
symcopy(sym1,sym2) /* returns - none*/
char *sym1; /* pointer to symbol to copy*/
char *sym2; /* pointer to area to copy to*/
{
register char *p, *q;
register int i;
for( p = sym1, q = sym2, i = SSIZE; --i >= 0; )
*q++ = ( *p ? *p++ : '\0');
}
/* index - find the index of a character in a string*/
/* This is identical to Software Tools index.*/
index(str,chr) /* returns index of c in str or -1*/
char *str; /* pointer to string to search*/
char chr; /* character to search for*/
{
register char *s;
register int i;
for( s = str, i = 0; *s != '\0'; i++ )
if( *s++ == chr )
return(i);
return(-1);
}
/* next - if next token matches given token, skip and return success*/
/* This allows for clean parsing of declarations.*/
next(tok) /* returns 1 if matched, 0 otherwise*/
int tok;
{
register int token;
if( (token=gettok()) == tok )
return(1);
peektok = token;
return(0);
}
/* pbtok - put back the given token*/
/* This merely sets the peektok variable*/
pbtok(tok) /* returns - none*/
int tok;
{
if( peektok )
error("too many tokens pushed back");
peektok = tok;
}

View File

@@ -0,0 +1,6 @@
$1lo68 -r -f $1 -unofloat 0$1s.o DECL.o EXPR.o ICODE.o INTERF.o LEX.o MAIN.o STMT.o TABL.o 0$1lib6.a 0$1libF.a 0$1clib
era *.o
era c068.rel
ren c068.rel=c.out
user 13!make $1

View File

@@ -0,0 +1,39 @@
$ num
DECL.C
DECL.lis
$ num
EXPR.C
EXPR.lis
$ num
ICODE.C
ICODE.lis
$ num
INIT.C
INIT.lis
$ num
INTERF.C
INTERF.lis
$ num
LEX.C
LEX.lis
$ num
MAIN.C
MAIN.lis
$ num
STMT.C
STMT.lis
$ num
TABL.C
TABL.lis
$ num
VERSION.C
VERSION.lis
$ num
ICODE.H
ICODE.lst
$ num
MACHINE.H
MACHINE.lst
$ num
PARSER.H
PARSER.lst

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
/*#define MC68000 1*/ /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
#define PDP11 1 /* PDP-11 Version*/
/*#define CPM 1*/ /* CP/M Operating System*/
#define UNIX 1 /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
#define MC68000 1 /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
#define CPM 1 /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
/*#define MC68000 1*/ /* 68000 version */
#define VAX 1 /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
/*#define CPM 1*/ /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
#define VMS 1 /* VMS Operating System*/

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
/*#define MC68000 1*/ /* 68000 version */
#define VAX 1 /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
/*#define CPM 1*/ /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
#define VMS 1 /* VMS Operating System*/

View File

@@ -0,0 +1,173 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char *version "@(#) c068 parser 4.0 - Feb 11, 1983";
/*
ALCYON C Compiler for the Motorola 68000 - Parser
Called from c68:
c068 source icode strings
source: input source code, preprocessed with comments stripped
icode: contains the intermediate code for the code generator,
for a detailed explanaion see ../doc/icode.
strings: contains all the string constants.
The basic structure of the parser is as follows:
main main driver for parser
syminit initializes symbol table
doextdef external definition syntax
getatt get type attributes
dlist declaration list for structures/unions
getatt recursive gettype call
dodecl do one declaration
declarator handle declarator syntax
dodecl do one external declaraion
initlist external initialization list
cexpr constant expressions
expr arithmetic expressions
maketree build operator tree
funcbody function body
dlist declaration list
stmt function statements
stmt recursive stmt call
expr arithmetic expressions
*/
#include "parser.h"
int nextlabel 1;
int lineno;
char *exprp &exprarea[0];
/*
* main - main routine for parser
* Checks arguments, opens input and output files, does main loop
* for external declarations and blocks.
*/
main(argc,argv) /* returns - none*/
int argc; /* argument count*/
char *argv[]; /* argument pointers*/
{
register char *q;
register int i;
for( i = 4; i < argc; i++ ) {
q = argv[i];
if( *q++ != '-' )
usage();
while( 1 ) {
switch( *q++ ) {
case 'F':
case 'f':
fflag++;
continue;
case 'E':
case 'e':
eflag++;
continue;
case 'W':
case 'w':
wflag++;
continue;
case '\0':
break;
default:
usage();
}
break;
}
}
if( argc < 4 )
usage();
if( fopen(argv[1],&ibuf,0) < 0 ) /* 3rd arg for versados */
ferror("can't open %s",argv[i]);
if( fcreat(argv[2],&obuf,0) < 0 || fcreat(argv[3],&sbuf,0) < 0 )
ferror("temp creation error");
obp = &obuf;
lineno++;
frstp = -1; /* [vlh] 3.4 - initialize only once */
syminit();
while( !peek(EOF) )
doextdef();
outeof();
outdata();
copysfile(argv[3]);
exit(errcnt!=0);
}
/* usage - output usage error message and die*/
usage()
{
ferror("usage: c068 source icode str [-e] [-f] [-w]");
}
/* error - report an error message*/
/* outputs current line number and error message*/
error(s,x1,x2,x3,x4,x5,x6) /* returns - none*/
char *s; /* error message*/
int x1, x2, x3, x4, x5, x6; /* args for printf*/
{
register char *savep;
savep = obp;
obp = 0;
errcnt++;
if (!inclflag) {
if( lineno )
printf("* %d: ",lineno);
}
else /*[vlh] generate filename and approp line #*/
printf("%s: * %d: ",inclfile,inclline);
printf(s,x1,x2,x3,x4,x5,x6);
printf("\n");
obp = savep;
}
/* ferror - fatal error*/
/* Outputs error message and exits*/
ferror(s,x1,x2,x3,x4,x5,x6) /* returns - none*/
char *s; /* error message*/
int x1, x2, x3, x4, x5, x6; /* args for printf*/
{
error(s,x1,x2,x3,x4,x5,x6);
exit(1);
}
v6flush(v6buf)
struct iobuf *v6buf;
{
register i;
i = BLEN - v6buf->nunused;
v6buf->nunused = BLEN;
v6buf->xfree = &(v6buf->buff[0]);
if(write(v6buf->fildes,v6buf->xfree,i) != i)
return(-1);
return(0);
}
printf(string,a,b,c,d,e,f,g)
char *string;
int a,b,c,d,e,f,g;
{
char area[256];
register char *p;
sprintf(area,string,a,b,c,d,e,f,g);
for(p = &area[0]; *p; p++)
putchar(*p);
}

View File

@@ -0,0 +1,86 @@
$1stat machine.h=rw
$1pip machine.h=machine.68k
$1cp68 -i 0$1 DECL.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic DECL.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u DECL.s
era DECL.s
$1cp68 -i 0$1 EXPR.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic EXPR.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u EXPR.s
era EXPR.s
$1cp68 -i 0$1 ICODE.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic ICODE.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u ICODE.s
era ICODE.s
$1cp68 -i 0$1 INTERF.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic INTERF.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u INTERF.s
era INTERF.s
$1cp68 -i 0$1 LEX.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic LEX.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u LEX.s
era LEX.s
$1cp68 -i 0$1 MAIN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic MAIN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u MAIN.s
era MAIN.s
$1cp68 -i 0$1 STMT.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic STMT.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u STMT.s
era STMT.s
$1cp68 -i 0$1 TABL.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic TABL.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u TABL.s
era TABL.s
$1cp68 -i 0$1 VERSION.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic VERSION.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u VERSION.s
era VERSION.s
link $1

View File

@@ -0,0 +1,320 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*
C68 Parser - include file
*/
#include <stdio.h>
#include <klib.h>
#undef putchar
#define putchar xputchar
#undef ferror
#define printf xprintf
#include "icode.h"
/*symbol attribute fields*/
#define SRESWORD 001 /*is symbol a reserved word?*/
#define SGLOBAL 002 /*is symbol global?*/
#define STYPEDEF 004 /*typedef declaration?*/
#define SDEFINED 010 /*symbol defined?*/
/*reserved words*/
#define R_AUTO 1
#define R_BREAK 2
#define R_CASE 3
#define R_CHAR 4
#define R_CONTINUE 5
#define R_DO 6
#define R_DEFAULT 7
#define R_DOUBLE 8
#define R_GOTO 9
#define R_ELSE 10
#define R_EXTERNAL 11
#define R_FLOAT 12
#define R_FOR 13
#define R_IF 14
#define R_INT 15
#define R_LONG 16
#define R_REGISTER 17
#define R_RETURN 18
#define R_SHORT 19
#define R_SIZEOF 20
#define R_STATIC 21
#define R_STRUCT 22
#define R_SWITCH 23
#define R_TYPEDEF 24
#define R_UNION 25
#define R_UNSIGNED 26
#define R_WHILE 27
/*
* mixed-mode conversions, entries in 2-d array indexed by:
* (int,unsn,long,doub,ptr)
*/
#define INT_CHAR 1
#define UNSN_CHAR 1
#define LONG_CHAR 1
#define DOUB_CHAR 1
#define PTR_CHAR 1
#define INT_UNSN 0 /*no conversion is generated*/
#define INT_LONG 2
#define INT_DOUB 3
#define INT_PTR 4
#define UNSN_INT 0 /*no conversion is generated*/
#define UNSN_LONG 6
#define UNSN_DOUB 7
#define UNSN_PTR 8
#define LONG_INT 9
#define LONG_UNSN 10
#define LONG_DOUB 11
#define LONG_PTR 12
#define DOUB_INT 13
#define DOUB_UNSN 14
#define DOUB_LONG 15
#define PTR_INT 16
#define PTR_UNSN 17
#define PTR_LONG 18
#define PTR_PTR 19
#define BADCONV 20
/* miscellaneous constants */
#define OPSSIZE 40 /*operator stack size*/
#define OPDSIZE 80 /*operand stack size*/
#define HSIZE 517 /*hash table size, 3.4 made prime */
#define SYMSIZE 1024 /*size to alloc for symbol structures*/
#define SWSIZE 256 /*max no. of cases in a switch*/
#define DSIZE 1000 /*dimension table size*/
#define BITSPWORD 16 /*bits per word*/
#define AREGLO 010 /*A reg flag*/
#define HICREG 2 /*highest reg # used for code generation*/
#define BITSPCHAR 8 /*bits per char*/
#define CHRSPWORD 2 /*chars per word*/
#define STRSIZE 300 /*max string length*/
#define NFARGS 40 /*max no. of args to function*/
#define NFRSTR 20 /*max no. of forward ref struct proto*/
/*symbol table node*/
struct symbol {
char s_attrib; /* defined, resword, global, typedef */
char s_sc; /* auto, static, external, register */
int s_type; /* 4bits specified, 2 bit fields for ptr... */
int s_dp; /* index into dimension table */
int s_ssp; /* dimension table/function arg table */
int s_offset; /* offset inside of structure */
char s_symbol[SSIZE]; /* symbol identifier, to SSIZE chars */
struct symbol *s_struc; /* if struct, ptr to parent (sys III) */
struct symbol *s_next; /* next symbol table entry */
};
/*expression tree operator node*/
struct tnode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
struct tnode *t_left;
struct tnode *t_right;
};
/*expression tree node for symbol - only keeps location*/
struct symnode {
int t_op;
int t_type; /*data type of symbol*/
int t_dp; /*dimension pointer of symbol*/
int t_ssp; /*structure size index to dtab*/
int t_sc; /*storage class of symbol*/
int t_offset; /*offset of symbol*/
int t_label;
};
/*expressioon tree node for external symbol - need to keep name*/
struct extnode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
int t_sc;
int t_offset;
int t_reg;
int t_symbol[SSIZE]; /*symbol name*/
};
/*expression tree node for integer constant*/
struct conode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
int t_value; /*constant value*/
};
struct lconode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
long t_lvalue; /*constant value*/
};
struct swtch {
int sw_label;
int sw_value;
} swtab[SWSIZE];
/*operator and operand stack used by expr*/
struct ops { /*operator stack*/
int o_op; /*operator*/
int o_pri; /*priority*/
} opstack[OPSSIZE], *opp;
char *opdstack[OPDSIZE]; /*operand stack*/
char **opdp; /*operand stack pointer*/
char *opap; /*ptr to next available loc in exprarea*/
char *exprp; /*place to start building expression*/
int opinfo[]; /*operator info table*/
struct tnode *frp; /*pointer to function return info node*/
int swp; /*current entry in switch table*/
int cswp; /*current low switch table index*/
int nextlabel; /*generates unique label numbers*/
int clabel; /*continue label*/
int blabel; /*break label*/
int rlabel; /*return label*/
int dlabel; /*default label*/
int lineno; /*current line number of input*/
int errcnt; /*count of errors*/
int inclflag; /*in include file, don't incr line #'s*/
int inclline; /*[vlh]line# in incl file for err rpting*/
char inclfile[13]; /*[vlh]include filename for err rpting*/
int equalstop; /*stop lex at '=', used for external init*/
int commastop; /*stop parse @ comma(used for const expr)*/
int colonstop; /*stop parse @ colon(used for case value)*/
int instruct; /*set when in structure declaration*/
int smember; /*set when seen . or ->*/
int infunc; /*set when in function body*/
int tdflag; /*declaration is a typedef proto*/
char *tdp; /*points to typedef prototype*/
int localsize; /*length of local variables*/
int naregs; /*keeps track of ptr registers alloc'd*/
int ndregs; /*keep track of data registers alloc'd*/
int loadreg; /*need to load registers...*/
int boffset; /*current bit offset in structure*/
int eflag; /*[vlh] 3.4 IEEE floats */
int fflag; /*[vlh] 3.4 FFP floats */
int xflag; /*translate int's to long's*/
int wflag; /*[vlh] don't generate warning mesgs*/
int reducep; /*[vlh] if(procid); reduction*/
int peektok; /*peeked at token*/
/*dimension table*/
long dtab[DSIZE]; /* [vlh] 3.4 int => long */
int cdp; /*next entry in dtab to alloc*/
/*lexical analyzer values*/
int cvalue; /*current token value if keyword or CINT*/
int cstrsize; /*current string size*/
long clvalue; /*current token value if long constant*/
struct symbol *csp; /*current token symbol ptr if SYMBOL*/
char cstr[STRSIZE]; /*current token value if CSTRING*/
struct symbol *dsp; /*declarator symbol pointer*/
/* -1 -> not instruct, 0 -> unnamed struct */
struct symbol *strucptr[10]; /*[vlh] ptrs to struc symbols*/
/*function argument table, used to collect function parameters*/
struct farg {
struct symbol *f_sp;
int f_offset;
} fargtab[NFARGS];
/*forward referenced structure prototype names*/
struct symbol *frstab[NFRSTR];
int frstp;
/*output buffers for intermediate code and strings*/
struct io_buf obuf, sbuf, ibuf, *obp;
#define stypedef(sp) (sp->s_attrib&STYPEDEF)
#define walign(add) ((add+1)&(~1))
#define array(type) ((type&SUPTYP)==ARRAY)
#define function(type) ((type&SUPTYP)==FUNCTION)
#define pointer(type) ((type&SUPTYP)==POINTER)
#define notarray(type) ((type&SUPTYP)!=ARRAY)
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
#define notpointer(type) ((type&SUPTYP)!=POINTER)
#define btype(type) (type&TYPE)
#define suptype(type) (type&SUPTYP)
#define alltype(type) (type&(SUPTYP|TYPE))
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
#define relop(op) ((opinfo[op]&OPREL)!=0)
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
#define binop(op) ((opinfo[op]&OPBIN)!=0)
#define unaryop(op) ((opinfo[op]&OPBIN)==0)
#define leaf(op) ((opinfo[op]&OPTERM)!=0)
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
#define oppriority(op) (opinfo[op]&OPPRI)
#define makeiop(op) (op|(0254<<8))
/* checks for symbol with structure element storage class */
#define isstel(tp) (tp->t_op==SYMBOL && (sesc(tp)))
#define sesc(t) (t->t_sc==STELCL||t->t_sc==UNELCL||t->t_sc==BFIELDCL)
/* peek at next token, if not read token put back, else delete */
/* 1 if matched, 0 otherwise */
#define peek(tok) ( (peektok=gettok()) == tok )
#define outcommon(sym,size) printf("\t.comm _%.8s,%ld\n",sym,size)
#define outgoto(lab) if( lab > 0 ) printf("\tbra L%d\n",lab)
/* change to text segment */
#define outtext() printf("\t.text\n")
/* change segment to bss */
#define outbss() printf("\t.bss\n")
/* output global symbol references */
#define outextdef(sym) printf("\t.globl _%.8s\n",sym)
/* outputs reserved memory [vlh] 3.4 %d => %ld */
#define outresmem(size) printf("\t.ds.b %ld\n",size)
/* output padding for word alignments */
#define outpad() printf("\t.even\n")
/* output long constant to assembler */
#define outlcon(val) printf("\t.dc.l %d\n",val)
/* output label constant */
#define outclab(lab) printf("\t.dc.l L%d\n",lab)
/* output a label */
#define outlab(lab) printf("\tL%d:",lab)
/* output function label */
#define outflab(sym) printf("\t_%.8s:\n\t~~%.8s:\n",sym,sym)
/* output data label */
#define outdlab(sym) printf("\t_%.8s:\n",sym)
/*functions returning pointers*/
char *expr();
char *talloc();
char *tnalloc();
char *enalloc();
char *snalloc();
char *cnalloc();
char *lcnalloc();
char *fpcnalloc();
char *popopd();
char *cvopgen();
char *arrayref();
char *funcref();
char *install();
char *lookup();
char *balpar();
char *sbrk();
long initlist();
long dsize();
long psize();
long dodecl();
long dlist();
long getdec();
long gethex();
long getoct();
long getfp();
long toieee();
long toffp();

View File

@@ -0,0 +1,16 @@
e:send DECL.C
e:send EXPR.C
e:send ICODE.C
e:send INTERF.C
e:send LEX.C
e:send MAIN.C
e:send STMT.C
e:send TABL.C
e:send VERSION.C
e:send ICODE.H
e:send PARSER.H
e:send MACHINE.68K
e:send LINK.SUB
e:send MAKE.SUB
e:send MACHINE.H
e:send SEND12.SU

View File

@@ -0,0 +1,507 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
#define labgen(l,sl) sl=l;l=nextlabel++;
int swp -1;
/* stmt - process a single statement*/
stmt() /* returns - none*/
{
register int token, lab, i;
register struct tnode *tp;
register char *p;
while( 1 ) {
switch(token=gettok()) {
case LCURBR: /*handle { ... }*/
while( !next(EOF) ) {
if( next(RCURBR) )
return;
stmt();
}
case EOF:
error("{ not matched by }");
case SEMI: /*null statement*/
return;
case RCURBR:
pbtok(token);
return;
case SYMBOL: /*symbol: statement*/
if( peekc(':') ) {
dolabel();
continue;
}
default: /*anything else...*/
pbtok(token);
outexpr(expr());
break;
case RESWORD:
switch(cvalue) {
case R_BREAK:
lab = brklabel();
outgoto(lab); /*branch to break label*/
break;
case R_CASE:
docase();
continue;
case R_CONTINUE:
lab = contlabel(); /*branch to continue label*/
outgoto(lab);
break;
case R_DEFAULT:
dodefault();
continue;
case R_DO:
dodo();
break;
case R_FOR:
dofor();
return;
case R_GOTO:
lab = gotolabel();
outgoto(lab);
break;
case R_IF:
doif();
return;
case R_RETURN:
doreturn();
break;
case R_SWITCH:
doswitch();
return;
case R_WHILE:
dowhile();
return;
default:
synerr("invalid keyword");
return;
}
}
if( !next(SEMI) )
synerr("missing semicolon");
return;
}
}
/* balpar - handle expression within parenthesis for while and if*/
/* Merely checks for left and right parens and builds expression.*/
char *balpar() /* returns pointer to expression*/
{
register struct tnode *tp;
if( next(LPAREN) ) {
reducep = 1;
tp = expr();
reducep = 0;
if( next(RPAREN) )
return(tp);
}
synerr("parenthesized expression syntax");
return(0);
}
/* synerr - syntax error*/
/* Outputs error message and tries to resyncronize input.*/
synerr(s,x1,x2,x3,x4,x5,x6) /* returns - none*/
char *s; /* printf format string*/
int x1, x2, x3, x4, x5, x6; /* printf arguments*/
{
register int token;
error(s,x1,x2,x3,x4,x5,x6);
while( (token=gettok()) != SEMI && token != EOF && token != LCURBR &&
token != RCURBR )
;
pbtok(token);
}
/* gotolabel - gets label id for goto*/
/* This is used for both: goto symbol and if(...)goto symbol*/
gotolabel() /* returns 0 if not, else label id*/
{
register struct symbol *sp;
if( !next(SYMBOL) )
synerr("expected label");
else {
sp = csp;
if( !(sp->s_sc) ) {
sp->s_type = LLABEL;
if( !sp->s_offset )
sp->s_offset = nextlabel++;
}
if( (!sp->s_sc || sp->s_sc == STATIC ) && sp->s_type == LLABEL )
return(sp->s_offset);
synerr("invalid label");
}
return(0);
}
/* dolabel - do statement label*/
/* Checks current symbol for already being defined, then sets*/
/* symbol attributes for label.*/
dolabel() /* returns - none*/
{
register struct symbol *sp;
sp = csp;
if( sp->s_sc )
error("label redeclaration: %.8s",sp->s_symbol);
else {
sp->s_attrib =| SDEFINED;
sp->s_sc = STATIC;
sp->s_type = LLABEL;
if( !sp->s_offset )
sp->s_offset = nextlabel++;
outlab(sp->s_offset);
}
}
/* brklabel - generate break label*/
/* Checks if break label is undefined, and if so, generates message*/
brklabel() /* returns label number*/
{
if( !blabel )
error("invalid break statement");
return(blabel);
}
/* contlabel - generate continue label*/
/* Checks if continue label is undefined, and if so, generates message*/
contlabel() /* returns label number*/
{
if( !clabel )
error("invalid continue statement");
return(clabel);
}
/* docase - handles: case constant : statement*/
/* Checks for being in a switch statement, adds entry to switch table*/
docase() /* returns - none*/
{
register int value, lab;
colonstop++;
value = cexpr(); /*get case value*/
colonstop--;
if( !next(COLON) ) /*check for colon*/
synerr("missing colon");
if( swp < 0 )
error("case not inside a switch block");
else if( swp >= (SWSIZE-1) )
error("too many cases in switch");
else {
addswitch(&swtab[cswp],swp-cswp,value,lab=nextlabel++);
outlab(lab);
swp++;
}
}
/* dodefault - handles: default : statement*/
/* Checks for colon and being in a switch statement*/
dodefault() /* returns - none*/
{
if( !next(COLON) )
error("missing colon");
if( swp < 0 )
error("default not inside a switch block");
else {
dlabel = nextlabel++; /*allocate default label*/
outlab(dlabel); /*output default label*/
}
}
/* dodo - handles: do statement while ( expression )*/
dodo() /* returns - none*/
{
register int lab, saveblab, saveclab;
labgen(blabel,saveblab);
labgen(clabel,saveclab);
lab = nextlabel++;
outlab(lab); /*branch back to here*/
stmt(); /*do statement*/
outlab(clabel); /*continue label*/
if( !nextrw(R_WHILE) ) {
error("missing while"); /*only advisory...*/
outgoto(lab);
}
else
outifgoto(balpar(),TRUE,lab); /*while expression*/
outlab(blabel); /*break label*/
blabel = saveblab; /*restore labels*/
clabel = saveclab;
}
/*
* dofor - handle: for ( expression ; expression ; expression ) statement
* Hard part is handling re-initialization expression, which is
* parsed and saved, then the statement is parsed, then the reinit
* clause expression tree is output.
*/
dofor() /* returns - none*/
{
register int lab, saveblab, saveclab, reinit, clineno;
register char *savep;
register struct tnode *tp;
labgen(blabel,saveblab);
labgen(clabel,saveclab);
if( !next(LPAREN) ) {
forerr:
synerr("invalid for statement");
return;
}
if( !next(SEMI) ) { /*do init expression*/
outexpr(expr());
if( !next(SEMI) )
goto forerr;
}
outlab(clabel); /*branch back to here*/
if( !next(SEMI) ) { /*do for condition*/
outifgoto(expr(),FALSE,blabel);
if( !next(SEMI) )
goto forerr;
}
if( next(RPAREN) ) { /*no re-init - easy case*/
stmt(); /*output statement*/
outgoto(clabel); /*output continue label*/
}
else { /*there is a re-init clause*/
labgen(clabel,lab);
savep = exprp;
tp = expr(); /*save re-init tree until done*/
exprp = opap; /*remember until reinit is output*/
reinit = lineno;
if( !next(RPAREN) )
goto forerr;
stmt(); /*do statment*/
clineno = lineno;
lineno = reinit;
outlab(clabel); /*we branch to here for reinit*/
outexpr(tp); /*output re-init clause*/
exprp = savep;
lineno = clineno;
outgoto(lab); /*branch back to top of loop*/
}
outlab(blabel); /*break to here*/
blabel = saveblab;
clabel = saveclab; /*restore labels*/
}
/* doif - handles: if ( expression ) statement [ else statement ]*/
/* Handles special cases for goto, break, continue and return.*/
doif() /* returns - none*/
{
register struct tnode *tp;
register int elselab, exitlab;
tp = balpar(); /*if( expr )...*/
exitlab = 0;
if( nextrw(R_GOTO) )
exitlab = gotolabel();
else if( nextrw(R_BREAK) )
exitlab = brklabel();
else if( nextrw(R_CONTINUE) )
exitlab = contlabel();
else if( nextrw(R_RETURN) ) {
if( peekc(';') ) {
exitlab = rlabel;
putback(';');
}
else
pbtok(RESWORD);
}
if( exitlab ) { /*easy goto, do branch if true*/
outifgoto(tp,TRUE,exitlab);
if( !next(SEMI) )
synerr("missing semicolon");
if( nextrw(R_ELSE) ) /*else clause, just output it*/
stmt();
}
else { /*hard goto, branch over statement*/
elselab = nextlabel++;
outifgoto(tp,FALSE,elselab);
stmt();
if( nextrw(R_ELSE) ) {
exitlab = nextlabel++; /*branches over else clause*/
outgoto(exitlab); /*branch out of then clause*/
outlab(elselab); /*label to start else clause*/
stmt(); /*else statement*/
outlab(exitlab);
}
else
outlab(elselab); /*no else, just branch out*/
}
}
/*
* doreturn - handles: return [ expression ] ;
* Expression is the hard part, must create an assignment expression
* to assign expression to the type of the function, then get it
* loaded into a specific register.
*/
doreturn() /* returns - none*/
{
register struct tnode *tp;
if( !peekc(';') ) /*need to compute return?*/
outforreg(FRETURN,frp,expr());
else
putback(';');
outgoto(rlabel); /*branch to the return label*/
}
/*
* doswitch - handles: switch ( expression ) statement
* Evaluates the expression, forces the result into a known register
* collects the case statements in swtab, then outputs the switch
* operator and switch cases.
*/
doswitch() /* returns - none*/
{
register int saveblab, swlab, savedlab, saveswp, i;
register struct tnode *tp;
labgen(blabel,saveblab);
tp = balpar();
integral(tp,-1); /*must be integral type result*/
outforreg(ASSIGN,snalloc(INT,AUTO,0,0,0),tp);
saveswp = swp; /*remember old switch pointer*/
if( saveswp < 0 )
swp++;
i = cswp;
cswp = swp; /*remember real first entry*/
swlab = nextlabel++;
outgoto(swlab); /*branch to switch code*/
savedlab = dlabel;
dlabel = 0;
stmt(); /*do switch statement*/
outgoto(blabel); /*output branch just in case*/
outlab(swlab); /*here we now do the switch code*/
if( !dlabel )
dlabel = blabel;
outswitch(swp-cswp,dlabel,&swtab[cswp]);
outlab(blabel); /*break to here*/
cswp = i;
swp = saveswp;
blabel = saveblab;
dlabel = savedlab;
}
/* dowhile - handles: while ( expression ) statement*/
/* This is fairly straight-forward.*/
dowhile() /* returns - none*/
{
register int saveclab, saveblab;
labgen(blabel,saveblab);
labgen(clabel,saveclab);
outlab(clabel); /*continue label*/
outifgoto(balpar(),FALSE,blabel); /*condition clause*/
stmt(); /*statement*/
outgoto(clabel); /*branch back to top of loop*/
outlab(blabel); /*break to here*/
blabel = saveblab;
clabel = saveclab; /*restore labels*/
}
/* nextrw - is next token the specified reserved word?*/
nextrw(rw) /* returns 1 if match, 0 otherwise*/
int rw; /* reserved word to match*/
{
register int token;
if( (token=gettok()) != RESWORD || cvalue != rw ) {
pbtok(token);
return(0);
}
return(1);
}
/*
* addswitch - add an entry into current switch table, bubble sorting
* This makes it easier on the code generator and also checks for
* duplicate labels at the "right" time.
*/
addswitch(sp,ncases,nval,nlab) /* returns - none*/
struct swtch *sp; /* switch table pointer*/
int ncases; /* number of cases in switch*/
int nval; /* new value*/
int nlab; /* new label*/
{
register struct swtch *nswp, *s;
register int temp, i;
nswp = &sp[ncases];
nswp->sw_value = nval;
nswp->sw_label = nlab;
s = nswp--;
for( ; --ncases >= 0; s--, nswp-- ) {
if( s->sw_value == nswp->sw_value )
error("duplicate case value");
if( s->sw_value < nswp->sw_value ) {
temp = s->sw_value;
s->sw_value = nswp->sw_value;
nswp->sw_value = temp;
temp = s->sw_label;
s->sw_label = nswp->sw_label;
nswp->sw_label = temp;
}
}
}
/* outforreg - generate assignment for switch and return*/
outforreg(op,ltp,rtp) /*returns - none*/
int op; /*operator for build tree*/
struct tnode *ltp; /*left expression tree*/
struct tnode *rtp; /*right expression tree*/
{
register struct tnode *tp;
opp = opstack;
opdp = opdstack;
pushopd(ltp);
pushopd(rtp);
maketree(op);
if( tp = popopd() )
outcforreg(tp->t_right);
opp = opdp = 0;
}
/* outassign - generate assignment for function args*/
outassign(ltp,rtp) /*returns - none*/
struct tnode *ltp; /*left expression tree*/
struct tnode *rtp; /*right expression tree*/
{
opp = opstack;
opdp = opdstack;
pushopd(ltp);
pushopd(rtp);
maketree(ASSIGN);
outexpr(popopd());
opp = opdp = 0;
}

View File

@@ -0,0 +1,119 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
#define ASGOP OPRAS|OPASSIGN|OPLVAL|OPBIN
/*info on operators:*/
/*000077-- OPPRI - priority*/
/*000100-- OPBIN - binary operator*/
/*000200-- OPLVAL - left operand must be lvalue*/
/*000400-- OPREL - relational operator*/
/*001000-- OPASSIGN - assignment operator*/
/*002000-- OPLWORD - int required on left*/
/*004000-- OPRWORD - int required on right*/
/*010000-- OPCOM commutative*/
/*020000-- OPRAS - right associative*/
/*040000-- OPTERM - termination node*/
/*100000 - OPCONVS - conversion operator*/
int opinfo[] {
TRMPRI, /*EOF*/
ADDPRI|OPCOM|OPBIN, /*ADD - expr + expr*/
ADDPRI|OPBIN, /*SUB - expr - expr*/
MULPRI|OPCOM|OPBIN, /*MULT - expr * expr*/
MULPRI|OPBIN, /*DIV - expr / expr*/
MULPRI|OPBIN, /*MOD - expr % expr*/
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*RSH - expr >> expr*/
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*LSH - expr << expr*/
ANDPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*AND - expr & expr*/
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*OR - expr | expr*/
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*XOR - expr ^ expr*/
UNOPRI|OPRAS|OPLWORD, /*NOT - ! expr*/
UNOPRI|OPRAS, /*UMINUS - - expr*/
UNOPRI|OPRAS|OPLWORD, /*COMPL - ~ expr*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREDEC - --lvalue*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREINC - ++lvalue*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTDEC - lvalue--*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTINC - lvalue++*/
ASGPRI|ASGOP, /*ASSIGN - lvalue = expr*/
ASGPRI|ASGOP, /*EQADD - lvalue += expr*/
ASGPRI|ASGOP, /*EQSUB - lvalue -= expr*/
ASGPRI|ASGOP, /*EQMULT - lvalue *= expr*/
ASGPRI|ASGOP, /*EQDIV - lvalue /= expr*/
ASGPRI|ASGOP, /*EQMOD - lvalue %= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQRSH - lvalue >>= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQLSH - lvalue <<= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQAND - lvalue &= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQOR - lvalue |= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQXOR - lvalue ^= expr*/
TRMPRI, /*FJSR - generate function jsr*/
EQLPRI|OPREL|OPBIN, /*EQUALS - expr == expr*/
EQLPRI|OPREL|OPBIN, /*NEQUALS - expr != expr*/
RELPRI|OPREL|OPBIN, /*GREAT - expr > expr*/
RELPRI|OPREL|OPBIN, /*GREATEQ - expr >= expr*/
RELPRI|OPREL|OPBIN, /*LESS - expr < expr*/
RELPRI|OPREL|OPBIN, /*LESSEQ - expr <= expr*/
TRMPRI|OPCONVS, /*INT2L*/
TRMPRI|OPCONVS, /*LONG2I*/
TRMPRI|OPBIN, /*BTST*/
TRMPRI, /*LOAD*/
TRMPRI|OPBIN, /*LMULT*/
TRMPRI|OPBIN, /*LDIV*/
TRMPRI|OPBIN, /*LMOD*/
TRMPRI|OPBIN, /*LEQMULT*/
TRMPRI|OPBIN, /*LEQDIV*/
TRMPRI|OPBIN, /*LEQMOD*/
TRMPRI|ASGOP, /*EQADDR*/
TRMPRI, /*EQNOT*/
TRMPRI, /*EQNEG*/
TRMPRI|OPBIN, /*DOCAST*/
ASGPRI|ASGOP, /*STASSIGN [vlh]*/
TRMPRI|OPCONVS, /*LONG2F [vlh] 3.4*/
TRMPRI|OPCONVS, /*FLOAT2L [vlh] 3.4*/
TRMPRI|OPCONVS, /*INT2F [vlh] 3.4*/
TRMPRI|OPCONVS, /*FLOAT2F [vlh] 3.4*/
TRMPRI, /*unused - 55*/
TRMPRI, /*unused - 56*/
TRMPRI, /*unused - 57*/
TRMPRI, /*unused - 58*/
TRMPRI, /*unused - 59*/
UNOPRI|OPRAS|OPLVAL, /*ADDR - & expr*/
UNOPRI|OPRAS|OPLWORD, /*INDR - * expr*/
LNDPRI|OPBIN, /*LAND - expr && expr*/
LORPRI|OPBIN, /*LOR - expr || expr*/
QMKPRI|OPRAS|OPBIN, /*QMARK - expr ? expr : expr*/
QMKPRI|OPRAS|OPBIN, /*COLON*/
COMPRI|OPBIN, /*COMMA*/
TRMPRI|OPTERM, /*CINT*/
TRMPRI|OPTERM, /*CLONG*/
TRMPRI|OPTERM, /*SYMBOL*/
TRMPRI|OPTERM, /*AUTOINC*/
TRMPRI|OPTERM, /*AUTODEC*/
LPNPRI|OPBIN, /*CALL - call with arguments*/
LPNPRI, /*NACALL - no argument call*/
TRMPRI, /*BFIELD - field selection*/
TRMPRI, /*IFGOTO*/
TRMPRI, /*INIT*/
TRMPRI, /*CFORREG*/
TRMPRI, /*unused - 78*/
TRMPRI|OPTERM, /*CFLOAT [vlh] 3.4*/
UNOPRI|OPRAS|OPASSIGN|OPBIN, /*CAST*/
TRMPRI, /*SEMI*/
TRMPRI, /*LCURBR - {*/
TRMPRI, /*RCURBR - }*/
LPNPRI, /*LBRACK - [*/
RPNPRI, /*RBRACK - ]*/
LPNPRI, /*LPAREN - )*/
RPNPRI, /*RPAREN - )*/
TRMPRI|OPTERM, /*STRING*/
TRMPRI, /*RESWORD*/
LPNPRI|OPBIN, /*APTR - expr -> symbol*/
LPNPRI|OPBIN, /*PERIOD - expr . symbol*/
UNOPRI|OPRAS, /*SIZEOF - sizeof expr*/
LPNPRI|OPBIN, /*MPARENS - matching parens ()*/
UNOPRI|OPRAS|OPASSIGN|OPBIN, /*FRETURN*/
};

View File

@@ -0,0 +1,16 @@
e:vax DECL.C s
e:vax EXPR.C s
e:vax ICODE.C s
e:vax INTERF.C s
e:vax LEX.C s
e:vax MAIN.C s
e:vax STMT.C s
e:vax TABL.C s
e:vax VERSION.C s
e:vax ICODE.H s
e:vax PARSER.H s
e:vax MACHINE.68K s
e:vax LINK.SUB s
e:vax MAKE.SUB s
e:vax MACHINE.H s
e:vax SEND12.SUB s

View File

@@ -0,0 +1 @@
char *compiled "@(#) parser - Thu Feb 10 13:02 1983";

View File

@@ -0,0 +1,18 @@
$ parser
$ set noon
$ !
$ ! C068 make file for VMS
$ !
$ copy machine.vax machine.h
$ pur machine.h
$ cx DECL
$ cx EXPR
$ cx ICODE
$ cx INIT
$ cx INTERF
$ cx LEX
$ cx MAIN
$ cx STMT
$ cx TABL
$ cx VERSION
$ clink DECL,EXPR,ICODE,INTERF,LEX,MAIN,STMT,TABL,init,version,lib:klib/lib c068

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,196 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include <stdio.h>
#include <klib.h>
#undef putchar
#define putchar xputchar
#undef ferror
#define ferror xferror
#define printf xprintf
#include "icode.h"
char brtab[][2];
int invrel[];
int swaprel[];
char *strtab[];
char null[];
/*operator tree node for unary and binary operators*/
struct tnode {
int t_op; /*operator*/
int t_type; /*data type of result*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
struct tnode *t_left; /*left sub-tree*/
struct tnode *t_right; /*right sub-tree (undefined if unary)*/
};
/*constant terminal node*/
struct conode {
int t_op; /*operator*/
int t_type; /*type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_value; /*value or label number*/
};
struct lconode {
int t_op; /*operator*/
int t_type; /*type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
long t_lvalue; /*value or label number*/
};
/*local symbol terminal node*/
struct symnode {
int t_op; /*operator*/
int t_type; /*symbol data type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_sc; /*storage class*/
int t_offset; /*register offset*/
int t_reg; /*register number*/
int t_label; /*label number if static*/
};
/*external symbol reference node*/
struct extnode {
int t_op; /*operator*/
int t_type; /*symbol data type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_sc; /*storage class*/
int t_offset; /*register offset*/
int t_reg; /*register number*/
char t_symbol[SSIZE]; /*symbol name*/
};
/*68000 special - indexed symbol node*/
/*this is used to generate a An(off,Xn.type) address*/
struct indexnode {
int t_op;
int t_type;
int t_su;
int t_ssp;
int t_sc;
int t_offset;
int t_reg;
int t_xreg;
int t_xtype;
};
int lflag;
int dflag;
int mflag;
int cflag;
int eflag;
int fflag;
int oflag;
struct io_buf ibuf, obuf;
int lineno;
int naregs;
int ndregs;
int errcnt;
int opinfo[];
int nextlabel;
char null[];
char optab[][6];
char *mnemonics[];
char *codeskels[];
int stacksize;
char *tnalloc();
char *snalloc();
char *cenalloc();
char *xnalloc();
char *talloc();
char *cnalloc();
char *lcnalloc();
char *fpcnalloc();
char *canon();
char *commute();
char *constant();
char *match();
char *addptree();
char *fixbfield();
char *coffset();
char *tcopy();
#define wallign(add) ((add+1)&(~1))
#define array(type) ((type&SUPTYP)==ARRAY)
#define function(type) ((type&SUPTYP)==FUNCTION)
#define pointer(type) ((type&SUPTYP)==POINTER)
#define notarray(type) ((type&SUPTYP)!=ARRAY)
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
#define notpointer(type) ((type&SUPTYP)!=POINTER)
#define isfloat(type) (type==FLOAT)
#define btype(type) (type&TYPE)
#define suptype(type) (type&SUPTYP)
#define alltype(type) (type&(SUPTYP|TYPE))
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
#define relop(op) ((opinfo[op]&OPREL)!=0)
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
#define binop(op) ((opinfo[op]&OPBIN)!=0)
#define unaryop(op) ((opinfo[op]&(OPBIN|OPTERM))==0)
#define leafop(op) ((opinfo[op]&OPTERM)!=0)
#define notleafop(op) ((opinfo[op]&OPTERM)==0)
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
#define oppriority(op) (opinfo[op]&OPPRI)
#define commop(op) ((opinfo[op]&OPCOM)!=0)
#define convop(op) ((opinfo[op]&OPCONVS)!=0)
#define notconvop(op) ((opinfo[op]&OPCONVS)==0)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define QUICKVAL 8
#define LEP 14
#define FORCC 1
#define FOREFF 2
#define FORSTACK 3
#define FORCREG 4
#define FORSP 5
#define FORREG 4
#define HICREG 2
#define NCREGS 3
#define AREGLO 8
#define IMMED 1
#define NOTIMMED 0
#define NOTLOFFSET 0
/* one line routines turned into defines [vlh] for speed */
/*outgoto - output "bra L[labno]"*/
#define outgoto(lab) if (lab>0) printf("bra L%d\n",lab)
/*outlab - output "L[labno]:"*/
#define outlab(lab) if (lab>0) printf("L%d:",lab)
/*outext - output register sign extension*/
#define outext(reg) printf("ext.l R%d\n",reg)
/*outuext - output unsigned to long register extension*/
#define outuext(reg) printf("swap R%d\nclr R%d\nswap R%d\n",reg,reg,reg)
/*outswap - output swap register instruction*/
#define outswap(reg) printf("swap R%d\n",reg)
/*outaddr - output "add [type] R1 R2" instruction*/
#define outaddr(r1,r2,tp) outrr("add",r1,r2,(tp))
/*outccsave - ouput instruction to move cc's to register*/
#define outccsave(reg) printf("move sr,R%d\n",reg)
/*outccrestore - output instruction to restore cc's from register*/
#define outccrestore(reg) printf("move R%d,ccr\n",reg)
/*basetype - get the btype info sans unsigned*/
#define basetype(type) ((type==UNSIGNED) ? INT : type)
#define unsign(type) ((type) == UNSIGNED)
#define longorptr(type) (type==LONG || (type&SUPTYP))
#define unorptr(type) (type==UNSIGNED || (type&SUPTYP))
#define dreg(reg) ((reg) & (~AREGLO))
#define areg(reg) ((reg) | AREGLO)
#define isareg(reg) ((reg) >= AREGLO)
#define isdreg(reg) ((reg) < AREGLO)
#define isreg(tp) ((tp)->t_op == SYMBOL && (tp)->t_sc == REGISTER)

View File

@@ -0,0 +1,756 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
#include "cskel.h"
/* scodegen - over-all code generation for expression*/
/* Picks off post-fix ++, --.*/
scodegen(tp,cookie,reg) /* returns register result is in*/
struct tnode *tp;
int cookie;
int reg;
{
struct tnode *clist[20];
struct tnode **clp;
register struct tnode **cp;
register int r;
register int ccflag;
register struct tnode *rtp;
if( tp->t_op == COMMA ) {
scodegen(tp->t_left,FOREFF,reg);
return(scodegen(tp->t_right,cookie,reg));
}
ccflag = 0;
clp = clist;
tp = addptree(tp,&clp);
if( clp > clist ) {
/*
* post ++, -- in tree. We need to compile the tree post operators
* then generate code to do the post operators, then do any fix up of
* condition codes since the Stupid 68000 architect was a nimnul.
*/
if( cookie == FORCC ) {
/*
* here we make the observation that if we are comparing something with
* zero OR the top operator of the tree is not a comparison operator,
* we can compile the tree to a register, and then set the condition
* codes OK with a tst instruction at the end.
*/
if( relop(tp->t_op) ) {
if( (rtp=constant(tp->t_right)) && !rtp->t_value ) {
ccflag = 1;
tp = tp->t_left;
cookie = FORREG;
}
else
ccflag = 2;
}
else {
ccflag = 1;
cookie = FORREG;
}
}
}
r = codegen(tp,cookie,reg);
if( clp > clist ) {
if( ccflag == 2 )
outccsave(r);
for( cp = clist; cp < clp; cp++ )
codegen(*cp,FOREFF,r+1);
if( ccflag == 1 )
outcmp0(r,tp);
else if( ccflag == 2 )
outccrestore(r);
}
return(r);
}
/* addptree - prune off postfix ++, -- from expression tree*/
/* This prunes off ++, -- and collects those expressions for*/
/* scodegen.*/
char *addptree(tp,clp) /* returns pointer to pruned tree*/
struct tnode *tp;
struct tnode ***clp;
{
register int op;
op = tp->t_op;
if( leafop(op) || op == QMARK ) /* [vlh] 4.0 QMARK... */
return(tp);
if( op == POSTINC || op == POSTDEC ) {
*(*clp)++ = tp;
return( tcopy(tp->t_left) );
}
if( binop(op) )
tp->t_right = addptree(tp->t_right,clp);
tp->t_left = addptree(tp->t_left,clp);
return(tp);
}
/* codegen - generate code for expression*/
/* This calls up rcodegen, which prunes off any special register*/
/* optimization code, then calls ucodegen (unrecursive) code*/
/* generation.*/
codegen(tp,cookie,reg) /* returns reg result is in*/
struct tnode *tp; /* tree pointer*/
int cookie; /* code generation goals*/
int reg; /* first available register*/
{
register int size, savestk, ssize, r, i, scookie;
register struct tnode *rtp;
#ifndef NODEBUG
if( cflag )
printf("codegen op=%d cookie=%d reg=%d\n",tp->t_op,cookie,reg);
#endif
switch( tp->t_op ) {
case CALL:
case NACALL:
ssize = 0;
savestk = stacksize;
if( tp->t_left->t_op != SYMBOL )
stacksize++;
if( tp->t_op == CALL ) {
rtp = tp->t_right;
while( rtp->t_op == COMMA ) {
ssize =+ dofarg(rtp->t_right);
rtp = rtp->t_left;
}
ssize =+ dofarg(rtp);
}
tp->t_op = FJSR; /*generate JSR (unary op)*/
codegen(tp,FORREG,reg);
popstack(ssize);
stacksize = savestk;
fixresult(tp,cookie,0);
return(0); /*result in R0*/
case COMMA:
codegen(tp->t_left,FOREFF,reg);
return(codegen(tp->t_right,cookie,reg));
case AND:
if( cookie == FORCC && (i=isonebit(tp->t_right)) >= 0 &&
(i=dobitadd(tp->t_left,i)) >= 0 ) {
if( convop(tp->t_right->t_op) )
tp->t_right = tp->t_right->t_left;
tp->t_right->t_value = i;
tp->t_op = BTST;
tp = canon(tp);
sucomp(tp,reg,1);
}
break;
}
if( rcodegen(&tp,cookie,reg) ) {
if( cookie == FORCC && tp->t_op == SYMBOL && tp->t_sc == REGISTER
&& isdreg(tp->t_reg))
return(reg);
}
r = ucodegen(tp,cookie,reg);
return(r);
}
/* fixresult - fix result of code generation*/
fixresult(tp,cookie,reg) /* returns - none*/
struct tnode *tp;
int cookie; /* wanted this cookie*/
int reg;
{
#ifndef NODEBUG
if (cflag)
printf("fixresult cookie=%d reg=%d op=%d\n",cookie,reg,tp->t_op);
#endif
switch( cookie ) {
case FORCC:
outcmp0(reg,tp);
break;
case FORSP:
case FORSTACK:
stacksize++;
outrpush(reg,tp,cookie==FORSTACK);
break;
}
return(reg);
}
/* ucodegen - generate code for tree given cookie and starting register*/
/* Handles the matching of the expression tree node with the*/
/* corresponding code generation table. When a match is found,*/
/* expand is called to expand the code skeleton macro.*/
ucodegen(tp,cookie,reg) /* returns reg result is in*/
struct tnode *tp; /* pointer to expression tree*/
int cookie; /* (FORCC,FOREFF,FORREG,FORSTACK)*/
int reg; /* first available register*/
{
register int r;
register char *p;
#ifndef NODEBUG
if(cflag)
putexpr("ucodegen",tp);
#endif
switch( tp->t_op ) {
case STASSIGN: /*[vlh]*/
outstrcpy(codegen(tp->t_left,FORREG,areg(reg)),
codegen(tp->t_right,FORREG,areg(reg+1)), tp->t_type);
return(reg);
break;
case SYMBOL:
if( cookie == FOREFF )
return(reg);
break;
case LSH:
if( (isareg(reg)) && (p=constant(tp->t_right)) &&
!(unsign(tp->t_left->t_type)) &&
(p->t_value == 1 || p->t_value == 2) ) {
r = codegen(tp->t_left,FORREG,reg);
outmovr(r,reg,tp->t_left);
if( p->t_value == 2 )
outaddr(reg,reg,tp);
outaddr(reg,reg,tp);
fixresult(tp,cookie,reg);
return(reg);
}
break;
case EQMULT:
case EQDIV:
case LEQMULT:
case LEQDIV:
case EQMOD:
case LEQMOD:
case EQRSH:
case EQLSH:
case EQAND:
case EQOR:
case EQXOR:
if( indexreg(tp->t_left) ) {
reg = dreg(reg);
outmovr(r=tp->t_left->t_reg,reg,tp);
tp->t_left->t_reg = reg;
codegen(tp,cookie,reg+1);
outmovr(reg,r,tp);
return(reg);
}
break;
case ADD:
case EQADD:
if( (p=constant(tp->t_right)) && p->t_value < 0 &&
p->t_value >= -QUICKVAL ) {
p->t_value = - p->t_value;
tp->t_op =+ (SUB-ADD);
}
break;
}
sucomp(tp,reg,1);
if( (r=loadexpr(tp,cookie,reg)) >= 0 )
return(r);
if( (r=cqmark(tp,cookie,reg)) >= 0 )
return(r);
if( (r=hardrel(tp,cookie,reg)) >= 0 )
return(r);
if( cookie == FORCC && (p=match(tp,FOREFF,reg)) != 0 ) {
r = expand(tp,FOREFF,reg,p);
if( asgop(tp->t_op) && indexreg(tp->t_left) )
outcmp0(tp->t_left->t_reg,tp->t_left);
}
else if( p = match(tp,cookie,reg) )
r = expand(tp,cookie,reg,p);
else if( cookie != FORREG )
r = fixresult(tp,cookie,ucodegen(tp,FORREG,reg));
else
error("no code table for %d",tp->t_op);
return(r);
}
/* outstrcpy - output structure copy */
outstrcpy(lr,rr,size) /*[vlh]*/
int lr, rr; /* left register, right register */
int size; /* structure size to copy */
{
register int lab;
lab = nextlabel++;
printf("move #%d,r%d\n",(size/2)-1,dreg(lr));
outlab(lab);
printf("move (r%d)+,(r%d)+\ndbra r%d,L%d\n",rr,lr,dreg(lr),lab);
}
/* loadexpr - load an addressable expression into a register*/
/* This checks for any possible usage of the register indexed*/
/* addressing mode. Note that this relies on the good graces of the*/
/* load code skeletons not to muck up the compiler registers before*/
/* loading an addressable expression...*/
loadexpr(tp,cookie,reg) /* returns register loaded or -1*/
struct tnode *tp; /* pointer to expression tree*/
int reg; /* register to load*/
{
register struct tnode *rtp, *ltp, *xtp, *atp;
register int off, r, type, nr, ar, xr, xt;
if( tp->t_op == INDR || LOADABLE(tp) ) {
type = tp->t_type;
if( tp->t_op == INDR && (ltp=tp->t_left)->t_op == ADD ) {
rtp = ltp->t_right;
ltp = ltp->t_left;
off = 0;
if( rtp->t_op == CINT && ((off=rtp->t_value) < -128 ||
off > 127 || ltp->t_op != ADD ) ) {
tp = snalloc(type,AUTO,off,0,0);
if( indexreg(ltp) )
tp->t_reg = ltp->t_reg;
else {
r = codegen(ltp,FORREG,areg(reg));
if( isdreg(r) )
outmovr(r,areg(r),ltp);
tp->t_reg = areg(r);
}
}
else {
if( rtp->t_op == CINT ) {
rtp = ltp->t_right;
ltp = ltp->t_left;
}
if(indexreg(rtp) || (!(indexreg(ltp)) && (isreg(rtp)))) {
xtp = ltp;
ltp = rtp;
rtp = xtp;
}
xtp = atp = 0;
if( indexreg(ltp) ) {
ar = ltp->t_reg;
if( (isreg(rtp)) && rtp->t_type != CHAR ) {
xr = rtp->t_reg;
xt = rtp->t_type;
}
else
xtp = rtp;
}
else if( (isreg(ltp)) && ltp->t_type != CHAR &&
(lflag || rtp->t_op != ADDR) ) {
xr = ltp->t_reg;
xt = ltp->t_type;
atp = rtp;
}
else if( rtp->t_op == ADDR ) {
atp = ltp;
xtp = rtp;
}
else {
atp = rtp;
xtp = ltp;
}
nr = 0;
if( atp )
nr++;
if( xtp && (xtp->t_op != ADDR || lflag ) )
nr++;
if( dreg(nr+reg) <= HICREG ) {
r = reg;
if( atp ) {
ar = codegen(atp,FORREG,areg(r));
if( isdreg(ar) ) {
outmovr(ar,areg(ar),atp);
ar = areg(ar);
}
r++;
}
if( xtp && xtp->t_op == ADDR && !lflag ) {
tp = xtp->t_left;
tp->t_sc =+ (EXTOFF-EXTERNAL);
tp->t_offset =+ off;
tp->t_reg = ar;
}
else {
if( xtp ) {
xr = codegen(xtp,FORREG,areg(r));
xt = xtp->t_type;
}
tp = xnalloc(type,ar,off,xr,xt);
}
}
}
}
if( (isareg(reg)) && tp->t_type == CHAR )
reg = dreg(reg);
tp = tnalloc(LOAD,tp->t_type,SU_EASY,0,tp,null);
return( codegen(tp,cookie,reg) );
}
return(-1);
}
/* coffset - check offset for addressable node*/
char *coffset(tp) /* returns ptr to const off node*/
struct tnode *tp; /* pointer to node*/
{
register struct tnode *rtp;
if( tp->t_op == ADD ) {
rtp = tp->t_right;
if( rtp->t_op == CINT )
return(rtp);
if(!lflag) {
if( rtp->t_op == ADDR )
return(rtp->t_left);
rtp = tp->t_left;
if( rtp->t_op == ADDR ) {
tp->t_left = tp->t_right;
tp->t_right = rtp;
return(rtp->t_left);
}
}
}
return(0);
}
/* hardrel - do relationals returning a value*/
hardrel(tp,cookie,reg) /* returns reg or -1*/
struct tnode *tp; /* pointer to tree*/
int cookie; /* cookie for code generation*/
int reg; /* low register*/
{
char *p;
int op, lab1, lab2;
if( cookie != FORCC && (relop(op=tp->t_op) || op == LOR ||
op == LAND || op == NOT) ) {
lab1 = nextlabel++;
condbr(tp,TRUE,lab1,reg);
p = canon(cnalloc(INT,0));
codegen(p,cookie,reg);
lab2 = nextlabel++;
outgoto(lab2);
outlab(lab1);
p = canon(cnalloc(INT,1));
codegen(p,cookie,reg);
outlab(lab2);
return(reg);
}
return(-1);
}
/* cqmark - compile question mark operator*/
/* This does the compilation of the question mark operator.*/
cqmark(tp,cookie,reg) /* returns reg or -1*/
struct tnode *tp;
int cookie;
int reg;
{
register int lab1, lab2, savestk, r;
if( tp->t_op == QMARK && cookie != FORCC ) {
lab1 = nextlabel++;
condbr(tp->t_left,FALSE,lab1,reg);
savestk = stacksize;
r = scodegen(tp->t_right->t_left,cookie,reg); /* [mc] 4.0 */
outmovr(r,reg,tp);
stacksize = savestk;
outgoto(lab2=nextlabel++);
outlab(lab1);
r = scodegen(tp->t_right->t_right,cookie,reg); /* [mc] 4.0 */
outmovr(r,reg,tp);
outlab(lab2);
return(reg);
}
return(-1);
}
/* condbr - handle conditional branch code generation*/
/* This handles the conditional branch code generation, handling*/
/* the special cases for constants, ||, &&, ! and generating the*/
/* correct conditional branch instruction.*/
condbr(tp,dir,lab,reg)
struct tnode *tp;
int dir;
int lab;
int reg;
{
register struct tnode *ltp, *rtp;
register int lab1, optype, op, subdir;
ltp = tp->t_left;
if( binop(op=tp->t_op) )
rtp = tp->t_right;
subdir = dir; /*set up for LOR*/
switch( op ) {
case CINT:
if( !tp->t_value ) {
if( dir == FALSE )
outgoto(lab);
}
else if( dir != FALSE )
outgoto(lab);
break;
case NOT:
condbr(ltp,!dir,lab,reg);
break;
case LAND:
dir = !dir;
case LOR:
if( dir == FALSE ) {
lab1 = nextlabel++;
condbr(ltp,!subdir,lab1,reg);
condbr(rtp,subdir,lab,reg);
outlab(lab1);
}
else {
condbr(ltp,subdir,lab,reg);
condbr(rtp,subdir,lab,reg);
}
break;
case COMMA:
scodegen(tp->t_left,FOREFF,reg);
condbr(tp->t_right,dir,lab,reg);
break;
default:
if( op == NEQUALS && ltp->t_op == PREDEC &&
isdreg(ltp->t_left->t_reg) && ltp->t_left->t_type == INT &&
rtp->t_op == CINT && rtp->t_value == -1 ) {
outdbra(ltp->t_left->t_reg,lab);
break;
}
if( relop(op) && ltp->t_op == AUTOINC && rtp->t_op == AUTOINC &&
ltp->t_type == rtp->t_type )
outcmpm(tp);
else
scodegen(tp,FORCC,reg);
optype = 0;
if( relop(op) ) {
if( unorptr(ltp->t_type) || unorptr(rtp->t_type) )
optype =+ 1;
}
else
op = NEQUALS;
if(!dir)
op = invrel[op-EQUALS];
optype = brtab[op-EQUALS][optype];
printf("%s L%d\n",mnemonics[optype],lab);
break;
}
}
rcodegen(tpp,cookie,reg) /* returns changed flag*/
struct tnode **tpp; /* pointer to tree*/
int cookie; /* code generation cookie*/
int reg; /* register to use for code*/
{
register int change, op;
register struct tnode *tp;
tp = *tpp;
op = tp->t_op;
change = 0;
if( notleafop(op) && op != COMMA ) {
change =+ rcodegen(&tp->t_left,cookie,reg);
if( binop(op) )
change =+ rcodegen(&tp->t_right,cookie,reg);
change =+ rcgen(tpp,cookie,reg);
}
if( change )
*tpp = canon(*tpp);
return(change);
}
rcgen(tpp,cookie,reg) /* returns changed flag*/
struct tnode **tpp; /* pointer to tree*/
int cookie; /* code generation goals*/
int reg; /* register to use*/
{
register struct tnode *tp, *p, *ltp, *rtp;
register int op, change;
change = 0;
for( tp = *tpp ; binop(op=tp->t_op); *tpp=tp=canon(tp), change++ ) {
ltp = tp->t_left;
if( ltp->t_op != SYMBOL )
break;
rtp = tp->t_right;
switch( op ) {
case ASSIGN:
if( ltp->t_sc != REGISTER )
return(change);
switch( rtp->t_op ) {
case MULT:
case DIV:
case MOD:
case AND:
case OR:
case XOR:
case LSH:
case RSH:
if( isareg(ltp->t_reg) )
return(change);
case ADD:
case SUB:
p = rtp->t_right;
if(NOTADDRESSABLE(ltp) || !noref(rtp->t_right,ltp->t_reg))
return(change);
p = rtp->t_left;
if( p->t_op != SYMBOL || p->t_sc != REGISTER ||
p->t_reg != ltp->t_reg ) {
tp->t_right = p;
#ifndef NODEBUG
if( cflag > 1 )
putexpr("rcgen",tp);
#endif
codegen(tp,FOREFF,reg);
}
tp->t_right = rtp->t_right;
tp->t_op = rtp->t_op + (EQADD-ADD);
continue;
}
case EQLSH:
case EQRSH:
if( ltp->t_sc != REGISTER )
return(change);
case EQADD:
case EQSUB:
case EQAND:
case EQOR:
case EQXOR:
if( ltp->t_type == CHAR )
return(change);
#ifndef NODEBUG
if( cflag > 1 )
putexpr("rcgen",tp);
#endif
ucodegen(tp,FOREFF,reg);
tp = ltp;
continue;
case PREDEC:
case PREINC:
if( cookie == FORCC || ltp->t_type == CHAR )
return(change);
ucodegen(tp,FOREFF,reg);
tp = ltp;
continue;
}
break;
}
return(change);
}
noref(tp,reg) /* 4.0 change */
struct tnode *tp; /* returns 1 if no reference in tree to reg */
int reg;
{
if ( leafop(tp->t_op) ) {
if (tp->t_op == SYMBOL && tp->t_sc == REGISTER && tp->t_reg == reg)
return(0);
return(1);
}
if ( !noref(tp->t_left,reg) )
return(0);
if (binop(tp->t_op))
return( noref(tp->t_right,reg) );
return(1);
}
/* cdsize - compute size of data item*/
cdsize(tp) /* returns data size in bytes*/
struct tnode *tp;
{
register int type;
type = tp->t_type;
if( suptype(type) )
return(PTRSIZE);
switch( type ) {
case CHAR:
case INT:
case UNSIGNED:
return(INTSIZE);
case LONG:
case FLOAT: /* [vlh] 3.4 */
return(LONGSIZE);
}
error("cdsize: invalid type %d",type);
return(0);
}
dofarg(tp) /* returns number of bytes pushed*/
struct tnode *tp; /* pointer to expression tree*/
{
register int nb;
nb = 0;
if( tp->t_op == SYMBOL && tp->t_sc == STRUCT )
error("structure operation not implemented");
else if( stacksize ) {
codegen(tp,FORSTACK,0);
nb = cdsize(tp);
}
else
codegen(tp,FORSP,0);
return( nb );
}
/* dobitadd - do bit operation address checking and fixup*/
dobitadd(tp,bitno) /* returns -1 if can't or bitno*/
struct tnode *tp;
int bitno;
{
register int offset;
if( tp->t_type == CHAR )
offset = 0;
else
offset = cdsize(tp) - (bitno/BITSPBYTE) - 1;
if( tp->t_op == SYMBOL ) {
switch( tp->t_sc ) {
case REGISTER:
if( isdreg(tp->t_reg) )
return(bitno);
default:
return(-1);
case EXTERNAL:
case STATIC:
case REGOFF:
case STATOFF:
case EXTOFF:
tp->t_offset =+ offset;
return( bitno % BITSPBYTE );
}
}
else if( tp->t_op == INDR ) {
tp->t_left = tnalloc(ADD,tp->t_left->t_type,0,0,tp->t_left,
cnalloc(INT,offset));
return( bitno % BITSPBYTE );
}
return(-1);
}
isonebit(tp) /* returns -1 if not 1 bit, else bitno*/
struct tnode *tp; /* pointer to tree*/
{
if( tp = constant(tp) )
return( onebit(tp->t_value) );
return(-1);
}

View File

@@ -0,0 +1,92 @@
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
/*built-in literals*/
#define MOV 128
#define MOVL 129
#define JSR 130
#define CLR 131
#define CLRL 132
#define EXTW 133
#define EXTL 134
#define LEA 135
#define STK 136
/*built-in macros*/
#define TREE 141
#define LEFT 142
#define RIGHT 143
#define LOFFSET 144
#define ROFFSET 145
#define LADDR 146
#define RADDR 147
#define CR 148
#define NR 149
#define CAR 150
#define NAR 151
#define TLEFT 152
#define TRIGHT 153
#define TEITHER 154
#define TLEFTL 155
#define OP 156
#define AOP 157
#define MODSWAP 158
#define EXL 159
#define EXLR 160
#define EXLRN 161
#define EXRL 162
#define EXRLN 163
#define PSH 164
#define POP 165
#define POP8 166
#define OPCALL 167
#define POP4 169
#define LADDRP 168
/*modifiers for compiling sub-trees*/
#define S_INDR 1 /*indirection*/
#define S_STACK 2 /*onto stack*/
#define S_FORCC 4 /*set condition codes*/
#define S_NEXT 8 /*into next register*/
/*Sethy-Ullman values*/
#define SU_ZERO 0x000 /*zero*/
#define SU_ONE 0x100 /*one*/
#define SU_SMALL 0x200 /*constant between 1 and 8*/
#define SU_QUICK 0x300 /*quick constant between -128 and 127*/
#define SU_CONST 0x400 /*any constant*/
#define SU_AREG 0x500 /*A register*/
#define SU_REG 0x600 /*register*/
#define SU_ADDR 0x700 /*addressable*/
#define SU_XREG 0x800 /*A register used as data...*/
#define SU_EASY 0x900 /*easy*/
#define SU_HARD 0xa00 /*hard*/
#define SU_VHARD 0xb00 /*very hard ... function calls, etc.*/
#define SU_ANY 0xf00 /*anything*/
#define ADDRESSABLE(x) (x->t_su<=SU_ADDR)
#define NOTADDRESSABLE(x) (x->t_su>SU_ADDR)
#define LOADABLE(x) (x->t_su<=SU_XREG)
/*flag byte (operand type):*/
#define T_CHAR 1 /*char only*/
#define T_SHORT 2 /*short*/
#define T_INT 3 /*int only*/
#define T_LONG 4 /*long*/
#define T_UCHAR 5 /*unsigned char*/
#define T_USHORT 6 /*unsigned short*/
#define T_UNSN 7 /*unsigned int*/
#define T_ULONG 8 /*unsigned long*/
#define T_FLOAT 9 /*float*/
#define T_DOUB 10 /*double*/
#define T_ANY 11 /*int or word (implied)*/
#define T_INDR 0x10 /*pointer type (bit)*/
struct skeleton {
int sk_left;
int sk_right;
char *sk_def;
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,251 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "machine.h"
/*
* intermediate code operators
* 0=>EOF, special operator
*/
#define EOF 0
/*1-59=>operators that generate code (entries in code gen optab)*/
#define ADD 1
#define SUB 2
#define MULT 3
#define DIV 4
#define MOD 5
#define RSH 6
#define LSH 7
#define AND 8
#define OR 9
#define XOR 10
#define NOT 11
#define UMINUS 12
#define COMPL 13
#define PREDEC 14
#define PREINC 15
#define POSTDEC 16
#define POSTINC 17
#define ASSIGN 18
#define EQADD 19
#define EQSUB 20
#define EQMULT 21
#define EQDIV 22
#define EQMOD 23
#define EQRSH 24
#define EQLSH 25
#define EQAND 26
#define EQOR 27
#define EQXOR 28
#define FJSR 29
#define EQUALS 30
#define NEQUALS 31
#define GREAT 32
#define GREATEQ 33
#define LESS 34
#define LESSEQ 35
#define INT2L 36
#define LONG2I 37
/*machine dependent operators that generate code*/
#define BTST 38
#define LOAD 39
#define LMULT 40
#define LDIV 41
#define LMOD 42
#define LEQMULT 43
#define LEQDIV 44
#define LEQMOD 45
#define EQADDR 46
#define EQNOT 47
#define EQNEG 48
#define DOCAST 49
#define STASSIGN 50 /*[vlh]*/
#define LONG2F 51 /*[vlh] 3.4*/
#define FLOAT2L 52 /*[vlh] 3.4*/
#define INT2F 53 /*[vlh] 3.4*/
#define FLOAT2I 54 /*[vlh] 3.4*/
#define LCGENOP 55 /*change if adding more operators...*/
/*intermediate code operators that do not generate code*/
#define ADDR 60
#define INDR 61
#define LAND 62
#define LOR 63
#define QMARK 64
#define COLON 65
#define COMMA 66
#define CINT 67
#define CLONG 68
#define SYMBOL 69
#define AUTOINC 70
#define AUTODEC 71
#define CALL 72
#define NACALL 73
#define BFIELD 74
#define IFGOTO 75
#define INIT 76
#define CFORREG 77
#define DCLONG 78
#define CFLOAT 79 /*[vlh] 3.4*/
/*operators local to parser*/
#define CAST 80
#define SEMI 81
#define LCURBR 82
#define RCURBR 83
#define LBRACK 84
#define RBRACK 85
#define LPAREN 86
#define RPAREN 87
#define STRING 88
#define RESWORD 89
#define APTR 90
#define PERIOD 91
#define SIZEOF 92
#define MPARENS 93
#define FRETURN 94
#define STACKEND 100
/*data types*/
#define TYPELESS 0
#define CHAR 1
#define SHORT 2
#define INT 3
#define LONG 4
#define UCHAR 5
#define USHORT 6
#define UNSIGNED 7
#define ULONG 8
#define FLOAT 9
#define DOUBLE 10
/*data types local to parser*/
#define STRUCT 11
#define FRSTRUCT 12
#define LLABEL 13
/*type flags and definitions*/
#define TYPE 017
#define SUPTYP 060
#define ALLTYPE 077
#define POINTER 020
#define FUNCTION 040
#define ARRAY 060
#define SUTYPLEN 2
/*data registers*/
#define DREG0 0
#define DREG2 2
#define DREG3 3
#define DREG4 4
#define DREG5 5
#define DREG6 6
#define DREG7 7
#define AREG3 11
#define AREG4 12
#define AREG5 13
/*storage classes*/
#define AUTO 1
#define REGISTER 2
#define EXTERNAL 3
#define STATIC 4
#define REGOFF 5
#define EXTOFF 6
#define STATOFF 7
#define INDEXED 8
/*exclusively code generator storage classes*/
#define CINDR 9
#define CLINDR 10
#define CFINDR 11 /* [vlh] 3.4 */
/*exclusively parser storage classes*/
#define STRPROTO 9
#define PDECLIST 10
#define PARMLIST 11
#define BFIELDCL 12
#define UNELCL 13
#define STELCL 14
/*opinfo table bits*/
#define OPPRI 077
#define OPBIN 0100
#define OPLVAL 0200
#define OPREL 0400
#define OPASSIGN 01000
#define OPLWORD 02000
#define OPRWORD 04000
#define OPCOM 010000
#define OPRAS 020000
#define OPTERM 040000
#define OPCONVS 0100000
/*68000 definitions*/
#define PTRSIZE 4
#define INTSIZE 2
#define LONGSIZE 4
#define SSIZE 8 /* chars per symbol */
#define TRUE 1
#define FALSE 0
#define TABC '\t' /* tab character */
#define EOLC '\n' /* end of line character */
#define BITSPBYTE 8
/*operator class priorities*/
#define TRMPRI 0 /* terminal nodes */
#define RPNPRI 1 /* ) and ] */
#define CALPRI 2 /* in-stack call, ( or [ */
#define COLPRI 3 /* init or case priority for : or , */
#define STKPRI 4 /* priority of end of stack */
#define COMPRI 5 /* normal priority for , */
#define ASGPRI 6 /* =, +=, -=, *=, /=, %=, ... */
#define QMKPRI 7 /* ?: */
#define LORPRI 8 /* || */
#define LNDPRI 9 /* && */
#define ORPRI 10 /* |, ! */
#define ANDPRI 11 /* & */
#define EQLPRI 12 /* ==, != */
#define RELPRI 13 /* >, <, >=, <= */
#define SHFPRI 14 /* <<, >> */
#define ADDPRI 15 /* +, - */
#define MULPRI 16 /* *, /, % */
#define UNOPRI 17 /* ++, --, &, *, -, ~, sizeof */
#define LPNPRI 18 /* ., ->, [, (, function call */
#define PSTPRI 19 /* in-stack post--, post++ */
struct io_buf {
int io_fd;
int io_nc;
char *io_p;
char io_b[512];
};
#ifdef PDP11
struct { short hiword; short loword; };
#endif
#ifdef MC68000
struct { short hiword; short loword; };
#endif
#ifdef VAX
struct { short loword; short hiword; };
#endif
#define EXPSIZE 1024
int exprarea[EXPSIZE];
/* v6io buffer declaration */
#define BLEN 512
struct iobuf{
int fildes;
int nunused;
char *xfree;
char buff[BLEN];
};

View File

@@ -0,0 +1,418 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char null[]=0;
#define SSIZE 8 /* chars per symbol */
/*operator tree node for unary and binary operators*/
struct tnode {
int t_op; /*operator*/
int t_type; /*data type of result*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
struct tnode *t_left; /*left sub-tree*/
struct tnode *t_right; /*right sub-tree (undefined if unary)*/
};
/*constant terminal node*/
struct conode {
int t_op; /*operator*/
int t_type; /*type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_value; /*value or label number*/
};
struct lconode {
int t_op; /*operator*/
int t_type; /*type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
long t_lvalue; /*value or label number*/
};
/*local symbol terminal node*/
struct symnode {
int t_op; /*operator*/
int t_type; /*symbol data type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_sc; /*storage class*/
int t_offset; /*register offset*/
int t_reg; /*register number*/
int t_label; /*label number if static*/
};
/*external symbol reference node*/
struct extnode {
int t_op; /*operator*/
int t_type; /*symbol data type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_sc; /*storage class*/
int t_offset; /*register offset*/
int t_reg; /*register number*/
char t_symbol[SSIZE]; /*symbol name*/
};
/*68000 special - indexed symbol node*/
/*this is used to generate a An(off,Xn.type) address*/
struct indexnode {
int t_op;
int t_type;
int t_su;
int t_ssp;
int t_sc;
int t_offset;
int t_reg;
int t_xreg;
int t_xtype;
};
int lflag=0;
int dflag=0;
int mflag=0;
int cflag=0;
int eflag=0;
int fflag=0;
int oflag=0;
int lineno=0;
int naregs=0;
int ndregs=0;
int errcnt=0;
int stacksize=0;
char *tnalloc();
char *snalloc();
char *cenalloc();
char *xnalloc();
char *talloc();
char *cnalloc();
char *lcnalloc();
char *fpcnalloc();
char *canon();
char *commute();
char *constant();
char *match();
char *addptree();
char *fixbfield();
char *coffset();
char *tcopy();
#define wallign(add) ((add+1)&(~1))
#define array(type) ((type&SUPTYP)==ARRAY)
#define function(type) ((type&SUPTYP)==FUNCTION)
#define pointer(type) ((type&SUPTYP)==POINTER)
#define notarray(type) ((type&SUPTYP)!=ARRAY)
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
#define notpointer(type) ((type&SUPTYP)!=POINTER)
#define isfloat(type) (type==FLOAT)
#define btype(type) (type&TYPE)
#define suptype(type) (type&SUPTYP)
#define alltype(type) (type&(SUPTYP|TYPE))
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
#define relop(op) ((opinfo[op]&OPREL)!=0)
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
#define binop(op) ((opinfo[op]&OPBIN)!=0)
#define unaryop(op) ((opinfo[op]&(OPBIN|OPTERM))==0)
#define leafop(op) ((opinfo[op]&OPTERM)!=0)
#define notleafop(op) ((opinfo[op]&OPTERM)==0)
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
#define oppriority(op) (opinfo[op]&OPPRI)
#define commop(op) ((opinfo[op]&OPCOM)!=0)
#define convop(op) ((opinfo[op]&OPCONVS)!=0)
#define notconvop(op) ((opinfo[op]&OPCONVS)==0)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define QUICKVAL 8
#define LEP 14
#define FORCC 1
#define FOREFF 2
#define FORSTACK 3
#define FORCREG 4
#define FORSP 5
#define FORREG 4
#define HICREG 2
#define NCREGS 3
#define AREGLO 8
#define IMMED 1
#define NOTIMMED 0
#define NOTLOFFSET 0
/* one line routines turned into defines [vlh] for speed */
/*outgoto - output "bra L[labno]"*/
#define outgoto(lab) if (lab>0) printf("bra L%d\n",lab)
/*outlab - output "L[labno]:"*/
#define outlab(lab) if (lab>0) printf("L%d:",lab)
/*outext - output register sign extension*/
#define outext(reg) printf("ext.l R%d\n",reg)
/*outuext - output unsigned to long register extension*/
#define outuext(reg) printf("swap R%d\nclr R%d\nswap R%d\n",reg,reg,reg)
/*outswap - output swap register instruction*/
#define outswap(reg) printf("swap R%d\n",reg)
/*outaddr - output "add [type] R1 R2" instruction*/
#define outaddr(r1,r2,tp) outrr("add",r1,r2,(tp))
/*outccsave - ouput instruction to move cc's to register*/
#define outccsave(reg) printf("move sr,R%d\n",reg)
/*outccrestore - output instruction to restore cc's from register*/
#define outccrestore(reg) printf("move R%d,ccr\n",reg)
/*basetype - get the btype info sans unsigned*/
#define basetype(type) ((type==UNSIGNED) ? INT : type)
#define unsign(type) ((type) == UNSIGNED)
#define longorptr(type) (type==LONG || (type&SUPTYP))
#define unorptr(type) (type==UNSIGNED || (type&SUPTYP))
#define dreg(reg) ((reg) & (~AREGLO))
#define areg(reg) ((reg) | AREGLO)
#define isareg(reg) ((reg) >= AREGLO)
#define isdreg(reg) ((reg) < AREGLO)
#define isreg(tp) ((tp)->t_op == SYMBOL && (tp)->t_sc == REGISTER)
/*
* intermediate code operators
* 0=>EOF, special operator
*/
#define EOF 0
/*1-59=>operators that generate code (entries in code gen optab)*/
#define ADD 1
#define SUB 2
#define MULT 3
#define DIV 4
#define MOD 5
#define RSH 6
#define LSH 7
#define AND 8
#define OR 9
#define XOR 10
#define NOT 11
#define UMINUS 12
#define COMPL 13
#define PREDEC 14
#define PREINC 15
#define POSTDEC 16
#define POSTINC 17
#define ASSIGN 18
#define EQADD 19
#define EQSUB 20
#define EQMULT 21
#define EQDIV 22
#define EQMOD 23
#define EQRSH 24
#define EQLSH 25
#define EQAND 26
#define EQOR 27
#define EQXOR 28
#define FJSR 29
#define EQUALS 30
#define NEQUALS 31
#define GREAT 32
#define GREATEQ 33
#define LESS 34
#define LESSEQ 35
#define INT2L 36
#define LONG2I 37
/*machine dependent operators that generate code*/
#define BTST 38
#define LOAD 39
#define LMULT 40
#define LDIV 41
#define LMOD 42
#define LEQMULT 43
#define LEQDIV 44
#define LEQMOD 45
#define EQADDR 46
#define EQNOT 47
#define EQNEG 48
#define DOCAST 49
#define STASSIGN 50 /*[vlh]*/
#define LONG2F 51 /*[vlh] 3.4*/
#define FLOAT2L 52 /*[vlh] 3.4*/
#define INT2F 53 /*[vlh] 3.4*/
#define FLOAT2I 54 /*[vlh] 3.4*/
#define LCGENOP 55 /*change if adding more operators...*/
/*intermediate code operators that do not generate code*/
#define ADDR 60
#define INDR 61
#define LAND 62
#define LOR 63
#define QMARK 64
#define COLON 65
#define COMMA 66
#define CINT 67
#define CLONG 68
#define SYMBOL 69
#define AUTOINC 70
#define AUTODEC 71
#define CALL 72
#define NACALL 73
#define BFIELD 74
#define IFGOTO 75
#define INIT 76
#define CFORREG 77
#define DCLONG 78
#define CFLOAT 79 /*[vlh] 3.4*/
/*operators local to parser*/
#define CAST 80
#define SEMI 81
#define LCURBR 82
#define RCURBR 83
#define LBRACK 84
#define RBRACK 85
#define LPAREN 86
#define RPAREN 87
#define STRING 88
#define RESWORD 89
#define APTR 90
#define PERIOD 91
#define SIZEOF 92
#define MPARENS 93
#define FRETURN 94
#define STACKEND 100
/*data types*/
#define TYPELESS 0
#define CHAR 1
#define SHORT 2
#define INT 3
#define LONG 4
#define UCHAR 5
#define USHORT 6
#define UNSIGNED 7
#define ULONG 8
#define FLOAT 9
#define DOUBLE 10
/*data types local to parser*/
#define STRUCT 11
#define FRSTRUCT 12
#define LLABEL 13
/*type flags and definitions*/
#define TYPE 017
#define SUPTYP 060
#define ALLTYPE 077
#define POINTER 020
#define FUNCTION 040
#define ARRAY 060
#define SUTYPLEN 2
/*data registers*/
#define DREG0 0
#define DREG2 2
#define DREG3 3
#define DREG4 4
#define DREG5 5
#define DREG6 6
#define DREG7 7
#define AREG3 11
#define AREG4 12
#define AREG5 13
/*storage classes*/
#define AUTO 1
#define REGISTER 2
#define EXTERNAL 3
#define STATIC 4
#define REGOFF 5
#define EXTOFF 6
#define STATOFF 7
#define INDEXED 8
/*exclusively code generator storage classes*/
#define CINDR 9
#define CLINDR 10
#define CFINDR 11 /* [vlh] 3.4 */
/*exclusively parser storage classes*/
#define STRPROTO 9
#define PDECLIST 10
#define PARMLIST 11
#define BFIELDCL 12
#define UNELCL 13
#define STELCL 14
/*opinfo table bits*/
#define OPPRI 077
#define OPBIN 0100
#define OPLVAL 0200
#define OPREL 0400
#define OPASSIGN 01000
#define OPLWORD 02000
#define OPRWORD 04000
#define OPCOM 010000
#define OPRAS 020000
#define OPTERM 040000
#define OPCONVS 0100000
/*68000 definitions*/
#define PTRSIZE 4
#define INTSIZE 2
#define LONGSIZE 4
#define TRUE 1
#define FALSE 0
#define TABC '\t' /* tab character */
#define EOLC '\n' /* end of line character */
#define BITSPBYTE 8
/*operator class priorities*/
#define TRMPRI 0 /* terminal nodes */
#define RPNPRI 1 /* ) and ] */
#define CALPRI 2 /* in-stack call, ( or [ */
#define COLPRI 3 /* init or case priority for : or , */
#define STKPRI 4 /* priority of end of stack */
#define COMPRI 5 /* normal priority for , */
#define ASGPRI 6 /* =, +=, -=, *=, /=, %=, ... */
#define QMKPRI 7 /* ?: */
#define LORPRI 8 /* || */
#define LNDPRI 9 /* && */
#define ORPRI 10 /* |, ! */
#define ANDPRI 11 /* & */
#define EQLPRI 12 /* ==, != */
#define RELPRI 13 /* >, <, >=, <= */
#define SHFPRI 14 /* <<, >> */
#define ADDPRI 15 /* +, - */
#define MULPRI 16 /* *, /, % */
#define UNOPRI 17 /* ++, --, &, *, -, ~, sizeof */
#define LPNPRI 18 /* ., ->, [, (, function call */
#define PSTPRI 19 /* in-stack post--, post++ */
struct io_buf {
int io_fd;
int io_nc;
char *io_p;
char io_b[512];
};
struct { int hiword; int loword; };
#define EXPSIZE 1024
int exprarea[EXPSIZE]=0;
/* v6io buffer declaration */
#define BLEN 512
struct iobuf {
int fildes;
int nunused;
char *xfree;
char buff[BLEN];
};
struct io_buf ibuf={0}, obuf={0};
int bol=0;
int errflg=0;
int level=0;
int onepass=0;
char *opap=0;

View File

@@ -0,0 +1,134 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
int bol;
int onepass;
/* outexpr - output expression*/
outexpr(tp) /* returns - none*/
struct tnode *tp; /* pointer to tree node*/
{
if( dflag )
outline();
if( exprok(tp) )
scodegen(canon(tp),FOREFF,0);
}
outifgoto(tp,dir,lab)
struct tnode *tp;
int dir;
int lab;
{
if( dflag )
outline();
if( exprok(tp) )
condbr(canon(tp),dir,lab,0);
}
outcforreg(tp)
struct tnode *tp;
{
if( dflag )
outline();
if( exprok(tp) )
outmovr(scodegen(canon(tp),FORREG,0),0,tp);
}
outinit(tp) /* returns - none*/
struct tnode *tp;
{
register int typeout;
if( dflag )
outline();
if( exprok(tp) ) {
typeout = tp->t_type;
tp = canon(tp);
if( tp->t_op == ADDR )
tp = tp->t_left;
if( tp->t_op == CINT || tp->t_op == SYMBOL ) {
if( tp->t_op != CINT )
printf(".dc.l ");
else {
printf(".dc");
outtype(typeout);
putchar(' ');
}
outaexpr(tp,NOTIMMED); /* [vlh] 4.0 not immed... */
}
else
error("invalid initialization");
putchar('\n');
}
}
/* snalloc - code generator symbol node allocation*/
/* This might be coalesced into parser snalloc.*/
char *snalloc(type,sc,offset,dp,ssp) /* returns ptr to node alloced*/
int type; /* type of symbol*/
int sc; /* storage class*/
int offset; /* offset from Local Environment Ptr*/
int dp; /*for compatability with parser*/
int ssp; /*for compatability with parser*/
{
register struct symnode *sp;
sp = talloc(sizeof(*sp));
sp->t_op = SYMBOL;
sp->t_type = type;
sp->t_su = dp;
sp->t_ssp = ssp;
sp->t_sc = sc;
switch( sc ) {
case STATIC:
sp->t_offset = 0;
sp->t_reg = 0;
sp->t_label = offset;
break;
case REGISTER:
sp->t_offset = 0;
sp->t_reg = offset;
sp->t_label = 0;
break;
case AUTO:
sp->t_sc = REGOFF;
sp->t_offset = offset;
sp->t_reg = LEP;
sp->t_label = 0;
break;
default:
sp->t_offset = offset;
sp->t_reg = 0;
sp->t_label = 0;
break;
}
return(sp);
}
exprok(tp)
struct tnode *tp;
{
if( tp < exprarea || tp > &exprarea[EXPSIZE] )
return(0);
if( leafop(tp->t_op) )
return(1);
if( binop(tp->t_op) && !exprok(tp->t_right) )
return(0);
return( exprok(tp->t_left) );
}
outline()
{
if( onepass && !bol )
putchar('\n');
printf("*line %d\n",lineno);
}

View File

@@ -0,0 +1,12 @@
ren u.o=util.o
ren t.o=tabl.o
ren c.o=codegen.o
ren i.o=interf.o
ren m.o=main.o
ren p.o=putexpr.o
$1lo68 -r -f $1 -unofloat 0$1s.o canon.o c.o cskels.o i.o m.o optab.o p.o smatch.o sucomp.o t.o u.o 0$1lib6.a 0$1clib
era c168.rel
ren c168.rel=c.out
era *.o
user 0!make $1

View File

@@ -0,0 +1,51 @@
$ num
CANON.C
CANON.lis
$ num
CODEGEN.C
CODEGEN.lis
$ num
CSKELS.C
CSKELS.lis
$ num
INIT.C
INIT.lis
$ num
INTERF.C
INTERF.lis
$ num
MAIN.C
MAIN.lis
$ num
OPTAB.C
OPTAB.lis
$ num
PUTEXPR.C
PUTEXPR.lis
$ num
SMATCH.C
SMATCH.lis
$ num
SUCOMP.C
SUCOMP.lis
$ num
TABL.C
TABL.lis
$ num
UTIL.C
UTIL.lis
$ num
VERSION.C
VERSION.lis
$ num
CGEN.H
CGEN.lst
$ num
CSKEL.H
CSKEL.lst
$ num
ICODE.H
ICODE.lst
$ num
MACHINE.H
MACHINE.lst

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
/*#define MC68000 1*/ /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
#define PDP11 1 /* PDP-11 Version*/
/*#define CPM 1*/ /* CP/M Operating System*/
#define UNIX 1 /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
#define MC68000 1 /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
#define CPM 1 /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
/*#define MC68000 1*/ /* 68000 version */
#define VAX 1 /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
/*#define CPM 1*/ /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
#define VMS 1 /* VMS Operating System*/

Some files were not shown because too many files have changed in this diff Show More