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:
1476
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/ccp/ccp.c
Normal file
1476
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/ccp/ccp.c
Normal file
File diff suppressed because it is too large
Load Diff
1478
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/ccp/ccp.c.65
Normal file
1478
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/ccp/ccp.c.65
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
*************************************************************************
|
||||
* *
|
||||
* INTERFACE MODULE BETWEEN *
|
||||
* CCP and THE BDOS *
|
||||
* *
|
||||
* *
|
||||
* THIS IS THE DUAL PROCESSOR,ROMABLE CP/M-68K SYSTEM *
|
||||
* ================================================== *
|
||||
* *
|
||||
* (C) Copyright Digital Research 1983 all rights reserved *
|
||||
* *
|
||||
*************************************************************************
|
||||
|
||||
.globl _bdos
|
||||
_bdos: move.w 4(sp),d0
|
||||
move.l 6(sp),d1
|
||||
trap #2
|
||||
rts
|
||||
158
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/ccp/ccpdef.h
Normal file
158
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/ccp/ccpdef.h
Normal file
@@ -0,0 +1,158 @@
|
||||
/*--------------------------------------------------------------*\
|
||||
| ccp_def.c DEFINES v1.0 |
|
||||
| ======= |
|
||||
| |
|
||||
| CP/M 68k: A CP/M derived operating system |
|
||||
| |
|
||||
| File contents: |
|
||||
| ------------- |
|
||||
| This file contains all of the #defines |
|
||||
| used by the console command processor. |
|
||||
| |
|
||||
| created by : Tom Saulpaugh Date: 7/13/82 |
|
||||
| ---------- |
|
||||
| last modified: 10/29/82 |
|
||||
| ------------- |
|
||||
| |
|
||||
| (c) COPYRIGHT Digital Research 1982 |
|
||||
| all rights reserved |
|
||||
| |
|
||||
\*--------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-------------------------------------------*\
|
||||
| CP/M Transient Commands |
|
||||
\*-------------------------------------------*/
|
||||
|
||||
#define DIRCMD 0
|
||||
#define TYPECMD 1
|
||||
#define RENCMD 2
|
||||
#define ERACMD 3
|
||||
#define UCMD 4
|
||||
#define CH_DISK 5
|
||||
#define SUBCMD 6
|
||||
#define SUB_FILE 7
|
||||
#define FILE 8
|
||||
#define DIRSCMD 9
|
||||
#define SEARCH 10
|
||||
|
||||
/*-------------------------------------------*\
|
||||
| Modes and Flags |
|
||||
\*-------------------------------------------*/
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
#define MATCH 0
|
||||
#define GOOD 1
|
||||
#define BAD 0
|
||||
#define FILL 1
|
||||
#define NOFILL 0
|
||||
#define VOID /*no return value*/
|
||||
#define NO_FILE 98
|
||||
#define STOP 99
|
||||
#define USER_ZERO 0
|
||||
#define DISK_A 1
|
||||
#define SOURCEDRIVE 88
|
||||
#define DESTDRIVE 99
|
||||
#define BYTE char
|
||||
#define REG register
|
||||
#define WORD signed short
|
||||
#define UWORD unsigned int
|
||||
#define LONG signed long
|
||||
#define ULONG unsigned long
|
||||
#define GET_MEM_REG 18
|
||||
#define ZERO 0
|
||||
#define NULL '\0'
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define NO_READ 255
|
||||
#define BLANK ' '
|
||||
#define BACKSLH '\\'
|
||||
#define EXLIMPT '!'
|
||||
#define CMASK 0177
|
||||
#define ONE (long)49
|
||||
#define TAB 9
|
||||
#define Cr 13
|
||||
#define Lf 10
|
||||
#define CR (long)13
|
||||
#define LF (long)10
|
||||
#define EOF 26
|
||||
#define BLANKS (long)32
|
||||
#define PERIOD (long)46
|
||||
#define COLON (long)58
|
||||
#define ARROW (long)62
|
||||
|
||||
/*-------------------------------------------*\
|
||||
| Data Structure Size Constants |
|
||||
\*-------------------------------------------*/
|
||||
|
||||
#define CMD_LEN 128
|
||||
#define BIG_CMD_LEN 255
|
||||
#define MAX_ARGS 4
|
||||
#define ARG_LEN 26
|
||||
#define NO_OF_DRIVES 16
|
||||
#define NUMDELS 16
|
||||
#define FCB_LEN 36
|
||||
#define DMA_LEN 128
|
||||
#define FILES_PER_LINE 5
|
||||
#define SCR_HEIGHT 23
|
||||
#define BIG_WIDTH 80
|
||||
#define SMALL_WIDTH 40
|
||||
|
||||
/*-------------------------------------------*\
|
||||
| BDOS Function Calls |
|
||||
\*-------------------------------------------*/
|
||||
|
||||
#define WARMBOOT 0
|
||||
#define CONIN 1
|
||||
#define CONSOLE_OUTPUT 2
|
||||
#define READER_INPUT 3
|
||||
#define PUNCH_OUTPUT 4
|
||||
#define LIST_OUTPUT 5
|
||||
#define DIR_CONS_I/O 6
|
||||
#define GET_I/O_BYTE 7
|
||||
#define SET_I/O_BYTE 8
|
||||
#define PRINT_STRING 9
|
||||
#define READ_CONS_BUF 10
|
||||
#define GET_CONS_STAT 11
|
||||
#define RET_VERSION_NO 12
|
||||
#define RESET_DISK_SYS 13
|
||||
#define SELECT_DISK 14
|
||||
#define OPEN_FILE 15
|
||||
#define CLOSE_FILE 16
|
||||
#define SEARCH_FIRST 17
|
||||
#define SEARCH_NEXT 18
|
||||
#define DELETE_FILE 19
|
||||
#define READ_SEQ 20
|
||||
#define WRITE_SEQ 21
|
||||
#define MAKE_FILE 22
|
||||
#define RENAME_FILE 23
|
||||
#define RET_LOGIN_VEC 24
|
||||
#define RET_CUR_DISK 25
|
||||
#define SET_DMA_ADDR 26
|
||||
#define GET_ADDR(ALLOC) 27
|
||||
#define WRITE_PROT_DISK 28
|
||||
#define GET_READ/O_VEC 29
|
||||
#define SET_FILE_ATTRIB 30
|
||||
#define GET_ADDR_D_PARM 31
|
||||
#define GET_USER_NO 32
|
||||
#define READ_RANDOM 33
|
||||
#define WRITE_RANDOM 34
|
||||
#define COMP_FILE-SIZE 35
|
||||
#define SET_RANDOM_REC 36
|
||||
#define RESET_DRIVE 37
|
||||
#define WRITE_RAN_ZERO 40
|
||||
#define BIOS_CALL 50
|
||||
#define LOAD_PROGRAM 59
|
||||
|
||||
/*----------------------------------------------*\
|
||||
| MACROS |
|
||||
\*----------------------------------------------*/
|
||||
|
||||
#define isalpha(c) (islower(c) || isupper(c))
|
||||
#define islower(c) ('a' <= (c) && (c) <= 'z')
|
||||
#define isupper(c) ('A' <= (c) && (c) <= 'Z')
|
||||
#define tolower(c) (isupper(c) ? ((c)+040):(c))
|
||||
#define toupper(c) (islower(c) ? ((c)-040):(c))
|
||||
#define isdigit(c) ('0' <= (c) && (c) <= '9')
|
||||
|
||||
113
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/ccp/ccpif.s
Normal file
113
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/ccp/ccpif.s
Normal file
@@ -0,0 +1,113 @@
|
||||
*************************************************************************
|
||||
* *
|
||||
* CPM68K INTERFACE MODULE FOR *
|
||||
* THE CONSOLE COMMAND PROCESSOR *
|
||||
* *
|
||||
* THIS IS THE DUAL-PROCESSOR,ROMABLE CP/M-68K SYSTEM *
|
||||
* ================================================== *
|
||||
* *
|
||||
* (C) Copyright Digital Research 1983 all rights reserved *
|
||||
* *
|
||||
*************************************************************************
|
||||
|
||||
|
||||
.globl _bios1
|
||||
.globl _bdos
|
||||
.globl _load68k
|
||||
.globl _load_tbl
|
||||
.globl init_tbl
|
||||
.globl _load_try
|
||||
.globl _autorom
|
||||
.globl flags
|
||||
.globl TPAB
|
||||
.globl stack
|
||||
.globl _bdosini
|
||||
.globl _main
|
||||
.globl _submit
|
||||
.globl _morecmds
|
||||
.globl _autost
|
||||
.globl _usercmd
|
||||
.globl _init
|
||||
.globl _ccp
|
||||
.globl _patch
|
||||
.globl cpm
|
||||
|
||||
.text
|
||||
cpm:
|
||||
jmp.l ccpstart * start ccp with possible initial command
|
||||
jmp.l ccpclear * clear auto start flag
|
||||
|
||||
|
||||
|
||||
.bss
|
||||
_autost: .ds.b 1 * autostart command flag
|
||||
_usercmd: .ds.b 130 * user command buffer
|
||||
|
||||
.text
|
||||
copy: .dc.b 'COPYRIGHT (C) 1982, Digital Research '
|
||||
|
||||
|
||||
.text
|
||||
ccpclear:
|
||||
clr.b _autost * clear the autostart flag
|
||||
|
||||
ccpstart:
|
||||
lea stack,sp * set up the stack pointer
|
||||
clr.b _autost * clear the auto start flag
|
||||
jsr _init * call bios init
|
||||
move.w d0,dskuser * save user # & disk
|
||||
*
|
||||
*
|
||||
* ROM SYSTEM INITIALIZATION
|
||||
* OF BSS VARIABLES
|
||||
*
|
||||
*
|
||||
|
||||
clr.b _load_try
|
||||
clr.b _submit
|
||||
clr.b _morecmds
|
||||
move.b #$1,_autorom
|
||||
clr.w flags
|
||||
clr.w TPAB
|
||||
jsr init_tbl
|
||||
|
||||
|
||||
|
||||
jsr _bdosini * do bdos init
|
||||
move.w #32,d0 * get user bdos func #
|
||||
clr.l d1 * clear out d1
|
||||
move.b dskuser,d1 * get the user #
|
||||
trap #2 * set the user number
|
||||
clr.l d0 * clear d0
|
||||
move.w #14,d0 * select function
|
||||
clr.l d1 * clear d1
|
||||
move.w dskuser,d1 * get disk to be selected
|
||||
andi #$0ff,d1 * mask off the user #
|
||||
trap #2 * select the disk
|
||||
|
||||
_ccp:
|
||||
lea stack,sp * set up the stack pointer
|
||||
jsr _main * call the CCP
|
||||
bra _ccp
|
||||
|
||||
.bss
|
||||
.even
|
||||
|
||||
dskuser: .ds.w 1
|
||||
.even
|
||||
_submit: .ds.b 1
|
||||
.even
|
||||
_morecmds: .ds.b 1
|
||||
.even
|
||||
_patch .ds.l 25
|
||||
.end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
188
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/ccp/ccpload.s
Normal file
188
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/ccp/ccpload.s
Normal file
@@ -0,0 +1,188 @@
|
||||
*****************************************************************
|
||||
* *
|
||||
* COMMAND FILE LOADER FOR CPM68K *
|
||||
* ============================== *
|
||||
* *
|
||||
* (c) COPYRIGHT Digital Research 1983 *
|
||||
* all rights reserved *
|
||||
* *
|
||||
* THIS IS THE DUAL PROCESSOR,ROMABLE CP/M-68K SYSTEM *
|
||||
* ================================================== *
|
||||
* *
|
||||
* Description: *
|
||||
* ----------- The command file loader is envoked by *
|
||||
* the CCP after the CCP has successfully *
|
||||
* opened that file. The loader must *
|
||||
* call the BDOS to obtain the boundries *
|
||||
* of the TPA. The load parameter block *
|
||||
* defined in this loader holds all the *
|
||||
* memory size and location details. *
|
||||
* Next the loader returns the system to *
|
||||
* its original user #. The CCP might *
|
||||
* have switched to user zero during its *
|
||||
* search for the file. Next the default *
|
||||
* dma address is set for the loaded *
|
||||
* program. Next the command tail is *
|
||||
* placed,along with the first two parsed *
|
||||
* fcb's,into the user basepage. *
|
||||
* Lastly the user stack pointer is set up *
|
||||
* and the return address is put on the *
|
||||
* user stack. An RTE transferes control. *
|
||||
* If a load was not successfull, the *
|
||||
* appropriate error message is printed. *
|
||||
* *
|
||||
* Created by: Tom Saulpaugh *
|
||||
* *
|
||||
* Last Modified: 3/02/83 *
|
||||
* *
|
||||
*****************************************************************
|
||||
|
||||
|
||||
|
||||
.globl _load68k * make this procedure public
|
||||
.globl _user * global user # before load occured
|
||||
.globl _cmdfcb * parsed fcb
|
||||
.globl _tail * global pointer to command tail
|
||||
.globl _fill_fcb * procedure to fill fcb's
|
||||
.globl flags * ROM SYSTEM INITIALIZATION
|
||||
.globl TPAB * ROM SYSTEM INITIALIZATION
|
||||
|
||||
|
||||
reboot = 0
|
||||
printstr = 9
|
||||
setdma = 26
|
||||
chuser = 32
|
||||
pgmldf = 59
|
||||
gettpa = 63
|
||||
|
||||
_load68k:
|
||||
*
|
||||
* Load the 68k file into the TPA
|
||||
* ------------------------------
|
||||
*
|
||||
.text
|
||||
|
||||
move.l #TPAB,d1 * move in address of tpa parameter block
|
||||
move.w #gettpa,d0 * get function number
|
||||
trap #2 * get the tpa limits
|
||||
move.l low,lowadr * put it in the lpb
|
||||
move.l high,hiadr * put high tpa addr in lpb
|
||||
move.l #_cmdfcb,LPB * get address of opened fcb
|
||||
move.l #pgmldf,d0 * move in bdos function no
|
||||
move.l #LPB,d1 * d1 points to load block
|
||||
trap #2 * do the program load
|
||||
tst d0 * was the load successful?
|
||||
bne lderr * if not print error message and return
|
||||
*
|
||||
* return to original user #
|
||||
* -------------------------
|
||||
move.w _user,d1 * put user # to switch to in d1
|
||||
move.l #chuser,d0 * put bdos func # in d0
|
||||
trap #2 * do the user # change
|
||||
*
|
||||
* set the default dma address
|
||||
* ---------------------------
|
||||
clr.l d1 * clear d1 register
|
||||
move.l baspag,d1 * d1 points to user base page
|
||||
add #$80,d1 * d1 points to default dma in base page
|
||||
movea.l d1,a1 * save it for later use
|
||||
move #setdma,d0 * move in bdos function no
|
||||
trap #2 * set the default dma address
|
||||
*
|
||||
* move in the command tail
|
||||
* ------------------------
|
||||
move.l a1,a2 * save a pointer to the count field
|
||||
add.l #$01,a1 * point past count field
|
||||
move.l _tail,a0 * point to command tail
|
||||
clr.l d0 * clear out d0
|
||||
mvtail: cmpi.b #$00,(a0) * check for a NULL ending byte
|
||||
beq done * NULL byte terminates command
|
||||
cmpi.b #$21,(a0) * check for an '!'
|
||||
beq done * '!' ends the command
|
||||
move.b (a0)+,(a1)+ * move a byte of the command tail
|
||||
addq #1,d0 * bump up the character count
|
||||
bra mvtail * continue byte move
|
||||
done: move.b d0,(a2) * put in the character count
|
||||
move.b #$00,(a1) * terminate cmd tail with a NULL byte
|
||||
*
|
||||
* fill fcb1 & fcb2
|
||||
* ----------------
|
||||
move.l #_cmdfcb,-(sp) * put address of fcb buffer onto stack
|
||||
move.w #1,-(sp) * put 1 on stack(parm1)
|
||||
jsr _fill_fcb * jump to 'C' code & fill cmdfcb with parm1
|
||||
add.l #6,sp * clean off the stack
|
||||
clr.l d0 * clear register d0
|
||||
moveq #$5c,d0 * put basepage address of fcb1 in d0
|
||||
bsr movfcb * put fcb1 in the basepage
|
||||
move.l #_cmdfcb,-(sp) * put address of fcb buffer onto stack
|
||||
move.w #2,-(sp) * put 2 on stack(parm2)
|
||||
jsr _fill_fcb * jump to 'C' code & fill cmdfcb with parm2
|
||||
add.l #6,sp * clean off the stack
|
||||
clr.l d0 * clear register d0
|
||||
moveq #$38,d0 * put basepage address of fcb1 in d0
|
||||
bsr movfcb * put fcb2 in the basepage
|
||||
*
|
||||
* now push rte stuff on stack
|
||||
* ---------------------------
|
||||
movea.l usrstk,a0 * get user stack pointer
|
||||
move.l baspag,a1 * get basepage address
|
||||
move.l 8(a1),-(sp) * push address we want to jump to
|
||||
move sr,d0 * get the status register in d0
|
||||
andi #$5f00,d0 * mask trace,system bits,user flags
|
||||
move.w d0,-(sp) * push it on stack
|
||||
move.l a1,-(a0) * push addr of basepage onto user stack
|
||||
move.l #cmdrtn,-(a0) * push return address onto user stack
|
||||
move.l a0,usp * set up user stack pointer
|
||||
rte
|
||||
*
|
||||
* load error
|
||||
* ----------
|
||||
lderr:
|
||||
rts * return with error code in d0
|
||||
cmdrtn:
|
||||
move #reboot,d0 * reboot CPM
|
||||
trap #2
|
||||
movfcb:
|
||||
add.l baspag,d0 * get offset into basepage
|
||||
move.l d0,a0 * move address into a0
|
||||
move.l #_cmdfcb,a1 * a1 points to fcb to be moved
|
||||
clr.l d0 * clear register d0
|
||||
moveq #35,d0 * get length of fcb
|
||||
mov1:
|
||||
move.b (a1)+,(a0)+ * move a byte into the basepage
|
||||
dbf d0,mov1 * if not done branch to mov1
|
||||
rts
|
||||
|
||||
|
||||
.bss
|
||||
|
||||
.even
|
||||
*
|
||||
* LOAD PARAMETER BLOCK
|
||||
*
|
||||
LPB: .ds.l 1
|
||||
lowadr: .ds.l 1
|
||||
hiadr: .ds.l 1
|
||||
baspag: .ds.l 1
|
||||
usrstk: .ds.l 1
|
||||
flags: .ds.w 1
|
||||
|
||||
*
|
||||
* TPA Parameter Block
|
||||
*
|
||||
.even
|
||||
TPAB: .ds.w 1
|
||||
low: .ds.l 1
|
||||
high: .ds.l 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.end
|
||||
106
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/ccp/filetyps.s
Normal file
106
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/ccp/filetyps.s
Normal file
@@ -0,0 +1,106 @@
|
||||
|
||||
*
|
||||
* CP/M-68K table driven file search module
|
||||
* ========================================
|
||||
*
|
||||
|
||||
* GLOBALS
|
||||
|
||||
|
||||
.globl _load_tbl * loader table
|
||||
.globl _load68k * default load program
|
||||
.globl init_tbl * initializes table on COLD BOOT
|
||||
|
||||
.text
|
||||
*************************************************************************
|
||||
* *
|
||||
* This is the DUAL PROCESSOR,ROMABLE version of CP/M-68K *
|
||||
* ====================================================== *
|
||||
* *
|
||||
* (c) Copyright Digital Research 1983 *
|
||||
* all rights reserved *
|
||||
* *
|
||||
*************************************************************************
|
||||
|
||||
*
|
||||
* The following code allows CP/M-68K to be ROM-able.
|
||||
* -------------------------------------------------
|
||||
*
|
||||
|
||||
init_tbl:
|
||||
move.l #typ1,typ1p
|
||||
move.l #typ2,typ2p * init the pointers to the filetypes
|
||||
move.l #typ3,typ3p
|
||||
move.l #null,typ4p
|
||||
|
||||
move.l #_load68k,pgld1
|
||||
move.l #_load68k,pgld2 * init the pointers to the loaders
|
||||
move.l #_load68k,pgld3
|
||||
move.l #_load68k,pgld4
|
||||
|
||||
rts
|
||||
.bss
|
||||
.even
|
||||
*************************************************************************
|
||||
* *
|
||||
* CP/M-68K LOADER TABLE *
|
||||
* ===================== *
|
||||
* *
|
||||
*-----------------------------------------------------------------------*
|
||||
* *
|
||||
* STRUCTURE OF A LOADER TABLE ENTRY: *
|
||||
* ================================= *
|
||||
* *
|
||||
* (1) LONG WORD pointer to a filetype *
|
||||
* (2) LONG WORD address of the program loader for the above type *
|
||||
* (3) BYTE flag #1 *
|
||||
* (4) BYTE flag #2 *
|
||||
* *
|
||||
*************************************************************************
|
||||
|
||||
|
||||
_load_tbl:
|
||||
typ1p: .ds.l 1
|
||||
pgld1: .ds.l 1
|
||||
.ds.b 1
|
||||
.ds.b 1
|
||||
typ2p: .ds.l 1
|
||||
pgld2: .ds.l 1
|
||||
.ds.b 1
|
||||
.ds.b 1
|
||||
typ3p: .ds.l 1
|
||||
pgld3: .ds.l 1
|
||||
.ds.b 1
|
||||
.ds.b 1
|
||||
typ4p: .ds.l 1
|
||||
pgld4: .ds.l 1
|
||||
.ds.b 1
|
||||
.ds.b 1
|
||||
|
||||
|
||||
*****************************************
|
||||
* *
|
||||
* FILETYPE TABLE *
|
||||
* ============== *
|
||||
* *
|
||||
*****************************************
|
||||
|
||||
|
||||
.data
|
||||
.even
|
||||
typ1: .dc.b '68K',0
|
||||
.even
|
||||
typ2: .dc.b ' ',0
|
||||
.even
|
||||
typ3: .dc.b 'SUB',0
|
||||
.even
|
||||
null: .dc.l 0
|
||||
.end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
$ num
|
||||
CCP.C
|
||||
CCP.lis
|
||||
$ num
|
||||
CCPBDOS.S
|
||||
CCPBDOS.lis
|
||||
$ num
|
||||
CCPDEF.H
|
||||
CCPDEF.lst
|
||||
$ num
|
||||
CCPIF.S
|
||||
CCPIF.lis
|
||||
$ num
|
||||
CCPLOAD.S
|
||||
CCPLOAD.lis
|
||||
$ num
|
||||
FILETYPS.S
|
||||
FILETYPS.lis
|
||||
$ num
|
||||
STACK.S
|
||||
STACK.lis
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
Directory DRB0:[STEVE.CPM68K.CCP]
|
||||
|
||||
CCP.C;65
|
||||
CCPBDOS.S;14
|
||||
CCPDEF.H;1
|
||||
CCPIF.S;175
|
||||
CCPLOAD.S;9
|
||||
FILETYPS.S;12
|
||||
LIST.COM;1
|
||||
SEND.COM;2
|
||||
STACK.S;2
|
||||
|
||||
Total of 9 files.
|
||||
@@ -0,0 +1,10 @@
|
||||
$ set noon
|
||||
$ vsend CCP.C
|
||||
$ vsend CCPBDOS.S
|
||||
$ vsend CCPDEF.H
|
||||
$ vsend CCPIF.S
|
||||
$ vsend CCPLOAD.S
|
||||
$ vsend FILETYPS.S
|
||||
$ vsend SEND.COM
|
||||
$ vsend STACK.S
|
||||
$ vsend done
|
||||
@@ -0,0 +1,15 @@
|
||||
*************************************************************************
|
||||
* *
|
||||
* THIS IS THE SYSTEM STACK AREA *
|
||||
* *
|
||||
* *
|
||||
* THIS IS THE DUAL PROCESSOR,ROMABLE CP/M-68K SYSTEM *
|
||||
* ================================================== *
|
||||
*************************************************************************
|
||||
|
||||
.globl stack
|
||||
.bss
|
||||
.ds.l 300
|
||||
stack:
|
||||
.ds.w 1
|
||||
.end
|
||||
917
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/canon.c
Normal file
917
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/canon.c
Normal file
@@ -0,0 +1,917 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
#include "cskel.h"
|
||||
|
||||
/* canon - expression canonicalization*/
|
||||
/* Top level tree canonicalization. This fixes any bit field*/
|
||||
/* accesses, then loops on commute and optim until no more*/
|
||||
/* optimizations are done.*/
|
||||
char *canon(tp) /* returns pointer to tree*/
|
||||
struct tnode *tp; /* pointer to tree to canonicalize*/
|
||||
{
|
||||
tp = fixbfield(tp);
|
||||
do {
|
||||
sucomp(tp,0,1); /*need Sethy-Ullman's for commute*/
|
||||
tp = commute(tp); /*commute the tree*/
|
||||
} while( optim(&tp) ); /*keep trying for optimizations*/
|
||||
#ifndef NODEBUG
|
||||
if( oflag )
|
||||
putexpr("canon",tp);
|
||||
#endif
|
||||
return(tp);
|
||||
}
|
||||
|
||||
/* fixbfield - fix bit field operators*/
|
||||
/* Fixes bit field assignment and normal usage*/
|
||||
char *fixbfield(tp) /* returns pointer to fixed tree*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
{
|
||||
register struct tnode *btp, *stp;
|
||||
register int foff, fmask, op, flen;
|
||||
|
||||
if( leafop(op=tp->t_op) )
|
||||
return(tp);
|
||||
if( asgop(op) && tp->t_left->t_op == BFIELD ) {
|
||||
btp = tp->t_left; /*pointer to BFIELD node*/
|
||||
stp = btp->t_left; /*pointer to son of BFIELD node*/
|
||||
foff = (btp->t_su>>8) & 0377;
|
||||
flen = btp->t_su & 0377;
|
||||
fmask = (1<<flen)-1;
|
||||
if( tp->t_right->t_op == CINT && (op == ASSIGN || op == EQXOR) ) {
|
||||
if( op == EQXOR ) {
|
||||
tp->t_left = stp;
|
||||
tp->t_right->t_value =<< foff;
|
||||
return(tp);
|
||||
}
|
||||
if( tp->t_right->t_value == 0 ) {
|
||||
tp->t_op = EQAND;
|
||||
tp->t_left = stp;
|
||||
tp->t_right->t_value = ~ (fmask << foff);
|
||||
return(tp);
|
||||
}
|
||||
if( (tp->t_right->t_value & fmask) == fmask ) {
|
||||
tp->t_op = EQOR;
|
||||
tp->t_left = stp;
|
||||
tp->t_right->t_value = fmask << foff;
|
||||
return(tp);
|
||||
}
|
||||
}
|
||||
if( fmask == -1 )
|
||||
tp->t_left = stp;
|
||||
else {
|
||||
stp = tcopy(stp);
|
||||
btp = fixbfield(btp);
|
||||
op = tp->t_op;
|
||||
tp = tp->t_right; /*pointer to expression*/
|
||||
if( op != ASSIGN ) /*=op operator?*/
|
||||
tp = tnalloc(op-(EQADD-ADD),INT,0,0,btp,tp);
|
||||
tp = tnalloc(AND,INT,0,0,tp,cnalloc(INT,fmask));
|
||||
tp = tnalloc(LSH,INT,0,0,tp,cnalloc(INT,foff));
|
||||
btp = tnalloc(AND,INT,0,0,tcopy(stp),
|
||||
cnalloc(INT,~(fmask<<foff)));
|
||||
tp = tnalloc(OR,INT,0,0,btp,tp);
|
||||
tp = tnalloc(ASSIGN,INT,0,0,stp,tp);
|
||||
}
|
||||
}
|
||||
else if( op == BFIELD ) {
|
||||
foff = (tp->t_su>>8) & 0377;
|
||||
fmask = (1<<(tp->t_su&0377))-1;
|
||||
tp = tnalloc(RSH,INT,0,0,tp->t_left,cnalloc(INT,foff));
|
||||
tp = tnalloc(AND,INT,0,0,tp,cnalloc(INT,fmask));
|
||||
}
|
||||
else {
|
||||
tp->t_left = fixbfield(tp->t_left);
|
||||
if( binop(op) )
|
||||
tp->t_right = fixbfield(tp->t_right);
|
||||
}
|
||||
return(tp);
|
||||
}
|
||||
|
||||
/* optim - optimize expression tree*/
|
||||
/* This takes expression tree and performs the following*/
|
||||
/* translations: folds auto names to accesses off the local*/
|
||||
/* environment pointer, performs mostly "machine-independent"*/
|
||||
/* optimizations, such as multiply by zero and one, etc.,*/
|
||||
/* turns field accesses into and's and or's, etc.*/
|
||||
optim(tpp) /* returns pointer to new tree*/
|
||||
struct tnode **tpp;
|
||||
{
|
||||
register struct tnode *ltp, *rtp, *tp;
|
||||
register char *p;
|
||||
register int i, cval, changes, op;
|
||||
|
||||
tp = *tpp;
|
||||
if( tp->t_type & ~TYPE ) {
|
||||
tp->t_type =& TYPE;
|
||||
tp->t_type =| POINTER;
|
||||
}
|
||||
if( leafop(op=tp->t_op) )
|
||||
return(0);
|
||||
changes = 0;
|
||||
if( binop(op) )
|
||||
changes =+ optim(&tp->t_right);
|
||||
changes =+ optim(&tp->t_left);
|
||||
for( ; notleafop(op=tp->t_op); changes++ ) {
|
||||
#ifndef NODEBUG
|
||||
if( oflag )
|
||||
putexpr("optim",tp);
|
||||
#endif
|
||||
*tpp = tp;
|
||||
ltp = tp->t_left;
|
||||
if( binop(op) ) {
|
||||
rtp = tp->t_right;
|
||||
if( tp->t_type == CHAR )
|
||||
tp->t_type = INT;
|
||||
p = constant(rtp);
|
||||
}
|
||||
else
|
||||
p = constant(ltp);
|
||||
ltp = tp->t_left;
|
||||
if( p )
|
||||
cval = p->t_value;
|
||||
switch( op ) {
|
||||
|
||||
case ADD:
|
||||
if( p ) {
|
||||
if( cval == 0 ) {
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
if( ltp->t_op == ADDR ) {
|
||||
ltp->t_left->t_offset =+ cval;
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ASSIGN:
|
||||
if( rtp->t_op == ADD && indexreg(rtp->t_left) &&
|
||||
rtp->t_right->t_op == CINT ) {
|
||||
ltp = rtp->t_left;
|
||||
ltp->t_sc = REGOFF;
|
||||
ltp->t_offset =+ rtp->t_right->t_value;
|
||||
tp->t_right = ltp;
|
||||
tp->t_op = EQADDR;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case SUB:
|
||||
if( p ) {
|
||||
if( cval == 0 ) {
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
tp->t_op = ADD;
|
||||
p->t_value = -cval;
|
||||
continue;
|
||||
}
|
||||
if( (p=constant(ltp)) && p->t_value == 0 ) { /*0-X=-X*/
|
||||
tp->t_op = UMINUS;
|
||||
tp->t_left = ltp = rtp;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case DIV:
|
||||
case EQDIV:
|
||||
if( p ) {
|
||||
if( cval == 0 ) { /*X/0->error*/
|
||||
error("divide by zero");
|
||||
tp = rtp;
|
||||
continue;
|
||||
}
|
||||
if( cval == 1 ) {
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
if( cval == -1 && op == DIV ) {
|
||||
tp->t_op = UMINUS;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( (p=constant(ltp)) && p->t_value == 0 ) {
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
if( multop(tpp) ) {
|
||||
tp = *tpp;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case EQMOD:
|
||||
case MOD:
|
||||
if( p ) {
|
||||
if( cval == 0 ) { /*X%0->error*/
|
||||
error("modulus by zero");
|
||||
tp = rtp;
|
||||
continue;
|
||||
}
|
||||
if( cval == 1 ) { /*X%1->0*/
|
||||
p->t_value = 0;
|
||||
tp = rtp;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( (p=constant(ltp)) && p->t_value == 0 ) {
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
if( multop(tpp) ) {
|
||||
tp = *tpp;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case MULT:
|
||||
case EQMULT:
|
||||
if( p ) {
|
||||
if( cval == 0 ) {
|
||||
tp = rtp;
|
||||
continue;
|
||||
}
|
||||
if( cval == 1 ) {
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
if( cval == -1 && op == MULT ) {
|
||||
tp->t_op = UMINUS;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( multop(tpp) ) {
|
||||
tp = *tpp;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case EQUALS:
|
||||
case NEQUALS:
|
||||
if( p && (i=onebit(cval)) >= 0 && ltp->t_op == AND &&
|
||||
(rtp=constant(ltp->t_right)) &&
|
||||
i == onebit(rtp->t_value) ) {
|
||||
tp->t_op = invrel[tp->t_op-EQUALS];
|
||||
p->t_value = 0;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case GREATEQ:
|
||||
if( p && cval == 0 && unsign(ltp->t_type) ) {
|
||||
p->t_value = 1;
|
||||
tp = p;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case LESS:
|
||||
if( p && cval == 0 && unsign(ltp->t_type) ) {
|
||||
tp = p;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case AND:
|
||||
if( p ) {
|
||||
if( cval == 0 ) {
|
||||
tp = rtp;
|
||||
continue;
|
||||
}
|
||||
if( cval == -1 ) {
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OR:
|
||||
if( p ) {
|
||||
if( cval == 0 ) {
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
if( cval == -1 ) {
|
||||
tp = rtp;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case XOR:
|
||||
if( p ) {
|
||||
if( cval == 0 ) {
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
if( cval == -1 ) {
|
||||
tp->t_op = COMPL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LSH:
|
||||
case EQLSH:
|
||||
if( tp->t_type == LONG && rtp->t_op == INT2L &&
|
||||
unsign(rtp->t_left) ) {
|
||||
tp->t_right = rtp->t_left;
|
||||
continue;
|
||||
}
|
||||
case RSH:
|
||||
case EQRSH:
|
||||
if( p ) {
|
||||
if( cval == 0 ) {
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
if( p != rtp ) {
|
||||
tp->t_right = p;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ADDR:
|
||||
if( ltp->t_op == INDR ) {
|
||||
tp = ltp->t_left;
|
||||
continue;
|
||||
}
|
||||
if( ltp->t_op == SYMBOL && ltp->t_sc == REGOFF ) {
|
||||
tp->t_op = ADD;
|
||||
tp->t_right = cnalloc(INT,ltp->t_offset);
|
||||
ltp->t_type = tp->t_type;
|
||||
ltp->t_sc = REGISTER;
|
||||
ltp->t_offset = 0;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case INDR:
|
||||
p = ltp->t_left;
|
||||
switch( ltp->t_op ) {
|
||||
|
||||
case ADDR:
|
||||
tp = p;
|
||||
continue;
|
||||
|
||||
case CINT:
|
||||
tp = snalloc(tp->t_type,CINDR,ltp->t_value,0,0);
|
||||
continue;
|
||||
|
||||
case CLONG:
|
||||
tp = snalloc(tp->t_type,CLINDR,ltp->t_lvalue.hiword,0,
|
||||
ltp->t_lvalue.loword);
|
||||
continue;
|
||||
|
||||
case SYMBOL:
|
||||
if( indexreg(ltp) ) {
|
||||
ltp->t_sc = REGOFF;
|
||||
ltp->t_type = tp->t_type;
|
||||
ltp->t_offset = 0;
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case ADD:
|
||||
if( p->t_op == SYMBOL && p->t_sc == REGOFF &&
|
||||
(rtp=constant(ltp->t_right)) &&
|
||||
notpointer(p->t_type) ) {
|
||||
p->t_offset =+ rtp->t_value;
|
||||
tp = p;
|
||||
continue;
|
||||
}
|
||||
if( indexreg(p) ) {
|
||||
if( rtp = constant(ltp->t_right) ) {
|
||||
|
||||
/*This combines an address register and a constant into a register*/
|
||||
/*offset. This relies on 68000 Addressing scheme somewhat.*/
|
||||
|
||||
p->t_sc = REGOFF;
|
||||
p->t_type = tp->t_type;
|
||||
p->t_offset =+ rtp->t_value;
|
||||
tp = p;
|
||||
continue;
|
||||
}
|
||||
if( lflag == 0 && ltp->t_right->t_op == ADDR ) {
|
||||
|
||||
/*We can fold *(An+&expr) into *(&expr(An)), but note that &expr*/
|
||||
/*must be 16 bits for 68000, hence we can only do this if short*/
|
||||
/*addresses are enabled. Note that the storage classes are mapped:*/
|
||||
/*EXTERNAL->EXTOFF, STATIC->STATOFF, REGISTER->REGOFF*/
|
||||
|
||||
ltp = ltp->t_right->t_left;
|
||||
ltp->t_sc =+ (EXTOFF-EXTERNAL);
|
||||
ltp->t_type = tp->t_type;
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/*--X and X++ can be folded into -(An) and (An)+ 68000 instructions*/
|
||||
|
||||
case PREDEC:
|
||||
case POSTINC:
|
||||
if( indexreg(p) && ltp->t_type == p->t_type ) {
|
||||
p->t_op = (ltp->t_op == PREDEC ? AUTODEC : AUTOINC);
|
||||
p->t_type = tp->t_type;
|
||||
tp = p;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NOT:
|
||||
if( relop(ltp->t_op) ) { /*!(X>Y)->X<=Y*/
|
||||
tp = ltp;
|
||||
tp->t_op = invrel[tp->t_op-EQUALS];
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case UMINUS:
|
||||
case COMPL:
|
||||
if( tp->t_type == CHAR )
|
||||
tp->t_type = INT;
|
||||
if( tp->t_op == ltp->t_op ) {
|
||||
tp = ltp->t_left;
|
||||
continue;
|
||||
}
|
||||
if( ltp->t_op == INT2L ) { /*~(INT2L X)->INT2L (~X)*/
|
||||
ltp->t_op = tp->t_op;
|
||||
tp->t_op = INT2L;
|
||||
ltp->t_type = INT;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case INT2L:
|
||||
if( ltp->t_op == MULT ) { /*INT2L (X*Y)->X*Y*/
|
||||
ltp->t_type = (ltp->t_type&(~TYPE))|LONG;
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if( ccexpr(tpp) == 0 )
|
||||
break;
|
||||
tp = *tpp;
|
||||
}
|
||||
*tpp = tp;
|
||||
return(changes);
|
||||
}
|
||||
|
||||
/* commute - commutes expression tree to canonical form*/
|
||||
/* This sorts commutable expression trees so that the most*/
|
||||
/* difficult expression is the left-most operand. Note that*/
|
||||
/* canon assumes that commute has placed constant operands in*/
|
||||
/* the right sub-tree. This also swaps relationals so that the*/
|
||||
/* most difficult expression is on the left.*/
|
||||
char *commute(tp) /* returns commuted expression tree*/
|
||||
struct tnode *tp;
|
||||
{
|
||||
struct tnode *clist[20], *plist[19];
|
||||
register struct tnode **p, **q, *s;
|
||||
struct tnode **plp, **clp;
|
||||
register int op;
|
||||
|
||||
if( relop(op=tp->t_op) ) {
|
||||
s = tp->t_left;
|
||||
if( harder(tp->t_right,s) ) {
|
||||
#ifndef NODEBUG
|
||||
if(oflag)
|
||||
putexpr("swaprel",tp);
|
||||
#endif
|
||||
tp->t_op = swaprel[op-EQUALS];
|
||||
tp->t_left = tp->t_right;
|
||||
tp->t_right = s;
|
||||
}
|
||||
}
|
||||
if( commop(op) ) {
|
||||
#ifndef NODEBUG
|
||||
if(oflag)
|
||||
putexpr("commute",tp);
|
||||
#endif
|
||||
clp = clist;
|
||||
plp = plist;
|
||||
addtree(tp,&clp,&plp); /*collect comm. expressions*/
|
||||
|
||||
/*see if any sub-trees can also be commuted (with different operator)*/
|
||||
|
||||
clp--;
|
||||
plp--;
|
||||
for( p = clist; p <= clp; p++ )
|
||||
*p = commute(*p);
|
||||
|
||||
/*this sorts the expressions in decreasing order of Sethy-Ullman*/
|
||||
/*values.*/
|
||||
|
||||
for( p = clist; p <= clp; p++ ) {
|
||||
for( q = p; q <= clp; q++ ) {
|
||||
if( harder(*q,*p) ) {
|
||||
s = *q;
|
||||
*q = *p;
|
||||
*p = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Now, we start at the end of the list and collect any constants*/
|
||||
/*if possible.*/
|
||||
|
||||
for( q = clp, p = plp; p > plist; p-- ) {
|
||||
s = *p;
|
||||
s->t_right = *q;
|
||||
s->t_left = *--q;
|
||||
if( ccexpr(p) ) {
|
||||
clp--;
|
||||
plp--;
|
||||
}
|
||||
}
|
||||
|
||||
/*this takes the sorted sub-expression pointers and the pointers*/
|
||||
/*to the commutable operator nodes (plist) and structures the*/
|
||||
/*tree so that the left sub-expression is the most complex. The*/
|
||||
/*code generation scheme is very sensitive to this...*/
|
||||
|
||||
q = clist;
|
||||
p = plist;
|
||||
s = *q++;
|
||||
while( p <= plp ) {
|
||||
(*p)->t_left = s;
|
||||
s = *p++;
|
||||
s->t_right = *q++;
|
||||
if( longorptr(s->t_type) == 0 ) {
|
||||
if( longorptr(s->t_right->t_type) )
|
||||
s->t_type = s->t_right->t_type;
|
||||
else if( longorptr(s->t_left->t_type) )
|
||||
s->t_type = s->t_left->t_type;
|
||||
}
|
||||
}
|
||||
tp = s;
|
||||
#ifndef NODEBUG
|
||||
if(oflag)
|
||||
putexpr("after commute",tp);
|
||||
#endif
|
||||
}
|
||||
else if( binop(op) ) {
|
||||
tp->t_left = commute(tp->t_left);
|
||||
tp->t_right = commute(tp->t_right);
|
||||
}
|
||||
else if( unaryop(op) )
|
||||
tp->t_left = commute(tp->t_left);
|
||||
return(tp);
|
||||
}
|
||||
|
||||
/* harder - test one sub-expression for being "harder" than another*/
|
||||
/* This requires some special finagling for registers. The reason*/
|
||||
/* for this is that the code skeletons produce better code if the*/
|
||||
/* register is on the left. Also note that allowing an address*/
|
||||
/* register on the right can have disastrous effects for AND and OR.*/
|
||||
/* The basic point is: don't mess with this routine unless you're*/
|
||||
/* 100% sure you understand the ramifications...*/
|
||||
harder(tp,ntp) /* returns 1 if tp > ntp, else 0*/
|
||||
struct tnode *tp;
|
||||
struct tnode *ntp;
|
||||
{
|
||||
if( ntp->t_su == SU_VHARD )
|
||||
return(0);
|
||||
if( tp->t_su == SU_VHARD )
|
||||
return(1);
|
||||
if( isreg(ntp) )
|
||||
return(0);
|
||||
if( isreg(tp) )
|
||||
return(1);
|
||||
if( constant(ntp) )
|
||||
return(1);
|
||||
if( constant(tp) )
|
||||
return(0);
|
||||
return( tp->t_su > ntp->t_su );
|
||||
}
|
||||
|
||||
/* addtree - collect commutable sub-trees for commute*/
|
||||
/* This recurses down the sub-trees looking for groups of*/
|
||||
/* commutable operators. It collects the sub-trees and their*/
|
||||
/* parent nodes for commute.*/
|
||||
addtree(tp,clist,plist) /* returns pointer to clist*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
struct tnode ***clist; /* commutable sub-trees*/
|
||||
struct tnode ***plist; /* parent nodes of sub-trees*/
|
||||
{
|
||||
register struct tnode ***p, ***c;
|
||||
|
||||
c = clist;
|
||||
p = plist;
|
||||
if( tp->t_op == tp->t_left->t_op )
|
||||
addtree(tp->t_left,c,p);
|
||||
else
|
||||
*(*c)++ = tp->t_left;
|
||||
if( tp->t_op == tp->t_right->t_op )
|
||||
addtree(tp->t_right,c,p);
|
||||
else
|
||||
*(*c)++ = tp->t_right;
|
||||
*(*p)++ = tp;
|
||||
}
|
||||
|
||||
/* constant - test for tree being a constant node*/
|
||||
char *constant(tp) /* returns 0 or ptr to const node*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
{
|
||||
if( tp->t_op == CINT )
|
||||
return(tp);
|
||||
if( tp->t_op == INT2L && tp->t_left->t_op == CINT )
|
||||
return(tp->t_left);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* indexreg - returns whether node is an address register*/
|
||||
/* For 68000, must be an A register*/
|
||||
indexreg(tp) /* returns whether node is A reg*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
{
|
||||
if( tp->t_op == SYMBOL && tp->t_sc == REGISTER &&
|
||||
isdreg(tp->t_reg) == 0 )
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* ccexpr - compute constant expression*/
|
||||
/* Evaluates constant expressions, including ?: and relationals*/
|
||||
ccexpr(tpp) /* returns 1 if changes, 0 otherwise*/
|
||||
struct tnode **tpp; /* pointer to tree*/
|
||||
{
|
||||
register struct tnode *ltp, *rtp, *tp;
|
||||
register int op, i, j, anylong;
|
||||
register long rval, lval;
|
||||
|
||||
tp = *tpp;
|
||||
op = tp->t_op;
|
||||
if( leafop(op) )
|
||||
return(0);
|
||||
anylong = 0;
|
||||
ltp = tp->t_left;
|
||||
if( ltp->t_op == CLONG ) {
|
||||
lval = ltp->t_lvalue;
|
||||
anylong++;
|
||||
}
|
||||
else if( ltp = constant(ltp) )
|
||||
lval = ltp->t_value;
|
||||
else
|
||||
return(0);
|
||||
if( binop(op) ) {
|
||||
rtp = tp->t_right;
|
||||
if( op == QMARK ) {
|
||||
ltp = rtp->t_left;
|
||||
rtp = rtp->t_right;
|
||||
if( ltp->t_op != CINT || rtp->t_op != CINT )
|
||||
return(0);
|
||||
ltp->t_value = (lval?ltp->t_value:rtp->t_value);
|
||||
*tpp = ltp;
|
||||
return(1);
|
||||
}
|
||||
if( rtp->t_op == CLONG ) {
|
||||
anylong++;
|
||||
rval = rtp->t_lvalue;
|
||||
}
|
||||
else if( rtp = constant(rtp) )
|
||||
rval = rtp->t_value;
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
i = lval;
|
||||
j = rval;
|
||||
switch( op ) {
|
||||
|
||||
case ADD:
|
||||
lval =+ rval;
|
||||
break;
|
||||
|
||||
case SUB:
|
||||
lval =- rval;
|
||||
break;
|
||||
|
||||
case MULT:
|
||||
case DIV:
|
||||
case MOD:
|
||||
case LSH:
|
||||
case RSH:
|
||||
case XOR:
|
||||
if( anylong )
|
||||
return(0);
|
||||
switch( op ) {
|
||||
|
||||
case MULT:
|
||||
lval = i * j;
|
||||
break;
|
||||
|
||||
case DIV:
|
||||
lval = i / j;
|
||||
break;
|
||||
|
||||
case MOD:
|
||||
lval = i % j;
|
||||
break;
|
||||
|
||||
case RSH:
|
||||
lval = i >> j;
|
||||
break;
|
||||
|
||||
case LSH:
|
||||
lval = i << j;
|
||||
break;
|
||||
|
||||
case XOR:
|
||||
lval = i ^ j;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case GREAT:
|
||||
lval = (lval>rval);
|
||||
break;
|
||||
|
||||
case GREATEQ:
|
||||
lval = (lval>=rval);
|
||||
break;
|
||||
|
||||
case LESS:
|
||||
lval = (lval<rval);
|
||||
break;
|
||||
|
||||
case LESSEQ:
|
||||
lval = (lval<=rval);
|
||||
break;
|
||||
|
||||
case UMINUS:
|
||||
lval = -lval;
|
||||
break;
|
||||
|
||||
case COMPL:
|
||||
lval = ~lval;
|
||||
break;
|
||||
|
||||
case NOT:
|
||||
lval = !lval;
|
||||
break;
|
||||
|
||||
case OR:
|
||||
lval =| rval;
|
||||
break;
|
||||
|
||||
case AND:
|
||||
lval =& rval;
|
||||
break;
|
||||
|
||||
default:
|
||||
return(0);
|
||||
|
||||
}
|
||||
if( anylong )
|
||||
ltp = lcnalloc(LONG,lval);
|
||||
else
|
||||
ltp->t_value = lval;
|
||||
*tpp = ltp;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* power2 - do multiply and divide by powers of two*/
|
||||
/* This changes multiplies and divides by constant powers of two*/
|
||||
/* to shifts.*/
|
||||
power2(tpp) /* returns 0 if not power of two*/
|
||||
struct tnode **tpp; /* pointer to expression tree*/
|
||||
{
|
||||
register char *p;
|
||||
register int i, j, op;
|
||||
register struct tnode *tp;
|
||||
|
||||
tp = *tpp;
|
||||
if( p = constant(tp->t_right) ) {
|
||||
if( (i=onebit(p->t_value)) < 0 )
|
||||
return(0);
|
||||
switch( op = tp->t_op ) {
|
||||
|
||||
case MULT:
|
||||
case LMULT:
|
||||
op = LSH;
|
||||
break;
|
||||
|
||||
case EQMULT:
|
||||
case LEQMULT:
|
||||
op = EQLSH;
|
||||
break;
|
||||
|
||||
case DIV:
|
||||
case LDIV:
|
||||
op = RSH;
|
||||
break;
|
||||
|
||||
case EQDIV:
|
||||
case LEQDIV:
|
||||
op = EQRSH;
|
||||
break;
|
||||
|
||||
case MOD:
|
||||
case LMOD:
|
||||
op = AND;
|
||||
i = p->t_value - 1;
|
||||
break;
|
||||
|
||||
case EQMOD:
|
||||
case LEQMOD:
|
||||
op = EQAND;
|
||||
i = p->t_value - 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return(0);
|
||||
}
|
||||
tp->t_op = op;
|
||||
p->t_value = i;
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* chklong - check for tree being a long*/
|
||||
chklong(tp) /* returns 1 if long, 0 otherwise*/
|
||||
struct tnode *tp; /* pointer to expression tree*/
|
||||
{
|
||||
if( tp->t_op == INT2L && unsign(tp->t_left->t_type) == 0 )
|
||||
return(0);
|
||||
if( tp->t_op == CLONG )
|
||||
return(1);
|
||||
return( longorptr(tp->t_type) );
|
||||
}
|
||||
|
||||
/* multop - handle multiplicative operators*/
|
||||
/* This checks for powers of two optimizations, then for a hard*/
|
||||
/* long operation.*/
|
||||
multop(tpp) /* returns ptr to expression tree*/
|
||||
struct tnode **tpp; /* pointer to expression tree*/
|
||||
{
|
||||
register struct tnode *ltp, *tp, *rtp, *p;
|
||||
register int change;
|
||||
register long l;
|
||||
|
||||
tp = *tpp;
|
||||
if( change = power2(tpp) )
|
||||
tp = *tpp;
|
||||
if( chklong(rtp=tp->t_right) || chklong(ltp=tp->t_left) ) {
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case MULT:
|
||||
tp->t_op = LMULT; /*hard if either is long*/
|
||||
break;
|
||||
|
||||
case DIV:
|
||||
case MOD:
|
||||
if( chklong(rtp) ) { /*only hard if divisor is long*/
|
||||
tp->t_op =+ (LMULT-MULT);
|
||||
if( rtp->t_op == CLONG )
|
||||
rtp->t_op = DCLONG;
|
||||
}
|
||||
break;
|
||||
|
||||
case EQDIV:
|
||||
case EQMOD:
|
||||
if( chklong(rtp) == 0 )
|
||||
break;
|
||||
if( rtp->t_op == CLONG )
|
||||
rtp->t_op = DCLONG;
|
||||
case EQMULT:
|
||||
if( ltp->t_op == SYMBOL && ltp->t_sc == REGISTER )
|
||||
error("hard long to register");
|
||||
else {
|
||||
tp->t_op =+ (LEQMULT-EQMULT);
|
||||
tp->t_left = tnalloc(ADDR,LONG|POINTER,0,0,ltp,null);
|
||||
change++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(change);
|
||||
}
|
||||
|
||||
/* onebit - returns whether constant is power of two (one bit on)*/
|
||||
onebit(val) /* returns bit number or -1*/
|
||||
int val; /* constant value to check*/
|
||||
{
|
||||
register int i;
|
||||
|
||||
for( i = 15; val != 0; val =<< 1, i-- )
|
||||
if( val & 0100000 )
|
||||
break;
|
||||
if( val != 0100000 )
|
||||
return(-1);
|
||||
return(i);
|
||||
}
|
||||
162
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/cgen.h
Normal file
162
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/cgen.h
Normal file
@@ -0,0 +1,162 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "icode.h"
|
||||
#define NODEBUG 1
|
||||
|
||||
|
||||
|
||||
char brtab[][2];
|
||||
int invrel[];
|
||||
int swaprel[];
|
||||
char *strtab[];
|
||||
char null[];
|
||||
|
||||
/*operator tree node for unary and binary operators*/
|
||||
struct tnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*data type of result*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
struct tnode *t_left; /*left sub-tree*/
|
||||
struct tnode *t_right; /*right sub-tree (undefined if unary)*/
|
||||
};
|
||||
|
||||
/*constant terminal node*/
|
||||
struct conode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_value; /*value or label number*/
|
||||
};
|
||||
|
||||
struct lconode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
long t_lvalue; /*value or label number*/
|
||||
};
|
||||
|
||||
/*local symbol terminal node*/
|
||||
struct symnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*symbol data type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_sc; /*storage class*/
|
||||
int t_offset; /*register offset*/
|
||||
int t_reg; /*register number*/
|
||||
int t_label; /*label number if static*/
|
||||
};
|
||||
|
||||
/*external symbol reference node*/
|
||||
struct extnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*symbol data type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_sc; /*storage class*/
|
||||
int t_offset; /*register offset*/
|
||||
int t_reg; /*register number*/
|
||||
char t_symbol[SSIZE]; /*symbol name*/
|
||||
};
|
||||
|
||||
/*68000 special - indexed symbol node*/
|
||||
/*this is used to generate a An(off,Xn.type) address*/
|
||||
struct indexnode {
|
||||
int t_op;
|
||||
int t_type;
|
||||
int t_su;
|
||||
int t_ssp;
|
||||
int t_sc;
|
||||
int t_offset;
|
||||
int t_reg;
|
||||
int t_xreg;
|
||||
int t_xtype;
|
||||
};
|
||||
|
||||
int lflag;
|
||||
int dflag;
|
||||
int mflag;
|
||||
int cflag;
|
||||
int eflag;
|
||||
int fflag;
|
||||
int oflag;
|
||||
struct io_buf ibuf, obuf;
|
||||
int lineno;
|
||||
int naregs;
|
||||
int ndregs;
|
||||
int errcnt;
|
||||
int opinfo[];
|
||||
int nextlabel;
|
||||
char null[];
|
||||
char optab[][6];
|
||||
char *mnemonics[];
|
||||
char *codeskels[];
|
||||
int stacksize;
|
||||
|
||||
char *tnalloc();
|
||||
char *snalloc();
|
||||
char *cenalloc();
|
||||
char *xnalloc();
|
||||
char *talloc();
|
||||
char *cnalloc();
|
||||
char *lcnalloc();
|
||||
char *canon();
|
||||
char *commute();
|
||||
char *constant();
|
||||
char *match();
|
||||
char *addptree();
|
||||
char *fixbfield();
|
||||
char *coffset();
|
||||
char *tcopy();
|
||||
#define wallign(add) ((add+1)&(~1))
|
||||
#define array(type) ((type&SUPTYP)==ARRAY)
|
||||
#define function(type) ((type&SUPTYP)==FUNCTION)
|
||||
#define pointer(type) ((type&SUPTYP)==POINTER)
|
||||
#define notarray(type) ((type&SUPTYP)!=ARRAY)
|
||||
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
|
||||
#define notpointer(type) ((type&SUPTYP)!=POINTER)
|
||||
#define btype(type) (type&TYPE)
|
||||
#define suptype(type) (type&SUPTYP)
|
||||
#define alltype(type) (type&(SUPTYP|TYPE))
|
||||
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
|
||||
#define relop(op) ((opinfo[op]&OPREL)!=0)
|
||||
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
|
||||
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
|
||||
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
|
||||
#define binop(op) ((opinfo[op]&OPBIN)!=0)
|
||||
#define unaryop(op) ((opinfo[op]&(OPBIN|OPTERM))==0)
|
||||
#define leafop(op) ((opinfo[op]&OPTERM)!=0)
|
||||
#define notleafop(op) ((opinfo[op]&OPTERM)==0)
|
||||
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
|
||||
#define oppriority(op) (opinfo[op]&OPPRI)
|
||||
#define commop(op) ((opinfo[op]&OPCOM)!=0)
|
||||
#define convop(op) ((opinfo[op]&OPCONVS)!=0)
|
||||
#define notconvop(op) ((opinfo[op]&OPCONVS)==0)
|
||||
#define max(a,b) (a>b?a:b)
|
||||
#define min(a,b) (a<b?a:b)
|
||||
|
||||
#define QUICKVAL 8
|
||||
#define LEP 14
|
||||
#define FORCC 1
|
||||
#define FOREFF 2
|
||||
#define FORSTACK 3
|
||||
#define FORCREG 4
|
||||
#define FORSP 5
|
||||
#define FORREG 4
|
||||
#define HICREG 2
|
||||
#define NCREGS 3
|
||||
#define AREGLO 8
|
||||
#define IMMED 1
|
||||
#define NOTIMMED 0
|
||||
#define LOFFSET 2
|
||||
#define NOTLOFFSET 0
|
||||
|
||||
1189
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/codegen.c
Normal file
1189
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/codegen.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,90 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/*built-in literals*/
|
||||
#define MOV 128
|
||||
#define MOVL 129
|
||||
#define JSR 130
|
||||
#define CLR 131
|
||||
#define CLRL 132
|
||||
#define EXTW 133
|
||||
#define EXTL 134
|
||||
#define LEA 135
|
||||
#define STK 136
|
||||
|
||||
/*built-in macros*/
|
||||
#define TREE 141
|
||||
#define LEFT 142
|
||||
#define RIGHT 143
|
||||
#define LOFFSET 144
|
||||
#define ROFFSET 145
|
||||
#define LADDR 146
|
||||
#define RADDR 147
|
||||
#define CR 148
|
||||
#define NR 149
|
||||
#define CAR 150
|
||||
#define NAR 151
|
||||
#define TLEFT 152
|
||||
#define TRIGHT 153
|
||||
#define TEITHER 154
|
||||
#define TLEFTL 155
|
||||
#define OP 156
|
||||
#define AOP 157
|
||||
#define MODSWAP 158
|
||||
#define EXL 159
|
||||
#define EXLR 160
|
||||
#define EXLRN 161
|
||||
#define EXRL 162
|
||||
#define EXRLN 163
|
||||
#define PSH 164
|
||||
#define POP 165
|
||||
#define POP8 166
|
||||
|
||||
/*modifiers for compiling sub-trees*/
|
||||
#define S_INDR 1 /*indirection*/
|
||||
#define S_STACK 2 /*onto stack*/
|
||||
#define S_FORCC 4 /*set condition codes*/
|
||||
#define S_NEXT 8 /*into next register*/
|
||||
|
||||
/*Sethy-Ullman values*/
|
||||
#define SU_ZERO 0x000 /*zero*/
|
||||
#define SU_ONE 0x100 /*one*/
|
||||
#define SU_SMALL 0x200 /*constant between 1 and 8*/
|
||||
#define SU_QUICK 0x300 /*quick constant between -128 and 127*/
|
||||
#define SU_CONST 0x400 /*any constant*/
|
||||
#define SU_AREG 0x500 /*A register*/
|
||||
#define SU_REG 0x600 /*register*/
|
||||
#define SU_ADDR 0x700 /*addressable*/
|
||||
#define SU_XREG 0x800 /*A register used as data...*/
|
||||
#define SU_EASY 0x900 /*easy*/
|
||||
#define SU_HARD 0xa00 /*hard*/
|
||||
#define SU_VHARD 0xb00 /*very hard ... function calls, etc.*/
|
||||
#define SU_ANY 0xf00 /*anything*/
|
||||
#define ADDRESSABLE(x) (x->t_su<=SU_ADDR)
|
||||
#define NOTADDRESSABLE(x) (x->t_su>SU_ADDR)
|
||||
#define LOADABLE(x) (x->t_su<=SU_XREG)
|
||||
|
||||
/*flag byte (operand type):*/
|
||||
#define T_CHAR 1 /*char only*/
|
||||
#define T_SHORT 2 /*short*/
|
||||
#define T_INT 3 /*int only*/
|
||||
#define T_LONG 4 /*long*/
|
||||
#define T_UCHAR 5 /*unsigned char*/
|
||||
#define T_USHORT 6 /*unsigned short*/
|
||||
#define T_UNSN 7 /*unsigned int*/
|
||||
#define T_ULONG 8 /*unsigned long*/
|
||||
#define T_FLOAT 9 /*float*/
|
||||
#define T_DOUB 10 /*double*/
|
||||
#define T_ANY 11 /*int or word (implied)*/
|
||||
#define T_INDR 0x10 /*pointer type (bit)*/
|
||||
|
||||
struct skeleton {
|
||||
int sk_left;
|
||||
int sk_right;
|
||||
char *sk_def;
|
||||
};
|
||||
1089
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/cskels.c
Normal file
1089
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/cskels.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,15 @@
|
||||
$ diff CANON.C drb1:[cpm68k.release.cgen]CANON.C
|
||||
$ diff CODEGEN.C drb1:[cpm68k.release.cgen]CODEGEN.C
|
||||
$ diff CSKELS.C drb1:[cpm68k.release.cgen]CSKELS.C
|
||||
$ diff INIT.C drb1:[cpm68k.release.cgen]INIT.C
|
||||
$ diff INITX.C drb1:[cpm68k.release.cgen]INITX.C
|
||||
$ diff INTERF.C drb1:[cpm68k.release.cgen]INTERF.C
|
||||
$ diff MAIN.C drb1:[cpm68k.release.cgen]MAIN.C
|
||||
$ diff OPTAB.C drb1:[cpm68k.release.cgen]OPTAB.C
|
||||
$ diff PUTEXPR.C drb1:[cpm68k.release.cgen]PUTEXPR.C
|
||||
$ diff SUCOMP.C drb1:[cpm68k.release.cgen]SUCOMP.C
|
||||
$ diff TABL.C drb1:[cpm68k.release.cgen]TABL.C
|
||||
$ diff UTIL.C drb1:[cpm68k.release.cgen]UTIL.C
|
||||
$ diff CGEN.H drb1:[cpm68k.release.cgen]CGEN.H
|
||||
$ diff CSKEL.H drb1:[cpm68k.release.cgen]CSKEL.H
|
||||
$ diff ICODE.H drb1:[cpm68k.release.cgen]ICODE.H
|
||||
215
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/icode.h
Normal file
215
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/icode.h
Normal file
@@ -0,0 +1,215 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/*intermediate code operators*/
|
||||
/*0=>EOF, special operator*/
|
||||
#define EOF 0
|
||||
|
||||
/*1-59=>operators that generate code (entries in code gen optab)*/
|
||||
#define ADD 1
|
||||
#define SUB 2
|
||||
#define MULT 3
|
||||
#define DIV 4
|
||||
#define MOD 5
|
||||
#define RSH 6
|
||||
#define LSH 7
|
||||
#define AND 8
|
||||
#define OR 9
|
||||
#define XOR 10
|
||||
#define NOT 11
|
||||
#define UMINUS 12
|
||||
#define COMPL 13
|
||||
#define PREDEC 14
|
||||
#define PREINC 15
|
||||
#define POSTDEC 16
|
||||
#define POSTINC 17
|
||||
#define ASSIGN 18
|
||||
#define EQADD 19
|
||||
#define EQSUB 20
|
||||
#define EQMULT 21
|
||||
#define EQDIV 22
|
||||
#define EQMOD 23
|
||||
#define EQRSH 24
|
||||
#define EQLSH 25
|
||||
#define EQAND 26
|
||||
#define EQOR 27
|
||||
#define EQXOR 28
|
||||
#define FJSR 29
|
||||
#define EQUALS 30
|
||||
#define NEQUALS 31
|
||||
#define GREAT 32
|
||||
#define GREATEQ 33
|
||||
#define LESS 34
|
||||
#define LESSEQ 35
|
||||
#define INT2L 36
|
||||
#define LONG2I 37
|
||||
|
||||
/*machine dependent operators that generate code*/
|
||||
#define BTST 38
|
||||
#define LOAD 39
|
||||
#define LMULT 40
|
||||
#define LDIV 41
|
||||
#define LMOD 42
|
||||
#define LEQMULT 43
|
||||
#define LEQDIV 44
|
||||
#define LEQMOD 45
|
||||
#define EQADDR 46
|
||||
#define LCGENOP 47 /*change if adding more operators...*/
|
||||
|
||||
/*intermediate code operators that do not generate code*/
|
||||
#define ADDR 60
|
||||
#define INDR 61
|
||||
#define LAND 62
|
||||
#define LOR 63
|
||||
#define QMARK 64
|
||||
#define COLON 65
|
||||
#define COMMA 66
|
||||
#define CINT 67
|
||||
#define CLONG 68
|
||||
#define SYMBOL 69
|
||||
#define AUTOINC 70
|
||||
#define AUTODEC 71
|
||||
#define CALL 72
|
||||
#define NACALL 73
|
||||
#define BFIELD 74
|
||||
#define IFGOTO 75
|
||||
#define INIT 76
|
||||
#define CFORREG 77
|
||||
#define DCLONG 78
|
||||
|
||||
/*operators local to parser*/
|
||||
#define CAST 80
|
||||
#define SEMI 81
|
||||
#define LCURBR 82
|
||||
#define RCURBR 83
|
||||
#define LBRACK 84
|
||||
#define RBRACK 85
|
||||
#define LPAREN 86
|
||||
#define RPAREN 87
|
||||
#define STRING 88
|
||||
#define RESWORD 89
|
||||
#define APTR 90
|
||||
#define PERIOD 91
|
||||
#define SIZEOF 92
|
||||
#define MPARENS 93
|
||||
#define STACKEND 100
|
||||
|
||||
/*data types*/
|
||||
#define TYPELESS 0
|
||||
#define CHAR 1
|
||||
#define SHORT 2
|
||||
#define INT 3
|
||||
#define LONG 4
|
||||
#define UCHAR 5
|
||||
#define USHORT 6
|
||||
#define UNSIGNED 7
|
||||
#define ULONG 8
|
||||
#define FLOAT 9
|
||||
#define DOUBLE 10
|
||||
|
||||
/*data types local to parser*/
|
||||
#define STRUCT 11
|
||||
#define FRSTRUCT 12
|
||||
#define LLABEL 13
|
||||
|
||||
/*type flags and definitions*/
|
||||
#define TYPE 017
|
||||
#define SUPTYP 060
|
||||
#define ALLTYPE 077
|
||||
#define POINTER 020
|
||||
#define FUNCTION 040
|
||||
#define ARRAY 060
|
||||
#define SUTYPLEN 2
|
||||
|
||||
/* data registers*/
|
||||
#define DREG2 2
|
||||
#define DREG3 3
|
||||
#define DREG4 4
|
||||
#define DREG5 5
|
||||
#define DREG6 6
|
||||
#define DREG7 7
|
||||
#define AREG3 11
|
||||
#define AREG4 12
|
||||
#define AREG5 13
|
||||
|
||||
/*storage classes*/
|
||||
#define AUTO 1
|
||||
#define REGISTER 2
|
||||
#define EXTERNAL 3
|
||||
#define STATIC 4
|
||||
#define REGOFF 5
|
||||
#define EXTOFF 6
|
||||
#define STATOFF 7
|
||||
#define INDEXED 8
|
||||
|
||||
/*exclusively code generator storage classes*/
|
||||
#define CINDR 9
|
||||
#define CLINDR 10
|
||||
|
||||
/*exclusively parser storage classes*/
|
||||
#define STRPROTO 9
|
||||
#define PDECLIST 10
|
||||
#define PARMLIST 11
|
||||
#define BFIELDCL 12
|
||||
#define UNELCL 13
|
||||
#define STELCL 14
|
||||
|
||||
|
||||
/*opinfo table bits*/
|
||||
#define OPPRI 077
|
||||
#define OPBIN 0100
|
||||
#define OPLVAL 0200
|
||||
#define OPREL 0400
|
||||
#define OPASSIGN 01000
|
||||
#define OPLWORD 02000
|
||||
#define OPRWORD 04000
|
||||
#define OPCOM 010000
|
||||
#define OPRAS 020000
|
||||
#define OPTERM 040000
|
||||
#define OPCONVS 0100000
|
||||
|
||||
/*68000 definitions*/
|
||||
#define PTRSIZE 4
|
||||
#define INTSIZE 2
|
||||
#define LONGSIZE 4
|
||||
#define SSIZE 8
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define BITSPBYTE 8
|
||||
|
||||
/*operator class priorities*/
|
||||
#define TRMPRI 0 /*terminal nodes*/
|
||||
#define RPNPRI 1 /*) and ]*/
|
||||
#define CALPRI 2 /*in-stack call, ( or [*/
|
||||
#define COLPRI 3 /*init or case priority for : or ,*/
|
||||
#define STKPRI 4 /*priority of end of stack*/
|
||||
#define COMPRI 5 /*normal priority for ,*/
|
||||
#define ASGPRI 6 /*=, +=, -=, *=, /=, %=, ...*/
|
||||
#define QMKPRI 7 /*?:*/
|
||||
#define LORPRI 8 /*||*/
|
||||
#define LNDPRI 9 /*&&*/
|
||||
#define ORPRI 10 /*|, !*/
|
||||
#define ANDPRI 11 /*&*/
|
||||
#define EQLPRI 12 /*==, !=*/
|
||||
#define RELPRI 13 /*>, <, >=, <=*/
|
||||
#define SHFPRI 14 /*<<, >>*/
|
||||
#define ADDPRI 15 /*+, -*/
|
||||
#define MULPRI 16 /**, /, %*/
|
||||
#define UNOPRI 17 /*++, --, &, *, -, ~, sizeof*/
|
||||
#define LPNPRI 18 /*., ->, [, (, function call*/
|
||||
#define PSTPRI 19 /*in-stack post--, post++*/
|
||||
|
||||
struct io_buf {
|
||||
int io_fd;
|
||||
int io_nc;
|
||||
char *io_p;
|
||||
char io_b[512];
|
||||
};
|
||||
struct { int hiword; int loword; };
|
||||
#define EXPSIZE 1024
|
||||
int exprarea[EXPSIZE];
|
||||
381
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/init.c
Normal file
381
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/init.c
Normal file
@@ -0,0 +1,381 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/*intermediate code operators*/
|
||||
/*0=>EOF, special operator*/
|
||||
#define EOF 0
|
||||
|
||||
/*1-59=>operators that generate code (entries in code gen optab)*/
|
||||
#define ADD 1
|
||||
#define SUB 2
|
||||
#define MULT 3
|
||||
#define DIV 4
|
||||
#define MOD 5
|
||||
#define RSH 6
|
||||
#define LSH 7
|
||||
#define AND 8
|
||||
#define OR 9
|
||||
#define XOR 10
|
||||
#define NOT 11
|
||||
#define UMINUS 12
|
||||
#define COMPL 13
|
||||
#define PREDEC 14
|
||||
#define PREINC 15
|
||||
#define POSTDEC 16
|
||||
#define POSTINC 17
|
||||
#define ASSIGN 18
|
||||
#define EQADD 19
|
||||
#define EQSUB 20
|
||||
#define EQMULT 21
|
||||
#define EQDIV 22
|
||||
#define EQMOD 23
|
||||
#define EQRSH 24
|
||||
#define EQLSH 25
|
||||
#define EQAND 26
|
||||
#define EQOR 27
|
||||
#define EQXOR 28
|
||||
#define FJSR 29
|
||||
#define EQUALS 30
|
||||
#define NEQUALS 31
|
||||
#define GREAT 32
|
||||
#define GREATEQ 33
|
||||
#define LESS 34
|
||||
#define LESSEQ 35
|
||||
#define INT2L 36
|
||||
#define LONG2I 37
|
||||
|
||||
/*machine dependent operators that generate code*/
|
||||
#define BTST 38
|
||||
#define LOAD 39
|
||||
#define LMULT 40
|
||||
#define LDIV 41
|
||||
#define LMOD 42
|
||||
#define LEQMULT 43
|
||||
#define LEQDIV 44
|
||||
#define LEQMOD 45
|
||||
#define EQADDR 46
|
||||
#define LCGENOP 47 /*change if adding more operators...*/
|
||||
|
||||
/*intermediate code operators that do not generate code*/
|
||||
#define ADDR 60
|
||||
#define INDR 61
|
||||
#define LAND 62
|
||||
#define LOR 63
|
||||
#define QMARK 64
|
||||
#define COLON 65
|
||||
#define COMMA 66
|
||||
#define CINT 67
|
||||
#define CLONG 68
|
||||
#define SYMBOL 69
|
||||
#define AUTOINC 70
|
||||
#define AUTODEC 71
|
||||
#define CALL 72
|
||||
#define NACALL 73
|
||||
#define BFIELD 74
|
||||
#define IFGOTO 75
|
||||
#define INIT 76
|
||||
#define CFORREG 77
|
||||
#define DCLONG 78
|
||||
|
||||
/*operators local to parser*/
|
||||
#define CAST 80
|
||||
#define SEMI 81
|
||||
#define LCURBR 82
|
||||
#define RCURBR 83
|
||||
#define LBRACK 84
|
||||
#define RBRACK 85
|
||||
#define LPAREN 86
|
||||
#define RPAREN 87
|
||||
#define STRING 88
|
||||
#define RESWORD 89
|
||||
#define APTR 90
|
||||
#define PERIOD 91
|
||||
#define SIZEOF 92
|
||||
#define MPARENS 93
|
||||
#define STACKEND 100
|
||||
|
||||
/*data types*/
|
||||
#define TYPELESS 0
|
||||
#define CHAR 1
|
||||
#define SHORT 2
|
||||
#define INT 3
|
||||
#define LONG 4
|
||||
#define UCHAR 5
|
||||
#define USHORT 6
|
||||
#define UNSIGNED 7
|
||||
#define ULONG 8
|
||||
#define FLOAT 9
|
||||
#define DOUBLE 10
|
||||
|
||||
/*data types local to parser*/
|
||||
#define STRUCT 11
|
||||
#define FRSTRUCT 12
|
||||
#define LLABEL 13
|
||||
|
||||
/*type flags and definitions*/
|
||||
#define TYPE 017
|
||||
#define SUPTYP 060
|
||||
#define ALLTYPE 077
|
||||
#define POINTER 020
|
||||
#define FUNCTION 040
|
||||
#define ARRAY 060
|
||||
#define SUTYPLEN 2
|
||||
|
||||
/* data registers*/
|
||||
#define DREG2 2
|
||||
#define DREG3 3
|
||||
#define DREG4 4
|
||||
#define DREG5 5
|
||||
#define DREG6 6
|
||||
#define DREG7 7
|
||||
#define AREG3 11
|
||||
#define AREG4 12
|
||||
#define AREG5 13
|
||||
|
||||
/*storage classes*/
|
||||
#define AUTO 1
|
||||
#define REGISTER 2
|
||||
#define EXTERNAL 3
|
||||
#define STATIC 4
|
||||
#define REGOFF 5
|
||||
#define EXTOFF 6
|
||||
#define STATOFF 7
|
||||
#define INDEXED 8
|
||||
|
||||
/*exclusively code generator storage classes*/
|
||||
#define CINDR 9
|
||||
#define CLINDR 10
|
||||
|
||||
/*exclusively parser storage classes*/
|
||||
#define STRPROTO 9
|
||||
#define PDECLIST 10
|
||||
#define PARMLIST 11
|
||||
#define BFIELDCL 12
|
||||
#define UNELCL 13
|
||||
#define STELCL 14
|
||||
|
||||
|
||||
/*opinfo table bits*/
|
||||
#define OPPRI 077
|
||||
#define OPBIN 0100
|
||||
#define OPLVAL 0200
|
||||
#define OPREL 0400
|
||||
#define OPASSIGN 01000
|
||||
#define OPLWORD 02000
|
||||
#define OPRWORD 04000
|
||||
#define OPCOM 010000
|
||||
#define OPRAS 020000
|
||||
#define OPTERM 040000
|
||||
#define OPCONVS 0100000
|
||||
|
||||
/*68000 definitions*/
|
||||
#define PTRSIZE 4
|
||||
#define INTSIZE 2
|
||||
#define LONGSIZE 4
|
||||
#define SSIZE 8
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define BITSPBYTE 8
|
||||
|
||||
/*operator class priorities*/
|
||||
#define TRMPRI 0 /*terminal nodes*/
|
||||
#define RPNPRI 1 /*) and ]*/
|
||||
#define CALPRI 2 /*in-stack call, ( or [*/
|
||||
#define COLPRI 3 /*init or case priority for : or ,*/
|
||||
#define STKPRI 4 /*priority of end of stack*/
|
||||
#define COMPRI 5 /*normal priority for ,*/
|
||||
#define ASGPRI 6 /*=, +=, -=, *=, /=, %=, ...*/
|
||||
#define QMKPRI 7 /*?:*/
|
||||
#define LORPRI 8 /*||*/
|
||||
#define LNDPRI 9 /*&&*/
|
||||
#define ORPRI 10 /*|, !*/
|
||||
#define ANDPRI 11 /*&*/
|
||||
#define EQLPRI 12 /*==, !=*/
|
||||
#define RELPRI 13 /*>, <, >=, <=*/
|
||||
#define SHFPRI 14 /*<<, >>*/
|
||||
#define ADDPRI 15 /*+, -*/
|
||||
#define MULPRI 16 /**, /, %*/
|
||||
#define UNOPRI 17 /*++, --, &, *, -, ~, sizeof*/
|
||||
#define LPNPRI 18 /*., ->, [, (, function call*/
|
||||
#define PSTPRI 19 /*in-stack post--, post++*/
|
||||
|
||||
struct io_buf {
|
||||
int io_fd;
|
||||
int io_nc;
|
||||
char *io_p;
|
||||
char io_b[512];
|
||||
};
|
||||
struct { int hiword; int loword; };
|
||||
#define EXPSIZE 1024
|
||||
int exprarea[EXPSIZE] = {0};
|
||||
|
||||
#define NODEBUG 1
|
||||
|
||||
|
||||
|
||||
char brtab[][2];
|
||||
int invrel[];
|
||||
int swaprel[];
|
||||
char *strtab[];
|
||||
char null[]={0};
|
||||
|
||||
/*operator tree node for unary and binary operators*/
|
||||
struct tnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*data type of result*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
struct tnode *t_left; /*left sub-tree*/
|
||||
struct tnode *t_right; /*right sub-tree (undefined if unary)*/
|
||||
};
|
||||
|
||||
/*constant terminal node*/
|
||||
struct conode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_value; /*value or label number*/
|
||||
};
|
||||
|
||||
struct lconode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
long t_lvalue; /*value or label number*/
|
||||
};
|
||||
|
||||
/*local symbol terminal node*/
|
||||
struct symnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*symbol data type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_sc; /*storage class*/
|
||||
int t_offset; /*register offset*/
|
||||
int t_reg; /*register number*/
|
||||
int t_label; /*label number if static*/
|
||||
};
|
||||
|
||||
/*external symbol reference node*/
|
||||
struct extnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*symbol data type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_sc; /*storage class*/
|
||||
int t_offset; /*register offset*/
|
||||
int t_reg; /*register number*/
|
||||
char t_symbol[SSIZE]; /*symbol name*/
|
||||
};
|
||||
|
||||
/*68000 special - indexed symbol node*/
|
||||
/*this is used to generate a An(off,Xn.type) address*/
|
||||
struct indexnode {
|
||||
int t_op;
|
||||
int t_type;
|
||||
int t_su;
|
||||
int t_ssp;
|
||||
int t_sc;
|
||||
int t_offset;
|
||||
int t_reg;
|
||||
int t_xreg;
|
||||
int t_xtype;
|
||||
};
|
||||
|
||||
int lflag=0;
|
||||
int dflag=0;
|
||||
int mflag=0;
|
||||
int cflag=0;
|
||||
int eflag=0;
|
||||
int fflag=0;
|
||||
int oflag=0;
|
||||
struct io_buf ibuf = {0},
|
||||
obuf = {0};
|
||||
int lineno=0;
|
||||
int naregs=0;
|
||||
int ndregs=0;
|
||||
int errcnt=0;
|
||||
int opinfo[];
|
||||
int nextlabel;
|
||||
char null[];
|
||||
char optab[][6];
|
||||
char *mnemonics[];
|
||||
char *codeskels[];
|
||||
int stacksize;
|
||||
|
||||
char *tnalloc();
|
||||
char *snalloc();
|
||||
char *cenalloc();
|
||||
char *xnalloc();
|
||||
char *talloc();
|
||||
char *cnalloc();
|
||||
char *lcnalloc();
|
||||
char *canon();
|
||||
char *commute();
|
||||
char *constant();
|
||||
char *match();
|
||||
char *addptree();
|
||||
char *fixbfield();
|
||||
char *coffset();
|
||||
char *tcopy();
|
||||
#define wallign(add) ((add+1)&(~1))
|
||||
#define array(type) ((type&SUPTYP)==ARRAY)
|
||||
#define function(type) ((type&SUPTYP)==FUNCTION)
|
||||
#define pointer(type) ((type&SUPTYP)==POINTER)
|
||||
#define notarray(type) ((type&SUPTYP)!=ARRAY)
|
||||
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
|
||||
#define notpointer(type) ((type&SUPTYP)!=POINTER)
|
||||
#define btype(type) (type&TYPE)
|
||||
#define suptype(type) (type&SUPTYP)
|
||||
#define alltype(type) (type&(SUPTYP|TYPE))
|
||||
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
|
||||
#define relop(op) ((opinfo[op]&OPREL)!=0)
|
||||
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
|
||||
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
|
||||
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
|
||||
#define binop(op) ((opinfo[op]&OPBIN)!=0)
|
||||
#define unaryop(op) ((opinfo[op]&(OPBIN|OPTERM))==0)
|
||||
#define leafop(op) ((opinfo[op]&OPTERM)!=0)
|
||||
#define notleafop(op) ((opinfo[op]&OPTERM)==0)
|
||||
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
|
||||
#define oppriority(op) (opinfo[op]&OPPRI)
|
||||
#define commop(op) ((opinfo[op]&OPCOM)!=0)
|
||||
#define convop(op) ((opinfo[op]&OPCONVS)!=0)
|
||||
#define notconvop(op) ((opinfo[op]&OPCONVS)==0)
|
||||
#define max(a,b) (a>b?a:b)
|
||||
#define min(a,b) (a<b?a:b)
|
||||
|
||||
#define QUICKVAL 8
|
||||
#define LEP 14
|
||||
#define FORCC 1
|
||||
#define FOREFF 2
|
||||
#define FORSTACK 3
|
||||
#define FORCREG 4
|
||||
#define FORSP 5
|
||||
#define FORREG 4
|
||||
#define HICREG 2
|
||||
#define NCREGS 3
|
||||
#define AREGLO 8
|
||||
#define IMMED 1
|
||||
#define NOTIMMED 0
|
||||
#define LOFFSET 2
|
||||
#define NOTLOFFSET 0
|
||||
|
||||
int bol=0;
|
||||
int errflg=0;
|
||||
int onepass=0;
|
||||
char *opap=0;
|
||||
int stacksize=0;
|
||||
|
||||
fflush(fp)
|
||||
char *fp;
|
||||
{
|
||||
return(myfflush(fp));
|
||||
}
|
||||
381
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/init.vms
Normal file
381
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/init.vms
Normal file
@@ -0,0 +1,381 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/*intermediate code operators*/
|
||||
/*0=>EOF, special operator*/
|
||||
#define EOF 0
|
||||
|
||||
/*1-59=>operators that generate code (entries in code gen optab)*/
|
||||
#define ADD 1
|
||||
#define SUB 2
|
||||
#define MULT 3
|
||||
#define DIV 4
|
||||
#define MOD 5
|
||||
#define RSH 6
|
||||
#define LSH 7
|
||||
#define AND 8
|
||||
#define OR 9
|
||||
#define XOR 10
|
||||
#define NOT 11
|
||||
#define UMINUS 12
|
||||
#define COMPL 13
|
||||
#define PREDEC 14
|
||||
#define PREINC 15
|
||||
#define POSTDEC 16
|
||||
#define POSTINC 17
|
||||
#define ASSIGN 18
|
||||
#define EQADD 19
|
||||
#define EQSUB 20
|
||||
#define EQMULT 21
|
||||
#define EQDIV 22
|
||||
#define EQMOD 23
|
||||
#define EQRSH 24
|
||||
#define EQLSH 25
|
||||
#define EQAND 26
|
||||
#define EQOR 27
|
||||
#define EQXOR 28
|
||||
#define FJSR 29
|
||||
#define EQUALS 30
|
||||
#define NEQUALS 31
|
||||
#define GREAT 32
|
||||
#define GREATEQ 33
|
||||
#define LESS 34
|
||||
#define LESSEQ 35
|
||||
#define INT2L 36
|
||||
#define LONG2I 37
|
||||
|
||||
/*machine dependent operators that generate code*/
|
||||
#define BTST 38
|
||||
#define LOAD 39
|
||||
#define LMULT 40
|
||||
#define LDIV 41
|
||||
#define LMOD 42
|
||||
#define LEQMULT 43
|
||||
#define LEQDIV 44
|
||||
#define LEQMOD 45
|
||||
#define EQADDR 46
|
||||
#define LCGENOP 47 /*change if adding more operators...*/
|
||||
|
||||
/*intermediate code operators that do not generate code*/
|
||||
#define ADDR 60
|
||||
#define INDR 61
|
||||
#define LAND 62
|
||||
#define LOR 63
|
||||
#define QMARK 64
|
||||
#define COLON 65
|
||||
#define COMMA 66
|
||||
#define CINT 67
|
||||
#define CLONG 68
|
||||
#define SYMBOL 69
|
||||
#define AUTOINC 70
|
||||
#define AUTODEC 71
|
||||
#define CALL 72
|
||||
#define NACALL 73
|
||||
#define BFIELD 74
|
||||
#define IFGOTO 75
|
||||
#define INIT 76
|
||||
#define CFORREG 77
|
||||
#define DCLONG 78
|
||||
|
||||
/*operators local to parser*/
|
||||
#define CAST 80
|
||||
#define SEMI 81
|
||||
#define LCURBR 82
|
||||
#define RCURBR 83
|
||||
#define LBRACK 84
|
||||
#define RBRACK 85
|
||||
#define LPAREN 86
|
||||
#define RPAREN 87
|
||||
#define STRING 88
|
||||
#define RESWORD 89
|
||||
#define APTR 90
|
||||
#define PERIOD 91
|
||||
#define SIZEOF 92
|
||||
#define MPARENS 93
|
||||
#define STACKEND 100
|
||||
|
||||
/*data types*/
|
||||
#define TYPELESS 0
|
||||
#define CHAR 1
|
||||
#define SHORT 2
|
||||
#define INT 3
|
||||
#define LONG 4
|
||||
#define UCHAR 5
|
||||
#define USHORT 6
|
||||
#define UNSIGNED 7
|
||||
#define ULONG 8
|
||||
#define FLOAT 9
|
||||
#define DOUBLE 10
|
||||
|
||||
/*data types local to parser*/
|
||||
#define STRUCT 11
|
||||
#define FRSTRUCT 12
|
||||
#define LLABEL 13
|
||||
|
||||
/*type flags and definitions*/
|
||||
#define TYPE 017
|
||||
#define SUPTYP 060
|
||||
#define ALLTYPE 077
|
||||
#define POINTER 020
|
||||
#define FUNCTION 040
|
||||
#define ARRAY 060
|
||||
#define SUTYPLEN 2
|
||||
|
||||
/* data registers*/
|
||||
#define DREG2 2
|
||||
#define DREG3 3
|
||||
#define DREG4 4
|
||||
#define DREG5 5
|
||||
#define DREG6 6
|
||||
#define DREG7 7
|
||||
#define AREG3 11
|
||||
#define AREG4 12
|
||||
#define AREG5 13
|
||||
|
||||
/*storage classes*/
|
||||
#define AUTO 1
|
||||
#define REGISTER 2
|
||||
#define EXTERNAL 3
|
||||
#define STATIC 4
|
||||
#define REGOFF 5
|
||||
#define EXTOFF 6
|
||||
#define STATOFF 7
|
||||
#define INDEXED 8
|
||||
|
||||
/*exclusively code generator storage classes*/
|
||||
#define CINDR 9
|
||||
#define CLINDR 10
|
||||
|
||||
/*exclusively parser storage classes*/
|
||||
#define STRPROTO 9
|
||||
#define PDECLIST 10
|
||||
#define PARMLIST 11
|
||||
#define BFIELDCL 12
|
||||
#define UNELCL 13
|
||||
#define STELCL 14
|
||||
|
||||
|
||||
/*opinfo table bits*/
|
||||
#define OPPRI 077
|
||||
#define OPBIN 0100
|
||||
#define OPLVAL 0200
|
||||
#define OPREL 0400
|
||||
#define OPASSIGN 01000
|
||||
#define OPLWORD 02000
|
||||
#define OPRWORD 04000
|
||||
#define OPCOM 010000
|
||||
#define OPRAS 020000
|
||||
#define OPTERM 040000
|
||||
#define OPCONVS 0100000
|
||||
|
||||
/*68000 definitions*/
|
||||
#define PTRSIZE 4
|
||||
#define INTSIZE 2
|
||||
#define LONGSIZE 4
|
||||
#define SSIZE 8
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define BITSPBYTE 8
|
||||
|
||||
/*operator class priorities*/
|
||||
#define TRMPRI 0 /*terminal nodes*/
|
||||
#define RPNPRI 1 /*) and ]*/
|
||||
#define CALPRI 2 /*in-stack call, ( or [*/
|
||||
#define COLPRI 3 /*init or case priority for : or ,*/
|
||||
#define STKPRI 4 /*priority of end of stack*/
|
||||
#define COMPRI 5 /*normal priority for ,*/
|
||||
#define ASGPRI 6 /*=, +=, -=, *=, /=, %=, ...*/
|
||||
#define QMKPRI 7 /*?:*/
|
||||
#define LORPRI 8 /*||*/
|
||||
#define LNDPRI 9 /*&&*/
|
||||
#define ORPRI 10 /*|, !*/
|
||||
#define ANDPRI 11 /*&*/
|
||||
#define EQLPRI 12 /*==, !=*/
|
||||
#define RELPRI 13 /*>, <, >=, <=*/
|
||||
#define SHFPRI 14 /*<<, >>*/
|
||||
#define ADDPRI 15 /*+, -*/
|
||||
#define MULPRI 16 /**, /, %*/
|
||||
#define UNOPRI 17 /*++, --, &, *, -, ~, sizeof*/
|
||||
#define LPNPRI 18 /*., ->, [, (, function call*/
|
||||
#define PSTPRI 19 /*in-stack post--, post++*/
|
||||
|
||||
struct io_buf {
|
||||
int io_fd;
|
||||
int io_nc;
|
||||
char *io_p;
|
||||
char io_b[512];
|
||||
};
|
||||
struct { int hiword; int loword; };
|
||||
#define EXPSIZE 1024
|
||||
int exprarea[EXPSIZE] = {0};
|
||||
|
||||
#define NODEBUG 1
|
||||
|
||||
|
||||
|
||||
char brtab[][2];
|
||||
int invrel[];
|
||||
int swaprel[];
|
||||
char *strtab[];
|
||||
char null[]={0};
|
||||
|
||||
/*operator tree node for unary and binary operators*/
|
||||
struct tnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*data type of result*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
struct tnode *t_left; /*left sub-tree*/
|
||||
struct tnode *t_right; /*right sub-tree (undefined if unary)*/
|
||||
};
|
||||
|
||||
/*constant terminal node*/
|
||||
struct conode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_value; /*value or label number*/
|
||||
};
|
||||
|
||||
struct lconode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
long t_lvalue; /*value or label number*/
|
||||
};
|
||||
|
||||
/*local symbol terminal node*/
|
||||
struct symnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*symbol data type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_sc; /*storage class*/
|
||||
int t_offset; /*register offset*/
|
||||
int t_reg; /*register number*/
|
||||
int t_label; /*label number if static*/
|
||||
};
|
||||
|
||||
/*external symbol reference node*/
|
||||
struct extnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*symbol data type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_sc; /*storage class*/
|
||||
int t_offset; /*register offset*/
|
||||
int t_reg; /*register number*/
|
||||
char t_symbol[SSIZE]; /*symbol name*/
|
||||
};
|
||||
|
||||
/*68000 special - indexed symbol node*/
|
||||
/*this is used to generate a An(off,Xn.type) address*/
|
||||
struct indexnode {
|
||||
int t_op;
|
||||
int t_type;
|
||||
int t_su;
|
||||
int t_ssp;
|
||||
int t_sc;
|
||||
int t_offset;
|
||||
int t_reg;
|
||||
int t_xreg;
|
||||
int t_xtype;
|
||||
};
|
||||
|
||||
int lflag=0;
|
||||
int dflag=0;
|
||||
int mflag=0;
|
||||
int cflag=0;
|
||||
int eflag=0;
|
||||
int fflag=0;
|
||||
int oflag=0;
|
||||
struct io_buf ibuf = {0},
|
||||
obuf = {0};
|
||||
int lineno=0;
|
||||
int naregs=0;
|
||||
int ndregs=0;
|
||||
int errcnt=0;
|
||||
int opinfo[];
|
||||
int nextlabel;
|
||||
char null[];
|
||||
char optab[][6];
|
||||
char *mnemonics[];
|
||||
char *codeskels[];
|
||||
int stacksize;
|
||||
|
||||
char *tnalloc();
|
||||
char *snalloc();
|
||||
char *cenalloc();
|
||||
char *xnalloc();
|
||||
char *talloc();
|
||||
char *cnalloc();
|
||||
char *lcnalloc();
|
||||
char *canon();
|
||||
char *commute();
|
||||
char *constant();
|
||||
char *match();
|
||||
char *addptree();
|
||||
char *fixbfield();
|
||||
char *coffset();
|
||||
char *tcopy();
|
||||
#define wallign(add) ((add+1)&(~1))
|
||||
#define array(type) ((type&SUPTYP)==ARRAY)
|
||||
#define function(type) ((type&SUPTYP)==FUNCTION)
|
||||
#define pointer(type) ((type&SUPTYP)==POINTER)
|
||||
#define notarray(type) ((type&SUPTYP)!=ARRAY)
|
||||
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
|
||||
#define notpointer(type) ((type&SUPTYP)!=POINTER)
|
||||
#define btype(type) (type&TYPE)
|
||||
#define suptype(type) (type&SUPTYP)
|
||||
#define alltype(type) (type&(SUPTYP|TYPE))
|
||||
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
|
||||
#define relop(op) ((opinfo[op]&OPREL)!=0)
|
||||
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
|
||||
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
|
||||
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
|
||||
#define binop(op) ((opinfo[op]&OPBIN)!=0)
|
||||
#define unaryop(op) ((opinfo[op]&(OPBIN|OPTERM))==0)
|
||||
#define leafop(op) ((opinfo[op]&OPTERM)!=0)
|
||||
#define notleafop(op) ((opinfo[op]&OPTERM)==0)
|
||||
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
|
||||
#define oppriority(op) (opinfo[op]&OPPRI)
|
||||
#define commop(op) ((opinfo[op]&OPCOM)!=0)
|
||||
#define convop(op) ((opinfo[op]&OPCONVS)!=0)
|
||||
#define notconvop(op) ((opinfo[op]&OPCONVS)==0)
|
||||
#define max(a,b) (a>b?a:b)
|
||||
#define min(a,b) (a<b?a:b)
|
||||
|
||||
#define QUICKVAL 8
|
||||
#define LEP 14
|
||||
#define FORCC 1
|
||||
#define FOREFF 2
|
||||
#define FORSTACK 3
|
||||
#define FORCREG 4
|
||||
#define FORSP 5
|
||||
#define FORREG 4
|
||||
#define HICREG 2
|
||||
#define NCREGS 3
|
||||
#define AREGLO 8
|
||||
#define IMMED 1
|
||||
#define NOTIMMED 0
|
||||
#define LOFFSET 2
|
||||
#define NOTLOFFSET 0
|
||||
|
||||
int bol=0;
|
||||
int errflg=0;
|
||||
int onepass=0;
|
||||
char *opap=0;
|
||||
int stacksize=0;
|
||||
|
||||
fflush(fp)
|
||||
char *fp;
|
||||
{
|
||||
return(myfflush(fp));
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
fflush(fp)
|
||||
char *fp;
|
||||
{
|
||||
return(myfflush(fp));
|
||||
}
|
||||
char *null = "";
|
||||
137
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/interf.c
Normal file
137
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/interf.c
Normal file
@@ -0,0 +1,137 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
int bol;
|
||||
int onepass;
|
||||
|
||||
/* outexpr - output expression*/
|
||||
outexpr(tp) /* returns - none*/
|
||||
struct tnode *tp; /* pointer to tree node*/
|
||||
{
|
||||
if( dflag )
|
||||
outline();
|
||||
if( exprok(tp) )
|
||||
scodegen(canon(tp),FOREFF,0);
|
||||
}
|
||||
|
||||
outforreg(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
register int reg;
|
||||
|
||||
if( dflag )
|
||||
outline();
|
||||
if( exprok(tp) && (reg=scodegen(canon(tp),FORREG,0)) != 0 )
|
||||
outmovr(reg,0,tp);
|
||||
}
|
||||
|
||||
outifgoto(tp,dir,lab)
|
||||
struct tnode *tp;
|
||||
int dir;
|
||||
int lab;
|
||||
{
|
||||
if( dflag )
|
||||
outline();
|
||||
if( exprok(tp) )
|
||||
condbr(canon(tp),dir,lab,0);
|
||||
}
|
||||
|
||||
outinit(tp) /* returns - none*/
|
||||
struct tnode *tp;
|
||||
{
|
||||
register int typeout;
|
||||
|
||||
if( dflag )
|
||||
outline();
|
||||
if( exprok(tp) ) {
|
||||
typeout = tp->t_type;
|
||||
tp = canon(tp);
|
||||
if( tp->t_op == ADDR )
|
||||
tp = tp->t_left;
|
||||
if( tp->t_op == CINT || tp->t_op == SYMBOL ) {
|
||||
if( tp->t_op == SYMBOL )
|
||||
printf(".dc.l ");
|
||||
else {
|
||||
printf(".dc.");
|
||||
outtype(typeout);
|
||||
putchar(' ');
|
||||
}
|
||||
outaexpr(tp,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) == 0 )
|
||||
return(0);
|
||||
return( exprok(tp->t_left) );
|
||||
}
|
||||
|
||||
outline()
|
||||
{
|
||||
if( onepass && bol == 0 )
|
||||
putchar('\n');
|
||||
printf("*line %d\n",lineno);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
lo68 -r -s s.o canon.o codegen.o cskels.o interf.o main.o optab.o putexpr.o sucomp.o tabl.o util.o initx.o lib6.a
|
||||
ren c168.rel=c.out
|
||||
@@ -0,0 +1,45 @@
|
||||
$ num
|
||||
CANON.C
|
||||
CANON.lis
|
||||
$ num
|
||||
CODEGEN.C
|
||||
CODEGEN.lis
|
||||
$ num
|
||||
CSKELS.C
|
||||
CSKELS.lis
|
||||
$ num
|
||||
INIT.C
|
||||
INIT.lis
|
||||
$ num
|
||||
INITX.C
|
||||
INITX.lis
|
||||
$ num
|
||||
INTERF.C
|
||||
INTERF.lis
|
||||
$ num
|
||||
MAIN.C
|
||||
MAIN.lis
|
||||
$ num
|
||||
OPTAB.C
|
||||
OPTAB.lis
|
||||
$ num
|
||||
PUTEXPR.C
|
||||
PUTEXPR.lis
|
||||
$ num
|
||||
SUCOMP.C
|
||||
SUCOMP.lis
|
||||
$ num
|
||||
TABL.C
|
||||
TABL.lis
|
||||
$ num
|
||||
UTIL.C
|
||||
UTIL.lis
|
||||
$ num
|
||||
CGEN.H
|
||||
CGEN.lst
|
||||
$ num
|
||||
CSKEL.H
|
||||
CSKEL.lst
|
||||
$ num
|
||||
ICODE.H
|
||||
ICODE.lst
|
||||
392
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/main.c
Normal file
392
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/main.c
Normal file
@@ -0,0 +1,392 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
#include "cskel.h"
|
||||
char *opap;
|
||||
int errflg;
|
||||
int nextlabel 10000;
|
||||
char *readtree();
|
||||
char *readsym();
|
||||
|
||||
|
||||
/* main - main routine, handles arguments and files*/
|
||||
main(argc,argv) /* returns - none*/
|
||||
int argc; /* arg count*/
|
||||
char **argv; /* arg pointers*/
|
||||
{
|
||||
register char *q;
|
||||
register int i;
|
||||
|
||||
for( i = 3; i < argc; i++ ) {
|
||||
q = argv[i];
|
||||
if( *q++ != '-' )
|
||||
usage();
|
||||
while( 1 ) {
|
||||
switch( *q++ ) {
|
||||
|
||||
case 'D':
|
||||
case 'd':
|
||||
dflag++;
|
||||
continue;
|
||||
|
||||
case 'L':
|
||||
case 'l':
|
||||
lflag++;
|
||||
continue;
|
||||
|
||||
case 'e':
|
||||
case 'E':
|
||||
eflag++;
|
||||
continue;
|
||||
|
||||
case 'f':
|
||||
case 'F':
|
||||
fflag++;
|
||||
continue;
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
mflag++;
|
||||
continue;
|
||||
|
||||
case 'o':
|
||||
case 'O':
|
||||
oflag++;
|
||||
continue;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
cflag++;
|
||||
continue;
|
||||
|
||||
case '\0':
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( argc < 3 )
|
||||
usage();
|
||||
if( fopen(argv[1],&ibuf,0) < 0 )
|
||||
ferror("can't open %s\n",argv[1]);
|
||||
if( fcreat(argv[2],&obuf,0) < 0 )
|
||||
ferror("can't create %s\n",argv[2]);
|
||||
readicode();
|
||||
fflush(&obuf);
|
||||
exit(errcnt!=0);
|
||||
}
|
||||
|
||||
/* readicode - read intermediate code and dispatch output*/
|
||||
/* This copies assembler lines beginning with '(' to assembler*/
|
||||
/* output and builds trees starting with '.' line.*/
|
||||
readicode() /*returns - none*/
|
||||
{
|
||||
register int c;
|
||||
register struct tnode *tp;
|
||||
|
||||
while( (c=getc(&ibuf)) > 0 ) {
|
||||
switch(c) {
|
||||
|
||||
case '.':
|
||||
lineno = readint();
|
||||
opap = exprarea;
|
||||
if( tp = readtree() ) {
|
||||
#ifndef NODEBUG
|
||||
if( cflag )
|
||||
putexpr("readicode",tp);
|
||||
#endif
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case INIT:
|
||||
outinit(tp->t_left);
|
||||
break;
|
||||
|
||||
case IFGOTO:
|
||||
outifgoto(tp->t_left,tp->t_type,tp->t_su);
|
||||
break;
|
||||
|
||||
case CFORREG:
|
||||
outforreg(tp->t_left);
|
||||
break;
|
||||
|
||||
default:
|
||||
outexpr(tp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '(':
|
||||
while( (c=getc(&ibuf)) != '\n' )
|
||||
putchar(c);
|
||||
putchar(c);
|
||||
break;
|
||||
|
||||
default:
|
||||
error("intermediate code error");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* readtree - recursive intermediate code tree read*/
|
||||
char *readtree() /* returns ptr to expression tree*/
|
||||
{
|
||||
register int op, type, sc;
|
||||
register struct tnode *tp, *rtp;
|
||||
char sym[SSIZE];
|
||||
long l;
|
||||
|
||||
if( (op=readint()) <= 0 )
|
||||
return(0);
|
||||
type = readint();
|
||||
switch( op ) {
|
||||
|
||||
case SYMBOL:
|
||||
if( (sc=readint()) == EXTERNAL )
|
||||
tp = cenalloc(type,sc,readsym(sym));
|
||||
else
|
||||
tp = snalloc(type,sc,readint(),0,0);
|
||||
break;
|
||||
|
||||
case CINT:
|
||||
tp = cnalloc(type,readint());
|
||||
break;
|
||||
|
||||
case CLONG:
|
||||
l.hiword = readint();
|
||||
l.loword = readint();
|
||||
tp = lcnalloc(type,l);
|
||||
break;
|
||||
|
||||
case IFGOTO:
|
||||
case BFIELD:
|
||||
sc = readint();
|
||||
if( tp = readtree() )
|
||||
tp = tnalloc(op,type,sc,0,tp,null);
|
||||
break;
|
||||
|
||||
default:
|
||||
if( binop(op) ) {
|
||||
if( (tp=readtree()) == 0 )
|
||||
return(0);
|
||||
if( (rtp=readtree()) == 0 )
|
||||
return(0);
|
||||
tp = tnalloc(op,type,0,0,tp,rtp);
|
||||
}
|
||||
else if( tp = readtree() )
|
||||
tp = tnalloc(op,type,0,0,tp,null);
|
||||
break;
|
||||
}
|
||||
return(tp);
|
||||
}
|
||||
|
||||
/* readint - reads an integer value from intermediate code*/
|
||||
readint()
|
||||
{
|
||||
register int i, c;
|
||||
|
||||
i = 0;
|
||||
while(1) {
|
||||
switch( c = getc(&ibuf) ) {
|
||||
|
||||
case '.':
|
||||
case '\n':
|
||||
return(i);
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
i =<< 4;
|
||||
i =+ (c-'0');
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
i =<< 4;
|
||||
i =+ (c-('A'-10));
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
i =<< 4;
|
||||
i =+ (c-('a'-10));
|
||||
break;
|
||||
|
||||
default:
|
||||
error("intermediate code error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* readsym - read a symbol from intermediate code*/
|
||||
char *readsym(sym)
|
||||
char *sym;
|
||||
{
|
||||
register int i, c;
|
||||
register char *s;
|
||||
|
||||
for( i = SSIZE, s = sym; (c=getc(&ibuf)) != '\n'; )
|
||||
if( --i >= 0 )
|
||||
*s++ = c;
|
||||
if( i > 0 )
|
||||
*s = '\0';
|
||||
return(sym);
|
||||
}
|
||||
|
||||
/* error - output an error message*/
|
||||
error(s,x1,x2,x3,x4,x5,x6)
|
||||
char *s;
|
||||
int x1, x2, x3, x4, x5, x6;
|
||||
{
|
||||
errcnt++;
|
||||
errflg++;
|
||||
if( lineno != 0 )
|
||||
printf("** %d: ",lineno);
|
||||
printf(s,x1,x2,x3,x4,x5,x6);
|
||||
putchar('\n');
|
||||
errflg--;
|
||||
}
|
||||
|
||||
/* ferror - output error message and die*/
|
||||
ferror(s,x1,x2,x3,x4,x5,x6)
|
||||
char *s;
|
||||
int x1, x2, x3, x4, x5, x6;
|
||||
{
|
||||
error(s,x1,x2,x3,x4,x5,x6);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* tnalloc - allocate binary expression tree node*/
|
||||
char *tnalloc(op,type,info,dummy,left,right) /* returns ptr to node made*/
|
||||
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);
|
||||
}
|
||||
|
||||
/* talloc - allocate expression tree area*/
|
||||
char *talloc(size) /* returns pointer to area alloced*/
|
||||
int size; /* number of bytes to alloc*/
|
||||
{
|
||||
register char *p;
|
||||
|
||||
p = opap;
|
||||
if( p + size >= &exprarea[EXPSIZE] )
|
||||
ferror("expression too complex");
|
||||
opap = p + size;
|
||||
return(p);
|
||||
}
|
||||
|
||||
/* symcopy - copy symbol*/
|
||||
symcopy(sym1,sym2) /* returns - none*/
|
||||
char *sym1; /* from symbol*/
|
||||
char *sym2; /* to symbol*/
|
||||
{
|
||||
register char *p, *q;
|
||||
register int i;
|
||||
|
||||
for( p = sym1, q = sym2, i = SSIZE; --i >= 0; )
|
||||
*q++ = (*p ? *p++ : '\0');
|
||||
}
|
||||
|
||||
/* usage - ouput usage message*/
|
||||
usage()
|
||||
{
|
||||
ferror("usage: c168 icode asm [-DLmec]");
|
||||
}
|
||||
|
||||
/* outgoto - output "bra L[labno]"*/
|
||||
outgoto(lab)
|
||||
int lab;
|
||||
{
|
||||
if( lab > 0 )
|
||||
printf("bra L%d\n",lab);
|
||||
}
|
||||
|
||||
/* outlab - output "L[labno]:"*/
|
||||
outlab(lab)
|
||||
int lab;
|
||||
{
|
||||
if( lab > 0 )
|
||||
printf("L%d:",lab);
|
||||
}
|
||||
|
||||
/* putchar - special version*/
|
||||
/* This allows the use of printf for error messages, debugging*/
|
||||
/* output and normal output.*/
|
||||
putchar(c) /* returns - none*/
|
||||
char c; /* character to output*/
|
||||
{
|
||||
if( errflg ) /*error message?*/
|
||||
write(1,&c,1); /*write to standard output*/
|
||||
else {
|
||||
if( dflag > 1 )
|
||||
write(1,&c,1); /*to standard output*/
|
||||
putc(c,&obuf); /*put to assembler file*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
$ set def [steve.cpm68k.c.cgen]
|
||||
$ !
|
||||
$ cc68 CANON
|
||||
$ cc68 CODEGEN
|
||||
$ cc68 CSKELS
|
||||
$ cc68 INTERF
|
||||
$ cc68 MAIN
|
||||
$ cc68 OPTAB
|
||||
$ cc68 PUTEXPR
|
||||
$ cc68 SUCOMP
|
||||
$ cc68 TABL
|
||||
$ cc68 UTIL
|
||||
$ cc68 initx
|
||||
$ @relink
|
||||
100
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/make.sub
Normal file
100
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/make.sub
Normal file
@@ -0,0 +1,100 @@
|
||||
cp68 CANON.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic CANON.s -l
|
||||
as68 -l -u CANON.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era CANON.s
|
||||
|
||||
cp68 CODEGEN.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic CODEGEN.s -l
|
||||
as68 -l -u CODEGEN.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era CODEGEN.s
|
||||
|
||||
cp68 CSKELS.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic CSKELS.s -l
|
||||
as68 -l -u CSKELS.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era CSKELS.s
|
||||
|
||||
cp68 INTERF.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic INTERF.s -l
|
||||
as68 -l -u INTERF.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era INTERF.s
|
||||
|
||||
cp68 MAIN.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic MAIN.s -l
|
||||
as68 -l -u MAIN.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era MAIN.s
|
||||
|
||||
cp68 OPTAB.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic OPTAB.s -l
|
||||
as68 -l -u OPTAB.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era OPTAB.s
|
||||
|
||||
cp68 PUTEXPR.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic PUTEXPR.s -l
|
||||
as68 -l -u PUTEXPR.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era PUTEXPR.s
|
||||
|
||||
cp68 SUCOMP.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic SUCOMP.s -l
|
||||
as68 -l -u SUCOMP.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era SUCOMP.s
|
||||
|
||||
cp68 TABL.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic TABL.s -l
|
||||
as68 -l -u TABL.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era TABL.s
|
||||
|
||||
cp68 UTIL.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic UTIL.s -l
|
||||
as68 -l -u UTIL.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era UTIL.s
|
||||
|
||||
cp68 initx.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic initx.s -l
|
||||
as68 -l -u initx.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era initx.s
|
||||
|
||||
submit link
|
||||
259
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/optab.c
Normal file
259
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/optab.c
Normal file
@@ -0,0 +1,259 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
|
||||
#define I_NULL 0
|
||||
#define I_ADD 1
|
||||
#define I_INC 2
|
||||
#define I_SUB 3
|
||||
#define I_DEC 4
|
||||
#define I_MULS 5
|
||||
#define I_MULU 6
|
||||
#define I_DIVS 7
|
||||
#define I_DIVU 8
|
||||
#define I_ASR 9
|
||||
#define I_LSR 10
|
||||
#define I_ASL 11
|
||||
#define I_LSL 12
|
||||
#define I_AND 13
|
||||
#define I_OR 14
|
||||
#define I_EOR 15
|
||||
#define I_NEG 16
|
||||
#define I_NOT 17
|
||||
#define I_MOVE 18
|
||||
#define I_CLR 19
|
||||
#define I_CMP 20
|
||||
#define I_TST 21
|
||||
#define I_LMUL 22
|
||||
#define I_LDIV 23
|
||||
#define I_LREM 24
|
||||
#define I_LEML 25
|
||||
#define I_LEDV 26
|
||||
#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_LEMUL 29
|
||||
#define FR_EQADDR 30
|
||||
/*
|
||||
* You left these out, Bill.
|
||||
*/
|
||||
char fe_eqop[], fe_assign[], fe_eqshft[], fe_eqxor[], fe_eqaddr[];
|
||||
char fc_fix[], fc_rel[], fc_btst[];
|
||||
char fs_op[], fs_itl[], fs_ld[];
|
||||
char fr_op[], fr_mult[], fr_div[], fr_shft[], fr_xor[], fr_neg[],
|
||||
fr_eqop[], fr_postop[], fr_assign[], fr_eqmult[], fr_eqdiv[],
|
||||
fr_eqshft[], fr_eqxor[], fr_call[], fr_itl[], fr_lti[],
|
||||
fr_ld[], fr_lemul[], fr_eqaddr[];
|
||||
|
||||
char *codeskels[] {
|
||||
0,
|
||||
fe_eqop,
|
||||
fe_assign,
|
||||
fe_eqshft,
|
||||
fe_eqxor,
|
||||
fe_eqaddr,
|
||||
fc_fix,
|
||||
fc_rel,
|
||||
fc_btst,
|
||||
fs_op,
|
||||
fs_itl,
|
||||
fs_ld,
|
||||
fr_op,
|
||||
fr_mult,
|
||||
fr_div,
|
||||
fr_shft,
|
||||
fr_xor,
|
||||
fr_neg,
|
||||
fr_eqop,
|
||||
fr_postop,
|
||||
fr_assign,
|
||||
fr_eqmult,
|
||||
fr_eqdiv,
|
||||
fr_eqshft,
|
||||
fr_eqxor,
|
||||
fr_call,
|
||||
fr_itl,
|
||||
fr_lti,
|
||||
fr_ld,
|
||||
fr_lemul,
|
||||
fr_eqaddr,
|
||||
};
|
||||
|
||||
/*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, /*NULL*/
|
||||
I_ADD, I_INC, I_NULL, FC_FIX, FS_OP, FR_ADD, /*ADD*/
|
||||
I_SUB, I_DEC, I_NULL, FC_FIX, FS_OP, FR_ADD, /*SUB*/
|
||||
I_MULS, I_MULU, I_NULL, FC_FIX, I_NULL, FR_MULT, /*MULT*/
|
||||
I_DIVS, I_DIVU, I_NULL, FC_FIX, I_NULL, FR_DIV, /*DIV*/
|
||||
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*MOD*/
|
||||
I_ASR, I_LSR, I_NULL, FC_FIX, I_NULL, FR_SHFT, /*RSH*/
|
||||
I_ASL, I_LSL, I_NULL, FC_FIX, I_NULL, FR_SHFT, /*LSH*/
|
||||
I_AND, I_AND, I_NULL, FC_FIX, FS_OP, FR_ADD, /*AND*/
|
||||
I_OR, I_OR, I_NULL, FC_FIX, FS_OP, FR_ADD, /*OR*/
|
||||
I_EOR, I_EOR, I_NULL, FC_FIX, I_NULL, FR_XOR, /*XOR*/
|
||||
I_NULL, I_NULL, I_NULL, FC_FIX, I_NULL, I_NULL, /*NOT*/
|
||||
I_NEG, I_NEG, I_NULL, FC_FIX, I_NULL, FR_NEG, /*NEG*/
|
||||
I_NOT, I_NOT, I_NULL, I_NULL, I_NULL, FR_NEG, /*COMPL*/
|
||||
I_SUB, I_DEC, FE_EQOP, FC_FIX, I_NULL, FR_EQOP, /*PREDEC*/
|
||||
I_ADD, I_INC, FE_EQOP, FC_FIX, I_NULL, FR_EQOP, /*PREINC*/
|
||||
I_SUB, I_DEC, FE_EQOP, I_NULL, I_NULL, FR_POSTOP, /*POSTDEC*/
|
||||
I_ADD, I_INC, FE_EQOP, I_NULL, I_NULL, FR_POSTOP, /*POSTINC*/
|
||||
I_MOVE, I_CLR, FE_ASSIGN, I_NULL, I_NULL, FR_ASSIGN, /*ASSIGN*/
|
||||
I_ADD, I_INC, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*EQADD*/
|
||||
I_SUB, I_DEC, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*EQSUB*/
|
||||
I_MULS, I_MULU, I_NULL, FC_FIX, I_NULL, FR_EQMULT, /*EQMULT*/
|
||||
I_DIVS, I_DIVU, I_NULL, FC_FIX, I_NULL, FR_EQDIV, /*EQDIV*/
|
||||
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_EQDIV, /*EQMOD*/
|
||||
I_ASR, I_LSR, FE_EQSHFT, I_NULL, I_NULL, FR_EQSHFT, /*EQRSH*/
|
||||
I_ASL, I_LSL, FE_EQSHFT, I_NULL, I_NULL, FR_EQSHFT, /*EQLSH*/
|
||||
I_AND, I_AND, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*EQAND*/
|
||||
I_OR, I_OR, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*EQOR*/
|
||||
I_EOR, I_EOR, FE_EQXOR, FC_FIX, I_NULL, FR_EQXOR, /*EQXOR*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_CALL, /*FJSR*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*EQUALS*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*NEQUALS*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*GREAT*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*GREATEQ*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*LESS*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*LESSEQ*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, FS_ITL, FR_ITL, /*INT2L*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_LTI, /*LONG2I*/
|
||||
I_BTST, I_BTST, I_NULL, FC_BTST, I_NULL, I_NULL, /*BTST*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, FS_LD, FR_LD, /*LOAD*/
|
||||
I_MULS, I_LMUL, I_NULL, I_NULL, I_NULL, FR_MULT, /*LMULT*/
|
||||
I_DIVS, I_LDIV, I_NULL, I_NULL, I_NULL, FR_DIV, /*LDIV*/
|
||||
I_DIVS, I_LREM, I_NULL, I_NULL, I_NULL, FR_DIV, /*LMOD*/
|
||||
I_LEML, I_LEML, I_NULL, I_NULL, I_NULL, FR_LEMUL, /*LEQMULT*/
|
||||
I_LEDV, I_LEDV, I_NULL, I_NULL, I_NULL, FR_LEMUL, /*LEQDIV*/
|
||||
I_LERM, I_LERM, I_NULL, I_NULL, I_NULL, FR_LEMUL, /*LEQMOD*/
|
||||
I_NULL, I_NULL, FE_EQADDR, I_NULL, I_NULL, FR_EQADDR, /*EQADDR*/
|
||||
};
|
||||
|
||||
|
||||
/*this maps comparison operators and comparison types into the*/
|
||||
/*actual branch opcode used.*/
|
||||
char brtab[][2] {
|
||||
I_BEQ, I_BEQ, /*EQUALS*/
|
||||
I_BNE, I_BNE, /*NEQUALS*/
|
||||
I_BGT, I_BHI, /*GREAT*/
|
||||
I_BGE, I_BCC, /*GREATEQ*/
|
||||
I_BLT, I_BLO, /*LESS*/
|
||||
I_BLE, I_BLS, /*LESSEQ*/
|
||||
};
|
||||
|
||||
/*turns !x>y into x<=y*/
|
||||
int invrel[] { NEQUALS, EQUALS, LESSEQ, LESS, GREATEQ, GREAT };
|
||||
|
||||
/*turns x>y into y<=x*/
|
||||
int swaprel[] { EQUALS, NEQUALS, LESS, LESSEQ, GREAT, GREATEQ };
|
||||
|
||||
/*code skeleton built-in strings*/
|
||||
char *strtab[] {
|
||||
"move", /*MOV*/
|
||||
"move.l", /*MOVL*/
|
||||
"jsr", /*JSR*/
|
||||
"clr", /*CLR*/
|
||||
"clr.l", /*CLRL*/
|
||||
"ext.w", /*EXTW*/
|
||||
"ext.l", /*EXTL*/
|
||||
"lea", /*LEA*/
|
||||
"(sp)", /*STK*/
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* P R I N T F F U N C T I O N
|
||||
* -------------------------------
|
||||
*
|
||||
* The "printf" function is used to write data to the standard output.
|
||||
*
|
||||
* calling sequence:
|
||||
*
|
||||
* printf(format,arg1,arg2, ... argn);
|
||||
*
|
||||
* Where:
|
||||
*
|
||||
* format is a text string as described in K & R
|
||||
* Arg1-argn are optional arguments to be converted and
|
||||
* placed in the output
|
||||
*
|
||||
*****************************************************************************/
|
||||
__putc(fd,c) /* WSL is backwards!! */
|
||||
{ /****************************/
|
||||
putchar(c); /* Output character */
|
||||
} /****************************/
|
||||
printf (fmt,a1) /* Declare args */
|
||||
char *fmt; /* -> Format string */
|
||||
int a1; /* Whatever the right size */
|
||||
{ /****************************/
|
||||
_printf (0,__putc,fmt,&a1); /* Invoke secret routine */
|
||||
} /****************************/
|
||||
|
||||
252
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/putexpr.c
Normal file
252
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/putexpr.c
Normal file
@@ -0,0 +1,252 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
#ifndef NODEBUG
|
||||
|
||||
char invalid[] "INVALID";
|
||||
|
||||
char *opname[] {
|
||||
invalid, /*0*/
|
||||
"+", /*1*/
|
||||
"-", /*2*/
|
||||
"*", /*3*/
|
||||
"/", /*4*/
|
||||
"%", /*5*/
|
||||
">>", /*6*/
|
||||
"<<", /*7*/
|
||||
"&", /*8*/
|
||||
"|", /*9*/
|
||||
"^", /*10*/
|
||||
"!", /*11*/
|
||||
"U-", /*12*/
|
||||
"~", /*13*/
|
||||
"--p", /*14*/
|
||||
"++p", /*15*/
|
||||
"p--", /*16*/
|
||||
"p++", /*17*/
|
||||
"=", /*18*/
|
||||
"+=", /*19*/
|
||||
"-=", /*20*/
|
||||
"*=", /*21*/
|
||||
"/=", /*22*/
|
||||
"%=", /*23*/
|
||||
">>=", /*24*/
|
||||
"<<=", /*25*/
|
||||
"&=", /*26*/
|
||||
"|=", /*27*/
|
||||
"^=", /*28*/
|
||||
"jsr", /*29*/
|
||||
"==", /*30*/
|
||||
"!=", /*31*/
|
||||
">", /*32*/
|
||||
">=", /*33*/
|
||||
"<", /*34*/
|
||||
"<=", /*35*/
|
||||
"int->long", /*36*/
|
||||
"long->int", /*37*/
|
||||
"btst", /*38*/
|
||||
"load", /*39*/
|
||||
"long*", /*40*/
|
||||
"long/", /*41*/
|
||||
"long%", /*42*/
|
||||
"long*=", /*43*/
|
||||
"long/=", /*44*/
|
||||
"long%=", /*45*/
|
||||
"=addr", /*46*/
|
||||
invalid, /*47*/
|
||||
invalid, /*48*/
|
||||
invalid, /*49*/
|
||||
invalid, /*50*/
|
||||
invalid, /*51*/
|
||||
invalid, /*52*/
|
||||
invalid, /*53*/
|
||||
invalid, /*54*/
|
||||
invalid, /*55*/
|
||||
invalid, /*56*/
|
||||
invalid, /*57*/
|
||||
invalid, /*58*/
|
||||
invalid, /*59*/
|
||||
"U&", /*60*/
|
||||
"U*", /*61*/
|
||||
"&&", /*62*/
|
||||
"||", /*63*/
|
||||
"?", /*64*/
|
||||
":", /*65*/
|
||||
",", /*66*/
|
||||
"cint", /*67*/
|
||||
"clong", /*68*/
|
||||
"symbol", /*69*/
|
||||
"++a", /*70*/
|
||||
"a--", /*71*/
|
||||
"call", /*72*/
|
||||
"call()", /*73*/
|
||||
"bitfield", /*74*/
|
||||
"if", /*75*/
|
||||
"init", /*76*/
|
||||
"loadR0", /*77*/
|
||||
"divlong", /*78*/
|
||||
};
|
||||
|
||||
char *types[] {
|
||||
invalid, /*0=TYPELESS*/
|
||||
"char", /*1=CHAR*/
|
||||
invalid, /*2=SHORT*/
|
||||
"int", /*3=INT*/
|
||||
"long", /*4=LONG*/
|
||||
invalid, /*5=UCHAR*/
|
||||
invalid, /*6=USHORT*/
|
||||
"uint", /*7=UINT*/
|
||||
invalid, /*8=ULONG*/
|
||||
invalid, /*9=FLOAT*/
|
||||
invalid, /*10=DOUBLE*/
|
||||
"struct", /*11=STRUCT*/
|
||||
invalid, /*12=undefined*/
|
||||
invalid, /*13=undefined*/
|
||||
invalid, /*14=undefined*/
|
||||
invalid, /*15=undefined*/
|
||||
};
|
||||
|
||||
char *suvals[] {
|
||||
"zero",
|
||||
"one",
|
||||
"quick",
|
||||
"small",
|
||||
"constant",
|
||||
"Areg",
|
||||
"Dreg",
|
||||
"addressable",
|
||||
"loadable",
|
||||
"easy",
|
||||
"hard",
|
||||
};
|
||||
|
||||
int level;
|
||||
|
||||
putexpr(name,tp)
|
||||
char *name;
|
||||
struct tnode *tp;
|
||||
{
|
||||
printf("%s\n",name);
|
||||
putsexpr(tp);
|
||||
}
|
||||
|
||||
putsexpr(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
register struct tnode *ltp;
|
||||
|
||||
level++;
|
||||
ltp = tp->t_left;
|
||||
outlevel();
|
||||
printf("%s ",opname[tp->t_op]);
|
||||
if( tp->t_op == BFIELD || tp->t_op == IFGOTO ) {
|
||||
if( tp->t_op == BFIELD )
|
||||
printf("off=%d len=%d\n",(tp->t_su>>8)&0377,tp->t_su&0377);
|
||||
else
|
||||
printf("%s goto L%d\n",tp->t_type?"TRUE":"FALSE",tp->t_su);
|
||||
putsexpr(tp->t_left);
|
||||
level--;
|
||||
return;
|
||||
}
|
||||
puttsu(tp);
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case DCLONG:
|
||||
case CLONG:
|
||||
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:
|
||||
printf(" %x.%x\n",tp->t_offset,tp->t_ssp);
|
||||
break;
|
||||
|
||||
case REGOFF:
|
||||
printf(" %d(R%d)",tp->t_offset,tp->t_reg);
|
||||
break;
|
||||
|
||||
case EXTERNAL:
|
||||
case EXTOFF:
|
||||
printf(" %s+%d",tp->t_symbol,tp->t_offset);
|
||||
if( tp->t_sc == EXTOFF )
|
||||
printf("(R%d)",tp->t_reg);
|
||||
break;
|
||||
|
||||
case STATIC:
|
||||
case STATOFF:
|
||||
printf(" L%d+%d",tp->t_label,tp->t_offset);
|
||||
if( tp->t_sc == STATOFF )
|
||||
printf("(R%d)",tp->t_reg);
|
||||
break;
|
||||
|
||||
case INDEXED:
|
||||
printf(" %d(R%d,R%d)",tp->t_offset,tp->t_reg,tp->t_xreg);
|
||||
break;
|
||||
}
|
||||
putchar('\n');
|
||||
break;
|
||||
|
||||
case IFGOTO:
|
||||
putsexpr(tp->t_left);
|
||||
break;
|
||||
|
||||
default:
|
||||
putchar('\n');
|
||||
putsexpr(tp->t_left);
|
||||
if( binop(tp->t_op) )
|
||||
putsexpr(tp->t_right);
|
||||
break;
|
||||
}
|
||||
level--;
|
||||
}
|
||||
|
||||
outlevel()
|
||||
{
|
||||
register int i;
|
||||
|
||||
for( i = 0; i < level; i++ )
|
||||
putchar('\t');
|
||||
}
|
||||
|
||||
puttsu(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
register int i;
|
||||
|
||||
if( suptype(tp->t_type) )
|
||||
putchar('*');
|
||||
printf("%s ",types[btype(tp->t_type)]);
|
||||
if( tp->t_su != 0 || (tp->t_op == CINT && tp->t_value == 0) ) {
|
||||
i = tp->t_su >> 8;
|
||||
if( i > 15 || i < 0 )
|
||||
printf("INVALID");
|
||||
else
|
||||
printf("%s",suvals[tp->t_su>>8]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,8 @@
|
||||
$ set def [steve.cpm68k.c.cgen]
|
||||
$ set noon
|
||||
$ lo68 -r -s -o c168.out lib:startup.o canon.o codegen.o cskels.o interf.o -
|
||||
main.o optab.o putexpr.o sucomp.o tabl.o util.o initx.o lib:lib6.a
|
||||
$ conv :== $bin:conv
|
||||
$ conv
|
||||
c168.out
|
||||
[--.asc]c168.asc
|
||||
111
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/sucomp.c
Normal file
111
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/sucomp.c
Normal file
@@ -0,0 +1,111 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
#include "cskel.h"
|
||||
|
||||
/* sucomp - Sethy-Ullman expression complexity measure computation*/
|
||||
/* This is a heuristic computation of the Sethy-Ullman numbers*/
|
||||
/* for expressions. This gives an approximation of the complexity*/
|
||||
/* of the expression. The code generation scheme works best if*/
|
||||
/* the most complex expressions are done first.*/
|
||||
sucomp(tp,nregs,flag) /* returns - none*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
int nregs; /* number of registers left*/
|
||||
int flag; /* 1=>set values in tree, 0=>return*/
|
||||
{
|
||||
register int su, sur, op, i;
|
||||
register struct tnode *ltp, *rtp;
|
||||
|
||||
nregs = dreg(nregs);
|
||||
if( binop(op=tp->t_op) ) {
|
||||
ltp = tp->t_left;
|
||||
rtp = tp->t_right;
|
||||
}
|
||||
else if( unaryop(op) )
|
||||
ltp = tp->t_left;
|
||||
switch( op ) {
|
||||
|
||||
case CLONG:
|
||||
if( tp->t_lvalue >= 0x8000L || tp->t_lvalue <= 0xffff8000L ) {
|
||||
su = SU_ADDR;
|
||||
break;
|
||||
}
|
||||
i = tp->t_lvalue;
|
||||
case CINT:
|
||||
if( op == CINT )
|
||||
i = tp->t_value;
|
||||
if( i == 0 )
|
||||
su = SU_ZERO;
|
||||
else if( i == 1 )
|
||||
su = SU_ONE;
|
||||
else if( i >= 1 && i <= QUICKVAL )
|
||||
su = SU_SMALL;
|
||||
else if( i >= -128 && i <= 127 )
|
||||
su = SU_QUICK;
|
||||
else
|
||||
su = SU_CONST;
|
||||
break;
|
||||
|
||||
case COMMA:
|
||||
su = max(sucomp(rtp,nregs,flag),sucomp(ltp,nregs,flag));
|
||||
su = max(su,SU_EASY);
|
||||
break;
|
||||
|
||||
case ADDR:
|
||||
su = sucomp(ltp,nregs,flag);
|
||||
break;
|
||||
|
||||
case 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 LEQDIV:
|
||||
case LMOD:
|
||||
case LEQMOD:
|
||||
case CALL:
|
||||
case LMULT:
|
||||
case LEQMULT:
|
||||
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);
|
||||
break;
|
||||
}
|
||||
if( flag )
|
||||
tp->t_su = su;
|
||||
return(su);
|
||||
}
|
||||
119
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/tabl.c
Normal file
119
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/tabl.c
Normal file
@@ -0,0 +1,119 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
#define ASGOP OPRAS|OPASSIGN|OPLVAL|OPBIN
|
||||
|
||||
/*info on operators:*/
|
||||
/*000077-- OPPRI - priority*/
|
||||
/*000100-- OPBIN - binary operator*/
|
||||
/*000200-- OPLVAL - left operand must be lvalue*/
|
||||
/*000400-- OPREL - relational operator*/
|
||||
/*001000-- OPASSIGN - assignment operator*/
|
||||
/*002000-- OPLWORD - int required on left*/
|
||||
/*004000-- OPRWORD - int required on right*/
|
||||
/*010000-- OPCOM commutative*/
|
||||
/*020000-- OPRAS - right associative*/
|
||||
/*040000-- OPTERM - termination node*/
|
||||
/*100000 - OPCONVS - conversion operator*/
|
||||
int opinfo[] {
|
||||
TRMPRI, /*EOF*/
|
||||
ADDPRI|OPCOM|OPBIN, /*ADD - expr + expr*/
|
||||
ADDPRI|OPBIN, /*SUB - expr - expr*/
|
||||
MULPRI|OPCOM|OPBIN, /*MULT - expr * expr*/
|
||||
MULPRI|OPBIN, /*DIV - expr / expr*/
|
||||
MULPRI|OPBIN, /*MOD - expr % expr*/
|
||||
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*RSH - expr >> expr*/
|
||||
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*LSH - expr << expr*/
|
||||
ANDPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*AND - expr & expr*/
|
||||
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*OR - expr | expr*/
|
||||
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*XOR - expr ^ expr*/
|
||||
UNOPRI|OPRAS|OPLWORD, /*NOT - ! expr*/
|
||||
UNOPRI|OPRAS, /*UMINUS - - expr*/
|
||||
UNOPRI|OPRAS|OPLWORD, /*COMPL - ~ expr*/
|
||||
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREDEC - --lvalue*/
|
||||
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREINC - ++lvalue*/
|
||||
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTDEC - lvalue--*/
|
||||
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTINC - lvalue++*/
|
||||
ASGPRI|ASGOP, /*ASSIGN - lvalue = expr*/
|
||||
ASGPRI|ASGOP, /*EQADD - lvalue += expr*/
|
||||
ASGPRI|ASGOP, /*EQSUB - lvalue -= expr*/
|
||||
ASGPRI|ASGOP, /*EQMULT - lvalue *= expr*/
|
||||
ASGPRI|ASGOP, /*EQDIV - lvalue /= expr*/
|
||||
ASGPRI|ASGOP, /*EQMOD - lvalue %= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQRSH - lvalue >>= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQLSH - lvalue <<= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQAND - lvalue &= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQOR - lvalue |= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQXOR - lvalue ^= expr*/
|
||||
TRMPRI, /*FJSR - generate function jsr*/
|
||||
EQLPRI|OPREL|OPBIN, /*EQUALS - expr == expr*/
|
||||
EQLPRI|OPREL|OPBIN, /*NEQUALS - expr != expr*/
|
||||
RELPRI|OPREL|OPBIN, /*GREAT - expr > expr*/
|
||||
RELPRI|OPREL|OPBIN, /*GREATEQ - expr >= expr*/
|
||||
RELPRI|OPREL|OPBIN, /*LESS - expr < expr*/
|
||||
RELPRI|OPREL|OPBIN, /*LESSEQ - expr <= expr*/
|
||||
TRMPRI|OPCONVS, /*INT2L*/
|
||||
TRMPRI|OPCONVS, /*LONG2I*/
|
||||
TRMPRI|OPBIN, /*BTST*/
|
||||
TRMPRI, /*LOAD*/
|
||||
TRMPRI|OPBIN, /*LMULT*/
|
||||
TRMPRI|OPBIN, /*LDIV*/
|
||||
TRMPRI|OPBIN, /*LMOD*/
|
||||
TRMPRI|OPBIN, /*LEQMULT*/
|
||||
TRMPRI|OPBIN, /*LEQDIV*/
|
||||
TRMPRI|OPBIN, /*LEQMOD*/
|
||||
TRMPRI|ASGOP, /*EQADDR*/
|
||||
TRMPRI, /*unused - 47*/
|
||||
TRMPRI, /*unused - 48*/
|
||||
TRMPRI, /*unused - 49*/
|
||||
TRMPRI, /*unused - 50*/
|
||||
TRMPRI, /*unused - 51*/
|
||||
TRMPRI, /*unused - 52*/
|
||||
TRMPRI, /*unused - 53*/
|
||||
TRMPRI, /*unused - 54*/
|
||||
TRMPRI, /*unused - 55*/
|
||||
TRMPRI, /*unused - 56*/
|
||||
TRMPRI, /*unused - 57*/
|
||||
TRMPRI, /*unused - 58*/
|
||||
TRMPRI, /*unused - 59*/
|
||||
UNOPRI|OPRAS|OPLVAL, /*ADDR - & expr*/
|
||||
UNOPRI|OPRAS|OPLWORD, /*INDR - * expr*/
|
||||
LNDPRI|OPBIN, /*LAND - expr && expr*/
|
||||
LORPRI|OPBIN, /*LOR - expr || expr*/
|
||||
QMKPRI|OPRAS|OPBIN, /*QMARK - expr ? expr : expr*/
|
||||
QMKPRI|OPRAS|OPBIN, /*COLON*/
|
||||
COMPRI|OPBIN, /*COMMA*/
|
||||
TRMPRI|OPTERM, /*CINT*/
|
||||
TRMPRI|OPTERM, /*CLONG*/
|
||||
TRMPRI|OPTERM, /*SYMBOL*/
|
||||
TRMPRI|OPTERM, /*AUTOINC*/
|
||||
TRMPRI|OPTERM, /*AUTODEC*/
|
||||
LPNPRI|OPBIN, /*CALL - call with arguments*/
|
||||
LPNPRI, /*NACALL - no argument call*/
|
||||
TRMPRI, /*BFIELD - field selection*/
|
||||
TRMPRI, /*CONDBR*/
|
||||
TRMPRI, /*INIT*/
|
||||
TRMPRI, /*LOADREG*/
|
||||
TRMPRI|OPTERM, /*DCLONG - divide const long*/
|
||||
TRMPRI, /*unused - 79*/
|
||||
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 ()*/
|
||||
};
|
||||
387
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/util.c
Normal file
387
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/cgen/util.c
Normal file
@@ -0,0 +1,387 @@
|
||||
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
#include "cskel.h"
|
||||
|
||||
/* xnalloc - allocate address-indexed node*/
|
||||
char *xnalloc(type,ar,off,xr,xt) /* returns ptr to node alloced*/
|
||||
int type; /* data type*/
|
||||
int ar; /* address register*/
|
||||
int off; /* 8-bit offset*/
|
||||
int xr; /* index register*/
|
||||
int xt; /* index register type*/
|
||||
{
|
||||
register struct indexnode *xp;
|
||||
|
||||
xp = talloc(sizeof(*xp));
|
||||
xp->t_op = SYMBOL;
|
||||
xp->t_type = type;
|
||||
xp->t_sc = INDEXED;
|
||||
xp->t_reg = ar;
|
||||
xp->t_su = SU_ADDR;
|
||||
xp->t_offset = off;
|
||||
xp->t_xreg = xr;
|
||||
xp->t_xtype = xt;
|
||||
return(xp);
|
||||
}
|
||||
|
||||
/* tcopy - expression tree copy*/
|
||||
char *tcopy(tp) /* returns ptr to copied tree*/
|
||||
struct tnode *tp;
|
||||
{
|
||||
register char *p;
|
||||
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case SYMBOL:
|
||||
if( tp->t_sc == EXTERNAL || tp->t_sc == EXTOFF )
|
||||
p = cenalloc(tp->t_type,tp->t_sc,tp->t_symbol);
|
||||
else {
|
||||
p = snalloc(tp->t_type,tp->t_sc,tp->t_offset,0,0);
|
||||
p->t_label = tp->t_label;
|
||||
}
|
||||
p->t_offset = tp->t_offset;
|
||||
p->t_reg = tp->t_reg;
|
||||
return(p);
|
||||
|
||||
case CINT:
|
||||
return(cnalloc(tp->t_type,tp->t_value));
|
||||
|
||||
case CLONG:
|
||||
return(lcnalloc(tp->t_type,tp->t_lvalue));
|
||||
|
||||
case DCLONG:
|
||||
p = lcnalloc(tp->t_type,tp->t_lvalue);
|
||||
p->t_op = DCLONG;
|
||||
return(p);
|
||||
|
||||
default:
|
||||
if( binop(tp->t_op) )
|
||||
return(tnalloc(tp->t_op,tp->t_type,0,0,tcopy(tp->t_left),
|
||||
tcopy(tp->t_right)));
|
||||
if( unaryop(tp->t_op) )
|
||||
return(tnalloc(tp->t_op,tp->t_type,0,0,tcopy(tp->t_left),
|
||||
null));
|
||||
error("tcopy op=%d",tp->t_op);
|
||||
return(tp);
|
||||
}
|
||||
}
|
||||
|
||||
/* outaexpr - output address expression*/
|
||||
outaexpr(tp,flags) /* returns - none*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
int flags; /* flags (IMMED,LOFFSET,...)*/
|
||||
{
|
||||
register int off, reg, lab;
|
||||
long l;
|
||||
|
||||
if( tp->t_op == ADDR ) {
|
||||
tp = tp->t_left;
|
||||
putchar('#');
|
||||
}
|
||||
off = tp->t_offset;
|
||||
reg = tp->t_reg;
|
||||
lab = tp->t_label;
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case AUTOINC:
|
||||
printf("(R%d)+",reg);
|
||||
break;
|
||||
|
||||
case AUTODEC:
|
||||
printf("-(R%d)",reg);
|
||||
break;
|
||||
|
||||
case CINT:
|
||||
if( flags & IMMED )
|
||||
putchar('#');
|
||||
printf("%d",tp->t_value);
|
||||
break;
|
||||
|
||||
case DCLONG:
|
||||
case CLONG:
|
||||
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 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:
|
||||
l.hiword = tp->t_offset;
|
||||
l.loword = tp->t_ssp;
|
||||
outlval(l);
|
||||
break;
|
||||
|
||||
default:
|
||||
error("invalid storage class %d\n",tp->t_sc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error("invalid operator %d\n",tp->t_op);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* outlval - output long value*/
|
||||
/* This is a big pain because the PDP-11 doesn't do long divides*/
|
||||
/* in hardware.*/
|
||||
outlval(lval)
|
||||
long lval;
|
||||
{
|
||||
char digs[8];
|
||||
register int i, c;
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
digs[i++] = lval & 0xf;
|
||||
lval =>> 4;
|
||||
lval =& 0xfffffff;
|
||||
} while ( lval );
|
||||
putchar('$');
|
||||
while( --i >= 0 ) {
|
||||
c = digs[i];
|
||||
putchar(c>=10?c+('a'-10):c+'0');
|
||||
}
|
||||
}
|
||||
|
||||
/* outtype - output 68000 type (null, .b, .l) depending on data type*/
|
||||
outtype(type)
|
||||
int type;
|
||||
{
|
||||
if( 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) )
|
||||
printf(".l");
|
||||
}
|
||||
|
||||
/* outext - output register sign extension*/
|
||||
outext(reg)
|
||||
int reg;
|
||||
{
|
||||
printf("ext.l R%d\n",reg);
|
||||
}
|
||||
|
||||
/* outuext - output unsigned to long register extension*/
|
||||
outuext(reg)
|
||||
int reg;
|
||||
{
|
||||
printf("swap R%d\nclr R%d\nswap R%d\n",reg,reg,reg);
|
||||
}
|
||||
|
||||
/* 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) == 0 && longorptr(type) ) {
|
||||
if( unsign(tp->t_type) )
|
||||
outuext(reg);
|
||||
else
|
||||
outext(reg);
|
||||
}
|
||||
}
|
||||
|
||||
/* outswap - output swap register instruction*/
|
||||
outswap(reg)
|
||||
int reg;
|
||||
{
|
||||
printf("swap R%d\n",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);
|
||||
}
|
||||
|
||||
/* outaddr - output "add[type] R1,R2" instruction*/
|
||||
outaddr(r1,r2,tp)
|
||||
int r1;
|
||||
int r2;
|
||||
struct tnode *tp;
|
||||
{
|
||||
outrr("add",r1,r2,tp);
|
||||
}
|
||||
|
||||
/* outcmpm - output "cmpm[type] (R1)+,(R2)+"*/
|
||||
outcmpm(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
printf("cmpm");
|
||||
outtype(tp->t_left->t_type);
|
||||
printf(" (R%d)+,(R%d)+\n",tp->t_left->t_reg,tp->t_right->t_reg);
|
||||
}
|
||||
|
||||
/* outcreg - output reference to compiler temp register*/
|
||||
outcreg(reg)
|
||||
int reg;
|
||||
{
|
||||
if( dreg(reg) > HICREG )
|
||||
error("expression too complex");
|
||||
printf("R%d",reg);
|
||||
}
|
||||
|
||||
/* outcmp0 - output a compare with 0, special for address register*/
|
||||
outcmp0(reg,tp)
|
||||
int reg;
|
||||
struct tnode *tp;
|
||||
{
|
||||
if( isareg(reg) ) {
|
||||
printf("cmp");
|
||||
outatype(tp->t_type);
|
||||
printf(" #0,R%d\n",reg);
|
||||
}
|
||||
else {
|
||||
printf("tst");
|
||||
outtype(tp->t_type);
|
||||
printf(" R%d\n",reg);
|
||||
}
|
||||
}
|
||||
|
||||
/* outrpush - output "move[type] R1,[-](sp)"*/
|
||||
outrpush(reg,tp,pflag)
|
||||
int reg;
|
||||
struct tnode *tp;
|
||||
int pflag;
|
||||
{
|
||||
printf("move");
|
||||
outatype(tp->t_type);
|
||||
printf(" R%d,%c(sp)\n",reg,pflag?'-':'\0');
|
||||
}
|
||||
|
||||
/* popstack - output instruction to pop stack desired number of bytes*/
|
||||
/* Makes use of special case instructions to save a word.*/
|
||||
popstack(nb) /* returns - none*/
|
||||
int nb; /* number of bytes to pop*/
|
||||
{
|
||||
if( nb > 0 )
|
||||
printf("add #%d,sp\n",nb);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* outccsave - output instruction to move cc's to register.*/
|
||||
outccsave(reg)
|
||||
int reg;
|
||||
{
|
||||
printf("move sr,R%d\n",reg);
|
||||
}
|
||||
|
||||
/* outccrestore - output instruction to restore cc's from register*/
|
||||
outccrestore(reg)
|
||||
int reg;
|
||||
{
|
||||
printf("move R%d,ccr\n",reg);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
$ set def [steve.cpm68k.c.cgen]
|
||||
$ !
|
||||
$ cx CANON
|
||||
$ cx CODEGEN
|
||||
$ cx CSKELS
|
||||
$ cx INIT
|
||||
$ cx INTERF
|
||||
$ cx MAIN
|
||||
$ cx OPTAB
|
||||
$ cx PUTEXPR
|
||||
$ cx SUCOMP
|
||||
$ cx TABL
|
||||
$ cx UTIL
|
||||
$ @vrelink
|
||||
@@ -0,0 +1,3 @@
|
||||
$ set def [steve.cpm68k.c.cgen]
|
||||
$ clink canon,codegen,cskels,init,interf,main,optab,putexpr,sucomp,tabl,util,-
|
||||
lib:k3/lib c168'p1'
|
||||
@@ -0,0 +1,2 @@
|
||||
c68 -S test.c
|
||||
as68 -u -p test.s > test.asmlist
|
||||
@@ -0,0 +1,2 @@
|
||||
$ set def [steve.cpm68k.c.ctest]
|
||||
$ diff test.asm test.src
|
||||
@@ -0,0 +1,60 @@
|
||||
#include <math.h>
|
||||
|
||||
float *f1();
|
||||
float f2();
|
||||
|
||||
struct type {
|
||||
float ft;
|
||||
double dt;
|
||||
float *pft;
|
||||
} fstruc;
|
||||
|
||||
char *fstr = "-2.3E-4";
|
||||
char *astr = "8.6324";
|
||||
|
||||
main()
|
||||
{
|
||||
double d;
|
||||
float f, *fp;
|
||||
char *s, buf[20];
|
||||
long l;
|
||||
int i;
|
||||
|
||||
if ((fp = f1()) != fstruc.pft) error(0xf1);
|
||||
if ((f = f2()) != 2.0) error(0xf2);
|
||||
d = f;
|
||||
if (d != f) error(0xf3);
|
||||
f = atof(fstr);
|
||||
s = ftoa(f,buf,6);
|
||||
if (strcmp(s,"-0.000230") != 0) error(0xf4);
|
||||
f = 3.4;
|
||||
l = f;
|
||||
if (l != 3L) error(0xf5);
|
||||
i = f;
|
||||
if (i != 3) error(0xf6);
|
||||
f = l;
|
||||
if (f < 3.0) error(0xf7);
|
||||
f = i;
|
||||
if (f < 3.0) error(0xf8);
|
||||
f = atof(astr);
|
||||
printf("%s ==> ~ %f or %e\n",astr,f,f);
|
||||
printf("Far Freaking Out....\n");
|
||||
}
|
||||
|
||||
float *
|
||||
f1()
|
||||
{
|
||||
return(fstruc.pft);
|
||||
}
|
||||
|
||||
float
|
||||
f2()
|
||||
{
|
||||
return(2.0);
|
||||
}
|
||||
|
||||
error(enum)
|
||||
int enum;
|
||||
{
|
||||
printf("%x\n",enum);
|
||||
}
|
||||
1104
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/ctest/test.c
Normal file
1104
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/ctest/test.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
#define test2x
|
||||
@@ -0,0 +1,3 @@
|
||||
c68 -L *.c -n -o c168.st -l6 ; setstack c168.st 8192 8192
|
||||
c68 -L *.c -o c168.68 -l6 ; setstack c168.68 8192 8192
|
||||
cc *.c -o c168.11 -lx
|
||||
1006
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/canon.c
Normal file
1006
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/canon.c
Normal file
File diff suppressed because it is too large
Load Diff
189
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/cgen.h
Normal file
189
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/cgen.h
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "icode.h"
|
||||
|
||||
char brtab[][2];
|
||||
int invrel[];
|
||||
int swaprel[];
|
||||
char *strtab[];
|
||||
char null[];
|
||||
|
||||
/*operator tree node for unary and binary operators*/
|
||||
struct tnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*data type of result*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
struct tnode *t_left; /*left sub-tree*/
|
||||
struct tnode *t_right; /*right sub-tree (undefined if unary)*/
|
||||
};
|
||||
|
||||
/*constant terminal node*/
|
||||
struct conode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_value; /*value or label number*/
|
||||
};
|
||||
|
||||
struct lconode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
long t_lvalue; /*value or label number*/
|
||||
};
|
||||
|
||||
/*local symbol terminal node*/
|
||||
struct symnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*symbol data type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_sc; /*storage class*/
|
||||
int t_offset; /*register offset*/
|
||||
int t_reg; /*register number*/
|
||||
int t_label; /*label number if static*/
|
||||
};
|
||||
|
||||
/*external symbol reference node*/
|
||||
struct extnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*symbol data type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_sc; /*storage class*/
|
||||
int t_offset; /*register offset*/
|
||||
int t_reg; /*register number*/
|
||||
char t_symbol[SSIZE]; /*symbol name*/
|
||||
};
|
||||
|
||||
/*68000 special - indexed symbol node*/
|
||||
/*this is used to generate a An(off,Xn.type) address*/
|
||||
struct indexnode {
|
||||
int t_op;
|
||||
int t_type;
|
||||
int t_su;
|
||||
int t_ssp;
|
||||
int t_sc;
|
||||
int t_offset;
|
||||
int t_reg;
|
||||
int t_xreg;
|
||||
int t_xtype;
|
||||
};
|
||||
|
||||
int lflag;
|
||||
int dflag;
|
||||
int mflag;
|
||||
int cflag;
|
||||
int eflag;
|
||||
int fflag;
|
||||
int oflag;
|
||||
struct io_buf ibuf, obuf;
|
||||
int lineno;
|
||||
int naregs;
|
||||
int ndregs;
|
||||
int errcnt;
|
||||
int opinfo[];
|
||||
int nextlabel;
|
||||
char null[];
|
||||
char optab[][6];
|
||||
char *mnemonics[];
|
||||
char *codeskels[];
|
||||
int stacksize;
|
||||
|
||||
char *tnalloc();
|
||||
char *snalloc();
|
||||
char *cenalloc();
|
||||
char *xnalloc();
|
||||
char *talloc();
|
||||
char *cnalloc();
|
||||
char *lcnalloc();
|
||||
char *fpcnalloc();
|
||||
char *canon();
|
||||
char *commute();
|
||||
char *constant();
|
||||
char *match();
|
||||
char *addptree();
|
||||
char *fixbfield();
|
||||
char *coffset();
|
||||
char *tcopy();
|
||||
|
||||
#define wallign(add) ((add+1)&(~1))
|
||||
#define array(type) ((type&SUPTYP)==ARRAY)
|
||||
#define function(type) ((type&SUPTYP)==FUNCTION)
|
||||
#define pointer(type) ((type&SUPTYP)==POINTER)
|
||||
#define notarray(type) ((type&SUPTYP)!=ARRAY)
|
||||
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
|
||||
#define notpointer(type) ((type&SUPTYP)!=POINTER)
|
||||
#define isfloat(type) (type==FLOAT)
|
||||
#define btype(type) (type&TYPE)
|
||||
#define suptype(type) (type&SUPTYP)
|
||||
#define alltype(type) (type&(SUPTYP|TYPE))
|
||||
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
|
||||
#define relop(op) ((opinfo[op]&OPREL)!=0)
|
||||
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
|
||||
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
|
||||
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
|
||||
#define binop(op) ((opinfo[op]&OPBIN)!=0)
|
||||
#define unaryop(op) ((opinfo[op]&(OPBIN|OPTERM))==0)
|
||||
#define leafop(op) ((opinfo[op]&OPTERM)!=0)
|
||||
#define notleafop(op) ((opinfo[op]&OPTERM)==0)
|
||||
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
|
||||
#define oppriority(op) (opinfo[op]&OPPRI)
|
||||
#define commop(op) ((opinfo[op]&OPCOM)!=0)
|
||||
#define convop(op) ((opinfo[op]&OPCONVS)!=0)
|
||||
#define notconvop(op) ((opinfo[op]&OPCONVS)==0)
|
||||
#define max(a,b) (a>b?a:b)
|
||||
#define min(a,b) (a<b?a:b)
|
||||
|
||||
#define QUICKVAL 8
|
||||
#define LEP 14
|
||||
#define FORCC 1
|
||||
#define FOREFF 2
|
||||
#define FORSTACK 3
|
||||
#define FORCREG 4
|
||||
#define FORSP 5
|
||||
#define FORREG 4
|
||||
#define HICREG 2
|
||||
#define NCREGS 3
|
||||
#define AREGLO 8
|
||||
#define IMMED 1
|
||||
#define NOTIMMED 0
|
||||
#define NOTLOFFSET 0
|
||||
|
||||
/* one line routines turned into defines [vlh] for speed */
|
||||
|
||||
/*outgoto - output "bra L[labno]"*/
|
||||
#define outgoto(lab) if (lab>0) printf("bra L%d\n",lab)
|
||||
/*outlab - output "L[labno]:"*/
|
||||
#define outlab(lab) if (lab>0) printf("L%d:",lab)
|
||||
|
||||
/*outext - output register sign extension*/
|
||||
#define outext(reg) printf("ext.l R%d\n",reg)
|
||||
/*outuext - output unsigned to long register extension*/
|
||||
#define outuext(reg) printf("swap R%d\nclr R%d\nswap R%d\n",reg,reg,reg)
|
||||
/*outswap - output swap register instruction*/
|
||||
#define outswap(reg) printf("swap R%d\n",reg)
|
||||
/*outaddr - output "add [type] R1 R2" instruction*/
|
||||
#define outaddr(r1,r2,tp) outrr("add",r1,r2,(tp))
|
||||
/*outccsave - ouput instruction to move cc's to register*/
|
||||
#define outccsave(reg) printf("move sr,R%d\n",reg)
|
||||
/*outccrestore - output instruction to restore cc's from register*/
|
||||
#define outccrestore(reg) printf("move R%d,ccr\n",reg)
|
||||
/*basetype - get the btype info sans unsigned*/
|
||||
#define basetype(type) ((type==UNSIGNED) ? INT : type)
|
||||
#define unsign(type) ((type) == UNSIGNED)
|
||||
#define longorptr(type) (type==LONG || (type&SUPTYP))
|
||||
#define unorptr(type) (type==UNSIGNED || (type&SUPTYP))
|
||||
#define dreg(reg) ((reg) & (~AREGLO))
|
||||
#define areg(reg) ((reg) | AREGLO)
|
||||
#define isareg(reg) ((reg) >= AREGLO)
|
||||
#define isdreg(reg) ((reg) < AREGLO)
|
||||
#define isreg(tp) ((tp)->t_op == SYMBOL && (tp)->t_sc == REGISTER)
|
||||
@@ -0,0 +1,756 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
#include "cskel.h"
|
||||
|
||||
|
||||
/* scodegen - over-all code generation for expression*/
|
||||
/* Picks off post-fix ++, --.*/
|
||||
scodegen(tp,cookie,reg) /* returns register result is in*/
|
||||
struct tnode *tp;
|
||||
int cookie;
|
||||
int reg;
|
||||
{
|
||||
struct tnode *clist[20];
|
||||
struct tnode **clp;
|
||||
register struct tnode **cp;
|
||||
register int r;
|
||||
register int ccflag;
|
||||
register struct tnode *rtp;
|
||||
|
||||
if( tp->t_op == COMMA ) {
|
||||
scodegen(tp->t_left,FOREFF,reg);
|
||||
return(scodegen(tp->t_right,cookie,reg));
|
||||
}
|
||||
ccflag = 0;
|
||||
clp = clist;
|
||||
tp = addptree(tp,&clp);
|
||||
if( clp > clist ) {
|
||||
/*
|
||||
* post ++, -- in tree. We need to compile the tree post operators
|
||||
* then generate code to do the post operators, then do any fix up of
|
||||
* condition codes since the Stupid 68000 architect was a nimnul.
|
||||
*/
|
||||
if( cookie == FORCC ) {
|
||||
/*
|
||||
* here we make the observation that if we are comparing something with
|
||||
* zero OR the top operator of the tree is not a comparison operator,
|
||||
* we can compile the tree to a register, and then set the condition
|
||||
* codes OK with a tst instruction at the end.
|
||||
*/
|
||||
if( relop(tp->t_op) ) {
|
||||
if( (rtp=constant(tp->t_right)) && !rtp->t_value ) {
|
||||
ccflag = 1;
|
||||
tp = tp->t_left;
|
||||
cookie = FORREG;
|
||||
}
|
||||
else
|
||||
ccflag = 2;
|
||||
}
|
||||
else {
|
||||
ccflag = 1;
|
||||
cookie = FORREG;
|
||||
}
|
||||
}
|
||||
}
|
||||
r = codegen(tp,cookie,reg);
|
||||
if( clp > clist ) {
|
||||
if( ccflag == 2 )
|
||||
outccsave(r);
|
||||
for( cp = clist; cp < clp; cp++ )
|
||||
codegen(*cp,FOREFF,r+1);
|
||||
if( ccflag == 1 )
|
||||
outcmp0(r,tp);
|
||||
else if( ccflag == 2 )
|
||||
outccrestore(r);
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
||||
/* addptree - prune off postfix ++, -- from expression tree*/
|
||||
/* This prunes off ++, -- and collects those expressions for*/
|
||||
/* scodegen.*/
|
||||
char *addptree(tp,clp) /* returns pointer to pruned tree*/
|
||||
struct tnode *tp;
|
||||
struct tnode ***clp;
|
||||
{
|
||||
register int op;
|
||||
|
||||
op = tp->t_op;
|
||||
if( leafop(op) || op == QMARK ) /* [vlh] 4.0 QMARK... */
|
||||
return(tp);
|
||||
if( op == POSTINC || op == POSTDEC ) {
|
||||
*(*clp)++ = tp;
|
||||
return( tcopy(tp->t_left) );
|
||||
}
|
||||
if( binop(op) )
|
||||
tp->t_right = addptree(tp->t_right,clp);
|
||||
tp->t_left = addptree(tp->t_left,clp);
|
||||
return(tp);
|
||||
}
|
||||
|
||||
/* codegen - generate code for expression*/
|
||||
/* This calls up rcodegen, which prunes off any special register*/
|
||||
/* optimization code, then calls ucodegen (unrecursive) code*/
|
||||
/* generation.*/
|
||||
codegen(tp,cookie,reg) /* returns reg result is in*/
|
||||
struct tnode *tp; /* tree pointer*/
|
||||
int cookie; /* code generation goals*/
|
||||
int reg; /* first available register*/
|
||||
{
|
||||
register int size, savestk, ssize, r, i, scookie;
|
||||
register struct tnode *rtp;
|
||||
|
||||
#ifndef NODEBUG
|
||||
if( cflag )
|
||||
printf("codegen op=%d cookie=%d reg=%d\n",tp->t_op,cookie,reg);
|
||||
#endif
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case CALL:
|
||||
case NACALL:
|
||||
ssize = 0;
|
||||
savestk = stacksize;
|
||||
if( tp->t_left->t_op != SYMBOL )
|
||||
stacksize++;
|
||||
if( tp->t_op == CALL ) {
|
||||
rtp = tp->t_right;
|
||||
while( rtp->t_op == COMMA ) {
|
||||
ssize =+ dofarg(rtp->t_right);
|
||||
rtp = rtp->t_left;
|
||||
}
|
||||
ssize =+ dofarg(rtp);
|
||||
}
|
||||
tp->t_op = FJSR; /*generate JSR (unary op)*/
|
||||
codegen(tp,FORREG,reg);
|
||||
popstack(ssize);
|
||||
stacksize = savestk;
|
||||
fixresult(tp,cookie,0);
|
||||
return(0); /*result in R0*/
|
||||
|
||||
case COMMA:
|
||||
codegen(tp->t_left,FOREFF,reg);
|
||||
return(codegen(tp->t_right,cookie,reg));
|
||||
|
||||
case AND:
|
||||
if( cookie == FORCC && (i=isonebit(tp->t_right)) >= 0 &&
|
||||
(i=dobitadd(tp->t_left,i)) >= 0 ) {
|
||||
if( convop(tp->t_right->t_op) )
|
||||
tp->t_right = tp->t_right->t_left;
|
||||
tp->t_right->t_value = i;
|
||||
tp->t_op = BTST;
|
||||
tp = canon(tp);
|
||||
sucomp(tp,reg,1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if( rcodegen(&tp,cookie,reg) ) {
|
||||
if( cookie == FORCC && tp->t_op == SYMBOL && tp->t_sc == REGISTER
|
||||
&& isdreg(tp->t_reg))
|
||||
return(reg);
|
||||
}
|
||||
r = ucodegen(tp,cookie,reg);
|
||||
return(r);
|
||||
}
|
||||
|
||||
/* fixresult - fix result of code generation*/
|
||||
fixresult(tp,cookie,reg) /* returns - none*/
|
||||
struct tnode *tp;
|
||||
int cookie; /* wanted this cookie*/
|
||||
int reg;
|
||||
{
|
||||
#ifndef NODEBUG
|
||||
if (cflag)
|
||||
printf("fixresult cookie=%d reg=%d op=%d\n",cookie,reg,tp->t_op);
|
||||
#endif
|
||||
switch( cookie ) {
|
||||
|
||||
case FORCC:
|
||||
outcmp0(reg,tp);
|
||||
break;
|
||||
|
||||
case FORSP:
|
||||
case FORSTACK:
|
||||
stacksize++;
|
||||
outrpush(reg,tp,cookie==FORSTACK);
|
||||
break;
|
||||
|
||||
}
|
||||
return(reg);
|
||||
}
|
||||
|
||||
/* ucodegen - generate code for tree given cookie and starting register*/
|
||||
/* Handles the matching of the expression tree node with the*/
|
||||
/* corresponding code generation table. When a match is found,*/
|
||||
/* expand is called to expand the code skeleton macro.*/
|
||||
ucodegen(tp,cookie,reg) /* returns reg result is in*/
|
||||
struct tnode *tp; /* pointer to expression tree*/
|
||||
int cookie; /* (FORCC,FOREFF,FORREG,FORSTACK)*/
|
||||
int reg; /* first available register*/
|
||||
{
|
||||
register int r;
|
||||
register char *p;
|
||||
|
||||
#ifndef NODEBUG
|
||||
if(cflag)
|
||||
putexpr("ucodegen",tp);
|
||||
#endif
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case STASSIGN: /*[vlh]*/
|
||||
outstrcpy(codegen(tp->t_left,FORREG,areg(reg)),
|
||||
codegen(tp->t_right,FORREG,areg(reg+1)), tp->t_type);
|
||||
return(reg);
|
||||
break;
|
||||
|
||||
case SYMBOL:
|
||||
if( cookie == FOREFF )
|
||||
return(reg);
|
||||
break;
|
||||
|
||||
case LSH:
|
||||
if( (isareg(reg)) && (p=constant(tp->t_right)) &&
|
||||
!(unsign(tp->t_left->t_type)) &&
|
||||
(p->t_value == 1 || p->t_value == 2) ) {
|
||||
r = codegen(tp->t_left,FORREG,reg);
|
||||
outmovr(r,reg,tp->t_left);
|
||||
if( p->t_value == 2 )
|
||||
outaddr(reg,reg,tp);
|
||||
outaddr(reg,reg,tp);
|
||||
fixresult(tp,cookie,reg);
|
||||
return(reg);
|
||||
}
|
||||
break;
|
||||
|
||||
case EQMULT:
|
||||
case EQDIV:
|
||||
case LEQMULT:
|
||||
case LEQDIV:
|
||||
case EQMOD:
|
||||
case LEQMOD:
|
||||
case EQRSH:
|
||||
case EQLSH:
|
||||
case EQAND:
|
||||
case EQOR:
|
||||
case EQXOR:
|
||||
if( indexreg(tp->t_left) ) {
|
||||
reg = dreg(reg);
|
||||
outmovr(r=tp->t_left->t_reg,reg,tp);
|
||||
tp->t_left->t_reg = reg;
|
||||
codegen(tp,cookie,reg+1);
|
||||
outmovr(reg,r,tp);
|
||||
return(reg);
|
||||
}
|
||||
break;
|
||||
|
||||
case ADD:
|
||||
case EQADD:
|
||||
if( (p=constant(tp->t_right)) && p->t_value < 0 &&
|
||||
p->t_value >= -QUICKVAL ) {
|
||||
p->t_value = - p->t_value;
|
||||
tp->t_op =+ (SUB-ADD);
|
||||
}
|
||||
break;
|
||||
}
|
||||
sucomp(tp,reg,1);
|
||||
if( (r=loadexpr(tp,cookie,reg)) >= 0 )
|
||||
return(r);
|
||||
if( (r=cqmark(tp,cookie,reg)) >= 0 )
|
||||
return(r);
|
||||
if( (r=hardrel(tp,cookie,reg)) >= 0 )
|
||||
return(r);
|
||||
if( cookie == FORCC && (p=match(tp,FOREFF,reg)) != 0 ) {
|
||||
r = expand(tp,FOREFF,reg,p);
|
||||
if( asgop(tp->t_op) && indexreg(tp->t_left) )
|
||||
outcmp0(tp->t_left->t_reg,tp->t_left);
|
||||
}
|
||||
else if( p = match(tp,cookie,reg) )
|
||||
r = expand(tp,cookie,reg,p);
|
||||
else if( cookie != FORREG )
|
||||
r = fixresult(tp,cookie,ucodegen(tp,FORREG,reg));
|
||||
else
|
||||
error("no code table for %d",tp->t_op);
|
||||
return(r);
|
||||
}
|
||||
|
||||
/* outstrcpy - output structure copy */
|
||||
outstrcpy(lr,rr,size) /*[vlh]*/
|
||||
int lr, rr; /* left register, right register */
|
||||
int size; /* structure size to copy */
|
||||
{
|
||||
register int lab;
|
||||
lab = nextlabel++;
|
||||
printf("move #%d,r%d\n",(size/2)-1,dreg(lr));
|
||||
outlab(lab);
|
||||
printf("move (r%d)+,(r%d)+\ndbra r%d,L%d\n",rr,lr,dreg(lr),lab);
|
||||
}
|
||||
|
||||
/* loadexpr - load an addressable expression into a register*/
|
||||
/* This checks for any possible usage of the register indexed*/
|
||||
/* addressing mode. Note that this relies on the good graces of the*/
|
||||
/* load code skeletons not to muck up the compiler registers before*/
|
||||
/* loading an addressable expression...*/
|
||||
loadexpr(tp,cookie,reg) /* returns register loaded or -1*/
|
||||
struct tnode *tp; /* pointer to expression tree*/
|
||||
int reg; /* register to load*/
|
||||
{
|
||||
register struct tnode *rtp, *ltp, *xtp, *atp;
|
||||
register int off, r, type, nr, ar, xr, xt;
|
||||
|
||||
if( tp->t_op == INDR || LOADABLE(tp) ) {
|
||||
type = tp->t_type;
|
||||
if( tp->t_op == INDR && (ltp=tp->t_left)->t_op == ADD ) {
|
||||
rtp = ltp->t_right;
|
||||
ltp = ltp->t_left;
|
||||
off = 0;
|
||||
if( rtp->t_op == CINT && ((off=rtp->t_value) < -128 ||
|
||||
off > 127 || ltp->t_op != ADD ) ) {
|
||||
tp = snalloc(type,AUTO,off,0,0);
|
||||
if( indexreg(ltp) )
|
||||
tp->t_reg = ltp->t_reg;
|
||||
else {
|
||||
r = codegen(ltp,FORREG,areg(reg));
|
||||
if( isdreg(r) )
|
||||
outmovr(r,areg(r),ltp);
|
||||
tp->t_reg = areg(r);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if( rtp->t_op == CINT ) {
|
||||
rtp = ltp->t_right;
|
||||
ltp = ltp->t_left;
|
||||
}
|
||||
if(indexreg(rtp) || (!(indexreg(ltp)) && (isreg(rtp)))) {
|
||||
xtp = ltp;
|
||||
ltp = rtp;
|
||||
rtp = xtp;
|
||||
}
|
||||
xtp = atp = 0;
|
||||
if( indexreg(ltp) ) {
|
||||
ar = ltp->t_reg;
|
||||
if( (isreg(rtp)) && rtp->t_type != CHAR ) {
|
||||
xr = rtp->t_reg;
|
||||
xt = rtp->t_type;
|
||||
}
|
||||
else
|
||||
xtp = rtp;
|
||||
}
|
||||
else if( (isreg(ltp)) && ltp->t_type != CHAR &&
|
||||
(lflag || rtp->t_op != ADDR) ) {
|
||||
xr = ltp->t_reg;
|
||||
xt = ltp->t_type;
|
||||
atp = rtp;
|
||||
}
|
||||
else if( rtp->t_op == ADDR ) {
|
||||
atp = ltp;
|
||||
xtp = rtp;
|
||||
}
|
||||
else {
|
||||
atp = rtp;
|
||||
xtp = ltp;
|
||||
}
|
||||
nr = 0;
|
||||
if( atp )
|
||||
nr++;
|
||||
if( xtp && (xtp->t_op != ADDR || lflag ) )
|
||||
nr++;
|
||||
if( dreg(nr+reg) <= HICREG ) {
|
||||
r = reg;
|
||||
if( atp ) {
|
||||
ar = codegen(atp,FORREG,areg(r));
|
||||
if( isdreg(ar) ) {
|
||||
outmovr(ar,areg(ar),atp);
|
||||
ar = areg(ar);
|
||||
}
|
||||
r++;
|
||||
}
|
||||
if( xtp && xtp->t_op == ADDR && !lflag ) {
|
||||
tp = xtp->t_left;
|
||||
tp->t_sc =+ (EXTOFF-EXTERNAL);
|
||||
tp->t_offset =+ off;
|
||||
tp->t_reg = ar;
|
||||
}
|
||||
else {
|
||||
if( xtp ) {
|
||||
xr = codegen(xtp,FORREG,areg(r));
|
||||
xt = xtp->t_type;
|
||||
}
|
||||
tp = xnalloc(type,ar,off,xr,xt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( (isareg(reg)) && tp->t_type == CHAR )
|
||||
reg = dreg(reg);
|
||||
tp = tnalloc(LOAD,tp->t_type,SU_EASY,0,tp,null);
|
||||
return( codegen(tp,cookie,reg) );
|
||||
}
|
||||
return(-1);
|
||||
|
||||
}
|
||||
|
||||
/* coffset - check offset for addressable node*/
|
||||
char *coffset(tp) /* returns ptr to const off node*/
|
||||
struct tnode *tp; /* pointer to node*/
|
||||
{
|
||||
register struct tnode *rtp;
|
||||
|
||||
if( tp->t_op == ADD ) {
|
||||
rtp = tp->t_right;
|
||||
if( rtp->t_op == CINT )
|
||||
return(rtp);
|
||||
if(!lflag) {
|
||||
if( rtp->t_op == ADDR )
|
||||
return(rtp->t_left);
|
||||
rtp = tp->t_left;
|
||||
if( rtp->t_op == ADDR ) {
|
||||
tp->t_left = tp->t_right;
|
||||
tp->t_right = rtp;
|
||||
return(rtp->t_left);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* hardrel - do relationals returning a value*/
|
||||
hardrel(tp,cookie,reg) /* returns reg or -1*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
int cookie; /* cookie for code generation*/
|
||||
int reg; /* low register*/
|
||||
{
|
||||
char *p;
|
||||
int op, lab1, lab2;
|
||||
|
||||
if( cookie != FORCC && (relop(op=tp->t_op) || op == LOR ||
|
||||
op == LAND || op == NOT) ) {
|
||||
lab1 = nextlabel++;
|
||||
condbr(tp,TRUE,lab1,reg);
|
||||
p = canon(cnalloc(INT,0));
|
||||
codegen(p,cookie,reg);
|
||||
lab2 = nextlabel++;
|
||||
outgoto(lab2);
|
||||
outlab(lab1);
|
||||
p = canon(cnalloc(INT,1));
|
||||
codegen(p,cookie,reg);
|
||||
outlab(lab2);
|
||||
return(reg);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* cqmark - compile question mark operator*/
|
||||
/* This does the compilation of the question mark operator.*/
|
||||
cqmark(tp,cookie,reg) /* returns reg or -1*/
|
||||
struct tnode *tp;
|
||||
int cookie;
|
||||
int reg;
|
||||
{
|
||||
register int lab1, lab2, savestk, r;
|
||||
|
||||
if( tp->t_op == QMARK && cookie != FORCC ) {
|
||||
lab1 = nextlabel++;
|
||||
condbr(tp->t_left,FALSE,lab1,reg);
|
||||
savestk = stacksize;
|
||||
r = scodegen(tp->t_right->t_left,cookie,reg); /* [mc] 4.0 */
|
||||
outmovr(r,reg,tp);
|
||||
stacksize = savestk;
|
||||
outgoto(lab2=nextlabel++);
|
||||
outlab(lab1);
|
||||
r = scodegen(tp->t_right->t_right,cookie,reg); /* [mc] 4.0 */
|
||||
outmovr(r,reg,tp);
|
||||
outlab(lab2);
|
||||
return(reg);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* condbr - handle conditional branch code generation*/
|
||||
/* This handles the conditional branch code generation, handling*/
|
||||
/* the special cases for constants, ||, &&, ! and generating the*/
|
||||
/* correct conditional branch instruction.*/
|
||||
condbr(tp,dir,lab,reg)
|
||||
struct tnode *tp;
|
||||
int dir;
|
||||
int lab;
|
||||
int reg;
|
||||
{
|
||||
register struct tnode *ltp, *rtp;
|
||||
register int lab1, optype, op, subdir;
|
||||
|
||||
ltp = tp->t_left;
|
||||
if( binop(op=tp->t_op) )
|
||||
rtp = tp->t_right;
|
||||
subdir = dir; /*set up for LOR*/
|
||||
switch( op ) {
|
||||
|
||||
case CINT:
|
||||
if( !tp->t_value ) {
|
||||
if( dir == FALSE )
|
||||
outgoto(lab);
|
||||
}
|
||||
else if( dir != FALSE )
|
||||
outgoto(lab);
|
||||
break;
|
||||
|
||||
case NOT:
|
||||
condbr(ltp,!dir,lab,reg);
|
||||
break;
|
||||
|
||||
case LAND:
|
||||
dir = !dir;
|
||||
case LOR:
|
||||
if( dir == FALSE ) {
|
||||
lab1 = nextlabel++;
|
||||
condbr(ltp,!subdir,lab1,reg);
|
||||
condbr(rtp,subdir,lab,reg);
|
||||
outlab(lab1);
|
||||
}
|
||||
else {
|
||||
condbr(ltp,subdir,lab,reg);
|
||||
condbr(rtp,subdir,lab,reg);
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMA:
|
||||
scodegen(tp->t_left,FOREFF,reg);
|
||||
condbr(tp->t_right,dir,lab,reg);
|
||||
break;
|
||||
|
||||
default:
|
||||
if( op == NEQUALS && ltp->t_op == PREDEC &&
|
||||
isdreg(ltp->t_left->t_reg) && ltp->t_left->t_type == INT &&
|
||||
rtp->t_op == CINT && rtp->t_value == -1 ) {
|
||||
outdbra(ltp->t_left->t_reg,lab);
|
||||
break;
|
||||
}
|
||||
if( relop(op) && ltp->t_op == AUTOINC && rtp->t_op == AUTOINC &&
|
||||
ltp->t_type == rtp->t_type )
|
||||
outcmpm(tp);
|
||||
else
|
||||
scodegen(tp,FORCC,reg);
|
||||
optype = 0;
|
||||
if( relop(op) ) {
|
||||
if( unorptr(ltp->t_type) || unorptr(rtp->t_type) )
|
||||
optype =+ 1;
|
||||
}
|
||||
else
|
||||
op = NEQUALS;
|
||||
if(!dir)
|
||||
op = invrel[op-EQUALS];
|
||||
optype = brtab[op-EQUALS][optype];
|
||||
printf("%s L%d\n",mnemonics[optype],lab);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rcodegen(tpp,cookie,reg) /* returns changed flag*/
|
||||
struct tnode **tpp; /* pointer to tree*/
|
||||
int cookie; /* code generation cookie*/
|
||||
int reg; /* register to use for code*/
|
||||
{
|
||||
register int change, op;
|
||||
register struct tnode *tp;
|
||||
|
||||
tp = *tpp;
|
||||
op = tp->t_op;
|
||||
change = 0;
|
||||
if( notleafop(op) && op != COMMA ) {
|
||||
change =+ rcodegen(&tp->t_left,cookie,reg);
|
||||
if( binop(op) )
|
||||
change =+ rcodegen(&tp->t_right,cookie,reg);
|
||||
change =+ rcgen(tpp,cookie,reg);
|
||||
}
|
||||
if( change )
|
||||
*tpp = canon(*tpp);
|
||||
return(change);
|
||||
}
|
||||
|
||||
rcgen(tpp,cookie,reg) /* returns changed flag*/
|
||||
struct tnode **tpp; /* pointer to tree*/
|
||||
int cookie; /* code generation goals*/
|
||||
int reg; /* register to use*/
|
||||
{
|
||||
register struct tnode *tp, *p, *ltp, *rtp;
|
||||
register int op, change;
|
||||
|
||||
change = 0;
|
||||
for( tp = *tpp ; binop(op=tp->t_op); *tpp=tp=canon(tp), change++ ) {
|
||||
ltp = tp->t_left;
|
||||
if( ltp->t_op != SYMBOL )
|
||||
break;
|
||||
rtp = tp->t_right;
|
||||
switch( op ) {
|
||||
|
||||
case ASSIGN:
|
||||
if( ltp->t_sc != REGISTER )
|
||||
return(change);
|
||||
switch( rtp->t_op ) {
|
||||
|
||||
case MULT:
|
||||
case DIV:
|
||||
case MOD:
|
||||
case AND:
|
||||
case OR:
|
||||
case XOR:
|
||||
case LSH:
|
||||
case RSH:
|
||||
if( isareg(ltp->t_reg) )
|
||||
return(change);
|
||||
case ADD:
|
||||
case SUB:
|
||||
p = rtp->t_right;
|
||||
if(NOTADDRESSABLE(ltp) || !noref(rtp->t_right,ltp->t_reg))
|
||||
return(change);
|
||||
p = rtp->t_left;
|
||||
if( p->t_op != SYMBOL || p->t_sc != REGISTER ||
|
||||
p->t_reg != ltp->t_reg ) {
|
||||
tp->t_right = p;
|
||||
#ifndef NODEBUG
|
||||
if( cflag > 1 )
|
||||
putexpr("rcgen",tp);
|
||||
#endif
|
||||
codegen(tp,FOREFF,reg);
|
||||
}
|
||||
tp->t_right = rtp->t_right;
|
||||
tp->t_op = rtp->t_op + (EQADD-ADD);
|
||||
continue;
|
||||
}
|
||||
case EQLSH:
|
||||
case EQRSH:
|
||||
if( ltp->t_sc != REGISTER )
|
||||
return(change);
|
||||
case EQADD:
|
||||
case EQSUB:
|
||||
case EQAND:
|
||||
case EQOR:
|
||||
case EQXOR:
|
||||
if( ltp->t_type == CHAR )
|
||||
return(change);
|
||||
#ifndef NODEBUG
|
||||
if( cflag > 1 )
|
||||
putexpr("rcgen",tp);
|
||||
#endif
|
||||
ucodegen(tp,FOREFF,reg);
|
||||
tp = ltp;
|
||||
continue;
|
||||
|
||||
case PREDEC:
|
||||
case PREINC:
|
||||
if( cookie == FORCC || ltp->t_type == CHAR )
|
||||
return(change);
|
||||
ucodegen(tp,FOREFF,reg);
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return(change);
|
||||
}
|
||||
|
||||
noref(tp,reg) /* 4.0 change */
|
||||
struct tnode *tp; /* returns 1 if no reference in tree to reg */
|
||||
int reg;
|
||||
{
|
||||
if ( leafop(tp->t_op) ) {
|
||||
if (tp->t_op == SYMBOL && tp->t_sc == REGISTER && tp->t_reg == reg)
|
||||
return(0);
|
||||
return(1);
|
||||
}
|
||||
if ( !noref(tp->t_left,reg) )
|
||||
return(0);
|
||||
if (binop(tp->t_op))
|
||||
return( noref(tp->t_right,reg) );
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* cdsize - compute size of data item*/
|
||||
cdsize(tp) /* returns data size in bytes*/
|
||||
struct tnode *tp;
|
||||
{
|
||||
register int type;
|
||||
|
||||
type = tp->t_type;
|
||||
if( suptype(type) )
|
||||
return(PTRSIZE);
|
||||
switch( type ) {
|
||||
|
||||
case CHAR:
|
||||
case INT:
|
||||
case UNSIGNED:
|
||||
return(INTSIZE);
|
||||
|
||||
case LONG:
|
||||
case FLOAT: /* [vlh] 3.4 */
|
||||
return(LONGSIZE);
|
||||
}
|
||||
error("cdsize: invalid type %d",type);
|
||||
return(0);
|
||||
}
|
||||
|
||||
dofarg(tp) /* returns number of bytes pushed*/
|
||||
struct tnode *tp; /* pointer to expression tree*/
|
||||
{
|
||||
register int nb;
|
||||
|
||||
nb = 0;
|
||||
if( tp->t_op == SYMBOL && tp->t_sc == STRUCT )
|
||||
error("structure operation not implemented");
|
||||
else if( stacksize ) {
|
||||
codegen(tp,FORSTACK,0);
|
||||
nb = cdsize(tp);
|
||||
}
|
||||
else
|
||||
codegen(tp,FORSP,0);
|
||||
return( nb );
|
||||
}
|
||||
|
||||
/* dobitadd - do bit operation address checking and fixup*/
|
||||
dobitadd(tp,bitno) /* returns -1 if can't or bitno*/
|
||||
struct tnode *tp;
|
||||
int bitno;
|
||||
{
|
||||
register int offset;
|
||||
|
||||
if( tp->t_type == CHAR )
|
||||
offset = 0;
|
||||
else
|
||||
offset = cdsize(tp) - (bitno/BITSPBYTE) - 1;
|
||||
if( tp->t_op == SYMBOL ) {
|
||||
switch( tp->t_sc ) {
|
||||
|
||||
case REGISTER:
|
||||
if( isdreg(tp->t_reg) )
|
||||
return(bitno);
|
||||
default:
|
||||
return(-1);
|
||||
|
||||
case EXTERNAL:
|
||||
case STATIC:
|
||||
case REGOFF:
|
||||
case STATOFF:
|
||||
case EXTOFF:
|
||||
tp->t_offset =+ offset;
|
||||
return( bitno % BITSPBYTE );
|
||||
}
|
||||
}
|
||||
else if( tp->t_op == INDR ) {
|
||||
tp->t_left = tnalloc(ADD,tp->t_left->t_type,0,0,tp->t_left,
|
||||
cnalloc(INT,offset));
|
||||
return( bitno % BITSPBYTE );
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
isonebit(tp) /* returns -1 if not 1 bit, else bitno*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
{
|
||||
if( tp = constant(tp) )
|
||||
return( onebit(tp->t_value) );
|
||||
return(-1);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/*built-in literals*/
|
||||
#define MOV 128
|
||||
#define MOVL 129
|
||||
#define JSR 130
|
||||
#define CLR 131
|
||||
#define CLRL 132
|
||||
#define EXTW 133
|
||||
#define EXTL 134
|
||||
#define LEA 135
|
||||
#define STK 136
|
||||
|
||||
/*built-in macros*/
|
||||
#define TREE 141
|
||||
#define LEFT 142
|
||||
#define RIGHT 143
|
||||
#define LOFFSET 144
|
||||
#define ROFFSET 145
|
||||
#define LADDR 146
|
||||
#define RADDR 147
|
||||
#define CR 148
|
||||
#define NR 149
|
||||
#define CAR 150
|
||||
#define NAR 151
|
||||
#define TLEFT 152
|
||||
#define TRIGHT 153
|
||||
#define TEITHER 154
|
||||
#define TLEFTL 155
|
||||
#define OP 156
|
||||
#define AOP 157
|
||||
#define MODSWAP 158
|
||||
#define EXL 159
|
||||
#define EXLR 160
|
||||
#define EXLRN 161
|
||||
#define EXRL 162
|
||||
#define EXRLN 163
|
||||
#define PSH 164
|
||||
#define POP 165
|
||||
#define POP8 166
|
||||
#define OPCALL 167
|
||||
#define POP4 169
|
||||
#define LADDRP 168
|
||||
|
||||
/*modifiers for compiling sub-trees*/
|
||||
#define S_INDR 1 /*indirection*/
|
||||
#define S_STACK 2 /*onto stack*/
|
||||
#define S_FORCC 4 /*set condition codes*/
|
||||
#define S_NEXT 8 /*into next register*/
|
||||
|
||||
/*Sethy-Ullman values*/
|
||||
#define SU_ZERO 0x000 /*zero*/
|
||||
#define SU_ONE 0x100 /*one*/
|
||||
#define SU_SMALL 0x200 /*constant between 1 and 8*/
|
||||
#define SU_QUICK 0x300 /*quick constant between -128 and 127*/
|
||||
#define SU_CONST 0x400 /*any constant*/
|
||||
#define SU_AREG 0x500 /*A register*/
|
||||
#define SU_REG 0x600 /*register*/
|
||||
#define SU_ADDR 0x700 /*addressable*/
|
||||
#define SU_XREG 0x800 /*A register used as data...*/
|
||||
#define SU_EASY 0x900 /*easy*/
|
||||
#define SU_HARD 0xa00 /*hard*/
|
||||
#define SU_VHARD 0xb00 /*very hard ... function calls, etc.*/
|
||||
#define SU_ANY 0xf00 /*anything*/
|
||||
#define ADDRESSABLE(x) (x->t_su<=SU_ADDR)
|
||||
#define NOTADDRESSABLE(x) (x->t_su>SU_ADDR)
|
||||
#define LOADABLE(x) (x->t_su<=SU_XREG)
|
||||
|
||||
/*flag byte (operand type):*/
|
||||
#define T_CHAR 1 /*char only*/
|
||||
#define T_SHORT 2 /*short*/
|
||||
#define T_INT 3 /*int only*/
|
||||
#define T_LONG 4 /*long*/
|
||||
#define T_UCHAR 5 /*unsigned char*/
|
||||
#define T_USHORT 6 /*unsigned short*/
|
||||
#define T_UNSN 7 /*unsigned int*/
|
||||
#define T_ULONG 8 /*unsigned long*/
|
||||
#define T_FLOAT 9 /*float*/
|
||||
#define T_DOUB 10 /*double*/
|
||||
#define T_ANY 11 /*int or word (implied)*/
|
||||
#define T_INDR 0x10 /*pointer type (bit)*/
|
||||
|
||||
struct skeleton {
|
||||
int sk_left;
|
||||
int sk_right;
|
||||
char *sk_def;
|
||||
};
|
||||
1387
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/cskels.c
Normal file
1387
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/cskels.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
||||
$ set def [steve.cpm68k.c.fcgen]
|
||||
$ diff CANON.C [-.cgen]CANON.C
|
||||
$ diff CODEGEN.C [-.cgen]CODEGEN.C
|
||||
$ diff INIT.C [-.cgen]INIT.C
|
||||
$ diff INTERF.C [-.cgen]INTERF.C
|
||||
$ diff MAIN.C [-.cgen]MAIN.C
|
||||
$ diff OPTAB.C [-.cgen]OPTAB.C
|
||||
$ diff PUTEXPR.C [-.cgen]PUTEXPR.C
|
||||
$ diff SMATCH.C [-.cgen]SMATCH.C
|
||||
$ diff SUCOMP.C [-.cgen]SUCOMP.C
|
||||
$ diff TABL.C [-.cgen]TABL.C
|
||||
$ diff UTIL.C [-.cgen]UTIL.C
|
||||
$ diff VERSION.C [-.cgen]VERSION.C
|
||||
$ diff CGEN.H [-.cgen]CGEN.H
|
||||
$ diff CSKEL.H [-.cgen]CSKEL.H
|
||||
$ diff ICODE.H [-.cgen]ICODE.H
|
||||
@@ -0,0 +1,16 @@
|
||||
vax CANON.C r
|
||||
vax CODEGEN.C r
|
||||
vax CSKELS.C r
|
||||
vax INTERF.C r
|
||||
vax MAIN.C r
|
||||
vax OPTAB.C r
|
||||
vax PUTEXPR.C r
|
||||
vax SMATCH.C r
|
||||
vax SUCOMP.C r
|
||||
vax TABL.C r
|
||||
vax UTIL.C r
|
||||
vax CGEN.H r
|
||||
vax CSKEL.H r
|
||||
vax ICODE.H r
|
||||
vax LINK.SUB r
|
||||
vax MAKE.SUB r
|
||||
251
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/icode.h
Normal file
251
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/icode.h
Normal file
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
#include "machine.h"
|
||||
/*
|
||||
* intermediate code operators
|
||||
* 0=>EOF, special operator
|
||||
*/
|
||||
#define EOF 0
|
||||
|
||||
/*1-59=>operators that generate code (entries in code gen optab)*/
|
||||
#define ADD 1
|
||||
#define SUB 2
|
||||
#define MULT 3
|
||||
#define DIV 4
|
||||
#define MOD 5
|
||||
#define RSH 6
|
||||
#define LSH 7
|
||||
#define AND 8
|
||||
#define OR 9
|
||||
#define XOR 10
|
||||
#define NOT 11
|
||||
#define UMINUS 12
|
||||
#define COMPL 13
|
||||
#define PREDEC 14
|
||||
#define PREINC 15
|
||||
#define POSTDEC 16
|
||||
#define POSTINC 17
|
||||
#define ASSIGN 18
|
||||
#define EQADD 19
|
||||
#define EQSUB 20
|
||||
#define EQMULT 21
|
||||
#define EQDIV 22
|
||||
#define EQMOD 23
|
||||
#define EQRSH 24
|
||||
#define EQLSH 25
|
||||
#define EQAND 26
|
||||
#define EQOR 27
|
||||
#define EQXOR 28
|
||||
#define FJSR 29
|
||||
#define EQUALS 30
|
||||
#define NEQUALS 31
|
||||
#define GREAT 32
|
||||
#define GREATEQ 33
|
||||
#define LESS 34
|
||||
#define LESSEQ 35
|
||||
#define INT2L 36
|
||||
#define LONG2I 37
|
||||
|
||||
/*machine dependent operators that generate code*/
|
||||
#define BTST 38
|
||||
#define LOAD 39
|
||||
#define LMULT 40
|
||||
#define LDIV 41
|
||||
#define LMOD 42
|
||||
#define LEQMULT 43
|
||||
#define LEQDIV 44
|
||||
#define LEQMOD 45
|
||||
#define EQADDR 46
|
||||
#define EQNOT 47
|
||||
#define EQNEG 48
|
||||
#define DOCAST 49
|
||||
|
||||
#define STASSIGN 50 /*[vlh]*/
|
||||
#define LONG2F 51 /*[vlh] 3.4*/
|
||||
#define FLOAT2L 52 /*[vlh] 3.4*/
|
||||
#define INT2F 53 /*[vlh] 3.4*/
|
||||
#define FLOAT2I 54 /*[vlh] 3.4*/
|
||||
#define LCGENOP 55 /*change if adding more operators...*/
|
||||
|
||||
/*intermediate code operators that do not generate code*/
|
||||
#define ADDR 60
|
||||
#define INDR 61
|
||||
#define LAND 62
|
||||
#define LOR 63
|
||||
#define QMARK 64
|
||||
#define COLON 65
|
||||
#define COMMA 66
|
||||
#define CINT 67
|
||||
#define CLONG 68
|
||||
#define SYMBOL 69
|
||||
#define AUTOINC 70
|
||||
#define AUTODEC 71
|
||||
#define CALL 72
|
||||
#define NACALL 73
|
||||
#define BFIELD 74
|
||||
#define IFGOTO 75
|
||||
#define INIT 76
|
||||
#define CFORREG 77
|
||||
#define DCLONG 78
|
||||
#define CFLOAT 79 /*[vlh] 3.4*/
|
||||
|
||||
/*operators local to parser*/
|
||||
#define CAST 80
|
||||
#define SEMI 81
|
||||
#define LCURBR 82
|
||||
#define RCURBR 83
|
||||
#define LBRACK 84
|
||||
#define RBRACK 85
|
||||
#define LPAREN 86
|
||||
#define RPAREN 87
|
||||
#define STRING 88
|
||||
#define RESWORD 89
|
||||
#define APTR 90
|
||||
#define PERIOD 91
|
||||
#define SIZEOF 92
|
||||
#define MPARENS 93
|
||||
#define FRETURN 94
|
||||
#define STACKEND 100
|
||||
|
||||
/*data types*/
|
||||
#define TYPELESS 0
|
||||
#define CHAR 1
|
||||
#define SHORT 2
|
||||
#define INT 3
|
||||
#define LONG 4
|
||||
#define UCHAR 5
|
||||
#define USHORT 6
|
||||
#define UNSIGNED 7
|
||||
#define ULONG 8
|
||||
#define FLOAT 9
|
||||
#define DOUBLE 10
|
||||
|
||||
/*data types local to parser*/
|
||||
#define STRUCT 11
|
||||
#define FRSTRUCT 12
|
||||
#define LLABEL 13
|
||||
|
||||
/*type flags and definitions*/
|
||||
#define TYPE 017
|
||||
#define SUPTYP 060
|
||||
#define ALLTYPE 077
|
||||
#define POINTER 020
|
||||
#define FUNCTION 040
|
||||
#define ARRAY 060
|
||||
#define SUTYPLEN 2
|
||||
|
||||
/*data registers*/
|
||||
#define DREG0 0
|
||||
#define DREG2 2
|
||||
#define DREG3 3
|
||||
#define DREG4 4
|
||||
#define DREG5 5
|
||||
#define DREG6 6
|
||||
#define DREG7 7
|
||||
#define AREG3 11
|
||||
#define AREG4 12
|
||||
#define AREG5 13
|
||||
|
||||
/*storage classes*/
|
||||
#define AUTO 1
|
||||
#define REGISTER 2
|
||||
#define EXTERNAL 3
|
||||
#define STATIC 4
|
||||
#define REGOFF 5
|
||||
#define EXTOFF 6
|
||||
#define STATOFF 7
|
||||
#define INDEXED 8
|
||||
|
||||
/*exclusively code generator storage classes*/
|
||||
#define CINDR 9
|
||||
#define CLINDR 10
|
||||
#define CFINDR 11 /* [vlh] 3.4 */
|
||||
|
||||
/*exclusively parser storage classes*/
|
||||
#define STRPROTO 9
|
||||
#define PDECLIST 10
|
||||
#define PARMLIST 11
|
||||
#define BFIELDCL 12
|
||||
#define UNELCL 13
|
||||
#define STELCL 14
|
||||
|
||||
|
||||
/*opinfo table bits*/
|
||||
#define OPPRI 077
|
||||
#define OPBIN 0100
|
||||
#define OPLVAL 0200
|
||||
#define OPREL 0400
|
||||
#define OPASSIGN 01000
|
||||
#define OPLWORD 02000
|
||||
#define OPRWORD 04000
|
||||
#define OPCOM 010000
|
||||
#define OPRAS 020000
|
||||
#define OPTERM 040000
|
||||
#define OPCONVS 0100000
|
||||
|
||||
/*68000 definitions*/
|
||||
#define PTRSIZE 4
|
||||
#define INTSIZE 2
|
||||
#define LONGSIZE 4
|
||||
#define SSIZE 8 /* chars per symbol */
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define TABC '\t' /* tab character */
|
||||
#define EOLC '\n' /* end of line character */
|
||||
#define BITSPBYTE 8
|
||||
|
||||
/*operator class priorities*/
|
||||
#define TRMPRI 0 /* terminal nodes */
|
||||
#define RPNPRI 1 /* ) and ] */
|
||||
#define CALPRI 2 /* in-stack call, ( or [ */
|
||||
#define COLPRI 3 /* init or case priority for : or , */
|
||||
#define STKPRI 4 /* priority of end of stack */
|
||||
#define COMPRI 5 /* normal priority for , */
|
||||
#define ASGPRI 6 /* =, +=, -=, *=, /=, %=, ... */
|
||||
#define QMKPRI 7 /* ?: */
|
||||
#define LORPRI 8 /* || */
|
||||
#define LNDPRI 9 /* && */
|
||||
#define ORPRI 10 /* |, ! */
|
||||
#define ANDPRI 11 /* & */
|
||||
#define EQLPRI 12 /* ==, != */
|
||||
#define RELPRI 13 /* >, <, >=, <= */
|
||||
#define SHFPRI 14 /* <<, >> */
|
||||
#define ADDPRI 15 /* +, - */
|
||||
#define MULPRI 16 /* *, /, % */
|
||||
#define UNOPRI 17 /* ++, --, &, *, -, ~, sizeof */
|
||||
#define LPNPRI 18 /* ., ->, [, (, function call */
|
||||
#define PSTPRI 19 /* in-stack post--, post++ */
|
||||
|
||||
struct io_buf {
|
||||
int io_fd;
|
||||
int io_nc;
|
||||
char *io_p;
|
||||
char io_b[512];
|
||||
};
|
||||
|
||||
#ifdef PDP11
|
||||
struct { short hiword; short loword; };
|
||||
#endif
|
||||
#ifdef MC68000
|
||||
struct { short hiword; short loword; };
|
||||
#endif
|
||||
#ifdef VAX
|
||||
struct { short loword; short hiword; };
|
||||
#endif
|
||||
|
||||
#define EXPSIZE 1024
|
||||
int exprarea[EXPSIZE];
|
||||
|
||||
/* v6io buffer declaration */
|
||||
#define BLEN 512
|
||||
|
||||
struct iobuf{
|
||||
int fildes;
|
||||
int nunused;
|
||||
char *xfree;
|
||||
char buff[BLEN];
|
||||
};
|
||||
418
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/init.c
Normal file
418
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/init.c
Normal file
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
|
||||
char null[]=0;
|
||||
#define SSIZE 8 /* chars per symbol */
|
||||
|
||||
/*operator tree node for unary and binary operators*/
|
||||
struct tnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*data type of result*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
struct tnode *t_left; /*left sub-tree*/
|
||||
struct tnode *t_right; /*right sub-tree (undefined if unary)*/
|
||||
};
|
||||
|
||||
/*constant terminal node*/
|
||||
struct conode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_value; /*value or label number*/
|
||||
};
|
||||
|
||||
struct lconode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
long t_lvalue; /*value or label number*/
|
||||
};
|
||||
|
||||
/*local symbol terminal node*/
|
||||
struct symnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*symbol data type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_sc; /*storage class*/
|
||||
int t_offset; /*register offset*/
|
||||
int t_reg; /*register number*/
|
||||
int t_label; /*label number if static*/
|
||||
};
|
||||
|
||||
/*external symbol reference node*/
|
||||
struct extnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*symbol data type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_sc; /*storage class*/
|
||||
int t_offset; /*register offset*/
|
||||
int t_reg; /*register number*/
|
||||
char t_symbol[SSIZE]; /*symbol name*/
|
||||
};
|
||||
|
||||
/*68000 special - indexed symbol node*/
|
||||
/*this is used to generate a An(off,Xn.type) address*/
|
||||
struct indexnode {
|
||||
int t_op;
|
||||
int t_type;
|
||||
int t_su;
|
||||
int t_ssp;
|
||||
int t_sc;
|
||||
int t_offset;
|
||||
int t_reg;
|
||||
int t_xreg;
|
||||
int t_xtype;
|
||||
};
|
||||
|
||||
int lflag=0;
|
||||
int dflag=0;
|
||||
int mflag=0;
|
||||
int cflag=0;
|
||||
int eflag=0;
|
||||
int fflag=0;
|
||||
int oflag=0;
|
||||
int lineno=0;
|
||||
int naregs=0;
|
||||
int ndregs=0;
|
||||
int errcnt=0;
|
||||
int stacksize=0;
|
||||
|
||||
char *tnalloc();
|
||||
char *snalloc();
|
||||
char *cenalloc();
|
||||
char *xnalloc();
|
||||
char *talloc();
|
||||
char *cnalloc();
|
||||
char *lcnalloc();
|
||||
char *fpcnalloc();
|
||||
char *canon();
|
||||
char *commute();
|
||||
char *constant();
|
||||
char *match();
|
||||
char *addptree();
|
||||
char *fixbfield();
|
||||
char *coffset();
|
||||
char *tcopy();
|
||||
|
||||
#define wallign(add) ((add+1)&(~1))
|
||||
#define array(type) ((type&SUPTYP)==ARRAY)
|
||||
#define function(type) ((type&SUPTYP)==FUNCTION)
|
||||
#define pointer(type) ((type&SUPTYP)==POINTER)
|
||||
#define notarray(type) ((type&SUPTYP)!=ARRAY)
|
||||
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
|
||||
#define notpointer(type) ((type&SUPTYP)!=POINTER)
|
||||
#define isfloat(type) (type==FLOAT)
|
||||
#define btype(type) (type&TYPE)
|
||||
#define suptype(type) (type&SUPTYP)
|
||||
#define alltype(type) (type&(SUPTYP|TYPE))
|
||||
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
|
||||
#define relop(op) ((opinfo[op]&OPREL)!=0)
|
||||
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
|
||||
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
|
||||
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
|
||||
#define binop(op) ((opinfo[op]&OPBIN)!=0)
|
||||
#define unaryop(op) ((opinfo[op]&(OPBIN|OPTERM))==0)
|
||||
#define leafop(op) ((opinfo[op]&OPTERM)!=0)
|
||||
#define notleafop(op) ((opinfo[op]&OPTERM)==0)
|
||||
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
|
||||
#define oppriority(op) (opinfo[op]&OPPRI)
|
||||
#define commop(op) ((opinfo[op]&OPCOM)!=0)
|
||||
#define convop(op) ((opinfo[op]&OPCONVS)!=0)
|
||||
#define notconvop(op) ((opinfo[op]&OPCONVS)==0)
|
||||
#define max(a,b) (a>b?a:b)
|
||||
#define min(a,b) (a<b?a:b)
|
||||
|
||||
#define QUICKVAL 8
|
||||
#define LEP 14
|
||||
#define FORCC 1
|
||||
#define FOREFF 2
|
||||
#define FORSTACK 3
|
||||
#define FORCREG 4
|
||||
#define FORSP 5
|
||||
#define FORREG 4
|
||||
#define HICREG 2
|
||||
#define NCREGS 3
|
||||
#define AREGLO 8
|
||||
#define IMMED 1
|
||||
#define NOTIMMED 0
|
||||
#define NOTLOFFSET 0
|
||||
|
||||
/* one line routines turned into defines [vlh] for speed */
|
||||
|
||||
/*outgoto - output "bra L[labno]"*/
|
||||
#define outgoto(lab) if (lab>0) printf("bra L%d\n",lab)
|
||||
/*outlab - output "L[labno]:"*/
|
||||
#define outlab(lab) if (lab>0) printf("L%d:",lab)
|
||||
|
||||
/*outext - output register sign extension*/
|
||||
#define outext(reg) printf("ext.l R%d\n",reg)
|
||||
/*outuext - output unsigned to long register extension*/
|
||||
#define outuext(reg) printf("swap R%d\nclr R%d\nswap R%d\n",reg,reg,reg)
|
||||
/*outswap - output swap register instruction*/
|
||||
#define outswap(reg) printf("swap R%d\n",reg)
|
||||
/*outaddr - output "add [type] R1 R2" instruction*/
|
||||
#define outaddr(r1,r2,tp) outrr("add",r1,r2,(tp))
|
||||
/*outccsave - ouput instruction to move cc's to register*/
|
||||
#define outccsave(reg) printf("move sr,R%d\n",reg)
|
||||
/*outccrestore - output instruction to restore cc's from register*/
|
||||
#define outccrestore(reg) printf("move R%d,ccr\n",reg)
|
||||
/*basetype - get the btype info sans unsigned*/
|
||||
#define basetype(type) ((type==UNSIGNED) ? INT : type)
|
||||
#define unsign(type) ((type) == UNSIGNED)
|
||||
#define longorptr(type) (type==LONG || (type&SUPTYP))
|
||||
#define unorptr(type) (type==UNSIGNED || (type&SUPTYP))
|
||||
#define dreg(reg) ((reg) & (~AREGLO))
|
||||
#define areg(reg) ((reg) | AREGLO)
|
||||
#define isareg(reg) ((reg) >= AREGLO)
|
||||
#define isdreg(reg) ((reg) < AREGLO)
|
||||
#define isreg(tp) ((tp)->t_op == SYMBOL && (tp)->t_sc == REGISTER)
|
||||
|
||||
/*
|
||||
* intermediate code operators
|
||||
* 0=>EOF, special operator
|
||||
*/
|
||||
#define EOF 0
|
||||
|
||||
/*1-59=>operators that generate code (entries in code gen optab)*/
|
||||
#define ADD 1
|
||||
#define SUB 2
|
||||
#define MULT 3
|
||||
#define DIV 4
|
||||
#define MOD 5
|
||||
#define RSH 6
|
||||
#define LSH 7
|
||||
#define AND 8
|
||||
#define OR 9
|
||||
#define XOR 10
|
||||
#define NOT 11
|
||||
#define UMINUS 12
|
||||
#define COMPL 13
|
||||
#define PREDEC 14
|
||||
#define PREINC 15
|
||||
#define POSTDEC 16
|
||||
#define POSTINC 17
|
||||
#define ASSIGN 18
|
||||
#define EQADD 19
|
||||
#define EQSUB 20
|
||||
#define EQMULT 21
|
||||
#define EQDIV 22
|
||||
#define EQMOD 23
|
||||
#define EQRSH 24
|
||||
#define EQLSH 25
|
||||
#define EQAND 26
|
||||
#define EQOR 27
|
||||
#define EQXOR 28
|
||||
#define FJSR 29
|
||||
#define EQUALS 30
|
||||
#define NEQUALS 31
|
||||
#define GREAT 32
|
||||
#define GREATEQ 33
|
||||
#define LESS 34
|
||||
#define LESSEQ 35
|
||||
#define INT2L 36
|
||||
#define LONG2I 37
|
||||
|
||||
/*machine dependent operators that generate code*/
|
||||
#define BTST 38
|
||||
#define LOAD 39
|
||||
#define LMULT 40
|
||||
#define LDIV 41
|
||||
#define LMOD 42
|
||||
#define LEQMULT 43
|
||||
#define LEQDIV 44
|
||||
#define LEQMOD 45
|
||||
#define EQADDR 46
|
||||
#define EQNOT 47
|
||||
#define EQNEG 48
|
||||
#define DOCAST 49
|
||||
|
||||
#define STASSIGN 50 /*[vlh]*/
|
||||
#define LONG2F 51 /*[vlh] 3.4*/
|
||||
#define FLOAT2L 52 /*[vlh] 3.4*/
|
||||
#define INT2F 53 /*[vlh] 3.4*/
|
||||
#define FLOAT2I 54 /*[vlh] 3.4*/
|
||||
#define LCGENOP 55 /*change if adding more operators...*/
|
||||
|
||||
/*intermediate code operators that do not generate code*/
|
||||
#define ADDR 60
|
||||
#define INDR 61
|
||||
#define LAND 62
|
||||
#define LOR 63
|
||||
#define QMARK 64
|
||||
#define COLON 65
|
||||
#define COMMA 66
|
||||
#define CINT 67
|
||||
#define CLONG 68
|
||||
#define SYMBOL 69
|
||||
#define AUTOINC 70
|
||||
#define AUTODEC 71
|
||||
#define CALL 72
|
||||
#define NACALL 73
|
||||
#define BFIELD 74
|
||||
#define IFGOTO 75
|
||||
#define INIT 76
|
||||
#define CFORREG 77
|
||||
#define DCLONG 78
|
||||
#define CFLOAT 79 /*[vlh] 3.4*/
|
||||
|
||||
/*operators local to parser*/
|
||||
#define CAST 80
|
||||
#define SEMI 81
|
||||
#define LCURBR 82
|
||||
#define RCURBR 83
|
||||
#define LBRACK 84
|
||||
#define RBRACK 85
|
||||
#define LPAREN 86
|
||||
#define RPAREN 87
|
||||
#define STRING 88
|
||||
#define RESWORD 89
|
||||
#define APTR 90
|
||||
#define PERIOD 91
|
||||
#define SIZEOF 92
|
||||
#define MPARENS 93
|
||||
#define FRETURN 94
|
||||
#define STACKEND 100
|
||||
|
||||
/*data types*/
|
||||
#define TYPELESS 0
|
||||
#define CHAR 1
|
||||
#define SHORT 2
|
||||
#define INT 3
|
||||
#define LONG 4
|
||||
#define UCHAR 5
|
||||
#define USHORT 6
|
||||
#define UNSIGNED 7
|
||||
#define ULONG 8
|
||||
#define FLOAT 9
|
||||
#define DOUBLE 10
|
||||
|
||||
/*data types local to parser*/
|
||||
#define STRUCT 11
|
||||
#define FRSTRUCT 12
|
||||
#define LLABEL 13
|
||||
|
||||
/*type flags and definitions*/
|
||||
#define TYPE 017
|
||||
#define SUPTYP 060
|
||||
#define ALLTYPE 077
|
||||
#define POINTER 020
|
||||
#define FUNCTION 040
|
||||
#define ARRAY 060
|
||||
#define SUTYPLEN 2
|
||||
|
||||
/*data registers*/
|
||||
#define DREG0 0
|
||||
#define DREG2 2
|
||||
#define DREG3 3
|
||||
#define DREG4 4
|
||||
#define DREG5 5
|
||||
#define DREG6 6
|
||||
#define DREG7 7
|
||||
#define AREG3 11
|
||||
#define AREG4 12
|
||||
#define AREG5 13
|
||||
|
||||
/*storage classes*/
|
||||
#define AUTO 1
|
||||
#define REGISTER 2
|
||||
#define EXTERNAL 3
|
||||
#define STATIC 4
|
||||
#define REGOFF 5
|
||||
#define EXTOFF 6
|
||||
#define STATOFF 7
|
||||
#define INDEXED 8
|
||||
|
||||
/*exclusively code generator storage classes*/
|
||||
#define CINDR 9
|
||||
#define CLINDR 10
|
||||
#define CFINDR 11 /* [vlh] 3.4 */
|
||||
|
||||
/*exclusively parser storage classes*/
|
||||
#define STRPROTO 9
|
||||
#define PDECLIST 10
|
||||
#define PARMLIST 11
|
||||
#define BFIELDCL 12
|
||||
#define UNELCL 13
|
||||
#define STELCL 14
|
||||
|
||||
|
||||
/*opinfo table bits*/
|
||||
#define OPPRI 077
|
||||
#define OPBIN 0100
|
||||
#define OPLVAL 0200
|
||||
#define OPREL 0400
|
||||
#define OPASSIGN 01000
|
||||
#define OPLWORD 02000
|
||||
#define OPRWORD 04000
|
||||
#define OPCOM 010000
|
||||
#define OPRAS 020000
|
||||
#define OPTERM 040000
|
||||
#define OPCONVS 0100000
|
||||
|
||||
/*68000 definitions*/
|
||||
#define PTRSIZE 4
|
||||
#define INTSIZE 2
|
||||
#define LONGSIZE 4
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define TABC '\t' /* tab character */
|
||||
#define EOLC '\n' /* end of line character */
|
||||
#define BITSPBYTE 8
|
||||
|
||||
/*operator class priorities*/
|
||||
#define TRMPRI 0 /* terminal nodes */
|
||||
#define RPNPRI 1 /* ) and ] */
|
||||
#define CALPRI 2 /* in-stack call, ( or [ */
|
||||
#define COLPRI 3 /* init or case priority for : or , */
|
||||
#define STKPRI 4 /* priority of end of stack */
|
||||
#define COMPRI 5 /* normal priority for , */
|
||||
#define ASGPRI 6 /* =, +=, -=, *=, /=, %=, ... */
|
||||
#define QMKPRI 7 /* ?: */
|
||||
#define LORPRI 8 /* || */
|
||||
#define LNDPRI 9 /* && */
|
||||
#define ORPRI 10 /* |, ! */
|
||||
#define ANDPRI 11 /* & */
|
||||
#define EQLPRI 12 /* ==, != */
|
||||
#define RELPRI 13 /* >, <, >=, <= */
|
||||
#define SHFPRI 14 /* <<, >> */
|
||||
#define ADDPRI 15 /* +, - */
|
||||
#define MULPRI 16 /* *, /, % */
|
||||
#define UNOPRI 17 /* ++, --, &, *, -, ~, sizeof */
|
||||
#define LPNPRI 18 /* ., ->, [, (, function call */
|
||||
#define PSTPRI 19 /* in-stack post--, post++ */
|
||||
|
||||
struct io_buf {
|
||||
int io_fd;
|
||||
int io_nc;
|
||||
char *io_p;
|
||||
char io_b[512];
|
||||
};
|
||||
struct { int hiword; int loword; };
|
||||
#define EXPSIZE 1024
|
||||
int exprarea[EXPSIZE]=0;
|
||||
|
||||
/* v6io buffer declaration */
|
||||
#define BLEN 512
|
||||
|
||||
struct iobuf {
|
||||
int fildes;
|
||||
int nunused;
|
||||
char *xfree;
|
||||
char buff[BLEN];
|
||||
};
|
||||
struct io_buf ibuf={0}, obuf={0};
|
||||
int bol=0;
|
||||
int errflg=0;
|
||||
int level=0;
|
||||
int onepass=0;
|
||||
char *opap=0;
|
||||
134
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/interf.c
Normal file
134
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/interf.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
int bol;
|
||||
int onepass;
|
||||
|
||||
/* outexpr - output expression*/
|
||||
outexpr(tp) /* returns - none*/
|
||||
struct tnode *tp; /* pointer to tree node*/
|
||||
{
|
||||
if( dflag )
|
||||
outline();
|
||||
if( exprok(tp) )
|
||||
scodegen(canon(tp),FOREFF,0);
|
||||
}
|
||||
|
||||
outifgoto(tp,dir,lab)
|
||||
struct tnode *tp;
|
||||
int dir;
|
||||
int lab;
|
||||
{
|
||||
if( dflag )
|
||||
outline();
|
||||
if( exprok(tp) )
|
||||
condbr(canon(tp),dir,lab,0);
|
||||
}
|
||||
|
||||
outcforreg(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
if( dflag )
|
||||
outline();
|
||||
if( exprok(tp) )
|
||||
outmovr(scodegen(canon(tp),FORREG,0),0,tp);
|
||||
}
|
||||
|
||||
outinit(tp) /* returns - none*/
|
||||
struct tnode *tp;
|
||||
{
|
||||
register int typeout;
|
||||
|
||||
if( dflag )
|
||||
outline();
|
||||
if( exprok(tp) ) {
|
||||
typeout = tp->t_type;
|
||||
tp = canon(tp);
|
||||
if( tp->t_op == ADDR )
|
||||
tp = tp->t_left;
|
||||
if( tp->t_op == CINT || tp->t_op == SYMBOL ) {
|
||||
if( tp->t_op != CINT )
|
||||
printf(".dc.l ");
|
||||
else {
|
||||
printf(".dc");
|
||||
outtype(typeout);
|
||||
putchar(' ');
|
||||
}
|
||||
outaexpr(tp,NOTIMMED); /* [vlh] 4.0 not immed... */
|
||||
}
|
||||
else
|
||||
error("invalid initialization");
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/* snalloc - code generator symbol node allocation*/
|
||||
/* This might be coalesced into parser snalloc.*/
|
||||
char *snalloc(type,sc,offset,dp,ssp) /* returns ptr to node alloced*/
|
||||
int type; /* type of symbol*/
|
||||
int sc; /* storage class*/
|
||||
int offset; /* offset from Local Environment Ptr*/
|
||||
int dp; /*for compatability with parser*/
|
||||
int ssp; /*for compatability with parser*/
|
||||
{
|
||||
register struct symnode *sp;
|
||||
|
||||
sp = talloc(sizeof(*sp));
|
||||
sp->t_op = SYMBOL;
|
||||
sp->t_type = type;
|
||||
sp->t_su = dp;
|
||||
sp->t_ssp = ssp;
|
||||
sp->t_sc = sc;
|
||||
switch( sc ) {
|
||||
|
||||
case STATIC:
|
||||
sp->t_offset = 0;
|
||||
sp->t_reg = 0;
|
||||
sp->t_label = offset;
|
||||
break;
|
||||
|
||||
case REGISTER:
|
||||
sp->t_offset = 0;
|
||||
sp->t_reg = offset;
|
||||
sp->t_label = 0;
|
||||
break;
|
||||
|
||||
case AUTO:
|
||||
sp->t_sc = REGOFF;
|
||||
sp->t_offset = offset;
|
||||
sp->t_reg = LEP;
|
||||
sp->t_label = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
sp->t_offset = offset;
|
||||
sp->t_reg = 0;
|
||||
sp->t_label = 0;
|
||||
break;
|
||||
}
|
||||
return(sp);
|
||||
}
|
||||
|
||||
exprok(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
if( tp < exprarea || tp > &exprarea[EXPSIZE] )
|
||||
return(0);
|
||||
if( leafop(tp->t_op) )
|
||||
return(1);
|
||||
if( binop(tp->t_op) && !exprok(tp->t_right) )
|
||||
return(0);
|
||||
return( exprok(tp->t_left) );
|
||||
}
|
||||
|
||||
outline()
|
||||
{
|
||||
if( onepass && !bol )
|
||||
putchar('\n');
|
||||
printf("*line %d\n",lineno);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
$1lo68 -r s.o canon.o codegen.o cskels.o interf.o main.o optab.o putexpr.o smatch.o sucomp.o tabl.o util.o lib6.a
|
||||
era c168.rel
|
||||
ren c168.rel=c.out
|
||||
era *.o
|
||||
era lib6.a
|
||||
era as68symb.dat
|
||||
@@ -0,0 +1,3 @@
|
||||
$1lo68 -r s.o canon.o codegen.o cskels.o interf.o main.o optab.o putexpr.o smatch.o sucomp.o tabl.o util.o lib6.a
|
||||
era c168.rel
|
||||
ren c168.rel=c.out
|
||||
@@ -0,0 +1,42 @@
|
||||
$ num
|
||||
CANON.C
|
||||
CANON.lis
|
||||
$ num
|
||||
CODEGEN.C
|
||||
CODEGEN.lis
|
||||
$ num
|
||||
INTERF.C
|
||||
INTERF.lis
|
||||
$ num
|
||||
MAIN.C
|
||||
MAIN.lis
|
||||
$ num
|
||||
OPTAB.C
|
||||
OPTAB.lis
|
||||
$ num
|
||||
PUTEXPR.C
|
||||
PUTEXPR.lis
|
||||
$ num
|
||||
SMATCH.C
|
||||
SMATCH.lis
|
||||
$ num
|
||||
SUCOMP.C
|
||||
SUCOMP.lis
|
||||
$ num
|
||||
TABL.C
|
||||
TABL.lis
|
||||
$ num
|
||||
UTIL.C
|
||||
UTIL.lis
|
||||
$ num
|
||||
VERSION.C
|
||||
VERSION.lis
|
||||
$ num
|
||||
CGEN.H
|
||||
CGEN.lst
|
||||
$ num
|
||||
CSKEL.H
|
||||
CSKEL.lst
|
||||
$ num
|
||||
ICODE.H
|
||||
ICODE.lst
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Use this file to determine what kind of machine you want the
|
||||
* Alcyon stuff to run on ....
|
||||
*/
|
||||
/*#define MC68000 1*/ /* 68000 version */
|
||||
/*#define VAX 1*/ /* VAX Version */
|
||||
#define PDP11 1 /* PDP-11 Version*/
|
||||
/*#define CPM 1*/ /* CP/M Operating System*/
|
||||
#define UNIX 1 /* UNIX Operating System*/
|
||||
/*#define VMS 1*/ /* VMS Operating System*/
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Use this file to determine what kind of machine you want the
|
||||
* Alcyon stuff to run on ....
|
||||
*/
|
||||
#define MC68000 1 /* 68000 version */
|
||||
/*#define VAX 1*/ /* VAX Version */
|
||||
/*#define PDP11 1*/ /* PDP-11 Version*/
|
||||
#define CPM 1 /* CP/M Operating System*/
|
||||
/*#define UNIX 1*/ /* UNIX Operating System*/
|
||||
/*#define VMS 1*/ /* VMS Operating System*/
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Use this file to determine what kind of machine you want the
|
||||
* Alcyon stuff to run on ....
|
||||
*/
|
||||
/*#define MC68000 1*/ /* 68000 version */
|
||||
#define VAX 1 /* VAX Version */
|
||||
/*#define PDP11 1*/ /* PDP-11 Version*/
|
||||
/*#define CPM 1*/ /* CP/M Operating System*/
|
||||
/*#define UNIX 1*/ /* UNIX Operating System*/
|
||||
#define VMS 1 /* VMS Operating System*/
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Use this file to determine what kind of machine you want the
|
||||
* Alcyon stuff to run on ....
|
||||
*/
|
||||
/*#define MC68000 1*/ /* 68000 version */
|
||||
#define VAX 1 /* VAX Version */
|
||||
/*#define PDP11 1*/ /* PDP-11 Version*/
|
||||
/*#define CPM 1*/ /* CP/M Operating System*/
|
||||
/*#define UNIX 1*/ /* UNIX Operating System*/
|
||||
#define VMS 1 /* VMS Operating System*/
|
||||
418
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/main.c
Normal file
418
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/main.c
Normal file
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
char *version "@(#) c168 code generator 4.0 - Feb 10, 1983";
|
||||
|
||||
#include "cgen.h"
|
||||
#include "cskel.h"
|
||||
char *opap;
|
||||
int errflg;
|
||||
int nextlabel 10000;
|
||||
char *readtree();
|
||||
char *readsym();
|
||||
|
||||
|
||||
/* main - main routine, handles arguments and files*/
|
||||
main(argc,argv) /* returns - none*/
|
||||
int argc; /* arg count*/
|
||||
char **argv; /* arg pointers*/
|
||||
{
|
||||
register char *q;
|
||||
register int i;
|
||||
|
||||
#ifdef VERSADOS
|
||||
lflag++;
|
||||
#endif
|
||||
for( i = 3; i < argc; i++ ) {
|
||||
q = argv[i];
|
||||
if( *q++ != '-' )
|
||||
usage(argc,argv,1);
|
||||
while( 1 ) {
|
||||
switch( *q++ ) {
|
||||
|
||||
case 'D':
|
||||
case 'd':
|
||||
dflag++;
|
||||
continue;
|
||||
|
||||
case 'L':
|
||||
case 'l':
|
||||
lflag++;
|
||||
continue;
|
||||
|
||||
case 'E':
|
||||
case 'e':
|
||||
eflag++;
|
||||
continue;
|
||||
|
||||
case 'F':
|
||||
case 'f':
|
||||
fflag++;
|
||||
continue;
|
||||
|
||||
case 'M':
|
||||
case 'm':
|
||||
mflag++;
|
||||
continue;
|
||||
|
||||
case 'O':
|
||||
case 'o':
|
||||
oflag++;
|
||||
continue;
|
||||
|
||||
case 'C':
|
||||
case 'c':
|
||||
cflag++;
|
||||
continue;
|
||||
|
||||
case '\0':
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(argc,argv,2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( argc < 3 )
|
||||
usage(argc,argv,3);
|
||||
if( fopen(argv[1],&ibuf,0) < 0 ) /* 3rd arg for versados */
|
||||
ferror("can't open %s\n",argv[1]);
|
||||
if( fcreat(argv[2],&obuf,0) < 0 ) /* 3rd arg for versados */
|
||||
ferror("can't create %s\n",argv[2]);
|
||||
readicode();
|
||||
v6flush(&obuf);
|
||||
exit(errcnt!=0);
|
||||
}
|
||||
|
||||
/* readicode - read intermediate code and dispatch output*/
|
||||
/* This copies assembler lines beginning with '(' to assembler*/
|
||||
/* output and builds trees starting with '.' line.*/
|
||||
readicode() /*returns - none*/
|
||||
{
|
||||
register int c;
|
||||
register struct tnode *tp;
|
||||
|
||||
while( (c=getc(&ibuf)) > 0 ) {
|
||||
switch(c) {
|
||||
|
||||
case '.':
|
||||
lineno = readint();
|
||||
opap = exprarea;
|
||||
if( tp = readtree() ) {
|
||||
#ifndef NODEBUG
|
||||
if( cflag )
|
||||
putexpr("readicode",tp);
|
||||
#endif
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case INIT:
|
||||
outinit(tp->t_left);
|
||||
break;
|
||||
|
||||
case CFORREG:
|
||||
outcforreg(tp->t_left);
|
||||
break;
|
||||
|
||||
case IFGOTO:
|
||||
outifgoto(tp->t_left,tp->t_type,tp->t_su);
|
||||
break;
|
||||
|
||||
default:
|
||||
outexpr(tp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '(':
|
||||
while( (c=getc(&ibuf)) != '\n' )
|
||||
putchar(c);
|
||||
putchar(c);
|
||||
break;
|
||||
|
||||
default:
|
||||
error("intermediate code error %c,%d",c,c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* readtree - recursive intermediate code tree read*/
|
||||
char *readtree() /* returns ptr to expression tree*/
|
||||
{
|
||||
register int op, type, sc;
|
||||
register struct tnode *tp, *rtp;
|
||||
char sym[SSIZE];
|
||||
long l;
|
||||
|
||||
if( (op=readint()) <= 0 )
|
||||
return(0);
|
||||
type = readint();
|
||||
switch( op ) {
|
||||
|
||||
case SYMBOL:
|
||||
if( (sc=readint()) == EXTERNAL )
|
||||
tp = cenalloc(type,sc,readsym(sym));
|
||||
else
|
||||
tp = snalloc(type,sc,readint(),0,0);
|
||||
break;
|
||||
|
||||
case CINT:
|
||||
tp = cnalloc(type,readint());
|
||||
break;
|
||||
|
||||
case CLONG:
|
||||
l.hiword = readint();
|
||||
l.loword = readint();
|
||||
tp = lcnalloc(type,l);
|
||||
break;
|
||||
|
||||
case CFLOAT: /* [vlh] 3.4 */
|
||||
l.hiword = readint();
|
||||
l.loword = readint();
|
||||
tp = fpcnalloc(type,l);
|
||||
break;
|
||||
|
||||
case IFGOTO:
|
||||
case BFIELD:
|
||||
sc = readint();
|
||||
if( tp = readtree() )
|
||||
tp = tnalloc(op,type,sc,0,tp,null);
|
||||
break;
|
||||
|
||||
default:
|
||||
if( binop(op) ) {
|
||||
if( !(tp=readtree()) )
|
||||
return(0);
|
||||
if( !(rtp=readtree()) )
|
||||
return(0);
|
||||
tp = tnalloc(op,type,0,0,tp,rtp);
|
||||
}
|
||||
else if( tp = readtree() )
|
||||
tp = tnalloc(op,type,0,0,tp,null);
|
||||
break;
|
||||
}
|
||||
return(tp);
|
||||
}
|
||||
|
||||
/* readint - reads an integer value from intermediate code*/
|
||||
readint()
|
||||
{
|
||||
register int i, c;
|
||||
|
||||
i = 0;
|
||||
while(1) {
|
||||
switch( c = getc(&ibuf) ) {
|
||||
|
||||
case '.':
|
||||
case '\n':
|
||||
return(i);
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
i =<< 4;
|
||||
i =+ (c-'0');
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
i =<< 4;
|
||||
i =+ (c-('a'-10));
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
i =<< 4;
|
||||
i =+ (c-('A'-10));
|
||||
break;
|
||||
|
||||
default:
|
||||
error("intermediate code error - %c,%d",c,c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* readsym - read a symbol from intermediate code*/
|
||||
char *readsym(sym)
|
||||
char *sym;
|
||||
{
|
||||
register int i, c;
|
||||
register char *s;
|
||||
|
||||
for( i = SSIZE, s = sym; (c=getc(&ibuf)) != '\n'; )
|
||||
if( --i >= 0 )
|
||||
*s++ = c;
|
||||
if( i > 0 )
|
||||
*s = '\0';
|
||||
return(sym);
|
||||
}
|
||||
|
||||
/* error - output an error message*/
|
||||
error(s,x1,x2,x3,x4,x5,x6)
|
||||
char *s;
|
||||
int x1, x2, x3, x4, x5, x6;
|
||||
{
|
||||
errcnt++;
|
||||
errflg++;
|
||||
if( lineno != 0 )
|
||||
printf("** %d: ",lineno);
|
||||
printf(s,x1,x2,x3,x4,x5,x6);
|
||||
putchar('\n');
|
||||
errflg--;
|
||||
}
|
||||
|
||||
/* ferror - output error message and die*/
|
||||
ferror(s,x1,x2,x3,x4,x5,x6)
|
||||
char *s;
|
||||
int x1, x2, x3, x4, x5, x6;
|
||||
{
|
||||
error(s,x1,x2,x3,x4,x5,x6);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* tnalloc - allocate binary expression tree node*/
|
||||
/* returns ptr to node made.*/
|
||||
char *tnalloc(op,type,info,dummy,left,right)
|
||||
int op; /* operator*/
|
||||
int type; /* resultant node type*/
|
||||
int info; /* info field*/
|
||||
int dummy; /* dummy field - used to match pass1 args*/
|
||||
struct tnode *left; /* left sub-tree*/
|
||||
struct tnode *right; /* righst sub-tree*/
|
||||
{
|
||||
register struct tnode *tp;
|
||||
|
||||
tp = talloc(sizeof(*tp));
|
||||
tp->t_op = op;
|
||||
tp->t_type = type;
|
||||
tp->t_su = info; /* info for bit-field & condbr's*/
|
||||
tp->t_left = left;
|
||||
tp->t_right = right;
|
||||
return(tp);
|
||||
}
|
||||
|
||||
/* cnalloc - allocate constant expression tree node*/
|
||||
char *cnalloc(type,value) /* returns pointer to node alloced*/
|
||||
int type; /* type of constant*/
|
||||
int value; /* value of constant*/
|
||||
{
|
||||
register struct conode *cp;
|
||||
|
||||
cp = talloc(sizeof(*cp));
|
||||
cp->t_op = CINT;
|
||||
cp->t_type = type;
|
||||
cp->t_value = value;
|
||||
return(cp);
|
||||
}
|
||||
|
||||
/* lcnalloc - allocate constant expression tree node*/
|
||||
char *lcnalloc(type,value) /* returns pointer to node alloced*/
|
||||
int type; /* type of constant*/
|
||||
long value; /* value of constant*/
|
||||
{
|
||||
register struct lconode *cp;
|
||||
|
||||
cp = talloc(sizeof(*cp));
|
||||
cp->t_op = CLONG;
|
||||
cp->t_type = type;
|
||||
cp->t_lvalue = value;
|
||||
return(cp);
|
||||
}
|
||||
|
||||
/* fpcnalloc - allocate constant expression tree node*/
|
||||
char *fpcnalloc(type,value) /* returns pointer to node alloced*/
|
||||
int type; /* type of constant*/
|
||||
long value; /* value of constant*/
|
||||
{ /* [vlh] 3.4 */
|
||||
register struct lconode *cp;
|
||||
|
||||
cp = talloc(sizeof(*cp));
|
||||
cp->t_op = CFLOAT;
|
||||
cp->t_type = type;
|
||||
cp->t_lvalue = value;
|
||||
return(cp);
|
||||
}
|
||||
|
||||
/* talloc - allocate expression tree area*/
|
||||
char *talloc(size) /* returns pointer to area alloced*/
|
||||
int size; /* number of bytes to alloc*/
|
||||
{
|
||||
register char *p;
|
||||
|
||||
p = opap;
|
||||
if( p + size >= &exprarea[EXPSIZE] )
|
||||
ferror("expression too complex");
|
||||
opap = p + size;
|
||||
return(p);
|
||||
}
|
||||
|
||||
/* symcopy - copy symbol*/
|
||||
symcopy(sym1,sym2) /* returns - none*/
|
||||
char *sym1; /* from symbol*/
|
||||
char *sym2; /* to symbol*/
|
||||
{
|
||||
register char *p, *q;
|
||||
register int i;
|
||||
|
||||
for( p = sym1, q = sym2, i = SSIZE; --i >= 0; )
|
||||
*q++ = (*p ? *p++ : '\0');
|
||||
}
|
||||
|
||||
/* usage - ouput usage message*/
|
||||
usage(argc,argv,n)
|
||||
char *argv[];
|
||||
{
|
||||
register int i;
|
||||
error("usage call #%d:\n",n);
|
||||
for (i=0; i<argc; i++) error(" argv[%d] = %s\n",i,argv[i]);
|
||||
ferror("usage: c168 icode asm [-DLmec]");
|
||||
}
|
||||
|
||||
/* putchar - special version*/
|
||||
/* This allows the use of printf for error messages, debugging*/
|
||||
/* output and normal output.*/
|
||||
putchar(c) /* returns - none*/
|
||||
char c; /* character to output*/
|
||||
{
|
||||
if( errflg ) /*error message?*/
|
||||
write(1,&c,1); /*write to standard output*/
|
||||
else {
|
||||
if( dflag > 1 )
|
||||
write(1,&c,1); /*to standard output*/
|
||||
putc(c,&obuf); /*put to assembler file*/
|
||||
}
|
||||
}
|
||||
|
||||
v6flush(v6b)
|
||||
struct iobuf *v6b;
|
||||
{
|
||||
register i;
|
||||
|
||||
i = BLEN - v6b->nunused;
|
||||
v6b->nunused = BLEN;
|
||||
v6b->xfree = &(v6b->buff[0]);
|
||||
if(write(v6b->fildes,v6b->xfree,i) != i)
|
||||
return(-1);
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
$ set noon
|
||||
$ fcgen
|
||||
$ copy machine.vax machine.h
|
||||
$ cc68 CANON
|
||||
$ cc68 CODEGEN
|
||||
$ cc68 INTERF
|
||||
$ cc68 MAIN
|
||||
$ cc68 OPTAB
|
||||
$ cc68 PUTEXPR
|
||||
$ cc68 SMATCH
|
||||
$ cc68 SUCOMP
|
||||
$ cc68 TABL
|
||||
$ cc68 UTIL
|
||||
$ cc68 VERSION
|
||||
$ @relink
|
||||
105
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/make.sub
Normal file
105
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/make.sub
Normal file
@@ -0,0 +1,105 @@
|
||||
$1pip d:=$1as68symb.dat[g0
|
||||
$1pip d:=lib6.a[g5
|
||||
$1pip d:=s.o[g6
|
||||
$1pip machine.h=machine.68k
|
||||
|
||||
$1cp68 CANON.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic CANON.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u CANON.s
|
||||
era CANON.s
|
||||
|
||||
$1cp68 CODEGEN.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic CODEGEN.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u CODEGEN.s
|
||||
era CODEGEN.s
|
||||
|
||||
$1cp68 CSKELS.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic CSKELS.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u CSKELS.s
|
||||
era CSKELS.s
|
||||
|
||||
$1cp68 INTERF.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic INTERF.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u INTERF.s
|
||||
era INTERF.s
|
||||
|
||||
$1cp68 MAIN.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic MAIN.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u MAIN.s
|
||||
era MAIN.s
|
||||
|
||||
$1cp68 OPTAB.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic OPTAB.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u OPTAB.s
|
||||
era OPTAB.s
|
||||
|
||||
$1cp68 PUTEXPR.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic PUTEXPR.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u PUTEXPR.s
|
||||
era PUTEXPR.s
|
||||
|
||||
$1cp68 SMATCH.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic SMATCH.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u SMATCH.s
|
||||
era SMATCH.s
|
||||
|
||||
$1cp68 SUCOMP.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic SUCOMP.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u SUCOMP.s
|
||||
era SUCOMP.s
|
||||
|
||||
$1cp68 TABL.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic TABL.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u TABL.s
|
||||
era TABL.s
|
||||
|
||||
$1cp68 UTIL.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic UTIL.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u UTIL.s
|
||||
era UTIL.s
|
||||
|
||||
link $1
|
||||
@@ -0,0 +1,105 @@
|
||||
$1pip d:=as68symb.dat[g0
|
||||
$1pip d:=lib6.a[g5
|
||||
$1pip d:=s.o[g6
|
||||
$1pip machine.h=machine.68k
|
||||
|
||||
$1cp68 CANON.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic CANON.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u CANON.s
|
||||
era CANON.s
|
||||
|
||||
$1cp68 CODEGEN.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic CODEGEN.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u CODEGEN.s
|
||||
era CODEGEN.s
|
||||
|
||||
$1cp68 CSKELS.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic CSKELS.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u CSKELS.s
|
||||
era CSKELS.s
|
||||
|
||||
$1cp68 INTERF.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic INTERF.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u INTERF.s
|
||||
era INTERF.s
|
||||
|
||||
$1cp68 MAIN.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic MAIN.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u MAIN.s
|
||||
era MAIN.s
|
||||
|
||||
$1cp68 OPTAB.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic OPTAB.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u OPTAB.s
|
||||
era OPTAB.s
|
||||
|
||||
$1cp68 PUTEXPR.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic PUTEXPR.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u PUTEXPR.s
|
||||
era PUTEXPR.s
|
||||
|
||||
$1cp68 SMATCH.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic SMATCH.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u SMATCH.s
|
||||
era SMATCH.s
|
||||
|
||||
$1cp68 SUCOMP.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic SUCOMP.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u SUCOMP.s
|
||||
era SUCOMP.s
|
||||
|
||||
$1cp68 TABL.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic TABL.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u TABL.s
|
||||
era TABL.s
|
||||
|
||||
$1cp68 UTIL.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic UTIL.s -LD
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
$1as68 -f $1 -l -u UTIL.s
|
||||
era UTIL.s
|
||||
|
||||
link e:
|
||||
322
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/optab.c
Normal file
322
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/optab.c
Normal file
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
|
||||
#define I_NULL 0
|
||||
#define I_ADD 1
|
||||
#define I_INC 2
|
||||
#define I_SUB 3
|
||||
#define I_DEC 4
|
||||
#define I_MULS 5
|
||||
#define I_MULU 6
|
||||
#define I_DIVS 7
|
||||
#define I_DIVU 8
|
||||
#define I_ASR 9
|
||||
#define I_LSR 10
|
||||
#define I_ASL 11
|
||||
#define I_LSL 12
|
||||
#define I_AND 13
|
||||
#define I_OR 14
|
||||
#define I_EOR 15
|
||||
#define I_NEG 16
|
||||
#define I_NOT 17
|
||||
#define I_MOVE 18
|
||||
#define I_CLR 19
|
||||
#define I_CMP 20
|
||||
#define I_TST 21
|
||||
#define I_LMUL 22
|
||||
#define I_LDIV 23
|
||||
#define I_LREM 24
|
||||
#define I_LEML 25
|
||||
#define I_LERM 27
|
||||
#define I_BEQ 28
|
||||
#define I_BNE 29
|
||||
#define I_BGT 30
|
||||
#define I_BGE 31
|
||||
#define I_BLT 32
|
||||
#define I_BLE 33
|
||||
#define I_BLS 34
|
||||
#define I_BLO 35
|
||||
#define I_BCC 36
|
||||
#define I_BHI 37
|
||||
#define I_BRA 38
|
||||
#define I_NOP 39
|
||||
#define I_BTST 40
|
||||
|
||||
char *mnemonics[] {
|
||||
"",
|
||||
"add",
|
||||
"inc",
|
||||
"sub",
|
||||
"dec",
|
||||
"muls",
|
||||
"mulu",
|
||||
"divs",
|
||||
"divu",
|
||||
"asr",
|
||||
"lsr",
|
||||
"asl",
|
||||
"lsl",
|
||||
"and",
|
||||
"or",
|
||||
"eor",
|
||||
"neg",
|
||||
"not",
|
||||
"move",
|
||||
"clr",
|
||||
"cmp",
|
||||
"tst",
|
||||
"lmul",
|
||||
"_ldiv",
|
||||
"lrem",
|
||||
"almul",
|
||||
"aldiv",
|
||||
"alrem",
|
||||
"beq",
|
||||
"bne",
|
||||
"bgt",
|
||||
"bge",
|
||||
"blt",
|
||||
"ble",
|
||||
"bls",
|
||||
"blo",
|
||||
"bcc",
|
||||
"bhi",
|
||||
"jmp",
|
||||
"*nop",
|
||||
"btst",
|
||||
};
|
||||
|
||||
#define FE_EQOP 1
|
||||
#define FE_ASSIGN 2
|
||||
#define FE_EQSHFT 3
|
||||
#define FE_EQXOR 4
|
||||
#define FE_EQADDR 5
|
||||
#define FC_FIX 6
|
||||
#define FC_REL 7
|
||||
#define FC_BTST 8
|
||||
#define FS_OP 9
|
||||
#define FS_ITL 10
|
||||
#define FS_LD 11
|
||||
#define FR_ADD 12
|
||||
#define FR_MULT 13
|
||||
#define FR_DIV 14
|
||||
#define FR_SHFT 15
|
||||
#define FR_XOR 16
|
||||
#define FR_NEG 17
|
||||
#define FR_EQOP 18
|
||||
#define FR_POSTOP 19
|
||||
#define FR_ASSIGN 20
|
||||
#define FR_EQMULT 21
|
||||
#define FR_EQDIV 22
|
||||
#define FR_EQSHFT 23
|
||||
#define FR_EQXOR 24
|
||||
#define FR_CALL 25
|
||||
#define FR_ITL 26
|
||||
#define FR_LTI 27
|
||||
#define FR_LD 28
|
||||
#define FR_EQADDR 29
|
||||
#define FR_EQNOT 30
|
||||
#define FE_EQNOT 31
|
||||
#define FR_DOCAST 32
|
||||
#define FS_DOCAST 33
|
||||
#define FR_FTOL 34
|
||||
#define FR_LTOF 35
|
||||
#define FR_FTOI 36
|
||||
#define FR_ITOF 37
|
||||
#define FE_EQMULT 38
|
||||
#define FE_EQDIV 39
|
||||
#define FE_EQMOD 40
|
||||
#define FR_TOCHAR 41
|
||||
|
||||
char
|
||||
fe_eqop[], /* 1=FE_EQOP */
|
||||
fe_assign[], /* 2=FE_ASSIGN */
|
||||
fe_eqshft[], /* 3=FE_EQSHFT */
|
||||
fe_eqxor[], /* 4=FE_EQXOR */
|
||||
fe_eqaddr[], /* 5=FE_EQADDR */
|
||||
fc_fix[], /* 6=FC_FIX */
|
||||
fc_rel[], /* 7=FC_REL */
|
||||
fc_btst[], /* 8=FC_BTST */
|
||||
fs_op[], /* 9=FS_OP */
|
||||
fs_itl[], /* 10=FS_ITL */
|
||||
fs_ld[], /* 11=FS_LD */
|
||||
fr_op[], /* 12=FR_OP */
|
||||
fr_mult[], /* 13=FR_MULT */
|
||||
fr_div[], /* 14=FR_DIV */
|
||||
fr_shft[], /* 15=FR_SHFT */
|
||||
fr_xor[], /* 16=FR_XOR */
|
||||
fr_neg[], /* 17=FR_NEG */
|
||||
fr_eqop[], /* 18=FR_EQOP */
|
||||
fr_postop[], /* 19=FR_POSTOP */
|
||||
fr_assign[], /* 20=FR_ASSIGN */
|
||||
fr_eqmult[], /* 21=FR_EQMULT */
|
||||
fr_eqdiv[], /* 22=FR_EQDIV */
|
||||
fr_eqshft[], /* 23=FR_EQSHFT */
|
||||
fr_eqxor[], /* 23=FR_EQXOR */
|
||||
fr_call[], /* 24=FR_CALL */
|
||||
fr_itl[], /* 25=FR_ITL */
|
||||
fr_lti[], /* 26=FR_LTI */
|
||||
fr_ld[], /* 27=FR_LD */
|
||||
fr_eqaddr[], /* 28=FR_EQADDR */
|
||||
fr_eqnot[], /* 29=FR_EQNOT */
|
||||
fe_eqnot[], /* 30=FE_EQNOT */
|
||||
fr_docast[], /* 31=FR_DOCAST */
|
||||
fs_docast[], /* 32=FS_DOCAST */
|
||||
fr_ftol[], /* 34=FE_FTOL */
|
||||
fr_ltof[], /* 35=FE_LTOF */
|
||||
fr_ftoi[], /* 36=FE_FTOI */
|
||||
fr_itof[], /* 37=FE_ITOF */
|
||||
fe_eqmult[], /* 38=FE_EQMULT */
|
||||
fe_eqdiv[], /* 39=FE_EQDIV */
|
||||
fe_eqmod[], /* 40=FE_EQMOD */
|
||||
fr_tochar[]; /* 41=FR_TOCHAR */
|
||||
|
||||
char *codeskels[] {
|
||||
0, /*NULL*/
|
||||
fe_eqop, /*1=FE_EQOP*/
|
||||
fe_assign, /*2=FE_ASSIGN*/
|
||||
fe_eqshft, /*3=FE_EQSHFT*/
|
||||
fe_eqxor, /*4=FE_EQXOR*/
|
||||
fe_eqaddr, /*5=FE_EQADDR*/
|
||||
fc_fix, /*6=FC_FIX*/
|
||||
fc_rel, /*7=FC_REL*/
|
||||
fc_btst, /*8=FC_BTST*/
|
||||
fs_op, /*9=FS_OP*/
|
||||
fs_itl, /*10=FS_ITL*/
|
||||
fs_ld, /*11=FS_LD*/
|
||||
fr_op, /*12=FR_OP*/
|
||||
fr_mult, /*13=FR_MULT*/
|
||||
fr_div, /*14=FR_DIV*/
|
||||
fr_shft, /*15=FR_SHFT*/
|
||||
fr_xor, /*16=FR_XOR*/
|
||||
fr_neg, /*17=FR_NEG*/
|
||||
fr_eqop, /*18=FR_EQOP*/
|
||||
fr_postop, /*19=FR_POSTOP*/
|
||||
fr_assign, /*20=FR_ASSIGN*/
|
||||
fr_eqmult, /*21=FR_EQMULT*/
|
||||
fr_eqdiv, /*22=FR_EQDIV*/
|
||||
fr_eqshft, /*23=FR_EQSHFT*/
|
||||
fr_eqxor, /*24=FR_EQXOR*/
|
||||
fr_call, /*25=FR_CALL*/
|
||||
fr_itl, /*26=FR_ITL*/
|
||||
fr_lti, /*27=FR_LTI*/
|
||||
fr_ld, /*28=FE_LD*/
|
||||
fr_eqaddr, /*29=FE_EQADDR*/
|
||||
fr_eqnot, /*30=FE_EQNOT*/
|
||||
fe_eqnot, /*31=FE_EQNOT*/
|
||||
fr_docast, /*32=FE_DOCAST*/
|
||||
fs_docast, /*33=FS_DOCAST*/
|
||||
fr_ftol, /*34=FE_FTOL*/
|
||||
fr_ltof, /*35=FE_LTOF*/
|
||||
fr_ftoi, /*36=FE_FTOI*/
|
||||
fr_itof, /*37=FE_ITOF*/
|
||||
fe_eqmult, /*38=FE_EQMULT*/
|
||||
fe_eqdiv, /*39=FE_EQDIV*/
|
||||
fe_eqmod, /*40=FE_EQMOD*/
|
||||
fr_tochar, /*41=FR_TOCHAR*/
|
||||
};
|
||||
/*
|
||||
*This is the major table directing the code generation process.
|
||||
*It is indexed by an O_op operator, which is obtained from the
|
||||
*opinfo table for an intermediate code operator. The actual
|
||||
*code skeleton macros are in cskels.c, which are in a linked
|
||||
*list in order of decreasing order of difficulty.
|
||||
*/
|
||||
char optab[][6] {
|
||||
|
||||
/* I I2 effect cc's stack register*/
|
||||
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*0=NULL*/
|
||||
I_ADD, I_INC, I_NULL, FC_FIX, FS_OP, FR_ADD, /*1=ADD*/
|
||||
I_SUB, I_DEC, I_NULL, FC_FIX, FS_OP, FR_ADD, /*2=SUB*/
|
||||
I_MULS, I_MULU, I_NULL, FC_FIX, I_NULL, FR_MULT, /*3=MULT*/
|
||||
I_DIVS, I_DIVU, I_NULL, FC_FIX, I_NULL, FR_DIV, /*4=DIV*/
|
||||
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*5=MOD*/
|
||||
I_ASR, I_LSR, I_NULL, FC_FIX, I_NULL, FR_SHFT, /*6=RSH*/
|
||||
I_ASL, I_LSL, I_NULL, FC_FIX, I_NULL, FR_SHFT, /*7=LSH*/
|
||||
I_AND, I_AND, I_NULL, FC_FIX, FS_OP, FR_ADD, /*8=AND*/
|
||||
I_OR, I_OR, I_NULL, FC_FIX, FS_OP, FR_ADD, /*9=OR*/
|
||||
I_EOR, I_EOR, I_NULL, FC_FIX, I_NULL, FR_XOR, /*10=XOR*/
|
||||
I_NULL, I_NULL, I_NULL, FC_FIX, I_NULL, I_NULL, /*11=NOT*/
|
||||
I_NEG, I_NEG, I_NULL, FC_FIX, I_NULL, FR_NEG, /*12=NEG*/
|
||||
I_NOT, I_NOT, I_NULL, I_NULL, I_NULL, FR_NEG, /*13=COMPL*/
|
||||
I_SUB, I_DEC, FE_EQOP, FC_FIX, I_NULL, FR_EQOP, /*14=PREDEC*/
|
||||
I_ADD, I_INC, FE_EQOP, FC_FIX, I_NULL, FR_EQOP, /*15=PREINC*/
|
||||
I_SUB, I_DEC, FE_EQOP, I_NULL, I_NULL, FR_POSTOP, /*16=POSTDEC*/
|
||||
I_ADD, I_INC, FE_EQOP, I_NULL, I_NULL, FR_POSTOP, /*17=POSTINC*/
|
||||
I_MOVE, I_CLR, FE_ASSIGN, I_NULL, I_NULL, FR_ASSIGN, /*18=ASSIGN*/
|
||||
I_ADD, I_INC, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*19=EQADD*/
|
||||
I_SUB, I_DEC, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*20=EQSUB*/
|
||||
I_MULS, I_MULU, FE_EQMULT, FC_FIX, I_NULL, FR_EQMULT, /*21=EQMULT*/
|
||||
I_DIVS, I_DIVU, FE_EQDIV, FC_FIX, I_NULL, FR_EQDIV, /*22=EQDIV*/
|
||||
I_DIVS, I_DIVU, FE_EQMOD, I_NULL, I_NULL, FR_EQDIV, /*23=EQMOD*/
|
||||
I_ASR, I_LSR, FE_EQSHFT, I_NULL, I_NULL, FR_EQSHFT, /*24=EQRSH*/
|
||||
I_ASL, I_LSL, FE_EQSHFT, I_NULL, I_NULL, FR_EQSHFT, /*25=EQLSH*/
|
||||
I_AND, I_AND, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*26=EQAND*/
|
||||
I_OR, I_OR, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*27=EQOR*/
|
||||
I_EOR, I_EOR, FE_EQXOR, FC_FIX, I_NULL, FR_EQXOR, /*28=EQXOR*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_CALL, /*29=FJSR*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*30=EQUALS*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*31=NEQUALS*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*32=GREAT*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*33=GREATEQ*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*34=LESS*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*35=LESSEQ*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, FS_ITL, FR_ITL, /*36=INT2L*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_LTI, /*37=LONG2I*/
|
||||
I_BTST, I_BTST, I_NULL, FC_BTST, I_NULL, I_NULL, /*38=BTST*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, FS_LD, FR_LD, /*39=LOAD*/
|
||||
I_MULS, I_MULU, I_NULL, I_NULL, I_NULL, FR_MULT, /*40=LMULT*/
|
||||
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*41=LDIV*/
|
||||
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*42=LMOD*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*43=NULL*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*44=NULL*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*45=NULL*/
|
||||
I_NULL, I_NULL, FE_EQADDR, I_NULL, I_NULL, FR_EQADDR, /*46=EQADDR*/
|
||||
I_NOT, I_NOT, FE_EQNOT, I_NULL, I_NULL, FR_EQNOT, /*47=EQNOT*/
|
||||
I_NEG, I_NEG, FE_EQNOT, I_NULL, I_NULL, FR_EQNOT, /*48=EQNEG*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, FS_DOCAST, FR_DOCAST, /*49=DOCAST*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*50=STASSIGN*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_LTOF, /*51=LONG2F*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_FTOL, /*52=FLOAT2L*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_ITOF, /*53=INT2F*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_FTOI, /*54=FLOAT2I*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_TOCHAR, /*55=TOCHAR*/
|
||||
};
|
||||
|
||||
|
||||
/*this maps comparison operators and comparison types into the*/
|
||||
/*actual branch opcode used.*/
|
||||
char brtab[][2] {
|
||||
I_BEQ, I_BEQ, /*EQUALS*/
|
||||
I_BNE, I_BNE, /*NEQUALS*/
|
||||
I_BGT, I_BHI, /*GREAT*/
|
||||
I_BGE, I_BCC, /*GREATEQ*/
|
||||
I_BLT, I_BLO, /*LESS*/
|
||||
I_BLE, I_BLS, /*LESSEQ*/
|
||||
};
|
||||
|
||||
/*turns !x>y into x<=y*/
|
||||
int invrel[] { NEQUALS, EQUALS, LESSEQ, LESS, GREATEQ, GREAT };
|
||||
|
||||
/*turns x>y into y<=x*/
|
||||
int swaprel[] { EQUALS, NEQUALS, LESS, LESSEQ, GREAT, GREATEQ };
|
||||
|
||||
/*code skeleton built-in strings*/
|
||||
char *strtab[] {
|
||||
"move", /*MOV*/
|
||||
"move.l", /*MOVL*/
|
||||
"jsr", /*JSR*/
|
||||
"clr", /*CLR*/
|
||||
"clr.l", /*CLRL*/
|
||||
"ext.w", /*EXTW*/
|
||||
"ext.l", /*EXTL*/
|
||||
"lea", /*LEA*/
|
||||
"(sp)", /*STK*/
|
||||
};
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
#ifndef NODEBUG
|
||||
|
||||
char invalid[] "INVALID";
|
||||
|
||||
char *opname[] {
|
||||
invalid, /*0*/
|
||||
"+", /*1*/
|
||||
"-", /*2*/
|
||||
"*", /*3*/
|
||||
"/", /*4*/
|
||||
"%", /*5*/
|
||||
">>", /*6*/
|
||||
"<<", /*7*/
|
||||
"&", /*8*/
|
||||
"|", /*9*/
|
||||
"^", /*10*/
|
||||
"!", /*11*/
|
||||
"U-", /*12*/
|
||||
"~", /*13*/
|
||||
"--p", /*14*/
|
||||
"++p", /*15*/
|
||||
"p--", /*16*/
|
||||
"p++", /*17*/
|
||||
"=", /*18*/
|
||||
"+=", /*19*/
|
||||
"-=", /*20*/
|
||||
"*=", /*21*/
|
||||
"/=", /*22*/
|
||||
"%=", /*23*/
|
||||
">>=", /*24*/
|
||||
"<<=", /*25*/
|
||||
"&=", /*26*/
|
||||
"|=", /*27*/
|
||||
"^=", /*28*/
|
||||
"jsr", /*29*/
|
||||
"==", /*30*/
|
||||
"!=", /*31*/
|
||||
">", /*32*/
|
||||
">=", /*33*/
|
||||
"<", /*34*/
|
||||
"<=", /*35*/
|
||||
"int->long", /*36*/
|
||||
"long->int", /*37*/
|
||||
"btst", /*38*/
|
||||
"load", /*39*/
|
||||
"long*", /*40*/
|
||||
"long/", /*41*/
|
||||
"long%", /*42*/
|
||||
"long*=", /*43*/
|
||||
"long/=", /*44*/
|
||||
"long%=", /*45*/
|
||||
"=addr", /*46*/
|
||||
"=not", /*47*/
|
||||
"=neg", /*48*/
|
||||
"docast", /*49*/
|
||||
"st=", /*50*/
|
||||
"long->float", /*51*/
|
||||
"float->long", /*52*/
|
||||
"int->float", /*53*/
|
||||
"float->int", /*54*/
|
||||
"tochar", /*55*/
|
||||
invalid, /*56*/
|
||||
invalid, /*57*/
|
||||
invalid, /*58*/
|
||||
invalid, /*59*/
|
||||
"U&", /*60*/
|
||||
"U*", /*61*/
|
||||
"&&", /*62*/
|
||||
"||", /*63*/
|
||||
"?", /*64*/
|
||||
":", /*65*/
|
||||
",", /*66*/
|
||||
"cint", /*67*/
|
||||
"clong", /*68*/
|
||||
"symbol", /*69*/
|
||||
"++a", /*70*/
|
||||
"a--", /*71*/
|
||||
"call", /*72*/
|
||||
"call()", /*73*/
|
||||
"bitfield", /*74*/
|
||||
"if", /*75*/
|
||||
"init", /*76*/
|
||||
"loadR0", /*77*/
|
||||
"divlong", /*78*/
|
||||
};
|
||||
|
||||
char *types[] {
|
||||
invalid, /*0=TYPELESS*/
|
||||
"char", /*1=CHAR*/
|
||||
invalid, /*2=SHORT*/
|
||||
"int", /*3=INT*/
|
||||
"long", /*4=LONG*/
|
||||
invalid, /*5=UCHAR*/
|
||||
invalid, /*6=USHORT*/
|
||||
"uint", /*7=UINT*/
|
||||
invalid, /*8=ULONG*/
|
||||
"float", /*9=FLOAT*/
|
||||
invalid, /*10=DOUBLE*/
|
||||
"struct", /*11=STRUCT*/
|
||||
invalid, /*12=undefined*/
|
||||
invalid, /*13=undefined*/
|
||||
invalid, /*14=undefined*/
|
||||
invalid, /*15=undefined*/
|
||||
};
|
||||
|
||||
char *suvals[] {
|
||||
"zero",
|
||||
"one",
|
||||
"quick",
|
||||
"small",
|
||||
"constant",
|
||||
"Areg",
|
||||
"Dreg",
|
||||
"addressable",
|
||||
"loadable",
|
||||
"easy",
|
||||
"hard",
|
||||
"veryhard",
|
||||
};
|
||||
|
||||
int level;
|
||||
|
||||
putexpr(name,tp)
|
||||
char *name;
|
||||
struct tnode *tp;
|
||||
{
|
||||
printf("%s\n",name);
|
||||
putsexpr(tp);
|
||||
}
|
||||
|
||||
putsexpr(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
register struct tnode *ltp;
|
||||
|
||||
level++;
|
||||
ltp = tp->t_left;
|
||||
outlevel();
|
||||
printf("%s ",opname[tp->t_op]);
|
||||
if( tp->t_op == BFIELD || tp->t_op == IFGOTO ) {
|
||||
if( tp->t_op == BFIELD )
|
||||
printf("off=%d len=%d\n",(tp->t_su>>8)&0377,tp->t_su&0377);
|
||||
else
|
||||
printf("%s goto L%d\n",tp->t_type?"TRUE":"FALSE",tp->t_su);
|
||||
putsexpr(tp->t_left);
|
||||
level--;
|
||||
return;
|
||||
}
|
||||
puttsu(tp);
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case DCLONG:
|
||||
case CLONG:
|
||||
case CFLOAT: /*[vlh] 3.4 */
|
||||
printf(" %x.%x\n",tp->t_lvalue.hiword,tp->t_lvalue.loword);
|
||||
break;
|
||||
|
||||
|
||||
case CINT:
|
||||
printf(" %d\n",tp->t_value);
|
||||
break;
|
||||
|
||||
case AUTODEC:
|
||||
case AUTOINC:
|
||||
printf(" R%d\n",tp->t_reg);
|
||||
break;
|
||||
|
||||
case SYMBOL:
|
||||
switch( tp->t_sc ) {
|
||||
|
||||
case REGISTER:
|
||||
printf(" R%d",tp->t_reg);
|
||||
break;
|
||||
|
||||
case CINDR:
|
||||
printf(" %d\n",tp->t_offset);
|
||||
break;
|
||||
|
||||
case CLINDR:
|
||||
case CFINDR: /* [vlh] 3.4 */
|
||||
printf(" %x.%x\n",tp->t_offset,tp->t_ssp);
|
||||
break;
|
||||
|
||||
case REGOFF:
|
||||
printf(" %d(R%d)",tp->t_offset,tp->t_reg);
|
||||
break;
|
||||
|
||||
case EXTERNAL:
|
||||
case EXTOFF:
|
||||
printf(" %s+%d",tp->t_symbol,tp->t_offset);
|
||||
if( tp->t_sc == EXTOFF )
|
||||
printf("(R%d)",tp->t_reg);
|
||||
break;
|
||||
|
||||
case STATIC:
|
||||
case STATOFF:
|
||||
printf(" L%d+%d",tp->t_label,tp->t_offset);
|
||||
if( tp->t_sc == STATOFF )
|
||||
printf("(R%d)",tp->t_reg);
|
||||
break;
|
||||
|
||||
case INDEXED:
|
||||
printf(" %d(R%d,R%d)",tp->t_offset,tp->t_reg,tp->t_xreg);
|
||||
break;
|
||||
}
|
||||
putchar('\n');
|
||||
break;
|
||||
|
||||
case IFGOTO:
|
||||
putsexpr(tp->t_left);
|
||||
break;
|
||||
|
||||
default:
|
||||
putchar('\n');
|
||||
putsexpr(tp->t_left);
|
||||
if( binop(tp->t_op) )
|
||||
putsexpr(tp->t_right);
|
||||
break;
|
||||
}
|
||||
level--;
|
||||
}
|
||||
|
||||
outlevel()
|
||||
{
|
||||
register int i;
|
||||
|
||||
for( i = 0; i < level; i++ )
|
||||
putchar('\t');
|
||||
}
|
||||
|
||||
puttsu(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
register int i;
|
||||
|
||||
if( suptype(tp->t_type) )
|
||||
putchar('*');
|
||||
printf("%s ",types[btype(tp->t_type)]);
|
||||
if( tp->t_su != 0 || (tp->t_op == CINT && tp->t_value == 0) ) {
|
||||
i = tp->t_su >> 8;
|
||||
if( i > 15 || i < 0 )
|
||||
printf("INVALID");
|
||||
else
|
||||
printf("%s",suvals[tp->t_su>>8]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,2 @@
|
||||
$ lo68 -r -o c168.rel canon.o codegen.o cskels.o init.o interf.o main.o -
|
||||
optab.o putexpr.o smatch.o sucomp.o tabl.o util.o version.o
|
||||
@@ -0,0 +1,20 @@
|
||||
$ set noon
|
||||
$ vsend CANON.C
|
||||
$ vsend CODEGEN.C
|
||||
$ vsend CSKELS.C
|
||||
$ vsend INTERF.C
|
||||
$ vsend MAIN.C
|
||||
$ vsend OPTAB.C
|
||||
$ vsend PUTEXPR.C
|
||||
$ vsend SMATCH.C
|
||||
$ vsend SUCOMP.C
|
||||
$ vsend TABL.C
|
||||
$ vsend UTIL.C
|
||||
$ vsend VERSION.C
|
||||
$ vsend CGEN.H
|
||||
$ vsend CSKEL.H
|
||||
$ vsend ICODE.H
|
||||
$ vsend machine.68k
|
||||
$ vsend LINK.SUB
|
||||
$ vsend MAKE.SUB
|
||||
$ vsend done
|
||||
517
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/smatch.c
Normal file
517
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/smatch.c
Normal file
@@ -0,0 +1,517 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/* Code Skeleton expansion and matching */
|
||||
|
||||
#include "cgen.h"
|
||||
#include "cskel.h"
|
||||
#define SK_TYPE(x) (x&017)
|
||||
|
||||
/* expand - code skeleton expansion*/
|
||||
/* Handles the expansion of code skeleton macros.*/
|
||||
expand(tp,cookie,freg,skp) /* returns register result is in*/
|
||||
struct tnode *tp; /* pointer to expression tree*/
|
||||
int cookie; /* goal of expression tree*/
|
||||
int freg; /* register to leave results in*/
|
||||
struct skeleton *skp; /* pointer to code skeleton*/
|
||||
{
|
||||
register int op, nreg, reg;
|
||||
register int c;
|
||||
register int extf, i2f;
|
||||
register struct tnode *ltp, *rtp;
|
||||
register char *p;
|
||||
register int i, inaddreg, sreg, flag, subtrees, scookie;
|
||||
register char *macro;
|
||||
|
||||
#ifndef NODEBUG
|
||||
if( eflag )
|
||||
printf("expand op=%d left=%x right=%x skp=%o\n",tp->t_op,
|
||||
skp->sk_left,skp->sk_right,skp);
|
||||
#endif
|
||||
if( ((op=tp->t_op) >= MULT && op <= XOR) || tp->t_type == CHAR )
|
||||
freg = dreg(freg);
|
||||
macro = skp->sk_def;
|
||||
extf = 0;
|
||||
i2f = 0;
|
||||
rtp = ltp = tp->t_left;
|
||||
subtrees = 1;
|
||||
if( binop(op) ) {
|
||||
subtrees++;
|
||||
rtp = tp->t_right;
|
||||
if( (longorptr(tp->t_type)) && (op == DIV || op == MOD ||
|
||||
(op != MULT && (isdreg(freg)) &&
|
||||
!(longorptr(ltp->t_type)) && !(longorptr(rtp->t_type)))) )
|
||||
extf++;
|
||||
switch( op ) {
|
||||
|
||||
case RSH:
|
||||
case LSH:
|
||||
case EQLSH:
|
||||
case EQRSH:
|
||||
if( unsign(ltp->t_type) )
|
||||
i2f++;
|
||||
break;
|
||||
|
||||
case MULT:
|
||||
case EQMULT:
|
||||
case DIV:
|
||||
case MOD:
|
||||
case EQDIV:
|
||||
case EQMOD:
|
||||
if( unsign(ltp->t_type) || unsign(rtp->t_type) )
|
||||
i2f++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
nreg = freg + 1;
|
||||
while( c = *macro++ ) {
|
||||
c =& 0xff;
|
||||
switch( c ) {
|
||||
|
||||
default:
|
||||
putchar(c);
|
||||
break;
|
||||
|
||||
case POP:
|
||||
stacksize--;
|
||||
printf("(sp)+");
|
||||
break;
|
||||
|
||||
case POP4:
|
||||
stacksize--;
|
||||
popstack(4);
|
||||
break;
|
||||
|
||||
case POP8:
|
||||
stacksize =- 2;
|
||||
popstack(8);
|
||||
break;
|
||||
|
||||
case PSH:
|
||||
if( cookie == FORSP ) /*don't affect sp*/
|
||||
printf("(sp)");
|
||||
else
|
||||
printf("-(sp)");
|
||||
stacksize++;
|
||||
break;
|
||||
|
||||
case MOV:
|
||||
case MOVL:
|
||||
case JSR:
|
||||
case CLR:
|
||||
case CLRL:
|
||||
case EXTW:
|
||||
case EXTL:
|
||||
case LEA:
|
||||
case STK:
|
||||
printf("%s",strtab[c-128]);
|
||||
break;
|
||||
|
||||
case OPCALL:
|
||||
if( isfloat(tp->t_type) || isfloat(ltp->t_type) ) {
|
||||
switch( op ) {
|
||||
|
||||
case ADD:
|
||||
case EQADD:
|
||||
printf("_fpadd");
|
||||
break;
|
||||
|
||||
case SUB:
|
||||
case EQSUB:
|
||||
printf("_fpsub");
|
||||
break;
|
||||
|
||||
case MULT:
|
||||
case EQMULT:
|
||||
printf("_fpmult");
|
||||
break;
|
||||
|
||||
case DIV:
|
||||
case EQDIV:
|
||||
printf("_fpdiv");
|
||||
break;
|
||||
|
||||
case UMINUS:
|
||||
case EQNEG:
|
||||
printf("_fpneg");
|
||||
break;
|
||||
|
||||
case FLOAT2L:
|
||||
case FLOAT2I:
|
||||
printf("_fpftol");
|
||||
break;
|
||||
|
||||
case LONG2F:
|
||||
case INT2F:
|
||||
printf("_fpltof");
|
||||
break;
|
||||
|
||||
case EQUALS:
|
||||
case NEQUALS:
|
||||
case GREAT:
|
||||
case GREATEQ:
|
||||
case LESS:
|
||||
case LESSEQ:
|
||||
printf("_fpcmp");
|
||||
break;
|
||||
|
||||
default:
|
||||
error("invalid floating op %d\n",op);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch( op ) {
|
||||
|
||||
case MULT:
|
||||
case LMULT:
|
||||
printf("lmul");
|
||||
break;
|
||||
|
||||
case DIV:
|
||||
case LDIV:
|
||||
printf("ldiv");
|
||||
break;
|
||||
|
||||
case MOD:
|
||||
case LMOD:
|
||||
printf("lrem");
|
||||
break;
|
||||
|
||||
default:
|
||||
error("opcall bad op %d",op);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TLEFT:
|
||||
outtype( leafop(op) ? tp->t_type : ltp->t_type );
|
||||
break;
|
||||
|
||||
case TLEFTL:
|
||||
outatype( leafop(op) ? tp->t_type : ltp->t_type );
|
||||
break;
|
||||
|
||||
case TEITHER:
|
||||
if( longorptr(rtp->t_type) || longorptr(ltp->t_type) )
|
||||
outtype(LONG);
|
||||
break;
|
||||
|
||||
case TRIGHT:
|
||||
outtype(rtp->t_type);
|
||||
break;
|
||||
|
||||
case OP:
|
||||
case AOP:
|
||||
if( c == AOP || i2f )
|
||||
i = optab[op][1];
|
||||
else
|
||||
i = optab[op][0];
|
||||
printf(mnemonics[i]);
|
||||
break;
|
||||
|
||||
case LADDR:
|
||||
case RADDR:
|
||||
p = (c==RADDR?rtp:ltp);
|
||||
outaexpr(p,IMMED);
|
||||
break;
|
||||
|
||||
case CR:
|
||||
outcreg(freg);
|
||||
break;
|
||||
|
||||
case NR:
|
||||
outcreg(nreg);
|
||||
break;
|
||||
|
||||
case CAR:
|
||||
outcreg(areg(freg));
|
||||
break;
|
||||
|
||||
case NAR:
|
||||
outcreg(areg(nreg));
|
||||
break;
|
||||
|
||||
case EXL:
|
||||
outextend(ltp,LONG,freg);
|
||||
break;
|
||||
|
||||
case EXRL:
|
||||
case EXRLN:
|
||||
outextend(rtp,ltp->t_type,c==EXRL?freg:nreg);
|
||||
break;
|
||||
|
||||
case EXLR:
|
||||
case EXLRN:
|
||||
outextend(ltp,rtp->t_type,c==EXLR?freg:nreg);
|
||||
break;
|
||||
|
||||
case LEFT:
|
||||
case RIGHT:
|
||||
subtrees--;
|
||||
case TREE:
|
||||
p = (c==LEFT?ltp:c==RIGHT?rtp:tp);
|
||||
flag = *macro++;
|
||||
scookie = FORREG;
|
||||
if( flag & S_STACK ) {
|
||||
if( cookie == FORSP )
|
||||
scookie = FORSP;
|
||||
else
|
||||
scookie = FORSTACK;
|
||||
}
|
||||
else if( flag & S_FORCC )
|
||||
scookie = FORCC;
|
||||
if( flag & S_NEXT )
|
||||
reg = nreg;
|
||||
else
|
||||
reg = freg;
|
||||
if( flag & S_INDR ) {
|
||||
if( p->t_op != INDR )
|
||||
error("code skeleton error: %d\n",op);
|
||||
p = p->t_left; /*skip INDR*/
|
||||
if( coffset(p) ) {
|
||||
p = p->t_left;
|
||||
if( longorptr(p->t_type) == 0 && (flag&S_STACK) != 0 )
|
||||
p = tnalloc(INT2L,LONG,0,0,p);
|
||||
}
|
||||
reg = areg(reg);
|
||||
}
|
||||
sreg = codegen(p,scookie,reg); /*code for subtree*/
|
||||
if( scookie == FORREG ) {
|
||||
if( flag & S_INDR ) {
|
||||
if( isdreg(sreg) )
|
||||
outmovr(sreg,areg(reg),p);
|
||||
}
|
||||
else if( flag & S_NEXT )
|
||||
nreg = sreg;
|
||||
else if( sreg != reg ) {
|
||||
/*
|
||||
* result was not in expected register, if remaining sub-tree can be
|
||||
* compiled using the remaining registers, update current and next
|
||||
* registers, saving us the trouble of moving the register.
|
||||
*/
|
||||
if( c == TREE || ((isdreg(sreg)) && subtrees > 0 &&
|
||||
((c == LEFT &&
|
||||
sucomp(rtp,sreg,0) <= skp->sk_right &&
|
||||
sucomp(rtp,sreg,1) <= SU_ANY) ||
|
||||
( c == RIGHT &&
|
||||
sucomp(ltp,sreg,0) <= skp->sk_left &&
|
||||
sucomp(ltp,sreg,1) <= SU_ANY))) ) {
|
||||
freg = dreg(sreg);
|
||||
nreg = freg + 1;
|
||||
}
|
||||
else
|
||||
outmovr(sreg,dreg(freg),p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LOFFSET:
|
||||
case ROFFSET:
|
||||
p = (c==LOFFSET) ? ltp->t_left : rtp->t_left;
|
||||
if((p=coffset(p)) != 0 && (p->t_op != CINT || p->t_value != 0))
|
||||
outaexpr(p,NOTIMMED);
|
||||
break;
|
||||
|
||||
case MODSWAP:
|
||||
switch( op ) {
|
||||
|
||||
case MOD:
|
||||
case EQMOD:
|
||||
case LMOD:
|
||||
case LEQMOD:
|
||||
outswap(freg);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
if( extf && cookie == FORREG && (isdreg(freg)) ) {
|
||||
if( unsign(ltp->t_type) || unsign(rtp->t_type) )
|
||||
outuext(freg);
|
||||
else
|
||||
outext(freg);
|
||||
}
|
||||
#ifndef NODEBUG
|
||||
if( eflag )
|
||||
printf("ending expand skp=%o\n",skp);
|
||||
#endif
|
||||
return(freg);
|
||||
}
|
||||
|
||||
/*
|
||||
* match - try to match expression tree with code skeleton
|
||||
* Given the expression tree, tries to match the given tree with
|
||||
* the appropriate code skeleton. The code skeleton list is
|
||||
* gotten from the root operator and the cookie value. The code
|
||||
* skeleton list is then searched, checking the Sethy-Ullman numbers
|
||||
* of the sub-trees against the Sethy-Ullman numbers in the code
|
||||
* skeleton list. If the Sethy-Ullman numbers are OK, then the
|
||||
* left and right sub-trees are checked for compatability, e.g.
|
||||
* integer pointers, etc. If a match is found, the code skeleton
|
||||
* list pointer is returned.
|
||||
*/
|
||||
char *match(tp,cookie,reg) /* returns ptr to code skeleton*/
|
||||
/* or 0 if no skeleton*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
int cookie; /* goal for code expansion*/
|
||||
int reg; /* register to use*/
|
||||
{
|
||||
register struct skeleton *skp;
|
||||
register int op, bop, opndx;
|
||||
int i;
|
||||
register struct tnode *ltp, *rtp;
|
||||
|
||||
#ifndef NODEBUG
|
||||
if( mflag )
|
||||
printf("match op=%d cookie=%d reg=%d\n",tp->t_op,cookie,reg);
|
||||
#endif
|
||||
if( (op=tp->t_op) >= LCGENOP )
|
||||
return(0);
|
||||
if( leafop(op) )
|
||||
ltp = tp;
|
||||
else
|
||||
ltp = tp->t_left;
|
||||
if( (bop=binop(op)) ) {
|
||||
rtp = tp->t_right;
|
||||
if( convop(ltp->t_op) ) {
|
||||
if( op != LSH && notconvop(rtp->t_op) ) {
|
||||
if( !(unsign(ltp->t_left->t_type)) || op == ASSIGN ) {
|
||||
tp->t_left = ltp->t_left;
|
||||
if( (skp=match(tp,cookie,reg)) != 0 )
|
||||
return(skp);
|
||||
tp->t_left = ltp;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( convop(rtp->t_op) ) {
|
||||
if( !(unsign(rtp->t_left->t_type)) || op == ASSIGN ) {
|
||||
tp->t_right = rtp->t_left;
|
||||
if( (skp=match(tp,cookie,reg)) != 0 )
|
||||
return(skp);
|
||||
tp->t_right = rtp;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch( cookie ) {
|
||||
|
||||
case FORCC:
|
||||
i = 3;
|
||||
break;
|
||||
|
||||
case FOREFF:
|
||||
i = 2;
|
||||
break;
|
||||
|
||||
case FORSTACK:
|
||||
case FORSP:
|
||||
i = 4;
|
||||
break;
|
||||
|
||||
case FORREG:
|
||||
i = 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
error("match cookie=%d\n",cookie);
|
||||
return(0);
|
||||
}
|
||||
#ifndef NODEBUG
|
||||
if( mflag )
|
||||
printf("match op=%d i=%d ",op,i);
|
||||
#endif
|
||||
if( !(i=optab[op][i]) )
|
||||
return(0);
|
||||
skp = codeskels[i];
|
||||
#ifndef NODEBUG
|
||||
if( mflag )
|
||||
printf("codeskels[%d]=%o\n",i,skp);
|
||||
#endif
|
||||
#ifndef NODEBUG
|
||||
if(mflag) {
|
||||
printf("match LEFT ");
|
||||
puttsu(ltp);
|
||||
if(bop) {
|
||||
printf(" RIGHT ");
|
||||
puttsu(rtp);
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
#endif
|
||||
for( ; skp->sk_left != 0; skp++ ) {
|
||||
#ifndef NODEBUG
|
||||
if( mflag > 1 )
|
||||
printf("sk_left=%x sk_right=%x\n",skp->sk_left,skp->sk_right);
|
||||
#endif
|
||||
if( !(skelmatch(ltp,skp->sk_left)) )
|
||||
continue;
|
||||
if( bop && !(skelmatch(rtp,skp->sk_right)) )
|
||||
continue;
|
||||
#ifndef NODEBUG
|
||||
if( mflag )
|
||||
printf("match found skp=%o left=%x right=%x\n",skp,
|
||||
skp->sk_left,skp->sk_right);
|
||||
#endif
|
||||
return(skp);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* skelmatch - sub-tree type matching for match*/
|
||||
/* This checks a subtree for type compatability in match.*/
|
||||
skelmatch(tp,skinfo) /* returns 1 if matched, else 0*/
|
||||
struct tnode *tp; /* pointer to expression tree*/
|
||||
int skinfo;
|
||||
{
|
||||
register int type, unsignf, const, stype;
|
||||
|
||||
if( tp->t_su > skinfo || ((skinfo&T_INDR) && tp->t_op != INDR) )
|
||||
return(0);
|
||||
stype = SK_TYPE(skinfo);
|
||||
type = tp->t_type;
|
||||
if( function(type) )
|
||||
type = btype(type);
|
||||
if( unsignf = unsign(type) )
|
||||
type = basetype(type);
|
||||
const = 0;
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case CFLOAT: /* [vlh] 3.4 */
|
||||
case CLONG:
|
||||
if( tp->t_su > SU_CONST )
|
||||
break;
|
||||
case CINT:
|
||||
const++;
|
||||
break;
|
||||
}
|
||||
switch( stype ) {
|
||||
|
||||
case T_CHAR:
|
||||
return( type == CHAR );
|
||||
|
||||
case T_ANY: /*either int or char*/
|
||||
if( type == CHAR )
|
||||
return(1);
|
||||
case T_INT:
|
||||
return( type == INT || const );
|
||||
|
||||
case T_UNSN:
|
||||
return( unsignf );
|
||||
|
||||
case T_LONG:
|
||||
return( longorptr(type) );
|
||||
|
||||
case T_FLOAT:
|
||||
return( isfloat(type) );
|
||||
|
||||
default:
|
||||
error("skelmatch type: %x",stype);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
110
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/sucomp.c
Normal file
110
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/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 int su, sur, op, i;
|
||||
register struct tnode *ltp, *rtp;
|
||||
|
||||
nregs = dreg(nregs);
|
||||
if( binop(op=tp->t_op) ) {
|
||||
ltp = tp->t_left;
|
||||
rtp = tp->t_right;
|
||||
}
|
||||
else if( unaryop(op) )
|
||||
ltp = tp->t_left;
|
||||
switch( op ) {
|
||||
|
||||
case CLONG:
|
||||
if( tp->t_lvalue >= 0x8000L || tp->t_lvalue <= 0xffff8000L ) {
|
||||
su = SU_ADDR;
|
||||
break;
|
||||
}
|
||||
i = tp->t_lvalue;
|
||||
case CINT:
|
||||
if( op == CINT )
|
||||
i = tp->t_value;
|
||||
if( i == 0 )
|
||||
su = SU_ZERO;
|
||||
else if( i == 1 )
|
||||
su = SU_ONE;
|
||||
else if( i >= 1 && i <= QUICKVAL )
|
||||
su = SU_SMALL;
|
||||
else if( i >= -128 && i <= 127 )
|
||||
su = SU_QUICK;
|
||||
else
|
||||
su = SU_CONST;
|
||||
break;
|
||||
|
||||
case COMMA:
|
||||
su = max(sucomp(rtp,nregs,flag),sucomp(ltp,nregs,flag));
|
||||
su = max(su,SU_EASY);
|
||||
break;
|
||||
|
||||
case ADDR:
|
||||
su = sucomp(ltp,nregs,flag);
|
||||
break;
|
||||
|
||||
case CFLOAT:
|
||||
case DCLONG:
|
||||
case AUTOINC:
|
||||
case AUTODEC:
|
||||
su = SU_ADDR;
|
||||
break;
|
||||
|
||||
case SYMBOL:
|
||||
if( tp->t_sc != REGISTER )
|
||||
su = SU_ADDR;
|
||||
else if( isdreg(tp->t_reg) )
|
||||
su = SU_REG;
|
||||
else
|
||||
su = SU_AREG;
|
||||
break;
|
||||
|
||||
case LDIV:
|
||||
case LMOD:
|
||||
case LMULT:
|
||||
case CALL:
|
||||
sucomp(rtp,nregs,flag);
|
||||
case NACALL:
|
||||
sucomp(ltp,nregs,flag);
|
||||
su = SU_VHARD; /*very hard*/
|
||||
break;
|
||||
|
||||
default:
|
||||
su = sucomp(ltp,nregs,flag);
|
||||
if( binop(op) ) {
|
||||
if( su <= SU_ADDR )
|
||||
su = max(su,sucomp(rtp,nregs,flag));
|
||||
else {
|
||||
sur = sucomp(rtp,nregs+1,flag);
|
||||
if( sur > SU_ADDR && nregs > HICREG )
|
||||
su = max(su,SU_HARD);
|
||||
}
|
||||
su = max(SU_EASY,su);
|
||||
}
|
||||
else if( su <= SU_XREG )
|
||||
su = max(SU_EASY,su);
|
||||
if( isfloat(tp->t_type) )
|
||||
su = SU_VHARD;
|
||||
break;
|
||||
}
|
||||
if( flag )
|
||||
tp->t_su = su;
|
||||
return(su);
|
||||
}
|
||||
118
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/tabl.c
Normal file
118
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/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 - int required on left*/
|
||||
/*004000-- OPRWORD - int required on right*/
|
||||
/*010000-- OPCOM commutative*/
|
||||
/*020000-- OPRAS - right associative*/
|
||||
/*040000-- OPTERM - termination node*/
|
||||
/*100000 - OPCONVS - conversion operator*/
|
||||
int opinfo[] {
|
||||
TRMPRI, /*EOF*/
|
||||
ADDPRI|OPCOM|OPBIN, /*ADD - expr + expr*/
|
||||
ADDPRI|OPBIN, /*SUB - expr - expr*/
|
||||
MULPRI|OPCOM|OPBIN, /*MULT - expr * expr*/
|
||||
MULPRI|OPBIN, /*DIV - expr / expr*/
|
||||
MULPRI|OPBIN, /*MOD - expr % expr*/
|
||||
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*RSH - expr >> expr*/
|
||||
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*LSH - expr << expr*/
|
||||
ANDPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*AND - expr & expr*/
|
||||
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*OR - expr | expr*/
|
||||
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*XOR - expr ^ expr*/
|
||||
UNOPRI|OPRAS|OPLWORD, /*NOT - ! expr*/
|
||||
UNOPRI|OPRAS, /*UMINUS - - expr*/
|
||||
UNOPRI|OPRAS|OPLWORD, /*COMPL - ~ expr*/
|
||||
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREDEC - --lvalue*/
|
||||
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREINC - ++lvalue*/
|
||||
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTDEC - lvalue--*/
|
||||
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTINC - lvalue++*/
|
||||
ASGPRI|ASGOP, /*ASSIGN - lvalue = expr*/
|
||||
ASGPRI|ASGOP, /*EQADD - lvalue += expr*/
|
||||
ASGPRI|ASGOP, /*EQSUB - lvalue -= expr*/
|
||||
ASGPRI|ASGOP, /*EQMULT - lvalue *= expr*/
|
||||
ASGPRI|ASGOP, /*EQDIV - lvalue /= expr*/
|
||||
ASGPRI|ASGOP, /*EQMOD - lvalue %= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQRSH - lvalue >>= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQLSH - lvalue <<= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQAND - lvalue &= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQOR - lvalue |= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQXOR - lvalue ^= expr*/
|
||||
TRMPRI, /*FJSR - generate function jsr*/
|
||||
EQLPRI|OPREL|OPBIN, /*EQUALS - expr == expr*/
|
||||
EQLPRI|OPREL|OPBIN, /*NEQUALS - expr != expr*/
|
||||
RELPRI|OPREL|OPBIN, /*GREAT - expr > expr*/
|
||||
RELPRI|OPREL|OPBIN, /*GREATEQ - expr >= expr*/
|
||||
RELPRI|OPREL|OPBIN, /*LESS - expr < expr*/
|
||||
RELPRI|OPREL|OPBIN, /*LESSEQ - expr <= expr*/
|
||||
TRMPRI|OPCONVS, /*INT2L*/
|
||||
TRMPRI|OPCONVS, /*LONG2I*/
|
||||
TRMPRI|OPBIN, /*BTST*/
|
||||
TRMPRI, /*LOAD*/
|
||||
TRMPRI|OPBIN, /*LMULT*/
|
||||
TRMPRI|OPBIN, /*LDIV*/
|
||||
TRMPRI|OPBIN, /*LMOD*/
|
||||
TRMPRI|OPBIN, /*LEQMULT*/
|
||||
TRMPRI|OPBIN, /*LEQDIV*/
|
||||
TRMPRI|OPBIN, /*LEQMOD*/
|
||||
TRMPRI|ASGOP, /*EQADDR*/
|
||||
TRMPRI, /*EQNOT*/
|
||||
TRMPRI, /*EQNEG*/
|
||||
TRMPRI|OPBIN, /*DOCAST*/
|
||||
ASGPRI|ASGOP, /*STASSIGN [vlh]*/
|
||||
TRMPRI|OPCONVS, /*LONG2F [vlh] 3.4*/
|
||||
TRMPRI|OPCONVS, /*FLOAT2L [vlh] 3.4*/
|
||||
TRMPRI|OPCONVS, /*INT2F [vlh] 3.4*/
|
||||
TRMPRI|OPCONVS, /*FLOAT2I [vlh] 3.4*/
|
||||
UNOPRI|OPRAS, /*TOCHAR [vlh] 4.0*/
|
||||
TRMPRI, /*unused - 56*/
|
||||
TRMPRI, /*unused - 57*/
|
||||
TRMPRI, /*unused - 58*/
|
||||
TRMPRI, /*unused - 59*/
|
||||
UNOPRI|OPRAS|OPLVAL, /*ADDR - & expr*/
|
||||
UNOPRI|OPRAS|OPLWORD, /*INDR - * expr*/
|
||||
LNDPRI|OPBIN, /*LAND - expr && expr*/
|
||||
LORPRI|OPBIN, /*LOR - expr || expr*/
|
||||
QMKPRI|OPRAS|OPBIN, /*QMARK - expr ? expr : expr*/
|
||||
QMKPRI|OPRAS|OPBIN, /*COLON*/
|
||||
COMPRI|OPBIN, /*COMMA*/
|
||||
TRMPRI|OPTERM, /*CINT*/
|
||||
TRMPRI|OPTERM, /*CLONG*/
|
||||
TRMPRI|OPTERM, /*SYMBOL*/
|
||||
TRMPRI|OPTERM, /*AUTOINC*/
|
||||
TRMPRI|OPTERM, /*AUTODEC*/
|
||||
LPNPRI|OPBIN, /*CALL - call with arguments*/
|
||||
LPNPRI, /*NACALL - no argument call*/
|
||||
TRMPRI, /*BFIELD - field selection*/
|
||||
TRMPRI, /*CONDBR*/
|
||||
TRMPRI, /*INIT*/
|
||||
TRMPRI, /*LOADREG*/
|
||||
TRMPRI|OPTERM, /*DCLONG - divide const long*/
|
||||
TRMPRI|OPTERM, /*CFLOAT [vlh] 3.4*/
|
||||
UNOPRI|OPRAS|OPASSIGN|OPBIN, /*CAST*/
|
||||
TRMPRI, /*SEMI*/
|
||||
TRMPRI, /*LCURBR - {*/
|
||||
TRMPRI, /*RCURBR - }*/
|
||||
LPNPRI, /*LBRACK - [*/
|
||||
RPNPRI, /*RBRACK - ]*/
|
||||
LPNPRI, /*LPAREN - )*/
|
||||
RPNPRI, /*RPAREN - )*/
|
||||
TRMPRI|OPTERM, /*STRING*/
|
||||
TRMPRI, /*RESWORD*/
|
||||
LPNPRI|OPBIN, /*APTR - expr -> symbol*/
|
||||
LPNPRI|OPBIN, /*PERIOD - expr . symbol*/
|
||||
UNOPRI|OPRAS, /*SIZEOF - sizeof expr*/
|
||||
LPNPRI|OPBIN, /*MPARENS - matching parens ()*/
|
||||
};
|
||||
357
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/util.c
Normal file
357
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen/util.c
Normal file
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
#include "cskel.h"
|
||||
|
||||
/* xnalloc - allocate address-indexed node*/
|
||||
char *xnalloc(type,ar,off,xr,xt) /* returns ptr to node alloced*/
|
||||
int type; /* data type*/
|
||||
int ar; /* address register*/
|
||||
int off; /* 8-bit offset*/
|
||||
int xr; /* index register*/
|
||||
int xt; /* index register type*/
|
||||
{
|
||||
register struct indexnode *xp;
|
||||
|
||||
xp = talloc(sizeof(*xp));
|
||||
xp->t_op = SYMBOL;
|
||||
xp->t_type = type;
|
||||
xp->t_sc = INDEXED;
|
||||
xp->t_reg = ar;
|
||||
xp->t_su = SU_ADDR;
|
||||
xp->t_offset = off;
|
||||
xp->t_xreg = xr;
|
||||
xp->t_xtype = xt;
|
||||
return(xp);
|
||||
}
|
||||
|
||||
/* tcopy - expression tree copy*/
|
||||
char *tcopy(tp) /* returns ptr to copied tree*/
|
||||
struct tnode *tp;
|
||||
{
|
||||
register char *p;
|
||||
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case SYMBOL:
|
||||
if( tp->t_sc == EXTERNAL || tp->t_sc == EXTOFF )
|
||||
p = cenalloc(tp->t_type,tp->t_sc,tp->t_symbol);
|
||||
else {
|
||||
p = snalloc(tp->t_type,tp->t_sc,tp->t_offset,0,0);
|
||||
p->t_label = tp->t_label;
|
||||
}
|
||||
p->t_offset = tp->t_offset;
|
||||
p->t_reg = tp->t_reg;
|
||||
return(p);
|
||||
|
||||
case CINT:
|
||||
return(cnalloc(tp->t_type,tp->t_value));
|
||||
|
||||
case CLONG:
|
||||
return(lcnalloc(tp->t_type,tp->t_lvalue));
|
||||
|
||||
case CFLOAT: /*[vlh] 3.4 */
|
||||
return(fpcnalloc(tp->t_type,tp->t_lvalue));
|
||||
|
||||
case DCLONG:
|
||||
p = lcnalloc(tp->t_type,tp->t_lvalue);
|
||||
p->t_op = DCLONG;
|
||||
return(p);
|
||||
|
||||
default:
|
||||
if( binop(tp->t_op) )
|
||||
return(tnalloc(tp->t_op,tp->t_type,0,0,tcopy(tp->t_left),
|
||||
tcopy(tp->t_right)));
|
||||
if( unaryop(tp->t_op) )
|
||||
return(tnalloc(tp->t_op,tp->t_type,0,0,tcopy(tp->t_left),
|
||||
null));
|
||||
error("tcopy op=%d",tp->t_op);
|
||||
return(tp);
|
||||
}
|
||||
}
|
||||
|
||||
/* outaexpr - output address expression*/
|
||||
outaexpr(tp,flags) /* returns - none*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
int flags; /* flags (IMMED,LOFFSET,...)*/
|
||||
{
|
||||
register int off, reg, lab;
|
||||
long l;
|
||||
|
||||
if( tp->t_op == ADDR ) {
|
||||
tp = tp->t_left;
|
||||
putchar('#');
|
||||
}
|
||||
off = tp->t_offset;
|
||||
reg = tp->t_reg;
|
||||
lab = tp->t_label;
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case AUTOINC:
|
||||
printf("(R%d)+",reg);
|
||||
break;
|
||||
|
||||
case AUTODEC:
|
||||
printf("-(R%d)",reg);
|
||||
break;
|
||||
|
||||
case CINT:
|
||||
if( flags & IMMED )
|
||||
putchar('#');
|
||||
printf("%d",tp->t_value);
|
||||
break;
|
||||
|
||||
case DCLONG:
|
||||
case CLONG:
|
||||
case CFLOAT: /*[vlh] 3.4 */
|
||||
if( flags & IMMED )
|
||||
putchar('#');
|
||||
outlval(tp->t_lvalue);
|
||||
break;
|
||||
|
||||
case SYMBOL:
|
||||
if( off ) {
|
||||
switch( tp->t_sc ) {
|
||||
|
||||
default:
|
||||
printf("%d+",off);
|
||||
break;
|
||||
|
||||
case REGOFF:
|
||||
printf("%d",off);
|
||||
case CINDR:
|
||||
case CLINDR:
|
||||
case CFINDR: /* [vlh] 3.4 */
|
||||
case INDEXED:
|
||||
break;
|
||||
|
||||
case REGISTER:
|
||||
error("invalid register expression");
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch( tp->t_sc ) {
|
||||
|
||||
case REGISTER:
|
||||
printf("R%d",reg);
|
||||
break;
|
||||
|
||||
case REGOFF:
|
||||
printf("(R%d)",reg);
|
||||
break;
|
||||
|
||||
case EXTERNAL:
|
||||
printf("_%.8s",tp->t_symbol);
|
||||
break;
|
||||
|
||||
case EXTOFF:
|
||||
printf("_%.8s(R%d)",tp->t_symbol,reg);
|
||||
break;
|
||||
|
||||
case STATIC:
|
||||
printf("L%d",lab);
|
||||
break;
|
||||
|
||||
case STATOFF:
|
||||
printf("L%d(R%d)",lab,reg);
|
||||
break;
|
||||
|
||||
case INDEXED:
|
||||
printf("%d(R%d,R%d",off,reg,tp->t_xreg);
|
||||
outatype(tp->t_xtype);
|
||||
putchar(')');
|
||||
break;
|
||||
|
||||
case CINDR:
|
||||
printf("%d",off);
|
||||
break;
|
||||
/*
|
||||
* the following will work on: PDP-11, 68000, IBM-360, VAX, etc.
|
||||
* it will not work on word machines or on machines where either
|
||||
* longs two ints or two shorts.
|
||||
*/
|
||||
case CLINDR:
|
||||
case CFINDR: /* [vlh] 3.4 */
|
||||
l.hiword = tp->t_offset;
|
||||
l.loword = tp->t_ssp;
|
||||
outlval(l);
|
||||
break;
|
||||
|
||||
default:
|
||||
error("invalid storage class %d\n",tp->t_sc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error("invalid operator %d\n",tp->t_op);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* outlval - output long value*/
|
||||
/* This is a big pain because the PDP-11 doesn't do long divides*/
|
||||
/* in hardware.*/
|
||||
outlval(lval)
|
||||
long lval;
|
||||
{
|
||||
char digs[8];
|
||||
register int i, c;
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
digs[i++] = lval & 0xf;
|
||||
lval =>> 4;
|
||||
lval =& 0xfffffff;
|
||||
} while ( lval );
|
||||
putchar('$');
|
||||
while( --i >= 0 ) {
|
||||
c = digs[i];
|
||||
putchar(c>=10?c+('a'-10):c+'0');
|
||||
}
|
||||
}
|
||||
|
||||
/* outtype - output 68000 type (null, .b, .l) depending on data type*/
|
||||
outtype(type)
|
||||
int type;
|
||||
{
|
||||
if( isfloat(type) )
|
||||
printf(".l");
|
||||
else if( longorptr(type) )
|
||||
printf(".l");
|
||||
else if( type == CHAR )
|
||||
printf(".b");
|
||||
}
|
||||
|
||||
/* outatype - output address type (.l or null) depending on data type*/
|
||||
outatype(type)
|
||||
int type;
|
||||
{
|
||||
if( longorptr(type) || isfloat(type) )
|
||||
printf(".l");
|
||||
}
|
||||
|
||||
/* outextend - output register extension to long depending on type*/
|
||||
outextend(tp,type,reg) /* returns - none*/
|
||||
struct tnode *tp; /* tree to convert from*/
|
||||
int type; /* type to convert to*/
|
||||
int reg; /* register to convert*/
|
||||
{
|
||||
if( (isdreg(reg)) && !(longorptr(tp->t_type)) && (longorptr(type)) ) {
|
||||
if( unsign(tp->t_type) )
|
||||
outuext(reg);
|
||||
else
|
||||
outext(reg);
|
||||
}
|
||||
}
|
||||
|
||||
/* outrr - output register to register instruction*/
|
||||
outrr(ins,r1,r2,tp)
|
||||
char *ins;
|
||||
int r1;
|
||||
int r2;
|
||||
struct tnode *tp;
|
||||
{
|
||||
printf("%s",ins);
|
||||
if( isareg(r1) || isareg(r2) )
|
||||
outatype(tp->t_type);
|
||||
else
|
||||
outtype(tp->t_type);
|
||||
printf(" R%d,R%d\n",r1,r2);
|
||||
}
|
||||
|
||||
/* outmovr - output "move[type] R1,R2" instruction*/
|
||||
outmovr(r1,r2,tp)
|
||||
int r1;
|
||||
int r2;
|
||||
struct tnode *tp;
|
||||
{
|
||||
if( r1 != r2 )
|
||||
outrr("move",r1,r2,tp);
|
||||
}
|
||||
|
||||
/* outcmpm - output "cmpm[type] (R1)+,(R2)+"*/
|
||||
outcmpm(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
printf("cmpm");
|
||||
outtype(tp->t_left->t_type);
|
||||
printf(" (R%d)+,(R%d)+\n",tp->t_left->t_reg,tp->t_right->t_reg);
|
||||
}
|
||||
|
||||
/* outcreg - output reference to compiler temp register*/
|
||||
outcreg(reg)
|
||||
int reg;
|
||||
{
|
||||
if( (dreg(reg)) > HICREG )
|
||||
error("expression too complex");
|
||||
printf("R%d",reg);
|
||||
}
|
||||
|
||||
/* outcmp0 - output a compare with 0, special for address register*/
|
||||
outcmp0(reg,tp)
|
||||
int reg;
|
||||
struct tnode *tp;
|
||||
{
|
||||
if( isareg(reg) ) {
|
||||
printf("cmp");
|
||||
outatype(tp->t_type);
|
||||
printf(" #0,R%d\n",reg);
|
||||
}
|
||||
else {
|
||||
printf("tst");
|
||||
outtype(tp->t_type);
|
||||
printf(" R%d\n",reg);
|
||||
}
|
||||
}
|
||||
|
||||
/* outrpush - output "move[type] R1,[-](sp)"*/
|
||||
outrpush(reg,tp,pflag)
|
||||
int reg;
|
||||
struct tnode *tp;
|
||||
int pflag;
|
||||
{
|
||||
printf("move");
|
||||
outatype(tp->t_type);
|
||||
printf(" R%d,%c(sp)\n",reg,pflag?'-':'\0');
|
||||
}
|
||||
|
||||
outdbra(reg,lab)
|
||||
int reg;
|
||||
int lab;
|
||||
{
|
||||
printf("dbra R%d,L%d\n",reg,lab);
|
||||
}
|
||||
|
||||
/* cenalloc - code generator external node allocation*/
|
||||
/* This may be coalesced into enalloc in parser.*/
|
||||
char *cenalloc(type,sc,sym) /* returns ptr to node alloced*/
|
||||
int type; /* type of symbol*/
|
||||
int sc; /* storage class*/
|
||||
char *sym; /* symbol name*/
|
||||
{
|
||||
register struct extnode *ep;
|
||||
|
||||
ep = talloc(sizeof(*ep));
|
||||
ep->t_op = SYMBOL;
|
||||
ep->t_type = type;
|
||||
ep->t_sc = sc;
|
||||
ep->t_su = 0;
|
||||
ep->t_offset = 0;
|
||||
symcopy(sym,ep->t_symbol);
|
||||
return(ep);
|
||||
}
|
||||
|
||||
/*popstack - clear off the stack after a call if necessary */
|
||||
popstack(nb)
|
||||
{
|
||||
if (nb > 0 && nb <= 8)
|
||||
printf("addq.l #%d,sp\n",nb);
|
||||
else if (nb > 0)
|
||||
printf("adda.l #%d,sp\n",nb);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
char *compiled "@(#) code generator - Fri Mar 18 12:02 1983";
|
||||
@@ -0,0 +1,17 @@
|
||||
$ set def [steve.cpm68k.c.fcgen]
|
||||
$ set noon
|
||||
$ copy machine.vax machine.h
|
||||
$ cx CANON
|
||||
$ cx CODEGEN
|
||||
$ cx CSKELS
|
||||
$ cx INTERF
|
||||
$ cx MAIN
|
||||
$ cx OPTAB
|
||||
$ cx PUTEXPR
|
||||
$ cx SMATCH
|
||||
$ cx SUCOMP
|
||||
$ cx TABL
|
||||
$ cx UTIL
|
||||
$ cx VERSION
|
||||
$ cx init
|
||||
$ @vrelink
|
||||
@@ -0,0 +1,2 @@
|
||||
clink canon,codegen,cskels,init,interf,main,optab,putexpr,smatch,sucomp,tabl,-
|
||||
util,version,lib:k3/lib c168'p1'
|
||||
@@ -0,0 +1,3 @@
|
||||
c68 -L *.c -n -o c168.st -l6 ; setstack c168.st 8192 8192
|
||||
c68 -L *.c -o c168.68 -l6 ; setstack c168.68 8192 8192
|
||||
cc *.c -o c168.11 -lx
|
||||
1006
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/canon.c
Normal file
1006
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/canon.c
Normal file
File diff suppressed because it is too large
Load Diff
191
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/cgen.h
Normal file
191
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/cgen.h
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "../icode.h"
|
||||
//#define NODEBUG 0
|
||||
//#define VERSADOS
|
||||
|
||||
char brtab[][2];
|
||||
int invrel[];
|
||||
int swaprel[];
|
||||
char *strtab[];
|
||||
char null[];
|
||||
|
||||
/*operator tree node for unary and binary operators*/
|
||||
struct tnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*data type of result*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
struct tnode *t_left; /*left sub-tree*/
|
||||
struct tnode *t_right; /*right sub-tree (undefined if unary)*/
|
||||
};
|
||||
|
||||
/*constant terminal node*/
|
||||
struct conode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_value; /*value or label number*/
|
||||
};
|
||||
|
||||
struct lconode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
long t_lvalue; /*value or label number*/
|
||||
};
|
||||
|
||||
/*local symbol terminal node*/
|
||||
struct symnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*symbol data type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_sc; /*storage class*/
|
||||
int t_offset; /*register offset*/
|
||||
int t_reg; /*register number*/
|
||||
int t_label; /*label number if static*/
|
||||
};
|
||||
|
||||
/*external symbol reference node*/
|
||||
struct extnode {
|
||||
int t_op; /*operator*/
|
||||
int t_type; /*symbol data type*/
|
||||
int t_su; /*Sethy-Ullman number*/
|
||||
int t_ssp;
|
||||
int t_sc; /*storage class*/
|
||||
int t_offset; /*register offset*/
|
||||
int t_reg; /*register number*/
|
||||
char t_symbol[SSIZE]; /*symbol name*/
|
||||
};
|
||||
|
||||
/*68000 special - indexed symbol node*/
|
||||
/*this is used to generate a An(off,Xn.type) address*/
|
||||
struct indexnode {
|
||||
int t_op;
|
||||
int t_type;
|
||||
int t_su;
|
||||
int t_ssp;
|
||||
int t_sc;
|
||||
int t_offset;
|
||||
int t_reg;
|
||||
int t_xreg;
|
||||
int t_xtype;
|
||||
};
|
||||
|
||||
int lflag;
|
||||
int dflag;
|
||||
int mflag;
|
||||
int cflag;
|
||||
int eflag;
|
||||
int fflag;
|
||||
int oflag;
|
||||
struct io_buf ibuf, obuf;
|
||||
int lineno;
|
||||
int naregs;
|
||||
int ndregs;
|
||||
int errcnt;
|
||||
int opinfo[];
|
||||
int nextlabel;
|
||||
char null[];
|
||||
char optab[][6];
|
||||
char *mnemonics[];
|
||||
char *codeskels[];
|
||||
int stacksize;
|
||||
|
||||
char *tnalloc();
|
||||
char *snalloc();
|
||||
char *cenalloc();
|
||||
char *xnalloc();
|
||||
char *talloc();
|
||||
char *cnalloc();
|
||||
char *lcnalloc();
|
||||
char *fpcnalloc();
|
||||
char *canon();
|
||||
char *commute();
|
||||
char *constant();
|
||||
char *match();
|
||||
char *addptree();
|
||||
char *fixbfield();
|
||||
char *coffset();
|
||||
char *tcopy();
|
||||
|
||||
#define wallign(add) ((add+1)&(~1))
|
||||
#define array(type) ((type&SUPTYP)==ARRAY)
|
||||
#define function(type) ((type&SUPTYP)==FUNCTION)
|
||||
#define pointer(type) ((type&SUPTYP)==POINTER)
|
||||
#define notarray(type) ((type&SUPTYP)!=ARRAY)
|
||||
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
|
||||
#define notpointer(type) ((type&SUPTYP)!=POINTER)
|
||||
#define isfloat(type) (type==FLOAT)
|
||||
#define btype(type) (type&TYPE)
|
||||
#define suptype(type) (type&SUPTYP)
|
||||
#define alltype(type) (type&(SUPTYP|TYPE))
|
||||
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
|
||||
#define relop(op) ((opinfo[op]&OPREL)!=0)
|
||||
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
|
||||
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
|
||||
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
|
||||
#define binop(op) ((opinfo[op]&OPBIN)!=0)
|
||||
#define unaryop(op) ((opinfo[op]&(OPBIN|OPTERM))==0)
|
||||
#define leafop(op) ((opinfo[op]&OPTERM)!=0)
|
||||
#define notleafop(op) ((opinfo[op]&OPTERM)==0)
|
||||
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
|
||||
#define oppriority(op) (opinfo[op]&OPPRI)
|
||||
#define commop(op) ((opinfo[op]&OPCOM)!=0)
|
||||
#define convop(op) ((opinfo[op]&OPCONVS)!=0)
|
||||
#define notconvop(op) ((opinfo[op]&OPCONVS)==0)
|
||||
#define max(a,b) (a>b?a:b)
|
||||
#define min(a,b) (a<b?a:b)
|
||||
|
||||
#define QUICKVAL 8
|
||||
#define LEP 14
|
||||
#define FORCC 1
|
||||
#define FOREFF 2
|
||||
#define FORSTACK 3
|
||||
#define FORCREG 4
|
||||
#define FORSP 5
|
||||
#define FORREG 4
|
||||
#define HICREG 2
|
||||
#define NCREGS 3
|
||||
#define AREGLO 8
|
||||
#define IMMED 1
|
||||
#define NOTIMMED 0
|
||||
#define NOTLOFFSET 0
|
||||
|
||||
/* one line routines turned into defines [vlh] for speed */
|
||||
|
||||
/*outgoto - output "bra L[labno]"*/
|
||||
#define outgoto(lab) if (lab>0) printf("bra L%d\n",lab)
|
||||
/*outlab - output "L[labno]:"*/
|
||||
#define outlab(lab) if (lab>0) printf("L%d:",lab)
|
||||
|
||||
/*outext - output register sign extension*/
|
||||
#define outext(reg) printf("ext.l R%d\n",reg)
|
||||
/*outuext - output unsigned to long register extension*/
|
||||
#define outuext(reg) printf("swap R%d\nclr R%d\nswap R%d\n",reg,reg,reg)
|
||||
/*outswap - output swap register instruction*/
|
||||
#define outswap(reg) printf("swap R%d\n",reg)
|
||||
/*outaddr - output "add [type] R1 R2" instruction*/
|
||||
#define outaddr(r1,r2,tp) outrr("add",r1,r2,(tp))
|
||||
/*outccsave - ouput instruction to move cc's to register*/
|
||||
#define outccsave(reg) printf("move sr,R%d\n",reg)
|
||||
/*outccrestore - output instruction to restore cc's from register*/
|
||||
#define outccrestore(reg) printf("move R%d,ccr\n",reg)
|
||||
/*basetype - get the btype info sans unsigned*/
|
||||
#define basetype(type) ((type==UNSIGNED) ? INT : type)
|
||||
#define unsign(type) ((type) == UNSIGNED)
|
||||
#define longorptr(type) (type==LONG || (type&SUPTYP))
|
||||
#define unorptr(type) (type==UNSIGNED || (type&SUPTYP))
|
||||
#define dreg(reg) ((reg) & (~AREGLO))
|
||||
#define areg(reg) ((reg) | AREGLO)
|
||||
#define isareg(reg) ((reg) >= AREGLO)
|
||||
#define isdreg(reg) ((reg) < AREGLO)
|
||||
#define isreg(tp) ((tp)->t_op == SYMBOL && (tp)->t_sc == REGISTER)
|
||||
@@ -0,0 +1,756 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
#include "cskel.h"
|
||||
|
||||
|
||||
/* scodegen - over-all code generation for expression*/
|
||||
/* Picks off post-fix ++, --.*/
|
||||
scodegen(tp,cookie,reg) /* returns register result is in*/
|
||||
struct tnode *tp;
|
||||
int cookie;
|
||||
int reg;
|
||||
{
|
||||
struct tnode *clist[20];
|
||||
struct tnode **clp;
|
||||
register struct tnode **cp;
|
||||
register int r;
|
||||
register int ccflag;
|
||||
register struct tnode *rtp;
|
||||
|
||||
if( tp->t_op == COMMA ) {
|
||||
scodegen(tp->t_left,FOREFF,reg);
|
||||
return(scodegen(tp->t_right,cookie,reg));
|
||||
}
|
||||
ccflag = 0;
|
||||
clp = clist;
|
||||
tp = addptree(tp,&clp);
|
||||
if( clp > clist ) {
|
||||
/*
|
||||
* post ++, -- in tree. We need to compile the tree post operators
|
||||
* then generate code to do the post operators, then do any fix up of
|
||||
* condition codes since the Stupid 68000 architect was a nimnul.
|
||||
*/
|
||||
if( cookie == FORCC ) {
|
||||
/*
|
||||
* here we make the observation that if we are comparing something with
|
||||
* zero OR the top operator of the tree is not a comparison operator,
|
||||
* we can compile the tree to a register, and then set the condition
|
||||
* codes OK with a tst instruction at the end.
|
||||
*/
|
||||
if( relop(tp->t_op) ) {
|
||||
if( (rtp=constant(tp->t_right)) && !rtp->t_value ) {
|
||||
ccflag = 1;
|
||||
tp = tp->t_left;
|
||||
cookie = FORREG;
|
||||
}
|
||||
else
|
||||
ccflag = 2;
|
||||
}
|
||||
else {
|
||||
ccflag = 1;
|
||||
cookie = FORREG;
|
||||
}
|
||||
}
|
||||
}
|
||||
r = codegen(tp,cookie,reg);
|
||||
if( clp > clist ) {
|
||||
if( ccflag == 2 )
|
||||
outccsave(r);
|
||||
for( cp = clist; cp < clp; cp++ )
|
||||
codegen(*cp,FOREFF,r+1);
|
||||
if( ccflag == 1 )
|
||||
outcmp0(r,tp);
|
||||
else if( ccflag == 2 )
|
||||
outccrestore(r);
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
||||
/* addptree - prune off postfix ++, -- from expression tree*/
|
||||
/* This prunes off ++, -- and collects those expressions for*/
|
||||
/* scodegen.*/
|
||||
char *addptree(tp,clp) /* returns pointer to pruned tree*/
|
||||
struct tnode *tp;
|
||||
struct tnode ***clp;
|
||||
{
|
||||
register int op;
|
||||
|
||||
op = tp->t_op;
|
||||
if( leafop(op) || op == QMARK ) /* [vlh] 4.0 QMARK... */
|
||||
return(tp);
|
||||
if( op == POSTINC || op == POSTDEC ) {
|
||||
*(*clp)++ = tp;
|
||||
return( tcopy(tp->t_left) );
|
||||
}
|
||||
if( binop(op) )
|
||||
tp->t_right = addptree(tp->t_right,clp);
|
||||
tp->t_left = addptree(tp->t_left,clp);
|
||||
return(tp);
|
||||
}
|
||||
|
||||
/* codegen - generate code for expression*/
|
||||
/* This calls up rcodegen, which prunes off any special register*/
|
||||
/* optimization code, then calls ucodegen (unrecursive) code*/
|
||||
/* generation.*/
|
||||
codegen(tp,cookie,reg) /* returns reg result is in*/
|
||||
struct tnode *tp; /* tree pointer*/
|
||||
int cookie; /* code generation goals*/
|
||||
int reg; /* first available register*/
|
||||
{
|
||||
register int size, savestk, ssize, r, i, scookie;
|
||||
register struct tnode *rtp;
|
||||
|
||||
#ifndef NODEBUG
|
||||
if( cflag )
|
||||
printf("codegen op=%d cookie=%d reg=%d\n",tp->t_op,cookie,reg);
|
||||
#endif
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case CALL:
|
||||
case NACALL:
|
||||
ssize = 0;
|
||||
savestk = stacksize;
|
||||
if( tp->t_left->t_op != SYMBOL )
|
||||
stacksize++;
|
||||
if( tp->t_op == CALL ) {
|
||||
rtp = tp->t_right;
|
||||
while( rtp->t_op == COMMA ) {
|
||||
ssize =+ dofarg(rtp->t_right);
|
||||
rtp = rtp->t_left;
|
||||
}
|
||||
ssize =+ dofarg(rtp);
|
||||
}
|
||||
tp->t_op = FJSR; /*generate JSR (unary op)*/
|
||||
codegen(tp,FORREG,reg);
|
||||
popstack(ssize);
|
||||
stacksize = savestk;
|
||||
fixresult(tp,cookie,0);
|
||||
return(0); /*result in R0*/
|
||||
|
||||
case COMMA:
|
||||
codegen(tp->t_left,FOREFF,reg);
|
||||
return(codegen(tp->t_right,cookie,reg));
|
||||
|
||||
case AND:
|
||||
if( cookie == FORCC && (i=isonebit(tp->t_right)) >= 0 &&
|
||||
(i=dobitadd(tp->t_left,i)) >= 0 ) {
|
||||
if( convop(tp->t_right->t_op) )
|
||||
tp->t_right = tp->t_right->t_left;
|
||||
tp->t_right->t_value = i;
|
||||
tp->t_op = BTST;
|
||||
tp = canon(tp);
|
||||
sucomp(tp,reg,1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if( rcodegen(&tp,cookie,reg) ) {
|
||||
if( cookie == FORCC && tp->t_op == SYMBOL && tp->t_sc == REGISTER
|
||||
&& isdreg(tp->t_reg))
|
||||
return(reg);
|
||||
}
|
||||
r = ucodegen(tp,cookie,reg);
|
||||
return(r);
|
||||
}
|
||||
|
||||
/* fixresult - fix result of code generation*/
|
||||
fixresult(tp,cookie,reg) /* returns - none*/
|
||||
struct tnode *tp;
|
||||
int cookie; /* wanted this cookie*/
|
||||
int reg;
|
||||
{
|
||||
#ifndef NODEBUG
|
||||
if (cflag)
|
||||
printf("fixresult cookie=%d reg=%d op=%d\n",cookie,reg,tp->t_op);
|
||||
#endif
|
||||
switch( cookie ) {
|
||||
|
||||
case FORCC:
|
||||
outcmp0(reg,tp);
|
||||
break;
|
||||
|
||||
case FORSP:
|
||||
case FORSTACK:
|
||||
stacksize++;
|
||||
outrpush(reg,tp,cookie==FORSTACK);
|
||||
break;
|
||||
|
||||
}
|
||||
return(reg);
|
||||
}
|
||||
|
||||
/* ucodegen - generate code for tree given cookie and starting register*/
|
||||
/* Handles the matching of the expression tree node with the*/
|
||||
/* corresponding code generation table. When a match is found,*/
|
||||
/* expand is called to expand the code skeleton macro.*/
|
||||
ucodegen(tp,cookie,reg) /* returns reg result is in*/
|
||||
struct tnode *tp; /* pointer to expression tree*/
|
||||
int cookie; /* (FORCC,FOREFF,FORREG,FORSTACK)*/
|
||||
int reg; /* first available register*/
|
||||
{
|
||||
register int r;
|
||||
register char *p;
|
||||
|
||||
#ifndef NODEBUG
|
||||
if(cflag)
|
||||
putexpr("ucodegen",tp);
|
||||
#endif
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case STASSIGN: /*[vlh]*/
|
||||
outstrcpy(codegen(tp->t_left,FORREG,areg(reg)),
|
||||
codegen(tp->t_right,FORREG,areg(reg+1)), tp->t_type);
|
||||
return(reg);
|
||||
break;
|
||||
|
||||
case SYMBOL:
|
||||
if( cookie == FOREFF )
|
||||
return(reg);
|
||||
break;
|
||||
|
||||
case LSH:
|
||||
if( (isareg(reg)) && (p=constant(tp->t_right)) &&
|
||||
!(unsign(tp->t_left->t_type)) &&
|
||||
(p->t_value == 1 || p->t_value == 2) ) {
|
||||
r = codegen(tp->t_left,FORREG,reg);
|
||||
outmovr(r,reg,tp->t_left);
|
||||
if( p->t_value == 2 )
|
||||
outaddr(reg,reg,tp);
|
||||
outaddr(reg,reg,tp);
|
||||
fixresult(tp,cookie,reg);
|
||||
return(reg);
|
||||
}
|
||||
break;
|
||||
|
||||
case EQMULT:
|
||||
case EQDIV:
|
||||
case LEQMULT:
|
||||
case LEQDIV:
|
||||
case EQMOD:
|
||||
case LEQMOD:
|
||||
case EQRSH:
|
||||
case EQLSH:
|
||||
case EQAND:
|
||||
case EQOR:
|
||||
case EQXOR:
|
||||
if( indexreg(tp->t_left) ) {
|
||||
reg = dreg(reg);
|
||||
outmovr(r=tp->t_left->t_reg,reg,tp);
|
||||
tp->t_left->t_reg = reg;
|
||||
codegen(tp,cookie,reg+1);
|
||||
outmovr(reg,r,tp);
|
||||
return(reg);
|
||||
}
|
||||
break;
|
||||
|
||||
case ADD:
|
||||
case EQADD:
|
||||
if( (p=constant(tp->t_right)) && p->t_value < 0 &&
|
||||
p->t_value >= -QUICKVAL ) {
|
||||
p->t_value = - p->t_value;
|
||||
tp->t_op =+ (SUB-ADD);
|
||||
}
|
||||
break;
|
||||
}
|
||||
sucomp(tp,reg,1);
|
||||
if( (r=loadexpr(tp,cookie,reg)) >= 0 )
|
||||
return(r);
|
||||
if( (r=cqmark(tp,cookie,reg)) >= 0 )
|
||||
return(r);
|
||||
if( (r=hardrel(tp,cookie,reg)) >= 0 )
|
||||
return(r);
|
||||
if( cookie == FORCC && (p=match(tp,FOREFF,reg)) != 0 ) {
|
||||
r = expand(tp,FOREFF,reg,p);
|
||||
if( asgop(tp->t_op) && indexreg(tp->t_left) )
|
||||
outcmp0(tp->t_left->t_reg,tp->t_left);
|
||||
}
|
||||
else if( p = match(tp,cookie,reg) )
|
||||
r = expand(tp,cookie,reg,p);
|
||||
else if( cookie != FORREG )
|
||||
r = fixresult(tp,cookie,ucodegen(tp,FORREG,reg));
|
||||
else
|
||||
error("no code table for %d",tp->t_op);
|
||||
return(r);
|
||||
}
|
||||
|
||||
/* outstrcpy - output structure copy */
|
||||
outstrcpy(lr,rr,size) /*[vlh]*/
|
||||
int lr, rr; /* left register, right register */
|
||||
int size; /* structure size to copy */
|
||||
{
|
||||
register int lab;
|
||||
lab = nextlabel++;
|
||||
printf("move #%d,r%d\n",(size/2)-1,dreg(lr));
|
||||
outlab(lab);
|
||||
printf("move (r%d)+,(r%d)+\ndbra r%d,L%d\n",rr,lr,dreg(lr),lab);
|
||||
}
|
||||
|
||||
/* loadexpr - load an addressable expression into a register*/
|
||||
/* This checks for any possible usage of the register indexed*/
|
||||
/* addressing mode. Note that this relies on the good graces of the*/
|
||||
/* load code skeletons not to muck up the compiler registers before*/
|
||||
/* loading an addressable expression...*/
|
||||
loadexpr(tp,cookie,reg) /* returns register loaded or -1*/
|
||||
struct tnode *tp; /* pointer to expression tree*/
|
||||
int reg; /* register to load*/
|
||||
{
|
||||
register struct tnode *rtp, *ltp, *xtp, *atp;
|
||||
register int off, r, type, nr, ar, xr, xt;
|
||||
|
||||
if( tp->t_op == INDR || LOADABLE(tp) ) {
|
||||
type = tp->t_type;
|
||||
if( tp->t_op == INDR && (ltp=tp->t_left)->t_op == ADD ) {
|
||||
rtp = ltp->t_right;
|
||||
ltp = ltp->t_left;
|
||||
off = 0;
|
||||
if( rtp->t_op == CINT && ((off=rtp->t_value) < -128 ||
|
||||
off > 127 || ltp->t_op != ADD ) ) {
|
||||
tp = snalloc(type,AUTO,off,0,0);
|
||||
if( indexreg(ltp) )
|
||||
tp->t_reg = ltp->t_reg;
|
||||
else {
|
||||
r = codegen(ltp,FORREG,areg(reg));
|
||||
if( isdreg(r) )
|
||||
outmovr(r,areg(r),ltp);
|
||||
tp->t_reg = areg(r);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if( rtp->t_op == CINT ) {
|
||||
rtp = ltp->t_right;
|
||||
ltp = ltp->t_left;
|
||||
}
|
||||
if(indexreg(rtp) || (!(indexreg(ltp)) && (isreg(rtp)))) {
|
||||
xtp = ltp;
|
||||
ltp = rtp;
|
||||
rtp = xtp;
|
||||
}
|
||||
xtp = atp = 0;
|
||||
if( indexreg(ltp) ) {
|
||||
ar = ltp->t_reg;
|
||||
if( (isreg(rtp)) && rtp->t_type != CHAR ) {
|
||||
xr = rtp->t_reg;
|
||||
xt = rtp->t_type;
|
||||
}
|
||||
else
|
||||
xtp = rtp;
|
||||
}
|
||||
else if( (isreg(ltp)) && ltp->t_type != CHAR &&
|
||||
(lflag || rtp->t_op != ADDR) ) {
|
||||
xr = ltp->t_reg;
|
||||
xt = ltp->t_type;
|
||||
atp = rtp;
|
||||
}
|
||||
else if( rtp->t_op == ADDR ) {
|
||||
atp = ltp;
|
||||
xtp = rtp;
|
||||
}
|
||||
else {
|
||||
atp = rtp;
|
||||
xtp = ltp;
|
||||
}
|
||||
nr = 0;
|
||||
if( atp )
|
||||
nr++;
|
||||
if( xtp && (xtp->t_op != ADDR || lflag ) )
|
||||
nr++;
|
||||
if( dreg(nr+reg) <= HICREG ) {
|
||||
r = reg;
|
||||
if( atp ) {
|
||||
ar = codegen(atp,FORREG,areg(r));
|
||||
if( isdreg(ar) ) {
|
||||
outmovr(ar,areg(ar),atp);
|
||||
ar = areg(ar);
|
||||
}
|
||||
r++;
|
||||
}
|
||||
if( xtp && xtp->t_op == ADDR && !lflag ) {
|
||||
tp = xtp->t_left;
|
||||
tp->t_sc =+ (EXTOFF-EXTERNAL);
|
||||
tp->t_offset =+ off;
|
||||
tp->t_reg = ar;
|
||||
}
|
||||
else {
|
||||
if( xtp ) {
|
||||
xr = codegen(xtp,FORREG,areg(r));
|
||||
xt = xtp->t_type;
|
||||
}
|
||||
tp = xnalloc(type,ar,off,xr,xt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( (isareg(reg)) && tp->t_type == CHAR )
|
||||
reg = dreg(reg);
|
||||
tp = tnalloc(LOAD,tp->t_type,SU_EASY,0,tp,null);
|
||||
return( codegen(tp,cookie,reg) );
|
||||
}
|
||||
return(-1);
|
||||
|
||||
}
|
||||
|
||||
/* coffset - check offset for addressable node*/
|
||||
char *coffset(tp) /* returns ptr to const off node*/
|
||||
struct tnode *tp; /* pointer to node*/
|
||||
{
|
||||
register struct tnode *rtp;
|
||||
|
||||
if( tp->t_op == ADD ) {
|
||||
rtp = tp->t_right;
|
||||
if( rtp->t_op == CINT )
|
||||
return(rtp);
|
||||
if(!lflag) {
|
||||
if( rtp->t_op == ADDR )
|
||||
return(rtp->t_left);
|
||||
rtp = tp->t_left;
|
||||
if( rtp->t_op == ADDR ) {
|
||||
tp->t_left = tp->t_right;
|
||||
tp->t_right = rtp;
|
||||
return(rtp->t_left);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* hardrel - do relationals returning a value*/
|
||||
hardrel(tp,cookie,reg) /* returns reg or -1*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
int cookie; /* cookie for code generation*/
|
||||
int reg; /* low register*/
|
||||
{
|
||||
char *p;
|
||||
int op, lab1, lab2;
|
||||
|
||||
if( cookie != FORCC && (relop(op=tp->t_op) || op == LOR ||
|
||||
op == LAND || op == NOT) ) {
|
||||
lab1 = nextlabel++;
|
||||
condbr(tp,TRUE,lab1,reg);
|
||||
p = canon(cnalloc(INT,0));
|
||||
codegen(p,cookie,reg);
|
||||
lab2 = nextlabel++;
|
||||
outgoto(lab2);
|
||||
outlab(lab1);
|
||||
p = canon(cnalloc(INT,1));
|
||||
codegen(p,cookie,reg);
|
||||
outlab(lab2);
|
||||
return(reg);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* cqmark - compile question mark operator*/
|
||||
/* This does the compilation of the question mark operator.*/
|
||||
cqmark(tp,cookie,reg) /* returns reg or -1*/
|
||||
struct tnode *tp;
|
||||
int cookie;
|
||||
int reg;
|
||||
{
|
||||
register int lab1, lab2, savestk, r;
|
||||
|
||||
if( tp->t_op == QMARK && cookie != FORCC ) {
|
||||
lab1 = nextlabel++;
|
||||
condbr(tp->t_left,FALSE,lab1,reg);
|
||||
savestk = stacksize;
|
||||
r = scodegen(tp->t_right->t_left,cookie,reg); /* [mc] 4.0 */
|
||||
outmovr(r,reg,tp);
|
||||
stacksize = savestk;
|
||||
outgoto(lab2=nextlabel++);
|
||||
outlab(lab1);
|
||||
r = scodegen(tp->t_right->t_right,cookie,reg); /* [mc] 4.0 */
|
||||
outmovr(r,reg,tp);
|
||||
outlab(lab2);
|
||||
return(reg);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* condbr - handle conditional branch code generation*/
|
||||
/* This handles the conditional branch code generation, handling*/
|
||||
/* the special cases for constants, ||, &&, ! and generating the*/
|
||||
/* correct conditional branch instruction.*/
|
||||
condbr(tp,dir,lab,reg)
|
||||
struct tnode *tp;
|
||||
int dir;
|
||||
int lab;
|
||||
int reg;
|
||||
{
|
||||
register struct tnode *ltp, *rtp;
|
||||
register int lab1, optype, op, subdir;
|
||||
|
||||
ltp = tp->t_left;
|
||||
if( binop(op=tp->t_op) )
|
||||
rtp = tp->t_right;
|
||||
subdir = dir; /*set up for LOR*/
|
||||
switch( op ) {
|
||||
|
||||
case CINT:
|
||||
if( !tp->t_value ) {
|
||||
if( dir == FALSE )
|
||||
outgoto(lab);
|
||||
}
|
||||
else if( dir != FALSE )
|
||||
outgoto(lab);
|
||||
break;
|
||||
|
||||
case NOT:
|
||||
condbr(ltp,!dir,lab,reg);
|
||||
break;
|
||||
|
||||
case LAND:
|
||||
dir = !dir;
|
||||
case LOR:
|
||||
if( dir == FALSE ) {
|
||||
lab1 = nextlabel++;
|
||||
condbr(ltp,!subdir,lab1,reg);
|
||||
condbr(rtp,subdir,lab,reg);
|
||||
outlab(lab1);
|
||||
}
|
||||
else {
|
||||
condbr(ltp,subdir,lab,reg);
|
||||
condbr(rtp,subdir,lab,reg);
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMA:
|
||||
scodegen(tp->t_left,FOREFF,reg);
|
||||
condbr(tp->t_right,dir,lab,reg);
|
||||
break;
|
||||
|
||||
default:
|
||||
if( op == NEQUALS && ltp->t_op == PREDEC &&
|
||||
isdreg(ltp->t_left->t_reg) && ltp->t_left->t_type == INT &&
|
||||
rtp->t_op == CINT && rtp->t_value == -1 ) {
|
||||
outdbra(ltp->t_left->t_reg,lab);
|
||||
break;
|
||||
}
|
||||
if( relop(op) && ltp->t_op == AUTOINC && rtp->t_op == AUTOINC &&
|
||||
ltp->t_type == rtp->t_type )
|
||||
outcmpm(tp);
|
||||
else
|
||||
scodegen(tp,FORCC,reg);
|
||||
optype = 0;
|
||||
if( relop(op) ) {
|
||||
if( unorptr(ltp->t_type) || unorptr(rtp->t_type) )
|
||||
optype =+ 1;
|
||||
}
|
||||
else
|
||||
op = NEQUALS;
|
||||
if(!dir)
|
||||
op = invrel[op-EQUALS];
|
||||
optype = brtab[op-EQUALS][optype];
|
||||
printf("%s L%d\n",mnemonics[optype],lab);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rcodegen(tpp,cookie,reg) /* returns changed flag*/
|
||||
struct tnode **tpp; /* pointer to tree*/
|
||||
int cookie; /* code generation cookie*/
|
||||
int reg; /* register to use for code*/
|
||||
{
|
||||
register int change, op;
|
||||
register struct tnode *tp;
|
||||
|
||||
tp = *tpp;
|
||||
op = tp->t_op;
|
||||
change = 0;
|
||||
if( notleafop(op) && op != COMMA ) {
|
||||
change =+ rcodegen(&tp->t_left,cookie,reg);
|
||||
if( binop(op) )
|
||||
change =+ rcodegen(&tp->t_right,cookie,reg);
|
||||
change =+ rcgen(tpp,cookie,reg);
|
||||
}
|
||||
if( change )
|
||||
*tpp = canon(*tpp);
|
||||
return(change);
|
||||
}
|
||||
|
||||
rcgen(tpp,cookie,reg) /* returns changed flag*/
|
||||
struct tnode **tpp; /* pointer to tree*/
|
||||
int cookie; /* code generation goals*/
|
||||
int reg; /* register to use*/
|
||||
{
|
||||
register struct tnode *tp, *p, *ltp, *rtp;
|
||||
register int op, change;
|
||||
|
||||
change = 0;
|
||||
for( tp = *tpp ; binop(op=tp->t_op); *tpp=tp=canon(tp), change++ ) {
|
||||
ltp = tp->t_left;
|
||||
if( ltp->t_op != SYMBOL )
|
||||
break;
|
||||
rtp = tp->t_right;
|
||||
switch( op ) {
|
||||
|
||||
case ASSIGN:
|
||||
if( ltp->t_sc != REGISTER )
|
||||
return(change);
|
||||
switch( rtp->t_op ) {
|
||||
|
||||
case MULT:
|
||||
case DIV:
|
||||
case MOD:
|
||||
case AND:
|
||||
case OR:
|
||||
case XOR:
|
||||
case LSH:
|
||||
case RSH:
|
||||
if( isareg(ltp->t_reg) )
|
||||
return(change);
|
||||
case ADD:
|
||||
case SUB:
|
||||
p = rtp->t_right;
|
||||
if(NOTADDRESSABLE(ltp) || !noref(rtp->t_right,ltp->t_reg))
|
||||
return(change);
|
||||
p = rtp->t_left;
|
||||
if( p->t_op != SYMBOL || p->t_sc != REGISTER ||
|
||||
p->t_reg != ltp->t_reg ) {
|
||||
tp->t_right = p;
|
||||
#ifndef NODEBUG
|
||||
if( cflag > 1 )
|
||||
putexpr("rcgen",tp);
|
||||
#endif
|
||||
codegen(tp,FOREFF,reg);
|
||||
}
|
||||
tp->t_right = rtp->t_right;
|
||||
tp->t_op = rtp->t_op + (EQADD-ADD);
|
||||
continue;
|
||||
}
|
||||
case EQLSH:
|
||||
case EQRSH:
|
||||
if( ltp->t_sc != REGISTER )
|
||||
return(change);
|
||||
case EQADD:
|
||||
case EQSUB:
|
||||
case EQAND:
|
||||
case EQOR:
|
||||
case EQXOR:
|
||||
if( ltp->t_type == CHAR )
|
||||
return(change);
|
||||
#ifndef NODEBUG
|
||||
if( cflag > 1 )
|
||||
putexpr("rcgen",tp);
|
||||
#endif
|
||||
ucodegen(tp,FOREFF,reg);
|
||||
tp = ltp;
|
||||
continue;
|
||||
|
||||
case PREDEC:
|
||||
case PREINC:
|
||||
if( cookie == FORCC || ltp->t_type == CHAR )
|
||||
return(change);
|
||||
ucodegen(tp,FOREFF,reg);
|
||||
tp = ltp;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return(change);
|
||||
}
|
||||
|
||||
noref(tp,reg) /* 4.0 change */
|
||||
struct tnode *tp; /* returns 1 if no reference in tree to reg */
|
||||
int reg;
|
||||
{
|
||||
if ( leafop(tp->t_op) ) {
|
||||
if (tp->t_op == SYMBOL && tp->t_sc == REGISTER && tp->t_reg == reg)
|
||||
return(0);
|
||||
return(1);
|
||||
}
|
||||
if ( !noref(tp->t_left,reg) )
|
||||
return(0);
|
||||
if (binop(tp->t_op))
|
||||
return( noref(tp->t_right,reg) );
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* cdsize - compute size of data item*/
|
||||
cdsize(tp) /* returns data size in bytes*/
|
||||
struct tnode *tp;
|
||||
{
|
||||
register int type;
|
||||
|
||||
type = tp->t_type;
|
||||
if( suptype(type) )
|
||||
return(PTRSIZE);
|
||||
switch( type ) {
|
||||
|
||||
case CHAR:
|
||||
case INT:
|
||||
case UNSIGNED:
|
||||
return(INTSIZE);
|
||||
|
||||
case LONG:
|
||||
case FLOAT: /* [vlh] 3.4 */
|
||||
return(LONGSIZE);
|
||||
}
|
||||
error("cdsize: invalid type %d",type);
|
||||
return(0);
|
||||
}
|
||||
|
||||
dofarg(tp) /* returns number of bytes pushed*/
|
||||
struct tnode *tp; /* pointer to expression tree*/
|
||||
{
|
||||
register int nb;
|
||||
|
||||
nb = 0;
|
||||
if( tp->t_op == SYMBOL && tp->t_sc == STRUCT )
|
||||
error("structure operation not implemented");
|
||||
else if( stacksize ) {
|
||||
codegen(tp,FORSTACK,0);
|
||||
nb = cdsize(tp);
|
||||
}
|
||||
else
|
||||
codegen(tp,FORSP,0);
|
||||
return( nb );
|
||||
}
|
||||
|
||||
/* dobitadd - do bit operation address checking and fixup*/
|
||||
dobitadd(tp,bitno) /* returns -1 if can't or bitno*/
|
||||
struct tnode *tp;
|
||||
int bitno;
|
||||
{
|
||||
register int offset;
|
||||
|
||||
if( tp->t_type == CHAR )
|
||||
offset = 0;
|
||||
else
|
||||
offset = cdsize(tp) - (bitno/BITSPBYTE) - 1;
|
||||
if( tp->t_op == SYMBOL ) {
|
||||
switch( tp->t_sc ) {
|
||||
|
||||
case REGISTER:
|
||||
if( isdreg(tp->t_reg) )
|
||||
return(bitno);
|
||||
default:
|
||||
return(-1);
|
||||
|
||||
case EXTERNAL:
|
||||
case STATIC:
|
||||
case REGOFF:
|
||||
case STATOFF:
|
||||
case EXTOFF:
|
||||
tp->t_offset =+ offset;
|
||||
return( bitno % BITSPBYTE );
|
||||
}
|
||||
}
|
||||
else if( tp->t_op == INDR ) {
|
||||
tp->t_left = tnalloc(ADD,tp->t_left->t_type,0,0,tp->t_left,
|
||||
cnalloc(INT,offset));
|
||||
return( bitno % BITSPBYTE );
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
isonebit(tp) /* returns -1 if not 1 bit, else bitno*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
{
|
||||
if( tp = constant(tp) )
|
||||
return( onebit(tp->t_value) );
|
||||
return(-1);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/*built-in literals*/
|
||||
#define MOV 128
|
||||
#define MOVL 129
|
||||
#define JSR 130
|
||||
#define CLR 131
|
||||
#define CLRL 132
|
||||
#define EXTW 133
|
||||
#define EXTL 134
|
||||
#define LEA 135
|
||||
#define STK 136
|
||||
|
||||
/*built-in macros*/
|
||||
#define TREE 141
|
||||
#define LEFT 142
|
||||
#define RIGHT 143
|
||||
#define LOFFSET 144
|
||||
#define ROFFSET 145
|
||||
#define LADDR 146
|
||||
#define RADDR 147
|
||||
#define CR 148
|
||||
#define NR 149
|
||||
#define CAR 150
|
||||
#define NAR 151
|
||||
#define TLEFT 152
|
||||
#define TRIGHT 153
|
||||
#define TEITHER 154
|
||||
#define TLEFTL 155
|
||||
#define OP 156
|
||||
#define AOP 157
|
||||
#define MODSWAP 158
|
||||
#define EXL 159
|
||||
#define EXLR 160
|
||||
#define EXLRN 161
|
||||
#define EXRL 162
|
||||
#define EXRLN 163
|
||||
#define PSH 164
|
||||
#define POP 165
|
||||
#define POP8 166
|
||||
#define OPCALL 167
|
||||
#define POP4 169
|
||||
#define LADDRP 168
|
||||
|
||||
/*modifiers for compiling sub-trees*/
|
||||
#define S_INDR 1 /*indirection*/
|
||||
#define S_STACK 2 /*onto stack*/
|
||||
#define S_FORCC 4 /*set condition codes*/
|
||||
#define S_NEXT 8 /*into next register*/
|
||||
|
||||
/*Sethy-Ullman values*/
|
||||
#define SU_ZERO 0x000 /*zero*/
|
||||
#define SU_ONE 0x100 /*one*/
|
||||
#define SU_SMALL 0x200 /*constant between 1 and 8*/
|
||||
#define SU_QUICK 0x300 /*quick constant between -128 and 127*/
|
||||
#define SU_CONST 0x400 /*any constant*/
|
||||
#define SU_AREG 0x500 /*A register*/
|
||||
#define SU_REG 0x600 /*register*/
|
||||
#define SU_ADDR 0x700 /*addressable*/
|
||||
#define SU_XREG 0x800 /*A register used as data...*/
|
||||
#define SU_EASY 0x900 /*easy*/
|
||||
#define SU_HARD 0xa00 /*hard*/
|
||||
#define SU_VHARD 0xb00 /*very hard ... function calls, etc.*/
|
||||
#define SU_ANY 0xf00 /*anything*/
|
||||
#define ADDRESSABLE(x) (x->t_su<=SU_ADDR)
|
||||
#define NOTADDRESSABLE(x) (x->t_su>SU_ADDR)
|
||||
#define LOADABLE(x) (x->t_su<=SU_XREG)
|
||||
|
||||
/*flag byte (operand type):*/
|
||||
#define T_CHAR 1 /*char only*/
|
||||
#define T_SHORT 2 /*short*/
|
||||
#define T_INT 3 /*int only*/
|
||||
#define T_LONG 4 /*long*/
|
||||
#define T_UCHAR 5 /*unsigned char*/
|
||||
#define T_USHORT 6 /*unsigned short*/
|
||||
#define T_UNSN 7 /*unsigned int*/
|
||||
#define T_ULONG 8 /*unsigned long*/
|
||||
#define T_FLOAT 9 /*float*/
|
||||
#define T_DOUB 10 /*double*/
|
||||
#define T_ANY 11 /*int or word (implied)*/
|
||||
#define T_INDR 0x10 /*pointer type (bit)*/
|
||||
|
||||
struct skeleton {
|
||||
int sk_left;
|
||||
int sk_right;
|
||||
char *sk_def;
|
||||
};
|
||||
1387
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/cskels.c
Normal file
1387
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/cskels.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
||||
$ set noon
|
||||
$ set def DRB0:[STEVE.CPM68K.C.FCGEN2]
|
||||
$ diff CANON.C [-.fcgen]CANON.C
|
||||
$ diff CODEGEN.C [-.fcgen]CODEGEN.C
|
||||
$ diff CSKELS.C [-.fcgen]CSKELS.C
|
||||
$ diff INTERF.C [-.fcgen]INTERF.C
|
||||
$ diff MAIN.C [-.fcgen]MAIN.C
|
||||
$ diff OPTAB.C [-.fcgen]OPTAB.C
|
||||
$ diff PUTEXPR.C [-.fcgen]PUTEXPR.C
|
||||
$ diff SMATCH.C [-.fcgen]SMATCH.C
|
||||
$ diff SUCOMP.C [-.fcgen]SUCOMP.C
|
||||
$ diff TABL.C [-.fcgen]TABL.C
|
||||
$ diff UTIL.C [-.fcgen]UTIL.C
|
||||
$ diff VERSION.C [-.fcgen]VERSION.C
|
||||
$ diff CGEN.H [-.fcgen]CGEN.H
|
||||
$ diff CSKEL.H [-.fcgen]CSKEL.H
|
||||
$ diff ICODE.H [-.fcgen]ICODE.H
|
||||
241
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/icode.h
Normal file
241
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/icode.h
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/*
|
||||
* intermediate code operators
|
||||
* 0=>EOF, special operator
|
||||
*/
|
||||
#define EOF 0
|
||||
|
||||
/*1-59=>operators that generate code (entries in code gen optab)*/
|
||||
#define ADD 1
|
||||
#define SUB 2
|
||||
#define MULT 3
|
||||
#define DIV 4
|
||||
#define MOD 5
|
||||
#define RSH 6
|
||||
#define LSH 7
|
||||
#define AND 8
|
||||
#define OR 9
|
||||
#define XOR 10
|
||||
#define NOT 11
|
||||
#define UMINUS 12
|
||||
#define COMPL 13
|
||||
#define PREDEC 14
|
||||
#define PREINC 15
|
||||
#define POSTDEC 16
|
||||
#define POSTINC 17
|
||||
#define ASSIGN 18
|
||||
#define EQADD 19
|
||||
#define EQSUB 20
|
||||
#define EQMULT 21
|
||||
#define EQDIV 22
|
||||
#define EQMOD 23
|
||||
#define EQRSH 24
|
||||
#define EQLSH 25
|
||||
#define EQAND 26
|
||||
#define EQOR 27
|
||||
#define EQXOR 28
|
||||
#define FJSR 29
|
||||
#define EQUALS 30
|
||||
#define NEQUALS 31
|
||||
#define GREAT 32
|
||||
#define GREATEQ 33
|
||||
#define LESS 34
|
||||
#define LESSEQ 35
|
||||
#define INT2L 36
|
||||
#define LONG2I 37
|
||||
|
||||
/*machine dependent operators that generate code*/
|
||||
#define BTST 38
|
||||
#define LOAD 39
|
||||
#define LMULT 40
|
||||
#define LDIV 41
|
||||
#define LMOD 42
|
||||
#define LEQMULT 43
|
||||
#define LEQDIV 44
|
||||
#define LEQMOD 45
|
||||
#define EQADDR 46
|
||||
#define EQNOT 47
|
||||
#define EQNEG 48
|
||||
#define DOCAST 49
|
||||
|
||||
#define STASSIGN 50 /*[vlh]*/
|
||||
#define LONG2F 51 /*[vlh] 3.4*/
|
||||
#define FLOAT2L 52 /*[vlh] 3.4*/
|
||||
#define INT2F 53 /*[vlh] 3.4*/
|
||||
#define FLOAT2I 54 /*[vlh] 3.4*/
|
||||
#define LCGENOP 55 /*change if adding more operators...*/
|
||||
|
||||
/*intermediate code operators that do not generate code*/
|
||||
#define ADDR 60
|
||||
#define INDR 61
|
||||
#define LAND 62
|
||||
#define LOR 63
|
||||
#define QMARK 64
|
||||
#define COLON 65
|
||||
#define COMMA 66
|
||||
#define CINT 67
|
||||
#define CLONG 68
|
||||
#define SYMBOL 69
|
||||
#define AUTOINC 70
|
||||
#define AUTODEC 71
|
||||
#define CALL 72
|
||||
#define NACALL 73
|
||||
#define BFIELD 74
|
||||
#define IFGOTO 75
|
||||
#define INIT 76
|
||||
#define CFORREG 77
|
||||
#define DCLONG 78
|
||||
#define CFLOAT 79 /*[vlh] 3.4*/
|
||||
|
||||
/*operators local to parser*/
|
||||
#define CAST 80
|
||||
#define SEMI 81
|
||||
#define LCURBR 82
|
||||
#define RCURBR 83
|
||||
#define LBRACK 84
|
||||
#define RBRACK 85
|
||||
#define LPAREN 86
|
||||
#define RPAREN 87
|
||||
#define STRING 88
|
||||
#define RESWORD 89
|
||||
#define APTR 90
|
||||
#define PERIOD 91
|
||||
#define SIZEOF 92
|
||||
#define MPARENS 93
|
||||
#define FRETURN 94
|
||||
#define STACKEND 100
|
||||
|
||||
/*data types*/
|
||||
#define TYPELESS 0
|
||||
#define CHAR 1
|
||||
#define SHORT 2
|
||||
#define INT 3
|
||||
#define LONG 4
|
||||
#define UCHAR 5
|
||||
#define USHORT 6
|
||||
#define UNSIGNED 7
|
||||
#define ULONG 8
|
||||
#define FLOAT 9
|
||||
#define DOUBLE 10
|
||||
|
||||
/*data types local to parser*/
|
||||
#define STRUCT 11
|
||||
#define FRSTRUCT 12
|
||||
#define LLABEL 13
|
||||
|
||||
/*type flags and definitions*/
|
||||
#define TYPE 017
|
||||
#define SUPTYP 060
|
||||
#define ALLTYPE 077
|
||||
#define POINTER 020
|
||||
#define FUNCTION 040
|
||||
#define ARRAY 060
|
||||
#define SUTYPLEN 2
|
||||
|
||||
/*data registers*/
|
||||
#define DREG0 0
|
||||
#define DREG2 2
|
||||
#define DREG3 3
|
||||
#define DREG4 4
|
||||
#define DREG5 5
|
||||
#define DREG6 6
|
||||
#define DREG7 7
|
||||
#define AREG3 11
|
||||
#define AREG4 12
|
||||
#define AREG5 13
|
||||
|
||||
/*storage classes*/
|
||||
#define AUTO 1
|
||||
#define REGISTER 2
|
||||
#define EXTERNAL 3
|
||||
#define STATIC 4
|
||||
#define REGOFF 5
|
||||
#define EXTOFF 6
|
||||
#define STATOFF 7
|
||||
#define INDEXED 8
|
||||
|
||||
/*exclusively code generator storage classes*/
|
||||
#define CINDR 9
|
||||
#define CLINDR 10
|
||||
#define CFINDR 11 /* [vlh] 3.4 */
|
||||
|
||||
/*exclusively parser storage classes*/
|
||||
#define STRPROTO 9
|
||||
#define PDECLIST 10
|
||||
#define PARMLIST 11
|
||||
#define BFIELDCL 12
|
||||
#define UNELCL 13
|
||||
#define STELCL 14
|
||||
|
||||
|
||||
/*opinfo table bits*/
|
||||
#define OPPRI 077
|
||||
#define OPBIN 0100
|
||||
#define OPLVAL 0200
|
||||
#define OPREL 0400
|
||||
#define OPASSIGN 01000
|
||||
#define OPLWORD 02000
|
||||
#define OPRWORD 04000
|
||||
#define OPCOM 010000
|
||||
#define OPRAS 020000
|
||||
#define OPTERM 040000
|
||||
#define OPCONVS 0100000
|
||||
|
||||
/*68000 definitions*/
|
||||
#define PTRSIZE 4
|
||||
#define INTSIZE 2
|
||||
#define LONGSIZE 4
|
||||
#define SSIZE 8 /* chars per symbol */
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define TABC '\t' /* tab character */
|
||||
#define EOLC '\n' /* end of line character */
|
||||
#define BITSPBYTE 8
|
||||
|
||||
/*operator class priorities*/
|
||||
#define TRMPRI 0 /* terminal nodes */
|
||||
#define RPNPRI 1 /* ) and ] */
|
||||
#define CALPRI 2 /* in-stack call, ( or [ */
|
||||
#define COLPRI 3 /* init or case priority for : or , */
|
||||
#define STKPRI 4 /* priority of end of stack */
|
||||
#define COMPRI 5 /* normal priority for , */
|
||||
#define ASGPRI 6 /* =, +=, -=, *=, /=, %=, ... */
|
||||
#define QMKPRI 7 /* ?: */
|
||||
#define LORPRI 8 /* || */
|
||||
#define LNDPRI 9 /* && */
|
||||
#define ORPRI 10 /* |, ! */
|
||||
#define ANDPRI 11 /* & */
|
||||
#define EQLPRI 12 /* ==, != */
|
||||
#define RELPRI 13 /* >, <, >=, <= */
|
||||
#define SHFPRI 14 /* <<, >> */
|
||||
#define ADDPRI 15 /* +, - */
|
||||
#define MULPRI 16 /* *, /, % */
|
||||
#define UNOPRI 17 /* ++, --, &, *, -, ~, sizeof */
|
||||
#define LPNPRI 18 /* ., ->, [, (, function call */
|
||||
#define PSTPRI 19 /* in-stack post--, post++ */
|
||||
|
||||
struct io_buf {
|
||||
int io_fd;
|
||||
int io_nc;
|
||||
char *io_p;
|
||||
char io_b[512];
|
||||
};
|
||||
struct { int hiword; int loword; };
|
||||
#define EXPSIZE 1024
|
||||
int exprarea[EXPSIZE];
|
||||
|
||||
/* v6io buffer declaration */
|
||||
#define BLEN 512
|
||||
|
||||
struct iobuf{
|
||||
int fildes;
|
||||
int nunused;
|
||||
char *xfree;
|
||||
char buff[BLEN];
|
||||
};
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
int bol;
|
||||
int onepass;
|
||||
|
||||
/* outexpr - output expression*/
|
||||
outexpr(tp) /* returns - none*/
|
||||
struct tnode *tp; /* pointer to tree node*/
|
||||
{
|
||||
if( dflag )
|
||||
outline();
|
||||
if( exprok(tp) )
|
||||
scodegen(canon(tp),FOREFF,0);
|
||||
}
|
||||
|
||||
outifgoto(tp,dir,lab)
|
||||
struct tnode *tp;
|
||||
int dir;
|
||||
int lab;
|
||||
{
|
||||
if( dflag )
|
||||
outline();
|
||||
if( exprok(tp) )
|
||||
condbr(canon(tp),dir,lab,0);
|
||||
}
|
||||
|
||||
outcforreg(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
if( dflag )
|
||||
outline();
|
||||
if( exprok(tp) )
|
||||
outmovr(scodegen(canon(tp),FORREG,0),0,tp);
|
||||
}
|
||||
|
||||
outinit(tp) /* returns - none*/
|
||||
struct tnode *tp;
|
||||
{
|
||||
register int typeout;
|
||||
|
||||
if( dflag )
|
||||
outline();
|
||||
if( exprok(tp) ) {
|
||||
typeout = tp->t_type;
|
||||
tp = canon(tp);
|
||||
if( tp->t_op == ADDR )
|
||||
tp = tp->t_left;
|
||||
if( tp->t_op == CINT || tp->t_op == SYMBOL ) {
|
||||
if( tp->t_op != CINT )
|
||||
printf(".dc.l ");
|
||||
else {
|
||||
printf(".dc");
|
||||
outtype(typeout);
|
||||
putchar(' ');
|
||||
}
|
||||
outaexpr(tp,NOTIMMED); /* [vlh] 4.0 not immed... */
|
||||
}
|
||||
else
|
||||
error("invalid initialization");
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/* snalloc - code generator symbol node allocation*/
|
||||
/* This might be coalesced into parser snalloc.*/
|
||||
char *snalloc(type,sc,offset,dp,ssp) /* returns ptr to node alloced*/
|
||||
int type; /* type of symbol*/
|
||||
int sc; /* storage class*/
|
||||
int offset; /* offset from Local Environment Ptr*/
|
||||
int dp; /*for compatability with parser*/
|
||||
int ssp; /*for compatability with parser*/
|
||||
{
|
||||
register struct symnode *sp;
|
||||
|
||||
sp = talloc(sizeof(*sp));
|
||||
sp->t_op = SYMBOL;
|
||||
sp->t_type = type;
|
||||
sp->t_su = dp;
|
||||
sp->t_ssp = ssp;
|
||||
sp->t_sc = sc;
|
||||
switch( sc ) {
|
||||
|
||||
case STATIC:
|
||||
sp->t_offset = 0;
|
||||
sp->t_reg = 0;
|
||||
sp->t_label = offset;
|
||||
break;
|
||||
|
||||
case REGISTER:
|
||||
sp->t_offset = 0;
|
||||
sp->t_reg = offset;
|
||||
sp->t_label = 0;
|
||||
break;
|
||||
|
||||
case AUTO:
|
||||
sp->t_sc = REGOFF;
|
||||
sp->t_offset = offset;
|
||||
sp->t_reg = LEP;
|
||||
sp->t_label = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
sp->t_offset = offset;
|
||||
sp->t_reg = 0;
|
||||
sp->t_label = 0;
|
||||
break;
|
||||
}
|
||||
return(sp);
|
||||
}
|
||||
|
||||
exprok(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
if( tp < exprarea || tp > &exprarea[EXPSIZE] )
|
||||
return(0);
|
||||
if( leafop(tp->t_op) )
|
||||
return(1);
|
||||
if( binop(tp->t_op) && !exprok(tp->t_right) )
|
||||
return(0);
|
||||
return( exprok(tp->t_left) );
|
||||
}
|
||||
|
||||
outline()
|
||||
{
|
||||
if( onepass && !bol )
|
||||
putchar('\n');
|
||||
printf("*line %d\n",lineno);
|
||||
}
|
||||
401
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/main.c
Normal file
401
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/main.c
Normal file
@@ -0,0 +1,401 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
char *version "@(#) c168 code generator 4.0 - Mar 18, 1983";
|
||||
|
||||
#include "cgen.h"
|
||||
#include "cskel.h"
|
||||
char *opap;
|
||||
int errflg;
|
||||
int nextlabel 10000;
|
||||
char *readtree();
|
||||
char *readsym();
|
||||
|
||||
|
||||
/* main - main routine, handles arguments and files*/
|
||||
main(argc,argv) /* returns - none*/
|
||||
int argc; /* arg count*/
|
||||
char **argv; /* arg pointers*/
|
||||
{
|
||||
register char *q;
|
||||
register int i;
|
||||
|
||||
#ifdef VERSADOS
|
||||
lflag++;
|
||||
#endif
|
||||
for( i = 3; i < argc; i++ ) {
|
||||
q = argv[i];
|
||||
if( *q++ != '-' )
|
||||
usage(argc,argv,1);
|
||||
while( 1 ) {
|
||||
switch( *q++ ) {
|
||||
|
||||
case 'D':
|
||||
dflag++;
|
||||
continue;
|
||||
|
||||
case 'L':
|
||||
lflag++;
|
||||
continue;
|
||||
|
||||
case 'e':
|
||||
eflag++;
|
||||
continue;
|
||||
|
||||
case 'f':
|
||||
fflag++;
|
||||
continue;
|
||||
|
||||
case 'm':
|
||||
mflag++;
|
||||
continue;
|
||||
|
||||
case 'o':
|
||||
oflag++;
|
||||
continue;
|
||||
|
||||
case 'c':
|
||||
cflag++;
|
||||
continue;
|
||||
|
||||
case '\0':
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(argc,argv,2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( argc < 3 )
|
||||
usage(argc,argv,3);
|
||||
if( fopen(argv[1],&ibuf,0) < 0 ) /* 3rd arg for versados */
|
||||
ferror("can't open %s\n",argv[1]);
|
||||
if( fcreat(argv[2],&obuf,0) < 0 ) /* 3rd arg for versados */
|
||||
ferror("can't create %s\n",argv[2]);
|
||||
readicode();
|
||||
v6flush(&obuf);
|
||||
exit(errcnt!=0);
|
||||
}
|
||||
|
||||
/* readicode - read intermediate code and dispatch output*/
|
||||
/* This copies assembler lines beginning with '(' to assembler*/
|
||||
/* output and builds trees starting with '.' line.*/
|
||||
readicode() /*returns - none*/
|
||||
{
|
||||
register int c;
|
||||
register struct tnode *tp;
|
||||
|
||||
while( (c=getc(&ibuf)) > 0 ) {
|
||||
switch(c) {
|
||||
|
||||
case '.':
|
||||
lineno = readint();
|
||||
opap = exprarea;
|
||||
if( tp = readtree() ) {
|
||||
#ifndef NODEBUG
|
||||
if( cflag )
|
||||
putexpr("readicode",tp);
|
||||
#endif
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case INIT:
|
||||
outinit(tp->t_left);
|
||||
break;
|
||||
|
||||
case CFORREG:
|
||||
outcforreg(tp->t_left);
|
||||
break;
|
||||
|
||||
case IFGOTO:
|
||||
outifgoto(tp->t_left,tp->t_type,tp->t_su);
|
||||
break;
|
||||
|
||||
default:
|
||||
outexpr(tp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '(':
|
||||
while( (c=getc(&ibuf)) != '\n' )
|
||||
putchar(c);
|
||||
putchar(c);
|
||||
break;
|
||||
|
||||
default:
|
||||
error("intermediate code error %c,%d",c,c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* readtree - recursive intermediate code tree read*/
|
||||
char *readtree() /* returns ptr to expression tree*/
|
||||
{
|
||||
register int op, type, sc;
|
||||
register struct tnode *tp, *rtp;
|
||||
char sym[SSIZE];
|
||||
long l;
|
||||
|
||||
if( (op=readint()) <= 0 )
|
||||
return(0);
|
||||
type = readint();
|
||||
switch( op ) {
|
||||
|
||||
case SYMBOL:
|
||||
if( (sc=readint()) == EXTERNAL )
|
||||
tp = cenalloc(type,sc,readsym(sym));
|
||||
else
|
||||
tp = snalloc(type,sc,readint(),0,0);
|
||||
break;
|
||||
|
||||
case CINT:
|
||||
tp = cnalloc(type,readint());
|
||||
break;
|
||||
|
||||
case CLONG:
|
||||
l.hiword = readint();
|
||||
l.loword = readint();
|
||||
tp = lcnalloc(type,l);
|
||||
break;
|
||||
|
||||
case CFLOAT: /* [vlh] 3.4 */
|
||||
l.hiword = readint();
|
||||
l.loword = readint();
|
||||
tp = fpcnalloc(type,l);
|
||||
break;
|
||||
|
||||
case IFGOTO:
|
||||
case BFIELD:
|
||||
sc = readint();
|
||||
if( tp = readtree() )
|
||||
tp = tnalloc(op,type,sc,0,tp,null);
|
||||
break;
|
||||
|
||||
default:
|
||||
if( binop(op) ) {
|
||||
if( !(tp=readtree()) )
|
||||
return(0);
|
||||
if( !(rtp=readtree()) )
|
||||
return(0);
|
||||
tp = tnalloc(op,type,0,0,tp,rtp);
|
||||
}
|
||||
else if( tp = readtree() )
|
||||
tp = tnalloc(op,type,0,0,tp,null);
|
||||
break;
|
||||
}
|
||||
return(tp);
|
||||
}
|
||||
|
||||
/* readint - reads an integer value from intermediate code*/
|
||||
readint()
|
||||
{
|
||||
register int i, c;
|
||||
|
||||
i = 0;
|
||||
while(1) {
|
||||
switch( c = getc(&ibuf) ) {
|
||||
|
||||
case '.':
|
||||
case '\n':
|
||||
return(i);
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
i =<< 4;
|
||||
i =+ (c-'0');
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
i =<< 4;
|
||||
i =+ (c-('a'-10));
|
||||
break;
|
||||
|
||||
default:
|
||||
error("intermediate code error - %c,%d",c,c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* readsym - read a symbol from intermediate code*/
|
||||
char *readsym(sym)
|
||||
char *sym;
|
||||
{
|
||||
register int i, c;
|
||||
register char *s;
|
||||
|
||||
for( i = SSIZE, s = sym; (c=getc(&ibuf)) != '\n'; )
|
||||
if( --i >= 0 )
|
||||
*s++ = c;
|
||||
if( i > 0 )
|
||||
*s = '\0';
|
||||
return(sym);
|
||||
}
|
||||
|
||||
/* error - output an error message*/
|
||||
error(s,x1,x2,x3,x4,x5,x6)
|
||||
char *s;
|
||||
int x1, x2, x3, x4, x5, x6;
|
||||
{
|
||||
errcnt++;
|
||||
errflg++;
|
||||
if( lineno != 0 )
|
||||
printf("** %d: ",lineno);
|
||||
printf(s,x1,x2,x3,x4,x5,x6);
|
||||
putchar('\n');
|
||||
errflg--;
|
||||
}
|
||||
|
||||
/* ferror - output error message and die*/
|
||||
ferror(s,x1,x2,x3,x4,x5,x6)
|
||||
char *s;
|
||||
int x1, x2, x3, x4, x5, x6;
|
||||
{
|
||||
error(s,x1,x2,x3,x4,x5,x6);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* tnalloc - allocate binary expression tree node*/
|
||||
/* returns ptr to node made.*/
|
||||
char *tnalloc(op,type,info,dummy,left,right)
|
||||
int op; /* operator*/
|
||||
int type; /* resultant node type*/
|
||||
int info; /* info field*/
|
||||
int dummy; /* dummy field - used to match pass1 args*/
|
||||
struct tnode *left; /* left sub-tree*/
|
||||
struct tnode *right; /* righst sub-tree*/
|
||||
{
|
||||
register struct tnode *tp;
|
||||
|
||||
tp = talloc(sizeof(*tp));
|
||||
tp->t_op = op;
|
||||
tp->t_type = type;
|
||||
tp->t_su = info; /* info for bit-field & condbr's*/
|
||||
tp->t_left = left;
|
||||
tp->t_right = right;
|
||||
return(tp);
|
||||
}
|
||||
|
||||
/* cnalloc - allocate constant expression tree node*/
|
||||
char *cnalloc(type,value) /* returns pointer to node alloced*/
|
||||
int type; /* type of constant*/
|
||||
int value; /* value of constant*/
|
||||
{
|
||||
register struct conode *cp;
|
||||
|
||||
cp = talloc(sizeof(*cp));
|
||||
cp->t_op = CINT;
|
||||
cp->t_type = type;
|
||||
cp->t_value = value;
|
||||
return(cp);
|
||||
}
|
||||
|
||||
/* lcnalloc - allocate constant expression tree node*/
|
||||
char *lcnalloc(type,value) /* returns pointer to node alloced*/
|
||||
int type; /* type of constant*/
|
||||
long value; /* value of constant*/
|
||||
{
|
||||
register struct lconode *cp;
|
||||
|
||||
cp = talloc(sizeof(*cp));
|
||||
cp->t_op = CLONG;
|
||||
cp->t_type = type;
|
||||
cp->t_lvalue = value;
|
||||
return(cp);
|
||||
}
|
||||
|
||||
/* fpcnalloc - allocate constant expression tree node*/
|
||||
char *fpcnalloc(type,value) /* returns pointer to node alloced*/
|
||||
int type; /* type of constant*/
|
||||
long value; /* value of constant*/
|
||||
{ /* [vlh] 3.4 */
|
||||
register struct lconode *cp;
|
||||
|
||||
cp = talloc(sizeof(*cp));
|
||||
cp->t_op = CFLOAT;
|
||||
cp->t_type = type;
|
||||
cp->t_lvalue = value;
|
||||
return(cp);
|
||||
}
|
||||
|
||||
/* talloc - allocate expression tree area*/
|
||||
char *talloc(size) /* returns pointer to area alloced*/
|
||||
int size; /* number of bytes to alloc*/
|
||||
{
|
||||
register char *p;
|
||||
|
||||
p = opap;
|
||||
if( p + size >= &exprarea[EXPSIZE] )
|
||||
ferror("expression too complex");
|
||||
opap = p + size;
|
||||
return(p);
|
||||
}
|
||||
|
||||
/* symcopy - copy symbol*/
|
||||
symcopy(sym1,sym2) /* returns - none*/
|
||||
char *sym1; /* from symbol*/
|
||||
char *sym2; /* to symbol*/
|
||||
{
|
||||
register char *p, *q;
|
||||
register int i;
|
||||
|
||||
for( p = sym1, q = sym2, i = SSIZE; --i >= 0; )
|
||||
*q++ = (*p ? *p++ : '\0');
|
||||
}
|
||||
|
||||
/* usage - ouput usage message*/
|
||||
usage(argc,argv,n)
|
||||
char *argv[];
|
||||
{
|
||||
register int i;
|
||||
error("usage call #%d:\n",n);
|
||||
for (i=0; i<argc; i++) error(" argv[%d] = %s\n",i,argv[i]);
|
||||
ferror("usage: c168 icode asm [-DLmec]");
|
||||
}
|
||||
|
||||
/* putchar - special version*/
|
||||
/* This allows the use of printf for error messages, debugging*/
|
||||
/* output and normal output.*/
|
||||
putchar(c) /* returns - none*/
|
||||
char c; /* character to output*/
|
||||
{
|
||||
if( errflg ) /*error message?*/
|
||||
write(1,&c,1); /*write to standard output*/
|
||||
else {
|
||||
if( dflag > 1 )
|
||||
write(1,&c,1); /*to standard output*/
|
||||
putc(c,&obuf); /*put to assembler file*/
|
||||
}
|
||||
}
|
||||
|
||||
v6flush(v6b)
|
||||
struct iobuf *v6b;
|
||||
{
|
||||
register i;
|
||||
|
||||
i = BLEN - v6b->nunused;
|
||||
v6b->nunused = BLEN;
|
||||
v6b->xfree = &(v6b->buff[0]);
|
||||
if(write(v6b->fildes,v6b->xfree,i) != i)
|
||||
return(-1);
|
||||
return(0);
|
||||
}
|
||||
322
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/optab.c
Normal file
322
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/optab.c
Normal file
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
|
||||
#define I_NULL 0
|
||||
#define I_ADD 1
|
||||
#define I_INC 2
|
||||
#define I_SUB 3
|
||||
#define I_DEC 4
|
||||
#define I_MULS 5
|
||||
#define I_MULU 6
|
||||
#define I_DIVS 7
|
||||
#define I_DIVU 8
|
||||
#define I_ASR 9
|
||||
#define I_LSR 10
|
||||
#define I_ASL 11
|
||||
#define I_LSL 12
|
||||
#define I_AND 13
|
||||
#define I_OR 14
|
||||
#define I_EOR 15
|
||||
#define I_NEG 16
|
||||
#define I_NOT 17
|
||||
#define I_MOVE 18
|
||||
#define I_CLR 19
|
||||
#define I_CMP 20
|
||||
#define I_TST 21
|
||||
#define I_LMUL 22
|
||||
#define I_LDIV 23
|
||||
#define I_LREM 24
|
||||
#define I_LEML 25
|
||||
#define I_LERM 27
|
||||
#define I_BEQ 28
|
||||
#define I_BNE 29
|
||||
#define I_BGT 30
|
||||
#define I_BGE 31
|
||||
#define I_BLT 32
|
||||
#define I_BLE 33
|
||||
#define I_BLS 34
|
||||
#define I_BLO 35
|
||||
#define I_BCC 36
|
||||
#define I_BHI 37
|
||||
#define I_BRA 38
|
||||
#define I_NOP 39
|
||||
#define I_BTST 40
|
||||
|
||||
char *mnemonics[] {
|
||||
"",
|
||||
"add",
|
||||
"inc",
|
||||
"sub",
|
||||
"dec",
|
||||
"muls",
|
||||
"mulu",
|
||||
"divs",
|
||||
"divu",
|
||||
"asr",
|
||||
"lsr",
|
||||
"asl",
|
||||
"lsl",
|
||||
"and",
|
||||
"or",
|
||||
"eor",
|
||||
"neg",
|
||||
"not",
|
||||
"move",
|
||||
"clr",
|
||||
"cmp",
|
||||
"tst",
|
||||
"lmul",
|
||||
"_ldiv",
|
||||
"lrem",
|
||||
"almul",
|
||||
"aldiv",
|
||||
"alrem",
|
||||
"beq",
|
||||
"bne",
|
||||
"bgt",
|
||||
"bge",
|
||||
"blt",
|
||||
"ble",
|
||||
"bls",
|
||||
"blo",
|
||||
"bcc",
|
||||
"bhi",
|
||||
"jmp",
|
||||
"*nop",
|
||||
"btst",
|
||||
};
|
||||
|
||||
#define FE_EQOP 1
|
||||
#define FE_ASSIGN 2
|
||||
#define FE_EQSHFT 3
|
||||
#define FE_EQXOR 4
|
||||
#define FE_EQADDR 5
|
||||
#define FC_FIX 6
|
||||
#define FC_REL 7
|
||||
#define FC_BTST 8
|
||||
#define FS_OP 9
|
||||
#define FS_ITL 10
|
||||
#define FS_LD 11
|
||||
#define FR_ADD 12
|
||||
#define FR_MULT 13
|
||||
#define FR_DIV 14
|
||||
#define FR_SHFT 15
|
||||
#define FR_XOR 16
|
||||
#define FR_NEG 17
|
||||
#define FR_EQOP 18
|
||||
#define FR_POSTOP 19
|
||||
#define FR_ASSIGN 20
|
||||
#define FR_EQMULT 21
|
||||
#define FR_EQDIV 22
|
||||
#define FR_EQSHFT 23
|
||||
#define FR_EQXOR 24
|
||||
#define FR_CALL 25
|
||||
#define FR_ITL 26
|
||||
#define FR_LTI 27
|
||||
#define FR_LD 28
|
||||
#define FR_EQADDR 29
|
||||
#define FR_EQNOT 30
|
||||
#define FE_EQNOT 31
|
||||
#define FR_DOCAST 32
|
||||
#define FS_DOCAST 33
|
||||
#define FR_FTOL 34
|
||||
#define FR_LTOF 35
|
||||
#define FR_FTOI 36
|
||||
#define FR_ITOF 37
|
||||
#define FE_EQMULT 38
|
||||
#define FE_EQDIV 39
|
||||
#define FE_EQMOD 40
|
||||
#define FR_TOCHAR 41
|
||||
|
||||
char
|
||||
fe_eqop[], /* 1=FE_EQOP */
|
||||
fe_assign[], /* 2=FE_ASSIGN */
|
||||
fe_eqshft[], /* 3=FE_EQSHFT */
|
||||
fe_eqxor[], /* 4=FE_EQXOR */
|
||||
fe_eqaddr[], /* 5=FE_EQADDR */
|
||||
fc_fix[], /* 6=FC_FIX */
|
||||
fc_rel[], /* 7=FC_REL */
|
||||
fc_btst[], /* 8=FC_BTST */
|
||||
fs_op[], /* 9=FS_OP */
|
||||
fs_itl[], /* 10=FS_ITL */
|
||||
fs_ld[], /* 11=FS_LD */
|
||||
fr_op[], /* 12=FR_OP */
|
||||
fr_mult[], /* 13=FR_MULT */
|
||||
fr_div[], /* 14=FR_DIV */
|
||||
fr_shft[], /* 15=FR_SHFT */
|
||||
fr_xor[], /* 16=FR_XOR */
|
||||
fr_neg[], /* 17=FR_NEG */
|
||||
fr_eqop[], /* 18=FR_EQOP */
|
||||
fr_postop[], /* 19=FR_POSTOP */
|
||||
fr_assign[], /* 20=FR_ASSIGN */
|
||||
fr_eqmult[], /* 21=FR_EQMULT */
|
||||
fr_eqdiv[], /* 22=FR_EQDIV */
|
||||
fr_eqshft[], /* 23=FR_EQSHFT */
|
||||
fr_eqxor[], /* 23=FR_EQXOR */
|
||||
fr_call[], /* 24=FR_CALL */
|
||||
fr_itl[], /* 25=FR_ITL */
|
||||
fr_lti[], /* 26=FR_LTI */
|
||||
fr_ld[], /* 27=FR_LD */
|
||||
fr_eqaddr[], /* 28=FR_EQADDR */
|
||||
fr_eqnot[], /* 29=FR_EQNOT */
|
||||
fe_eqnot[], /* 30=FE_EQNOT */
|
||||
fr_docast[], /* 31=FR_DOCAST */
|
||||
fs_docast[], /* 32=FS_DOCAST */
|
||||
fr_ftol[], /* 34=FE_FTOL */
|
||||
fr_ltof[], /* 35=FE_LTOF */
|
||||
fr_ftoi[], /* 36=FE_FTOI */
|
||||
fr_itof[], /* 37=FE_ITOF */
|
||||
fe_eqmult[], /* 38=FE_EQMULT */
|
||||
fe_eqdiv[], /* 39=FE_EQDIV */
|
||||
fe_eqmod[], /* 40=FE_EQMOD */
|
||||
fr_tochar[]; /* 41=FR_TOCHAR */
|
||||
|
||||
char *codeskels[] {
|
||||
0, /*NULL*/
|
||||
fe_eqop, /*1=FE_EQOP*/
|
||||
fe_assign, /*2=FE_ASSIGN*/
|
||||
fe_eqshft, /*3=FE_EQSHFT*/
|
||||
fe_eqxor, /*4=FE_EQXOR*/
|
||||
fe_eqaddr, /*5=FE_EQADDR*/
|
||||
fc_fix, /*6=FC_FIX*/
|
||||
fc_rel, /*7=FC_REL*/
|
||||
fc_btst, /*8=FC_BTST*/
|
||||
fs_op, /*9=FS_OP*/
|
||||
fs_itl, /*10=FS_ITL*/
|
||||
fs_ld, /*11=FS_LD*/
|
||||
fr_op, /*12=FR_OP*/
|
||||
fr_mult, /*13=FR_MULT*/
|
||||
fr_div, /*14=FR_DIV*/
|
||||
fr_shft, /*15=FR_SHFT*/
|
||||
fr_xor, /*16=FR_XOR*/
|
||||
fr_neg, /*17=FR_NEG*/
|
||||
fr_eqop, /*18=FR_EQOP*/
|
||||
fr_postop, /*19=FR_POSTOP*/
|
||||
fr_assign, /*20=FR_ASSIGN*/
|
||||
fr_eqmult, /*21=FR_EQMULT*/
|
||||
fr_eqdiv, /*22=FR_EQDIV*/
|
||||
fr_eqshft, /*23=FR_EQSHFT*/
|
||||
fr_eqxor, /*24=FR_EQXOR*/
|
||||
fr_call, /*25=FR_CALL*/
|
||||
fr_itl, /*26=FR_ITL*/
|
||||
fr_lti, /*27=FR_LTI*/
|
||||
fr_ld, /*28=FE_LD*/
|
||||
fr_eqaddr, /*29=FE_EQADDR*/
|
||||
fr_eqnot, /*30=FE_EQNOT*/
|
||||
fe_eqnot, /*31=FE_EQNOT*/
|
||||
fr_docast, /*32=FE_DOCAST*/
|
||||
fs_docast, /*33=FS_DOCAST*/
|
||||
fr_ftol, /*34=FE_FTOL*/
|
||||
fr_ltof, /*35=FE_LTOF*/
|
||||
fr_ftoi, /*36=FE_FTOI*/
|
||||
fr_itof, /*37=FE_ITOF*/
|
||||
fe_eqmult, /*38=FE_EQMULT*/
|
||||
fe_eqdiv, /*39=FE_EQDIV*/
|
||||
fe_eqmod, /*40=FE_EQMOD*/
|
||||
fr_tochar, /*41=FR_TOCHAR*/
|
||||
};
|
||||
/*
|
||||
*This is the major table directing the code generation process.
|
||||
*It is indexed by an O_op operator, which is obtained from the
|
||||
*opinfo table for an intermediate code operator. The actual
|
||||
*code skeleton macros are in cskels.c, which are in a linked
|
||||
*list in order of decreasing order of difficulty.
|
||||
*/
|
||||
char optab[][6] {
|
||||
|
||||
/* I I2 effect cc's stack register*/
|
||||
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*0=NULL*/
|
||||
I_ADD, I_INC, I_NULL, FC_FIX, FS_OP, FR_ADD, /*1=ADD*/
|
||||
I_SUB, I_DEC, I_NULL, FC_FIX, FS_OP, FR_ADD, /*2=SUB*/
|
||||
I_MULS, I_MULU, I_NULL, FC_FIX, I_NULL, FR_MULT, /*3=MULT*/
|
||||
I_DIVS, I_DIVU, I_NULL, FC_FIX, I_NULL, FR_DIV, /*4=DIV*/
|
||||
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*5=MOD*/
|
||||
I_ASR, I_LSR, I_NULL, FC_FIX, I_NULL, FR_SHFT, /*6=RSH*/
|
||||
I_ASL, I_LSL, I_NULL, FC_FIX, I_NULL, FR_SHFT, /*7=LSH*/
|
||||
I_AND, I_AND, I_NULL, FC_FIX, FS_OP, FR_ADD, /*8=AND*/
|
||||
I_OR, I_OR, I_NULL, FC_FIX, FS_OP, FR_ADD, /*9=OR*/
|
||||
I_EOR, I_EOR, I_NULL, FC_FIX, I_NULL, FR_XOR, /*10=XOR*/
|
||||
I_NULL, I_NULL, I_NULL, FC_FIX, I_NULL, I_NULL, /*11=NOT*/
|
||||
I_NEG, I_NEG, I_NULL, FC_FIX, I_NULL, FR_NEG, /*12=NEG*/
|
||||
I_NOT, I_NOT, I_NULL, I_NULL, I_NULL, FR_NEG, /*13=COMPL*/
|
||||
I_SUB, I_DEC, FE_EQOP, FC_FIX, I_NULL, FR_EQOP, /*14=PREDEC*/
|
||||
I_ADD, I_INC, FE_EQOP, FC_FIX, I_NULL, FR_EQOP, /*15=PREINC*/
|
||||
I_SUB, I_DEC, FE_EQOP, I_NULL, I_NULL, FR_POSTOP, /*16=POSTDEC*/
|
||||
I_ADD, I_INC, FE_EQOP, I_NULL, I_NULL, FR_POSTOP, /*17=POSTINC*/
|
||||
I_MOVE, I_CLR, FE_ASSIGN, I_NULL, I_NULL, FR_ASSIGN, /*18=ASSIGN*/
|
||||
I_ADD, I_INC, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*19=EQADD*/
|
||||
I_SUB, I_DEC, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*20=EQSUB*/
|
||||
I_MULS, I_MULU, FE_EQMULT, FC_FIX, I_NULL, FR_EQMULT, /*21=EQMULT*/
|
||||
I_DIVS, I_DIVU, FE_EQDIV, FC_FIX, I_NULL, FR_EQDIV, /*22=EQDIV*/
|
||||
I_DIVS, I_DIVU, FE_EQMOD, I_NULL, I_NULL, FR_EQDIV, /*23=EQMOD*/
|
||||
I_ASR, I_LSR, FE_EQSHFT, I_NULL, I_NULL, FR_EQSHFT, /*24=EQRSH*/
|
||||
I_ASL, I_LSL, FE_EQSHFT, I_NULL, I_NULL, FR_EQSHFT, /*25=EQLSH*/
|
||||
I_AND, I_AND, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*26=EQAND*/
|
||||
I_OR, I_OR, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*27=EQOR*/
|
||||
I_EOR, I_EOR, FE_EQXOR, FC_FIX, I_NULL, FR_EQXOR, /*28=EQXOR*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_CALL, /*29=FJSR*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*30=EQUALS*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*31=NEQUALS*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*32=GREAT*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*33=GREATEQ*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*34=LESS*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*35=LESSEQ*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, FS_ITL, FR_ITL, /*36=INT2L*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_LTI, /*37=LONG2I*/
|
||||
I_BTST, I_BTST, I_NULL, FC_BTST, I_NULL, I_NULL, /*38=BTST*/
|
||||
I_CMP, I_TST, I_NULL, FC_REL, FS_LD, FR_LD, /*39=LOAD*/
|
||||
I_MULS, I_MULU, I_NULL, I_NULL, I_NULL, FR_MULT, /*40=LMULT*/
|
||||
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*41=LDIV*/
|
||||
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*42=LMOD*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*43=NULL*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*44=NULL*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*45=NULL*/
|
||||
I_NULL, I_NULL, FE_EQADDR, I_NULL, I_NULL, FR_EQADDR, /*46=EQADDR*/
|
||||
I_NOT, I_NOT, FE_EQNOT, I_NULL, I_NULL, FR_EQNOT, /*47=EQNOT*/
|
||||
I_NEG, I_NEG, FE_EQNOT, I_NULL, I_NULL, FR_EQNOT, /*48=EQNEG*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, FS_DOCAST, FR_DOCAST, /*49=DOCAST*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*50=STASSIGN*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_LTOF, /*51=LONG2F*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_FTOL, /*52=FLOAT2L*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_ITOF, /*53=INT2F*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_FTOI, /*54=FLOAT2I*/
|
||||
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_TOCHAR, /*55=TOCHAR*/
|
||||
};
|
||||
|
||||
|
||||
/*this maps comparison operators and comparison types into the*/
|
||||
/*actual branch opcode used.*/
|
||||
char brtab[][2] {
|
||||
I_BEQ, I_BEQ, /*EQUALS*/
|
||||
I_BNE, I_BNE, /*NEQUALS*/
|
||||
I_BGT, I_BHI, /*GREAT*/
|
||||
I_BGE, I_BCC, /*GREATEQ*/
|
||||
I_BLT, I_BLO, /*LESS*/
|
||||
I_BLE, I_BLS, /*LESSEQ*/
|
||||
};
|
||||
|
||||
/*turns !x>y into x<=y*/
|
||||
int invrel[] { NEQUALS, EQUALS, LESSEQ, LESS, GREATEQ, GREAT };
|
||||
|
||||
/*turns x>y into y<=x*/
|
||||
int swaprel[] { EQUALS, NEQUALS, LESS, LESSEQ, GREAT, GREATEQ };
|
||||
|
||||
/*code skeleton built-in strings*/
|
||||
char *strtab[] {
|
||||
"move", /*MOV*/
|
||||
"move.l", /*MOVL*/
|
||||
"jsr", /*JSR*/
|
||||
"clr", /*CLR*/
|
||||
"clr.l", /*CLRL*/
|
||||
"ext.w", /*EXTW*/
|
||||
"ext.l", /*EXTL*/
|
||||
"lea", /*LEA*/
|
||||
"(sp)", /*STK*/
|
||||
};
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
#ifndef NODEBUG
|
||||
|
||||
char invalid[] "INVALID";
|
||||
|
||||
char *opname[] {
|
||||
invalid, /*0*/
|
||||
"+", /*1*/
|
||||
"-", /*2*/
|
||||
"*", /*3*/
|
||||
"/", /*4*/
|
||||
"%", /*5*/
|
||||
">>", /*6*/
|
||||
"<<", /*7*/
|
||||
"&", /*8*/
|
||||
"|", /*9*/
|
||||
"^", /*10*/
|
||||
"!", /*11*/
|
||||
"U-", /*12*/
|
||||
"~", /*13*/
|
||||
"--p", /*14*/
|
||||
"++p", /*15*/
|
||||
"p--", /*16*/
|
||||
"p++", /*17*/
|
||||
"=", /*18*/
|
||||
"+=", /*19*/
|
||||
"-=", /*20*/
|
||||
"*=", /*21*/
|
||||
"/=", /*22*/
|
||||
"%=", /*23*/
|
||||
">>=", /*24*/
|
||||
"<<=", /*25*/
|
||||
"&=", /*26*/
|
||||
"|=", /*27*/
|
||||
"^=", /*28*/
|
||||
"jsr", /*29*/
|
||||
"==", /*30*/
|
||||
"!=", /*31*/
|
||||
">", /*32*/
|
||||
">=", /*33*/
|
||||
"<", /*34*/
|
||||
"<=", /*35*/
|
||||
"int->long", /*36*/
|
||||
"long->int", /*37*/
|
||||
"btst", /*38*/
|
||||
"load", /*39*/
|
||||
"long*", /*40*/
|
||||
"long/", /*41*/
|
||||
"long%", /*42*/
|
||||
"long*=", /*43*/
|
||||
"long/=", /*44*/
|
||||
"long%=", /*45*/
|
||||
"=addr", /*46*/
|
||||
"=not", /*47*/
|
||||
"=neg", /*48*/
|
||||
"docast", /*49*/
|
||||
"st=", /*50*/
|
||||
"long->float", /*51*/
|
||||
"float->long", /*52*/
|
||||
"int->float", /*53*/
|
||||
"float->int", /*54*/
|
||||
"tochar", /*55*/
|
||||
invalid, /*56*/
|
||||
invalid, /*57*/
|
||||
invalid, /*58*/
|
||||
invalid, /*59*/
|
||||
"U&", /*60*/
|
||||
"U*", /*61*/
|
||||
"&&", /*62*/
|
||||
"||", /*63*/
|
||||
"?", /*64*/
|
||||
":", /*65*/
|
||||
",", /*66*/
|
||||
"cint", /*67*/
|
||||
"clong", /*68*/
|
||||
"symbol", /*69*/
|
||||
"++a", /*70*/
|
||||
"a--", /*71*/
|
||||
"call", /*72*/
|
||||
"call()", /*73*/
|
||||
"bitfield", /*74*/
|
||||
"if", /*75*/
|
||||
"init", /*76*/
|
||||
"loadR0", /*77*/
|
||||
"divlong", /*78*/
|
||||
};
|
||||
|
||||
char *types[] {
|
||||
invalid, /*0=TYPELESS*/
|
||||
"char", /*1=CHAR*/
|
||||
invalid, /*2=SHORT*/
|
||||
"int", /*3=INT*/
|
||||
"long", /*4=LONG*/
|
||||
invalid, /*5=UCHAR*/
|
||||
invalid, /*6=USHORT*/
|
||||
"uint", /*7=UINT*/
|
||||
invalid, /*8=ULONG*/
|
||||
"float", /*9=FLOAT*/
|
||||
invalid, /*10=DOUBLE*/
|
||||
"struct", /*11=STRUCT*/
|
||||
invalid, /*12=undefined*/
|
||||
invalid, /*13=undefined*/
|
||||
invalid, /*14=undefined*/
|
||||
invalid, /*15=undefined*/
|
||||
};
|
||||
|
||||
char *suvals[] {
|
||||
"zero",
|
||||
"one",
|
||||
"quick",
|
||||
"small",
|
||||
"constant",
|
||||
"Areg",
|
||||
"Dreg",
|
||||
"addressable",
|
||||
"loadable",
|
||||
"easy",
|
||||
"hard",
|
||||
"veryhard",
|
||||
};
|
||||
|
||||
int level;
|
||||
|
||||
putexpr(name,tp)
|
||||
char *name;
|
||||
struct tnode *tp;
|
||||
{
|
||||
printf("%s\n",name);
|
||||
putsexpr(tp);
|
||||
}
|
||||
|
||||
putsexpr(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
register struct tnode *ltp;
|
||||
|
||||
level++;
|
||||
ltp = tp->t_left;
|
||||
outlevel();
|
||||
printf("%s ",opname[tp->t_op]);
|
||||
if( tp->t_op == BFIELD || tp->t_op == IFGOTO ) {
|
||||
if( tp->t_op == BFIELD )
|
||||
printf("off=%d len=%d\n",(tp->t_su>>8)&0377,tp->t_su&0377);
|
||||
else
|
||||
printf("%s goto L%d\n",tp->t_type?"TRUE":"FALSE",tp->t_su);
|
||||
putsexpr(tp->t_left);
|
||||
level--;
|
||||
return;
|
||||
}
|
||||
puttsu(tp);
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case DCLONG:
|
||||
case CLONG:
|
||||
case CFLOAT: /*[vlh] 3.4 */
|
||||
printf(" %x.%x\n",tp->t_lvalue.hiword,tp->t_lvalue.loword);
|
||||
break;
|
||||
|
||||
|
||||
case CINT:
|
||||
printf(" %d\n",tp->t_value);
|
||||
break;
|
||||
|
||||
case AUTODEC:
|
||||
case AUTOINC:
|
||||
printf(" R%d\n",tp->t_reg);
|
||||
break;
|
||||
|
||||
case SYMBOL:
|
||||
switch( tp->t_sc ) {
|
||||
|
||||
case REGISTER:
|
||||
printf(" R%d",tp->t_reg);
|
||||
break;
|
||||
|
||||
case CINDR:
|
||||
printf(" %d\n",tp->t_offset);
|
||||
break;
|
||||
|
||||
case CLINDR:
|
||||
case CFINDR: /* [vlh] 3.4 */
|
||||
printf(" %x.%x\n",tp->t_offset,tp->t_ssp);
|
||||
break;
|
||||
|
||||
case REGOFF:
|
||||
printf(" %d(R%d)",tp->t_offset,tp->t_reg);
|
||||
break;
|
||||
|
||||
case EXTERNAL:
|
||||
case EXTOFF:
|
||||
printf(" %s+%d",tp->t_symbol,tp->t_offset);
|
||||
if( tp->t_sc == EXTOFF )
|
||||
printf("(R%d)",tp->t_reg);
|
||||
break;
|
||||
|
||||
case STATIC:
|
||||
case STATOFF:
|
||||
printf(" L%d+%d",tp->t_label,tp->t_offset);
|
||||
if( tp->t_sc == STATOFF )
|
||||
printf("(R%d)",tp->t_reg);
|
||||
break;
|
||||
|
||||
case INDEXED:
|
||||
printf(" %d(R%d,R%d)",tp->t_offset,tp->t_reg,tp->t_xreg);
|
||||
break;
|
||||
}
|
||||
putchar('\n');
|
||||
break;
|
||||
|
||||
case IFGOTO:
|
||||
putsexpr(tp->t_left);
|
||||
break;
|
||||
|
||||
default:
|
||||
putchar('\n');
|
||||
putsexpr(tp->t_left);
|
||||
if( binop(tp->t_op) )
|
||||
putsexpr(tp->t_right);
|
||||
break;
|
||||
}
|
||||
level--;
|
||||
}
|
||||
|
||||
outlevel()
|
||||
{
|
||||
register int i;
|
||||
|
||||
for( i = 0; i < level; i++ )
|
||||
putchar('\t');
|
||||
}
|
||||
|
||||
puttsu(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
register int i;
|
||||
|
||||
if( suptype(tp->t_type) )
|
||||
putchar('*');
|
||||
printf("%s ",types[btype(tp->t_type)]);
|
||||
if( tp->t_su != 0 || (tp->t_op == CINT && tp->t_value == 0) ) {
|
||||
i = tp->t_su >> 8;
|
||||
if( i > 15 || i < 0 )
|
||||
printf("INVALID");
|
||||
else
|
||||
printf("%s",suvals[tp->t_su>>8]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,517 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/* Code Skeleton expansion and matching */
|
||||
|
||||
#include "cgen.h"
|
||||
#include "cskel.h"
|
||||
#define SK_TYPE(x) (x&017)
|
||||
|
||||
/* expand - code skeleton expansion*/
|
||||
/* Handles the expansion of code skeleton macros.*/
|
||||
expand(tp,cookie,freg,skp) /* returns register result is in*/
|
||||
struct tnode *tp; /* pointer to expression tree*/
|
||||
int cookie; /* goal of expression tree*/
|
||||
int freg; /* register to leave results in*/
|
||||
struct skeleton *skp; /* pointer to code skeleton*/
|
||||
{
|
||||
register int op, nreg, reg;
|
||||
register int c;
|
||||
register int extf, i2f;
|
||||
register struct tnode *ltp, *rtp;
|
||||
register char *p;
|
||||
register int i, inaddreg, sreg, flag, subtrees, scookie;
|
||||
register char *macro;
|
||||
|
||||
#ifndef NODEBUG
|
||||
if( eflag )
|
||||
printf("expand op=%d left=%x right=%x skp=%o\n",tp->t_op,
|
||||
skp->sk_left,skp->sk_right,skp);
|
||||
#endif
|
||||
if( ((op=tp->t_op) >= MULT && op <= XOR) || tp->t_type == CHAR )
|
||||
freg = dreg(freg);
|
||||
macro = skp->sk_def;
|
||||
extf = 0;
|
||||
i2f = 0;
|
||||
rtp = ltp = tp->t_left;
|
||||
subtrees = 1;
|
||||
if( binop(op) ) {
|
||||
subtrees++;
|
||||
rtp = tp->t_right;
|
||||
if( (longorptr(tp->t_type)) && (op == DIV || op == MOD ||
|
||||
(op != MULT && (isdreg(freg)) &&
|
||||
!(longorptr(ltp->t_type)) && !(longorptr(rtp->t_type)))) )
|
||||
extf++;
|
||||
switch( op ) {
|
||||
|
||||
case RSH:
|
||||
case LSH:
|
||||
case EQLSH:
|
||||
case EQRSH:
|
||||
if( unsign(ltp->t_type) )
|
||||
i2f++;
|
||||
break;
|
||||
|
||||
case MULT:
|
||||
case EQMULT:
|
||||
case DIV:
|
||||
case MOD:
|
||||
case EQDIV:
|
||||
case EQMOD:
|
||||
if( unsign(ltp->t_type) || unsign(rtp->t_type) )
|
||||
i2f++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
nreg = freg + 1;
|
||||
while( c = *macro++ ) {
|
||||
c =& 0xff;
|
||||
switch( c ) {
|
||||
|
||||
default:
|
||||
putchar(c);
|
||||
break;
|
||||
|
||||
case POP:
|
||||
stacksize--;
|
||||
printf("(sp)+");
|
||||
break;
|
||||
|
||||
case POP4:
|
||||
stacksize--;
|
||||
popstack(4);
|
||||
break;
|
||||
|
||||
case POP8:
|
||||
stacksize =- 2;
|
||||
popstack(8);
|
||||
break;
|
||||
|
||||
case PSH:
|
||||
if( cookie == FORSP ) /*don't affect sp*/
|
||||
printf("(sp)");
|
||||
else
|
||||
printf("-(sp)");
|
||||
stacksize++;
|
||||
break;
|
||||
|
||||
case MOV:
|
||||
case MOVL:
|
||||
case JSR:
|
||||
case CLR:
|
||||
case CLRL:
|
||||
case EXTW:
|
||||
case EXTL:
|
||||
case LEA:
|
||||
case STK:
|
||||
printf("%s",strtab[c-128]);
|
||||
break;
|
||||
|
||||
case OPCALL:
|
||||
if( isfloat(tp->t_type) || isfloat(ltp->t_type) ) {
|
||||
switch( op ) {
|
||||
|
||||
case ADD:
|
||||
case EQADD:
|
||||
printf("_fpadd");
|
||||
break;
|
||||
|
||||
case SUB:
|
||||
case EQSUB:
|
||||
printf("_fpsub");
|
||||
break;
|
||||
|
||||
case MULT:
|
||||
case EQMULT:
|
||||
printf("_fpmult");
|
||||
break;
|
||||
|
||||
case DIV:
|
||||
case EQDIV:
|
||||
printf("_fpdiv");
|
||||
break;
|
||||
|
||||
case UMINUS:
|
||||
case EQNEG:
|
||||
printf("_fpneg");
|
||||
break;
|
||||
|
||||
case FLOAT2L:
|
||||
case FLOAT2I:
|
||||
printf("_fpftol");
|
||||
break;
|
||||
|
||||
case LONG2F:
|
||||
case INT2F:
|
||||
printf("_fpltof");
|
||||
break;
|
||||
|
||||
case EQUALS:
|
||||
case NEQUALS:
|
||||
case GREAT:
|
||||
case GREATEQ:
|
||||
case LESS:
|
||||
case LESSEQ:
|
||||
printf("_fpcmp");
|
||||
break;
|
||||
|
||||
default:
|
||||
error("invalid floating op %d\n",op);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch( op ) {
|
||||
|
||||
case MULT:
|
||||
case LMULT:
|
||||
printf("lmul");
|
||||
break;
|
||||
|
||||
case DIV:
|
||||
case LDIV:
|
||||
printf("ldiv");
|
||||
break;
|
||||
|
||||
case MOD:
|
||||
case LMOD:
|
||||
printf("lrem");
|
||||
break;
|
||||
|
||||
default:
|
||||
error("opcall bad op %d",op);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TLEFT:
|
||||
outtype( leafop(op) ? tp->t_type : ltp->t_type );
|
||||
break;
|
||||
|
||||
case TLEFTL:
|
||||
outatype( leafop(op) ? tp->t_type : ltp->t_type );
|
||||
break;
|
||||
|
||||
case TEITHER:
|
||||
if( longorptr(rtp->t_type) || longorptr(ltp->t_type) )
|
||||
outtype(LONG);
|
||||
break;
|
||||
|
||||
case TRIGHT:
|
||||
outtype(rtp->t_type);
|
||||
break;
|
||||
|
||||
case OP:
|
||||
case AOP:
|
||||
if( c == AOP || i2f )
|
||||
i = optab[op][1];
|
||||
else
|
||||
i = optab[op][0];
|
||||
printf(mnemonics[i]);
|
||||
break;
|
||||
|
||||
case LADDR:
|
||||
case RADDR:
|
||||
p = (c==RADDR?rtp:ltp);
|
||||
outaexpr(p,IMMED);
|
||||
break;
|
||||
|
||||
case CR:
|
||||
outcreg(freg);
|
||||
break;
|
||||
|
||||
case NR:
|
||||
outcreg(nreg);
|
||||
break;
|
||||
|
||||
case CAR:
|
||||
outcreg(areg(freg));
|
||||
break;
|
||||
|
||||
case NAR:
|
||||
outcreg(areg(nreg));
|
||||
break;
|
||||
|
||||
case EXL:
|
||||
outextend(ltp,LONG,freg);
|
||||
break;
|
||||
|
||||
case EXRL:
|
||||
case EXRLN:
|
||||
outextend(rtp,ltp->t_type,c==EXRL?freg:nreg);
|
||||
break;
|
||||
|
||||
case EXLR:
|
||||
case EXLRN:
|
||||
outextend(ltp,rtp->t_type,c==EXLR?freg:nreg);
|
||||
break;
|
||||
|
||||
case LEFT:
|
||||
case RIGHT:
|
||||
subtrees--;
|
||||
case TREE:
|
||||
p = (c==LEFT?ltp:c==RIGHT?rtp:tp);
|
||||
flag = *macro++;
|
||||
scookie = FORREG;
|
||||
if( flag & S_STACK ) {
|
||||
if( cookie == FORSP )
|
||||
scookie = FORSP;
|
||||
else
|
||||
scookie = FORSTACK;
|
||||
}
|
||||
else if( flag & S_FORCC )
|
||||
scookie = FORCC;
|
||||
if( flag & S_NEXT )
|
||||
reg = nreg;
|
||||
else
|
||||
reg = freg;
|
||||
if( flag & S_INDR ) {
|
||||
if( p->t_op != INDR )
|
||||
error("code skeleton error: %d\n",op);
|
||||
p = p->t_left; /*skip INDR*/
|
||||
if( coffset(p) ) {
|
||||
p = p->t_left;
|
||||
if( longorptr(p->t_type) == 0 && (flag&S_STACK) != 0 )
|
||||
p = tnalloc(INT2L,LONG,0,0,p);
|
||||
}
|
||||
reg = areg(reg);
|
||||
}
|
||||
sreg = codegen(p,scookie,reg); /*code for subtree*/
|
||||
if( scookie == FORREG ) {
|
||||
if( flag & S_INDR ) {
|
||||
if( isdreg(sreg) )
|
||||
outmovr(sreg,areg(reg),p);
|
||||
}
|
||||
else if( flag & S_NEXT )
|
||||
nreg = sreg;
|
||||
else if( sreg != reg ) {
|
||||
/*
|
||||
* result was not in expected register, if remaining sub-tree can be
|
||||
* compiled using the remaining registers, update current and next
|
||||
* registers, saving us the trouble of moving the register.
|
||||
*/
|
||||
if( c == TREE || ((isdreg(sreg)) && subtrees > 0 &&
|
||||
((c == LEFT &&
|
||||
sucomp(rtp,sreg,0) <= skp->sk_right &&
|
||||
sucomp(rtp,sreg,1) <= SU_ANY) ||
|
||||
( c == RIGHT &&
|
||||
sucomp(ltp,sreg,0) <= skp->sk_left &&
|
||||
sucomp(ltp,sreg,1) <= SU_ANY))) ) {
|
||||
freg = dreg(sreg);
|
||||
nreg = freg + 1;
|
||||
}
|
||||
else
|
||||
outmovr(sreg,dreg(freg),p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LOFFSET:
|
||||
case ROFFSET:
|
||||
p = (c==LOFFSET) ? ltp->t_left : rtp->t_left;
|
||||
if((p=coffset(p)) != 0 && (p->t_op != CINT || p->t_value != 0))
|
||||
outaexpr(p,NOTIMMED);
|
||||
break;
|
||||
|
||||
case MODSWAP:
|
||||
switch( op ) {
|
||||
|
||||
case MOD:
|
||||
case EQMOD:
|
||||
case LMOD:
|
||||
case LEQMOD:
|
||||
outswap(freg);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
if( extf && cookie == FORREG && (isdreg(freg)) ) {
|
||||
if( unsign(ltp->t_type) || unsign(rtp->t_type) )
|
||||
outuext(freg);
|
||||
else
|
||||
outext(freg);
|
||||
}
|
||||
#ifndef NODEBUG
|
||||
if( eflag )
|
||||
printf("ending expand skp=%o\n",skp);
|
||||
#endif
|
||||
return(freg);
|
||||
}
|
||||
|
||||
/*
|
||||
* match - try to match expression tree with code skeleton
|
||||
* Given the expression tree, tries to match the given tree with
|
||||
* the appropriate code skeleton. The code skeleton list is
|
||||
* gotten from the root operator and the cookie value. The code
|
||||
* skeleton list is then searched, checking the Sethy-Ullman numbers
|
||||
* of the sub-trees against the Sethy-Ullman numbers in the code
|
||||
* skeleton list. If the Sethy-Ullman numbers are OK, then the
|
||||
* left and right sub-trees are checked for compatability, e.g.
|
||||
* integer pointers, etc. If a match is found, the code skeleton
|
||||
* list pointer is returned.
|
||||
*/
|
||||
char *match(tp,cookie,reg) /* returns ptr to code skeleton*/
|
||||
/* or 0 if no skeleton*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
int cookie; /* goal for code expansion*/
|
||||
int reg; /* register to use*/
|
||||
{
|
||||
register struct skeleton *skp;
|
||||
register int op, bop, opndx;
|
||||
int i;
|
||||
register struct tnode *ltp, *rtp;
|
||||
|
||||
#ifndef NODEBUG
|
||||
if( mflag )
|
||||
printf("match op=%d cookie=%d reg=%d\n",tp->t_op,cookie,reg);
|
||||
#endif
|
||||
if( (op=tp->t_op) >= LCGENOP )
|
||||
return(0);
|
||||
if( leafop(op) )
|
||||
ltp = tp;
|
||||
else
|
||||
ltp = tp->t_left;
|
||||
if( (bop=binop(op)) ) {
|
||||
rtp = tp->t_right;
|
||||
if( convop(ltp->t_op) ) {
|
||||
if( op != LSH && notconvop(rtp->t_op) ) {
|
||||
if( !(unsign(ltp->t_left->t_type)) || op == ASSIGN ) {
|
||||
tp->t_left = ltp->t_left;
|
||||
if( (skp=match(tp,cookie,reg)) != 0 )
|
||||
return(skp);
|
||||
tp->t_left = ltp;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( convop(rtp->t_op) ) {
|
||||
if( !(unsign(rtp->t_left->t_type)) || op == ASSIGN ) {
|
||||
tp->t_right = rtp->t_left;
|
||||
if( (skp=match(tp,cookie,reg)) != 0 )
|
||||
return(skp);
|
||||
tp->t_right = rtp;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch( cookie ) {
|
||||
|
||||
case FORCC:
|
||||
i = 3;
|
||||
break;
|
||||
|
||||
case FOREFF:
|
||||
i = 2;
|
||||
break;
|
||||
|
||||
case FORSTACK:
|
||||
case FORSP:
|
||||
i = 4;
|
||||
break;
|
||||
|
||||
case FORREG:
|
||||
i = 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
error("match cookie=%d\n",cookie);
|
||||
return(0);
|
||||
}
|
||||
#ifndef NODEBUG
|
||||
if( mflag )
|
||||
printf("match op=%d i=%d ",op,i);
|
||||
#endif
|
||||
if( !(i=optab[op][i]) )
|
||||
return(0);
|
||||
skp = codeskels[i];
|
||||
#ifndef NODEBUG
|
||||
if( mflag )
|
||||
printf("codeskels[%d]=%o\n",i,skp);
|
||||
#endif
|
||||
#ifndef NODEBUG
|
||||
if(mflag) {
|
||||
printf("match LEFT ");
|
||||
puttsu(ltp);
|
||||
if(bop) {
|
||||
printf(" RIGHT ");
|
||||
puttsu(rtp);
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
#endif
|
||||
for( ; skp->sk_left != 0; skp++ ) {
|
||||
#ifndef NODEBUG
|
||||
if( mflag > 1 )
|
||||
printf("sk_left=%x sk_right=%x\n",skp->sk_left,skp->sk_right);
|
||||
#endif
|
||||
if( !(skelmatch(ltp,skp->sk_left)) )
|
||||
continue;
|
||||
if( bop && !(skelmatch(rtp,skp->sk_right)) )
|
||||
continue;
|
||||
#ifndef NODEBUG
|
||||
if( mflag )
|
||||
printf("match found skp=%o left=%x right=%x\n",skp,
|
||||
skp->sk_left,skp->sk_right);
|
||||
#endif
|
||||
return(skp);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* skelmatch - sub-tree type matching for match*/
|
||||
/* This checks a subtree for type compatability in match.*/
|
||||
skelmatch(tp,skinfo) /* returns 1 if matched, else 0*/
|
||||
struct tnode *tp; /* pointer to expression tree*/
|
||||
int skinfo;
|
||||
{
|
||||
register int type, unsignf, const, stype;
|
||||
|
||||
if( tp->t_su > skinfo || ((skinfo&T_INDR) && tp->t_op != INDR) )
|
||||
return(0);
|
||||
stype = SK_TYPE(skinfo);
|
||||
type = tp->t_type;
|
||||
if( function(type) )
|
||||
type = btype(type);
|
||||
if( unsignf = unsign(type) )
|
||||
type = basetype(type);
|
||||
const = 0;
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case CFLOAT: /* [vlh] 3.4 */
|
||||
case CLONG:
|
||||
if( tp->t_su > SU_CONST )
|
||||
break;
|
||||
case CINT:
|
||||
const++;
|
||||
break;
|
||||
}
|
||||
switch( stype ) {
|
||||
|
||||
case T_CHAR:
|
||||
return( type == CHAR );
|
||||
|
||||
case T_ANY: /*either int or char*/
|
||||
if( type == CHAR )
|
||||
return(1);
|
||||
case T_INT:
|
||||
return( type == INT || const );
|
||||
|
||||
case T_UNSN:
|
||||
return( unsignf );
|
||||
|
||||
case T_LONG:
|
||||
return( longorptr(type) );
|
||||
|
||||
case T_FLOAT:
|
||||
return( isfloat(type) );
|
||||
|
||||
default:
|
||||
error("skelmatch type: %x",stype);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
#include "cskel.h"
|
||||
|
||||
/* sucomp - Sethy-Ullman expression complexity measure computation*/
|
||||
/* This is a heuristic computation of the Sethy-Ullman numbers*/
|
||||
/* for expressions. This gives an approximation of the complexity*/
|
||||
/* of the expression. The code generation scheme works best if*/
|
||||
/* the most complex expressions are done first.*/
|
||||
sucomp(tp,nregs,flag) /* returns - none*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
int nregs; /* number of registers left*/
|
||||
int flag; /* 1=>set values in tree, 0=>return*/
|
||||
{
|
||||
register int su, sur, op, i;
|
||||
register struct tnode *ltp, *rtp;
|
||||
|
||||
nregs = dreg(nregs);
|
||||
if( binop(op=tp->t_op) ) {
|
||||
ltp = tp->t_left;
|
||||
rtp = tp->t_right;
|
||||
}
|
||||
else if( unaryop(op) )
|
||||
ltp = tp->t_left;
|
||||
switch( op ) {
|
||||
|
||||
case CLONG:
|
||||
if( tp->t_lvalue >= 0x8000L || tp->t_lvalue <= 0xffff8000L ) {
|
||||
su = SU_ADDR;
|
||||
break;
|
||||
}
|
||||
i = tp->t_lvalue;
|
||||
case CINT:
|
||||
if( op == CINT )
|
||||
i = tp->t_value;
|
||||
if( i == 0 )
|
||||
su = SU_ZERO;
|
||||
else if( i == 1 )
|
||||
su = SU_ONE;
|
||||
else if( i >= 1 && i <= QUICKVAL )
|
||||
su = SU_SMALL;
|
||||
else if( i >= -128 && i <= 127 )
|
||||
su = SU_QUICK;
|
||||
else
|
||||
su = SU_CONST;
|
||||
break;
|
||||
|
||||
case COMMA:
|
||||
su = max(sucomp(rtp,nregs,flag),sucomp(ltp,nregs,flag));
|
||||
su = max(su,SU_EASY);
|
||||
break;
|
||||
|
||||
case ADDR:
|
||||
su = sucomp(ltp,nregs,flag);
|
||||
break;
|
||||
|
||||
case CFLOAT:
|
||||
case DCLONG:
|
||||
case AUTOINC:
|
||||
case AUTODEC:
|
||||
su = SU_ADDR;
|
||||
break;
|
||||
|
||||
case SYMBOL:
|
||||
if( tp->t_sc != REGISTER )
|
||||
su = SU_ADDR;
|
||||
else if( isdreg(tp->t_reg) )
|
||||
su = SU_REG;
|
||||
else
|
||||
su = SU_AREG;
|
||||
break;
|
||||
|
||||
case LDIV:
|
||||
case LMOD:
|
||||
case LMULT:
|
||||
case CALL:
|
||||
sucomp(rtp,nregs,flag);
|
||||
case NACALL:
|
||||
sucomp(ltp,nregs,flag);
|
||||
su = SU_VHARD; /*very hard*/
|
||||
break;
|
||||
|
||||
default:
|
||||
su = sucomp(ltp,nregs,flag);
|
||||
if( binop(op) ) {
|
||||
if( su <= SU_ADDR )
|
||||
su = max(su,sucomp(rtp,nregs,flag));
|
||||
else {
|
||||
sur = sucomp(rtp,nregs+1,flag);
|
||||
if( sur > SU_ADDR && nregs > HICREG )
|
||||
su = max(su,SU_HARD);
|
||||
}
|
||||
su = max(SU_EASY,su);
|
||||
}
|
||||
else if( su <= SU_XREG )
|
||||
su = max(SU_EASY,su);
|
||||
if( isfloat(tp->t_type) )
|
||||
su = SU_VHARD;
|
||||
break;
|
||||
}
|
||||
if( flag )
|
||||
tp->t_su = su;
|
||||
return(su);
|
||||
}
|
||||
118
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/tabl.c
Normal file
118
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/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 - int required on left*/
|
||||
/*004000-- OPRWORD - int required on right*/
|
||||
/*010000-- OPCOM commutative*/
|
||||
/*020000-- OPRAS - right associative*/
|
||||
/*040000-- OPTERM - termination node*/
|
||||
/*100000 - OPCONVS - conversion operator*/
|
||||
int opinfo[] {
|
||||
TRMPRI, /*EOF*/
|
||||
ADDPRI|OPCOM|OPBIN, /*ADD - expr + expr*/
|
||||
ADDPRI|OPBIN, /*SUB - expr - expr*/
|
||||
MULPRI|OPCOM|OPBIN, /*MULT - expr * expr*/
|
||||
MULPRI|OPBIN, /*DIV - expr / expr*/
|
||||
MULPRI|OPBIN, /*MOD - expr % expr*/
|
||||
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*RSH - expr >> expr*/
|
||||
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*LSH - expr << expr*/
|
||||
ANDPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*AND - expr & expr*/
|
||||
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*OR - expr | expr*/
|
||||
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*XOR - expr ^ expr*/
|
||||
UNOPRI|OPRAS|OPLWORD, /*NOT - ! expr*/
|
||||
UNOPRI|OPRAS, /*UMINUS - - expr*/
|
||||
UNOPRI|OPRAS|OPLWORD, /*COMPL - ~ expr*/
|
||||
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREDEC - --lvalue*/
|
||||
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREINC - ++lvalue*/
|
||||
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTDEC - lvalue--*/
|
||||
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTINC - lvalue++*/
|
||||
ASGPRI|ASGOP, /*ASSIGN - lvalue = expr*/
|
||||
ASGPRI|ASGOP, /*EQADD - lvalue += expr*/
|
||||
ASGPRI|ASGOP, /*EQSUB - lvalue -= expr*/
|
||||
ASGPRI|ASGOP, /*EQMULT - lvalue *= expr*/
|
||||
ASGPRI|ASGOP, /*EQDIV - lvalue /= expr*/
|
||||
ASGPRI|ASGOP, /*EQMOD - lvalue %= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQRSH - lvalue >>= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQLSH - lvalue <<= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQAND - lvalue &= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQOR - lvalue |= expr*/
|
||||
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQXOR - lvalue ^= expr*/
|
||||
TRMPRI, /*FJSR - generate function jsr*/
|
||||
EQLPRI|OPREL|OPBIN, /*EQUALS - expr == expr*/
|
||||
EQLPRI|OPREL|OPBIN, /*NEQUALS - expr != expr*/
|
||||
RELPRI|OPREL|OPBIN, /*GREAT - expr > expr*/
|
||||
RELPRI|OPREL|OPBIN, /*GREATEQ - expr >= expr*/
|
||||
RELPRI|OPREL|OPBIN, /*LESS - expr < expr*/
|
||||
RELPRI|OPREL|OPBIN, /*LESSEQ - expr <= expr*/
|
||||
TRMPRI|OPCONVS, /*INT2L*/
|
||||
TRMPRI|OPCONVS, /*LONG2I*/
|
||||
TRMPRI|OPBIN, /*BTST*/
|
||||
TRMPRI, /*LOAD*/
|
||||
TRMPRI|OPBIN, /*LMULT*/
|
||||
TRMPRI|OPBIN, /*LDIV*/
|
||||
TRMPRI|OPBIN, /*LMOD*/
|
||||
TRMPRI|OPBIN, /*LEQMULT*/
|
||||
TRMPRI|OPBIN, /*LEQDIV*/
|
||||
TRMPRI|OPBIN, /*LEQMOD*/
|
||||
TRMPRI|ASGOP, /*EQADDR*/
|
||||
TRMPRI, /*EQNOT*/
|
||||
TRMPRI, /*EQNEG*/
|
||||
TRMPRI|OPBIN, /*DOCAST*/
|
||||
ASGPRI|ASGOP, /*STASSIGN [vlh]*/
|
||||
TRMPRI|OPCONVS, /*LONG2F [vlh] 3.4*/
|
||||
TRMPRI|OPCONVS, /*FLOAT2L [vlh] 3.4*/
|
||||
TRMPRI|OPCONVS, /*INT2F [vlh] 3.4*/
|
||||
TRMPRI|OPCONVS, /*FLOAT2I [vlh] 3.4*/
|
||||
UNOPRI|OPRAS, /*TOCHAR [vlh] 4.0*/
|
||||
TRMPRI, /*unused - 56*/
|
||||
TRMPRI, /*unused - 57*/
|
||||
TRMPRI, /*unused - 58*/
|
||||
TRMPRI, /*unused - 59*/
|
||||
UNOPRI|OPRAS|OPLVAL, /*ADDR - & expr*/
|
||||
UNOPRI|OPRAS|OPLWORD, /*INDR - * expr*/
|
||||
LNDPRI|OPBIN, /*LAND - expr && expr*/
|
||||
LORPRI|OPBIN, /*LOR - expr || expr*/
|
||||
QMKPRI|OPRAS|OPBIN, /*QMARK - expr ? expr : expr*/
|
||||
QMKPRI|OPRAS|OPBIN, /*COLON*/
|
||||
COMPRI|OPBIN, /*COMMA*/
|
||||
TRMPRI|OPTERM, /*CINT*/
|
||||
TRMPRI|OPTERM, /*CLONG*/
|
||||
TRMPRI|OPTERM, /*SYMBOL*/
|
||||
TRMPRI|OPTERM, /*AUTOINC*/
|
||||
TRMPRI|OPTERM, /*AUTODEC*/
|
||||
LPNPRI|OPBIN, /*CALL - call with arguments*/
|
||||
LPNPRI, /*NACALL - no argument call*/
|
||||
TRMPRI, /*BFIELD - field selection*/
|
||||
TRMPRI, /*CONDBR*/
|
||||
TRMPRI, /*INIT*/
|
||||
TRMPRI, /*LOADREG*/
|
||||
TRMPRI|OPTERM, /*DCLONG - divide const long*/
|
||||
TRMPRI|OPTERM, /*CFLOAT [vlh] 3.4*/
|
||||
UNOPRI|OPRAS|OPASSIGN|OPBIN, /*CAST*/
|
||||
TRMPRI, /*SEMI*/
|
||||
TRMPRI, /*LCURBR - {*/
|
||||
TRMPRI, /*RCURBR - }*/
|
||||
LPNPRI, /*LBRACK - [*/
|
||||
RPNPRI, /*RBRACK - ]*/
|
||||
LPNPRI, /*LPAREN - )*/
|
||||
RPNPRI, /*RPAREN - )*/
|
||||
TRMPRI|OPTERM, /*STRING*/
|
||||
TRMPRI, /*RESWORD*/
|
||||
LPNPRI|OPBIN, /*APTR - expr -> symbol*/
|
||||
LPNPRI|OPBIN, /*PERIOD - expr . symbol*/
|
||||
UNOPRI|OPRAS, /*SIZEOF - sizeof expr*/
|
||||
LPNPRI|OPBIN, /*MPARENS - matching parens ()*/
|
||||
};
|
||||
357
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/util.c
Normal file
357
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fcgen2/util.c
Normal file
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "cgen.h"
|
||||
#include "cskel.h"
|
||||
|
||||
/* xnalloc - allocate address-indexed node*/
|
||||
char *xnalloc(type,ar,off,xr,xt) /* returns ptr to node alloced*/
|
||||
int type; /* data type*/
|
||||
int ar; /* address register*/
|
||||
int off; /* 8-bit offset*/
|
||||
int xr; /* index register*/
|
||||
int xt; /* index register type*/
|
||||
{
|
||||
register struct indexnode *xp;
|
||||
|
||||
xp = talloc(sizeof(*xp));
|
||||
xp->t_op = SYMBOL;
|
||||
xp->t_type = type;
|
||||
xp->t_sc = INDEXED;
|
||||
xp->t_reg = ar;
|
||||
xp->t_su = SU_ADDR;
|
||||
xp->t_offset = off;
|
||||
xp->t_xreg = xr;
|
||||
xp->t_xtype = xt;
|
||||
return(xp);
|
||||
}
|
||||
|
||||
/* tcopy - expression tree copy*/
|
||||
char *tcopy(tp) /* returns ptr to copied tree*/
|
||||
struct tnode *tp;
|
||||
{
|
||||
register char *p;
|
||||
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case SYMBOL:
|
||||
if( tp->t_sc == EXTERNAL || tp->t_sc == EXTOFF )
|
||||
p = cenalloc(tp->t_type,tp->t_sc,tp->t_symbol);
|
||||
else {
|
||||
p = snalloc(tp->t_type,tp->t_sc,tp->t_offset,0,0);
|
||||
p->t_label = tp->t_label;
|
||||
}
|
||||
p->t_offset = tp->t_offset;
|
||||
p->t_reg = tp->t_reg;
|
||||
return(p);
|
||||
|
||||
case CINT:
|
||||
return(cnalloc(tp->t_type,tp->t_value));
|
||||
|
||||
case CLONG:
|
||||
return(lcnalloc(tp->t_type,tp->t_lvalue));
|
||||
|
||||
case CFLOAT: /*[vlh] 3.4 */
|
||||
return(fpcnalloc(tp->t_type,tp->t_lvalue));
|
||||
|
||||
case DCLONG:
|
||||
p = lcnalloc(tp->t_type,tp->t_lvalue);
|
||||
p->t_op = DCLONG;
|
||||
return(p);
|
||||
|
||||
default:
|
||||
if( binop(tp->t_op) )
|
||||
return(tnalloc(tp->t_op,tp->t_type,0,0,tcopy(tp->t_left),
|
||||
tcopy(tp->t_right)));
|
||||
if( unaryop(tp->t_op) )
|
||||
return(tnalloc(tp->t_op,tp->t_type,0,0,tcopy(tp->t_left),
|
||||
null));
|
||||
error("tcopy op=%d",tp->t_op);
|
||||
return(tp);
|
||||
}
|
||||
}
|
||||
|
||||
/* outaexpr - output address expression*/
|
||||
outaexpr(tp,flags) /* returns - none*/
|
||||
struct tnode *tp; /* pointer to tree*/
|
||||
int flags; /* flags (IMMED,LOFFSET,...)*/
|
||||
{
|
||||
register int off, reg, lab;
|
||||
long l;
|
||||
|
||||
if( tp->t_op == ADDR ) {
|
||||
tp = tp->t_left;
|
||||
putchar('#');
|
||||
}
|
||||
off = tp->t_offset;
|
||||
reg = tp->t_reg;
|
||||
lab = tp->t_label;
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case AUTOINC:
|
||||
printf("(R%d)+",reg);
|
||||
break;
|
||||
|
||||
case AUTODEC:
|
||||
printf("-(R%d)",reg);
|
||||
break;
|
||||
|
||||
case CINT:
|
||||
if( flags & IMMED )
|
||||
putchar('#');
|
||||
printf("%d",tp->t_value);
|
||||
break;
|
||||
|
||||
case DCLONG:
|
||||
case CLONG:
|
||||
case CFLOAT: /*[vlh] 3.4 */
|
||||
if( flags & IMMED )
|
||||
putchar('#');
|
||||
outlval(tp->t_lvalue);
|
||||
break;
|
||||
|
||||
case SYMBOL:
|
||||
if( off ) {
|
||||
switch( tp->t_sc ) {
|
||||
|
||||
default:
|
||||
printf("%d+",off);
|
||||
break;
|
||||
|
||||
case REGOFF:
|
||||
printf("%d",off);
|
||||
case CINDR:
|
||||
case CLINDR:
|
||||
case CFINDR: /* [vlh] 3.4 */
|
||||
case INDEXED:
|
||||
break;
|
||||
|
||||
case REGISTER:
|
||||
error("invalid register expression");
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch( tp->t_sc ) {
|
||||
|
||||
case REGISTER:
|
||||
printf("R%d",reg);
|
||||
break;
|
||||
|
||||
case REGOFF:
|
||||
printf("(R%d)",reg);
|
||||
break;
|
||||
|
||||
case EXTERNAL:
|
||||
printf("_%.8s",tp->t_symbol);
|
||||
break;
|
||||
|
||||
case EXTOFF:
|
||||
printf("_%.8s(R%d)",tp->t_symbol,reg);
|
||||
break;
|
||||
|
||||
case STATIC:
|
||||
printf("L%d",lab);
|
||||
break;
|
||||
|
||||
case STATOFF:
|
||||
printf("L%d(R%d)",lab,reg);
|
||||
break;
|
||||
|
||||
case INDEXED:
|
||||
printf("%d(R%d,R%d",off,reg,tp->t_xreg);
|
||||
outatype(tp->t_xtype);
|
||||
putchar(')');
|
||||
break;
|
||||
|
||||
case CINDR:
|
||||
printf("%d",off);
|
||||
break;
|
||||
/*
|
||||
* the following will work on: PDP-11, 68000, IBM-360, VAX, etc.
|
||||
* it will not work on word machines or on machines where either
|
||||
* longs two ints or two shorts.
|
||||
*/
|
||||
case CLINDR:
|
||||
case CFINDR: /* [vlh] 3.4 */
|
||||
l.hiword = tp->t_offset;
|
||||
l.loword = tp->t_ssp;
|
||||
outlval(l);
|
||||
break;
|
||||
|
||||
default:
|
||||
error("invalid storage class %d\n",tp->t_sc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error("invalid operator %d\n",tp->t_op);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* outlval - output long value*/
|
||||
/* This is a big pain because the PDP-11 doesn't do long divides*/
|
||||
/* in hardware.*/
|
||||
outlval(lval)
|
||||
long lval;
|
||||
{
|
||||
char digs[8];
|
||||
register int i, c;
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
digs[i++] = lval & 0xf;
|
||||
lval =>> 4;
|
||||
lval =& 0xfffffff;
|
||||
} while ( lval );
|
||||
putchar('$');
|
||||
while( --i >= 0 ) {
|
||||
c = digs[i];
|
||||
putchar(c>=10?c+('a'-10):c+'0');
|
||||
}
|
||||
}
|
||||
|
||||
/* outtype - output 68000 type (null, .b, .l) depending on data type*/
|
||||
outtype(type)
|
||||
int type;
|
||||
{
|
||||
if( isfloat(type) )
|
||||
printf(".l");
|
||||
else if( longorptr(type) )
|
||||
printf(".l");
|
||||
else if( type == CHAR )
|
||||
printf(".b");
|
||||
}
|
||||
|
||||
/* outatype - output address type (.l or null) depending on data type*/
|
||||
outatype(type)
|
||||
int type;
|
||||
{
|
||||
if( longorptr(type) || isfloat(type) )
|
||||
printf(".l");
|
||||
}
|
||||
|
||||
/* outextend - output register extension to long depending on type*/
|
||||
outextend(tp,type,reg) /* returns - none*/
|
||||
struct tnode *tp; /* tree to convert from*/
|
||||
int type; /* type to convert to*/
|
||||
int reg; /* register to convert*/
|
||||
{
|
||||
if( (isdreg(reg)) && !(longorptr(tp->t_type)) && (longorptr(type)) ) {
|
||||
if( unsign(tp->t_type) )
|
||||
outuext(reg);
|
||||
else
|
||||
outext(reg);
|
||||
}
|
||||
}
|
||||
|
||||
/* outrr - output register to register instruction*/
|
||||
outrr(ins,r1,r2,tp)
|
||||
char *ins;
|
||||
int r1;
|
||||
int r2;
|
||||
struct tnode *tp;
|
||||
{
|
||||
printf("%s",ins);
|
||||
if( isareg(r1) || isareg(r2) )
|
||||
outatype(tp->t_type);
|
||||
else
|
||||
outtype(tp->t_type);
|
||||
printf(" R%d,R%d\n",r1,r2);
|
||||
}
|
||||
|
||||
/* outmovr - output "move[type] R1,R2" instruction*/
|
||||
outmovr(r1,r2,tp)
|
||||
int r1;
|
||||
int r2;
|
||||
struct tnode *tp;
|
||||
{
|
||||
if( r1 != r2 )
|
||||
outrr("move",r1,r2,tp);
|
||||
}
|
||||
|
||||
/* outcmpm - output "cmpm[type] (R1)+,(R2)+"*/
|
||||
outcmpm(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
printf("cmpm");
|
||||
outtype(tp->t_left->t_type);
|
||||
printf(" (R%d)+,(R%d)+\n",tp->t_left->t_reg,tp->t_right->t_reg);
|
||||
}
|
||||
|
||||
/* outcreg - output reference to compiler temp register*/
|
||||
outcreg(reg)
|
||||
int reg;
|
||||
{
|
||||
if( (dreg(reg)) > HICREG )
|
||||
error("expression too complex");
|
||||
printf("R%d",reg);
|
||||
}
|
||||
|
||||
/* outcmp0 - output a compare with 0, special for address register*/
|
||||
outcmp0(reg,tp)
|
||||
int reg;
|
||||
struct tnode *tp;
|
||||
{
|
||||
if( isareg(reg) ) {
|
||||
printf("cmp");
|
||||
outatype(tp->t_type);
|
||||
printf(" #0,R%d\n",reg);
|
||||
}
|
||||
else {
|
||||
printf("tst");
|
||||
outtype(tp->t_type);
|
||||
printf(" R%d\n",reg);
|
||||
}
|
||||
}
|
||||
|
||||
/* outrpush - output "move[type] R1,[-](sp)"*/
|
||||
outrpush(reg,tp,pflag)
|
||||
int reg;
|
||||
struct tnode *tp;
|
||||
int pflag;
|
||||
{
|
||||
printf("move");
|
||||
outatype(tp->t_type);
|
||||
printf(" R%d,%c(sp)\n",reg,pflag?'-':'\0');
|
||||
}
|
||||
|
||||
outdbra(reg,lab)
|
||||
int reg;
|
||||
int lab;
|
||||
{
|
||||
printf("dbra R%d,L%d\n",reg,lab);
|
||||
}
|
||||
|
||||
/* cenalloc - code generator external node allocation*/
|
||||
/* This may be coalesced into enalloc in parser.*/
|
||||
char *cenalloc(type,sc,sym) /* returns ptr to node alloced*/
|
||||
int type; /* type of symbol*/
|
||||
int sc; /* storage class*/
|
||||
char *sym; /* symbol name*/
|
||||
{
|
||||
register struct extnode *ep;
|
||||
|
||||
ep = talloc(sizeof(*ep));
|
||||
ep->t_op = SYMBOL;
|
||||
ep->t_type = type;
|
||||
ep->t_sc = sc;
|
||||
ep->t_su = 0;
|
||||
ep->t_offset = 0;
|
||||
symcopy(sym,ep->t_symbol);
|
||||
return(ep);
|
||||
}
|
||||
|
||||
/*popstack - clear off the stack after a call if necessary */
|
||||
popstack(nb)
|
||||
{
|
||||
if (nb > 0 && nb <= 8)
|
||||
printf("addq.l #%d,sp\n",nb);
|
||||
else if (nb > 0)
|
||||
printf("adda.l #%d,sp\n",nb);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
char *compiled "@(#) code generator - Fri Mar 18 12:02 1983";
|
||||
@@ -0,0 +1,3 @@
|
||||
c68 -L -e *.c -o c068.68 -l6
|
||||
c68 -L -r -n -e *.c -o c068.st -l6
|
||||
cc -f *.c -o c068.11 -lP -lx
|
||||
1072
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fparser/decl.c
Normal file
1072
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fparser/decl.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
$ set def [steve.cpm68k.c.fparser]
|
||||
$ diff DECL.C [-.parser]DECL.C
|
||||
$ diff EXPR.C [-.parser]EXPR.C
|
||||
$ diff ICODE.C [-.parser]ICODE.C
|
||||
$ diff INTERF.C [-.parser]INTERF.C
|
||||
$ diff LEX.C [-.parser]LEX.C
|
||||
$ diff MAIN.C [-.parser]MAIN.C
|
||||
$ diff STMT.C [-.parser]STMT.C
|
||||
$ diff TABL.C [-.parser]TABL.C
|
||||
$ diff VERSION.C [-.parser]VERSION.C
|
||||
$ diff ICODE.H [-.parser]ICODE.H
|
||||
$ diff PARSER.H [-.parser]PARSER.H
|
||||
1040
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fparser/expr.c
Normal file
1040
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fparser/expr.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
int bol 1;
|
||||
int inittype;
|
||||
int begseq;
|
||||
/* int onepass; */
|
||||
|
||||
/*
|
||||
This interfaces the Parser and the Code Generator, note that these
|
||||
allow you to link together the Parser and the Code Generator.
|
||||
*/
|
||||
|
||||
/* outbdata - set up for byte data*/
|
||||
outbdata() /* returns - none*/
|
||||
{
|
||||
inittype = CHAR;
|
||||
printf("\t.dc.b ");
|
||||
}
|
||||
|
||||
/* outc - output a constant*/
|
||||
outc(type,value) /* returns - none*/
|
||||
int type;
|
||||
int value;
|
||||
{
|
||||
if( type == CHAR )
|
||||
outbdata();
|
||||
else
|
||||
outwdata();
|
||||
printf("%d\n",value);
|
||||
}
|
||||
|
||||
/* outwdata - set up for word data*/
|
||||
outwdata() /* returns - none*/
|
||||
{
|
||||
inittype = INT;
|
||||
printf("\t.dc.w ");
|
||||
}
|
||||
|
||||
/* outdata - set up for data output*/
|
||||
outdata() /* returns - none*/
|
||||
{
|
||||
inittype = INT;
|
||||
printf("\t.data\n");
|
||||
}
|
||||
|
||||
/* outldata - set up for long data output*/
|
||||
outldata() /* returns - none*/
|
||||
{
|
||||
inittype = LONG;
|
||||
printf("\t.data\n");
|
||||
}
|
||||
|
||||
/* outfpdata - set up for floating point data output*/
|
||||
outfpdata() /*[vlh] 3.4 returns - none*/
|
||||
{
|
||||
inittype = FLOAT;
|
||||
printf("\t.data\n");
|
||||
}
|
||||
|
||||
/* outbentry - outputs block/function entry code*/
|
||||
outbentry(nlocs,nds,nas) /* returns - none*/
|
||||
int nlocs; /* local size*/
|
||||
int nds; /* number of D registers*/
|
||||
int nas; /* number of A registers*/
|
||||
{
|
||||
if( !nds && !nas ) /* adjust for 1 arg*/
|
||||
nlocs =+ 4;
|
||||
printf("\tlink R14,#%d\n",-nlocs);
|
||||
if( nds || nas ) {
|
||||
printf("\tmovem.l R%d-R7",7-nds); /*7 for one arg*/
|
||||
if( nas ) {
|
||||
putchar('/');
|
||||
printf("R%d-R13",14-nas);
|
||||
}
|
||||
printf(",-(sp)\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* outbexit - output function exit code*/
|
||||
outbexit(nds,nas) /* returns - none*/
|
||||
int nds; /* number of D registers*/
|
||||
int nas; /* number of A registers*/
|
||||
{
|
||||
if( nds || nas ) {
|
||||
printf("\ttst.l (sp)+\n\tmovem.l (sp)+,"); /*1 arg stuff*/
|
||||
if( nds ) {
|
||||
printf("R%d-R7",8-nds);
|
||||
if( nas )
|
||||
putchar('/');
|
||||
}
|
||||
if( nas )
|
||||
printf("R%d-R13",14-nas);
|
||||
putchar('\n');
|
||||
}
|
||||
printf("\tunlk R14\n\trts\n");
|
||||
}
|
||||
|
||||
/* outlocal - output local symbol for debugger*/
|
||||
outlocal(type,sc,sym,val)
|
||||
int type; /* local name type*/
|
||||
int sc; /* storage type*/
|
||||
char *sym; /* symbol name*/
|
||||
int val;
|
||||
{
|
||||
switch( sc ) {
|
||||
|
||||
case STATIC:
|
||||
if( notfunction(type) )
|
||||
printf("\t~%.8s=L%d\n",sym,val);
|
||||
break;
|
||||
|
||||
case REGISTER:
|
||||
printf("\t~%.8s=R%d\n",sym,val);
|
||||
break;
|
||||
|
||||
case AUTO:
|
||||
printf("\t~%.8s=%d\n",sym,val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* outswitch - output switch table info*/
|
||||
outswitch(ncases,deflab,sp) /* returns - none*/
|
||||
int ncases; /* number of cases in switch*/
|
||||
int deflab; /* default label*/
|
||||
struct swtch *sp; /* switch table pointer*/
|
||||
{
|
||||
register int vdif, val, hval, i, tlab;
|
||||
register struct swtch *s;
|
||||
|
||||
val = sp->sw_value;
|
||||
hval = sp[ncases-1].sw_value;
|
||||
vdif = hval - val;
|
||||
if( ncases <= 4 ) {
|
||||
/*
|
||||
*simple switch, do compares and brances, followed by branch to default
|
||||
*/
|
||||
for( s = sp; --ncases >= 0; s++ ) {
|
||||
if( !s->sw_value )
|
||||
printf("\ttst R0\n");
|
||||
else
|
||||
printf("\tcmp #%d,R0\n",s->sw_value);
|
||||
printf("\tbeq L%d\n",s->sw_label);
|
||||
}
|
||||
outgoto(deflab);
|
||||
}
|
||||
else if( vdif > 0 && vdif <= ncases*3 ) {
|
||||
|
||||
/*jump switch, uses value in R0 to index into table of labels*/
|
||||
|
||||
if( val )
|
||||
printf("\tsub #%d,R0\n",val);
|
||||
tlab = nextlabel++;
|
||||
printf("\tcmp #%d,R0\n\tbhi L%d\n",vdif,deflab); /*check for max*/
|
||||
printf("\tasl #2,R0\n\tmove R0,R8\n\tadd.l #L%d,R8\n",tlab);
|
||||
printf("\tmove.l (R8),R8\n\tjmp (R8)\n");
|
||||
outdata();
|
||||
outlab(tlab);
|
||||
for( s = sp; val <= hval; val++ ) {
|
||||
if( val == s->sw_value ) {
|
||||
outclab(s->sw_label);
|
||||
s++;
|
||||
}
|
||||
else
|
||||
outclab(deflab);
|
||||
}
|
||||
outtext();
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* direct switch, searches down table of values for match, if match
|
||||
* found, branches to corresponding label in label table.
|
||||
*/
|
||||
tlab = nextlabel++;
|
||||
printf("\text.l R0\n\tmove.l #L%d,R8\n\tmove #%d,R1\n",tlab,ncases);
|
||||
i = nextlabel++;
|
||||
outlab(i); /*loop label*/
|
||||
printf("\tcmp.l (R8)+,R0\n\tdbeq R1,L%d\n",i);
|
||||
printf("\tmove.l %d(R8),R8\n\tjmp (R8)\n",ncases*4);
|
||||
outdata();
|
||||
outlab(tlab);
|
||||
for( s = sp, i = ncases; --i >= 0; s++ )
|
||||
outlcon(s->sw_value);
|
||||
outlcon(0); /* mark for default label*/
|
||||
for( s = sp, i = ncases; --i >= 0; s++ )
|
||||
outclab(s->sw_label);
|
||||
outclab(deflab);
|
||||
outtext();
|
||||
}
|
||||
}
|
||||
|
||||
outeof()
|
||||
{
|
||||
register int c;
|
||||
|
||||
v6flush(&sbuf);
|
||||
v6flush(&obuf);
|
||||
}
|
||||
|
||||
/* copysfile - copy string file to end of output file*/
|
||||
copysfile(fname)
|
||||
char *fname;
|
||||
{
|
||||
register int c;
|
||||
|
||||
close(sbuf.io_fd);
|
||||
if( fopen(fname,&sbuf,0) < 0 ) /* 3rd arg for versados */
|
||||
ferror("can't copy %s",fname);
|
||||
while( (c=getc(&sbuf)) > 0 )
|
||||
putc(c,&obuf);
|
||||
v6flush(&obuf);
|
||||
}
|
||||
|
||||
/* outword - output a word of data*/
|
||||
outword(w) /* word expression*/
|
||||
int w;
|
||||
{
|
||||
if( begseq )
|
||||
putchar(',');
|
||||
begseq++;
|
||||
printf("%d",w);
|
||||
}
|
||||
|
||||
/* outlong - output a long data*/
|
||||
outlong(l) /* returns - none*/
|
||||
long l; /* long data to output*/
|
||||
{
|
||||
outwdata();
|
||||
outword(l.hiword);
|
||||
outword(l.loword);
|
||||
outendseq();
|
||||
}
|
||||
|
||||
/* outfp - output floating point data*/
|
||||
outfp(l) /*[vlh] 3.4 returns - none*/
|
||||
long l; /* floating point data to output*/
|
||||
{
|
||||
outwdata();
|
||||
outword(l.hiword);
|
||||
outword(l.loword);
|
||||
outendseq();
|
||||
}
|
||||
|
||||
outendseq() /* returns - none*/
|
||||
{
|
||||
begseq = 0;
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
/*
|
||||
* outtstr - output text string
|
||||
* This outputs a string to the string file, this is used wherever
|
||||
* you cannot output the string directly to data space, such as in
|
||||
* the middle of expressions.
|
||||
*/
|
||||
outtstr(lab)
|
||||
int lab;
|
||||
{
|
||||
char *savep;
|
||||
int sbol;
|
||||
|
||||
savep = obp; /*save to restore later...*/
|
||||
obp = &sbuf;
|
||||
sbol = bol;
|
||||
bol = 1;
|
||||
printf("\tL%d:",lab);
|
||||
outstr();
|
||||
obp = savep;
|
||||
bol = sbol;
|
||||
}
|
||||
|
||||
/* outstr - output a string as a sequence of bytes*/
|
||||
/* Outputs ".dc.b <byte1>,<byte2>,...,<0>*/
|
||||
outstr()
|
||||
{
|
||||
register char *s;
|
||||
register int i;
|
||||
|
||||
outbdata();
|
||||
for( s = cstr, i = cstrsize; i > 0; i-- )
|
||||
outword(*s++ & 0xff);
|
||||
outendseq();
|
||||
}
|
||||
|
||||
/*
|
||||
* putchar - handle outputting to intermediate or error files
|
||||
* This catches tabs to allow for the integration of the parser
|
||||
* and code generator into one pass. By merely throwing away the
|
||||
* tabs here, the output will be OK for the assembler.
|
||||
*/
|
||||
putchar(c)
|
||||
char c;
|
||||
{
|
||||
if( !obp )
|
||||
write(1,&c,1);
|
||||
else if( c == '\t' ) {
|
||||
if( bol ) /* not used && !onepass ) */
|
||||
putc('(',obp); /*for code generator*/
|
||||
}
|
||||
else {
|
||||
bol = (c == '\n');
|
||||
putc(c,obp);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
#include "machine.h"
|
||||
/*
|
||||
* intermediate code operators
|
||||
* 0=>EOF, special operator
|
||||
*/
|
||||
#define EOF 0
|
||||
|
||||
/*1-59=>operators that generate code (entries in code gen optab)*/
|
||||
#define ADD 1
|
||||
#define SUB 2
|
||||
#define MULT 3
|
||||
#define DIV 4
|
||||
#define MOD 5
|
||||
#define RSH 6
|
||||
#define LSH 7
|
||||
#define AND 8
|
||||
#define OR 9
|
||||
#define XOR 10
|
||||
#define NOT 11
|
||||
#define UMINUS 12
|
||||
#define COMPL 13
|
||||
#define PREDEC 14
|
||||
#define PREINC 15
|
||||
#define POSTDEC 16
|
||||
#define POSTINC 17
|
||||
#define ASSIGN 18
|
||||
#define EQADD 19
|
||||
#define EQSUB 20
|
||||
#define EQMULT 21
|
||||
#define EQDIV 22
|
||||
#define EQMOD 23
|
||||
#define EQRSH 24
|
||||
#define EQLSH 25
|
||||
#define EQAND 26
|
||||
#define EQOR 27
|
||||
#define EQXOR 28
|
||||
#define FJSR 29
|
||||
#define EQUALS 30
|
||||
#define NEQUALS 31
|
||||
#define GREAT 32
|
||||
#define GREATEQ 33
|
||||
#define LESS 34
|
||||
#define LESSEQ 35
|
||||
#define INT2L 36
|
||||
#define LONG2I 37
|
||||
|
||||
/*machine dependent operators that generate code*/
|
||||
#define BTST 38
|
||||
#define LOAD 39
|
||||
#define LMULT 40
|
||||
#define LDIV 41
|
||||
#define LMOD 42
|
||||
#define LEQMULT 43
|
||||
#define LEQDIV 44
|
||||
#define LEQMOD 45
|
||||
#define EQADDR 46
|
||||
#define EQNOT 47
|
||||
#define EQNEG 48
|
||||
#define DOCAST 49
|
||||
|
||||
#define STASSIGN 50 /*[vlh]*/
|
||||
#define LONG2F 51 /*[vlh] 3.4*/
|
||||
#define FLOAT2L 52 /*[vlh] 3.4*/
|
||||
#define INT2F 53 /*[vlh] 3.4*/
|
||||
#define FLOAT2I 54 /*[vlh] 3.4*/
|
||||
#define LCGENOP 55 /*change if adding more operators...*/
|
||||
|
||||
/*intermediate code operators that do not generate code*/
|
||||
#define ADDR 60
|
||||
#define INDR 61
|
||||
#define LAND 62
|
||||
#define LOR 63
|
||||
#define QMARK 64
|
||||
#define COLON 65
|
||||
#define COMMA 66
|
||||
#define CINT 67
|
||||
#define CLONG 68
|
||||
#define SYMBOL 69
|
||||
#define AUTOINC 70
|
||||
#define AUTODEC 71
|
||||
#define CALL 72
|
||||
#define NACALL 73
|
||||
#define BFIELD 74
|
||||
#define IFGOTO 75
|
||||
#define INIT 76
|
||||
#define CFORREG 77
|
||||
#define DCLONG 78
|
||||
#define CFLOAT 79 /*[vlh] 3.4*/
|
||||
|
||||
/*operators local to parser*/
|
||||
#define CAST 80
|
||||
#define SEMI 81
|
||||
#define LCURBR 82
|
||||
#define RCURBR 83
|
||||
#define LBRACK 84
|
||||
#define RBRACK 85
|
||||
#define LPAREN 86
|
||||
#define RPAREN 87
|
||||
#define STRING 88
|
||||
#define RESWORD 89
|
||||
#define APTR 90
|
||||
#define PERIOD 91
|
||||
#define SIZEOF 92
|
||||
#define MPARENS 93
|
||||
#define FRETURN 94
|
||||
#define STACKEND 100
|
||||
|
||||
/*data types*/
|
||||
#define TYPELESS 0
|
||||
#define CHAR 1
|
||||
#define SHORT 2
|
||||
#define INT 3
|
||||
#define LONG 4
|
||||
#define UCHAR 5
|
||||
#define USHORT 6
|
||||
#define UNSIGNED 7
|
||||
#define ULONG 8
|
||||
#define FLOAT 9
|
||||
#define DOUBLE 10
|
||||
|
||||
/*data types local to parser*/
|
||||
#define STRUCT 11
|
||||
#define FRSTRUCT 12
|
||||
#define LLABEL 13
|
||||
|
||||
/*type flags and definitions*/
|
||||
#define TYPE 017
|
||||
#define SUPTYP 060
|
||||
#define ALLTYPE 077
|
||||
#define POINTER 020
|
||||
#define FUNCTION 040
|
||||
#define ARRAY 060
|
||||
#define SUTYPLEN 2
|
||||
|
||||
/*data registers*/
|
||||
#define DREG0 0
|
||||
#define DREG2 2
|
||||
#define DREG3 3
|
||||
#define DREG4 4
|
||||
#define DREG5 5
|
||||
#define DREG6 6
|
||||
#define DREG7 7
|
||||
#define AREG3 11
|
||||
#define AREG4 12
|
||||
#define AREG5 13
|
||||
|
||||
/*storage classes*/
|
||||
#define AUTO 1
|
||||
#define REGISTER 2
|
||||
#define EXTERNAL 3
|
||||
#define STATIC 4
|
||||
#define REGOFF 5
|
||||
#define EXTOFF 6
|
||||
#define STATOFF 7
|
||||
#define INDEXED 8
|
||||
|
||||
/*exclusively code generator storage classes*/
|
||||
#define CINDR 9
|
||||
#define CLINDR 10
|
||||
#define CFINDR 11 /* [vlh] 3.4 */
|
||||
|
||||
/*exclusively parser storage classes*/
|
||||
#define STRPROTO 9
|
||||
#define PDECLIST 10
|
||||
#define PARMLIST 11
|
||||
#define BFIELDCL 12
|
||||
#define UNELCL 13
|
||||
#define STELCL 14
|
||||
|
||||
|
||||
/*opinfo table bits*/
|
||||
#define OPPRI 077
|
||||
#define OPBIN 0100
|
||||
#define OPLVAL 0200
|
||||
#define OPREL 0400
|
||||
#define OPASSIGN 01000
|
||||
#define OPLWORD 02000
|
||||
#define OPRWORD 04000
|
||||
#define OPCOM 010000
|
||||
#define OPRAS 020000
|
||||
#define OPTERM 040000
|
||||
#define OPCONVS 0100000
|
||||
|
||||
/*68000 definitions*/
|
||||
#define PTRSIZE 4
|
||||
#define INTSIZE 2
|
||||
#define LONGSIZE 4
|
||||
#define SSIZE 8 /* chars per symbol */
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define TABC '\t' /* tab character */
|
||||
#define EOLC '\n' /* end of line character */
|
||||
#define BITSPBYTE 8
|
||||
|
||||
/*operator class priorities*/
|
||||
#define TRMPRI 0 /* terminal nodes */
|
||||
#define RPNPRI 1 /* ) and ] */
|
||||
#define CALPRI 2 /* in-stack call, ( or [ */
|
||||
#define COLPRI 3 /* init or case priority for : or , */
|
||||
#define STKPRI 4 /* priority of end of stack */
|
||||
#define COMPRI 5 /* normal priority for , */
|
||||
#define ASGPRI 6 /* =, +=, -=, *=, /=, %=, ... */
|
||||
#define QMKPRI 7 /* ?: */
|
||||
#define LORPRI 8 /* || */
|
||||
#define LNDPRI 9 /* && */
|
||||
#define ORPRI 10 /* |, ! */
|
||||
#define ANDPRI 11 /* & */
|
||||
#define EQLPRI 12 /* ==, != */
|
||||
#define RELPRI 13 /* >, <, >=, <= */
|
||||
#define SHFPRI 14 /* <<, >> */
|
||||
#define ADDPRI 15 /* +, - */
|
||||
#define MULPRI 16 /* *, /, % */
|
||||
#define UNOPRI 17 /* ++, --, &, *, -, ~, sizeof */
|
||||
#define LPNPRI 18 /* ., ->, [, (, function call */
|
||||
#define PSTPRI 19 /* in-stack post--, post++ */
|
||||
|
||||
struct io_buf {
|
||||
int io_fd;
|
||||
int io_nc;
|
||||
char *io_p;
|
||||
char io_b[512];
|
||||
};
|
||||
|
||||
#ifdef PDP11
|
||||
struct { short hiword; short loword; };
|
||||
#endif
|
||||
#ifdef MC68000
|
||||
struct { short hiword; short loword; };
|
||||
#endif
|
||||
#ifdef VAX
|
||||
struct { short loword; short hiword; };
|
||||
#endif
|
||||
|
||||
#define EXPSIZE 1024
|
||||
int exprarea[EXPSIZE];
|
||||
|
||||
/* v6io buffer declaration */
|
||||
#define BLEN 512
|
||||
|
||||
struct iobuf{
|
||||
int fildes;
|
||||
int nunused;
|
||||
char *xfree;
|
||||
char buff[BLEN];
|
||||
};
|
||||
323
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fparser/init.c
Normal file
323
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fparser/init.c
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/*
|
||||
C68 Parser - include file
|
||||
*/
|
||||
#include "icode.h"
|
||||
|
||||
/*symbol attribute fields*/
|
||||
#define SRESWORD 001 /*is symbol a reserved word?*/
|
||||
#define SGLOBAL 002 /*is symbol global?*/
|
||||
#define STYPEDEF 004 /*typedef declaration?*/
|
||||
#define SDEFINED 010 /*symbol defined?*/
|
||||
|
||||
/*reserved words*/
|
||||
#define R_AUTO 1
|
||||
#define R_BREAK 2
|
||||
#define R_CASE 3
|
||||
#define R_CHAR 4
|
||||
#define R_CONTINUE 5
|
||||
#define R_DO 6
|
||||
#define R_DEFAULT 7
|
||||
#define R_DOUBLE 8
|
||||
#define R_GOTO 9
|
||||
#define R_ELSE 10
|
||||
#define R_EXTERNAL 11
|
||||
#define R_FLOAT 12
|
||||
#define R_FOR 13
|
||||
#define R_IF 14
|
||||
#define R_INT 15
|
||||
#define R_LONG 16
|
||||
#define R_REGISTER 17
|
||||
#define R_RETURN 18
|
||||
#define R_SHORT 19
|
||||
#define R_SIZEOF 20
|
||||
#define R_STATIC 21
|
||||
#define R_STRUCT 22
|
||||
#define R_SWITCH 23
|
||||
#define R_TYPEDEF 24
|
||||
#define R_UNION 25
|
||||
#define R_UNSIGNED 26
|
||||
#define R_WHILE 27
|
||||
|
||||
/*
|
||||
* mixed-mode conversions, entries in 2-d array indexed by:
|
||||
* (int,unsn,long,doub,ptr)
|
||||
*/
|
||||
#define INT_CHAR 1
|
||||
#define UNSN_CHAR 1
|
||||
#define LONG_CHAR 1
|
||||
#define DOUB_CHAR 1
|
||||
#define PTR_CHAR 1
|
||||
#define INT_UNSN 0 /*no conversion is generated*/
|
||||
#define INT_LONG 2
|
||||
#define INT_DOUB 3
|
||||
#define INT_PTR 4
|
||||
#define UNSN_INT 0 /*no conversion is generated*/
|
||||
#define UNSN_LONG 6
|
||||
#define UNSN_DOUB 7
|
||||
#define UNSN_PTR 8
|
||||
#define LONG_INT 9
|
||||
#define LONG_UNSN 10
|
||||
#define LONG_DOUB 11
|
||||
#define LONG_PTR 12
|
||||
#define DOUB_INT 13
|
||||
#define DOUB_UNSN 14
|
||||
#define DOUB_LONG 15
|
||||
#define PTR_INT 16
|
||||
#define PTR_UNSN 17
|
||||
#define PTR_LONG 18
|
||||
#define PTR_PTR 19
|
||||
#define BADCONV 20
|
||||
|
||||
/* miscellaneous constants */
|
||||
#define OPSSIZE 40 /*operator stack size*/
|
||||
#define OPDSIZE 80 /*operand stack size*/
|
||||
#define HSIZE 517 /*hash table size, 3.4 made prime */
|
||||
#define SYMSIZE 1024 /*size to alloc for symbol structures*/
|
||||
#define SWSIZE 256 /*max no. of cases in a switch*/
|
||||
#define DSIZE 1000 /*dimension table size*/
|
||||
#define BITSPWORD 16 /*bits per word*/
|
||||
#define AREGLO 010 /*A reg flag*/
|
||||
#define HICREG 2 /*highest reg # used for code generation*/
|
||||
#define BITSPCHAR 8 /*bits per char*/
|
||||
#define CHRSPWORD 2 /*chars per word*/
|
||||
#define STRSIZE 300 /*max string length*/
|
||||
#define NFARGS 40 /*max no. of args to function*/
|
||||
#define NFRSTR 20 /*max no. of forward ref struct proto*/
|
||||
|
||||
/*symbol table node*/
|
||||
struct symbol {
|
||||
char s_attrib; /* defined, resword, global, typedef */
|
||||
char s_sc; /* auto, static, external, register */
|
||||
int s_type; /* 4bits specified, 2 bit fields for ptr... */
|
||||
int s_dp; /* index into dimension table */
|
||||
int s_ssp; /* dimension table/function arg table */
|
||||
int s_offset; /* offset inside of structure */
|
||||
char s_symbol[SSIZE]; /* symbol identifier, to SSIZE chars */
|
||||
struct symbol *s_struc; /* if struct, ptr to parent (sys III) */
|
||||
struct symbol *s_next; /* next symbol table entry */
|
||||
};
|
||||
|
||||
/*expression tree operator node*/
|
||||
struct tnode {
|
||||
int t_op;
|
||||
int t_type;
|
||||
int t_dp;
|
||||
int t_ssp;
|
||||
struct tnode *t_left;
|
||||
struct tnode *t_right;
|
||||
};
|
||||
|
||||
/*expression tree node for symbol - only keeps location*/
|
||||
struct symnode {
|
||||
int t_op;
|
||||
int t_type; /*data type of symbol*/
|
||||
int t_dp; /*dimension pointer of symbol*/
|
||||
int t_ssp; /*structure size index to dtab*/
|
||||
int t_sc; /*storage class of symbol*/
|
||||
int t_offset; /*offset of symbol*/
|
||||
int t_label;
|
||||
};
|
||||
|
||||
/*expressioon tree node for external symbol - need to keep name*/
|
||||
struct extnode {
|
||||
int t_op;
|
||||
int t_type;
|
||||
int t_dp;
|
||||
int t_ssp;
|
||||
int t_sc;
|
||||
int t_offset;
|
||||
int t_reg;
|
||||
int t_symbol[SSIZE]; /*symbol name*/
|
||||
};
|
||||
|
||||
/*expression tree node for integer constant*/
|
||||
struct conode {
|
||||
int t_op;
|
||||
int t_type;
|
||||
int t_dp;
|
||||
int t_ssp;
|
||||
int t_value; /*constant value*/
|
||||
};
|
||||
|
||||
struct lconode {
|
||||
int t_op;
|
||||
int t_type;
|
||||
int t_dp;
|
||||
int t_ssp;
|
||||
long t_lvalue; /*constant value*/
|
||||
};
|
||||
|
||||
struct swtch {
|
||||
int sw_label;
|
||||
int sw_value;
|
||||
} swtab[SWSIZE]=0;
|
||||
|
||||
/*operator and operand stack used by expr*/
|
||||
struct ops { /*operator stack*/
|
||||
int o_op; /*operator*/
|
||||
int o_pri; /*priority*/
|
||||
} opstack[OPSSIZE]=0, *opp=0;
|
||||
|
||||
char *opdstack[OPDSIZE]=0; /*operand stack*/
|
||||
char **opdp=0; /*operand stack pointer*/
|
||||
char *opap=0; /*ptr to next available loc in exprarea*/
|
||||
struct tnode *frp=0; /*pointer to function return info node*/
|
||||
int cswp=0; /*current low switch table index*/
|
||||
int clabel=0; /*continue label*/
|
||||
int blabel=0; /*break label*/
|
||||
int rlabel=0; /*return label*/
|
||||
int dlabel=0; /*default label*/
|
||||
int lineno=0; /*current line number of input*/
|
||||
int errcnt=0; /*count of errors*/
|
||||
int inclflag=0; /*in include file, don't incr line #'s*/
|
||||
int inclline=0; /*[vlh]line# in incl file for err rpting*/
|
||||
char inclfile[13]=0; /*[vlh]include filename for err rpting*/
|
||||
int equalstop=0; /*stop lex at '=', used for external init*/
|
||||
int commastop=0; /*stop parse @ comma(used for const expr)*/
|
||||
int colonstop=0; /*stop parse @ colon(used for case value)*/
|
||||
int instruct=0; /*set when in structure declaration*/
|
||||
int smember=0; /*set when seen . or ->*/
|
||||
int infunc=0; /*set when in function body*/
|
||||
int tdflag=0; /*declaration is a typedef proto*/
|
||||
char *tdp=0; /*points to typedef prototype*/
|
||||
int localsize=0; /*length of local variables*/
|
||||
int naregs=0; /*keeps track of ptr registers alloc'd*/
|
||||
int ndregs=0; /*keep track of data registers alloc'd*/
|
||||
int loadreg=0; /*need to load registers...*/
|
||||
int boffset=0; /*current bit offset in structure*/
|
||||
int eflag=0; /*[vlh] 3.4 IEEE floats */
|
||||
int fflag=0; /*[vlh] 3.4 FFP floats */
|
||||
int xflag=0; /*translate int's to long's*/
|
||||
int wflag=0; /*[vlh] don't generate warning mesgs*/
|
||||
int reducep=0; /*[vlh] if(procid); reduction*/
|
||||
int peektok=0; /*peeked at token*/
|
||||
|
||||
/*dimension table*/
|
||||
long dtab[DSIZE]=0; /* [vlh] 3.4 int => long */
|
||||
int cdp=0; /*next entry in dtab to alloc*/
|
||||
|
||||
/*lexical analyzer values*/
|
||||
int cvalue=0; /*current token value if keyword or CINT*/
|
||||
int cstrsize=0; /*current string size*/
|
||||
long clvalue=0; /*current token value if long constant*/
|
||||
struct symbol *csp=0; /*current token symbol ptr if SYMBOL*/
|
||||
char cstr[STRSIZE]=0; /*current token value if CSTRING*/
|
||||
struct symbol *dsp=0; /*declarator symbol pointer*/
|
||||
|
||||
/* -1 -> not instruct, 0 -> unnamed struct */
|
||||
struct symbol *strucptr[10]=0; /*[vlh] ptrs to struc symbols*/
|
||||
|
||||
/*function argument table, used to collect function parameters*/
|
||||
struct farg {
|
||||
struct symbol *f_sp;
|
||||
int f_offset;
|
||||
} fargtab[NFARGS]=0;
|
||||
|
||||
/*forward referenced structure prototype names*/
|
||||
struct symbol *frstab[NFRSTR]=0;
|
||||
int frstp=0;
|
||||
|
||||
/*output buffers for intermediate code and strings*/
|
||||
struct io_buf obuf=0, sbuf=0, ibuf=0, *obp=0;
|
||||
|
||||
#define stypedef(sp) (sp->s_attrib&STYPEDEF)
|
||||
#define walign(add) ((add+1)&(~1))
|
||||
#define array(type) ((type&SUPTYP)==ARRAY)
|
||||
#define function(type) ((type&SUPTYP)==FUNCTION)
|
||||
#define pointer(type) ((type&SUPTYP)==POINTER)
|
||||
#define notarray(type) ((type&SUPTYP)!=ARRAY)
|
||||
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
|
||||
#define notpointer(type) ((type&SUPTYP)!=POINTER)
|
||||
#define btype(type) (type&TYPE)
|
||||
#define suptype(type) (type&SUPTYP)
|
||||
#define alltype(type) (type&(SUPTYP|TYPE))
|
||||
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
|
||||
#define relop(op) ((opinfo[op]&OPREL)!=0)
|
||||
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
|
||||
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
|
||||
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
|
||||
#define binop(op) ((opinfo[op]&OPBIN)!=0)
|
||||
#define unaryop(op) ((opinfo[op]&OPBIN)==0)
|
||||
#define leaf(op) ((opinfo[op]&OPTERM)!=0)
|
||||
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
|
||||
#define oppriority(op) (opinfo[op]&OPPRI)
|
||||
#define makeiop(op) (op|(0254<<8))
|
||||
/* checks for symbol with structure element storage class */
|
||||
#define isstel(tp) (tp->t_op==SYMBOL && (sesc(tp)))
|
||||
#define sesc(t) (t->t_sc==STELCL||t->t_sc==UNELCL||t->t_sc==BFIELDCL)
|
||||
/* peek at next token, if not read token put back, else delete */
|
||||
/* 1 if matched, 0 otherwise */
|
||||
#define peek(tok) ( (peektok=gettok()) == tok )
|
||||
|
||||
#define outcommon(sym,size) printf("\t.comm _%.8s,%ld\n",sym,size)
|
||||
#define outgoto(lab) if( lab > 0 ) printf("\tbra L%d\n",lab)
|
||||
/* change to text segment */
|
||||
#define outtext() printf("\t.text\n")
|
||||
/* change segment to bss */
|
||||
#define outbss() printf("\t.bss\n")
|
||||
/* output global symbol references */
|
||||
#define outextdef(sym) printf("\t.globl _%.8s\n",sym)
|
||||
/* outputs reserved memory [vlh] 3.4 %d => %ld */
|
||||
#define outresmem(size) printf("\t.ds.b %ld\n",size)
|
||||
/* output padding for word alignments */
|
||||
#define outpad() printf("\t.even\n")
|
||||
/* output long constant to assembler */
|
||||
#define outlcon(val) printf("\t.dc.l %d\n",val)
|
||||
/* output label constant */
|
||||
#define outclab(lab) printf("\t.dc.l L%d\n",lab)
|
||||
/* output a label */
|
||||
#define outlab(lab) printf("\tL%d:",lab)
|
||||
/* output function label */
|
||||
#define outflab(sym) printf("\t_%.8s:\n\t~~%.8s:\n",sym,sym)
|
||||
/* output data label */
|
||||
#define outdlab(sym) printf("\t_%.8s:\n",sym)
|
||||
|
||||
/*functions returning pointers*/
|
||||
char *expr();
|
||||
char *talloc();
|
||||
char *tnalloc();
|
||||
char *enalloc();
|
||||
char *snalloc();
|
||||
char *cnalloc();
|
||||
char *lcnalloc();
|
||||
char *fpcnalloc();
|
||||
char *popopd();
|
||||
char *cvopgen();
|
||||
char *arrayref();
|
||||
char *funcref();
|
||||
char *install();
|
||||
char *lookup();
|
||||
char *balpar();
|
||||
char *sbrk();
|
||||
|
||||
long initlist();
|
||||
long dsize();
|
||||
long psize();
|
||||
long dodecl();
|
||||
long dlist();
|
||||
long getdec();
|
||||
long gethex();
|
||||
long getoct();
|
||||
long getfp();
|
||||
long toieee();
|
||||
long toffp();
|
||||
|
||||
int inittype=0;
|
||||
int strassign=0;
|
||||
int begseq=0;
|
||||
|
||||
#define EXPSIZE 1024
|
||||
int exprarea[EXPSIZE]=0;
|
||||
|
||||
int opdontop=0;
|
||||
int pbchar=0;
|
||||
|
||||
struct symbol *symbols=0;
|
||||
struct symbol *symtab[HSIZE]=0;
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "parser.h"
|
||||
int bol;
|
||||
|
||||
outinit(tp,type) /* returns - none*/
|
||||
struct tnode *tp;
|
||||
{
|
||||
outexpr(tnalloc(INIT,type,0,0,tp));
|
||||
}
|
||||
|
||||
outcforreg(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
outexpr(tnalloc(CFORREG,tp->t_type,0,0,tp));
|
||||
}
|
||||
|
||||
outifgoto(tp,dir,lab)
|
||||
struct tnode *tp;
|
||||
int dir;
|
||||
int lab;
|
||||
{
|
||||
outexpr(tnalloc(IFGOTO,dir,lab,0,tp));
|
||||
}
|
||||
|
||||
outexpr(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
if( !bol )
|
||||
putchar('\n');
|
||||
printf(".%x\n",lineno);
|
||||
outtree(tp);
|
||||
}
|
||||
|
||||
outtree(tp)
|
||||
struct tnode *tp;
|
||||
{
|
||||
if( !tp )
|
||||
return;
|
||||
printf("%x.%x",tp->t_op,tp->t_type);
|
||||
switch( tp->t_op ) {
|
||||
|
||||
case CINT:
|
||||
printf(".%x\n",tp->t_value);
|
||||
break;
|
||||
|
||||
case CLONG:
|
||||
printf(".%x.%x\n",tp->t_lvalue.hiword,tp->t_lvalue.loword);
|
||||
break;
|
||||
|
||||
case CFLOAT: /*[vlh] 3.4*/
|
||||
printf(".%x.%x\n",tp->t_lvalue.hiword,tp->t_lvalue.loword);
|
||||
break;
|
||||
|
||||
case SYMBOL:
|
||||
printf(".%x",tp->t_sc);
|
||||
if( tp->t_sc == EXTERNAL )
|
||||
printf(".%.8s\n",tp->t_symbol);
|
||||
else
|
||||
printf(".%x\n",tp->t_offset);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
putchar('\n');
|
||||
break;
|
||||
|
||||
case IFGOTO:
|
||||
case BFIELD:
|
||||
printf(".%x\n",tp->t_dp);
|
||||
outtree(tp->t_left);
|
||||
break;
|
||||
|
||||
default:
|
||||
putchar('\n');
|
||||
outtree(tp->t_left);
|
||||
if( binop(tp->t_op) )
|
||||
outtree(tp->t_right);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* snalloc - symbol node allocation*/
|
||||
/* Allocates a tree symbol node and sets the info in it*/
|
||||
char *snalloc(type,sc,off,dp,ssp) /* returns pointer to node alloc'ed*/
|
||||
int type; /* symbol type*/
|
||||
int sc; /* storage class*/
|
||||
int off; /* offset*/
|
||||
int dp; /* dimension pointer or other info*/
|
||||
int ssp; /* structure size pointer*/
|
||||
{
|
||||
register struct symnode *snp;
|
||||
|
||||
snp = talloc(sizeof(*snp));
|
||||
snp->t_op = SYMBOL;
|
||||
snp->t_sc = sc;
|
||||
snp->t_type = type;
|
||||
snp->t_dp = dp;
|
||||
snp->t_ssp = ssp;
|
||||
snp->t_offset = off;
|
||||
return(snp);
|
||||
}
|
||||
827
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fparser/lex.c
Normal file
827
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/fparser/lex.c
Normal file
@@ -0,0 +1,827 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "parser.h"
|
||||
#define SOI '\01'
|
||||
#define STEL HSIZE/2
|
||||
|
||||
/*
|
||||
* the following are the cases within gettok, all other cases are
|
||||
* single character unambiguous tokens. Note that we need to take
|
||||
* special care not to interfere with the single character unambiguous
|
||||
* operators, this is why there is a gap between WHITSP and EXCLAM.
|
||||
*/
|
||||
#define BADC 0 /*bad character*/
|
||||
#define WHITSP 101 /*white space*/
|
||||
#define EXCLAM 102 /*exlamation point*/
|
||||
#define DQUOTE 103 /*double quote*/
|
||||
#define PERCNT 104 /*percent sign*/
|
||||
#define AMPER 105 /*ampersand*/
|
||||
#define SQUOTE 106 /*single quote*/
|
||||
#define STAR 107 /*asterisk or mult sign*/
|
||||
#define PLUS 108 /*plus sign*/
|
||||
#define MINUS 109 /*minus sign*/
|
||||
#define SLASH 110 /*divide sign*/
|
||||
#define DIGIT 111 /*0..9*/
|
||||
#define LCAROT 112 /*less than sign*/
|
||||
#define EQUAL 113 /*equals sign*/
|
||||
#define RCAROT 114 /*greater than*/
|
||||
#define ALPHA 115 /*a..z,A..Z and underbar*/
|
||||
#define CAROT 116 /*^*/
|
||||
#define BAR 117 /*vertical bar*/
|
||||
|
||||
char ctype[] {
|
||||
BADC, BADC, BADC, BADC, BADC, BADC, BADC, BADC,
|
||||
BADC, WHITSP, WHITSP, WHITSP, WHITSP, WHITSP, BADC, BADC,
|
||||
BADC, BADC, BADC, BADC, WHITSP, BADC, BADC, BADC,
|
||||
BADC, BADC, BADC, BADC, BADC, BADC, BADC, BADC,
|
||||
WHITSP, EXCLAM, DQUOTE, BADC, BADC, PERCNT, AMPER, SQUOTE,
|
||||
LPAREN, RPAREN, STAR, PLUS, COMMA, MINUS, PERIOD, SLASH,
|
||||
DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
|
||||
DIGIT, DIGIT, COLON, SEMI, LCAROT, EQUAL, RCAROT, QMARK,
|
||||
BADC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
|
||||
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
|
||||
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
|
||||
ALPHA, ALPHA, ALPHA, LBRACK, BADC, RBRACK, CAROT, ALPHA,
|
||||
BADC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
|
||||
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
|
||||
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
|
||||
ALPHA, ALPHA, ALPHA, LCURBR, BAR, RCURBR, COMPL, BADC
|
||||
};
|
||||
|
||||
/*key word table*/
|
||||
struct resword {
|
||||
char *r_name;
|
||||
int r_value;
|
||||
} reswords[] {
|
||||
"auto", R_AUTO,
|
||||
"break", R_BREAK,
|
||||
"case", R_CASE,
|
||||
"char", R_CHAR,
|
||||
"continue", R_CONTINUE,
|
||||
"do", R_DO,
|
||||
"default", R_DEFAULT,
|
||||
"double", R_DOUBLE,
|
||||
"goto", R_GOTO,
|
||||
"else", R_ELSE,
|
||||
"extern", R_EXTERNAL,
|
||||
"float", R_FLOAT,
|
||||
"for", R_FOR,
|
||||
"if", R_IF,
|
||||
"int", R_INT,
|
||||
"long", R_LONG,
|
||||
"register", R_REGISTER,
|
||||
"return", R_RETURN,
|
||||
"short", R_SHORT,
|
||||
"sizeof", R_SIZEOF,
|
||||
"static", R_STATIC,
|
||||
"struct", R_STRUCT,
|
||||
"switch", R_SWITCH,
|
||||
"typedef", R_TYPEDEF,
|
||||
"union", R_UNION,
|
||||
"unsigned", R_UNSIGNED,
|
||||
"while", R_WHILE,
|
||||
0,
|
||||
};
|
||||
|
||||
#define SELFMOD 0200
|
||||
#define ASMASK 0177
|
||||
|
||||
/*
|
||||
* this table is used to check for an operator after an equals sign.
|
||||
* note that =-, =* and =& may all have an ambiguous meaning if not
|
||||
* followed by a space, this is checked for in gettok.
|
||||
*/
|
||||
char asmap[] {
|
||||
EQUALS, /*==*/
|
||||
EQADD, /*=+*/
|
||||
EQSUB|SELFMOD, /*=-*/
|
||||
EQMULT|SELFMOD, /*=**/
|
||||
EQDIV, /*=/*/
|
||||
EQOR, /*=|*/
|
||||
EQAND|SELFMOD, /*=&*/
|
||||
EQXOR, /*=^*/
|
||||
EQMOD, /*=%*/
|
||||
};
|
||||
|
||||
char escmap[] "\b\n\r\t";
|
||||
int pbchar; /*pushed back character*/
|
||||
struct symbol *symtab[HSIZE]; /*hash table*/
|
||||
struct symbol *symbols; /*pointer to next avail symbol buf*/
|
||||
int nsyms; /*number of symbol bufs in memory*/
|
||||
|
||||
/*
|
||||
* getdec - get a decimal number
|
||||
* Uses Horner's method to get decimal number. Note that
|
||||
* multiplication by 10 is cleverly programmed as two shifts and two
|
||||
* adds. This is because long multiplies are painful on both the
|
||||
* PDP-11 and 68000.
|
||||
*/
|
||||
long getdec() /* returns number*/
|
||||
{
|
||||
register long value;
|
||||
register char c;
|
||||
|
||||
for( value = 0; (c=ngetch()) >= '0' && c <= '9'; ) {
|
||||
value =<< 1; /*value = value*2*/
|
||||
value =+ value << 2; /*value*2 + value*8 = value*10*/
|
||||
value =+ (c-'0');
|
||||
}
|
||||
putback(c);
|
||||
return(value);
|
||||
}
|
||||
|
||||
#define BIAS 127L
|
||||
#define EXPSIZ 4
|
||||
#define FRACSIZ 20
|
||||
|
||||
long toieee();
|
||||
long toffp();
|
||||
float power10();
|
||||
|
||||
/*
|
||||
* getfp - get a floating point constant
|
||||
* we've already gotten the significant digits, now build a
|
||||
* floating point number with possible decimal digits and an
|
||||
* exponent, yields an ieee formated floating point number,
|
||||
* unless the fflag is on, then a ffp constant is generated.
|
||||
*/
|
||||
long
|
||||
getfp(significant)
|
||||
long significant;
|
||||
{
|
||||
register char c;
|
||||
register long places; /* decimal places */
|
||||
int esign;
|
||||
float exp, fraction, fp;
|
||||
|
||||
places = 0L; esign = 0; fraction = significant; exp = 0.0;
|
||||
if ((c = ngetch()) == '.') /* get decimal places */
|
||||
for( ; (c=ngetch()) >= '0' && c <= '9';) {
|
||||
fraction = fraction * 10.0;
|
||||
fraction = fraction + (c - '0');
|
||||
places++;
|
||||
}
|
||||
|
||||
if (c=='e' || c=='E') { /* exponent exists */
|
||||
esign = (peekis('-')) ? 1 : (peekis('+')) ? 0 : 0;
|
||||
for( ; (c=ngetch()) >= '0' && c <= '9'; ) {
|
||||
exp = exp * 10.0;
|
||||
exp = exp + (c - '0');
|
||||
}
|
||||
}
|
||||
|
||||
putback(c);
|
||||
if (esign)
|
||||
exp = -exp;
|
||||
places = exp - places;
|
||||
fp = fraction * power10(places);
|
||||
if (fflag)
|
||||
return( toffp(fp) );
|
||||
else
|
||||
return ( toieee(fp) );
|
||||
}
|
||||
|
||||
float
|
||||
power10(pwr) /* used by getfp, 10^pwr */
|
||||
long pwr;
|
||||
{
|
||||
float f;
|
||||
|
||||
if (pwr < 0L) /* negative power */
|
||||
for (f = 1.0; pwr < 0L; pwr++)
|
||||
f = f / 10.0;
|
||||
else /* positive power */
|
||||
for (f = 1.0; pwr > 0L; pwr--)
|
||||
f = f * 10.0;
|
||||
return(f);
|
||||
}
|
||||
|
||||
long
|
||||
toffp(f) /* converts current machine float to ffp rep */
|
||||
float f;
|
||||
{
|
||||
register long exp;
|
||||
register int sign, count;
|
||||
long l;
|
||||
|
||||
if (f == 0.0)
|
||||
return(0L);
|
||||
if (f < 0.0) {
|
||||
sign = 1;
|
||||
f = -f;
|
||||
}
|
||||
else
|
||||
sign = 0;
|
||||
exp = 0L;
|
||||
for( ; f >= 1.0; f = f / 2.0)
|
||||
exp++;
|
||||
for( ; f < 0.5; f = f * 2.0)
|
||||
exp--;
|
||||
f = f * 16777216.0; /* 2 ^ 24 */
|
||||
l = f;
|
||||
l =<< 8;
|
||||
if (sign)
|
||||
l =| 0x80;
|
||||
exp =+ 0x40;
|
||||
l =| (exp & 0x7f);
|
||||
return(l);
|
||||
}
|
||||
|
||||
long
|
||||
toieee(f) /* converts current machine float to ieee rep */
|
||||
float f;
|
||||
{
|
||||
register long exp;
|
||||
register int sign, count;
|
||||
long l;
|
||||
|
||||
if (f == 0.0)
|
||||
return(0L);
|
||||
if (f < 0.0) {
|
||||
sign = 1;
|
||||
f = -f;
|
||||
}
|
||||
else
|
||||
sign = 0;
|
||||
exp = 0L;
|
||||
for( ; f >= 2.0; f = f / 2.0)
|
||||
exp++;
|
||||
for( ; f < 1.0; f = f * 2.0)
|
||||
exp--;
|
||||
f = f - 1.0;
|
||||
f = f * 8388608.0; /* 2 ^ 23 */
|
||||
l = f;
|
||||
if (sign)
|
||||
l =| 0x80000000;
|
||||
exp = (exp + BIAS)<<23;
|
||||
l =| (exp & 0x7f800000);
|
||||
return(l);
|
||||
}
|
||||
|
||||
#define toupper(c) ((c) & ~32)
|
||||
/* gethex - get an hexidecimal number*/
|
||||
/* Uses Horner's method to get hexidecimal number*/
|
||||
long gethex() /* returns number*/
|
||||
{
|
||||
register long value;
|
||||
register char c, ch;
|
||||
|
||||
value = 0;
|
||||
while( 1 ) {
|
||||
if( (c=ngetch()) >= '0' && c <= '9' )
|
||||
c =- '0';
|
||||
else if((ch=toupper(c)) >= 'A' && ch <= 'F' ) /* [vlh] */
|
||||
c = ch - ('A'-10);
|
||||
else
|
||||
break;
|
||||
value = (value<<4) + c;
|
||||
}
|
||||
putback(c);
|
||||
return(value);
|
||||
}
|
||||
|
||||
/* getoct - get an octal number*/
|
||||
/* Uses Horner's method to get octal number*/
|
||||
long getoct(flag) /* returns number*/
|
||||
int flag; /* string flag 1=>in string, else 0*/
|
||||
{
|
||||
register long value;
|
||||
register char c;
|
||||
register int count;
|
||||
|
||||
count = 0;
|
||||
for( value = 0; (c=ngetch()) >= '0' && c <= '7'; ) {
|
||||
if( flag && ++count > 3 )
|
||||
break;
|
||||
value = (value<<3) + (c-'0');
|
||||
}
|
||||
putback(c);
|
||||
return(value);
|
||||
}
|
||||
|
||||
/*
|
||||
* gettok - get next token from input
|
||||
* Checks pushed-packed token buffer, supresses / * * / comments,
|
||||
* folds multiple character special symbols into single word token.
|
||||
*/
|
||||
gettok() /* returns token type*/
|
||||
{
|
||||
register int c, nextc, i;
|
||||
register char *p;
|
||||
register long value;
|
||||
char sym[SSIZE];
|
||||
|
||||
if( peektok ) {
|
||||
i = peektok;
|
||||
peektok = 0;
|
||||
return(i);
|
||||
}
|
||||
while( (c=ngetch()) != EOF ) {
|
||||
switch(ctype[c]) {
|
||||
|
||||
case BADC: /*bad character*/
|
||||
error("invalid character");
|
||||
break;
|
||||
|
||||
case SEMI:
|
||||
cvalue = 0; /* [vlh] not reserved word... */
|
||||
default:
|
||||
return( ctype[c] );
|
||||
|
||||
case WHITSP: /*skip all white space*/
|
||||
break;
|
||||
|
||||
case EXCLAM: /*!= or !*/
|
||||
return( peekis('=') ? NEQUALS : NOT );
|
||||
|
||||
case DQUOTE: /*quoted string*/
|
||||
getstr(cstr,STRSIZE,'"');
|
||||
cvalue = nextlabel++;
|
||||
return(STRING);
|
||||
|
||||
case PERCNT: /*%= or %*/
|
||||
return( peekis('=') ? EQMOD : MOD );
|
||||
|
||||
case AMPER: /*&=, && or &*/
|
||||
return( peekis('=') ? EQAND : peekis('&') ? LAND : AND );
|
||||
|
||||
case SQUOTE: /*character constant*/
|
||||
getstr(cstr,STRSIZE,'\'');
|
||||
if( cstrsize > CHRSPWORD+1 ) {
|
||||
error("character constant too long");
|
||||
cstrsize = CHRSPWORD + 1;
|
||||
}
|
||||
cvalue = 0;
|
||||
for( p = cstr; --cstrsize > 0; ) {
|
||||
cvalue =<< BITSPCHAR;
|
||||
cvalue =| (*p++ & 0377);
|
||||
}
|
||||
return(CINT);
|
||||
|
||||
case STAR: /**= or **/
|
||||
return( peekis('=') ? EQMULT : MULT );
|
||||
|
||||
case PLUS: /*+=, ++ or +*/
|
||||
return( peekis('=') ? EQADD : peekis('+') ? PREINC : ADD );
|
||||
|
||||
case MINUS: /*-=, --, -> or -*/
|
||||
return( peekis('=') ? EQSUB : peekis('-') ? PREDEC :
|
||||
peekis('>') ? APTR : SUB );
|
||||
|
||||
case SLASH: /*/ *..* /, //..., /= or /*/
|
||||
if( peekis('*') ) {
|
||||
while( (c=ngetch()) != EOF )
|
||||
if( c == '*' && peekis('/') )
|
||||
break;
|
||||
if( c == EOF ) {
|
||||
error("no */ before EOF");
|
||||
return(EOF);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if( peekis('/') ) {
|
||||
while( (c=ngetch()) != EOF && c != EOLC )
|
||||
;
|
||||
continue;
|
||||
}
|
||||
return( peekis('=') ? EQDIV : DIV );
|
||||
|
||||
case DIGIT: /*number constant (long or reg)*/
|
||||
i = 0; /*flags if long constant*/
|
||||
if( c != '0' ) {
|
||||
putback(c);
|
||||
dofp:
|
||||
value = getdec();
|
||||
if ((c=ngetch())=='.' || c=='e' || c=='E') { /*[vlh] 3.4 */
|
||||
putback(c);
|
||||
clvalue = getfp(value);
|
||||
return(CFLOAT);
|
||||
}
|
||||
putback(c);
|
||||
if( value > 32767 || value < -32768 )
|
||||
i++;
|
||||
}
|
||||
else if( peekis('x') || peekis('X') ) {
|
||||
value = gethex();
|
||||
if( value < 0 || value >= 0x10000L )
|
||||
i++;
|
||||
}
|
||||
else {
|
||||
if (peekis('.')) {
|
||||
putback('.');
|
||||
goto dofp;
|
||||
}
|
||||
value = getoct(0);
|
||||
if( value < 0 || value >= 0x10000L )
|
||||
i++;
|
||||
}
|
||||
if( peekis('l') || peekis('L') || i ) {
|
||||
clvalue = value;
|
||||
return(CLONG);
|
||||
}
|
||||
cvalue = value;
|
||||
return(CINT);
|
||||
|
||||
case LCAROT: /*<=, <<, <<= or <*/
|
||||
return( peekis('=') ? LESSEQ : peekis('<') ?
|
||||
(peekis('=') ? EQLSH : LSH) : LESS );
|
||||
|
||||
case EQUAL: /*==, =<<, =>>, =+, ..., =*/
|
||||
if( peekis('<') ) {
|
||||
if( peekis('<') )
|
||||
return(EQLSH);
|
||||
}
|
||||
else if( peekis('>') ) {
|
||||
if( peekis('>') )
|
||||
return(EQRSH);
|
||||
}
|
||||
else if( (i=index("=+-*/|&^%",(c=ngetch()))) >= 0 ) {
|
||||
i = asmap[i];
|
||||
if( i & SELFMOD ) {
|
||||
if( (nextc=ngetch()) != ' ' )
|
||||
if (!wflag) /*[vlh] old fashion initialization*/
|
||||
error("=%c assumed",c);
|
||||
putback(nextc);
|
||||
}
|
||||
return( i & ASMASK );
|
||||
}
|
||||
else
|
||||
putback(c);
|
||||
return(ASSIGN);
|
||||
|
||||
case RCAROT: /*>=, >>, >>= or >*/
|
||||
return( peekis('=') ? GREATEQ : peekis('>') ?
|
||||
(peekis('=') ? EQRSH : RSH) : GREAT );
|
||||
|
||||
case ALPHA: /*[A-Za-z][A-Za-z0-9]**/
|
||||
p = &sym[0];
|
||||
i = SSIZE;
|
||||
for(; ctype[c] == ALPHA || ctype[c] == DIGIT; c=ngetch(),i-- )
|
||||
if( i > 0 )
|
||||
*p++ = c;
|
||||
if( i > 0 )
|
||||
*p = '\0';
|
||||
putback(c);
|
||||
csp = lookup(sym);
|
||||
if( csp->s_attrib & SRESWORD ) {
|
||||
cvalue = csp->s_offset;
|
||||
return(RESWORD);
|
||||
}
|
||||
smember = 0;
|
||||
return(SYMBOL);
|
||||
|
||||
case CAROT: /*^= or ^*/
|
||||
return( peekis('=') ? EQXOR : XOR );
|
||||
|
||||
case BAR: /*|=, || or |*/
|
||||
return( peekis('=') ? EQOR : peekis('|') ? LOR : OR );
|
||||
|
||||
}
|
||||
}
|
||||
return(EOF);
|
||||
}
|
||||
|
||||
/*
|
||||
* peekis - peeks at next character for specific character
|
||||
* Gets next (possibly pushed back) character, if it matches
|
||||
* the given character 1 is returned, otherwise the character
|
||||
* is put back.
|
||||
*/
|
||||
peekis(tc) /* returns 1 if match, 0 otherwise*/
|
||||
int tc; /* test character*/
|
||||
{
|
||||
register int c;
|
||||
|
||||
if( (c=ngetch()) == tc )
|
||||
return(1);
|
||||
putback(c);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* ngetch - get a possibly pushed back character*/
|
||||
/* Checks pbchar variable, returns it if non-zero, handles counting*/
|
||||
/* of new lines and whether you are in an include or not.*/
|
||||
ngetch() /* returns character read or EOF*/
|
||||
{
|
||||
register int c;
|
||||
register char *ifile;
|
||||
|
||||
if( pbchar ) {
|
||||
c = pbchar;
|
||||
pbchar = 0;
|
||||
}
|
||||
else if( (c=getc(&ibuf)) == EOLC ) {
|
||||
if( inclflag )
|
||||
inclflag = 0;
|
||||
else
|
||||
lineno++;
|
||||
}
|
||||
else if( c == SOI) { /*[vlh]add incl filename & line # */
|
||||
inclflag++;
|
||||
ifile = &inclfile;
|
||||
while ((c=getc(&ibuf)) != SOI)
|
||||
*ifile++ = c&0377;
|
||||
*ifile = 0;
|
||||
inclline = getdec() & 077777;
|
||||
c = ' ';
|
||||
}
|
||||
else if( c < 0 )
|
||||
c = EOF;
|
||||
return(c);
|
||||
}
|
||||
|
||||
/*
|
||||
* peekc - peek at the next non-whitespace character after token
|
||||
* This allows for the problem of having to look at two tokens
|
||||
* at once. The second token is always a semi-colon or colon,
|
||||
* so we only look at the single character, rather than going
|
||||
* thru gettok.
|
||||
*/
|
||||
peekc(tc) /* returns 1 if match, 0 otherwise*/
|
||||
int tc; /* character to look for*/
|
||||
{
|
||||
register int c;
|
||||
|
||||
while( ctype[(c=ngetch())] == WHITSP) ;
|
||||
if( c == tc )
|
||||
return(1);
|
||||
putback(c);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* putback - puts back a single character*/
|
||||
/* Checks pbchar for error condition.*/
|
||||
putback(c) /* returns - none*/
|
||||
int c;
|
||||
{
|
||||
if( pbchar )
|
||||
error("too many chars pushed back");
|
||||
else
|
||||
pbchar = c;
|
||||
}
|
||||
|
||||
/* getstr - get a quoted (single or double) character string*/
|
||||
/* Gets specified number of characters, handling escapes.*/
|
||||
getstr(str,nchars,endc) /* returns - none*/
|
||||
char *str; /* pointer to string buffer*/
|
||||
int nchars; /* max number of characters*/
|
||||
char endc; /* ending string character*/
|
||||
{
|
||||
register char *p;
|
||||
register int i;
|
||||
register int c;
|
||||
register int j;
|
||||
|
||||
cstrsize = 1;
|
||||
p = str;
|
||||
for( i = nchars; (c=ngetch()) != endc; i-- ) {
|
||||
if( c == EOF || c == EOLC ) {
|
||||
error("string cannot cross line");
|
||||
break;
|
||||
}
|
||||
if( c == '\\' ) {
|
||||
if( (c=ngetch()) >= '0' && c <= '7' ) {
|
||||
putback(c);
|
||||
if( (c=getoct(1)) < 0 || c > 255 ) {
|
||||
error("bad character constant");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if( (j=index("bnrt",c)) >= 0 )
|
||||
c = escmap[j];
|
||||
else if( c == EOLC ) /*escape followed by nl->ignore*/
|
||||
continue;
|
||||
}
|
||||
if( i > 0 ) { /*room left in string?*/
|
||||
cstrsize++;
|
||||
*p++ = c;
|
||||
}
|
||||
else if( !i ) /*only say error once...*/
|
||||
error("string too long");
|
||||
}
|
||||
if( i <= 0 ) /*string overflow?*/
|
||||
p--;
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
/* syminit - initialize the symbol table, install reswords*/
|
||||
/* Goes thru the resword table and installs them into the symbol*/
|
||||
/* table.*/
|
||||
syminit() /* returns - none*/
|
||||
{
|
||||
register struct resword *rp;
|
||||
|
||||
for( rp = &reswords[0]; rp->r_name != 0; rp++ )
|
||||
install(rp->r_name,SRESWORD|SDEFINED,rp->r_value);
|
||||
}
|
||||
|
||||
/* install - install a symbol in the symbol table*/
|
||||
/* Allocates a symbol entry, copies info into it and links it*/
|
||||
/* into the hash table chain.*/
|
||||
char *install(sym,attrib,offset) /* returns pointer to symbol struct*/
|
||||
char *sym; /* symbol to install*/
|
||||
int attrib; /* attribues of symbol*/
|
||||
int offset; /* symbol offset (resword value)*/
|
||||
{
|
||||
register struct symbol *sp;
|
||||
register int i;
|
||||
|
||||
while( !(sp=symbols) ) {
|
||||
if( !(sp=sbrk(SYMSIZE)) )
|
||||
ferror("symbol table overflow");
|
||||
for( i = SYMSIZE/(sizeof *symbols); --i >= 0; ) {
|
||||
sp->s_next = symbols;
|
||||
symbols = sp++;
|
||||
}
|
||||
}
|
||||
symbols = sp->s_next;
|
||||
sp->s_attrib = attrib;
|
||||
sp->s_sc = 0; sp->s_type = 0; sp->s_dp = 0; sp->s_ssp = 0;
|
||||
sp->s_offset = offset;
|
||||
sp->s_struc = (instruct) ? strucptr[smember+instruct] : 0;
|
||||
symcopy(sym,sp->s_symbol); /*copy symbol to symbol struct*/
|
||||
i = symhash(sym,instruct|smember); /*link into chain list*/
|
||||
sp->s_next = symtab[i];
|
||||
symtab[i] = sp;
|
||||
return(sp);
|
||||
}
|
||||
|
||||
/* lookup - looks up a symbol in symbol table*/
|
||||
/* Hashes symbol, then goes thru chain, if not found, then*/
|
||||
/* installs the symbol.*/
|
||||
char *lookup(sym) /* returns pointer to symbol buffer*/
|
||||
char *sym; /* pointer to symbol*/
|
||||
{
|
||||
register struct symbol *sp, *hold;
|
||||
register char *p;
|
||||
int exact; /* same name, diff type or offset */
|
||||
|
||||
p = sym;
|
||||
for( sp = symtab[symhash(p,0)]; sp != 0; sp = sp->s_next )
|
||||
if((sp->s_attrib&(SRESWORD|STYPEDEF)) && symequal(p,sp->s_symbol))
|
||||
return(sp);
|
||||
if (!(smember|instruct)) { /*[vlh]*/
|
||||
for( sp=symtab[symhash(p,0)]; sp!=0; sp=sp->s_next )
|
||||
if( symequal(p,sp->s_symbol) ) return(sp);
|
||||
}
|
||||
else { /* doing a declaration or an expression */
|
||||
hold = 0; exact = 0;
|
||||
for( sp=symtab[symhash(p,instruct|smember)]; sp!=0; sp=sp->s_next )
|
||||
if( symequal(p,sp->s_symbol) )
|
||||
if (symsame(sp,hold,&exact)) return(sp);
|
||||
else if (!hold && !exact) hold = sp;
|
||||
if (hold && !exact) return(hold);
|
||||
}
|
||||
return(install(p,0,0));
|
||||
}
|
||||
|
||||
/* freesyms - frees all local symbols at end of function declaration*/
|
||||
/* Searches thru symbol table, deleting all symbols marked as locals*/
|
||||
freesyms() /* returns - none*/
|
||||
{
|
||||
register int i, tinfo;
|
||||
register struct symbol *sp, *tp, *nextp, **htp;
|
||||
|
||||
for( htp = &symtab[0], i = HSIZE; --i >= 0; htp++ )
|
||||
for( tp = 0, sp = *htp; sp != 0; sp = nextp ) {
|
||||
nextp = sp->s_next;
|
||||
if( !(sp->s_attrib&SDEFINED) ) {
|
||||
error("undefined label: %.8s",sp->s_symbol);
|
||||
sp->s_attrib =| SDEFINED;
|
||||
}
|
||||
if( sp->s_attrib & (SGLOBAL|SRESWORD) )
|
||||
tp = sp;
|
||||
else {
|
||||
if( tp )
|
||||
tp->s_next = sp->s_next;
|
||||
else
|
||||
*htp = sp->s_next;
|
||||
sp->s_next = symbols;
|
||||
symbols = sp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* chksyms - checks symbol table for undefined symbols, etc.*/
|
||||
/* Goes thru the symbol table checking for undeclared forward*/
|
||||
/* referenced structures, and outputs local symbols for debugger.*/
|
||||
chksyms() /* returns - none*/
|
||||
{
|
||||
register struct symbol **htp, *sp;
|
||||
register int i, sc;
|
||||
|
||||
for( htp = &symtab[0], i = HSIZE; --i >= 0; htp++ )
|
||||
for( sp = *htp; sp != 0; sp = sp->s_next ) {
|
||||
sc = sp->s_sc;
|
||||
if(sc!=0 && sp->s_ssp>=0 && (btype(sp->s_type))==FRSTRUCT) {
|
||||
sp->s_ssp = frstab[sp->s_ssp]->s_ssp; /* 3.4 ssp>0 */
|
||||
sp->s_type = (sp->s_type&~TYPE) | STRUCT;
|
||||
}
|
||||
if( sc == PDECLIST ) {
|
||||
error("not in parameter list: %.8s",sp->s_symbol);
|
||||
sp->s_sc = AUTO;
|
||||
}
|
||||
if( infunc )
|
||||
outlocal(sp->s_type,sp->s_sc,sp->s_symbol,sp->s_offset);
|
||||
}
|
||||
}
|
||||
|
||||
/* symhash - compute hash value for symbol*/
|
||||
/* Sums the symbols characters and takes that modulus the hash table*/
|
||||
/* size.*/
|
||||
symhash(sym,stel) /* returns hash value for symbol*/
|
||||
char *sym; /* pointer to symbol*/
|
||||
int stel; /* structure element flag*/
|
||||
{
|
||||
register char *p;
|
||||
register int hashval, i;
|
||||
|
||||
hashval = (stel ? STEL : 0 );
|
||||
for( p = sym, i = SSIZE; *p != '\0' && i > 0; i-- )
|
||||
hashval =+ *p++;
|
||||
return( hashval % HSIZE );
|
||||
}
|
||||
|
||||
/* symequal - check for symbol equality*/
|
||||
/* Does comparison between two symbols.*/
|
||||
symequal(sym1,sym2) /* returns 1 if equal, 0 otherwise*/
|
||||
char *sym1; /* pointer to first symbol*/
|
||||
char *sym2; /* pointer to second symbol*/
|
||||
{
|
||||
register char *p, *q;
|
||||
register int i;
|
||||
|
||||
for( p = sym1, q = sym2, i = SSIZE; *p == *q++; )
|
||||
if( *p++ == '\0' || --i == 0 )
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* symsame - symbol member same as declared */
|
||||
symsame(sp,hold,exact) /* [vlh] */
|
||||
struct symbol *sp, *hold;
|
||||
int *exact;
|
||||
{
|
||||
if (strucptr[smember+instruct])
|
||||
if (strucptr[smember+instruct]==sp->s_struc) return(1);
|
||||
if (hold)
|
||||
if (sp->s_type != hold->s_type || sp->s_offset != hold->s_offset)
|
||||
*exact = 1;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* symcopy - symbol copy*/
|
||||
/* Copies one symbol to another.*/
|
||||
symcopy(sym1,sym2) /* returns - none*/
|
||||
char *sym1; /* pointer to symbol to copy*/
|
||||
char *sym2; /* pointer to area to copy to*/
|
||||
{
|
||||
register char *p, *q;
|
||||
register int i;
|
||||
|
||||
for( p = sym1, q = sym2, i = SSIZE; --i >= 0; )
|
||||
*q++ = ( *p ? *p++ : '\0');
|
||||
}
|
||||
|
||||
/* index - find the index of a character in a string*/
|
||||
/* This is identical to Software Tools index.*/
|
||||
index(str,chr) /* returns index of c in str or -1*/
|
||||
char *str; /* pointer to string to search*/
|
||||
char chr; /* character to search for*/
|
||||
{
|
||||
register char *s;
|
||||
register int i;
|
||||
|
||||
for( s = str, i = 0; *s != '\0'; i++ )
|
||||
if( *s++ == chr )
|
||||
return(i);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* next - if next token matches given token, skip and return success*/
|
||||
/* This allows for clean parsing of declarations.*/
|
||||
next(tok) /* returns 1 if matched, 0 otherwise*/
|
||||
int tok;
|
||||
{
|
||||
register int token;
|
||||
|
||||
if( (token=gettok()) == tok )
|
||||
return(1);
|
||||
peektok = token;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* pbtok - put back the given token*/
|
||||
/* This merely sets the peektok variable*/
|
||||
pbtok(tok) /* returns - none*/
|
||||
int tok;
|
||||
{
|
||||
if( peektok )
|
||||
error("too many tokens pushed back");
|
||||
peektok = tok;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user