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,427 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "mach.h"
#ifdef VAX11
# include <c68/sys/cout.h>
#endif
#ifdef PDP11
# include <c68/sys/cout.h>
#endif
#ifdef MC68000
# include <sys/cout.h>
#endif
#ifdef DRI
# include <stdio.h>
# include <klib.h>
# include <ctype.h>
# include <cout.h>
#endif
/* 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, dir 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)*/
/* 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*/
/* 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
/* Register Range */
#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*/
/* Register values, as reflected in as68init */
#define CCR 16
#define SR 17
#define USP 18
#define WORD_ID 20 /* [vlh] 4.2 */
#define PC 22
#define SFC 23 /* [vlh] 4.2, control register for 68010 */
#define DFC 24 /* [vlh] 4.2, control register for 68010 */
#define VSR 25 /* [vlh] 4.2, control register for 68010 */
/* Control Register Numeric Values */
#define SFC_CR 0
#define DFC_CR 1
#define USP_CR 0x800
#define VSR_CR 0x801
/* Instruction Formats */
#define ANDI 01000
#define AND 0140000
#define ORI 0
#define OR 0100000
#define EORI 05000
#define EOR 0130000
#define MOVE 0
#define MOVEC 047172 /* [vlh] 4.2, 68010 */
#define MOVES 07000 /* [vlh] 4.2, 68010 */
#define RTD 047164 /* [vlh] 4.2, 68010 */
#define MOVETCC 042300
#define MOVEFCC 041300 /* [vlh] 4.2, 68010 */
#define MOVESR 043300
#define SRMOVE 040300
#define MOVEUSP 047140
#define CLRVAL 041000
#define CLRFOR 24
/*relocation values*/
#define ABS 0 /*absolute*/
#define DATA 1
#define TEXT 2
#define BSS 3
#define EXTRN 4 /*externally defined*/
/* Conditional Assembly variables and constants [vlh] */
#define LOW_CA 21 /* [vlh] */
#define HI_CA 30 /* [vlh] */
/* Size attribute */
#define BYTE 'b'
#define WORD 'w'
#define LONG 'l'
#define BYTESIZ 1
#define WORDSIZ 2
#define LONGSIZ 4
/* Ascii values */
#define EOLC '\n'/*end of line character*/
#define EOF 0 /*end of file indicator*/
#define NULL 0 /* [vlh] character null '\0' */
#define SOH 1
/* Miscellaneous Defines */
#define TRUE 1 /* [vlh] boolean values */
#define FALSE 0 /* [vlh] boolean values */
#define STDOUT 1 /* file descriptor for standard output */
#define STDERR 2 /* file descriptor for standard error */
#define NAMELEN 8 /* length of name in symbol table */
#define BSIZE 512
#define ITBSZ 256 /*size of the it buffer*/
#define STMAX 200 /*size of intermediate text buffer*/
#define SZIRT 128
#define EXTSZ 512
#define DIRECT 33 /* [vlh] 4.2, number of entries in p2direct */
#define ORGDIR 14 /* [vlh] 4.2, org entry in p2direct */
/*
* 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;
};
short mode; /*operand mode (byte, word, long)*/
short modelen; /*operand length per mode*/
/* parameters that define the main table*/
#define SZMT 300 /*initial size of the main table */
/*must be large enough to initialize*/
#define ICRSZMT 10 /*add to main table when run out*/
short cszmt; /*current size of main table*/
char *bmte; /*beginning of main table*/
char *emte; /*end of main table*/
short itbuf[ITBSZ]; /*it buffer*/
struct it stbuf[STMAX]; /*holds it for one statement*/
#define STBFSIZE (sizeof stbuf[0])
char sbuf[BSIZE]; /*holds one block of source*/
/* format of a symbol entry in the main table*/
struct symtab {
char name[NAMELEN]; /*symbol name*/
short flags;
long vl1; /*symbol value*/
char *tlnk; /*table link*/
} *symtptr;
/* STESIZE - byte length of symbol table entry -- should be 18 */
/* must use a sizeof to avoid over run variables */
#define STESIZE (sizeof *symtptr)
char *lmte; /*last entry in main table */
struct irts {
char *irle; /*ptr to last entry in chain*/
char *irfe; /*ptr to first entry in chain*/
};
long stlen; /*length of symbol table*/
/*initial reference table for symbols*/
char *sirt[SZIRT];
#define SIRTSIZE (sizeof sirt[0])
/*initial reference table to opcodes*/
char *oirt[SZIRT];
#define OIRTSIZE (sizeof oirt[0])
/*external symbol table*/
char *extbl[EXTSZ];
short extindx; /*index to external symbol table*/
char **pexti; /*ptr to external symbol table*/
short absln; /*absolute line number*/
short p2absln; /*pass 2 line number*/
short fcflg; /*0=>passed an item. 1=>first char*/
short fchr; /*first char in term*/
short ifn; /*source file descriptor*/
short *pitix; /*ptr to it buffer*/
short itwc; /*number of words in it buffer*/
struct it *pitw; /*ptr to it buffer next entry*/
short itype; /*type of item*/
long ival; /*value of item*/
char *lblpt; /*label pointer*/
char lbt[NAMELEN]; /*holds label name*/
long loctr; /*location counter*/
long savelc[4]; /*save relocation counters for 3 bases*/
short nite; /*number of entries in stbuf*/
struct it *pnite;
short lfn; /*loader output file descriptor*/
char *opcpt; /*pointer to opcode entry in main table*/
short p2flg; /*0=>pass 1 1=>pass 2*/
char **pirt; /*entry in initial reference table*/
short reloc; /*reloc value returned by expr evaluator (expr)*/
short rlflg; /*relocation value of current location counter*/
struct hdr couthd; /* cout header structure */
short format;
short sbuflen; /*number of chars in sbuf*/
char *psbuf; /*ptr into sbuf*/
short itfn; /*it file number*/
char itfnc; /*last char of it file name*/
short trbfn; /*temp for text relocation bits*/
char trbfnc; /*last char of text rb file*/
short dafn; /*file for data stuff*/
char dafnc; /*last char of data file*/
short drbfn; /*file for data relocation bits*/
char drbfnc; /*last char*/
short prtflg; /*print output flag*/
short undflg; /*make undefined symbols external flag*/
short starmul; /* * is multiply operator*/
/* Symbol Table Pointers for Subset of Opcodes */
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;
short numcon[2], numsym[2], indir[2], immed[2], numreg[2];
short plevel; /*parenthesis level counter*/
short opdix; /*operand index counter*/
/* ptrs to ins[] and rlbits[]*/
short *pins;
short *prlb;
short ins[5]; /*holds instruction words*/
#define PRTCHLEN 128
char prtchars[PRTCHLEN];/*line buffer for putchar*/
char *prtchidx; /*index for putchar*/
short extflg, extref; /*external in expr*/
struct op {
short ea; /*effective address bits*/
short len; /*effective address length in bytes*/
long con; /*constant or reloc part of operand*/
short drlc; /*reloc of con*/
short ext; /*external variable #*/
short idx; /*index register if any*/
short xmod; /*mode of index reg*/
} opnd[2];
struct iob {
int fd; /* file descriptor */
int cc; /* char count */
char *cp; /* next char pointer */
char cbuf[BSIZE]; /* character buffer */
} lbuf, tbuf, dabuf, drbuf;
char tfilname[];
#define LASTCHTFN tfilname[11]
/* assembler flag variables */
short didorg;
short shortadr; /*short addresses if set*/
short initflg; /*initialize flag*/
short m68010; /*[vlh] 4.2, 68010 code*/
/* pass 1 global variables */
short numops; /*number of operands*/
short inoffset; /*[vlh]offset directive*/
short p1inlen; /*pass 1 instr length*/
/* pass 2 global variables */
short instrlen; /*pass 2 bytes in current instruction*/
/* General Assembler Variables */
short stdofd;
extern int errno;
char peekc;
short ca_true; /* true unless in a false CA*/
short ca; /* depth of conditional assembly, none = 0*/
short ca_level; /* at what CA depth did CA go false?*/
short nerror; /*# of assembler errors*/
short in_err; /*[vlh] don't generate instrlen err if in err state*/
long itoffset;
short equflg; /*doing an equate stmt*/
short refpc; /* * referenced in expr*/
/* defines */
#define tolower(c) ((c)<='Z' && (c)>='A') ? (c)|32 : (c)
#define islower(c) ((c) <= 'z' && (c) >= 'a')
#define isalpha(c) (islower( (c) | 32 ))
#define isdigit(c) ((c) >= '0' && (c) <= '9')
#define isalnum(c) (isalpha(c) || isdigit(c))
#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)
#define ckreg(ap) ((ap)->ea>=0 && (ap)->ea<=AREGHI)
#define DBGSTRT() putchar(0); stdofd = 2
#define DBGEND() putchar(0); stdofd = 0
/* Predeclared Functions which return values */
long lseek();
char *sbrk();
char *lemt();
int endit();
int rubout();
int p2gi();
int (*p2direct[])();
/* Second Pass Subroutines */
int opf1(), opf2(), opf3(), opf4(), opf5(), relbr(), opf7(), opf8();
int opf9(), opf11(), opf12(), opf13(), opf15(), opf17(), opf20();
int opf21(), opf22(), opf23(), opf31();
/* Directive Handling Subroutines */
int hopd(), hend(), send(), horg(), sorg(), hequ(), hreg();
int hds(), sds(), sdcb();
int hdsect(), hpsect(), sdsect(), spsect();
int hsection(), ssection(), hoffset();
int hent(), hext();
int igrst();
int hbss(), sbss();
int heven(), seven();
int hdc(), sdc(), hdcb();
int hmask2(), hcomline(), hidnt(), httl(), hpage();
int hifeq(), hifne(), hiflt(), hifle(), hifgt(), hifge(), hendc();
int hifnc(), hifc(), hopt();

View File

@@ -0,0 +1,235 @@
**
* Copyright 1981
* Alcyon Corporation
* 8716 Production Ave.
* San Diego, Ca. 92121
*
* 68010 added operands: movec, moves, rtd.
* 68010 added control registers: sfc, dfc, vsr.
* [vlh] 3 august 83
**
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
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
sp: .equ 15,r
ccr: .equ 16,r
sr: .equ 17,r
usp: .equ 18,r
USP: .equ 18,r
pc: .equ 22,r
PC: .equ 22,r
sfc: .equ 23,r
SFC: .equ 23,r
dfc: .equ 24,r
DFC: .equ 24,r
vsr: .equ 25,r
VSR: .equ 25,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
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
movec: .opd 31,@047172
movem: .opd 20,@044200
movep: .opd 21,@000010
moveq: .opd 22,@070000
moves: .opd 31,@007000
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
rtd: .opd 14,@047164
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,10 @@
c68 -L -r -DMC68000 -c dir.c
c68 -L -r -DMC68000 -c expr.c
c68 -L -r -DMC68000 -c misc.c
c68 -L -r -DMC68000 -c pass1a.c
c68 -L -r -DMC68000 -c pass2.c
c68 -L -r -DMC68000 -c symt.c
c68 -L -r -DMC68000 -c main.c
mkver -e "assembler -"
c68 -n -L -r -DMC68000 -r dir.o expr.o misc.o pass1a.o pass2.o symt.o main.o version.c -o as68.4k -l6
setstack as68.4k 8192 8192

View File

@@ -0,0 +1,10 @@
mkver -e "assembler -"
cc -w -DPDP11 -c dir.c
cc -w -DPDP11 -c expr.c
cc -w -DPDP11 -c main.c
cc -w -DPDP11 -c misc.c
cc -w -DPDP11 -c pass1a.c
cc -w -DPDP11 -c pass2.c
cc -w -DPDP11 -c symt.c
cc -w -DPDP11 -c version.c
cc -n dir.o expr.o misc.o pass1a.o pass2.o symt.o main.o seek.o lseek.o version.o -o as68.pdp -l6 -lC

View File

@@ -0,0 +1,10 @@
mkver -e "assembler -"
cc -O -w -DVAX11 -c dir.c
cc -O -w -DVAX11 -c expr.c
cc -O -w -DVAX11 -c main.c
cc -O -w -DVAX11 -c misc.c
cc -O -w -DVAX11 -c pass1a.c
cc -O -w -DVAX11 -c pass2.c
cc -O -w -DVAX11 -c symt.c
cc -O -w -DVAX11 -c version.c
cc -n dir.o expr.o misc.o pass1a.o pass2.o symt.o main.o version.o ../binary/libV.a -o as68.vax

View File

@@ -0,0 +1,152 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char *ermsg[] = {
0, /*1*/
"invalid label", /*2*/
"invalid opcode", /*3*/
"no label for operand", /*4*/
"opcode redefined", /*5*/
"illegal expr", /*6*/
"undefined symbol in equate", /*7*/
"opcode for 68010 only", /*8*/ /* [vlh] 4.2 */
"invalid first operand", /*9*/
"invalid second operand", /*10*/
"absolute value required", /*11*/
"no code or data allowed in offset",/*12*/
"undefined symbol", /*13*/
"illegal index register", /*14*/
"illegal constant", /*15*/
"illegal extension", /*16*/ /*[vlh]*/
"constant required", /*17*/
"illegal format", /*18*/
"illegal string", /*19*/
"illegal addressing mode", /*20*/
"assembler confusion...", /*21*/ /*[vlh] should never get this*/
"illegal relative address", /*22*/
"invalid bit range", /*23*/
"illegal text delimiter", /*24*/
"unexpected endc", /*25*/
"endc expected", /*26*/
"relocation error", /*27*/
"symbol required", /*28*/
"bad use of symbol", /*29*/
"invalid data list", /*30*/
"warning: cmpm generated for 68010",/*31*/ /* [vlh] 4.2 */
"missing )", /*32*/
"register required", /*33*/
"illegal size", /*34*/
"illegal 8-bit displacement", /*35*/
"illegal external", /*36*/
"illegal shift count", /*37*/
"invalid instruction length", /*38*/
"code or data not allowed in bss", /*39*/
"backward assignment to *", /*40*/
"illegal 16-bit displacement", /*41*/
"illegal 16-bit immediate", /*42*/
"illegal 8-bit immediate", /*43*/
0
};
char tfilname[] = "/tmp/a6xxxxA"; /*temp file for it*/
#ifdef MC68000
char initfnam[] = "/lib/as68symb"; /*initialize file name*/
#else
char initfnam[] = "/usr/local/lib/as68symb";
#endif
char ldfn[40]; /*name of the relocatable object file*/
short brkln1 = 077777; /*pass 1 break line number for debugging*/
short opcval; /*opcode*/
short chmvq;
int (*p1direct[])() = { /* [vlh] 4.2, better have DIRECT number of entries... */
hopd, /*0*/
hend, /*1*/
hdsect, /*2*/
hpsect, /*3*/
hequ, /*4*/
hequ, /*5 .set same as .equ*/
0, /*6*/
0, /*7*/
hdc, /*8*/
hent, /*9*/
hext, /*10*/
hbss, /*11*/
hds, /*12*/
heven, /*13*/
horg, /*14*/
hmask2, /*15*/
hreg, /*16*/
hdcb, /*17*/
hcomline, /*18*/
hidnt, /*19*/
hoffset, /*20*/
hsection, /*21*/
hifeq, /*22*/
hifne, /*23*/
hiflt, /*24*/
hifle, /*25*/
hifgt, /*26*/
hifge, /*27*/
hendc, /*28*/
hifc, /*29*/
hifnc, /*30*/
hopt, /*31*/
httl, /*32*/
hpage, /*33*/
0};
int (*p2direct[])() = { /* [vlh] 4.2, better have DIRECT number of entries... */
0, /*0*/
send, /*1*/
sdsect, /*2*/
spsect, /*3*/
0, /*4*/
0, /*5*/
0, /*6*/
0, /*7*/
sdc, /*8*/
0, /*9*/
0, /*10*/
sbss, /*11*/
sds, /*12*/
seven, /*13*/
sorg, /*14*/
0, /*15*/
0, /*16*/
sdcb, /*17*/
sds, /*18 comline same as .ds.b*/
0, /*19*/
0, /*20*/
ssection, /*21*/
0, /*22*/
0, /*23*/
0, /*24*/
0, /*25*/
0, /*26*/
0, /*27*/
0, /*28*/
0, /*29*/
0, /*30*/
0, /*31*/
0, /*32*/
0, /*33*/
0};
short symcon;
char endstr[] = "end";
char equstr[] = "equ";
char evnstr[] = "even";
char orgstr1[] = "~.yxzorg";
char orgstr2[] = "org";
short poslab;
char tlab1[NAMELEN];
short explmode; /*explicit mode length given*/

View File

@@ -0,0 +1,939 @@
/*
Copyright 1983
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"
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(TRUE,oirt))!=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(FALSE,sirt))!=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 = LONGSIZ;
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)
int xrtyp;
{
inoffset = 0; /* [vlh] offset mode terminated my sect directive */
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()
{
if(loctr&1) { /*have to make it even*/
dorlst(rlflg);
loctr++;
}
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(FALSE,sirt)) == 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(FALSE,sirt)) == 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.hiword = ival; /* # bytes of storage required*/
}
else
lblpt->vl1.hiword = 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.loword = (int)(pexti - extbl); /* external symbol index #*/
*pexti++ = p; /*save external in external table*/
extindx++;
}
/* end statement*/
hend()
{
register short i;
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*/
if(pitix > itbuf) /*some it in buffer*/
if(write(itfn,itbuf,ITBSZ*(sizeof i)) != ITBSZ*(sizeof i)) {
rpterr("I/O write error on it file\n");
endit();
}
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()
{
chkeven(); /*may need to make pc even*/
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>BYTESIZ && (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)
int 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()
{
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] */
{
short mask;
if(lbt[0]==0) {
xerr(4); /*no label*/
return;
}
setname(); /*move label into main table*/
if((lblpt=lemt(FALSE,sirt))!=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();
}
short 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 short *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 short 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 = BYTESIZ; /* 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;
}
rlflg = (ival==14) ? DATA : (ival==15) ? BSS : 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();
}
/* hpage - page directive, ignore */
hpage() /* vlh */
{
igrst();
}
/* httl - title directive, ignore */
httl() /* vlh */
{
igrst();
}
/**** Second pass directive handling routines ****/
/* second pass end statement*/
send()
{
register short i;
savelc[rlflg] = loctr;
if(savelc[TEXT]&1) {
rlflg = TEXT;
outbyte(0,DABS);
}
if(savelc[DATA]&1) {
rlflg = DATA;
outbyte(0,DABS);
}
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) == -1L) || lwritel(lfn,&stlen) == -1)
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 short pfg, i, hflg, len;
pfg = hflg = 0;
expr(&p2gi);
if (itype != ITCN || reloc != ABS) {
uerr(13); /* must be absolute constant */
return;
}
len = ival;
expr(&p2gi);
if (modelen == BYTESIZ && (ival<-128 || ival>=256 || reloc != ABS)) {
uerr(20);
ival = 0;
reloc = ABS;
}
while (len--) {
if (modelen == BYTESIZ) {
if (!hflg) {
ins[i].hibyte = ival;
outbyte((int)ival.loword,DABS);
hflg++;
}
else {
ins[i++].lobyte = ival;
outbyte((int)ival.loword,DABS);
hflg=0;
}
goto sdbl2;
}
else if (modelen == WORDSIZ) {
sdbl1:
ins[i++] = ival.loword;
outword((int)ival.loword, reloc);
sdbl2:
if (i>3) {
instrlen = i*2;
print ((pfg++) ? 2 : 1);
loctr += instrlen;
i=0;
}
}
else { /* long word... */
ins[i++] = ival.hiword;
outword((int)ival.hiword,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()
{
register 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)
int dtyp;
{
register short pfg,i, 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((int)ival.loword,DABS);
hflg++;
}
else {
ins[i++].lobyte = ival;
hflg = 0;
outbyte((int)ival.loword,DABS);
}
goto sdal2;
}
else if(dtyp == 2) { /*defining a word*/
sdal1:
ins[i++] = ival.loword;
outword((int)ival.loword, reloc);
sdal2:
if(i>3) {
instrlen = i*2;
print ((pfg++) ? 2 : 1);
loctr += instrlen;
i=0;
}
}
else { /*long words*/
ins[i++] = ival.hiword;
outword((int)ival.hiword,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] */
{
short sect;
sect = stbuf[3].itrl;
if (sect==DATA)
sdsect();
else if (sect==BSS)
sbss();
else
spsect();
}
/**** 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();
}
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() /* return 1 true, 0 false */
{
char str1[25], str2[25];
register short len1, len2;
if (fchr != '\'') {
xerr(9);
return(0);
}
len1 = len2 = 0;
while ((fchr = gchr()) && fchr != '\'') {
if (fchr == EOLC)
return(0);
str1[len1++] = fchr;
}
if ((fchr=gchr()) != ',') {
xerr(9);
return(0);
}
if ((fchr=gchr()) != '\'') {
xerr(10);
return(0);
}
while ((fchr = gchr()) && fchr != '\'') {
if (fchr == EOLC)
return(0);
str2[len2++] = fchr;
}
igrst();
if (len1 != len2)
return(0);
str1[len1] = str2[len2] = NULL;
return((strcmp(str1,str2) == 0));
}
strcmp(s,t)
char *s, *t;
{
for( ; *s == *t; s++, t++ )
if( *s == '\0' )
return(0);
return( *s - *t );
}

View File

@@ -0,0 +1,511 @@
/*
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*/
#define OPSTLEN 10
#define TREELEN 20
/*global short's for this package*/
struct it exitm; /*expression item*/
short prcnt; /*paren count*/
short rval; /*relocation value*/
short lpflg;
short 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;
short iop, itr;
struct it opstk[OPSTLEN]; /*operator stack*/
struct it tree[TREELEN]; /*operand stack*/
expr(iploc)
int (*iploc)();
{
register short 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 = '?';
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=(int)ival.loword); /*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(); 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=(int)piop->itop.loword)) { /* >= 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 short rv1, rv2, topr, i, bos, low;
register long tv1;
long 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 */
low = tv2.loword;
tv1 <<= low; break;
case '>': /* right shift */
low = tv2.loword;
tv1 >>= low; break;
default: /*invalid operator*/
exerr(); 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.loword=='?')
{ exerr(); return; }
if (tree[bos+1].itty!=ITSP || tree[bos].itty==ITSP) {
reloc = ABS;
ival = 0;
itype = ITCN;
return;
}
if(tree[bos+1].itop.loword!='?') { /*end of statement*/
if(tree[bos+1].itop.loword!='+') { /*ignore unary plus*/
if(tree[bos+1].itop.loword!='-') { /* invalid operator */
exerr();
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() /* [vlh] */
{
uerr(6);
ival = 0;
itype = ITCN;
reloc = ABS;
}
/*
* get precedence of a operator
* call with
* operator
* returns
* precedence
*/
gprc(dprc)
int 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(FALSE,sirt); /*look 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)
int acksc;
{
register short 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)
int 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)
int 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)
int 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.loword; /*get external #*/
rval = EXTRN;
itype = ITCN;
ival = 0;
}

View File

@@ -0,0 +1,170 @@
.he "As68"Revisions"Page %"
.de bg
.sp
.in +5
..
.de eg
.sp
.ne 8
.in -5
..
1. [vlh] 15 sep 82
.bg
Added fix to make location relative equates correct even if branch
optimization occurs.
.eg
2. [vlh] 17 sep 82
.bg
Recognizes commands in uppercase. Added recognization of upper case
directives which do not have the preceding '.'.
.eg
3. [vlh] 17 sep 82
.bg
Added recognizing of ignored directives IDNT, ORG and MASK2.
Added new directives XDEF, XREF.
.eg
4. [vlh] 20 sep 82
.bg
Added COMLINE and SECTION.
.eg
5. [vlh] 21 sep 82
.bg
Added new directive REG.
.eg
6. [vlh] 22 sep 82
.bg
Added new directives DCB and OFFSET.
.eg
7. [vlh] 22 sep 82
.bg
Recognizes branch extensions and takes the appropriate action.
.eg
8. [vlh] 23 sep 82
.bg
Added assembler directives ifeq, ifne, ifle, iflt, ifge, ifgt.
.eg
9. [vlh] 23 sep 82
.bg
Added character '$' to set of legitimate characters in a symbol.
.eg
10. [vlh] 23 sep 82
.bg
Added new ignored directive OPT.
.eg
11. [vlh] 23 sep 82
.bg
Recognizes non-opcodes starting in column 1 as labels.
.eg
12. [vlh] 27 sep 82
.bg
Added conditional assembler directives ifc, ifnc.
.eg
13. [vlh] 01 oct 82
.bg
Major reworking of expression handler.
.eg
14. [vlh] 04 oct 82
.bg
More revisions to expression stacks.
.eg
15. [vlh] 26 oct 82
.bg
Added the recognition and handling of the 'illegal' instruction.
.eg
16. [vlh] 26 oct 82
.bg
Added handling of the jmp suffixes.
.eg
17. [vlh] 27 oct 82
.bg
Fixed problem with -p flag and external variable listings.
.eg
18. [vlh] 28 oct 82
.bg
Added checking for legitimate command suffixes.
.eg
19. [vlh] 28 oct 82
.bg
Added comma as a legitimate register divisor for the REG directive.
.eg
20. [vlh] 28 oct 82
.bg
Fixed second pass error/instr len problem
.eg
21. [vlh] 01 nov 82
.bg
Added checking for invalid bit ranges.
.eg
22. [vlh] 02 nov 82
.bg
Added proper 2nd pass handling of the '*' symbol (avoid turning jsr to bra).
.eg
23. [vlh] 04 nov 82
.bg
Fixed first pass guess if operand is (rx,rx) instead of d(rx,rx).
.eg
24. [vlh] 05 nov 82
.bg
Check for appropriate range of 16-bit immediate date.
.eg
25. [vlh] 05 nov 82
.bg
Operand type check for shift/bit manipulation.
.eg
26. [vlh] 05 nov 82
.bg
Turn and/or/eor #xxx,sr/ccr into the corresponding immediate instruction.
.eg
27. [vlh] 10 nov 82
.bg
Generate an error when an illegal pc relative ea is specified.
.eg
28. [vlh] 21 dec 82
.bg
Ignore PAGE and TTL macros.
.eg
29. [vlh] 7 jan 83
.bg
Generate an error on ".bss\n.dc.b 1\n".
.eg
30. [vlh] 19 jan 83
.bg
Generate an error on "move ccr,??".
.eg
31. [bea] 09 mar 83
.bg
Fixed problem of )* in expression.
.eg
32. [vlh] 16 mar 83
.bg
\&.ds should be allowed inside .offset
.eg
33. [vlh] 18 apr 83, version 4.1
.bg
Made it portable to vaxens via the use of #define's.
.eg
34. [vlh] 19 jul 83
.bg
Added the '-a' flag, made '-L' the default.
.eg
35. [vlh] 25 jul 83
.bg
Forced local symbols to be put into the symbol table even if non-unique.
.eg
36. [vlh] 03 aug 83
.bg
Made changes to as68init required for use with the 68010. Added
the new opcodes for movec, moves and rtd, and the new control registers
sfc, dfc and vsr.
.eg
37. [vlh] 04 aug 83
.bg
Added a new routine opf13 to handle the opcodes movec and moves. Added the
new code to opf9 to handle rtd.
.eg
38. [vlh] 07 sep 83
.bg
Made rpterr increment the number of errors which had occured in order to
force endit to return a bad status.
.eg

View File

@@ -0,0 +1,59 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#ifdef PDP11
struct {
char lobyte;
char hibyte;
};
struct {
char *ptrw1;
char *ptrw2;
};
struct {
short hiword; /* formally wd1 */
short loword; /* formally wd2 */
};
struct {
int swd1;
};
#endif
#ifdef MC68000
struct {
char hibyte;
char lobyte;
};
struct {
char *ptrw2;
};
struct {
short hiword; /* formally wd1 */
short loword; /* formally wd2 */
};
struct {
int swd1;
};
#endif
#ifdef VAX11
struct {
short loword;
short hiword;
};
struct {
short swd1;
};
struct {
char lobyte;
char hibyte;
};
struct {
char *ptrw2;
};
#endif

View File

@@ -0,0 +1,801 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char *version = "@(#)as68 assembler 4.2 - Sep 6, 1983";
/*
* a two pass relocatable assembler for the Motorola 68000 microprocessor
*
* Bill Allen
* Modified by Vicki Hutchison
*
* after any of this assembler is recompiled, it must be initialized
* before it will execute properly. To initialize, become super user
* and execute the command:
*
* as68 -i as68init
*
* where as68 is the newly compiled version of the assembler. With-
* out this initialization, the assembler will not run (probably bus
* error).
*/
#include "as68.h"
#include "def.h"
#include <signal.h>
#define INIT(op,ptr) pack(op,lmte); ptr=lemt(TRUE,oirt)
main(argc,argv)
int argc;
char **argv;
{
register short i, ttmp;
register long longtmp;
nerror = initflg = 0;
prtchidx = prtchars;
signal(SIGINT,rubout);
pitix = itbuf;
pexti = extbl;
ttmp = (STESIZE*SZMT) + 2;
bmte = sbrk(ttmp);
longtmp = bmte; /* 11 apr 83, for vax */
if(longtmp&1L) /* 11 apr 83, for vax */
bmte++; /*make it even*/
emte = bmte + ttmp - 2; /*end of main table*/
if(argc<=1)
usage();
i = 1;
shortadr = 0; /*long addresses...*/
while(argv[i][0] == '-') { /*may be print or initialize*/
switch(argv[i++][1]) {
case 'a': /*[vlh] 4.2, short addresses only*/
shortadr = -1;
break;
case 'i': /*initialize the assembler*/
initflg++;
break;
case 'p': /*produce a listing*/
prtflg++;
break;
case 'u': /*make undefined symbols external*/
undflg++;
break;
case 'N': /*no branch optimization*/
didorg++;
break;
case 'L': /*4.2 OBSOLETE, long addresses only*/
shortadr = 0;
break;
case 'T': /*generating code suitable for the 68010*/
m68010++;
break;
default:
usage();
}
}
if(i>=argc)
usage();
ifn=openfi(argv[i],0); /*open source file*/
setldfn(argv[i]); /*create relocatable object file name*/
lfn=openfi(ldfn,1); /*open loader file*/
itfn = gettempf(); /*get a temp file for it*/
itfnc = LASTCHTFN; /*remember last char for unlink*/
trbfn = gettempf(); /*temp for text relocation bits*/
trbfnc = LASTCHTFN;
dafn = gettempf(); /*temp for data binary*/
dafnc = LASTCHTFN;
drbfn = gettempf(); /*temp for data relocation bits*/
drbfnc = LASTCHTFN;
if(initflg) { /*initializing te main table*/
lmte=bmte; /*beginning main table*/
cszmt = SZMT; /*current size of main table*/
for(i = 0; i <= SZIRT-2; i += 2) {
sirt[i] = &sirt[i]; /*initialize the initial ref tables*/
sirt[i+1] = 0;
oirt[i] = &oirt[i];
oirt[i+1] = 0;
}
/*make entries in main table for directives*/
mdemt("opd",0); /*opcode definition*/
mdemt(endstr,1); /*end statement*/
mdemt("data",2); /*dsect directive(code DATA based)*/
mdemt("text",3); /*psect directive(code TEXT based)*/
mdemt(equstr,4); /*equate*/
mdemt("set",5); /*.set - same as .equ*/
mdemt("dc",8); /*define byte*/
mdemt("globl",9); /*define global (public) symbols*/
mdemt("xdef",9); /*[vlh]define global (public) symbols*/
mdemt("xref",9); /*[vlh]define global (public) symbols*/
mdemt("comm",10); /*define external symbols*/
mdemt("bss",11); /*block storage based*/
mdemt("ds",12); /*block storage based*/
mdemt(evnstr,13); /*round pc*/
mdemt(orgstr1,14); /*[vlh] internal, *= */
mdemt(orgstr2,14); /*[vlh] org location, also *= */
mdemt("mask2",15); /*[vlh] assemble for mask2, ignore*/
mdemt("reg",16); /*[vlh] register equate*/
mdemt("dcb",17); /*[vlh] define block*/
mdemt("comline",18); /*[vlh] command line*/
mdemt("idnt",19); /*[vlh] relocateable id record, ignore*/
mdemt("offset",20); /*[vlh] define offsets*/
mdemt("section",21); /*[vlh] define sections*/
mdemt("ifeq",22); /*[vlh] ca if expr = 0*/
mdemt("ifne",23); /*[vlh] ca if expr != 0*/
mdemt("iflt",24); /*[vlh] ca if expr < 0*/
mdemt("ifle",25); /*[vlh] ca if expr <= 0*/
mdemt("ifgt",26); /*[vlh] ca if expr > 0*/
mdemt("ifge",27); /*[vlh] ca if expr >= 0*/
mdemt("endc",28); /*[vlh] end ca*/
mdemt("ifc",29); /*[vlh] ca if string compare*/
mdemt("ifnc",30); /*[vlh] ca if not string compare*/
mdemt("opt",31); /*[vlh] ignored, assemb options*/
mdemt("ttl",32); /*[vlh] ttl define, ignore*/
mdemt("page",33); /*[vlh] page define, ignore*/
}
else /*not initializing*/
getsymtab(); /*read initialized main table*/
rlflg = TEXT; /*code initially TEXT based*/
inoffset = 0; /*[vlh]not in offset mode*/
loctr = 0; /*no generated code*/
ca = 0; /*[vlh]depth of conditional assembly*/
extindx = 0; /*no external symbols yet*/
p2flg = 0; /*pass 1*/
ca_true = 1; /*[vlh]true unless in side false case*/
absln = 1;
sbuflen = -1; /*no source yet*/
fchr = gchr(); /*get first char*/
if(!initflg) { /*not initializing*/
INIT(orgstr2,orgptr);
INIT(endstr,endptr);
INIT(equstr,equptr);
INIT("add",addptr);
INIT("addi",addiptr);
INIT("addq",addqptr);
INIT("sub",subptr);
INIT("subi",subiptr);
INIT("subq",subqptr);
INIT("cmp",cmpptr);
INIT("adda",addaptr);
INIT("cmpa",cmpaptr);
INIT("suba",subaptr);
INIT("cmpm",cmpmptr);
INIT("and",andptr);
INIT("andi",andiptr);
INIT("or",orptr);
INIT("ori",oriptr);
INIT("cmpi",cmpiptr);
INIT("eor",eorptr);
INIT("eori",eoriptr);
INIT("move",moveptr);
INIT("moveq",moveqptr);
INIT("exg",exgptr);
INIT("jsr",jsrptr);
INIT("bsr",bsrptr);
INIT("nop",nopptr);
INIT(evnstr,evenptr);
}
mloop();
}
usage()
{
rpterr("Usage: as68 [-p] [-u] [-L] [-N] sourcefile\n");
endit();
}
/*main loop*/
mloop()
{
register short i;
while(fchr!=EOF) {
if(absln>=brkln1) /*break for debugging the assembler*/
i=0;
fcflg = 0; /*first time thru expr pass one*/
cisit(); /*create it for one statement*/
}
opcpt = endptr;
hend();
}
#define NOCODE ((i>=0&&i<6)||i==9||i==11||i==12||i==16||(i>=20&&i<=30))
/* cond-directives, section, ds, set, equ, reg, globl, end, offset */
/*create intermediate text (it) for one statement*/
/* call with first character of statement in fchr*/
cisit()
{
register short *p1,*p2;
register short (*dirop)();
register short i, col1; /*[vlh] col1 labels in col 1...*/
char str[NAMELEN], *l;
ciss1:
immed[0] = immed[1] = indir[0] = indir[1] = numcon[0] = 0;
numcon[1] = numsym[0] = numsym[1] = numreg[0] = numreg[1]=0;
plevel = numops = opdix = explmode = 0;
cistop:
col1 = 1;
if(fchr==EOLC) {
fchr = gchr();
goto cistop;
}
if(fchr==' ') {
col1 = 0;
igblk();
if(fchr==EOLC) /*blank line*/
goto cistop;
peekc = fchr;
if (fchr != EOF)
fchr = ' '; /* [vlh] catch eof... */
}
if(fchr==EOF)
return;
if(fchr=='*') { /*ignore comments*/
fchr = gchr();
if(fchr=='=') { /*relocation counter assignment*/
fchr = gchr(); /*pass the =*/
horg(); /*output constants if not bss*/
}
igrst();
fcflg = 0; /*clear expr first time flag for next stmt*/
goto ciss1;
}
/* get the opcode and label*/
mode = 'w'; /*word mode*/
igblk(); /*ignore blanks*/
poslab = 1;
gterm(TRUE);
poslab = 0;
if(fchr==':' || fchr=='=') { /*there is a label*/
label:
col1 = 0;
if(itype!=ITSY) { /*not a symbol*/
uerr(2);
lbt[0] = (char)0; /*no label*/
}
else {
p2 = &lmte->name[0];
for(p1= &lbt[0]; p1 < &lbt[NAMELEN]; ) {
*p1++ = *p2++;
}
if(fchr==':')
fchr=gchr(); /*ignore the colons*/
}
labl1:
ligblk();
if(fchr == EOF)
return;
if(fchr == '*') {
igrst(); /*comment*/
goto labl1;
}
gterm(TRUE);
if(fchr==':' || fchr=='=') { /*another label*/
if(lbt[0]) {
strcpy(tlab1,lmte,NAMELEN); /*save current label */
dlabl(); /*define the last one*/
pack(tlab1,lmte); /*restor the old lable*/
}
goto label;
}
}
else
lbt[0] = 0; /*no label*/
igblk();
if(fchr == '=')
goto label;
if(itype==ITSP) {
if(ival.loword == '=') {
hequ();
return;
}
}
if(itype!=ITSY) /*not valid opcode*/
goto cisi3;
if (col1) { /* [vlh] could be a label save as is... */
l = &str;
strcpy(l,lmte->name,NAMELEN);
}
if((opcpt=lemt(TRUE,oirt))==lmte) { /*not in opcode table*/
if (col1) { /* [vlh] it's a label... */
strcpy(lmte->name,l,NAMELEN);
goto label;
}
cisi3:
if (ca_true) /* [vlh] report error if not in CA false */
xerr(3);
igrst();
return;
}
getmode(); /*look for .b .w or .l mode flag*/
if(opcpt->flags&OPDR) { /* its a directive*/
i = opcpt->vl1;
if (!ca_true && (i < LOW_CA || i > HI_CA)) { igrst(); return; }
if (inoffset) /* [vlh] */
if (!(NOCODE)) { /* can't generate code in offset */
xerr(12);
return;
}
dirop = p1direct[i]; /*call routine to handle directive*/
(*dirop)();
return;
}
else if (!ca_true) { /* [vlh] */
igrst();
return;
}
else if (inoffset) { /* [vlh] */
xerr(12);
return;
}
opcval = (opcpt->vl1); /*opcode*/
format = (opcpt->flags&OPFF); /*format of this instr*/
if (explmode)
if (!modeok()) { xerr(16); return; }
dlabl(); /*define label*/
opitb(); /*beginning of statement*/
if(format)
opito(); /*may have operands*/
else
igrst(); /*only comments*/
format = (opcpt->flags&OPFF); /* may have changed*/
/*end of statement*/
i = calcilen();
stbuf[1].itrl = i; /*assumed instruction length*/
stbuf[0].itrl = itwc; /*number of it entries*/
wostb(); /*write out statement buffer*/
loctr += i;
}
getmode()
{
if (fchr=='.') {
fchr = gchr();
switch (fchr) {
case 'b':
case 'B':
case 's':
case 'S':
modelen = BYTESIZ;
mode = BYTE;
break;
case 'w':
case 'W':
modelen = WORDSIZ;
mode = WORD;
break;
case 'l':
case 'L':
modelen = LONGSIZ;
mode = LONG;
break;
default:
peekc = fchr;
fchr = '.';
goto getm1;
}
explmode++;
fchr = gchr();
igblk();
return;
}
getm1:
if(opcpt == exgptr) { /*length is long*/
modelen = LONGSIZ;
mode = LONG;
}
else {
mode = WORD; /*default is word*/
modelen = WORDSIZ;
}
}
/* check to be sure specified mode is legal */
modeok() /* [vlh] */
{
switch(format) {
case 0 :
case 14 :
case 18 :
return(FALSE);
case 13 :
case 15 :
case 20 :
case 21 :
return(modelen==BYTESIZ?FALSE:TRUE);
case 4 :
case 25 :
return(modelen==BYTESIZ?TRUE:FALSE);
case 7 :
case 9 :
return(modelen==WORDSIZ?FALSE:TRUE);
case 5 :
case 11 :
case 28 :
return(modelen==WORDSIZ?TRUE:FALSE);
case 6 :
return(modelen==LONGSIZ?FALSE:TRUE);
case 12 :
case 30 :
case 22 :
case 29 :
return(modelen==LONGSIZ?TRUE:FALSE);
default :
return(TRUE);
}
}
/* calculate the instruction length in bytes*/
calcilen()
{
register short i;
register long l;
register char *p;
i = 2; /*all instrs at least 2 bytes*/
switch(format) {
case 20:
i += 2; /*for reg mask*/
case 1: /*two ea's -- one of which may be a reg*/
case 15:
case 30:
case 26:
case 5:
case 3:
case 21:
i += lenea(1);
case 16:
case 24:
case 25:
case 29:
i += lenea(0);
break;
case 9: /* [vlh] explicit jmp length... */
if (!explmode)
i += lenea(0);
else
return(mode==LONG?6:4); /*[vlh] explicit jmp.? */
break;
case 7:
i += (immed[0]) ? 2+lenea(1) : lenea(1);
break;
case 14:
case 11:
case 19:
case 31:
i += 2; /*always 4 bytes*/
break;
case 6: /*relative branches*/
if(itwc == ITOP1+1) {
if(stbuf[ITOP1].itty == ITCN)
l = stbuf[ITOP1].itop;
else if(stbuf[ITOP1].itty == ITSY) {
p = stbuf[ITOP1].itop.ptrw2;
if(p->flags&SYDF)
l = p->vl1; /*symbol value*/
else
goto loffst;
}
else
goto loffst;
l -= (loctr+2);
if(l<=127 && l>=-128) /*8 bit offset*/
break;
}
loffst:
if (!explmode || modelen > BYTESIZ) /*[vlh] recognize br extensions*/
i += 2; /*long offset for branches*/
break;
case 2:
i += (mode==LONG?4:2) + lenea(1);
break;
case 23:
if(immed[0])
i += (mode==LONG?4:2);
case 17:
case 22:
i += lenea(1);
break;
case 8:
if(numops==1) /*memory shift instruction*/
i += shiftea(0);
break;
}
return(i);
}
/* calc the length of an effective address*/
lenea(lidx)
int lidx;
{
if(immed[lidx])
return(mode==LONG?LONGSIZ:WORDSIZ);
return(shiftea(lidx));
}
shiftea(lidx)
int lidx;
{
if(indir[lidx])
return((numcon[lidx] || numsym[lidx]) ? 2 : 0);
if(numsym[lidx] || numcon[lidx])
return((!shortadr || numcon[lidx]==2) ? 4 : 2);
return(0);
}
/*
*define a label if there is one to define
* call with:
* label name in lbt if it exists
* else lbt[0] == 0
*/
dlabl()
{
if(lbt[0]) { /*got a label*/
pack(lbt,lmte); /*put label in main table*/
lblpt=lemt(FALSE,sirt); /*look up label*/
if(lblpt != lmte) { /*symbol entered previously*/
if(lbt[0] == '~') { /*local symbol -- may be duplicate*/
lblpt = lmte;
mmte();
}
else {
if(lblpt->flags&SYXR) {
uerr(29);
lblpt = 0;
return;
}
if((lblpt->flags)&SYDF) {
rpterr("label redefined %s\n",lbt); /* non fatal err */
lblpt = 0;
return;
}
}
}
else {
mmte(); /*make label entry in main table*/
}
lblpt->flags |= SYDF; /*label is now defined*/
lblpt->flags |= (rlflg==DATA)?SYRA:(rlflg==BSS)?SYBS:SYRO;
lblpt->vl1 = loctr; /*label value*/
}
else
lblpt = 0;
}
/*
* output it for operands
* gets intput from gterm
* puts output in stbuf using itwc as an index
* itwc should point at the next entry to be made in stbuf
*/
opito()
{
register short lopcomma;
lopcomma = symcon = chmvq = 0;
numops++; /*count first operand*/
while(1) {
starmul = symcon; /*star is multiply op if flag is set*/
if(fchr=='\'' || fchr=='"')
lopcomma = 0;
gterm(FALSE); /*get a term*/
if(itwc==ITOP1 && format==CLRFOR && opcval==CLRVAL)
chgclr();
opitoo(); /*output it for one operand*/
if(itype==ITSP && ival.loword==',') {
if (plevel==1 && !numcon[opdix]) /* [vlh] */
numcon[opdix] = 1;
if(lopcomma)
uerr(30);
lopcomma++;
igblk(); /*ignore blanks for 68000 C compiler*/
}
else
lopcomma=0;
if(ival==EOLC && itype==ITSP) /*end of operands*/
break;
if(fchr==EOLC) {
fchr=gchr();
break;
}
}
if(chmvq) /*changed move to moveq*/
if(numops!=2 || immed[1] || indir[1] || numcon[1] || numsym[1] ||
numreg[1]>=AREGLO) {
stbuf[2].itop.ptrw2 = moveptr; /*change it back*/
opcpt = moveptr;
}
if (stbuf[2].itop.ptrw2==cmpptr) /* [vlh] cmp -> cmpm ?? */
if (numreg[0] && numreg[1] && indir[0] && indir[1]) {
stbuf[2].itop.ptrw2 = cmpmptr;
opcpt = cmpmptr;
}
if(lopcomma)
uerr(30);
}
/* change clr.l An to suba.l An,An*/
chgclr()
{
register char *p;
if(itype==ITSY) { /*first op is symbol*/
p = lemt(FALSE,sirt);
if(p==lmte)
return;
if(!(p->flags&SYER) || p->vl1<AREGLO) /*not A reg*/
return;
opcpt = subaptr; /*make it a suba instr*/
opitb();
opitoo(); /*output first operand -- An*/
itype = ITSP;
ival = ',';
opitoo(); /*output a comma*/
itype = ITSY; /*now the A reg again*/
}
}
/*output it for one operand*/
opitoo()
{
register char *sp;
symcon = 0;
if(itype==ITSP) { /*special symbol*/
if(ival.loword==',' && !plevel) { /* another operand */
numops++;
if(!opdix)
opdix++;
}
if(ival.loword==')')
symcon = 1; /* star is multiply */
if(ival.loword==' ') { /*end of operands*/
while(fchr!=EOLC) /*ignore rest of statement*/
fchr=gchr();
return;
}
if(ival.loword==EOLC)
return;
}
else /*symbol or constant*/
symcon = 1;
if(itwc >= STMAX) { /*it overflow*/
rpterr("i.t. overflow\n");
abort();
}
pitw->itty = itype; /*type of it entry*/
/*put symbol in it buffer*/
if(itype==ITSY) {
sp=lemt(FALSE,sirt); /*look up it main table*/
pitw->itop.ptrw2 = sp; /*ptr to symbol entry*/
if(sp==lmte) /*first occurrance*/
mmte();
itwc++; /*count entries in it buffer*/
pitw++;
if(!(sp->flags&SYER)) /*is it a register?*/
numsym[opdix]++;
else /*yes, a register*/
numreg[opdix] = sp->vl1;
return;
}
else if(itype == ITCN ) {
if(ival.hiword && ival.hiword != -1)
numcon[opdix] = 2;
else if(!numcon[opdix])
numcon[opdix] = 1;
if(numops == 1)
tryquick();
}
/* special characters and constants*/
pitw->itop = ival;
pitw->itrl = reloc;
itwc++;
pitw++;
}
/* change add into addq and sub into subq if possible*/
tryquick()
{
register char *p;
register long l;
if(fchr!=',' || !immed[0])
return;
l = ival;
if(itwc != ITOP1+1) {
if(itwc!=ITOP1+2 || stbuf[ITOP1+1].itty!=ITSP ||
stbuf[ITOP1+1].itop.loword != '-')
return;
l = -l;
}
p = stbuf[2].itop.ptrw2;
if(p==moveptr) {
if(explmode && modelen != LONGSIZ) /*dont change .w or .b*/
return;
if(l>=-128 && l<=127) {
stbuf[2].itop.ptrw2 = moveqptr;
opcpt = moveqptr;
chmvq++;
}
return;
}
if(l<=0 || l>8) {
return;
}
if(p==addptr || p==addiptr) {
stbuf[2].itop.ptrw2 = opcpt = addqptr;
}
else if(p==subptr || p==subiptr) {
stbuf[2].itop.ptrw2 = opcpt = subqptr;
}
}
strcpy(astr1, astr2, alen)
char *astr1, *astr2;
register int alen;
{
register char *str1, *str2;
str1 = astr1;
str2 = astr2;
while (--alen != -1)
*str1++ = *str2++;
}
/* 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 short i;
for( s = str, i = 0; *s != '\0'; i++ )
if( *s++ == chr )
return(i);
return(-1);
}

View File

@@ -0,0 +1,79 @@
CC = cc
C68 = nc68
SOURCES = dir.c expr.c misc.c pass1a.c pass2.c symt.c main.c
INCLUDES = as68.h cout.h order.h
VAXOBJS = vaxobj/dir.o vaxobj/expr.o vaxobj/misc.o vaxobj/pass1a.o \
vaxobj/pass2.o vaxobj/symt.o vaxobj/main.o
C68OBJS = 68obj/dir.o 68obj/expr.o 68obj/misc.o 68obj/pass1a.o \
68obj/pass2.o 68obj/symt.o 68obj/main.o
CFLAGS = -w -O -DVAX11
C68FLAGS = -L -r -DMC68000 -t0 -t1
LIB = -lV6
C68LIB = -l6
vax: ${VAXOBJS}
@mkver -e "assembler -"
${CC} ${CFLAGS} version.c ${VAXOBJS} -o as68.vax ${LIB}
as68: ${C68OBJS}
@mkver -e "assembler -"
${C68} ${C68FLAGS} ${C68OBJS} version.c -o as68.68 ${C68LIB}
@setstack as68.68 8192 8192
2k: ${C68OBJS}
@mkver -e "assembler -"
${C68} -n2 ${C68FLAGS} -r ${C68OBJS} version.c -o as68.2k ${C68LIB}
@setstack as68.2k 8192 8192
4k: ${C68OBJS}
@mkver -e "assembler -"
${C68} -n ${C68FLAGS} -r ${C68OBJS} version.c -o as68.4k ${C68LIB}
@setstack as68.4k 8192 8192
all: vax 4k
tags:
ctags ${SOURCES} ${INCLUDES}
vaxobj/dir.o: dir.c
${CC} ${CFLAGS} -c dir.c;mv -f dir.o vaxobj/dir.o
vaxobj/expr.o: expr.c
${CC} ${CFLAGS} -c expr.c;mv -f expr.o vaxobj/expr.o
vaxobj/misc.o: misc.c
${CC} ${CFLAGS} -c misc.c;mv -f misc.o vaxobj/misc.o
vaxobj/pass1a.o: pass1a.c
${CC} ${CFLAGS} -c pass1a.c;mv -f pass1a.o vaxobj/pass1a.o
vaxobj/pass2.o: pass2.c
${CC} ${CFLAGS} -c pass2.c;mv -f pass2.o vaxobj/pass2.o
vaxobj/symt.o: symt.c
${CC} ${CFLAGS} -c symt.c;mv -f symt.o vaxobj/symt.o
vaxobj/main.o: main.c
${CC} ${CFLAGS} -c main.c;mv -f main.o vaxobj/main.o
68obj/dir.o: dir.c
${C68} ${C68FLAGS} -c dir.c;mv -f dir.o 68obj/dir.o
68obj/expr.o: expr.c
${C68} ${C68FLAGS} -c expr.c;mv -f expr.o 68obj/expr.o
68obj/misc.o: misc.c
${C68} ${C68FLAGS} -c misc.c;mv -f misc.o 68obj/misc.o
68obj/pass1a.o: pass1a.c
${C68} ${C68FLAGS} -c pass1a.c;mv -f pass1a.o 68obj/pass1a.o
68obj/pass2.o: pass2.c
${C68} ${C68FLAGS} -c pass2.c;mv -f pass2.o 68obj/pass2.o
68obj/symt.o: symt.c
${C68} ${C68FLAGS} -c symt.c;mv -f symt.o 68obj/symt.o
68obj/main.o: main.c
${C68} ${C68FLAGS} -c main.c;mv -f main.o 68obj/main.o

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
*/
#ifdef VAX11
struct { char b4; char b3; char b2; char b1; };
struct { char wb2; char wb1; };
#endif
#ifdef PDP11
struct { char b2; char b1; char b4; char b3; };
struct { char wb2; char wb1; };
#endif
#ifdef MC68000
struct { char b1; char b2; char b3; char b4; };
struct { char wb1; char wb2; };
#endif

View File

@@ -0,0 +1,62 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#define MOVEA 0100
extern char tfilname[]; /*name of it file*/
extern char initfnam[]; /*name of the initilization file*/
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 */
opf31 /*31*/ /* [vlh] 4.2, movec & moves 68010 */
};
#define LSTFRMT 31
short f1mode[] = {0,0,0100,0,0200};
short f2mode[] = {0,0,0100,0,0200};
short f3mode[] = {0,010000,030000,0,020000};
short f15mode[] = {0,0,0300,0,0700};
short f5mode[] = {0,0,0100,0,0200};
short f5amode[] = {0,0,0300,0,0700};
short f13mode[] = {0,0,0200,0,0300};
short f23mode[] = {0,0400,0500,0,0600};
short rlbits[5]; /*holds relocation bits for instr*/
short pline; /*number of last printed line*/
short brkln2 = 077777; /*pass 2 break line number for debugging*/
short prsp; /*special print alignment flag*/

View File

@@ -0,0 +1,105 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/* reduce long relative branches to short if possible*/
#include "as68.h"
pass1a()
{
register long reduced;
register short writfn, i, wsize;
pitix = &itbuf[ITBSZ];
reduced = itoffset = 0L; stbuf[0].itrl = 0;
wsize = 3*STBFSIZE; /* [vlh] don't calculate many times */
close(itfn);
LASTCHTFN = itfnc;
itfn = openfi(tfilname,0); /*open it for reading*/
writfn = open(tfilname,1); /*may need to rewrite some of it*/
if(writfn<0)
abort();
while(1) {
ristb(); /*read it for one statement*/
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*/
if(lseek(writfn,itoffset,0) == -1L) {
rpterr("seek error on intermediate file\n");
abort();
}
if(write(writfn,&stbuf[0],wsize) != wsize) {
rpterr("write error on it file\n");
abort();
}
}
}
}
else if(opcpt == endptr) {
savelc[TEXT] -= reduced;
close(writfn);
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 short 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,847 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*
* pass two for the 68000 assembler
* Bill Allen
* March 1980
*/
#include "as68.h"
#include "p2def.h"
/*pass two driver*/
pass2()
{
register short i;
register int (*dirop)();
pitix = &itbuf[ITBSZ]; /*it buffer is empty*/
lbuf.cc = tbuf.cc = dabuf.cc = drbuf.cc = BSIZE;
lbuf.fd = lfn; /*set buffered io for binary file*/
lbuf.cp = &lbuf.cbuf[0];
tbuf.fd = trbfn; /*set buffered io for text reloc bits file*/
tbuf.cp = &tbuf.cbuf[0];
dabuf.fd = dafn; /*set buffered io for data bytes*/
dabuf.cp = &dabuf.cbuf[0];
drbuf.fd = drbfn; /*set buffered io for data reloc bits*/
drbuf.cp = &drbuf.cbuf[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
**/
putchd(&lbuf,&couthd); /* [vlh] 4.1, replaces write_header */
savelc[0] = 0; savelc[1] = 0; savelc[2] = 0; savelc[3] = 0;
loctr = 0; /*location counter*/
rlflg = TEXT; /*TEXT relocatable*/
p2flg = 1; /*pass two*/
if (lseek(ifn,0L,0) == -1L) { /*beginning of source*/
rpterr("seek error on source file\n");
abort();
}
close(itfn);
LASTCHTFN = itfnc;
itfn = openfi(tfilname,0); /*open it for reading*/
pline = 1; /*no lines printed*/
fchr=gchr(); /*get first char*/
while(1) { /*pass 2 main loop*/
ristb(); /*read it for one statement*/
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].itty; /*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].itty; /*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*/
if (i<=DIRECT) {
dirop = p2direct[i];
(*dirop)(); /*handle directive*/
}
else
uerr(21);
}
else
gcist(); /*generate code for one statement*/
}
}
/* generate code for an instruction*/
/* call with*/
/* intermediate text for instruction in stbuf*/
gcist()
{
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.loword; /*opcode value, 4.2 ==> loword*/
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>32767 || ival<-32768)
uerr(22);
instrlen += 2;
*pins++ = ival;
*prlb++ = DABS; /*data absolute*/
}
else { /*short displacement*/
if(ival>127 || ival<-128)
uerr(22);
ins[0] |= (ival.loword&0377);
}
if (!ival) { /* make it a nop */
opcpt = nopptr;
ins[0] = opcpt->vl1.loword;
pins = &ins[1];
if (modelen == LONGSIZ) {
*pins++ = opcpt->vl1.loword;
rlbits[1] = INSABS;
}
}
in_err++; /* ignore extra eg. bra *+$d04(pc) vs. bra *+d04 */
}
#define US (unsigned short)
/* 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 short *p;
if(get2ops())
return;
if (ins[0]==(US AND) || ins[0]==(US OR))
if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
if (ins[0]==(US AND))
opcpt = andiptr;
else
opcpt = oriptr;
ins[0] = opcpt->vl1.loword;
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 short k;
if(get2ops())
return;
if(cksprg(&opnd[0],CCR)) { /* [vlh] 03-aug-83 */
ins[0] = MOVEFCC;
if(anysprg(&opnd[1]))
uerr(20);
if (modelen == BYTESIZ || modelen == LONGSIZ)
uerr(34);
if (!m68010)
uerr(8);
ins[0] |= opnd[1].ea;
if(!dataea(&opnd[1]))
uerr(9);
doea(&opnd[1]);
return;
}
if(cksprg(&opnd[1],CCR)) {
ins[0] = MOVETCC;
opf3l1:
if(anysprg(&opnd[0]))
uerr(20);
if (modelen == BYTESIZ || modelen == LONGSIZ)
uerr(34);
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 == BYTESIZ || modelen == LONGSIZ)
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 == BYTESIZ)
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 == BYTESIZ)
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));
if (m68010) { /* [vlh] 4.2 */
uerr(31);
nerror--; /* just a warning */
}
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 short 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.loword&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 14 -- rtd (68010) */
/* 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 (ins[0] == RTD && !m68010) /* [vlh] 4.2 */
uerr(8);
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 short 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.loword;
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 short 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.loword&7)<<9)|opnd[1].ea;
doea(&opnd[1]);
}
/* format 20 -- movem */
short regmsk0[] = {0100000,040000,020000,010000,04000,02000,01000,0400,0200,
0100,040,020,010,4,2,1};
short regmsk1[] = {1,2,4,010,020,040,0100,0200,0400,01000,02000,04000,010000,
020000,040000,0100000};
opf20()
{
register short dr, 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)
short *ap;
{
register short *p, i, j, 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)
int msk;
{
register short 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 short 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.loword;
*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.loword&0377);
}
/* format 23 -- eor*/
opf23()
{
if(get2ops())
return;
if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
opcpt = eoriptr;
ins[0] = opcpt->vl1.loword;
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]);
}
/* format 31 -- movec and moves (68010 only) [vlh] 4.2 */
opf31()
{
register struct op *cntrl, *genrl, *eaop;
instrlen += 2;
if (!m68010)
uerr(8);
if(get2ops())
return;
if (ins[0] == MOVEC) {
if (modelen == BYTESIZ)
uerr(34);
if ( cksprg(&opnd[0],USP) || cksprg(&opnd[0],SFC) ||
cksprg(&opnd[0],DFC) || cksprg(&opnd[0],VSR)) {
cntrl = &opnd[0];
genrl = &opnd[1];
}
else {
if ( !cksprg(&opnd[1],USP) && !cksprg(&opnd[1],SFC) &&
!cksprg(&opnd[1],DFC) && !cksprg(&opnd[1],VSR))
uerr(18);
ins[0] |= 1; /* direction Rn --> Rc */
cntrl = &opnd[1];
genrl = &opnd[0];
}
if (!ckreg(genrl))
uerr(18);
*pins = ((genrl->ea)<<11) & 0x8000;
if (cksprg(cntrl,DFC))
*pins |= DFC_CR;
else if (cksprg(cntrl,USP))
*pins |= USP_CR;
else if (cksprg(cntrl,VSR))
*pins |= VSR_CR;
/* else... *pins |= SFC_CR; (SFC_CR == 0)*/
}
else { /* MOVES */
ins[0] |= f1mode[modelen];
if (ckreg(&opnd[0])) {
genrl = &opnd[0];
eaop = &opnd[1];
*pins = 0x800; /* from general register to <ea> */
}
else {
genrl = &opnd[1];
eaop = &opnd[0];
*pins = 0;
}
*pins |= ((genrl->ea)<<11) & 0xF000;
if (!memalt(eaop) || pcea(eaop) || ckreg(eaop))
uerr(20);
ins[0] |= eaop->ea;
doea(eaop);
}
}

View File

@@ -0,0 +1,10 @@
This is a list of the files in this directory:
main.c: Main routine and utilities
symt.c Symbol table and miscellaneous pass 1 routines
dir.c Handle all directives including conditional assembly
expr.c: Expression handling routines
pass1a.c Pass1a branch optimization
pass2.c Second pass main routines
misc.c Second pass miscellaneous routines
The Shared Text version will no longer assemble test.s on the pdp11-23

View File

@@ -0,0 +1,822 @@
/*
Copyright 1981
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "as68.h"
char *ermsg[];
char initfnam[];
char ldfn[];
char tlab1[];
short ftudp;
short 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 short smode, i;
register char *p;
register short tmode;
register char *j;
long num;
char istr[80];
if(fchr == '\'' || fchr == '"')
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(FALSE,sirt);
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*/
}
}
/*astring - check for an ascii string enclosed in single quotes*/
astring()
{
register char delim;
if(fchr != '\'' && fchr != '"') /*valid delimiter*/
return(0);
delim = fchr;
if(equflg || (itype==ITSP && ival.loword=='#')) { /*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)
int adelim;
{
register short 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)
int ardx;
{
register short 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;
register char *pstr;
int idx;
{
register short i,j;
register long l;
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 symbol 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(oplook,airt)
char **airt;
int oplook; /* if true then looking in opcode table */
{
register char *mtpt;
register short *p1, *p2, 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*/
if((lmte->name[0]=='~') && (lmte->name[1]!='~') && (lmte->name[1]!='.'))
return(lmte); /*[vlh] 4.2, force local symbols */
/*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 short i, 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;
int dirnum;
{
register char *mdept;
pack(mdstr,lmte); /*pack name at end of main table*/
mdept=lemt(TRUE,oirt); /*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 short 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 from source file*/
gchr()
{
register short chr1;
if(peekc) {
chr1 = peekc;
peekc = 0;
}
else {
gchr1:
if(sbuflen<=0){ /*nothing on input buffer*/
sbuflen=read(ifn,sbuf,BSIZE); /*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*/
if(!p2flg) /*pass 1 only*/
absln++;
}
else if(chr1=='\t') { /*convert tabs to spaces*/
chr1 = ' ';
}
return(chr1);
}
/*
* write out intermediate text for one statement
* call with
* the it for the statement in stbuf
*/
wostb()
{
register short woix, *itwo, 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<STBFSIZE/(sizeof *itwo); i++) {
if(pitix > &itbuf[ITBSZ-1]) /*no room in buffer*/
doitwr();
*pitix++ = *itwo++; /*first word*/
}
}
/* debug(); //call debug package*/
}
doitwr()
{
register short i;
if(write(itfn,itbuf,ITBSZ*(sizeof i)) != ITBSZ*(sizeof i)) {
rpterr("it write error errno=%o\n",errno);
endit();
}
pitix = itbuf;
}
/*
* 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)
int errn;
{
putchar(0); /* clear the buffer */
stdofd = STDERR; /* output file descriptor <== STDERR */
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]);
putchar(0);
stdofd = STDOUT;
nerror++;
}
/*
* user error that causes the statement to be abandoned
* call with:
* error number
*/
xerr(xern)
int xern;
{
uerr(xern); /*type error message*/
if(!p2flg) /*pass one*/
igrst(); /*pass rest of source*/
}
/* abort the assembly*/
abort()
{
rpterr("as68 abort\n");
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');
putchar(0); /* flush the printing*/
}
if(nerror > 0) {
putchar(0);
stdofd = STDERR;
printf("& %d errors\n",nerror);
putchar(0);
}
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;
int hflag;
{
register short fd;
fd = (hflag) ? creat(pname,0666) : open(pname,hflag);
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*/
gettempf()
{
register short j;
register char *p;
if(LASTCHTFN == 'A') {
j = getpid();
p = &LASTCHTFN-4;
while(p < &LASTCHTFN) {
*p++ = (j&017) + 'a';
j >>= 4;
}
}
while(LASTCHTFN < 'z') {
LASTCHTFN++;
if((j=creat(tfilname,0600))>=0)
return(j);
}
rpterr("temp file create error: %s errno=%o\n",tfilname,errno);
endit();
}
/* move label name from lbt to main table entry pointed to by lmte*/
setname()
{
register short *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()
{
register char **p;
register struct symtab *p1;
register char *p2;
register short fd,i;
if((fd=open(initfnam,0)) < 0) {
rerr:
printf("& Unable to read init file: %s\n", initfnam);
endit();
}
if(read(fd,sirt,SZIRT*SIRTSIZE) != SZIRT*SIRTSIZE) {
goto rerr;
}
if(read(fd,oirt,SZIRT*SIRTSIZE) != SZIRT*SIRTSIZE)
goto rerr;
if((i=read(fd,bmte,SZMT*STESIZE)) <= 0)
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; /* 11 apr 83, for vax */
}
for(p=oirt; p<&oirt[SZIRT]; p++) {
if(*p)
*p += (long)p2; /* 11 apr 83, for vax */
}
for(p1=bmte; p1<lmte; p1++) {
if(p1->tlnk)
p1->tlnk += (long)p2; /* 11 apr 83, for vax */
}
close(fd);
}
/* write the initialization file*/
putsymtab()
{
register char **p;
register struct symtab *p1;
register char *p2;
register short fd,i;
if((fd=creat(initfnam,0644))<0) {
werr:
printf("& Write error on init file: %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 = *p - p2; /* 11 apr 83, for vax */
}
for(p=oirt; p<&oirt[SZIRT]; p++) {
if(*p)
*p = *p - p2; /* 11 apr 83, for vax */
}
for(p1=bmte; p1<lmte; p1++) {
if(p1->tlnk)
p1->tlnk = p1->tlnk - p2; /* 11 apr 83, for vax */
}
if(write(fd,sirt,SZIRT*SIRTSIZE) != SZIRT*SIRTSIZE) {
goto werr;
}
if(write(fd,oirt,SZIRT*OIRTSIZE) != SZIRT*OIRTSIZE)
goto werr;
i = (char *)lmte - bmte; /*length of current main table*/
if((i % STESIZE) != 0) {
goto werr;
}
if(write(fd,bmte,i) != i)
goto werr;
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;
{
putchar(0); /*flush buffer*/
stdofd = STDERR; /*error file*/
printf("& %d: ",absln);
printf(ptch,x1,x2,x3,x4,x5,x6);
nerror++; /* [vlh] 4.2.... */
}
/* 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';
}

View File

@@ -0,0 +1 @@
char *compiled = "@(#) assembler - Thu Sep 8 15:50 1983";

View File

@@ -0,0 +1,3 @@
mkver -e "c68 Main Driver -"
c68 -L -r -DMC68000 -n version.c main.c -o c68.4k -l6
setstack c68.4k 8000 8000

View File

@@ -0,0 +1,2 @@
mkver -e "c68 Main Driver -"
cc -DPDP11 -n maketask.c version.c main.c -l6 -o c68.pdp

View File

@@ -0,0 +1,4 @@
mkver -e "c68 Main Driver -"
cc -O -w -DVAX11 -n maketask.c version.c main.c ../binary/libV.a -o c68.vax

View File

@@ -0,0 +1,32 @@
.he "C68 Main Driver"Change Log"Page %"
.de bg
.sp
.in +5
..
.de eg
.sp
.ne 8
.in -5
..
1. 6/13/83 - Main driver split from Preprocessor [vlh] 4.2
.bg
For flexibility and to adhere to standards.
.eg
2. 6/18/83 - Signal catching [vlh] 4.2
.bg
The main driver now catches the kill signal and removes all temporary
files. Changed the way the temporaries were being removed.
.eg
3. 7/18/83 - Added new flags [vlh] 4.2
.bg
Added the '-C' preprocessor flag and the '-g' symbolic debugger flag.
Added the '-tp' and the '-t2' to allow for an alternate preprocessor
and assembler pass. Added the '-a' flag for forcing all externally
referenced variables to 16 bits, made the '-L' flag (it's opposite)
the default.
.eg
4. 8/3/83 - 68010 target flag [vlh] 4.2
.bg
Added the '-T' flag to distinguish between compilations targeted for the
68000 and those targeted for the 68010.
.eg

View File

@@ -0,0 +1,659 @@
/**
* Copyright 1983
* Alcyon Corporation
* 8716 Production Ave.
* San Diego, Ca. 92121
**/
char *version = "@(#)c68 main driver 4.2 - Sep 6, 1983";
/* C68 -- Cross Compiler Main Driver */
#include "mdriver.h"
/**
* 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
* assembler 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, index;
cfilep = &cfiles[0];
loadp = &loadargs[0];
nloadfiles = 0;
#ifdef MC68000
sysinfo(0,&mmuflag); /*[vlh] mmu system ??*/
#else
mmuflag = 1;
#endif
if (!mmuflag) /*[vlh] default args*/
*loadp = ldflg;
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':
if (ndefs == NDEFS)
ferror("To many command line defines");
defs[ndefs++] = arg-2; /* need -D... */
i++;
break;
case 'I':
if (ndefs == NDEFS)
ferror("To many command line include directories");
incl[nincl++] = arg-2; /* need -I... */
i++;
break;
case 'N':
nflag++;
continue;
case 'e': /* [vlh] 3.4 */
eflag++;
if (fflag)
ferror("incompatible flags : '-f' and '-e'\n");
continue;
case 'f': /* [vlh] 3.4 */
fflag++;
if (eflag)
ferror("incompatible flags : '-f' and '-e'\n");
continue;
case 'a': /* make all addresses 16 bits (short) */
lflag = 0;
continue;
case 'L': /* make all addresses 32 bits (long) */
lflag = 1;
continue;
case 'o':
if( --j <= 0 )
ferror("bad -o option\n");
*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++) == 'p' ) /* [vlh] 4.2 */
preproc = "/usr/c68/cpp68";
else if( c == '0' )
parser = "/usr/c68/c068";
else if( c == '1' )
cgen = "/usr/c68/c168";
else if (c == '2')
asmprog = "/usr/c68/as68";
else if( c == '\0' )
tflag++;
continue;
case 'T': /* [vlh] 4.2, 68010 target */
Tflag++;
continue;
case 'g': /* [vlh] 4.2 symbolic debugger label generation */
gflag++;
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\n");
*loadp++ = *p;
i++;
break;
} /* end of case statement */
break;
} /* end of for statement */
if( i )
continue;
} /* end of if statement */
/*C or Assembler files to process*/
if( strend(arg,".c") || strend(arg,".s") ) {
if( cfilep >= &cfiles[NARGS] )
ferror("too many files\n");
*cfilep++ = arg;
nloadfiles++;
if( !chkdup(arg) ) {
if( loadp >= &loadargs[NARGS] )
ferror("too many loader args\n");
*loadp++ = setend(arg,'o');
}
}
else if( !chkdup(arg) ) { /*check for loader args*/
if( loadp >= &loadargs[NARGS] )
ferror("too many loader args\n");
*loadp++ = arg;
if( strend(arg,".o") )
nloadfiles++;
}
} /* end of for statement which processes arguments */
if( cfilep != &cfiles[0] ) { /*had a C file?*/
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);
/* call the Preprocessor */
asflag = strend(arg,".s");
if (pflag||asflag)
tfns[MTEMP] = setend(arg,'i');
INITFARGS();
addfarg(preproc);
if(Eflag)
addfarg("-E");
else if (pflag)
addfarg("-P");
if ( v6flag ) /* v6 compatiblity */
addfarg("-6");
else if ( v7flag ) /* v7 compatiblity */
addfarg("-7");
else if ( s3flag ) /* sys3 compatiblity */
addfarg("-3");
else if ( s5flag ) /* sys5 compatiblity */
addfarg("-5");
if (nincl > 0)
for (index = 0; index != nincl; index++)
addfarg(incl[index]);
if (ndefs > 0)
for (index = 0; index != ndefs; index++)
addfarg(defs[index]);
addfarg(arg); /* source file name */
addfarg(tfns[MTEMP]);
ENDFARGS();
if( fexec(preproc,fargs) ) {
status++; /* preprocessor failure */
cflag++;
continue;
}
if (pflag) { /* no further processing on this file... */
tfns[MTEMP] = "";
continue;
}
/* call the Parser */
if( !asflag ) {
tfns[ASTEMP] = setend(arg,'s');
INITFARGS();
addfarg(parser);
addfarg(tfns[MTEMP]);
if( oneflag ) {
addfarg(tfns[ASTEMP]);
if( lflag )
addfarg("-L"); /* default for 4.2 and beyond */
else
addfarg("-a"); /* [vlh] 4.2 16 bit addresses */
if( sflag || nflag )
addfarg("-D");
addfarg("-1");
}
else {
addfarg(tfns[ICODE]);
addfarg(tfns[LINK]);
if ( fflag ) /* [vlh] 3.4 */
addfarg("-f");
else if ( eflag ) /* [vlh] 3.4 */
addfarg("-e");
if ( wflag )
addfarg("-w");
if( tflag )
addfarg("-t"); /* strings --> text segment */
if( gflag )
addfarg("-g"); /* symbolic debugger line numbers */
}
ENDFARGS();
if( fexec(parser,fargs) ) {
status++;
cflag++;
continue;
}
unlink(tfns[MTEMP]);
/* Call the Code Generator */
if( !oneflag ) {
INITFARGS();
addfarg(cgen);
addfarg(tfns[ICODE]);
addfarg(tfns[LINK]);
addfarg(tfns[ASTEMP]);
if( !sflag )
fns[ASTEMP] = tfns[ASTEMP];
if( lflag )
addfarg("-L"); /* default for 4.2 and beyond */
else
addfarg("-a"); /* [vlh] 4.2 16 bit addresses */
if (Tflag)
addfarg("-T"); /* [vlh] 4.2 68010 target... */
if( nflag || sflag )
addfarg("-D");
if( gflag )
addfarg("-g"); /* symbolic debugger line numbers */
ENDFARGS();
if( fexec(cgen,fargs) ) {
status++;
cflag++;
continue;
}
}
if( sflag ) {
tfns[ASTEMP] = tfns[MTEMP]; /* don't remove this file.... */
continue;
}
} /* if not processing an assembler file */
else
tfns[ASTEMP] = tfns[MTEMP];
/* Call the assembler */
INITFARGS();
addfarg(asmprog);
if( !asflag )
addfarg("-u");
if( lflag )
addfarg("-L"); /* default for 4.2 and beyond */
else
addfarg("-a"); /* [vlh] 4.2 16 bit addresses */
if (Tflag) /* [vlh] 4.2 68010 target */
addfarg("-T");
addfarg(tfns[ASTEMP]);
ENDFARGS();
if( fexec(asmprog,fargs) ) {
cflag++;
status++;
}
unlink(tfns[ASTEMP]);
}
} /* handle input source files */
/**
* 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.
**/
if( !cflag && (loadp != &loadargs[0] || cfilep != &cfiles[0] )) {
INITFARGS();
addfarg(loader);
addfarg("-X");
i = 1;
for( p = loadargs; *p ; p++ ) { /* insert pref before 1st .o */
if( i && strend(*p,".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);
if (gflag) /* [vlh] 4.2 */
addfarg(post);
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'));
}
cexit();
}
/**
* cexit - exit from C compiler driver
* This deletes any existing temps and exits with the error status.
**/
cexit() /* returns - none*/
{
register int i;
signal(SIGINT,SIG_IGN); /* [vlh] 4.2 */
for(i = 0; i < NTEMPS; i++)
if (fns[i])
unlink(tfns[i]);
exit(status);
}
/**
* 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;
signal(SIGINT,SIG_DFL);
pid = maketask(fname,0,0,args); /*do fork & exec*/
signal(SIGINT,SIG_IGN);
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 ) {
status = i;
if( status != 2 ) { /* DEL key (interrupt) */
#ifdef MC68000
if (i > 0 && i < 32)
#else
if (i > 0 && i < 16)
#endif
printf("%s error terminated, signal %d\n",fname,i);
else if (i == 0x8b)
printf("%s error terminated, segmentation fault\n",fname);
else if (i != 0x8a)
printf("%s error terminated, status $%x\n",fname,i);
else
printf("%s error terminated, bus error\n",fname);
}
cexit();
}
return((fstat>>8)&0xff);
}
/**
* 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);
}
/**
* 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 arguments\n");
*fargp++ = s;
}
/**
* ferror - fatal error
* Outputs error message and exits with error status.
**/
ferror(s) /* returns - none*/
char *s; /* printf string*/
{
printf(s);
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*/
{
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);
}
/**
* strcmp - string comparison
* Compares two strings for equality, less or greater.
**/
strcmp(s,t) /* returns 0 for equality*/
char *s, *t;
{
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[0];
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);
return((strcmp(&s[ls-lt],t) == 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,25 @@
CC = cc
C68 = nc68
CFLAGS = -O -w -DVAX11
C68FLAGS = -L -r -DMC68000 -t0 -t1
LIB = -lV6
C68LIB = -l6
.IGNORE:
vax:
mkver -e "c68 Main Driver -"
${CC} ${CFLAGS} -n version.c main.c -o c68.vax ${LIB}
4k:
mkver -e "c68 Main Driver -"
${C68} ${C68FLAGS} -n version.c main.c -o c68.4k ${C68LIB}
setstack c68.4k 8000 8000
all: vax 4k
obsolete:
mkver -e "c68 Main Driver -"
${C68} ${C68FLAGS} version.c main.c -o c68.68 ${C68LIB}
setstack c68.68 8000 8000
${C68} ${C68FLAGS} -n2 version.o main.o -o c68.2k ${C68LIB}
setstack c68.2k 8000 8000

View File

@@ -0,0 +1,27 @@
/* 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 on %s\n",fname);
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,121 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/* INITFARGS - initialize fexec arg block*/
/* This sets the arg block pointer to the beginning of the block.*/
#define INITFARGS() fargp = &fargs[0]
/* ENDFARGS - end fexec argument block*/
/* This ends the argument block with a zero pointer.*/
#define ENDFARGS() *fargp = 0
#define SIG_IGN ((int (*)())1) /* address of long 1 */
#define SIG_DFL ((int (*)())0) /* address of long 0 */
#define SIGINT 2 /* interrupt */
#define DEFSIZE 1024
#define NARGS 64
#define NINCL 10
#define NDEFS 20
#define ICODE 0
#define LINK 1
#define MTEMP 2
#define ASTEMP 3
#define NTEMPS 4
char *fargs[NARGS+1];
char **fargp;
char argbuf[DEFSIZE];
char *cfiles[NARGS+1];
char *loadargs[NARGS+1];
char *defs[NDEFS];
char *incl[NINCL];
char *fns[NTEMPS];
char *tfns[NTEMPS];
int ndefs;
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 = 1; /* [vlh] 4.2 default */
int pflag;
int Eflag; /* [vlh] 4.0 flag, Preprocessor only to stdout */
int sflag;
int Tflag; /* [vlh] 4.2, 68010 destination */
int tflag; /* [vlh] 4.2, put strings into .text segment */
int gflag; /* [vlh] 4.2, symbolic debugger label generation */
int wflag; /* [vlh] turn on warning messages */
int verbose; /* [vlh] 3.4 force printing of file being processed */
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;
#ifdef MC68000
char *preproc = "/lib/cpp68"; /*[vlh] 4.2 */
char *parser = "/lib/c068";
char *cgen = "/lib/c168";
char *onepass = "/lib/c0168";
char *pref = "/lib/c680.o";
char *post = "/lib/c68end.o"; /*[vlh] 4.2, for debugger */
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"; /* [vlh] 3.4 */
char *v7incl = "/usr/include/v7"; /* [vlh] 3.4 */
char *s3incl = "/usr/include/sys3"; /* [vlh] 3.4 */
char *s5incl = "/usr/include/sys5"; /* [vlh] 3.4 */
#else
char *preproc = "/usr/local/lib/cpp68"; /* [vlh] 4.2 */
char *parser = "/usr/local/lib/c068";
char *cgen = "/usr/local/lib/c168";
char *onepass = "/usr/local/lib/c0168";
char *pref = "/usr/local/lib/c680.o";
char *post = "/usr/local/lib/c68end.o";/*[vlh] 4.2, for debugger */
char *loader = "/usr/local/lo68";
char *asmprog = "/usr/local/as68";
char *deflib = "/usr/local/lib/lib7.a";
char *deflibfp = "/usr/local/lib/libF.a"; /* [vlh] 3.4 */
char *deflibep = "/usr/local/lib/libE.a"; /* [vlh] 3.4 */
char *v6lib = "/usr/local/lib/libv6.a"; /* [vlh] 3.4 */
char *v7lib = "/usr/local/lib/libv7.a"; /* [vlh] 3.4 */
char *s3lib = "/usr/local/lib/libs3.a"; /* [vlh] 3.4 */
char *s5lib = "/usr/local/lib/libs5.a"; /* [vlh] 3.4 */
char *v6incl = "/usr/include/c68/v6"; /* [vlh] 3.4 */
char *v7incl = "/usr/include/c68/v7"; /* [vlh] 3.4 */
char *s3incl = "/usr/include/c68/sys3"; /* [vlh] 3.4 */
char *s5incl = "/usr/include/c68/sys5"; /* [vlh] 3.4 */
#endif
/* Main driver Flags */
char *ldflg = "-r";
int mmuflag; /*[vlh] 3.4 */
int asflag;
/* Functions which return not integral values */
char *setend();
char *makecopy();
char *maketemp();
int (*signal())();

View File

@@ -0,0 +1 @@
char *compiled = "@(#) c68 Main Driver - Tue Sep 6 14:37 1983";

View File

@@ -0,0 +1,14 @@
c68 -L -r -DMC68000 -DDEBUG -c canon.c
c68 -L -r -DMC68000 -DDEBUG -c codegen.c
c68 -L -r -DMC68000 -DDEBUG -c interf.c
c68 -L -r -DMC68000 -DDEBUG -c main.c
c68 -L -r -DMC68000 -DDEBUG -c optab.c
c68 -L -r -DMC68000 -DDEBUG -c putexpr.c
c68 -L -r -DMC68000 -DDEBUG -c smatch.c
c68 -L -r -DMC68000 -DDEBUG -c sucomp.c
c68 -L -r -DMC68000 -DDEBUG -c tabl.c
c68 -L -r -DMC68000 -DDEBUG -c util.c
c68 -L -r -DMC68000 -DDEBUG -c cskels.c
mkver -e "Code Generator -"
c68 -n -r -L -r -DMC68000 -DDEBUG version.c canon.o codegen.o interf.o main.o optab.o putexpr.o smatch.o sucomp.o tabl.o util.o cskels.o -o c168.4k -l6
setstack c168.4k 8000 8000

View File

@@ -0,0 +1,14 @@
mkver -e "Code Generator -"
cc -DPDP11 -DDEBUG -c canon.c
cc -DPDP11 -DDEBUG -c codegen.c
cc -DPDP11 -DDEBUG -c interf.c
cc -DPDP11 -DDEBUG -c main.c
cc -DPDP11 -DDEBUG -c optab.c
cc -DPDP11 -DDEBUG -c putexpr.c
cc -DPDP11 -DDEBUG -c smatch.c
cc -DPDP11 -DDEBUG -c sucomp.c
cc -DPDP11 -DDEBUG -c tabl.c
cc -DPDP11 -DDEBUG -c util.c
cc -DPDP11 -DDEBUG -c cskels.c
cc -DPDP11 -DDEBUG -c version.c
cc version.o canon.o codegen.o interf.o main.o optab.o putexpr.o smatch.o sucomp.o tabl.o util.o cskels.o -l6 -o c168.pdp

View File

@@ -0,0 +1,14 @@
mkver -e "Code Generator -"
cc -O -w -DVAX11 -DDEBUG -c canon.c
cc -O -w -DVAX11 -DDEBUG -c codegen.c
cc -O -w -DVAX11 -DDEBUG -c interf.c
cc -O -w -DVAX11 -DDEBUG -c main.c
cc -O -w -DVAX11 -DDEBUG -c optab.c
cc -O -w -DVAX11 -DDEBUG -c putexpr.c
cc -O -w -DVAX11 -DDEBUG -c smatch.c
cc -O -w -DVAX11 -DDEBUG -c sucomp.c
cc -O -w -DVAX11 -DDEBUG -c tabl.c
cc -O -w -DVAX11 -DDEBUG -c util.c
cc -O -w -DVAX11 -DDEBUG -c cskels.c
cc -O -w -DVAX11 -DDEBUG -c version.c
cc -n version.o canon.o codegen.o interf.o main.o optab.o putexpr.o smatch.o sucomp.o tabl.o util.o cskels.o -o c168.vax

View File

@@ -0,0 +1,15 @@
mkver -e "C68 Code Generator -"
c68 -S -L -DVERSADOS -DMC68000 canon.c
c68 -S -L -DVERSADOS -DMC68000 codegen.c
c68 -S -L -DVERSADOS -DMC68000 cskels.c
c68 -S -L -DVERSADOS -DMC68000 interf.c
c68 -S -L -DVERSADOS -DMC68000 main.c
c68 -S -L -DVERSADOS -DMC68000 optab.c
c68 -S -L -DVERSADOS -DMC68000 putexpr.c
c68 -S -L -DVERSADOS -DMC68000 smatch.c
c68 -S -L -DVERSADOS -DMC68000 sucomp.c
c68 -S -L -DVERSADOS -DMC68000 tabl.c
c68 -S -L -DVERSADOS -DMC68000 util.c
c68 -S -L -DVERSADOS -DMC68000 version.c
mv *.s vst

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,229 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "../icode.h"
#ifdef DRI
# include <stdio.h>
# include <klib.h>
# undef putchar
# define putchar xputchar
# undef ferror
# define ferror xferror
# define printf xprintf
#endif
#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
#define NOAUTO 1
#define DOAUTO 0
#define STDERR 2
#define PATHSIZE 128
char brtab[][2];
short invrel[];
short swaprel[];
char *strtab[];
/*operator tree node for unary and binary operators*/
struct tnode {
short t_op; /*operator*/
short t_type; /*data type of result*/
short t_su; /*Sethy-Ullman number*/
short t_ssp;
struct tnode *t_left; /*left sub-tree*/
struct tnode *t_right; /*right sub-tree (undefined if unary)*/
};
/*constant terminal node*/
struct conode {
short t_op; /*operator*/
short t_type; /*type*/
short t_su; /*Sethy-Ullman number*/
short t_ssp;
short t_value; /*value or label number*/
};
/*long constant terminal node*/
struct lconode {
short t_op; /*operator*/
short t_type; /*type*/
short t_su; /*Sethy-Ullman number*/
short t_ssp;
long t_lvalue; /*value or label number*/
};
/*local symbol terminal node*/
struct symnode {
short t_op; /*operator*/
short t_type; /*symbol data type*/
short t_su; /*Sethy-Ullman number*/
short t_ssp;
short t_sc; /*storage class*/
short t_offset; /*register offset*/
short t_reg; /*register number*/
short t_label; /*label number if static*/
};
/*external symbol reference node*/
struct extnode {
short t_op; /*operator*/
short t_type; /*symbol data type*/
short t_su; /*Sethy-Ullman number*/
short t_ssp;
short t_sc; /*storage class*/
short t_offset; /*register offset*/
short 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 {
short t_op;
short t_type;
short t_su;
short t_ssp;
short t_sc;
short t_offset;
short t_reg;
short t_xreg;
short t_xtype;
};
/* io buffer declaration */
#define BSIZE 512
struct iob {
int fd;
int cc;
char *cp;
char cbuf[BSIZE];
} ibuf, lbuf, obuf;
/* Code generation argument flags */
short dflag;
short mflag;
short cflag;
short eflag;
short fflag;
short oflag;
short lflag;
short m68010; /* [vlh] 4.2, differentiate between chip destination */
/* Miscellaneous variables */
short lineno;
short errcnt;
short opinfo[];
short nextlabel;
char optab[][6];
char *mnemonics[];
char *codeskels[];
short stacksize;
/* general define macros */
#define WALLIGN(add) ((add+1)&(~1))
#define ISARRAY(type) ((type&SUPTYP)==ARRAY)
#define ISFUNCTION(type) ((type&SUPTYP)==FUNCTION)
#define ISPOINTER(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 ISALLTYPE(type) (type&(SUPTYP|TYPE))
#define ISASGOP(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)
/* 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 OUTSRSAVE(reg) printf("move sr,R%d\n",reg)
#define OUTCCSAVE(reg) printf("move ccr,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)
#define CONSTZERO(ltyp,p) ((ltyp && !p->t_lvalue) || (!ltyp && !p->t_value))
#define SETVAL(ltyp,p,val) if (ltyp) p->t_lvalue = val; else p->t_value = val
#ifdef DEBUG
# define PUTEXPR(cond,id_str,node_ptr) if (cond) putexpr(id_str,node_ptr)
#else
# define PUTEXPR(cond,id_str,node_ptr)
#endif
/* Functions pre-declared */
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();
char *fixptree();
long readlong();
short readshort();

View File

@@ -0,0 +1,841 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
#include "cskel.h"
char null[];
char *opname[];
/* 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 short r, ccflag;
short lconst;
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,&lconst)) &&
CONSTZERO(lconst,rtp)) { /* [vlh] */
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 ) {
if (!m68010) /* [vlh] 4.2, added differentiation */
OUTSRSAVE(r);
else
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 short op;
register struct tnode *stp;
op = tp->t_op;
if( LEAFOP(op) || op == QMARK || op == LAND || op == LOR ) /* [mac] 4.2 */
return(tp);
if( op == POSTINC || op == POSTDEC ) {
stp = tcopy(tp->t_left,NOAUTO); /* [mac] 4.2 c[i=+1]++ & c[*p++]++ */
*(*clp)++ = fixptree(tp);
return( stp );
}
if( BINOP(op) )
tp->t_right = addptree(tp->t_right,clp);
tp->t_left = addptree(tp->t_left,clp);
return(tp);
}
/* fixptree - fix post-fix tree */
/* This eliminates assignment operators from post-fix tree so that */
/* c[i=+1]++ will only evaluate i=+1 once */
char *
fixptree(tp)
struct tnode *tp;
{
register short op;
op = tp->t_op;
if( LEAFOP(op) )
return(tp);
/* This prevents assignments and pre-operators from being evaluated
twice... */
if( ISASGOP(op) || op == PREDEC || op == PREINC )
return( fixptree(tp->t_left) );
if( BINOP(op) )
tp->t_right = fixptree(tp->t_right);
tp->t_left = fixptree(tp->t_left);
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 short savestk, ssize, r, i;
register struct tnode *rtp;
#ifdef DEBUG
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_right->t_op = CINT; /* [vlh] 4.1 */
tp->t_right->t_type = INT; /* [vlh] 4.1 */
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;
{
#ifdef DEBUG
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 short r;
register char *p;
register struct tnode *ltp;
short lconst;
PUTEXPR(cflag,"ucodegen",tp);
switch( tp->t_op ) {
case ADDR: /* 4.2 */
ltp = tp->t_left;
if(cookie==FORCC && ltp->t_op==SYMBOL &&
(ltp->t_sc==EXTERNAL || ltp->t_sc==STATIC)) {
warning("function existence test");
printf("tst.l ");
outaexpr(ltp,NOTIMMED);
printf("\n");
return(reg);
}
break;
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,&lconst)) &&
!(UNSIGN(tp->t_left->t_type)) &&
((!lconst && (p->t_value == 1 || p->t_value == 2) ) ||
(lconst && (p->t_lvalue == 1 || p->t_lvalue == 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,&lconst)))
if (!lconst && (p->t_value < 0 && p->t_value >= -QUICKVAL)) {
p->t_value = - p->t_value;
tp->t_op += (SUB-ADD);
}
else if (lconst && p->t_lvalue<0 && p->t_lvalue >= -QUICKVAL) {
p->t_lvalue = -p->t_lvalue;
tp->t_op += (SUB-ADD);
}
break;
} /* end of case statement..... */
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( ISASGOP(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 %s",opname[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 short lab;
#ifdef DEBUG
if (cflag) printf("size is %d\n",size);
#endif
if (ISDREG(lr)) {
printf("move.l r%d,r%d\n",lr,AREG(lr));
lr = AREG(lr);
}
if (ISDREG(rr)) {
printf("move.l r%d,r%d\n",rr,AREG(rr));
rr = AREG(rr);
}
lab = nextlabel++;
printf("move #%d,r%d\n",(size/INTSIZE)-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 short off, r, type, nr, ar, xr, xt;
if( tp->t_op == INDR || LOADABLE(tp) ) {
PUTEXPR((cflag>1),"loadexpr",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);
PUTEXPR((cflag>1),"loadexpr final",tp);
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;
short op, lab1, lab2;
#ifdef DEBUG
if (cflag)
printf("hardrel: cookie=%d op=%d reg=%d\n",cookie,tp->t_op,reg);
#endif
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 short 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 short lab1, optype, op, subdir;
ltp = tp->t_left;
if( BINOP(op=tp->t_op) )
rtp = tp->t_right;
subdir = dir; /*set up for LOR*/
#ifdef DEBUG
if (cflag)
printf("condbr: dir = %d, lab = %d, reg = %d\n",dir,lab,reg);
#endif
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: /* [mc] 4.2.b */
if( ((dir!=0 && op==NEQUALS) || (dir==0 && op==EQUALS)) &&
ltp->t_op==PREDEC && rtp->t_op==CINT && rtp->t_value == -1 &&
ISDREG(ltp->t_left->t_reg) && ltp->t_left->t_type==INT) {
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++;
}
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 short change, op;
register struct tnode *tp;
tp = *tpp;
op = tp->t_op;
change = 0;
if (NOTLEAFOP(op) && op!=COMMA && op!=QMARK && op!=LAND && op!=LOR &&
op!=LESS && op!=LESSEQ && op!=GREAT && op!=GREATEQ) {
change += rcodegen(&tp->t_left,cookie,reg);
if( BINOP(op) )
change += rcodegen(&tp->t_right,cookie,reg);
change += rcgen(tpp,cookie,reg);
} /* [vlh] 4.2 stop getting to this code on <, >, <=, >= */
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 short 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;
PUTEXPR((cflag>1),"rcgen",tp);
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:
PUTEXPR((cflag>1),"rcgen EQOP",tp);
if( ltp->t_type == CHAR ) {
#ifdef DEBUG
if (cflag>1) printf("exiting rcgen with ltp type CHAR change %d\n",change);
#endif
return(change);
}
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 short type;
type = tp->t_type;
if( SUPTYPE(type) )
return(PTRSIZE);
switch( type ) {
case INT:
case CHAR:
case UCHAR: /* [vlh] 4.2 */
case UNSIGNED:
return(INTSIZE);
case LONG:
case ULONG: /* [vlh] 4.2 */
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 short 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 short 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*/
{
short lconst;
long bvalue;
if (!(tp = constant(tp,&lconst))) /* [vlh] 4.1 added long... */
return(-1);
bvalue = (lconst) ? tp->t_lvalue : (long) tp->t_value;
return(onebit(bvalue));
}

View File

@@ -0,0 +1,93 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave
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_UANY 12 /*4.2 unsigned short or char*/
#define T_INDR 0x10 /*pointer type (bit)*/
struct skeleton {
short sk_left;
short sk_right;
char *sk_def;
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
can't create (filename)
can't open (filename)
cdsize: invalid type (number)
code skeleton error: (number)
divide by zero
expression too complex
expression too complex
intermediate code error (number,number)
invalid floating op (number)
invalid initialization
invalid operator (number)
invalid register expression
invalid storage class (number)
modulus by zero
no code table for (number)
opcall bad op (number)
structure operation not implemented
usage: c168 icode asm [-DLmec]

View File

@@ -0,0 +1,142 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
short bol;
short gflag;
short onepass;
/* outexpr - output expression*/
outexpr(tp) /* returns - none*/
struct tnode *tp; /* pointer to tree node*/
{
outline();
if( exprok(tp) ) {
#ifdef DEBUG
if (cflag) printf("outexpr 1: type is %d\n",tp->t_type);
#endif
scodegen(canon(tp),FOREFF,0);
#ifdef DEBUG
if (cflag) printf("outexpr 2: type is %d\n",tp->t_type);
#endif
}
}
outifgoto(tp,dir,lab)
struct tnode *tp;
int dir;
int lab;
{
outline();
if( exprok(tp) )
condbr(canon(tp),dir,lab,0);
}
outcforreg(tp)
struct tnode *tp;
{
outline();
if( exprok(tp) )
outmovr(scodegen(canon(tp),FORREG,0),0,tp);
}
outinit(tp) /* returns - none*/
struct tnode *tp;
{
register short typeout;
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 == CLONG || tp->t_op == SYMBOL ) {
if( tp->t_op != CINT ) /* [vlh] 4.1 added CLONG... */
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');
if (!gflag)
printf("*line %d\n",lineno);
else
printf("~_lN%d:\n",lineno);
}

View File

@@ -0,0 +1,372 @@
.he "C68 Code Generator"Change Log"Page %"
.de bg
.sp
.in +5
..
.de eg
.sp
.in -5
..
1. 7/20/82 - Post fix operators
.bg
Post fix operators were being handled a la PDP-11, i.e. if( x++ ) ...
would be true if the result of the post-increment were true rather than
the original value of x.
Also, if( --x ) ... would generate an unnecessary test instruction.
Added scodegen (delay???) routine to pick off post-fix operators,
call codegen to generate the code for the pruned tree, then generate code
for the post-fix operators.
This will generate horrendous code for something like: if( x[i]++ );
but t.s.
.eg
2. 7/21/82 - divide by long constant
.bg
The construct: x / 10L did not generate a ldiv call because long constants
Sethy-Ullman numbers are being calculated normally.
Added DCLONG operator and check in canon to check for this case.
This prevents sucomp from incorrectly computing the Sethy-Ullman number.
.eg
3. 7/23/82 - shifting long or byte address by 1
.bg
The construct: x =<< 1 generated an invalid assembly instruction if x
was an automatic or static byte or long.
This is because you may only shift words in memory (The 68000
clone strikes again!!!).
Changed code skeletons for eqshft to only match for addressable words.
.eg
4. 8/7/82 - complex long divide/modulus expressions
.bg
Complex expressions involving long over short divides or modulus would
not work, not consistently sign extending word result.
Changed test in expand to check for DIV or MOD operators in long tree
and set extf flag.
.eg
5. 8/7/82 - add of quick negative did not generate subq
.bg
The expression: x = y - 1; with x & y registers generated an add #-1,Rx
rather than suq #1,Rx. This was because rcgen was turning ADD into EQADD.
Added test in ucodegen for both ADD and EQADD.
.eg
6. 8/12/82 - multiply(divide) by -1
.bg
The expression: x =* -1; was being "optimized" to negate x, however it
did not store the result in x.
This is because of multiply/divide by -1 optimization in canon not
checking for =* or =/.
Added checks.
.eg
7. 8/27/82 - character array assigned function value
.bg
The expression: x[i] = f(i); did not generate correct code, the address
register for x[i] was computed, but not saved on stack, then f was called.
This resulted in all further function calls using the first argument
push rather than a move.
In ucodegen, when optimizing for address register shifted left by 1 or 2
did not do fixresult call which would have saved register on stack.
Added this call.
Also added code skeleton to compile the function expression to the stack,
then move that directly to the computed address.
.eg
8. 9/1/82 - address-indexed addressing mode used .b index
.bg
If the index register used in an address-indexed addressing mode
operand was byte, the index register was given a .b extension even
though it had correctly extended the register to a word.
In outaexpr for INDEXED addressing mode an outatype of the index
type should have been used rather than outtype.
.eg
9. 9/1/82 - x =* -1, x =/ -1, x=^ -1 optimizations
.bg
Added EQNEG and EQNOT operators and added checks in canon so that
x =* -1 and x =/ -1 are changed to neg operations and x =^ -1 is
changed to not operation.
.eg
10. 9/15/82 - function redeclaration bug
.bg
If an external function was redeclared in a function body, a
redeclaration error occured.
This was fixed in dodecl by checking for a function of AUTO type
and changing it to a function of EXTERNAL type.
.eg
11. 9/15/82 - Hard long to register fix
.bg
The syntax: b =* x; where b was a long register would give an error
"hard long to register".
This was because the lamul function expected to do the assignment to
a memory location.
Changed canon so that hard =*, =/ and =% would be changed to use
the normal long multiply and divide routines, and then do an assignment.
.eg
12. 9/15/82 - Casting Problems (Not fixed)
.bg
The syntax: i = (char) i; where i is not a register would result in
i being assigned the high-order byte of i.
This also is a problem for any cast where the cast type is smaller
than the type being cast.
Generally this should be solved by moving the expression into a data
register, and then obtaining the result from there.
Added DOCAST operator to handle these problems.
However, this is all tightly interwined with conversions in the parser.
.eg
13. 11/24/82 - More than two constants couldn't be combined
.bg
Constant optimization failed to mathematically compute constant
arithmetic fully (the results were lost) thus yielding the result
as the computation of the last two constants in the expression
only.
.eg
14. 12/13/82 - structure assignments
.bg
One structure may be assigned to another provided that the one on
the right is smaller than or equal to the left one in size.
.eg
15. 1/10/83 - floating point
.bg
Floating point handling including constants, conversions and operations
added.
.eg
16. 1/14/83 - pop stack instruction
.bg
The popstack instruction of 1..8 was turned into an addq.w which only
affected half of the sp register. The "add #d,sp" has been replaced
by either "addq.l #d,sp" or "adda.l #d,sp".
.eg
17. 1/14/83 - optimization eqmult, eqdiv, eqmod
.bg
Generated a new code skeleton entry to deal with register integer mults,
divs, and mods (eg. register int i; i =* 34;).
.eg
18. 1/17/83 - return of 0L
.bg
Code skeletons generated a clr R0 regardless of operand type.
.eg
19. 1/21/83 - prefix ++, -- problems with bytes
.bg
The code skeletons for fr_eqop were a total mess, particularly for
the left hand side being a character.
Rewrote all fr_eqop and fr_eqmult code skeletons to handle these cases.
Unfortunately rcgen also gets into the act turning all =+, =-, =&, =| and
pre++, pre-- compiled for register into compiled for effect then returning
the left hand side symbol.
This is probably OK for word and long LHS but for byte it results in
lost precision.
Changed rcgen to check for CHAR LHS and not to compile for effect if so.
.eg
20. 2/2/83 - long eq_shift int
.bg
Bad code was generated for long's left shifted by integer values.
.eg
21. 2/23/83 - longs divided by integers
.bg
Ext.l was not always done.
.eg
22. 3/1/83 - casting to char
.bg
Added the docast operator, forces the variable to be put into a register
and an ext.w to be acted upon it.
.eg
23. 3/2/83 - casting register char * to int
.bg
Bad code was generated for casting a character to an integer if the
character was pointed to by a register character pointer.
.eg
24. 3/3/83 - Compiling complex indirect into A Reg.
.bg
The construct: *p->q->r generated an intermediate load into a D reg
then move to A reg, rather than compiling directly into A reg.
This was because of some hysterical PDP-11 code in expand checking
for whether an A register is appropriate.
.eg
25. 3/3/83 - dbra instruction
.bg
The construct: if( --i != -1 ) goto x; now generates a dbra i,x
instruction. This combined with the new for and while loops easily
enables you to generate dbra instructions for loops. This affected
code in condbr to check for the specific expression tree above.
.eg
26. 3/3/83 - Bit field assigned to bit field
.bg
The construct: x.bf1 = x.bf2 failed due to fixbfield not fixing up
the RHS of the expression. Added recursive call to fixbfield to
fix up RHS's of equal operators.
.eg
27. 3/4/83 - Post increment with ?: op
.bg
Post increment and post decrement operations can not be delayed in the
case of a ?: operation. The post operation was taking place regardless
of whether the case in question was executed.
.eg
28. 3/7/83 - long div/mod/mul/sub/add const 1L or const 0L
.bg
Added optimization handling for long constant zero and one handling.
An error is now generated is a mod or div 0 is found. Add/Sub of
a consant 0 does not generate any code. Mult/Div 1 does not generate
any code
.eg
29. 3/8/83 - eqmod 1 and eqmult 0
.bg
Incorrect storage of simple expressions eqmod 1 and eqmult 0 which
result in a zero store. Also added for the long case.
.eg
30. 3/18/83 - reg ptr assign and character compare
.bg
The statement if (*(regptr = str)); did not do the test for the character
pointed to but rather the result of the assignment. This was caused
by a codegen optimization which should not include a-registers.
.eg
31. 3/21/83 - Complex assignment to character array
.bg
The expression: ca[i] = f(); would move i to the stack as a word and pop
it as a long.
This was caused by the code skeleton macro (S_FORSTACK + S_INDR) assuming
what was going on the stack will always be a long.
Did quick and dirty fix in expand to extend an int sub-tree to a long
if compiling subtree FORSTACK+INDR.
.eg
32. 4/4/83 - unary operations on address registers [vlh] 4.1
.bg
Operations involving unary operations on addresses was not forcing the
use of a temporary data register to do the actual operation. This
was causing bad code to be generated for certain expressions, eg.
array[-i], or array[~i].
.eg
33. 5/23/83 - long constant optimizations [vlh] 4.1
.bg
Changed all the constant optimizations to handle longs as well as
ints. This will make life more difficult on the pdp-11 but makes
for more optimal code (eg. l *= 2...).
.eg
34. 5/25/83 - pre-operators over &&, ||, ? [vlh] 4.1
.bg
Preincrement/decrement were not working correctly over &&, || and ?
operators.
This was due to rcgen generating code for preinc/dec even if && or ||
was seen in tree.
Added test in rcodegen to stop trying for register optimizations over &&, ||
and ?.
.eg
35. 5/25/83 - post-operators over &&, ||. [vlh] 4.1
.bg
Postincrement/decrement operators were not working correctly over && and ||.
This was due to scodegen/addptree pulling out all post-operators over && and
|| operators. Added check in addptree to stop at && and ||.
Condbr then does an scodegen over the && and || to do the post-operators.
.eg
36. 5/25/83 - post-increments over assigns and autoinc/dec [mc] 4.1
.bg
Postincrement/decrement over expressions involving assignment operators and
autoinc/autodec did not work correctly. For example: c[i=+1]++ and c[*p++]++;
This was because the sub-expression tree which is copied did not adjust for
things which are being altered in the sub-expression.
Fixed tcopy, addptree and fixbfield to fix this problem.
This is not guaranteed to work in extremely complicated code involving
assignment and post-op operators, for example, something like:
c[c[i=+1]++]++; And is especially not guaranteed to work with bit-fields
in something like: (c[i=+1]++)->bitfield.
.eg
37. 6/1/83 - long multiplication/division as array subscripts [vlh] 4.1
.bg
Array subscripts which involved long operations which required calls to function
routines expected the results to be left in the first address register rather
than the first data register. This caused bad code to be generated.
.eg
38. 6/1/83 - allow long array indices [vlh] 4.1
.bg
In order to generate arrays which are as big as memory the arrays must be larger
than an int in side we need to also allow array indices to be longs. This was
tied in with the long constant evaluation.
.eg
39. 6/21/83 - link file [vlh] 4.2
.bg
Added the link file as an input file, this is necessary for auto inits
and block variables.
Added the symbol "%" as a readicode symbol to signify the need to pull
an entry out of the link file which is being created by the parser.
.eg
40. 7/6/83 - dbra instruction 4.2
.bg
Fixed the dbra conditional test to not be used in the case of a complex
expression (eg. while(--regi != -1 && *l != '\n'); )..
.eg
41. 7/11/83 - if test float [vlh] 4.2
.bg
The testing for float true was not being handled. The construction
if (fp); now does a test for the floating point value being a non zero
32 bit value. This is taking advantage of the fact that both floating
point constructs denote the value zero as a zero.
.eg
42. 7/13/83 - short vs. long vs. int [vlh] 4.2
.bg
For the sake of portability and the likelihood of generating the same
code on the vax which supports a 16 bit short, a 32 bit int and a 32
bit long versus Regulus which supports a 16 bit short, a 16 bit int and
a 32 bit long the code generator has been changed to use only longs
and shorts on the theory that most machines support 16 bit shorts and
32 bit longs.
.eg
43. 7/20/83 - symbolic debugger flag [vlh] 4.2
.bg
Added the '-g' flag. Required a change to the outline routine to outline
cdb type line number identifying lables rather than the standard sort.
Also altered readicode to output a line number identifier on a null
expression (allows a line number to be placed previous to asm() code
as well as loops).
.eg
44. 7/22/83 - Suppress optimization which gens bad code [vlh] 4.2
.bg
Changed rcodegen to not do the rcgen call if the operator is less-than,
or greater-than. This keeps certain expressions from being evaluated
in the wrong order. In particular ((regi=f(3)) > f(1)).
.eg
45. 7/25/83 - unsigned char/long [vlh] 4.2
.bg
Initial work required to generate code for unsigned char and unsigned
long types.
.eg
46. 7/26/83 - preinc/dec, postinc/dec floats [vlh] 4.2
.bg
Added OPCALL entries for preinc/predec and postinc/postdec.
.eg
47. 8/2/83 - bad optimizations [vlh] 4.2
.bg
An expression anded (&) with a 0 or an expression multiplied (*) by a
zero in which the expression has side effects (eg. function call which
changes global variables) would cause bad code to be generated. This
has been a problem in a number of other compilers and was noted on the
usenet by DMR himself.
.eg
48. 8/3/83 - 68010 changes [vlh] 4.2
.bg
Added the 68010 flag (called m68010). Code now generates a "move cc"
instead of "move sr" in scodegen if the 68010 flag is specified. An
alternative routine fakecmpm has been added because the 68010 does not
properly handle the cmpm instruction.
.eg
49. 8/9/83 - source file [vlh] 4.2
.bg
Fixed readicode to pick up a source filename as well as the current line
number, for use in error reporting.
.eg
50. 8/10/83 - int cast pushed on stack as long [vlh] 4.2
.bg
Fixed match() so that it would not optimize out conversion operators on
items destined to be put on the stack (eg. f(((int)l)&0xff);). Required
adding a test for cookie != FORSP.
.eg
51. 8/23/83 - long indexes [vlh] 4.2
.bg
Fixed optim to not optimize long constant offsets into arrays into 16 bit
displacements.
.eg
52. 8/26/83 - constant int/long assigned to char [vlh] 4.2
.bg
Added code to optim to truncate Constant integers and longs which were
being assigned to character values via ops: equal, eqadd, eqsub, eqand,
eqor, eqxor.
.eg
53. 8/30/83 - if (main)... [vlh] 4.2
.bg
Altered outaexpr to not generate the '#' preceding a symbol expression
which does not have an offset and is and external or static variable
being generated for condition codes.
.eg

View File

@@ -0,0 +1,623 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char *version = "@(#)c168 code generator 4.2 - Sep 6, 1983";
/**
* ALCYON C Compiler for the Motorola 68000 - Code Generator
*
* Called from c68:
*
* c168 icode link asm
*
* icode: parsed intermediate code with some assembly code
* preceded by left parens.
*
* link: contains the procedure link and movem instructions.
*
* asm: output assembler code for as68.
*
* The basic structure of the code generator is as follows:
*
* main - main routine
* readicode - code generation driven by intermediate code
*
**/
#include "cgen.h"
#include "cskel.h"
char *opap;
short gflag;
short nextlabel = 10000;
char null[] = "";
short lflag = 1;
char source[PATHSIZE] = "";
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, *calledby;
calledby = *argv++;
if( argc < 4 )
usage(calledby);
if( fopen(*argv,&ibuf,0) < 0 ) /* 3rd arg for versados */
ferror("can't open %s",*argv);
if( fopen(*++argv,&lbuf,0) < 0)
ferror("can't open %s",*argv);
if( fcreat(*++argv,&obuf,0) < 0 )
ferror("can't create %s",*argv);
for( argc -= 4; argc--; ) {
q = *++argv;
if( *q++ != '-' )
usage(calledby);
while( 1 ) {
switch( *q++ ) {
case 'a': /* [vlh] 4.2, alter ego of the '-L' flag */
lflag = 0;
continue;
case 'c':
cflag++;
continue;
case 'e':
eflag++;
continue;
case 'f':
fflag++;
continue;
case 'g': /* [vlh] 4.2 generate line labels for cdb */
gflag++;
continue;
case 'm':
mflag++;
continue;
case 'o':
oflag++;
continue;
case 'D':
dflag++;
continue;
case 'L': /* [vlh] 4.2, OBSOLETE */
lflag++;
continue;
case 'T': /* [vlh] 4.2 generates code for the 68010 */
m68010++;
continue;
case '\0':
break;
default:
usage(calledby);
}
break;
}
}
readicode();
myfflush(&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 short c;
register struct tnode *tp;
while( (c=getc(&ibuf)) > 0 ) {
switch(c) {
case '.':
lineno = readshort();
readfid();
opap = exprarea;
if( tp = readtree() ) {
PUTEXPR(cflag,"readicode",tp);
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;
}
}
else
outline();
break;
case '(':
while( (c=getc(&ibuf)) != '\n' )
putchar(c);
putchar(c);
break;
case '%': /* [vlh] 4.2 */
while( (c=getc(&ibuf)) != '\n' )
; /* skip over carriage return */
while( (c=getc(&lbuf)) != '%' && c != -1)
putchar(c);
if (c == -1)
ferror("early termination of link file");
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 short op, type, sc;
register struct tnode *tp, *rtp;
char sym[SSIZE];
if( (op=readshort()) <= 0 )
return(0);
type = readshort();
switch( op ) {
case SYMBOL:
if( (sc=readshort()) == EXTERNAL )
tp = cenalloc(type,sc,readsym(sym));
else
tp = snalloc(type,sc,readshort(),0,0);
break;
case CINT:
tp = cnalloc(type,readshort());
break;
case CLONG:
tp = lcnalloc(type,readlong()); /* [vlh] 4.1 was two readshort's */
break;
case CFLOAT: /* [vlh] 3.4 */
tp = fpcnalloc(type,readlong()); /* [vlh] 4.1 was two readshort's */
break;
case IFGOTO:
case BFIELD:
sc = readshort();
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);
}
/* readfid - read source filename out of intermediate file */
readfid()
{
register char *p;
p = &source[0];
while( (*p = getc(&ibuf)) != '\n')
p++;
*p = 0;
}
/* readshort - reads an integer value from intermediate code*/
short
readshort()
{
register short c;
register short i;
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;
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);
}
}
}
/* readlong - reads a long value from intermediate code*/
long
readlong() /* [vlh] 4.1 */
{
long l;
register unsigned short w1, w2;
register short c, onedot;
w2 = 0; onedot = 0;
while(1) {
switch( c = getc(&ibuf) ) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
w2 <<= 4;
w2 += (c-'0');
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
w2 <<= 4;
w2 += (c-('a'-10));
break;
case '.':
if (!onedot++) {
w1 = w2;
w2 = 0;
continue;
}
case '\n':
if (onedot) {
l.hiword = w1;
l.loword = w2;
return(l);
}
default:
error("intermediate code error - %c,%d",c,c);
}
}
}
/* readsym - read a symbol from intermediate code*/
char *readsym(sym)
char *sym;
{
register short 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++;
if( lineno != 0 )
printf((char *)STDERR,"\"%s\", ** %d: ",source,lineno);
printf((char *)STDERR,s,x1,x2,x3,x4,x5,x6);
cputc('\n',STDERR);
}
/* warning - output a warning message*/
warning(s,x1,x2,x3,x4,x5,x6)
char *s;
int x1, x2, x3, x4, x5, x6;
{
if( lineno != 0 )
printf((char *)STDERR,"\"%s\", ** %d: (warning) ",source,lineno);
else
printf((char *)STDERR,"(warning) ");
printf((char *)STDERR,s,x1,x2,x3,x4,x5,x6);
cputc('\n',STDERR);
}
/* 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 short i;
for( p = sym1, q = sym2, i = SSIZE; --i >= 0; )
*q++ = (*p ? *p++ : '\0');
}
/* usage - ouput usage message*/
usage(calledby)
char *calledby;
{
ferror("usage: %s icode link asm [-DLameco]",calledby);
}
/* cputc - put a character to a file descriptor (used by error) */
cputc(c, fn)
char c;
int fn;
{
#ifdef VERSADOS
versaputchar(c);
#else
if (fn == STDERR)
write(STDERR, &c, 1);
else
putchar(c);
#endif
}
/**
* 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( dflag > 1 )
write(1,&c,1); /*to standard output*/
putc(c,&obuf); /*put to assembler file*/
}
#ifdef VERSADOS
#define STDOUT 1
struct iob versfout { STDOUT, BSIZE, &versfout.cbuf[0]};
versaputchar(c)
char c;
{
if (c == '\n') { /* end of line */
if (versaflush()) /* write one line */
return(-1);
return(c);
}
/* buffered output */
if (versfout.cc <= 0) {
versfout.cp = &(versfout.cbuf[0]);
if (write(versfout.fd,versfout.cp,BSIZE) != BSIZE)
return(-1);
versfout.cc = BSIZE;
}
*(versfout.cp)++ = c;
versfout.cc--;
return(c);
}
versaflush()
{
register short size, fildes;
if ((size = (BSIZE - versfout.cc)) == 0)
return(0);
versfout.cc = BSIZE;
versfout.cp = &(versfout.cbuf[0]);
fildes = (versfout.fd <= STDERR) ? 6 : versfout.fd;
if (write(fildes,versfout.cp,size) < 0)
return(-1);
return(0);
}
#else
# ifdef VAX11
getc(ibuf)
struct iob *ibuf;
{
if (ibuf->cc <= 0) {
ibuf->cp = &(ibuf->cbuf[0]);
ibuf->cc = read(ibuf->fd,ibuf->cp,BSIZE);
}
if (ibuf->cc <= 0)
return(-1);
ibuf->cc--;
return((int)(*(ibuf->cp)++)&0xff);
}
fopen(fname,ibuf)
char *fname;
register struct iob *ibuf;
{
ibuf->cc = 0; /* no chars */
ibuf->fd = open(fname,0);
return(ibuf->fd);
}
# endif
#endif
myfflush(mybuf)
register struct iob *mybuf;
{
register i;
i = BSIZE - mybuf->cc;
mybuf->cc = BSIZE;
mybuf->cp = &(mybuf->cbuf[0]);
if (write(mybuf->fd,mybuf->cp,i) != i)
return(-1);
return(0);
}
#ifdef DRI
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);
}
#endif

View File

@@ -0,0 +1,116 @@
CC = cc
C68 = nc68
VAXOBJS = vaxobj/canon.o \
vaxobj/codegen.o \
vaxobj/interf.o \
vaxobj/main.o \
vaxobj/optab.o \
vaxobj/putexpr.o \
vaxobj/smatch.o \
vaxobj/sucomp.o \
vaxobj/tabl.o \
vaxobj/util.o \
vaxobj/cskels.o
C68OBJS = 68obj/canon.o \
68obj/codegen.o \
68obj/interf.o \
68obj/main.o \
68obj/optab.o \
68obj/putexpr.o \
68obj/smatch.o \
68obj/sucomp.o \
68obj/tabl.o \
68obj/util.o \
68obj/cskels.o
CFLAGS = -O -w -DVAX11 -DDEBUG
C68FLAGS = -L -r -DMC68000 -DDEBUG -t0 -t1
LIB = -lV6
C68LIB = -l6
.IGNORE:
vax: ${VAXOBJS}
mkver -e "Code Generator -"
${CC} ${CFLAGS} version.c ${VAXOBJS} -o c168.vax ${LIB}
c168: ${C68OBJS}
mkver -e "Code Generator -"
${C68} -r ${C68FLAGS} version.c ${C68OBJS} -o c168.68 ${C68LIB}
setstack c168.68 8000 8000
2k: ${C68OBJS}
mkver -e "Code Generator -"
${C68} -n2 -r ${C68FLAGS} version.c ${C68OBJS} -o c168.2k ${C68LIB}
setstack c168.2k 8000 8000
4k: ${C68OBJS}
mkver -e "Code Generator -"
${C68} -n -r ${C68FLAGS} version.c ${C68OBJS} -o c168.4k ${C68LIB}
setstack c168.4k 8000 8000
all: vax 4k
vaxobj/canon.o: canon.c
${CC} ${CFLAGS} -c canon.c;mv -f canon.o vaxobj/canon.o
vaxobj/codegen.o: codegen.c
${CC} ${CFLAGS} -c codegen.c;mv -f codegen.o vaxobj/codegen.o
vaxobj/interf.o: interf.c
${CC} ${CFLAGS} -c interf.c;mv -f interf.o vaxobj/interf.o
vaxobj/main.o: main.c
${CC} ${CFLAGS} -c main.c;mv -f main.o vaxobj/main.o
vaxobj/optab.o: optab.c
${CC} ${CFLAGS} -c optab.c;mv -f optab.o vaxobj/optab.o
vaxobj/putexpr.o: putexpr.c
${CC} ${CFLAGS} -c putexpr.c;mv -f putexpr.o vaxobj/putexpr.o
vaxobj/smatch.o: smatch.c
${CC} ${CFLAGS} -c smatch.c;mv -f smatch.o vaxobj/smatch.o
vaxobj/sucomp.o: sucomp.c
${CC} ${CFLAGS} -c sucomp.c;mv -f sucomp.o vaxobj/sucomp.o
vaxobj/tabl.o: tabl.c
${CC} ${CFLAGS} -c tabl.c;mv -f tabl.o vaxobj/tabl.o
vaxobj/util.o: util.c
${CC} ${CFLAGS} -c util.c;mv -f util.o vaxobj/util.o
vaxobj/cskels.o: cskels.c
${CC} ${CFLAGS} -c cskels.c;mv -f cskels.o vaxobj/cskels.o
68obj/canon.o: canon.c
${C68} ${C68FLAGS} -c canon.c;mv -f canon.o 68obj/canon.o
68obj/codegen.o: codegen.c
${C68} ${C68FLAGS} -c codegen.c;mv -f codegen.o 68obj/codegen.o
68obj/interf.o: interf.c
${C68} ${C68FLAGS} -c interf.c;mv -f interf.o 68obj/interf.o
68obj/main.o: main.c
${C68} ${C68FLAGS} -c main.c;mv -f main.o 68obj/main.o
68obj/optab.o: optab.c
${C68} ${C68FLAGS} -c optab.c;mv -f optab.o 68obj/optab.o
68obj/putexpr.o: putexpr.c
${C68} ${C68FLAGS} -c putexpr.c;mv -f putexpr.o 68obj/putexpr.o
68obj/smatch.o: smatch.c
${C68} ${C68FLAGS} -c smatch.c;mv -f smatch.o 68obj/smatch.o
68obj/sucomp.o: sucomp.c
${C68} ${C68FLAGS} -c sucomp.c;mv -f sucomp.o 68obj/sucomp.o
68obj/tabl.o: tabl.c
${C68} ${C68FLAGS} -c tabl.c;mv -f tabl.o 68obj/tabl.o
68obj/util.o: util.c
${C68} ${C68FLAGS} -c util.c;mv -f util.o 68obj/util.o
68obj/cskels.o: cskels.c
${C68} ${C68FLAGS} -c cskels.c;mv -f cskels.o 68obj/cskels.o

View File

@@ -0,0 +1,16 @@
CC = c68
OBJS = canon.o codegen.o interf.o main.o optab.o putexpr.o smatch.o sucomp.o \
tabl.o util.o cskels.o
CFLAGS = -L -r
LIB = -l6
st: ${OBJS}
@mkver -e "code generator - "
${CC} ${CFLAGS} -n ${OBJS} version.c ${LIB} -o c168.st
@setstack c168.st 8192 8192 ; size c168.st
c068: ${OBJS}
@mkver -e "code generator - "
${CC} ${CFLAGS} ${OBJS} version.c ${LIB} -o c168.68
@setstack c168.68 8192 8192 ; size c168.68

View File

@@ -0,0 +1,16 @@
>mkver -e "C68 Code Generator -"
char *compiled = "@(#) C68 Code Generator - Wed Sep 7 16:05 1983";
>c68 -S -L -DVERSADOS -DMC68000 canon.c
>c68 -S -L -DVERSADOS -DMC68000 codegen.c
>c68 -S -L -DVERSADOS -DMC68000 cskels.c
>c68 -S -L -DVERSADOS -DMC68000 interf.c
>c68 -S -L -DVERSADOS -DMC68000 main.c
>c68 -S -L -DVERSADOS -DMC68000 optab.c
>c68 -S -L -DVERSADOS -DMC68000 putexpr.c
>c68 -S -L -DVERSADOS -DMC68000 smatch.c
>c68 -S -L -DVERSADOS -DMC68000 sucomp.c
>c68 -S -L -DVERSADOS -DMC68000 tabl.c
>c68 -S -L -DVERSADOS -DMC68000 util.c
>c68 -S -L -DVERSADOS -DMC68000 version.c
>mv *.s vst
>

View File

@@ -0,0 +1,323 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
#include "cskel.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
extern struct skeleton /*char /* really struct skeleton.... */
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*/
short invrel[] = { NEQUALS, EQUALS, LESSEQ, LESS, GREATEQ, GREAT };
/*turns x>y into y<=x*/
short 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,252 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
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 ADDR*/
"U*", /*61 INDR*/
"&&", /*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*/
};
#ifdef DEBUG
char *types[] = {
"typeless-invalid", /*0=TYPELESS*/
"char", /*1=CHAR*/
"short", /*2=SHORT*/
"int", /*3=INT*/
"long", /*4=LONG*/
"uchar-invalid", /*5=UCHAR*/
"ushort-invalid", /*6=USHORT*/
"uint", /*7=UINT*/
"ulong-invalid", /*8=ULONG*/
"float", /*9=FLOAT*/
"double", /*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",
};
short level;
putexpr(name,tp)
char *name;
struct tnode *tp;
{
printf("%s\n",name);
putsexpr(tp);
}
putsexpr(tp)
struct tnode *tp;
{
level++;
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 short i;
for( i = 0; i < level; i++ ) {
putchar(' ');putchar(' ');putchar(' ');putchar(' ');
}
}
puttsu(tp)
struct tnode *tp;
{
register short 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,535 @@
/*
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 short op, nreg, reg;
register short c;
register short extf, i2f;
register struct tnode *ltp, *rtp;
register char *p;
register short i, sreg, flag, subtrees, scookie;
register char *macro;
/**
* This is a kludge because not all of the arithmetic operators
* will work on address registers - the 68000 clone strikes again
**/
op = tp->t_op;
#ifdef DEBUG
if(eflag) printf("expand op=%d left=%x right=%x skp=%lo\n",op,
skp->sk_left,skp->sk_right,skp);
#endif
if(((op>=MULT && op<=COMPL) || (op>=LMULT && op<=LMOD)) || tp->t_type==CHAR)
freg = DREG(freg); /* [vlh] 4.1 added UMINUS, COMPL, LMUL, LDIV */
macro = skp->sk_def;
i2f = extf = 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:
op_expand(op,tp->t_type,ltp->t_type);
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;
if( LONGORPTR(p->t_type) == 0 && (flag&S_STACK) != 0 )
p = tnalloc(INT2L,LONG,0,0,p);
}
reg = AREG(reg); /*no qualifications before...*/
#ifdef DEBUG
if (eflag)
printf("reg = %d, nreg = %d, freg = %d\n",reg,nreg,freg);
#endif
}
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);
}
#ifdef DEBUG
if(eflag) printf("ending expand skp=%lo\n",skp);
#endif
return(freg);
}
/* op_expand - printf out the subroutine being called */
op_expand(op,type,ltype)
int op, type,ltype;
{
if( ISFLOAT(type) || ISFLOAT(ltype) ) {
switch( op ) {
case ADD:
case EQADD:
case PREINC: /* [vlh] 4.2 */
case POSTINC: /* [vlh] 4.2 */
printf("_fpadd");
break;
case SUB:
case EQSUB:
case PREDEC: /* [vlh] 4.2 */
case POSTDEC: /* [vlh] 4.2 */
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 point 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;
}
}
}
/*
* 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 * /* returns ptr to code skeleton*/
match(tp,cookie,reg) /* 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 short op, bop;
short i;
register struct tnode *ltp, *rtp;
#ifdef DEBUG
if(mflag) printf("match op=%d cookie=%d reg=%d\n",tp->t_op,cookie,reg);
#endif
PUTEXPR(mflag,"match",tp);
if( (op=tp->t_op) >= LCGENOP )
return(0);
if( LEAFOP(op) )
ltp = tp;
else
ltp = tp->t_left;
if( (bop=BINOP(op)) && cookie!=FORSP) { /* [vlh] 4.2 !FORSP */
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);
}
#ifdef DEBUG
if(mflag) printf("match op=%d i=%d ",op,i);
#endif
if( !(i=optab[op][i]) )
return(0);
skp = codeskels[i];
#ifdef DEBUG
if(mflag) printf("codeskels[%d]=%o\n",i,skp);
#endif
#ifdef DEBUG
if(mflag) {
printf("match LEFT ");
puttsu(ltp);
if(bop) {
printf(" RIGHT ");
puttsu(rtp);
}
putchar('\n');
}
#endif
for( ; skp->sk_left != 0; skp++ ) {
#ifdef DEBUG
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;
#ifdef DEBUG
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 short 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( ISFUNCTION(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 short or char*/
if( type == CHAR )
return(1);
case T_INT:
return( type == INT || const );
case T_UNSN:
case T_UANY: /* [vlh] 4.2 */
case T_UCHAR: /* [vlh] 4.2 */
case T_ULONG: /* [vlh] 4.2 */
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 short 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 - short required on left*/
/*004000-- OPRWORD - short required on right*/
/*010000-- OPCOM commutative*/
/*020000-- OPRAS - right associative*/
/*040000-- OPTERM - termination node*/
/*100000 - OPCONVS - conversion operator*/
short 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,389 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
#include "cskel.h"
char null[];
char *opname[];
/* 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,autof) /* returns ptr to copied tree*/
struct tnode *tp;
int autof; /* can do AUTOINC and AUTODEC? */
{
register char *p;
register short op;
op = tp->t_op;
switch( 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);
case AUTOINC: /*[mac] 4.2*/
case AUTODEC:
p = snalloc(tp->t_type,AUTO,0,0,0);
if( autof == DOAUTO )
p->t_op = op;
p->t_reg = tp->t_reg;
return(p);
default:
p = tnalloc(op,tp->t_type,0,0,null,null);
if( ISASGOP(op) || op == PREINC || op == PREDEC ) /* [mac] 4.2 */
p->t_right = tcopy(tp->t_right,DOAUTO);
else if( BINOP(op) )
p->t_right = tcopy(tp->t_right,autof);
p->t_left = tcopy(tp->t_left,autof);
return(p);
}
}
/* outaexpr - output address expression*/
outaexpr(tp,flags) /* returns - none*/
struct tnode *tp; /* pointer to tree*/
int flags; /* flags (IMMED,LOFFSET,...)*/
{
register short 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 %s\n",opname[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 short 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) || 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;
{
register int lreg, rreg;
if (!m68010) { /* 68000 version cmpm ok !!! */
printf("cmpm");
outtype(tp->t_left->t_type);
printf(" (R%d)+,(R%d)+\n",tp->t_left->t_reg,tp->t_right->t_reg);
}
else /* generating code for 68010, micro code is bad for cmpm */
fakecmpm(tp->t_left->t_type,tp->t_left->t_reg,tp->t_right->t_reg);
}
/* fakecmpm - output 68010 fake cmpm for bad microcode [vlh] 4.2 */
fakecmpm(type,lreg,rreg)
int type,lreg,rreg;
{
printf("cmp");
outtype(type);
printf(" (R%d),(R%d)\n",lreg,rreg);
if( ISFLOAT(type) || LONGORPTR(type) )
printf("addq #4,R%d\naddq #4,R%d\n",lreg,rreg);
else if( type == CHAR )
printf("addq #1,R%d\naddq #1,R%d\n",lreg,rreg);
else
printf("addq #2,R%d\naddq #2,R%d\n",lreg,rreg);
}
/* 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 - Tue Sep 6 14:30 1983";

View File

@@ -0,0 +1,26 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) ar68.h - Jul 26, 1983 REGULUS 4.1
*/
#define LIBMAGIC 0177545
#define LIBHDSIZE 26
#define LIBNSIZE 14
struct libhdr {
char lfname[LIBNSIZE];
long lmodti;
char luserid;
char lgid;
#ifndef VAX11
int lfimode;
#else
unsigned short lfimode;
#endif
long lfsize;
};

View File

@@ -0,0 +1,97 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) sys/cout.h - Jul 26, 1983 REGULUS 4.1
*/
struct hdr {
#ifndef VAX11
int ch_magic; /* c.out magic number 060016 = $600E */
#else
unsigned short ch_magic;
#endif
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; /* location of entry point */
short ch_rlbflg; /* relocation bits present flag, must be signed */
};
struct hdr_cout {
#ifndef VAX11
int ftype; /* c.out magic number 060016 = $600E */
#else
unsigned short ftype;
#endif
long ftext; /* text size */
long fdata; /* data size */
long fbss; /* bss size */
long fsym; /* symbol table size */
long fssize; /* stack size */
long fentry; /* location of entry point */
short fflag; /* relocation bits present flag, must be signed */
};
struct hdr2 {
#ifndef VAX11
int ch_magic; /* c.out magic number = 601B hex */
#else
unsigned short ch_magic;
#endif
long ch_tsize; /* # bytes in program text segment */
long ch_dsize; /* # bytes in program data segment */
long ch_bsize; /* # bytes in program bss segment */
long ch_ssize; /* # bytes in symbol table */
long ch_stksize; /* initial stack size */
long ch_entry; /* entry point--address of text segment */
short ch_rlbflg; /* relocation bits suppressed flag, must be signed */
long ch_dstart; /* address of data segment */
long ch_bstart; /* address of bss segment */
};
/* HDSIZE should be 28 bytes, HDSIZ2 should be 36 bytes */
#ifndef VAX11
# define HDSIZE (sizeof (struct hdr))
# define HDSIZ2 (sizeof (struct hdr2))
#else
# define HDSIZE 28
# define HDSIZ2 36
#endif
#ifdef VAX11
# define MAGIC (unsigned short) 0x601a /* bra .+26 instruction */
# define MAGIC1 (unsigned short) 0x601b /* data & bss base defined */
# define MAGICST2 (unsigned short) 0x601c /* shared text 2K boundary */
# define MAGICID (unsigned short) 0x601d /* I & D split */
# define MAGICST (unsigned short) 0x601e /* shared test 4k boundary (-n default) */
# define EX_MAGIC (unsigned short) 0x601a
# define EX_ABMAGIC (unsigned short) 0x601b
# define EX_2KSTXT (unsigned short) 0x601c
# define EX_IDMAGIC (unsigned short) 0x601d
# define EX_4KSTXT (unsigned short) 0x601e
#else
# define MAGIC 0x601a /* bra .+26 instruction */
# define MAGIC1 0x601b /* data & bss base defined */
# define MAGICST2 0x601c /* shared text 2K boundary */
# define MAGICID 0x601d /* I & D split */
# define MAGICST 0x601e /* shared test 4k boundary (-n default) */
# define EX_MAGIC 0x601a
# define EX_ABMAGIC 0x601b
# define EX_2KSTXT 0x601c
# define EX_IDMAGIC 0x601d
# define EX_4KSTXT 0x601e
#endif
#define SHT2KBOUND 2048
#define SHT2KFIX(x) (((x+SHT2KBOUND-1)/SHT2KBOUND)*SHT2KBOUND)
#define SHT4KBOUND 4096
#define SHT4KFIX(x) (((x+SHT4KBOUND-1)/SHT4KBOUND)*SHT4KBOUND)

View File

@@ -0,0 +1,27 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) cputc.c - Sep 12, 1983 REGULUS 4.1
*/
# include "iodec.h"
/**
** put a single character
**/
int f_log 0;
cputc(c, fn)
char c;
int fn;
{
if (fn == 2) /* Standard Error */
write(fn, &c, 1);
else
putchar(c);
}

View File

@@ -0,0 +1,29 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) fcreat.c - Sep 12, 1983 REGULUS 4.1
*/
/* v6 fcreat library call */
#define BSIZE 512
struct iob {
int fd; /* file descriptor */
int cc; /* char count */
char *cp; /* ptr to next char */
char cbuf[BSIZE]; /* char buffer */
};
fcreat(fname,ibuf)
char *fname;
register struct iob *ibuf;
{
ibuf->cc = BSIZE; /* no chars */
ibuf->cp = &(ibuf->cbuf[0]);
return(ibuf->fd = creat(fname,0666));
}

View File

@@ -0,0 +1,46 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) getarhd.c - Sep 12, 1983 REGULUS 4.1
*/
/*
I/O independent mapping routine. Machine specific. Independent
of structure padding. Buffer must contain at least as many
characters as is required for structure.
*/
#include "ar68.h"
#include "iobuf.h"
/*
* getarhd - fills the archive header structure from the buffer int
* the manner which will be understood on the current machine.
*/
int
getarhd(fp,arptr) /* returns -1 for failure, 0 for success */
FILE *fp;
struct libhdr *arptr;
{
register int i;
register char *p, *lp;
for (i = 0, lp = arptr->lfname; i < LIBNSIZE; i++)
if ((*lp++ = getc(fp)) == -1)
return(-1);
if (lgetl(&arptr->lmodti,fp) == -1)
return(-1);
if ((arptr->luserid = getc(fp)) == -1)
return(-1);
if ((arptr->lgid = getc(fp)) == -1)
return(-1);
if (lgetw(&arptr->lfimode,fp) == -1)
return(-1);
if (lgetl(&arptr->lfsize,fp) == -1)
return(-1);
return(0);
}

View File

@@ -0,0 +1,34 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) getc.c - Sep 12, 1983 REGULUS 4.1
*/
/* v6 getc library routines */
#define BSIZE 512
struct iob {
int fd; /* file descriptor */
int cc; /* char count */
char *cp; /* ptr to next char */
char cbuf[BSIZE]; /* char buffer */
};
getc(ibuf)
struct iob *ibuf;
{
if (ibuf->cc <= 0) {
ibuf->cp = &(ibuf->cbuf[0]);
ibuf->cc = read(ibuf->fd,ibuf->cp,BSIZE);
}
if (ibuf->cc <= 0)
return(-1);
ibuf->cc--;
return((int)((*(ibuf->cp)++)&0xff));
}

View File

@@ -0,0 +1,44 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) getchar.c - Sep 12, 1983 REGULUS 4.1
*/
/* v6 getchar routine */
#define BSIZE 512
struct iob {
int fd; /* file descriptor */
int cc; /* char count */
char *cp; /* ptr to next character */
char cbuf[BSIZE]; /* char buffer */
} fin;
getchar()
{
char c;
register int i;
if (fin.fd == 0) {
if (read(0,&c,1) <= 0 || c==4)
return(0);
i = c;
return(i & 0xff);
}
if (fin.cc <= 0) {
fin.cp = &(fin.cbuf[0]);
fin.cc = read(fin.fd,fin.cp,BSIZE);
}
if (fin.cc <= 0)
return(0);
fin.cc--;
i = *(fin.cp)++;
return(i & 0xff);
}

View File

@@ -0,0 +1,52 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) getchd.c - Sep 12, 1983 REGULUS 4.1
*/
/*
I/O independent mapping routine. Machine specific. Independent
of structure padding. Buffer must contain at least as many
characters as is required for structure.
*/
#include "cout.h"
#include "iobuf.h"
/*
* getchd - fills the c.out header structure from the buffer in
* the manner which will be understood on the current machine.
*/
int
getchd(fp,arptr) /* returns 0 for success, -1 for failure */
FILE *fp;
struct hdr *arptr;
{
if (lgetw(&arptr->ch_magic,fp) == -1)
return(-1);
if (lgetl(&arptr->ch_tsize,fp) == -1)
return(-1);
if (lgetl(&arptr->ch_dsize,fp) == -1)
return(-1);
if (lgetl(&arptr->ch_bsize,fp) == -1)
return(-1);
if (lgetl(&arptr->ch_ssize,fp) == -1)
return(-1);
if (lgetl(&arptr->ch_stksize,fp) == -1)
return(-1);
if (lgetl(&arptr->ch_entry,fp) == -1)
return(-1);
if (lgetw(&arptr->ch_rlbflg,fp) == -1)
return(-1);
if (arptr->ch_magic == EX_ABMAGIC) {
if (lgetl(&arptr->ch_dstart,fp) == -1)
return(-1);
if (lgetl(&arptr->ch_bstart,fp) == -1)
return(-1);
}
return(0);
}

View File

@@ -0,0 +1,19 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) iobuf.h - Jul 26, 1983 REGULUS 4.1
*/
#define BLEN 512
struct iobuf{
int fildes;
int nunused;
char *xfree;
char buff[BLEN];
};
#define FILE struct iobuf

View File

@@ -0,0 +1,34 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) iodec.h - Sep 12, 1983 REGULUS 4.1
*/
# define MAXFILES 15
struct fileps
{
char *buff; /* beginning of buffer */
char *bptr; /* current position */
int nchars; /* number of characters internal */
int bsize; /* size of buffer */
char eoferr; /* end of file flag */
char wrflag; /* mode flag */
char *pbuff; /* bottom of peek buffer */
};
struct fileps __filehdr[MAXFILES];
struct param
{
int bufsize; /* initial buffer size */
int peeksize; /* initial peek size */
};
extern struct param __param;
int __statbuf[MAXFILES];

View File

@@ -0,0 +1,84 @@
.globl _ldivr
.comm _ldivr,4
.globl _ldiv
.globl ldiv
.text
_ldiv:
ldiv:
~~ldiv:
~b=R4
~q=R5
~l1=R7
~l2=R6
~al1=8
~al2=12
~sign=R3
link R14,#-2
movem.l R2-R7,-(sp)
clr R3
clr.l R5
move.l 8(R14),R7
move.l 12(R14),R6
bne L2
move.l #$80000000,_ldivr
move.l #$80000000,R0
bra L1
L2:
bge L3
neg.l R6
add #1,R3
L3:
tst.l R7
bge L4
neg.l R7
add #1,R3
L4:
cmp.l R7,R6
bgt L6
bne L7
move.l #1,R5
clr.l R7
bra L6
L7:
cmp.l #$10000,R7
bge L9
divu R6,R7
move R7,R5
swap R7
ext.l R7
bra L6
L9:
move.l #1,R4
L12:
cmp.l R6,R7
blo L11
asl.l #1,R6
asl.l #1,R4
bra L12
L11:
tst.l R4
beq L6
cmp.l R6,R7
blo L15
or.l R4,R5
sub.l R6,R7
L15:
lsr.l #1,R4
lsr.l #1,R6
bra L11
L6:
cmp #1,R3
bne L16
neg.l R7
move.l R7,_ldivr
move.l R5,R0
neg.l R0
bra L1
L16:
move.l R7,_ldivr
move.l R5,R0
L1:
tst.l (sp)+
movem.l (sp)+,R3-R7
unlk R14
rts

View File

@@ -0,0 +1,22 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) __length.c - Sep 12, 1983 REGULUS 4.1
*/
__length(s)
char *s;
{
register int l;
register char *p;
p = s;
l = 0;
while (*p++)
l++;
return(l);
}

View File

@@ -0,0 +1,46 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) libget.c - Sep 12, 1983 REGULUS 4.1
*/
/*
I/O independent mapping routine. Machine specific. Independent
of structure padding. Buffer must contain at least as many
characters as is required for structure.
*/
#include "order.h"
#include "iobuf.h"
#define dogetc(byte,i,fp) if((i=getc(fp))==-1) return(ERROR); else byte=(char)i
lgetl(lp,f) /* returns -1 for failure, 0 for success */
long *lp; /* 32 bits */
FILE *f;
{
register int i;
dogetc(lp->b1,i,f);
dogetc(lp->b2,i,f);
dogetc(lp->b3,i,f);
dogetc(lp->b4,i,f);
return(SUCCESS);
}
lgetw(lp,f) /* returns -1 for failure, 0 for success */
short *lp; /* 16 bits */
FILE *f;
{
register int i;
dogetc(lp->wb1,i,f);
dogetc(lp->wb2,i,f);
*lp &= 0xffff;
return(SUCCESS);
}

View File

@@ -0,0 +1,40 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) libput.c - Sep 12, 1983 REGULUS 4.1
*/
/*
I/O independent mapping routine. Machine specific. Independent
of structure padding. Buffer must contain at least as many
characters as is required for structure.
*/
#include "order.h"
#include "iobuf.h"
#define doputc(byte,fp) if(putc(byte,fp) == -1) return(ERROR)
lputl(lp,f) /* returns 0 for success, -1 for failure */
long *lp; /* 32 bits */
FILE *f;
{
doputc(lp->b1,f);
doputc(lp->b2,f);
doputc(lp->b3,f);
doputc(lp->b4,f);
return(SUCCESS);
}
lputw(lp,f) /* returns 0 for success, -1 for failure */
short *lp; /* 16 bits */
FILE *f;
{
doputc(lp->wb1,f);
doputc(lp->wb2,f);
return(SUCCESS);
}

View File

@@ -0,0 +1,53 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
@(#) libread.c - Sep 12, 1983 REGULUS 4.1
*/
#include "order.h"
lreadl(fd,str)
int fd;
long *str;
{
register char *p;
char junk[4];
if (read(fd,junk,4) != 4)
return(ERROR);
p = junk;
str->b1 = *p++;
str->b2 = *p++;
str->b3 = *p++;
str->b4 = *p;
return(SUCCESS);
}
lreadw(fd,str)
int fd;
short *str;
{
char junk[2];
if (read(fd,junk,2) != 2)
return(ERROR);
str->wb1 = junk[0];
str->wb2 = junk[1];
return(SUCCESS);
}
lreadc(fd,str)
int fd;
char *str;
{
char junk[1];
if (read(fd,&junk,1) != 1)
return(ERROR);
*str = junk[0];
return(SUCCESS);
}

View File

@@ -0,0 +1,54 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
@(#) libwrite.c - Sep 12, 1983 REGULUS 4.1
*/
#include "order.h"
lwritel(fd,str)
int fd;
long *str;
{
register char *p;
char junk[4];
p = junk;
*p++ = str->b1;
*p++ = str->b2;
*p++ = str->b3;
*p = str->b4;
if (write(fd,junk,4) == 4)
return(SUCCESS);
else
return(ERROR);
}
lwritew(fd,str)
int fd;
short *str;
{
register char *p;
char junk[2];
p = junk;
*p++ = str->wb1;
*p = str->wb2;
if (write(fd,junk,2) == 2)
return(SUCCESS);
else
return(ERROR);
}
lwritec(fd,str)
int fd;
char *str;
{
if (write(fd,str,1) != 1)
return(ERROR);
return(SUCCESS);
}

View File

@@ -0,0 +1,74 @@
*// long multiply routine without floating point
*// call with:
*// two long values on stack
*// returns:
*// long value in R0 and R1
*//
*// warning: no overflow checking or indication!!!!
*struct {
* int hiword;
* int loword;
*};
*long lmul(l1,l2)
*long l1,l2;
*{
*
* long t1;
* register int sign;
* register int t2;
*
* sign = 0;
* if(l1 < 0) {
* l1 = -l1; //make it positive
* sign++;
* }
* if(l2 < 0) {
* l2 = -l2; //make it positive
* sign++;
* }
* t1 = l1.loword*l2.loword;
* t2 = l1.hiword*l2.loword + l2.hiword*l1.loword;
* t1.hiword = t1.hiword + t2;
* if(sign&1)
* t1 = -t1; //negate results
* return(t1);
*}
*
*
.globl lmul
.text
lmul:
_lmul:
~~lmul:
~sign=R2
~l1=8
~l2=12
~t1=-4
~t2=R6
link R14,#-4
clr R2
tst.l 8(R14) //is first arg negative?
bge L2
neg.l 8(R14) //yes, negate it
inc R2 // increment sign flag
L2:tst.l 12(R14) //is second arg negative?
bge L3
neg.l 12(R14) //yes, make it positive
inc R2 //increment sign flag
L3:move 10(R14),R0 //arg1.loword
mulu 14(R14),R0 //arg2.loword
move.l R0,-4(R14) //save in temp
move 8(R14),R0 //arg1.hiword
mulu 14(R14),R0 //arg2.loword
move 12(R14),R1 //arg2.hiword
mulu 10(R14),R1 //arg1.loword
add R1,R0 //form the sum of 2 lo-hi products
add -4(R14),R0 //add to temp hiword
move R0,-4(R14) //store back in temp hiword
move.l -4(R14),R0 //long results
btst #0,R2 //test sign flag
beq L4
neg.l R0 //complement the results
L4:
unlk R14
rts

View File

@@ -0,0 +1,19 @@
.globl _ldiv
.globl _ldivr
.comm _ldivr,4
.globl _lrem
.globl lrem
.text
_lrem:
lrem:
~~lrem:
~l2=12
~al1=8
link R14,#-2
move.l 12(R14),-(sp)
move.l 8(R14),-(sp)
jsr _ldiv
cmpm.l (sp)+,(sp)+
move.l _ldivr,R0
unlk R14
rts

View File

@@ -0,0 +1,73 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) order.h - Jul 26, 1983 REGULUS 4.1
*/
#ifdef MC68000
struct { char b1; char b2; char b3; char b4; };
struct { char wb1; char wb2; };
union WORDPTR {
long longwd;
struct {
int hiword;
int loword;
} WORDSTR;
};
union BYTEPTR {
short shortwd;
struct {
char hibyte;
char lobyte;
} BYTESTR;
};
#endif
#ifdef VAX11
struct { char b4; char b3; char b2; char b1; };
struct { char wb2; char wb1; };
union WORDPTR {
long longwd;
struct {
short loword;
short hiword;
} WORDSTR;
};
union BYTEPTR {
short shortwd;
struct {
char lobyte;
char hibyte;
} BYTESTR;
};
#endif
#ifdef PDP11
struct { char b2; char b1; char b4; char b3; };
struct { char wb2; char wb1; };
union WORDPTR {
long longwd;
struct {
int hiword;
int loword;
} WORDSTR;
};
union BYTEPTR {
int shortwd;
struct {
char lobyte;
char hibyte;
} BYTESTR;
};
#endif
#define ERROR -1
#define SUCCESS 0

View File

@@ -0,0 +1,260 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) printf.c - Sep 12, 1983 REGULUS 4.1
*/
# include "iodec.h"
# define BUFSIZ 80
/**
** formated print
**/
printf(parlist)
char *parlist;
{
register char *fmt, c;
char buf[BUFSIZ];
extern char *__prtshort(), *__prtld(), *__prtld();
int mode;
char *fd;
register char **p;
register int *pi;
int width, prec;
int left, longf;
char padchar;
char *s;
int n;
auto (*fn)();
int len;
p = &parlist;
fd = 0;
mode = 0; /* mode zero, putchar */
if (parlist + 1 < MAXFILES + 1) {
mode++; /* mode one, cputc */
fd = *p++;
}
if (fd == -1) {
mode++; /* mode two, string */
fd = *p++;
}
fmt = *p++;
pi = p;
while (c = *fmt++)
{
p = pi;
if (c != '%') {
__putch(mode, &fd, c);
continue;
}
left = 0;
if ((c = *fmt++) == '-') {
c = *fmt++;
left++;
}
padchar = ' ';
if (c == '0') {
padchar = c;
c = *fmt++;
}
width = -1;
while (c >= '0' && c <= '9')
{
if (width < 0)
width = 0;
width = width * 10 + (c - '0');
c = *fmt++;
}
prec = -1;
if (c == '.')
{
prec = 0;
c = *fmt++;
}
while (c >= '0' && c <= '9')
{
prec = prec * 10 + (c - '0');
c = *fmt++;
}
longf = 0;
if (c == 'l')
{
longf++;
c = *fmt++;
}
/* we now have all the prelims out of the way;
let's see what we want to print */
s = buf;
switch (c)
{
case 'd': /* decimal signed */
case 'D':
if (longf)
fn = __prtld;
else
fn = __prtshort;
__prtint(pi++, buf, 10, 1, fn, 0);
if (longf)
pi++;
break;
case 'u': /* decimal unsigned */
case 'U':
__prtint(pi++, buf, 10, 0, __prtshort, 0);
break;
case 'o': /* octal unsigned */
case 'O':
if (longf)
fn = __prtld;
else
fn = __prtshort;
__prtint(pi++, buf, 8, 0, fn, 0);
if (longf)
pi++;
break;
case 'x': /* hexadecimal unsigned */
case 'X':
if (longf)
fn = __prtld;
else
fn = __prtshort;
__prtint(pi++, buf, 16, 0, fn, c == 'X');
if (longf)
pi++;
break;
case 's': /* string */
case 'S':
s = *p++;
pi = p;
break;
case 'c': /* character */
case 'C':
n = *pi++;
buf[0] = n;
buf[1] = '\0';
break;
default: /* just print the character */
__putch(mode, &fd, c);
continue;
}
len = __length(s);
if (prec < len && prec >= 0)
len = prec;
n = width - len;
if (!left)
{
if (padchar != ' ' && *s == '-')
{
len--;
__putch(mode, &fd, *s++);
}
while (n-- > 0)
__putch(mode, &fd, padchar);
}
while (len--)
__putch(mode, &fd, *s++);
while (n-- > 0)
__putch(mode, &fd, padchar);
}
if (mode == 2)
*fd = '\0';
}
__putch(mode, pfd, c)
int mode;
char c;
char **pfd;
{
switch (mode)
{
case 0:
putchar(c);
break;
case 1:
cputc(c, *pfd);
break;
case 2:
*(*pfd)++ = c;
break;
}
return (c);
}
char *__prtld(pobj, pbuf, base, signed, digs)
long *pobj;
char **pbuf;
int base;
int signed;
char *digs;
{
register long n;
register long b;
register char *p;
struct {
char cbyte0;
char cbyte1;
char cbyte2;
char cbyte3;
};
register i;
struct {
int wd1;
int wd2;
};
p = digs;
b = base;
n = *pobj;
if(base == 16) { /* special because of negatives */
i = 8;
while(n && i) {
*p++ = n & 0xf;
n =>> 4;
i--;
}
}
else if(base == 8) {
i = 11;
while(n && i) {
*p++ = n & 7;
n =>> 3;
i--;
}
if(i==0) {
*(p-1) =& 3; /* only 2 bits in upper octal digit */
}
}
else {
if (signed && n < 0) {
*(*pbuf)++ = '-';
n = -n;
}
while(n) {
*p++ = n%b;
n /= b;
}
}
return (p);
}

View File

@@ -0,0 +1,71 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) __prtint.c - Sep 12, 1983 REGULUS 4.1
*/
char *
__prtint(pobj, buf, base, signed, f, upper)
int *pobj;
char *buf;
int base, signed, upper;
char *(*f)();
{
char digs[15];
register char *dp;
register int k;
register char *p;
dp = (*f)(pobj, &buf, base, signed, digs);
if (dp == digs)
*dp++ = 0;
p = buf;
while (dp != digs)
{
k = *--dp;
if (k < 10)
k =+ '0';
else
k =+ upper ? 'A'-10 : 'a'-10;
*p++ = k;
}
*p = 0;
return (p);
}
char *
__prtshort(pobj, pbuf, base, signed, digs)
int *pobj;
char **pbuf;
int base, signed;
char *digs;
{
register long n;
register char *p;
register long b;
p = digs;
b = base;
n = *pobj;
if (signed && n < 0)
{
n = -n;
*(*pbuf)++ = '-';
}
else
n =& 0xffffL; /* clear upper half */
while (n != 0)
{
*p++ = n%b;
n /= b;
}
return (p);
}

View File

@@ -0,0 +1,47 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) putarhd.c - Sep 12, 1983 REGULUS 4.1
*/
/*
I/O independent mapping routine. Machine specific. Independent
of structure padding. Buffer must contain at least as many
characters as is required for structure.
*/
#include "ar68.h"
#include "iobuf.h"
/*
* putarhd - fills the buffer from the archive header structure in
* the byte orientation of the target machine (68000).
*/
int
putarhd(fp,arptr) /* returns 0 for success, -1 for error */
FILE *fp;
struct libhdr *arptr;
{
register int i;
register char *p, *lp;
for (i=0, lp = arptr->lfname; i<LIBNSIZE; i++, lp++)
if (putc(*lp,fp) == -1)
return(-1);
if (lputl(&arptr->lmodti,fp) == -1)
return(-1);
if (putc(arptr->luserid,fp) == -1)
return(-1);
if (putc(arptr->lgid,fp) == -1)
return(-1);
if (lputw(&arptr->lfimode,fp) == -1)
return(-1);
if (lputl(&arptr->lfsize,fp) == -1)
return(-1);
return(0);
}

View File

@@ -0,0 +1,34 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) putc.c - Sep 12, 1983 REGULUS 4.1
*/
#define BSIZE 512
struct iob {
int fd; /* file descriptor */
int cc; /* char count */
char *cp; /* ptr to next char */
char cbuf[BSIZE]; /* char buffer */
};
putc(c,ibuf)
char c;
register struct iob *ibuf;
{
if (ibuf->cc <= 0) {
ibuf->cp = &(ibuf->cbuf[0]);
if (write(ibuf->fd,ibuf->cp,BSIZE) != BSIZE)
return(-1);
ibuf->cc = BSIZE;
}
*(ibuf->cp)++ = c;
ibuf->cc--;
return((int)(c&0xff));
}

View File

@@ -0,0 +1,54 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) putchar.c - Sep 12, 1983 REGULUS 4.1
*/
/* version 6 putchar library routine */
#define BSIZE 512
struct iob {
int fd; /* file descriptor */
int cc; /* char count */
char *cp; /* prt to next char */
char cbuf[BSIZE]; /* char buffer */
} fout = {0,BSIZE,&fout.cbuf[0]};
putchar(cc)
char cc;
{
if (fout.fd <= 1) {
if (write(1,&cc,1) != 1)
return(-1);
return(cc);
}
/* buffered output */
if (fout.cc <= 0) {
fout.cp = &(fout.cbuf[0]);
if (write(fout.fd,fout.cp,BSIZE) != BSIZE)
return(-1);
fout.cc = BSIZE;
}
*(fout.cp)++ = cc;
fout.cc--;
return(cc);
}
flush()
{
register i;
i = BSIZE - fout.cc;
fout.cc = BSIZE;
fout.cp = &(fout.cbuf[0]);
if (write(fout.fd,fout.cp,i) != i)
return(-1);
return(0);
}

View File

@@ -0,0 +1,53 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) putchd.c - Sep 12, 1983 REGULUS 4.1
*/
/*
I/O independent mapping routine. Machine specific. Independent
of structure padding. Buffer must contain at least as many
characters as is required for structure.
*/
#include "cout.h"
#include "iobuf.h"
/*
* putchd - fills the buffer from the c.out header structure in
* the byte orientation of the target machine (68000).
*/
int
putchd(fp,arptr) /* returns 0 for success, -1 for failure */
FILE *fp;
struct hdr *arptr;
{
if (lputw(&arptr->ch_magic,fp) == -1)
return(-1);
if (lputl(&arptr->ch_tsize,fp) == -1)
return(-1);
if (lputl(&arptr->ch_dsize,fp) == -1)
return(-1);
if (lputl(&arptr->ch_bsize,fp) == -1)
return(-1);
if (lputl(&arptr->ch_ssize,fp) == -1)
return(-1);
if (lputl(&arptr->ch_stksize,fp) == -1)
return(-1);
if (lputl(&arptr->ch_entry,fp) == -1)
return(-1);
if (lputw(&arptr->ch_rlbflg,fp) == -1)
return(-1);
if (arptr->ch_magic == EX_ABMAGIC) {
if (lputl(&arptr->ch_dstart,fp) == -1)
return(-1);
if (lputl(&arptr->ch_bstart,fp) == -1)
return(-1);
}
return(0);
}

View File

@@ -0,0 +1,2 @@
This directory includes routines and include files necessary for porting
the Alcyon compiler, assembler and loader to a non-regulus machine.

View File

@@ -0,0 +1,24 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) seek.c - Sep 12, 1983 REGULUS 4.1
*/
/* fake v6 seek system call */
seek(fd,offset,position)
int fd, offset, position;
{
register long loffset;
loffset = offset;
if (position >= 3) {
loffset *= 512;
position -= 3;
}
lseek(fd,loffset,position);
}

View File

@@ -0,0 +1,35 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) v6fflush.c - Sep 12, 1983 REGULUS 4.1
*/
/* v6 v6fflush library call */
#define BSIZE 512
struct iob {
int fd; /* file descriptor */
int cc; /* char count */
char *cp; /* ptr to next char */
char cbuf[BSIZE]; /* char buffer */
};
v6fflush(ibuf)
register struct iob *ibuf;
{
register i;
i = BSIZE - ibuf->cc;
ibuf->cc = BSIZE;
ibuf->cp = &(ibuf->cbuf[0]);
if (write(ibuf->fd,ibuf->cp,i) != i)
return(-1);
return(0);
}

View File

@@ -0,0 +1,51 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) getarhd.c - Sep 12, 1983 REGULUS 4.1
*/
/*
I/O independent mapping routine. Machine specific. Independent
of structure padding. Buffer must contain at least as many
characters as is required for structure.
*/
#include <stdio.h>
#ifndef MC68000
# include <c68/ar68.h>
#else
# include <ar68.h>
#endif
/*
* getarhd - fills the archive header structure from the buffer int
* the manner which will be understood on the current machine.
*/
int
getarhd(fp,arptr) /* returns -1 for failure, 0 for success */
FILE *fp;
struct libhdr *arptr;
{
register int i;
register char *p, *lp;
for (i = 0, lp = arptr->lfname; i < LIBNSIZE; i++)
if ((*lp++ = getc(fp)) == EOF)
return(-1);
if ((lgetl(&arptr->lmodti,fp)) == -1)
return(-1);
if ((arptr->luserid = getc(fp)) == EOF)
return(-1);
if ((arptr->lgid = getc(fp)) == EOF)
return(-1);
if ((lgetw(&arptr->lfimode,fp)) == -1)
return(-1);
if ((lgetl(&arptr->lfsize,fp)) == -1)
return(-1);
return(0);
}

View File

@@ -0,0 +1,57 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) getchd.c - Sep 12, 1983 REGULUS 4.1
*/
/*
I/O independent mapping routine. Machine specific. Independent
of structure padding. Buffer must contain at least as many
characters as is required for structure.
*/
#include <stdio.h>
#ifndef MC68000
# include <c68/cout.h>
#else
# include <cout.h>
#endif
/*
* getchd - fills the c.out header structure from the buffer in
* the manner which will be understood on the current machine.
*/
int
getchd(fp,arptr) /* returns 0 for success, -1 for failure */
FILE *fp;
struct hdr2 *arptr;
{
if (lgetw(&arptr->ch_magic,fp) == -1)
return(-1);
if (lgetl(&arptr->ch_tsize,fp) == -1)
return(-1);
if (lgetl(&arptr->ch_dsize,fp) == -1)
return(-1);
if (lgetl(&arptr->ch_bsize,fp) == -1)
return(-1);
if (lgetl(&arptr->ch_ssize,fp) == -1)
return(-1);
if (lgetl(&arptr->ch_stksize,fp) == -1)
return(-1);
if (lgetl(&arptr->ch_entry,fp) == -1)
return(-1);
if (lgetw(&arptr->ch_rlbflg,fp) == -1)
return(-1);
if (arptr->ch_magic == EX_ABMAGIC) {
if (lgetl(&arptr->ch_dstart,fp) == -1)
return(-1);
if (lgetl(&arptr->ch_bstart,fp) == -1)
return(-1);
}
return(0);
}

View File

@@ -0,0 +1,49 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) libget.c - Sep 12, 1983 REGULUS 4.1
*/
/*
I/O independent mapping routine. Machine specific. Independent
of structure padding. Buffer must contain at least as many
characters as is required for structure.
*/
#include "order.h"
#include <stdio.h>
#ifndef PDP11
# define dogetc(byte,i,fp) byte = (unsigned char)getc(fp)
#else
# define dogetc(byte,i,fp) byte = getc(fp)
#endif
lgetl(lp,f) /* returns -1 for failure, 0 for success */
long *lp; /* 32 bits */
FILE *f;
{
register int i;
dogetc(lp->b1,i,f);
dogetc(lp->b2,i,f);
dogetc(lp->b3,i,f);
dogetc(lp->b4,i,f);
return((ferror(f)) ? ERROR :SUCCESS);
}
lgetw(lp,f) /* returns -1 for failure, 0 for success */
short *lp; /* 16 bits */
FILE *f;
{
register int i;
dogetc(lp->wb1,i,f);
dogetc(lp->wb2,i,f);
*lp &= 0xffff;
return((ferror(f)) ? ERROR :SUCCESS);
}

View File

@@ -0,0 +1,41 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) libput.c - Sep 12, 1983 REGULUS 4.1
*/
/*
I/O independent mapping routine. Machine specific. Independent
of structure padding. Buffer must contain at least as many
characters as is required for structure.
*/
#include "order.h"
#include <stdio.h>
#define doputc(byte,fp) putc(byte,fp)
lputl(lp,f) /* returns 0 for success, -1 for failure */
long *lp; /* 32 bits */
FILE *f;
{
doputc(lp->b1,f);
doputc(lp->b2,f);
doputc(lp->b3,f);
doputc(lp->b4,f);
return((ferror(f)) ? ERROR : SUCCESS);
}
lputw(lp,f) /* returns 0 for success, -1 for failure */
short *lp; /* 16 bits */
FILE *f;
{
doputc(lp->wb1,f);
doputc(lp->wb2,f);
return((ferror(f)) ? ERROR : SUCCESS);
}

View File

@@ -0,0 +1,55 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
@(#) libread.c - Sep 12, 1983 REGULUS 4.1
*/
#include "order.h"
lreadl(fd,str)
int fd;
long *str;
{
register char *p;
char junk[4];
if (read(fd,junk,4) != 4)
return(ERROR);
p = junk;
str->b1 = *p++;
str->b2 = *p++;
str->b3 = *p++;
str->b4 = *p;
return(SUCCESS);
}
lreadw(fd,str)
int fd;
short *str;
{
register char *p;
char junk[2];
if (read(fd,junk,2) != 2)
return(ERROR);
p = junk;
str->wb1 = *p++;
str->wb2 = *p;
return(SUCCESS);
}
lreadc(fd,str)
int fd;
char *str;
{
char junk[1];
if (read(fd,&junk,1) != 1)
return(ERROR);
*str = junk[0];
return(SUCCESS);
}

View File

@@ -0,0 +1,54 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
@(#) libwrite.c - Sep 12, 1983 REGULUS 4.1
*/
#include "order.h"
lwritel(fd,str)
int fd;
long *str;
{
register char *p;
char junk[4];
p = junk;
*p++ = str->b1;
*p++ = str->b2;
*p++ = str->b3;
*p = str->b4;
if (write(fd,junk,4) == 4)
return(SUCCESS);
else
return(ERROR);
}
lwritew(fd,str)
int fd;
short *str;
{
register char *p;
char junk[2];
p = junk;
*p++ = str->wb1;
*p = str->wb2;
if (write(fd,junk,2) == 2)
return(SUCCESS);
else
return(ERROR);
}
lwritec(fd,str)
int fd;
char *str;
{
if (write(fd,str,1) != 1)
return(ERROR);
return(SUCCESS);
}

View File

@@ -0,0 +1,51 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) putarhd.c - Sep 12, 1983 REGULUS 4.1
*/
/*
I/O independent mapping routine. Machine specific. Independent
of structure padding. Buffer must contain at least as many
characters as is required for structure.
*/
#include <stdio.h>
#ifndef MC68000
# include <c68/ar68.h>
#else
# include <ar68.h>
#endif
/*
* putarhd - fills the buffer from the archive header structure in
* the byte orientation of the target machine (68000).
*/
int
putarhd(fp,arptr) /* returns 0 for success, -1 for error */
FILE *fp;
struct libhdr *arptr;
{
register int i;
register char *p, *lp;
for (i=0, lp = arptr->lfname; i<LIBNSIZE; i++, lp++)
if ((putc(*lp,fp)) == -1)
return(-1);
if (lputl(&arptr->lmodti,fp) == -1)
return(-1);
if ((putc(arptr->luserid,fp)) == -1)
return(-1);
if ((putc(arptr->lgid,fp)) == -1)
return(-1);
if (lputw(&arptr->lfimode,fp) == -1)
return(-1);
if (lputl(&arptr->lfsize,fp) == -1)
return(-1);
return(0);
}

View File

@@ -0,0 +1,57 @@
/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, CA 92121
@(#) putchd.c - Sep 12, 1983 REGULUS 4.1
*/
/*
I/O independent mapping routine. Machine specific. Independent
of structure padding. Buffer must contain at least as many
characters as is required for structure.
*/
#include <stdio.h>
#ifndef MC68000
# include <c68/cout.h>
#else
# include <cout.h>
#endif
/*
* putchd - fills the buffer from the c.out header structure in
* the byte orientation of the target machine (68000).
*/
int
putchd(fp,arptr) /* returns 0 for success, -1 for failure */
FILE *fp;
struct hdr2 *arptr;
{
if (lputw(&arptr->ch_magic,fp) == -1)
return(-1);
if (lputl(&arptr->ch_tsize,fp) == -1)
return(-1);
if (lputl(&arptr->ch_dsize,fp) == -1)
return(-1);
if (lputl(&arptr->ch_bsize,fp) == -1)
return(-1);
if (lputl(&arptr->ch_ssize,fp) == -1)
return(-1);
if (lputl(&arptr->ch_stksize,fp) == -1)
return(-1);
if (lputl(&arptr->ch_entry,fp) == -1)
return(-1);
if (lputw(&arptr->ch_rlbflg,fp) == -1)
return(-1);
if (arptr->ch_magic == EX_ABMAGIC) {
if (lputl(&arptr->ch_dstart,fp) == -1)
return(-1);
if (lputl(&arptr->ch_bstart,fp) == -1)
return(-1);
}
return(0);
}

View File

@@ -0,0 +1,7 @@
mkver -e "Preprocessor -"
c68 -L -r -DMC68000 -c cexpr.c
c68 -L -r -DMC68000 -c lex.c
c68 -L -r -DMC68000 -c macro.c
c68 -L -r -DMC68000 -c main.c
c68 -L -r -DMC68000 -n version.c cexpr.o lex.o macro.o main.o -o cpp68.4k -l6
setstack cpp68.4k 8000 8000

View File

@@ -0,0 +1,7 @@
mkver -e "Preprocessor -"
cc -w -DPDP11 -c cexpr.c
cc -w -DPDP11 -c lex.c
cc -w -DPDP11 -c macro.c
cc -w -DPDP11 -c main.c
cc -w -DPDP11 -c version.c
cc -n version.o cexpr.o lex.o macro.o main.o seek.o lseek.o -l6 -lC -o cpp68.pdp

View File

@@ -0,0 +1,7 @@
mkver -e "Preprocessor -"
cc -O -w -DVAX11 -c cexpr.c
cc -O -w -DVAX11 -c lex.c
cc -O -w -DVAX11 -c macro.c
cc -O -w -DVAX11 -c main.c
cc -O -w -DVAX11 -c version.c
cc -n version.o cexpr.o lex.o macro.o main.o ../binary/libV.a -o cpp68.vax

View File

@@ -0,0 +1,7 @@
mkver "preproc - ";
c68 -S -L -DMC68000 -DVERSADOS cexpr.c
c68 -S -L -DMC68000 -DVERSADOS lex.c
c68 -S -L -DMC68000 -DVERSADOS macro.c
c68 -S -L -DMC68000 -DVERSADOS main.c
c68 -S -L -DMC68000 -DVERSADOS version.c
mv *.s vst

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((struct symbol *)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 op1, op2, pri;
for( pri = opinfo[opr]&OPPRI; pri < *priptr; ) {
if( *oprptr == LPAREN ) {
if( opr == RPAREN ) {
oprptr--;
priptr--;
return(1);
}
break;
}
op1 = *opnptr;
if( 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,35 @@
argument buffer overflow
bad -o option
bad argument: (name)
bad character
bad define name: (name)
bad include file (filename)
bad include file name (filename)
can't creat file (filename)
can't open include file: (filename)
can't open source file (filename)
condition stack overflow
define recursion
define table overflow
expression operator stack overflow
expression stack overflow
expression syntax
includes nested too deeply
incompatible flags : '-f' and '-e'
invalid #else
invalid #endif
invalid #line args
invalid preprocessor command
line overflow
macro argument too long
no */ before EOF
string cannot cross line
string too long
symbol table overflow
too many args
too many arguments
too many characters pushed back
too many files
too many loader args
unexpected EOF
unmatched conditional

View File

@@ -0,0 +1,411 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "preproc.h"
int Eflag;
int status;
extern 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 - 2 )); /* [vlh] 4.1 added -2 */
}
/* 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';
*q = '\0'; /* [vlh] 4.1, force null terminator */
}
/* 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 (literal)
printf((char *)STDERR,"%s, # line %d: ",lit_file, lit_num);
else if (filep == &filestack[0]) /* [vlh] 3.4 not in include */
printf((char *)STDERR,"%s, # line %d: ",source, lineno);
else
printf((char *)STDERR,"%s, # line %d: ",(filep-1)->ifile,(filep-1)->lineno);
printf((char *)STDERR,s,x1,x2,x3,x4,x5,x6);
cputc('\n',STDERR);
status++;
}
/* 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.cc = filep->tcc;
inbuf.cp = filep->tcp;
p = &inbuf.cbuf[0];
q = &filep->tbuf[0];
for(i = 0; i<BSIZE; i++)
*p++ = *q++;
#else
inbuf.cc = 0;
inbuf.cp = &inbuf.cbuf[0];
#endif
inbuf.fd = filep->ifd;
if( filep == &filestack[0] ) { /*need line for #include...*/
lineno++;
putid(source,lineno); /* [vlh] 4.2 id line .... */
}
else {
(filep-1)->lineno++;
putid((filep-1)->ifile,(filep-1)->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((char *)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, *s;
register int type, 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('*') ) {
if (Cflag) {
putl((int)'/');
putl((int)'*');
}
l = lineno;
while( (c=ngetch()) != EOF )
if( c == '\n' ) {
if( filep == &filestack[0] && pbp == &pbbuf[0] )
lineno++;
if (Cflag) { /* [vlh] 4.2 */
putl((int)'\0');
s = line;
while (*s)
doputc(*s++,&outbuf);
initl();
}
doputc(' ',&outbuf);
doputc('\n',&outbuf);
}
else if( c == '*' && peekis('/') ) {
if (Cflag) { /* [vlh] 4.2 */
putl((int)'*');
putl((int)'/');
}
break;
}
else if (Cflag) /* [vlh] 4.2.c */
putl((int)c);
if( c == EOF ) {
lineno = l;
error("no */ before EOF");
}
type = WHITE;
token[0] = ' ';
}
else if( peekis('/') ) {
if (Cflag) {
putl((int)'/');
putl((int)'/');
}
while( (c=ngetch()) != EOF && c != '\n' )
if (Cflag)
putl(c);
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, c;
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 iob *buffer;
{
if (!Eflag)
putc(ch,buffer);
else
putchar(ch);
}
#ifdef VAX11
getc(ibuf)
struct iob *ibuf;
{
if (ibuf->cc <= 0) {
ibuf->cp = &(ibuf->cbuf[0]);
ibuf->cc = read(ibuf->fd,ibuf->cp,BSIZE);
}
if (ibuf->cc <= 0)
return(-1);
ibuf->cc--;
return((int)(*(ibuf->cp)++)&0xff);
}
fopen(fname,ibuf)
char *fname;
register struct iob *ibuf;
{
ibuf->cc = 0; /* no chars */
ibuf->fd = open(fname,0);
return(ibuf->fd);
}
#endif

View File

@@ -0,0 +1,216 @@
.he "C68 Preprocessor"Change Log"Page %"
.de bg
.sp
.in +5
..
.de eg
.sp
.in -5
..
1. 4/20/82 - Long string bug
.bg
No error message for long string, caused in getstr checking for
"i-- > 0" then "i == 0". Also increased TOKSIZE to 300 to match
setting in parser.
.eg
2. 4/21/82 - Invalid characters not invalid
.bg
It was assumed that the only characters that would go thru the
preprocessor were those that were valid for the compiler. Using
preprocessor with the assembler (i.e. #define x $1) does not
work. Fixed cmap table.
.eg
3. 4/26/82 - Assembler temps not being deleted
.bg
Main not deleting assembler temps if more than one C file specified.
Added unlink to delete assembler temps.
.eg
4. 4/28/82 - Preprocessor enhancements
.bg
Changed '-D' flag to '-N' flag, Added '-D' flag to define a name.
Added built-in macros Newlabel[(num)] and Label[(num)] to
generate label numbers for assembler.
.eg
5. 5/8/82 - Added handling of ".s" files
.bg
Added code to check for ".s" files, which go thru the preprocessor
and then thru the assembler.
.eg
6. 5/8/82 - Suppress '\01' on macro file for -P flag
.bg
Added check in domacro to check for pflag, and if it is on, suppress
the outputting of '\01' to expanded macro file.
.eg
7. 5/20/82 - defines gobbling up parenthesised expressions
.bg
the syntax: #define x 1 (newline) x(1) resulted in only "1". This was
because expand always checked for a left parenthesis for any macro name.
Added NOARG flag at beginning of macro or argument count in dodefine
(although this is not used). The arguments are only collected if there
were args (or left parenthesis-right parenthesis) seen on the macro
definition.
.eg
8. 6/7/82 - multiple assembler files leaving temps
.bg
If more than one assembler file was given, the macro temp file was left.
Fixed problem in main.
.eg
9. 7/8/82 - added one pass logic
.bg
Added logic in main to add the "-1" flag, which runs the one pass
parser and code generator, which is 10% faster.
.eg
10. 7/17/82 - "-o" flag wiped out C file
.bg
The command "c68 -o x.c" would wipe out x.c.
Added code to main to check argument given for -o flag, made output file
the file name stripped of the ".c" or ".s".
.eg
11. 7/28/82 - checked for rubouts ignored
.bg
C68 was unconditionally catching rubouts whether its rubout signals were
ignored or not.
This had the (unfortunate) side effect of killing C68 in background
when you did a rubout from the terminal.
Added check to signal call to check if signal was ignored, and if so
the ignore condition was restored.
.eg
12. 8/26/82 - libraries not being handled properly
.bg
The -lX flag would be placed at the beginning of the loader's argument
list, thereby missing the library.
Changed main so that the loader arguments would be passed in the same
order as the c68 command line and the c068.o would be added before the
first .o file specified.
Also checked for: -o x.o and stripped off .o for output file name.
.eg
13. 9/1/82 - changed misleading "can't fork" message
.bg
Changed message in fexec so that "can't fork" message is now
"can't maketask [filename]".
This is to keep John Happy...
.eg
14. 11/15/82 - Multiple compiles define carry overs
.bg
The symbol table was not being cleared of defines which occured in
previous source files in a multi-source compile.
.eg
15. 11/15/82 - Paths of generated files
.bg
All files are now generated in the users current working directory
instead of the source directory by default.
.eg
16. 11/24/82 - Include file search paths
.bg
Added the -Idir flag to enable the user to alter the search path.
Also added searching of the parent directory of include files
specified using quotes.
.eg
17. 12/2/82 - Include file error messages
.bg
Added the include file name and line number to the preprocessor output
in order to generate error messages which specified the exact location
of errors which involve include files. Also suppressed output of
empty include file lines to the preprocessor temporary output file.
.eg
18. 12/28/82 - Temp files generated in the current directory
.bg
In generating all other files into the current directory the temp files
also were generated there.
.eg
18. 1/7/83 - Floating Point flags
.bg
Added the -e and -f flags for specification of the IEEE or FFP floating
point packages (constant evaluations and libraries).
.eg
19. 1/17/83 - Optimization flag
.bg
Recognize the -O optimization flag and ignore it.
.eg
20. 1/20/83 - Compatibility flags
.bg
Added the -3, -5, -6, -7 flags for system 3, system 5, version 6 and
version 7. Adds an include file on the search list, as well as a
default library.
.eg
21. 1/24/83 - include file error messages
.bg
Added explicit line number and file name's within the error messages if
processing an include file.
.eg
22. 1/24/83 - Symbol Table overflow
.bg
Added clearing of the symbol table between compiles (c68 *.c).
.eg
23. 2/7/83 - Preprocessor error status
.bg
If error's occurred in the preprocessor pass the exit status wasn't
reflecting it.
.eg
24. 2/22/83 - #line macro
.bg
Implemented the "#line LINENUM [FILENAME]" macro.
.eg
25. 2/23/83 - "-E" option flag
.bg
Implemented the "-E" flag, only the preprocessor is executed and the
output is written to the standard output device.
.eg
26. 3/3/83 - bus error on non-existent file error message
.bg
Error required certain variables to have been initialized in order to
generate the filename and the line number on which the error occured.
.eg
27. 3/28/83 - added two predefined macro's __FILE && __LINE
.bg
Added the two macro's __LINE and __FILE which are respectively
interpreted as the current line number and the current file name.
They may be redefined if desired as this test takes place after
the user defined macro expansions.
.eg
28. 3/29/83 - embedded macro arguments
.bg
Arguments from #define macro's which are not individual tokens but which
are embedded in quoted or non-quoted strings are now being expanded.
.eg
29. 3/29/83 - white space in macro call [vlh] 4.1
.bg
Allows tabs and spaces between a macro call identifier and the left
parenthesis associated with it's argument list.
.eg
30. 4/29/83 - embedded macro arguments [vlh] 4.1
.bg
An underscore '_' is no longer seen as a legitimate symbol separator.
Macro's which are embedded in strings are now expanded properly.
.eg
31. 6/13/83 - split preprocessor from main driver [vlh] 4.2
.bg
For more flexibility...
.eg
32. 7/6/83 - #line [vlh] 4.2
.bg
A blank line was not being added to the file for each line which was being
redirected or for the #line macro, and so for each case the line number
would be off by two from the original file and error's reported would
have the wrong line number associated with them.
Reworked the way #line was being handled. Now works properly if the line
referenced has a macro on it. Does not lose lines.
.eg
33. 7/15/83 - '-C' option [vlh] 4.2
.bg
Added the '-C' option to the preprocessor. This caused a major rewrite of
the way include files and the #line option were handled. The preprocessor
now outputs lines of the form: # 45 "file.h" for each include file, plus
one at the top of each source file, and one after each return from an include
file. The '-C' flag causes comments to be left in the output.
.eg
34. 7/18/83 - arguments [vlh] 4.2
.bg
The arguments are now handled as "cpp -[args] source". The destination
file is no longer required, the results are always written on the '.i'
name of the source.
.eg
35. 7/20/83 - -I option [vlh] 4.2
.bg
The concluding slash is no longer required.
.eg

View File

@@ -0,0 +1,845 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "preproc.h"
#include <ctype.h>
#ifndef VAX11
char *stdincl = "/usr/include"; /*standard include directory*/
#else
/* 11 apr 83, for vax */
char *stdincl = "/usr/include/c68"; /*standard include directory*/
#endif
int clabel = LABSTART;
int nlabel = LABSTART+1;
char null[] = "";
int nincl;
char *incl[10];
char tmp[NUMLEN]; /* temporary spot for line number itoa conversion */
char ctype[];
char lit_file[MAXPSIZE];
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(nd)
int nd; /* number of defines*/
{
register char *l;
register struct symbol *sp;
register int x;
filep = &filestack[0]; /* [vlh] 4.0 moved for error msgs */
lineno = 1; /* [vlh] 4.0 moved for error msgs */
if( fopen(source,&inbuf,0) < 0 ) { /* 3rd arg for versados */
error("can't open source file %s\n",source);
return(0);
}
if (!Eflag)
if( fcreat(dest,&outbuf,0) < 0 ) { /* 3rd arg for versados */
error("can't creat %s\n",dest);
return(0);
}
putid(source,1); /* identify as first line in source file */
for (sp= &symtab[0]; sp<= &symtab[HSIZE-1]; sp++) /*3.4*/
sp->s_def = null; /* clear out symbol table */
defp = defap = sbrk(DEFSIZE);
if (defp == (char *)-1) {
error("define table overflow");
cexit();
}
defmax = defcount = DEFSIZE;
defused = 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(source) ) {
l = line;
if( filep == &filestack[0] && pbp == &pbbuf[0] )
lineno++;
else if (filep != &filestack[0]) /*[vlh] include file*/
(filep-1)->lineno++;
while( *l )
doputc(*l++,&outbuf);
doputc(' ',&outbuf);
doputc('\n',&outbuf);
if (literal) {
if (filep != &filestack[0]) {
(filep-1)->lineno++;
putid((filep-1)->ifile,(filep-1)->lineno);
}
else {
lineno++;
putid(source,lineno);
}
literal = 0;
}
}
if( cstkptr != &cstack[0] )
error("unmatched conditional");
if( defused > defmax )
defmax = defused;
v6flush(&outbuf);
if (!Eflag)
close(outbuf.fd);
close(inbuf.fd);
return(1);
}
putid(fname,lnum) /* [vlh] 4.0 SOH line header */
char *fname;
int lnum;
{
register char *p;
if (asflag || pflag)
return;
if (literal) {
strcpy(lit_file,fname);
lit_num = lnum;
}
doputc('#',&outbuf);
doputc(' ',&outbuf);
itoa(lnum,tmp,NUMLEN-1);
for (p = tmp; *p==' '; )
p++;
for ( ; *p; p++)
doputc(*p,&outbuf);
doputc(' ',&outbuf);
doputc('"',&outbuf);
for (p = fname; *p; p++)
doputc(*p,&outbuf);
doputc('"',&outbuf);
doputc('\n',&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);
if (filep != &filestack[0])
i = getline((filep-1)->ifile);
else
i = getline(infile);
return(i);
}
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();
return(getline(infile));
break;
default:
error("invalid preprocessor command");
break;
}
eatup();
}
else
if( type != NEWL ) {
if( skip )
eatup();
else {
for( ; type!=NEWL && type!=EOF ; type=gettok(token) )
if(type == ALPHA && (p=lookup(token)))
expand((struct symbol *)p);
else if (!special(token,infile)) /* [vlh] 4.1 */
for (p=token; *p; )
putl((int)(*p++));
}
}
putl((int)('\0'));
return(1);
}
/* special - check for predefined macros, if they exist expand them */
/* __FILE - current file name, __LINE - current line number */
special(token,infile) /* [vlh] 4.1 */
char *token, *infile;
{
register char *p;
int xline;
char buf[8];
if (strcmp(token,"__FILE") == 0) {
putl((int)('"'));
for (p = infile; *p; )
putl((int)(*p++));
putl((int)('"'));
}
else
if (strcmp(token,"__LINE") == 0) {
xline = (literal) ? lit_num : (filep == &filestack[0]) ? lineno
: (filep-1)->lineno;
itoa(xline,buf,7);
buf[7] = 0;
for (p = &buf[0]; *p == ' '; )
p++;
while (*p)
putl((int)(*p++));
}
else
return(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) == (char *)-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 || type==SQUOTE || type==DQUOTE) { /* [vlh] 4.1 */
trymatch(token,type,nargs,args); /* [vlh] 4.1 */
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');
}
/* trymatch - check for arguments */
trymatch(token,type,nargs,args) /* [vlh] 4.1 */
char *token;
int type, nargs;
char *args[];
{
register char *p;
register int i, len;
p = token;
if (type != ALPHA)
putd(*p++);
while (*p != 0) {
for(i = 0; i < nargs; i++)
if ((len = pattern(args[i],p)) != 0)
break;
if (i < nargs) { /* sub ARG marker for formal arg */
putd(i+1);
putd(ARG);
p += len;
}
else
do {
putd(*p++);
} while (isalnum(*p) || *p == '_');
while (!(isalnum(*p)) && *p != '_' && *p) /* get to next possible */
putd(*p++);
}
}
/* pattern - if the pattern occurs in the token starting at the first */
/* position in the string, pattern returns the length of the pattern */
/* else pattern returns a zero. */
pattern(pat,token) /* [vlh] 4.1 */
char *pat, *token;
{
register int len;
len = strlen(pat);
if (len > strlen(token)) /* couldn't possibly work */
return(0);
if (isalnum(token[len]) || token[len]=='_')
return(0); /* not deliminated by non-alphanumeric */
for (len = 0; *pat; ) {
if( *pat++ != *token++ )
return(0);
len++;
}
return( len );
}
/* 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((int)(*mdef++));
return;
}
nargs = 0;
if( *mdef == NOARGS ) /*suppress grabbing of args*/
;
else if( getntok(token) != LPAREN ) /* [vlh] 4.1 ignore white space */
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, i;
char token[TOKSIZE], fname[TOKSIZE];
register char *p, *q, c, *ptr1, *ptr2;
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,(char *)0L);
}
eatup(); /*need here...*/
if( filep >= &filestack[FSTACK] )
error("includes nested too deeply");
else {
fd = inbuf.fd;
#ifdef NONEST
filep->tcc = inbuf.cc;
filep->tcp = inbuf.cp;
ptr1 = &filep->tbuf[0];
ptr2 = &inbuf.cbuf[0];
for(i=0; i<BSIZE; i++)
*ptr1++ = *ptr2++;
#else
seek(fd,-inbuf.cc,1); /*back up file ptr*/
#endif
inbuf.cc = 0;
if( fopen(p,&inbuf,0) < 0 ) { /* 3rd arg for versados */
if (type != SQUOTE && type != DQUOTE)
error("can't open include file %s",p);
else
error("can't open include file %s",fname);
#ifdef NONEST
inbuf.cc = filep->tcc;
#endif
}
else {
filep->ifd = fd;
filep->lineno = 1; /* [vlh] */
putid(p,1); /* id for include file */
doifile(p);
filep++;
}
}
}
doifile(p) /* [vlh] */
char *p;
{
register char *iptr;
register int ndx;
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;
for (i=0; i<nincl; i++) {
for(t=inclname, q=incl[i]; *t++ = *q++; )
;
*(t-1) = FILESEP;
for(q=fname; *t++ = *q++; ) ;
*t = 0;
if ((fd = open(inclname,0)) >= 0) {
close(fd);
return(&inclname[0]);
}
}
if (parent) { /* include filename surrounded by quotes */
q = (filep == &filestack[0]) ? parent : (filep-1)->ifile;
t = &inclname[0];
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[0]);
}
}
for(t=inclname, q=stdincl; *t++ = *q++; )
;
*(t-1) = FILESEP;
for(q=fname; *t++ = *q++; ) ;
*t = 0;
return(&inclname[0]);
}
#define SKIPWHITE(ch) do { ch = ngetch(); } while (ctype[ch] == WHITE)
doline() /* [vlh] 4.0 : returns - none */
{
register char *ptr;
char token[TOKSIZE];
register int ch, lnum, type;
/* get line number associated with #LINE */
while ((type = gettok(token)) == WHITE); /* skip white space */
if (type != DIGIT) {
error("invalid #line args");
return;
}
lnum = atoi(token);
literal = 1;
SKIPWHITE(ch);
if (ctype[ch] != NEWL && ctype[ch] != EOF) { /* associated filename */
ptr = &token[0];
do {
*ptr++ = ch;
ch = ngetch();
} while (ctype[ch]!=NEWL && ctype[ch]!=EOF && ctype[ch]!=WHITE);
*ptr = 0;
putid(token,lnum);
}
else /* source or header file */
if (filep == &filestack[0])
putid(source,lnum); /* [vlh] 4.2.c */
else
putid((filep-1)->ifile,lnum); /* [vlh] 4.2.c */
if (ch != NEWL)
for( ; ctype[ch]!=NEWL && ctype[ch]!=EOF; )
ch = ngetch();
}
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,280 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char *version = "@(#)cpp68 preprocessor 4.2 - Sep 6, 1983";
#include "preproc.h"
#define NARGS 64
#define FLAGS "[-C] [-P] [-E] [-D] [-I] [-6] [-7] [-3]"
#define USAGE "usage: %s %s source [dest]\n"
#ifndef VAX11
char *v6incl = "/usr/include/v6"; /* [vlh] 3.4 */
char *v7incl = "/usr/include/v7"; /* [vlh] 3.4 */
char *s3incl = "/usr/include/sys3"; /* [vlh] 3.4 */
char *s5incl = "/usr/include/sys5"; /* [vlh] 3.4 */
#else
char *v6incl = "/usr/include/c68/v6"; /* [vlh] 3.4 */
char *v7incl = "/usr/include/c68/v7"; /* [vlh] 3.4 */
char *s3incl = "/usr/include/c68/sys3"; /* [vlh] 3.4 */
char *s5incl = "/usr/include/c68/sys5"; /* [vlh] 3.4 */
#endif
char *incl[NINCL];
int ndefs, nincl;
int status = 0;
extern int errno;
/*
* 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;
register char **argv;
{
register char *arg, *calledby;
register int c, i, j, x;
calledby = *argv++;
if (argc < 2) { /* cpp source */
printf(USAGE,calledby,FLAGS);
exit(-1);
}
for( ; --argc > 0 && **argv == '-'; ) { /*process arguments*/
*(arg = *argv++);
arg++;
for( i = 0; c = *arg++; ) {
switch( c ) {
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 'C': /* [vlh] 4.2 Leave comments in... */
Cflag++;
case 'E': /* [vlh] 4.0 Preprocessor to stdout */
Eflag++;
continue;
case 'P': /* preprocessor pass only */
pflag++;
continue;
case '6': /* [vlh] 3.4 v6 compatibility */
incl[nincl++] = v6incl;
continue;
case '7': /* [vlh] 3.4 v7 compatibility */
incl[nincl++] = v7incl;
continue;
case '3': /* [vlh] 3.4 s3 compatibility */
incl[nincl++] = s3incl;
continue;
case '5': /* [vlh] 3.4 s5 compatiblity */
incl[nincl++] = s5incl;
continue;
default:
printf(USAGE,calledby,FLAGS);
exit(-1);
} /* end of case statement */
if (i)
break;
} /* end of for statement */
} /* end of for statement */
if (argc > 2) { /* source [dest] */
printf(USAGE,calledby,FLAGS);
exit(-1);
}
source = *argv++;
if ( !Eflag )
if (argc==2) /* destination file specified */
strcpy(dest,*argv);
else
make_intermediate();
asflag = (source[strlen(source)-1] == 's');
domacro(ndefs);
cexit();
}
/* cexit - exit from C compiler driver*/
/* This deletes any existing temps and exits with the error status.*/
cexit() /* returns - none*/
{
exit(status);
}
/**
* 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[0];
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';
}
/* 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);
}
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 );
}
make_intermediate() /* returns pointer to string*/
{ /* if source t.c dest <= t.i */
register char *d, *s;
register int ndx;
s = source;
while ((ndx = index(s,'/')) != -1)
s += ndx+1; /* [vlh] */
for( d = dest; *d++ = *s++; ) ;
*(d-2) = 'i'; /* overwrite termination character */
}
/* cputc - put a character to a file descriptor (used by error) */
cputc(c, fn)
char c;
int fn;
{
#ifdef VERSADOS
versaputchar(c);
#else
if (fn == STDERR)
write(STDERR, &c, 1);
else
putchar(c);
#endif
}
v6flush(v6buf)
struct iob *v6buf;
{
register i;
i = BSIZE - v6buf->cc;
v6buf->cc = BSIZE;
v6buf->cp = &(v6buf->cbuf[0]);
if(write(v6buf->fd,v6buf->cp,i) != i)
return(-1);
return(0);
}
#ifdef VERSADOS
#define BSIZE 512
struct iob versfout { 1, BSIZE, &versfout.cbuf[0]};
versaputchar(c)
char c;
{
if (c == '\n') { /* end of line */
if (versaflush()) /* write one line */
return(-1);
return(c);
}
/* buffered output */
if (versfout.cc <= 0) {
versfout.cp = &(versfout.cbuf[0]);
if (write(versfout.fd,versfout.cp,BSIZE) != BSIZE)
return(-1);
versfout.cc = BSIZE;
}
*(versfout.cp)++ = c;
versfout.cc--;
return(c);
}
versaflush()
{
register short size, fildes;
if ((size = (BSIZE - versfout.cc)) == 0)
return(0);
versfout.cc = BSIZE;
versfout.cp = &(versfout.cbuf[0]);
fildes = (versfout.fd <= STDERR) ? 6 : versfout.fd;
if (write(fildes,versfout.cp,size) < 0)
return(-1);
return(0);
}
#endif

View File

@@ -0,0 +1,61 @@
CC = cc
C68 = nc68
VAXOBJS = vaxobj/cexpr.o \
vaxobj/lex.o \
vaxobj/macro.o \
vaxobj/main.o
C68OBJS = 68obj/cexpr.o \
68obj/lex.o \
68obj/macro.o \
68obj/main.o
CFLAGS = -O -DVAX11
C68FLAGS = -L -r -DMC68000 -t0 -t1
LIB = -lV6
C68LIB = -l6
vax: ${VAXOBJS}
mkver -e "Preprocessor -"
${CC} ${CFLAGS} -n version.c ${VAXOBJS} -o cpp68.vax ${LIB}
cpp: ${C68OBJS}
mkver -e "Preprocessor -"
${C68} ${C68FLAGS} version.c ${C68OBJS} -o cpp68.68 ${C68LIB}
setstack cpp68.68 8000 8000
2k: ${C68OBJS}
mkver -e "Preprocessor -"
${C68} ${C68FLAGS} -n2 version.c ${C68OBJS} -o cpp68.2k ${C68LIB}
setstack cpp68.2k 8000 8000
4k: ${C68OBJS}
mkver -e "Preprocessor -"
${C68} ${C68FLAGS} -n version.c ${C68OBJS} -o cpp68.4k ${C68LIB}
setstack cpp68.4k 8000 8000
all: vax 4k
vaxobj/cexpr.o: cexpr.c
${CC} ${CFLAGS} -c cexpr.c;mv -f cexpr.o vaxobj/cexpr.o
vaxobj/lex.o: lex.c
${CC} ${CFLAGS} -c lex.c;mv -f lex.o vaxobj/lex.o
vaxobj/macro.o: macro.c
${CC} ${CFLAGS} -c macro.c;mv -f macro.o vaxobj/macro.o
vaxobj/main.o: main.c
${CC} ${CFLAGS} -c main.c;mv -f main.o vaxobj/main.o
68obj/cexpr.o: cexpr.c
${C68} ${C68FLAGS} -c cexpr.c;mv -f cexpr.o 68obj/cexpr.o
68obj/lex.o: lex.c
${C68} ${C68FLAGS} -c lex.c;mv -f lex.o 68obj/lex.o
68obj/macro.o: macro.c
${C68} ${C68FLAGS} -c macro.c;mv -f macro.o 68obj/macro.o
68obj/main.o: main.c
${C68} ${C68FLAGS} -c main.c;mv -f main.o 68obj/main.o

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