*** empty log message ***
This commit is contained in:
219
lang/cem/cemcom/em.c
Normal file
219
lang/cem/cemcom/em.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/* $Header$ */
|
||||
/* EM CODE OUTPUT ROUTINES */
|
||||
|
||||
#define CMODE 0644
|
||||
#define MAX_ARG_CNT 32
|
||||
|
||||
#include "em.h"
|
||||
#include "system.h"
|
||||
#include "bufsiz.h"
|
||||
#include "arith.h"
|
||||
#include "label.h"
|
||||
|
||||
/*
|
||||
putbyte(), C_open() and C_close() are the basic routines for
|
||||
respectively write on, open and close the output file.
|
||||
The put_*() functions serve as formatting functions of the
|
||||
various EM language constructs.
|
||||
See "Description of a Machine Architecture for use with
|
||||
Block Structured Languages" par. 11.2 for the meaning of these
|
||||
names.
|
||||
*/
|
||||
|
||||
/* supply a kind of buffered output */
|
||||
#define flush(x) sys_write(ofd, &obuf[0], x);
|
||||
|
||||
static char obuf[BUFSIZ];
|
||||
static char *opp = &obuf[0];
|
||||
int ofd = -1;
|
||||
|
||||
putbyte(b) /* shouldn't putbyte() be a macro ??? (EB) */
|
||||
int b;
|
||||
{
|
||||
if (opp >= &obuf[BUFSIZ]) { /* flush if buffer overflows */
|
||||
flush(BUFSIZ);
|
||||
opp = &obuf[0];
|
||||
}
|
||||
*opp++ = (char) b;
|
||||
}
|
||||
|
||||
C_open(nm) /* open file for compact code output */
|
||||
char *nm;
|
||||
{
|
||||
if (nm == 0)
|
||||
ofd = 1; /* standard output */
|
||||
else
|
||||
if ((ofd = sys_creat(nm, CMODE)) < 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
C_close()
|
||||
{
|
||||
flush(opp - &obuf[0]);
|
||||
opp = obuf; /* reset opp */
|
||||
sys_close(ofd);
|
||||
ofd = -1;
|
||||
}
|
||||
|
||||
C_busy()
|
||||
{
|
||||
return ofd >= 0; /* true if code is being generated */
|
||||
}
|
||||
|
||||
/*** front end for generating long CON/ROM lists ***/
|
||||
static arg_count;
|
||||
static arg_rom;
|
||||
|
||||
DC_start(rom){
|
||||
arg_count = 0;
|
||||
arg_rom = rom;
|
||||
}
|
||||
|
||||
DC_check(){
|
||||
if (arg_count++ >= MAX_ARG_CNT) {
|
||||
switch (arg_rom) {
|
||||
case ps_con:
|
||||
C_con_end();
|
||||
C_con_begin();
|
||||
break;
|
||||
case ps_rom:
|
||||
C_rom_end();
|
||||
C_rom_begin();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*** the compact code generating routines ***/
|
||||
#define fit16i(x) ((x) >= (long)0xFFFF8000 && (x) <= (long)0x00007FFF)
|
||||
#define fit8u(x) ((x) <= 0xFF) /* x is already unsigned */
|
||||
|
||||
put_ilb(l)
|
||||
label l;
|
||||
{
|
||||
if (fit8u(l)) {
|
||||
put8(sp_ilb1);
|
||||
put8((int)l);
|
||||
}
|
||||
else {
|
||||
put8(sp_ilb2);
|
||||
put16(l);
|
||||
}
|
||||
}
|
||||
|
||||
put_dlb(l)
|
||||
label l;
|
||||
{
|
||||
if (fit8u(l)) {
|
||||
put8(sp_dlb1);
|
||||
put8((int)l);
|
||||
}
|
||||
else {
|
||||
put8(sp_dlb2);
|
||||
put16(l);
|
||||
}
|
||||
}
|
||||
|
||||
put_cst(l)
|
||||
arith l;
|
||||
{
|
||||
if (l >= (arith) -sp_zcst0 && l < (arith) (sp_ncst0 - sp_zcst0)) {
|
||||
/* we can convert 'l' to an int because its value
|
||||
can be stored in a byte.
|
||||
*/
|
||||
put8((int) l + (sp_zcst0 + sp_fcst0));
|
||||
}
|
||||
else
|
||||
if (fit16i(l)) { /* the cast from long to int causes no trouble here */
|
||||
put8(sp_cst2);
|
||||
put16((int) l);
|
||||
}
|
||||
else {
|
||||
put8(sp_cst4);
|
||||
put32(l);
|
||||
}
|
||||
}
|
||||
|
||||
put_doff(l, v)
|
||||
label l;
|
||||
arith v;
|
||||
{
|
||||
if (v == 0)
|
||||
put_dlb(l);
|
||||
else {
|
||||
put8(sp_doff);
|
||||
put_dlb(l);
|
||||
put_cst(v);
|
||||
}
|
||||
}
|
||||
|
||||
put_noff(s, v)
|
||||
char *s;
|
||||
arith v;
|
||||
{
|
||||
if (v == 0)
|
||||
put_dnam(s);
|
||||
else {
|
||||
put8(sp_doff);
|
||||
put_dnam(s);
|
||||
put_cst(v);
|
||||
}
|
||||
}
|
||||
|
||||
put_dnam(s)
|
||||
char *s;
|
||||
{
|
||||
put8(sp_dnam);
|
||||
put_str(s);
|
||||
}
|
||||
|
||||
put_pnam(s)
|
||||
char *s;
|
||||
{
|
||||
put8(sp_pnam);
|
||||
put_str(s);
|
||||
}
|
||||
|
||||
#ifdef ____
|
||||
put_fcon(s, sz)
|
||||
char *s;
|
||||
arith sz;
|
||||
{
|
||||
put8(sp_fcon);
|
||||
put_cst(sz);
|
||||
put_str(s);
|
||||
}
|
||||
#endif ____
|
||||
|
||||
put_wcon(sp, v, sz) /* sp_icon, sp_ucon or sp_fcon with int repr */
|
||||
int sp;
|
||||
char *v;
|
||||
arith sz;
|
||||
{
|
||||
/* how 'bout signextension int --> long ??? */
|
||||
put8(sp);
|
||||
put_cst(sz);
|
||||
put_str(v);
|
||||
}
|
||||
|
||||
put_str(s)
|
||||
char *s;
|
||||
{
|
||||
register int len;
|
||||
|
||||
put_cst((arith) (len = strlen(s)));
|
||||
while (--len >= 0)
|
||||
put8(*s++);
|
||||
}
|
||||
|
||||
put_cstr(s)
|
||||
char *s;
|
||||
{
|
||||
register int len = prepare_string(s);
|
||||
|
||||
put8(sp_scon);
|
||||
put_cst((arith) len);
|
||||
while (--len >= 0)
|
||||
put8(*s++);
|
||||
}
|
||||
Reference in New Issue
Block a user