Initial revision
This commit is contained in:
parent
0f42cf1bd9
commit
9cb5c80981
143
modules/src/em_code/e/em.c
Normal file
143
modules/src/em_code/e/em.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
/* EM CODE OUTPUT ROUTINES */
|
||||
|
||||
#include <system.h>
|
||||
#include "em_private.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.
|
||||
*/
|
||||
|
||||
static File *ofp = 0;
|
||||
|
||||
C_open(nm) /* open file for readable code output */
|
||||
char *nm;
|
||||
{
|
||||
if (nm == 0)
|
||||
ofp = STDOUT; /* standard output */
|
||||
else
|
||||
if (sys_open(nm, OP_WRITE, &ofp) == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
C_close()
|
||||
{
|
||||
if (ofp != STDOUT)
|
||||
sys_close(ofp);
|
||||
ofp = 0;
|
||||
}
|
||||
|
||||
C_busy()
|
||||
{
|
||||
return ofp != 0; /* true if code is being generated */
|
||||
}
|
||||
|
||||
C_magic()
|
||||
{
|
||||
}
|
||||
|
||||
/*** the readable code generating routines ***/
|
||||
|
||||
put_ilb(l)
|
||||
label l;
|
||||
{
|
||||
_prnt("*%ld", (long) l);
|
||||
}
|
||||
|
||||
extern char em_mnem[][4];
|
||||
extern char em_pseu[][4];
|
||||
|
||||
put_op(x)
|
||||
{
|
||||
_prnt(" %s ", em_mnem[x - sp_fmnem]);
|
||||
}
|
||||
|
||||
put_cst(l)
|
||||
arith l;
|
||||
{
|
||||
_prnt("%ld", (long) l);
|
||||
}
|
||||
|
||||
put_scon(x, y)
|
||||
char *x;
|
||||
arith y;
|
||||
{
|
||||
char buf[1024];
|
||||
char sbuf[1024];
|
||||
register char *p, *q = &sbuf[0];
|
||||
char *bts2str();
|
||||
|
||||
p = bts2str(x, (int) y, buf);
|
||||
while (*p) {
|
||||
if (*p == '\'')
|
||||
*q++ = '\\';
|
||||
*q++ = *p++;
|
||||
}
|
||||
*q = '\0';
|
||||
_prnt("'%s'", buf);
|
||||
}
|
||||
|
||||
put_ps(x)
|
||||
{
|
||||
_prnt(" %s ", em_pseu[x - sp_fpseu]);
|
||||
}
|
||||
|
||||
put_dlb(l)
|
||||
label l;
|
||||
{
|
||||
_prnt(".%ld", (long) l);
|
||||
}
|
||||
|
||||
put_doff(l, v)
|
||||
label l;
|
||||
arith v;
|
||||
{
|
||||
if (v == 0) put_dlb(l);
|
||||
else _prnt(".%ld+%ld", (long) l, (long) v);
|
||||
}
|
||||
|
||||
put_noff(s, v)
|
||||
char *s;
|
||||
arith v;
|
||||
{
|
||||
if (v == 0) _prnt(s);
|
||||
else _prnt("%s+%ld", s, (long) v);
|
||||
}
|
||||
|
||||
put_pnam(s)
|
||||
char *s;
|
||||
{
|
||||
_prnt("$%s", s);
|
||||
}
|
||||
|
||||
put_dfilb(l)
|
||||
label l;
|
||||
{
|
||||
_prnt("%ld", (long) l);
|
||||
}
|
||||
|
||||
put_wcon(sp, v, sz) /* sp_icon, sp_ucon or sp_fcon with int repr */
|
||||
int sp;
|
||||
char *v;
|
||||
arith sz;
|
||||
{
|
||||
_prnt("%s%c%ld", v, sp == sp_icon ? 'I' : sp == sp_ucon ? 'U' : 'F',
|
||||
(long) sz);
|
||||
}
|
||||
|
||||
_prnt(fmt, args)
|
||||
char *fmt;
|
||||
int args;
|
||||
{
|
||||
doprnt(ofp, fmt, (int *)&args);
|
||||
}
|
||||
|
||||
put_nl() { _prnt("\n"); }
|
||||
put_comma() { _prnt(","); }
|
||||
put_ccend() { _prnt(" ?"); }
|
33
modules/src/em_code/e/em_private.h
Normal file
33
modules/src/em_code/e/em_private.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* private inclusion file */
|
||||
|
||||
#include <em_arith.h>
|
||||
#include <em_label.h>
|
||||
#include <em_code.h>
|
||||
|
||||
/* include the EM description files */
|
||||
#include <em_spec.h>
|
||||
#include <em_pseu.h>
|
||||
#include <em_mnem.h>
|
||||
#include <em_reg.h>
|
||||
|
||||
/* macros used in the definitions of the interface functions C_* */
|
||||
#define OP(x) put_op(x)
|
||||
#define CST(x) put_cst(x)
|
||||
#define DCST(x) put_cst(x)
|
||||
#define SCON(x,y) put_scon((x), (y))
|
||||
#define PS(x) put_ps(x)
|
||||
#define DLB(x) put_dlb(x)
|
||||
#define DFDLB(x) put_dlb(x)
|
||||
#define ILB(x) put_ilb(x)
|
||||
#define DFILB(x) put_dfilb(x)
|
||||
#define NOFF(x,y) put_noff((x), (y))
|
||||
#define DOFF(x,y) put_doff((x), (y))
|
||||
#define PNAM(x) put_pnam(x)
|
||||
#define DNAM(x) _prnt(x)
|
||||
#define DFDNAM(x) _prnt(x)
|
||||
#define CEND()
|
||||
#define CCEND() put_ccend()
|
||||
#define WCON(x,y,z) put_wcon((x), (y), (z))
|
||||
#define COMMA() put_comma()
|
||||
#define NL() put_nl()
|
||||
#define CILB(x) put_ilb(x)
|
106
modules/src/em_code/em.nogen
Normal file
106
modules/src/em_code/em.nogen
Normal file
|
@ -0,0 +1,106 @@
|
|||
% Definition of EM procedural interface: hand-written definitions
|
||||
|
||||
% C_open | char *:filename | <hand-written>
|
||||
% C_busy | | <hand-written>
|
||||
% C_close | | <hand-written>
|
||||
% C_magic | | <hand-written>
|
||||
|
||||
C_df_dlb | label:l | DFDLB(l); NL()
|
||||
C_df_dnam | char *:s | DFDNAM(s); NL()
|
||||
C_df_ilb | label:l | DFILB(l); NL()
|
||||
|
||||
C_pro | char *:s arith:l |
|
||||
PS(ps_pro); PNAM(s); COMMA(); CST(l); NL()
|
||||
C_pro_narg | char *:s |
|
||||
PS(ps_pro); PNAM(s); COMMA(); CCEND(); NL()
|
||||
C_end | arith:l | PS(ps_end); CST(l); NL()
|
||||
C_end_narg | | PS(ps_end); CCEND(); NL()
|
||||
|
||||
C_exa_dnam | char *:s | PS(ps_exa); DNAM(s); NL()
|
||||
C_exa_dlb | label:l | PS(ps_exa); DLB(l); NL()
|
||||
C_exp | char *:s | PS(ps_exp); PNAM(s); NL()
|
||||
C_ina_dnam | char *:s | PS(ps_ina); DNAM(s); NL()
|
||||
C_ina_dlb | label:l | PS(ps_ina); DLB(l); NL()
|
||||
C_inp | char *:s | PS(ps_inp); PNAM(s); NL()
|
||||
|
||||
C_bss_cst | arith:n arith:w int:i |
|
||||
PS(ps_bss); DCST(n); COMMA(); CST(w); COMMA(); CST((arith) i); NL()
|
||||
C_bss_icon | arith:n char *:s arith:sz int:i |
|
||||
PS(ps_bss); DCST(n); COMMA(); WCON(sp_icon, s, sz); COMMA(); CST((arith) i); NL()
|
||||
C_bss_ucon | arith:n char *:s arith:sz int:i |
|
||||
PS(ps_bss); DCST(n); COMMA(); WCON(sp_ucon, s, sz); COMMA(); CST((arith) i); NL()
|
||||
C_bss_fcon | arith:n char *:s arith:sz int:i |
|
||||
PS(ps_bss); DCST(n); COMMA(); WCON(sp_fcon, s, sz); COMMA(); CST((arith) i); NL()
|
||||
C_bss_dnam | arith:n char *:s arith:offs int:i |
|
||||
PS(ps_bss); DCST(n); COMMA(); NOFF(s, offs); COMMA(); CST((arith) i); NL()
|
||||
C_bss_dlb | arith:n label:l arith:offs int:i |
|
||||
PS(ps_bss); DCST(n); COMMA(); DOFF(l, offs); COMMA(); CST((arith) i); NL()
|
||||
C_bss_ilb | arith:n label:l int:i |
|
||||
PS(ps_bss); DCST(n); COMMA(); ILB(l); COMMA(); CST((arith) i); NL()
|
||||
C_bss_pnam | arith:n char *:s int:i |
|
||||
PS(ps_bss); DCST(n); COMMA(); PNAM(s); COMMA(); CST((arith) i); NL()
|
||||
|
||||
C_hol_cst | arith:n arith:w int:i |
|
||||
PS(ps_hol); DCST(n); COMMA(); CST(w); COMMA(); CST((arith) i); NL()
|
||||
C_hol_icon | arith:n char *:s arith:sz int:i |
|
||||
PS(ps_hol); DCST(n); COMMA(); WCON(sp_icon, s, sz); COMMA(); CST((arith) i); NL()
|
||||
C_hol_ucon | arith:n char *:s arith:sz int:i |
|
||||
PS(ps_hol); DCST(n); COMMA(); WCON(sp_ucon, s, sz); COMMA(); CST((arith) i); NL()
|
||||
C_hol_fcon | arith:n char *:s arith:sz int:i |
|
||||
PS(ps_hol); DCST(n); COMMA(); WCON(sp_fcon, s, sz); COMMA(); CST((arith) i); NL()
|
||||
C_hol_dnam | arith:n char *:s arith:offs int:i |
|
||||
PS(ps_hol); DCST(n); COMMA(); NOFF(s, offs); COMMA(); CST((arith) i); NL()
|
||||
C_hol_dlb | arith:n label:l arith:offs int:i |
|
||||
PS(ps_hol); DCST(n); COMMA(); DOFF(l, offs); COMMA(); CST((arith) i); NL()
|
||||
C_hol_ilb | arith:n label:l int:i |
|
||||
PS(ps_hol); DCST(n); COMMA(); ILB(l); COMMA(); CST((arith) i); NL()
|
||||
C_hol_pnam | arith:n char *:s int:i |
|
||||
PS(ps_hol); DCST(n); COMMA(); PNAM(s); COMMA(); CST((arith) i); NL()
|
||||
|
||||
C_con_cst | arith:l | PS(ps_con); CST(l); CEND(); NL()
|
||||
C_con_icon | char *:val arith:siz |
|
||||
PS(ps_con); WCON(sp_icon, val, siz); CEND(); NL()
|
||||
C_con_ucon | char *:val arith:siz |
|
||||
PS(ps_con); WCON(sp_ucon, val, siz); CEND(); NL()
|
||||
C_con_fcon | char *:val arith:siz |
|
||||
PS(ps_con); WCON(sp_fcon, val, siz); CEND(); NL()
|
||||
C_con_scon | char *:str arith:siz |
|
||||
PS(ps_con); SCON(str, siz); CEND(); NL()
|
||||
C_con_dnam | char *:str arith:val |
|
||||
PS(ps_con); NOFF(str, val); CEND(); NL()
|
||||
C_con_dlb | label:l arith:val |
|
||||
PS(ps_con); DOFF(l, val); CEND(); NL()
|
||||
C_con_ilb | label:l | PS(ps_con); ILB(l); CEND(); NL()
|
||||
C_con_pnam | char *:str | PS(ps_con); PNAM(str); CEND(); NL()
|
||||
|
||||
C_rom_cst | arith:l | PS(ps_rom); CST(l); CEND(); NL()
|
||||
C_rom_icon | char *:val arith:siz |
|
||||
PS(ps_rom); WCON(sp_icon, val, siz); CEND(); NL()
|
||||
C_rom_ucon | char *:val arith:siz |
|
||||
PS(ps_rom); WCON(sp_ucon, val, siz); CEND(); NL()
|
||||
C_rom_fcon | char *:val arith:siz |
|
||||
PS(ps_rom); WCON(sp_fcon, val, siz); CEND(); NL()
|
||||
C_rom_scon | char *:str arith:siz |
|
||||
PS(ps_rom); SCON(str, siz); CEND(); NL()
|
||||
C_rom_dnam | char *:str arith:val |
|
||||
PS(ps_rom); NOFF(str, val); CEND(); NL()
|
||||
C_rom_dlb | label:l arith:val |
|
||||
PS(ps_rom); DOFF(l, val); CEND(); NL()
|
||||
C_rom_ilb | label:l | PS(ps_rom); ILB(l); CEND(); NL()
|
||||
C_rom_pnam | char *:str | PS(ps_rom); PNAM(str); CEND(); NL()
|
||||
|
||||
C_cst | arith:l | COMMA(); CST(l)
|
||||
C_icon | char *:val arith:siz | COMMA(); WCON(sp_icon, val, siz)
|
||||
C_ucon | char *:val arith:siz | COMMA(); WCON(sp_ucon, val, siz)
|
||||
C_fcon | char *:val arith:siz | COMMA(); WCON(sp_fcon, val, siz)
|
||||
C_scon | char *:str arith:siz | COMMA(); SCON(str, siz)
|
||||
C_dnam | char *:str arith:val | COMMA(); NOFF(str, val)
|
||||
C_dlb | label:l arith:val | COMMA(); DOFF(l, val)
|
||||
C_ilb | label:l | COMMA(); ILB(l)
|
||||
C_pnam | char *:str | COMMA(); PNAM(str)
|
||||
|
||||
C_mes_begin | int:ms | PS(ps_mes); CST((arith)ms)
|
||||
C_mes_end | | CEND(); NL()
|
||||
|
||||
% Yes, there really is a C_exc routine...
|
||||
C_exc | arith:c1 arith:c2 | PS(ps_exc); CST(c1); COMMA(); CST(c2); NL()
|
408
modules/src/em_code/em_code.3X
Normal file
408
modules/src/em_code/em_code.3X
Normal file
|
@ -0,0 +1,408 @@
|
|||
.TH EM_CODE 3ACK "86/04/02"
|
||||
.SH NAME
|
||||
emcode \- EM code interface for compilers
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.B #include <em.h>
|
||||
.PP
|
||||
.B int C_open(filename)
|
||||
.B C_close()
|
||||
.B int C_busy()
|
||||
.B char *filename;
|
||||
.PP
|
||||
.B C_magic()
|
||||
.PP
|
||||
.B C_df_dlb(l)
|
||||
.B C_df_dnam(s)
|
||||
.B C_df_ilb(l)
|
||||
.B label l; char *s;
|
||||
.PP
|
||||
.B C_pro(s, l)
|
||||
.B C_pro_narg(s)
|
||||
.B C_end(l)
|
||||
.B C_end_narg()
|
||||
.B char *s; arith l;
|
||||
.PP
|
||||
.B C_exa_dlb(l)
|
||||
.B C_exa_dnam(s)
|
||||
.B C_exp(s)
|
||||
.B C_ina_dlb(l)
|
||||
.B C_ina_dnam(s)
|
||||
.B C_inp(s)
|
||||
.B char *s; label l;
|
||||
.PP
|
||||
.BI C_bss_ cstp ()
|
||||
.BI C_hol_ cstp ()
|
||||
.BI C_con_ cstp ()
|
||||
.BI C_rom_ cstp ()
|
||||
.PP
|
||||
.B #include <em_mes.h>
|
||||
.B C_mes_begin(ms)
|
||||
.BI C_ cstp ()
|
||||
.B C_mes_end()
|
||||
.B int ms;
|
||||
.PP
|
||||
.B C_exc(c1, c2)
|
||||
.B arith c1, c2;
|
||||
.PP
|
||||
.BI C_ mnem ()
|
||||
.BI C_ mnem _dlb()
|
||||
.BI C_ mnem _dnam()
|
||||
.BI C_ mnem _narg()
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
This package provides a procedural EM code interface to be used in
|
||||
compilers and other EM code producing programs.
|
||||
The basic idea behind this package is to simplify the program writer's task
|
||||
of producing EM code in any form, either compact or human-readable
|
||||
EM assembly code or a sequence of procedure calls.
|
||||
.PP
|
||||
The named types
|
||||
.B arith
|
||||
and
|
||||
.B label
|
||||
refer to types on the local
|
||||
machine that are suitable for doing arithmetics and storing EM numeric labels
|
||||
respectively.
|
||||
Common definitions are
|
||||
.B long
|
||||
for
|
||||
.B arith
|
||||
and
|
||||
.B
|
||||
unsigned int
|
||||
for
|
||||
.BR label .
|
||||
.PP
|
||||
.BI C_open( filename )
|
||||
should be invoked as initialiser for
|
||||
a sequence of calls that produce EM code on file
|
||||
.IR filename .
|
||||
When
|
||||
.I filename
|
||||
is a null pointer, the code is produced on standard output.
|
||||
Some implementations, such as fast back ends, may ignore the parameter.
|
||||
.B C_close
|
||||
causes some internal buffers to be flushed and the output file to be closed.
|
||||
All subsequent routines, except for
|
||||
.BR C_busy ,
|
||||
must be invoked between the calls to
|
||||
.B C_open
|
||||
and
|
||||
.BR C_close .
|
||||
.PP
|
||||
.B C_busy
|
||||
can be invoked in order
|
||||
to detect whether EM code is currently being generated, i.e. whether you are
|
||||
in between calls to
|
||||
.B C_open
|
||||
and
|
||||
.BR C_close .
|
||||
If this is the case,
|
||||
.B C_busy
|
||||
returns a 1.
|
||||
.PP
|
||||
.B C_magic()
|
||||
produces the EM magic word.
|
||||
.PP
|
||||
Two routines can be used to generate code for the definitions of global data
|
||||
labels:
|
||||
.BI C_df_dlb( l )
|
||||
for numeric labels
|
||||
.BI . l
|
||||
and
|
||||
.BI C_df_dnam( s )
|
||||
for alphanumeric labels
|
||||
.IR s .
|
||||
.PP
|
||||
.BI C_df_ilb( l )
|
||||
produces EM code for instruction label
|
||||
.IR l .
|
||||
.PP
|
||||
The routines for producing the EM procedure delimiters are:
|
||||
.PP
|
||||
.RS
|
||||
.TS
|
||||
box;
|
||||
l|l.
|
||||
routine EM pattern
|
||||
=
|
||||
\&\fBC_pro(\fP\fIs\fP\fB,\ \fP\fIl\fP\fB)\fP \fBpro\ \fP\fIs\fP\fB,\ \fP\fIl\fP
|
||||
_
|
||||
\&\fBC_pro_narg(\fP\fIs\fP\fB)\fP \fBpro\ \fP\fIs\fP\fB,\ ?\fP
|
||||
_
|
||||
\&\fBC_end(\fP\fIl\fP\fB)\fP \fBend\ \fP\fIl\fP
|
||||
_
|
||||
\&\fBC_end_narg()\fP \fBend\ ?\fP
|
||||
.TE
|
||||
.RE
|
||||
.PP
|
||||
A set of routines, concerning the scope definition pseudo instructions, is:
|
||||
.PP
|
||||
.RS
|
||||
.TS
|
||||
box;
|
||||
l|l.
|
||||
routine EM pattern
|
||||
=
|
||||
\&\fBC_exa_dnam(\fP\fIs\fP\fB)\fP \fBexa \fP\fIs\fP
|
||||
_
|
||||
\&\fBC_exa_dlb(\fP\fIl\fP\fB)\fP \fBexa .\fP\fIl\fP
|
||||
_
|
||||
\&\fBC_exp(\fP\fIs\fP\fB)\fP \fBexp $\fP\fIs\fP
|
||||
_
|
||||
\&\fBC_ina_dnam(\fP\fIs\fP\fB)\fP \fBina \fP\fIs\fP
|
||||
_
|
||||
\&\fBC_ina_dlb(\fP\fIl\fP\fB)\fP \fBina .\fP\fIl\fP
|
||||
_
|
||||
\&\fBC_inp(\fP\fIs\fP\fB)\fP \fBinp $\fP\fIs\fP
|
||||
.TE
|
||||
.RE
|
||||
.PP
|
||||
In the set of
|
||||
.B storage-declaration
|
||||
pseudo instructions, we can
|
||||
distinguish four groups, one for each type of storage declaration:
|
||||
.BR con ,
|
||||
.BR rom ,
|
||||
.B bss
|
||||
and
|
||||
.BR hol .
|
||||
.PP
|
||||
The
|
||||
.BR con / rom
|
||||
instructions are generated by
|
||||
.BI C_con_ cstp
|
||||
and
|
||||
.BI C_rom_ cstp ,
|
||||
respectively.
|
||||
The type of the initialization value and the number and type of the parameters
|
||||
are determined by
|
||||
.I cstp
|
||||
according to the following table:
|
||||
.PP
|
||||
.RS
|
||||
.TS
|
||||
box;
|
||||
l|l|l|l
|
||||
l|l|l|l
|
||||
l|n|l|l.
|
||||
\&\fIcstp\fP number of type of description
|
||||
parameters parameters
|
||||
=
|
||||
\&\fBcst\fP 1 \fBarith\fP word-sized integer of \fBarith\fP-type
|
||||
_
|
||||
\&\fBicon\fP 2 \fBchar *\fP integer in string representation
|
||||
\fBarith\fP number of bytes on target machine
|
||||
_
|
||||
\&\fBucon\fP 2 \fBchar *\fP unsigned integer in string representation
|
||||
\fBarith\fP number of bytes on target machine
|
||||
_
|
||||
\&\fBfcon\fP 2 \fBchar *\fP floating in string representation
|
||||
\fBarith\fP number of bytes on target machine
|
||||
_
|
||||
\&\fBscon\fP 2 \fBchar *\fP row of bytes
|
||||
\fBarith\fP length of the row of bytes
|
||||
_
|
||||
\&\fBdnam\fP 2 \fBchar *\fP alphanumeric global data label
|
||||
\fBarith\fP offset (possibly 0)
|
||||
_
|
||||
\&\fBdlb\fP 2 \fBlabel\fP numeric global data label
|
||||
\fBarith\fP offset (possibly 0)
|
||||
_
|
||||
\&\fBilb\fP 1 \fBlabel\fP instruction label
|
||||
_
|
||||
\&\fBpnam\fP 1 \fBchar *\fP procedure identifier
|
||||
.TE
|
||||
.RE
|
||||
.PP
|
||||
As an example of the use of the
|
||||
.BR con / rom
|
||||
routines, consider the
|
||||
following
|
||||
.B con
|
||||
instruction:
|
||||
.RS
|
||||
con 23I4, "hello world", .12, table + 12, *33
|
||||
.RE
|
||||
A sequence of calls to get this, is
|
||||
.RS
|
||||
.nf
|
||||
C_con_icon("23", (arith)4);
|
||||
C_con_scon("hello world");
|
||||
C_con_dlb((label)12, (arith)0);
|
||||
C_con_dnam("table", (arith)12);
|
||||
C_con_ilb((label)33);
|
||||
.fi
|
||||
.RE
|
||||
.PP
|
||||
A
|
||||
.B bss
|
||||
or
|
||||
.B hol
|
||||
instruction is produced by invoking
|
||||
.BI C_bss_ cstp
|
||||
or
|
||||
.BI C_hol_ cstp
|
||||
where
|
||||
.I cstp
|
||||
indicates the type of value that is used at initialisation.
|
||||
The parameter list of
|
||||
.BI C_bss_ cstp
|
||||
and
|
||||
.BI C_hol_ cstp
|
||||
is similar to that of the corresponding
|
||||
.BI C_con_ cstp,
|
||||
except that it is preceeded by an
|
||||
.BR arith -typed
|
||||
operand
|
||||
.I nbytes,
|
||||
and followed by an
|
||||
.BR int -typed
|
||||
operand
|
||||
.IR init ;
|
||||
.I nbytes
|
||||
indicates the number of bytes to reserve for the data;
|
||||
.I init
|
||||
has value 1 if the initialization is strictly necessary and 0 if not.
|
||||
Note that, according to the EM definition, an initialisation type of
|
||||
.B scon
|
||||
is not allowed in the
|
||||
.BR bss / hol
|
||||
instruction.
|
||||
.PP
|
||||
Another set of routines is that of the EM
|
||||
.B mes
|
||||
pseudo instructions.
|
||||
As there is an undefined number of messages and each type of message has
|
||||
its own number of parameters and each parameter its own type,
|
||||
the user is responsible for building his own message lists.
|
||||
Such a list consists of a list of
|
||||
.BI C_ cstp
|
||||
routine calls enclosed
|
||||
by
|
||||
.BI C_mes_begin( ms )
|
||||
where
|
||||
.I ms
|
||||
is the message number,
|
||||
and
|
||||
.BR C_mes_end() .
|
||||
.PP
|
||||
.I C_exc
|
||||
produces the EM
|
||||
.B exc
|
||||
.IR c1 , c2
|
||||
instruction.
|
||||
The use of this function may cause trouble in some implementations of this
|
||||
module.
|
||||
A fast back end, for instance, may refuse to implement
|
||||
.IR C_exc .
|
||||
The use of this function is therefore not recommended.
|
||||
.PP
|
||||
The final class of routines is that of the EM machine-instruction generating
|
||||
routines
|
||||
.BI C_ mnem,
|
||||
.BI C_ mnem _dlb ,
|
||||
.BI C_ mnem _dnam
|
||||
and
|
||||
.BI C_ mnem _narg .
|
||||
The best way to describe them is according to section 11.3 of [EM].
|
||||
Depending on the class of the argument (as indicated by a letter), one
|
||||
or more routines are available for each machine instruction.
|
||||
The following table gives an overview of the available routines for
|
||||
the EM machine instruction
|
||||
.IR mnem :
|
||||
.PP
|
||||
.RS
|
||||
.TS
|
||||
box;
|
||||
l|l|l|l
|
||||
l|l|l|l
|
||||
l|l|n|l.
|
||||
class routine(s) number of type of
|
||||
parameters parameter(s)
|
||||
=
|
||||
[\fBcdflnorsz\fP] \fBC_\fP\fImnem\fP 1 \fBarith\fP
|
||||
_
|
||||
\&\fBw\fP \fBC_\fP\fImnem\fP 1 \fBarith\fP
|
||||
\fBC_\fP\fImnem\fP\fB_narg\fP 0
|
||||
_
|
||||
\&\fBg\fP \fBC_\fP\fImnem\fP 1 \fBarith\fP
|
||||
\fBC_\fP\fImnem\fP\fB_dnam\fP 2 \fBchar *\fP
|
||||
\fBarith\fP
|
||||
\fBC_\fP\fImnem\fP\fB_dlb\fP 2 \fBlabel\fP
|
||||
\fBarith\fP
|
||||
_
|
||||
\&\fBp\fP \fBC_\fP\fImnem\fP 1 \fBchar *\fP
|
||||
_
|
||||
\&\fBb\fP \fBC_\fP\fImnem\fP 1 \fBlabel\fP
|
||||
_
|
||||
\&\fB\-\fP \fBC_\fP\fImnem\fP 0
|
||||
.TE
|
||||
.RE
|
||||
.PP
|
||||
The available routines for, for example, the EM machine instruction
|
||||
.B adi
|
||||
(with argument class
|
||||
.BR w )
|
||||
are
|
||||
.BI C_adi( w )
|
||||
for
|
||||
.B adi
|
||||
with a given argument, and
|
||||
.B C_adi_narg()
|
||||
for
|
||||
.B adi
|
||||
with an argument on top of the stack.
|
||||
Likewise are the available routines for
|
||||
.BR loe
|
||||
(which instruction has argument class
|
||||
.BR g ):
|
||||
.BI C_loe( g )
|
||||
where
|
||||
.I g
|
||||
is a constant,
|
||||
.BI C_loe_dnam( g , o )
|
||||
where
|
||||
.I g
|
||||
is an alphanumeric label, and
|
||||
.BI C_loe_dlb( g , o )
|
||||
where
|
||||
.I g
|
||||
is a numeric label.
|
||||
The latter two routines have the (possibly zero) offset
|
||||
.I o
|
||||
as second parameter.
|
||||
.SH FILES
|
||||
.nf
|
||||
~em/modules/h/em.h
|
||||
~em/modules/lib/libemk.a: library for generating compact EM code
|
||||
~em/modules/lib/libeme.a: library for generating human-readable EM code
|
||||
.fi
|
||||
.SH MODULES
|
||||
.nf
|
||||
libemk.a: system(3L), string(3L)
|
||||
libeme.a: print(3L), system(3L), string(3L)
|
||||
.fi
|
||||
.SH SEE ALSO
|
||||
read_em(3L), em_mes(3L)
|
||||
.SH REFERENCES
|
||||
.IP [EM] 6
|
||||
Andrew S. Tanenbaum, Hans van Staveren, Ed G. Keizer, Johan W. Stevenson,
|
||||
.B
|
||||
"Description of a Machine Architecture for use with Block Structured Languages",
|
||||
Informatica Rapport IR-81, Vrije Universiteit, Amsterdam, 1983.
|
||||
.LP
|
||||
.SH DIAGNOSTICS
|
||||
.I C_open
|
||||
returns 1 if the open is successful and 0 if not.
|
||||
The other routines do not give any information about their completion.
|
||||
.SH BUGS
|
||||
.IP \(bu
|
||||
Feel free to report them to the author.
|
||||
.IP \(bu
|
||||
It is not possible to indicate that the argument of
|
||||
.B C_con_cst ()
|
||||
must be seen as an unsigned value.
|
||||
.SH AUTHOR
|
||||
Erik Baalbergen <erikb@vu44.UUCP>
|
17
modules/src/em_code/make.em.gen
Executable file
17
modules/src/em_code/make.em.gen
Executable file
|
@ -0,0 +1,17 @@
|
|||
echo '% this part is generated from ../../../etc/em_table at: ' `date`
|
||||
ed - ../../../etc/em_table <<'EOI'
|
||||
1,/^$/d
|
||||
1,/^$/d
|
||||
1,$s/^\(...\) \(.\).*/\1:\2/
|
||||
g/:d/s/^\(...\):\(.\).*/C_\1 | arith:\2 | OP(op_\1); DCST(\2); NL()/
|
||||
g/:[cslnfzor]/s/^\(...\):\(.\).*/C_\1 | arith:\2 | OP(op_\1); CST(\2); NL()/
|
||||
g/:w/s/^\(...\).*/C_\1 | arith:w | OP(op_\1); CST(w); NL()\
|
||||
C_\1_narg | | OP(op_\1); CCEND(); NL()/
|
||||
g/:g/s/^\(...\).*/C_\1 | arith:g | OP(op_\1); CST(g); NL()\
|
||||
C_\1_dnam | char *:g arith:o | OP(op_\1); NOFF(g,o); NL()\
|
||||
C_\1_dlb | label:g arith:o | OP(op_\1); DOFF(g,o); NL()/
|
||||
g/:p/s/^\(...\).*/C_\1 | char *:p | OP(op_\1); PNAM(p); NL()/
|
||||
g/:b/s/^\(...\).*/C_\1 | label:b | OP(op_\1); CILB(b); NL()/
|
||||
g/:-/s/^\(...\).*/C_\1 | | OP(op_\1); NL()/
|
||||
1,$p
|
||||
EOI
|
51
modules/src/em_code/make.fun
Executable file
51
modules/src/em_code/make.fun
Executable file
|
@ -0,0 +1,51 @@
|
|||
TMP=tmp$$
|
||||
cat $* >$TMP
|
||||
ed - $TMP <<'--EOI--'
|
||||
g/^%/d
|
||||
g/^$/d
|
||||
g/^ /.-1,.j
|
||||
1,$s/[ ]*|[ ]*/|/g
|
||||
g/NOTIMPLEMENTED/d
|
||||
1,$s/\([^|]*\)|\([^|]*\)|\(.*\)$/\
|
||||
NAME \1\
|
||||
HEAD \1\
|
||||
PLST \2\
|
||||
DECL \2\
|
||||
BODY \3/
|
||||
$a
|
||||
END
|
||||
.
|
||||
g/^NAME/m$
|
||||
g/^PLST/s/[ ][ ]*\([^:]*\):\([^ ]*\)/,\2/g
|
||||
g/^PLST,/s//PLST /
|
||||
g/^PLST /s/^PLST \(.*\)$/(\1)/
|
||||
g/^HEAD/.,.+1j
|
||||
g/^HEAD /s/^HEAD \([^(]*\)\(.*\)$/cat >\1.c <<'--EOF--'\
|
||||
#include "em_private.h"\
|
||||
\
|
||||
\1\2/
|
||||
g/^DECL/s/[ ][ ]*\([^:]*\):\([^ ]*\)/\
|
||||
\1 \2;/g
|
||||
g/^DECL/d
|
||||
g/^BODY/s/^BODY \(.*\)$/{\
|
||||
\1;\
|
||||
}\
|
||||
--EOF--/
|
||||
1,/^END/-1p
|
||||
1,/^END/d
|
||||
g:^NAME:s:^NAME \(.*\)$:cc -c -O -I$1 -I../../h -I../../../h \1.c:
|
||||
1i
|
||||
cat >make.sh <<'--EOF--'
|
||||
: script for making lib
|
||||
rm -f *.o
|
||||
.
|
||||
$a
|
||||
cc -c -O -I$1 -I../../h -I../../../h $1/em.c
|
||||
mv em.o em$1.o
|
||||
rm -f libem$1.a
|
||||
ar rc libem$1.a *.o
|
||||
--EOF--
|
||||
.
|
||||
1,$p
|
||||
--EOI--
|
||||
rm -f $TMP
|
Loading…
Reference in a new issue