mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 08:54:17 +00:00
Upload
Digital Research
This commit is contained in:
427
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/as68.h
Normal file
427
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/as68.h
Normal 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();
|
||||
|
||||
235
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/as68init
Normal file
235
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/as68init
Normal 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
|
||||
10
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/build.m68
Normal file
10
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/build.m68
Normal 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
|
||||
10
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/build.pdp
Normal file
10
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/build.pdp
Normal 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
|
||||
10
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/build.vax
Normal file
10
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/build.vax
Normal 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
|
||||
152
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/def.h
Normal file
152
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/def.h
Normal 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*/
|
||||
|
||||
939
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/dir.c
Normal file
939
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/dir.c
Normal 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 = ®msk; 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 );
|
||||
}
|
||||
511
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/expr.c
Normal file
511
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/expr.c
Normal 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;
|
||||
}
|
||||
170
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/log
Normal file
170
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/log
Normal 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
|
||||
59
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/mach.h
Normal file
59
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/mach.h
Normal 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
|
||||
801
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/main.c
Normal file
801
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/main.c
Normal 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);
|
||||
}
|
||||
|
||||
79
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/makefile
Normal file
79
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/makefile
Normal 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
|
||||
|
||||
1001
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/misc.c
Normal file
1001
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/misc.c
Normal file
File diff suppressed because it is too large
Load Diff
22
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/order.h
Normal file
22
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/order.h
Normal 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
|
||||
|
||||
62
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/p2def.h
Normal file
62
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/p2def.h
Normal 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*/
|
||||
105
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/pass1a.c
Normal file
105
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/pass1a.c
Normal 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*/
|
||||
}
|
||||
}
|
||||
}
|
||||
847
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/pass2.c
Normal file
847
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/pass2.c
Normal 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);
|
||||
}
|
||||
}
|
||||
10
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/readme
Normal file
10
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/readme
Normal 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
|
||||
822
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/symt.c
Normal file
822
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/as/symt.c
Normal 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';
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
char *compiled = "@(#) assembler - Thu Sep 8 15:50 1983";
|
||||
@@ -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
|
||||
@@ -0,0 +1,2 @@
|
||||
mkver -e "c68 Main Driver -"
|
||||
cc -DPDP11 -n maketask.c version.c main.c -l6 -o c68.pdp
|
||||
@@ -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
|
||||
32
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cc/log
Normal file
32
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cc/log
Normal 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
|
||||
659
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cc/main.c
Normal file
659
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cc/main.c
Normal 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);
|
||||
}
|
||||
|
||||
25
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cc/makefile
Normal file
25
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cc/makefile
Normal 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
|
||||
@@ -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);
|
||||
}
|
||||
121
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cc/mdriver.h
Normal file
121
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cc/mdriver.h
Normal 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())();
|
||||
@@ -0,0 +1 @@
|
||||
char *compiled = "@(#) c68 Main Driver - Tue Sep 6 14:37 1983";
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
1008
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/canon.c
Normal file
1008
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/canon.c
Normal file
File diff suppressed because it is too large
Load Diff
229
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/cgen.h
Normal file
229
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/cgen.h
Normal 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();
|
||||
|
||||
841
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/codegen.c
Normal file
841
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/codegen.c
Normal 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));
|
||||
}
|
||||
93
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/cskel.h
Normal file
93
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/cskel.h
Normal 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;
|
||||
};
|
||||
1486
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/cskels.c
Normal file
1486
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/cskels.c
Normal file
File diff suppressed because it is too large
Load Diff
18
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/errors
Normal file
18
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/errors
Normal 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]
|
||||
142
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/interf.c
Normal file
142
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/interf.c
Normal 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);
|
||||
}
|
||||
372
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/log
Normal file
372
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/log
Normal 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
|
||||
623
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/main.c
Normal file
623
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/main.c
Normal 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
|
||||
|
||||
116
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/makefile
Normal file
116
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/makefile
Normal 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
|
||||
@@ -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
|
||||
16
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/mout
Normal file
16
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/mout
Normal 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
|
||||
>
|
||||
323
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/optab.c
Normal file
323
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/optab.c
Normal 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*/
|
||||
};
|
||||
252
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/putexpr.c
Normal file
252
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/putexpr.c
Normal 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
|
||||
535
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/smatch.c
Normal file
535
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/smatch.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
110
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/sucomp.c
Normal file
110
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/sucomp.c
Normal 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);
|
||||
}
|
||||
118
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/tabl.c
Normal file
118
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/tabl.c
Normal 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 ()*/
|
||||
};
|
||||
389
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/util.c
Normal file
389
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/util.c
Normal 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);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
char *compiled = "@(#) Code Generator - Tue Sep 6 14:30 1983";
|
||||
BIN
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/version.o
Normal file
BIN
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cgen/version.o
Normal file
Binary file not shown.
26
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/ar68.h
Normal file
26
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/ar68.h
Normal 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;
|
||||
};
|
||||
|
||||
97
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/cout.h
Normal file
97
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/cout.h
Normal 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)
|
||||
|
||||
27
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/cputc.c
Normal file
27
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/cputc.c
Normal 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);
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
34
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/getc.c
Normal file
34
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/getc.c
Normal 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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
19
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/iobuf.h
Normal file
19
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/iobuf.h
Normal 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
|
||||
34
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/iodec.h
Normal file
34
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/iodec.h
Normal 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];
|
||||
84
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/ldiv.s
Normal file
84
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/ldiv.s
Normal 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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
74
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/lmul.s
Normal file
74
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/lmul.s
Normal 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
|
||||
19
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/lrem.s
Normal file
19
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/lrem.s
Normal 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
|
||||
73
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/order.h
Normal file
73
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/order.h
Normal 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
|
||||
260
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/printf.c
Normal file
260
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/printf.c
Normal 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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
34
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/putc.c
Normal file
34
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/putc.c
Normal 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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
24
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/seek.c
Normal file
24
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/clib/seek.c
Normal 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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
340
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cpp/cexpr.c
Normal file
340
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cpp/cexpr.c
Normal 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);
|
||||
}
|
||||
35
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cpp/errors
Normal file
35
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cpp/errors
Normal 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
|
||||
411
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cpp/lex.c
Normal file
411
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cpp/lex.c
Normal 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
|
||||
|
||||
216
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cpp/log
Normal file
216
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cpp/log
Normal 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
|
||||
845
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cpp/macro.c
Normal file
845
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cpp/macro.c
Normal 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 );
|
||||
}
|
||||
|
||||
280
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cpp/main.c
Normal file
280
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cpp/main.c
Normal 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
|
||||
61
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cpp/makefile
Normal file
61
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v103/cpp/makefile
Normal 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
Reference in New Issue
Block a user