new version, different interface

This commit is contained in:
ceriel 1987-06-30 12:55:30 +00:00
parent f6a828b183
commit 0c5b54219e
12 changed files with 634 additions and 649 deletions

View file

@ -4,6 +4,7 @@ argtype
em_comp.h
m_C_mnem
m_C_mnem_na
m_C_funcs
mkcalls.c
read_em.3
read_em.c

View file

@ -6,6 +6,11 @@
/* Variables must be declared somewhere ... */
#include <em_arith.h>
char *EM_error;
char *EM_filename;
unsigned int EM_lineno;
int EM_wordsize, EM_pointersize;
arith em_holorbsssize;
int em_holorbssinit;

View file

@ -48,13 +48,13 @@ cmp: all
$(COMPARE) man/read_em.3
pr:
@pr Makefile m_C_mnem m_C_mnem_na argtype $(SRCFILES)
@pr Makefile m_C_funcs m_C_mnem m_C_mnem_na argtype $(SRCFILES)
opr:
make pr | opr
clean:
rm -f *.o *.a C_mnem C_mnem_narg
rm -f *.o *.a C_funcs C_mnem C_mnem_narg
libread_emk.a: $(K_OFILES)
ar r libread_emk.a $(K_OFILES)
@ -80,11 +80,11 @@ read_emeV.o: read_em.c em_comp.h reade.c
$(CC) -c $(CFLAGS) -DCHECKING read_em.c
mv read_em.o read_emeV.o
makecalls.o: C_mnem C_mnem_narg em_comp.h mkcalls.c
makecalls.o: C_funcs C_mnem C_mnem_narg em_comp.h mkcalls.c
$(CC) -c $(CFLAGS) mkcalls.c
mv mkcalls.o makecalls.o
makecallsV.o: C_mnem C_mnem_narg em_comp.h mkcalls.c
makecallsV.o: C_funcs C_mnem C_mnem_narg em_comp.h mkcalls.c
$(CC) -c $(CFLAGS) -DCHECKING mkcalls.c
mv mkcalls.o makecallsV.o
@ -94,7 +94,10 @@ C_mnem: m_C_mnem argtype
C_mnem_narg: m_C_mnem_na argtype
sh m_C_mnem_na > C_mnem_narg
lintlib: C_mnem C_mnem_narg
C_funcs: m_C_funcs argtype
sh m_C_funcs > C_funcs
lintlib: C_mnem C_mnem_narg C_funcs
lint $(INCLUDES) $(DEFINES) -DCOMPACT -DCHECKING -Cread_emkV $(KSRCFILES)
lint $(INCLUDES) $(DEFINES) -DCHECKING -Cread_emeV $(ESRCFILES)
mv llib-lread_emeV.ln llib-lread_emkV.ln $(MODULES)/lib

View file

@ -4,6 +4,26 @@
*/
/* $Header$ */
struct e_arg {
int ems_argtype; /* type of this argument */
union e_simple_arg {
arith emu_cst; /* a cst */
label emu_dlb; /* a numeric data label */
label emu_ilb; /* an instruction label */
char *emu_dnam; /* a data label */
char *emu_pnam; /* a procedure name */
char *emu_string; /* a string (fcon,icon,ucon,scon) */
} ems_arg;
arith ems_szoroff;
};
#define ema_cst ems_arg.emu_cst
#define ema_dlb ems_arg.emu_dlb
#define ema_ilb ems_arg.emu_ilb
#define ema_dnam ems_arg.emu_dnam
#define ema_pnam ems_arg.emu_pnam
#define ema_string ems_arg.emu_string
struct e_instr {
int em_type; /* Type of this instr */
#define EM_MNEM 256 /* A machine instruction */
@ -16,54 +36,36 @@ struct e_instr {
#define EM_DEFDNAM 263 /* A non-numeric data label def */
#define EM_ERROR 264 /* Recoverable error */
#define EM_FATAL 265 /* Unrecoverable error */
union {
struct {
int emus_opcode; /* Opcode of instruction */
struct e_args *emus_args; /* Arguments of instruction */
} emu_mp;
label emu_deflb; /* Numeric label definition */
char *emu_defdnam; /* Non-numeric label definition */
struct e_args *emu_arg; /* For an argument */
} em_i;
#define em_opcode em_i.emu_mp.emus_opcode
#define em_args em_i.emu_mp.emus_args
#define em_deflb em_i.emu_deflb
#define em_defdnam em_i.emu_defdnam
#define em_arg em_i.emu_arg
#define EM_EOF 266 /* End of file */
int em_opcode;
struct e_arg em_arg;
};
struct e_args {
struct e_args *em_next; /* Next argument */
short em_argtype; /* Type of this argument */
union {
arith emu_cst; /* A constant */
label emu_ilb; /* An instruction label */
char *emu_pnam; /* A procedure name (not including '$') */
struct {
label emus_dlb;
arith emus_noff;
} emu_ndlb; /* Numeric data label + offset */
struct {
char *emus_dnam;
arith emus_soff;
} emu_sdlb; /* String data label + offset */
struct {
char *emus_str;
arith emus_size;
} emu_con; /* An scon, icon, ucon or fcon */
} em_value;
#define em_cst em_value.emu_cst
#define em_ilb em_value.emu_ilb
#define em_pnam em_value.emu_pnam
#define em_dlb em_value.emu_ndlb.emus_dlb
#define em_noff em_value.emu_ndlb.emus_noff
#define em_dnam em_value.emu_sdlb.emus_dnam
#define em_soff em_value.emu_sdlb.emus_soff
#define em_str em_value.emu_con.emus_str
#define em_size em_value.emu_con.emus_size
};
extern arith
em_holorbsssize;
extern int
em_holorbssinit;
extern char *EM_error;
extern unsigned int EM_lineno;
extern char *EM_filename;
extern int EM_wordsize, EM_pointersize;
#define em_ilb em_arg.ema_ilb
#define em_dlb em_arg.ema_dlb
#define em_dnam em_arg.ema_dnam
#define em_argtype em_arg.ems_argtype
#define em_cst em_arg.ema_cst
#define em_pnam em_arg.ema_pnam
#define em_string em_arg.ema_string
#define em_off em_arg.ems_szoroff
#define em_size em_arg.ems_szoroff
#define em_exc1 em_arg.ema_cst
#define em_exc2 em_arg.ems_szoroff
#define em_holsize em_holorbsssize
#define em_bsssize em_holorbsssize
#define em_holinit em_holorbssinit
#define em_bssinit em_holorbssinit
extern char
*EM_error, *EM_filename;
extern unsigned int
EM_lineno;
extern int
EM_wordsize, EM_pointersize;

25
modules/src/read_em/m_C_funcs Executable file
View file

@ -0,0 +1,25 @@
EM_TABLE=../../../etc/em_table
ed - $EM_TABLE << EOF
1,/^\$/d
1,/^\$/d
1,\$s/^\(...\).*/int C_\\1();/
w blabla1
q
EOF
ed - $EM_TABLE << A
1,/^\$/d
1,/^\$/d
/^\$/d
1,\$s/^\(...\).*/C_\\1,/
\$a
};
.
1i
static int (*C_funcs[])() = {
0,
.
w blabla2
q
A
cat blabla1 blabla2 > C_funcs
rm blabla1 blabla2

View file

@ -1,5 +1,6 @@
EM_TABLE=../../../etc/em_table
echo "switch(opcode) {"
echo "switch(p->em_opcode) {"
echo ' default: EM_error = "Illegal mnemonic"; break;'
for i in - cdflnorswz p b
do
list=`./argtype $i $EM_TABLE`
@ -8,62 +9,56 @@ do
echo " /* no arguments */"
;;
cdflnorswz)
args='(arg->em_cst)'
args='(p->em_cst)'
echo " /* one integer constant argument */"
;;
p)
args='(arg->em_pnam)'
args='(p->em_pnam)'
echo " /* a procedure name argument */"
;;
b)
: Grumbl, an instruction label as argument is encoded in a sp_cst2
args='((label) (arg->em_cst))'
args='((label) (p->em_cst))'
echo " /* An instruction label argument */"
;;
esac
for i in $list
do
cat << EOF
case op_$i:
C_$i$args;
break;
EOF
echo " case op_$i:"
done
echo " (*C_funcs[p->em_opcode])$args; break;"
done
list=`./argtype g $EM_TABLE`
for i in $list
do
echo " case op_$i:"
done
cat << 'EOF'
default:
/* a "g" argument */
if (arg->em_argtype == nof_ptyp) {
switch(opcode) {
default:
EM_error = "Illegal mnemonic";
break;
if (p->em_argtype == nof_ptyp) {
switch(p->em_opcode) {
EOF
for i in $list
do
cat << EOF
case op_$i:
C_${i}_dlb(arg->em_dlb, arg->em_noff);
C_${i}_dlb(p->em_dlb, p->em_off);
break;
EOF
done
cat << 'EOF'
}
}
else if (arg->em_argtype == sof_ptyp) {
switch(opcode) {
default:
EM_error = "Illegal mnemonic";
break;
else if (p->em_argtype == sof_ptyp) {
switch(p->em_opcode) {
EOF
for i in $list
do
cat << EOF
case op_$i:
C_${i}_dnam(arg->em_dnam, arg->em_soff);
C_${i}_dnam(p->em_dnam, p->em_off);
break;
EOF
done
@ -71,21 +66,8 @@ cat << 'EOF'
}
}
else /*argtype == cst_ptyp */ {
switch(opcode) {
default:
EM_error = "Illegal mnemonic";
(*C_funcs[p->em_opcode])(p->em_cst);
break;
EOF
for i in $list
do
cat << EOF
case op_$i:
C_$i(arg->em_cst);
break;
EOF
done
cat << 'EOF'
}
}
}
EOF

View file

@ -1,6 +1,6 @@
EM_TABLE=../../../etc/em_table
list=`./argtype w $EM_TABLE`
echo "switch(opcode) {"
echo "switch(p->em_opcode) {"
for i in $list
do
cat << EOF

View file

@ -21,6 +21,8 @@
extern char em_flag[]; /* One per EM instruction: indicates parameter kind */
extern short em_ptyp[]; /* One per parameter kind: indicates parameter type */
#include "C_funcs"
static int listtype = 0; /* indicates pseudo when generating code for
variable length argument lists
(only for MES)
@ -31,45 +33,41 @@ static int listtype = 0; /* indicates pseudo when generating code for
The argument must be of a type allowed by "typset".
Return a pointer to the next argument.
*/
PRIVATE struct e_args *
c_getarg(args, typset)
register struct e_args *args;
PRIVATE
checkarg(arg, typset)
register struct e_arg *arg;
{
if (((!typset) && args) ||
((!args) && typset)) {
if (((!typset) && arg->ems_argtype) ||
((!arg->ems_argtype) && typset)) {
/* End of arguments expected, but there are more, or
an argument expected, but there is none
*/
EM_error = "Illegal number of parameters";
return 0;
return;
}
if (!args) return 0;
if (!(args->em_argtype & typset)) {
if (!(arg->ems_argtype & typset)) {
/* Type error */
EM_error = "Illegal parameter type";
}
return args->em_next;
}
#else not CHECKING
#define c_getarg(arg, x) ((arg) ? (arg)->em_next : (arg))
#define c_getarg(arg, x)
#endif CHECKING
/* EM_doinstr: An EM instruction
*/
PRIVATE
EM_doinstr(opcode, arg)
register struct e_args *arg;
EM_doinstr(p)
register struct e_instr *p;
{
register int parametertype; /* parametertype of the instruction */
register struct e_args *args;
parametertype = em_flag[opcode-sp_fmnem] & EM_PAR;
parametertype = em_flag[p->em_opcode-sp_fmnem] & EM_PAR;
#ifdef CHECKING
if (parametertype != PAR_NO && parametertype != PAR_W) {
if (!arg) {
if (p->em_argtype == 0) {
EM_error = "Illegal number of parameters";
return;
}
@ -79,13 +77,11 @@ EM_doinstr(opcode, arg)
case PAR_NO:
break;
default:
args = c_getarg(arg, em_ptyp[parametertype]);
args = c_getarg(args, 0);
checkarg(&(p->em_arg), em_ptyp[parametertype]);
break;
case PAR_W:
if (arg) {
args = c_getarg(arg, cst_ptyp);
args = c_getarg(args, 0);
if (p->em_argtype != 0) {
checkarg(&(p->em_arg), cst_ptyp);
}
else {
#include "C_mnem_narg"
@ -97,73 +93,62 @@ EM_doinstr(opcode, arg)
}
PRIVATE
EM_dopseudo(opcode, args)
register struct e_args *args;
EM_dopseudo(p)
register struct e_instr *p;
{
register struct e_args *arg;
switch(opcode) {
switch(p->em_opcode) {
case ps_exc: {
register struct e_args *args2;
arg = c_getarg(args, cst_ptyp);
args2 = c_getarg(arg, cst_ptyp);
args2 = c_getarg(args2, 0);
C_exc(args->em_cst, arg->em_cst);
C_exc(p->em_exc1, p->em_exc2);
break;
}
case ps_hol: {
register struct e_args *args2, *args3;
arg = c_getarg(args, cst_ptyp);
args2 = c_getarg(arg, par_ptyp);
args3 = c_getarg(args2, cst_ptyp);
args3 = c_getarg(args3, 0);
switch(arg->em_argtype) {
checkarg(&(p->em_arg), par_ptyp);
switch(p->em_argtype) {
case cst_ptyp:
C_hol_cst(args->em_cst,
arg->em_cst,
(int) (args2->em_cst));
C_hol_cst(em_holsize,
p->em_cst,
em_holinit);
break;
case ico_ptyp:
C_hol_icon(args->em_cst,
arg->em_str,
arg->em_size,
(int)(args2->em_cst));
C_hol_icon(em_holsize,
p->em_string,
p->em_size,
em_holinit);
break;
case uco_ptyp:
C_hol_ucon(args->em_cst,
arg->em_str,
arg->em_size,
(int)(args2->em_cst));
C_hol_ucon(em_holsize,
p->em_string,
p->em_size,
em_holinit);
break;
case fco_ptyp:
C_hol_fcon(args->em_cst,
arg->em_str,
arg->em_size,
(int)(args2->em_cst));
C_hol_fcon(em_holsize,
p->em_string,
p->em_size,
em_holinit);
break;
case sof_ptyp:
C_hol_dnam(args->em_cst,
arg->em_dnam,
arg->em_soff,
(int)(args2->em_cst));
C_hol_dnam(em_holsize,
p->em_dnam,
p->em_off,
em_holinit);
break;
case nof_ptyp:
C_hol_dlb(args->em_cst,
arg->em_dlb,
arg->em_noff,
(int)(args2->em_cst));
C_hol_dlb(em_holsize,
p->em_dlb,
p->em_off,
em_holinit);
break;
case ilb_ptyp:
C_hol_ilb(args->em_cst,
arg->em_ilb,
(int)(args2->em_cst));
C_hol_ilb(em_holsize,
p->em_ilb,
em_holinit);
break;
case pro_ptyp:
C_hol_pnam(args->em_cst,
arg->em_pnam,
(int)(args2->em_cst));
C_hol_pnam(em_holsize,
p->em_pnam,
em_holinit);
break;
default:
EM_error = "Illegal parameter type";
@ -172,57 +157,52 @@ EM_dopseudo(opcode, args)
break;
}
case ps_bss: {
register struct e_args *args2, *args3;
arg = c_getarg(args, cst_ptyp);
args2 = c_getarg(arg, par_ptyp);
args3 = c_getarg(args2, cst_ptyp);
args3 = c_getarg(args3, 0);
switch(arg->em_argtype) {
checkarg(&(p->em_arg), par_ptyp);
switch(p->em_argtype) {
case cst_ptyp:
C_bss_cst(args->em_cst,
arg->em_cst,
(int)(args2->em_cst));
C_bss_cst(em_bsssize,
p->em_cst,
em_bssinit);
break;
case ico_ptyp:
C_bss_icon(args->em_cst,
arg->em_str,
arg->em_size,
(int)(args2->em_cst));
C_bss_icon(em_bsssize,
p->em_string,
p->em_size,
em_bssinit);
break;
case uco_ptyp:
C_bss_ucon(args->em_cst,
arg->em_str,
arg->em_size,
(int)(args2->em_cst));
C_bss_ucon(em_bsssize,
p->em_string,
p->em_size,
em_bssinit);
break;
case fco_ptyp:
C_bss_fcon(args->em_cst,
arg->em_str,
arg->em_size,
(int)(args2->em_cst));
C_bss_fcon(em_bsssize,
p->em_string,
p->em_size,
em_bssinit);
break;
case sof_ptyp:
C_bss_dnam(args->em_cst,
arg->em_dnam,
arg->em_soff,
(int)(args2->em_cst));
C_bss_dnam(em_bsssize,
p->em_dnam,
p->em_off,
em_bssinit);
break;
case nof_ptyp:
C_bss_dlb(args->em_cst,
arg->em_dlb,
arg->em_noff,
(int)(args2->em_cst));
C_bss_dlb(em_bsssize,
p->em_dlb,
p->em_off,
em_bssinit);
break;
case ilb_ptyp:
C_bss_ilb(args->em_cst,
arg->em_ilb,
(int)(args2->em_cst));
C_bss_ilb(em_bsssize,
p->em_ilb,
em_bssinit);
break;
case pro_ptyp:
C_bss_pnam(args->em_cst,
arg->em_pnam,
(int)(args2->em_cst));
C_bss_pnam(em_bsssize,
p->em_pnam,
em_bssinit);
break;
default:
EM_error = "Illegal parameter type";
@ -231,80 +211,72 @@ EM_dopseudo(opcode, args)
break;
}
case ps_end:
if (args) {
arg = c_getarg(args, cst_ptyp);
arg = c_getarg(arg, 0);
C_end(args->em_cst);
if (p->em_argtype != 0) {
checkarg(&(p->em_arg), cst_ptyp);
C_end(p->em_cst);
break;
}
C_end_narg();
break;
case ps_exa:
case ps_ina:
arg = c_getarg(args, lab_ptyp);
arg = c_getarg(arg, 0);
if (args->em_argtype == nof_ptyp) {
if (opcode == ps_exa) {
C_exa_dlb(args->em_dlb);
checkarg(&(p->em_arg), lab_ptyp);
if (p->em_argtype == nof_ptyp) {
if (p->em_opcode == ps_exa) {
C_exa_dlb(p->em_dlb);
}
else C_ina_dlb(args->em_dlb);
else C_ina_dlb(p->em_dlb);
break;
}
if (opcode == ps_exa) {
C_exa_dnam(args->em_dnam);
if (p->em_opcode == ps_exa) {
C_exa_dnam(p->em_dnam);
}
else C_ina_dnam(args->em_dnam);
else C_ina_dnam(p->em_dnam);
break;
case ps_exp:
checkarg(&(p->em_arg), pro_ptyp);
C_exp(p->em_pnam);
break;
case ps_inp:
arg = c_getarg(args, pro_ptyp);
arg = c_getarg(arg, 0);
if (opcode == ps_exp) {
C_exp(args->em_pnam);
}
else C_inp(args->em_pnam);
checkarg(&(p->em_arg), pro_ptyp);
C_inp(p->em_pnam);
break;
case ps_pro:
arg = c_getarg(args, pro_ptyp);
if (arg) {
struct e_args *args2;
args2 = c_getarg(arg, cst_ptyp);
args2 = c_getarg(args2, 0);
C_pro(args->em_pnam, arg->em_cst);
checkarg(&(p->em_arg), pro_ptyp);
if (p->em_size >= 0) {
C_pro(p->em_pnam, p->em_size);
}
else C_pro_narg(args->em_pnam);
else C_pro_narg(p->em_pnam);
break;
case ps_con:
arg = c_getarg(args, val_ptyp);
arg = c_getarg(arg, 0);
switch(args->em_argtype) {
checkarg(&(p->em_arg), val_ptyp);
switch(p->em_argtype) {
case ilb_ptyp:
C_con_ilb(args->em_ilb);
C_con_ilb(p->em_ilb);
break;
case nof_ptyp:
C_con_dlb(args->em_dlb, args->em_noff);
C_con_dlb(p->em_dlb, p->em_off);
break;
case sof_ptyp:
C_con_dnam(args->em_dnam, args->em_soff);
C_con_dnam(p->em_dnam, p->em_off);
break;
case cst_ptyp:
C_con_cst(args->em_cst);
C_con_cst(p->em_cst);
break;
case pro_ptyp:
C_con_pnam(args->em_pnam);
C_con_pnam(p->em_pnam);
break;
case str_ptyp:
C_con_scon(args->em_str, args->em_size);
C_con_scon(p->em_string, p->em_size);
break;
case ico_ptyp:
C_con_icon(args->em_str, args->em_size);
C_con_icon(p->em_string, p->em_size);
break;
case uco_ptyp:
C_con_ucon(args->em_str, args->em_size);
C_con_ucon(p->em_string, p->em_size);
break;
case fco_ptyp:
C_con_fcon(args->em_str, args->em_size);
C_con_fcon(p->em_string, p->em_size);
break;
default:
EM_error = "Illegal argument type";
@ -312,35 +284,34 @@ EM_dopseudo(opcode, args)
}
break;
case ps_rom:
arg = c_getarg(args, val_ptyp);
arg = c_getarg(arg, 0);
switch(args->em_argtype) {
checkarg(&(p->em_arg), val_ptyp);
switch(p->em_argtype) {
case ilb_ptyp:
C_rom_ilb(args->em_ilb);
C_rom_ilb(p->em_ilb);
break;
case nof_ptyp:
C_rom_dlb(args->em_dlb, args->em_noff);
C_rom_dlb(p->em_dlb, p->em_off);
break;
case sof_ptyp:
C_rom_dnam(args->em_dnam, args->em_soff);
C_rom_dnam(p->em_dnam, p->em_off);
break;
case cst_ptyp:
C_rom_cst(args->em_cst);
C_rom_cst(p->em_cst);
break;
case pro_ptyp:
C_rom_pnam(args->em_pnam);
C_rom_pnam(p->em_pnam);
break;
case str_ptyp:
C_rom_scon(args->em_str, args->em_size);
C_rom_scon(p->em_string, p->em_size);
break;
case ico_ptyp:
C_rom_icon(args->em_str, args->em_size);
C_rom_icon(p->em_string, p->em_size);
break;
case uco_ptyp:
C_rom_ucon(args->em_str, args->em_size);
C_rom_ucon(p->em_string, p->em_size);
break;
case fco_ptyp:
C_rom_fcon(args->em_str, args->em_size);
C_rom_fcon(p->em_string, p->em_size);
break;
default:
EM_error = "Illegal argument type";
@ -354,40 +325,37 @@ EM_dopseudo(opcode, args)
}
PRIVATE
EM_docon(args)
register struct e_args *args;
EM_docon(p)
register struct e_instr *p;
{
register struct e_args *arg;
arg = c_getarg(args, val_ptyp);
arg = c_getarg(arg, 0);
switch(args->em_argtype) {
checkarg(&(p->em_arg), val_ptyp);
switch(p->em_argtype) {
case ilb_ptyp:
C_ilb(args->em_ilb);
C_ilb(p->em_ilb);
break;
case nof_ptyp:
C_dlb(args->em_dlb, args->em_noff);
C_dlb(p->em_dlb, p->em_off);
break;
case sof_ptyp:
C_dnam(args->em_dnam, args->em_soff);
C_dnam(p->em_dnam, p->em_off);
break;
case cst_ptyp:
C_cst(args->em_cst);
C_cst(p->em_cst);
break;
case pro_ptyp:
C_pnam(args->em_pnam);
C_pnam(p->em_pnam);
break;
case str_ptyp:
C_scon(args->em_str, args->em_size);
C_scon(p->em_string, p->em_size);
break;
case ico_ptyp:
C_icon(args->em_str, args->em_size);
C_icon(p->em_string, p->em_size);
break;
case uco_ptyp:
C_ucon(args->em_str, args->em_size);
C_ucon(p->em_string, p->em_size);
break;
case fco_ptyp:
C_fcon(args->em_str, args->em_size);
C_fcon(p->em_string, p->em_size);
break;
default:
EM_error = "Illegal argument type";
@ -396,18 +364,16 @@ EM_docon(args)
}
PRIVATE
EM_dostartmes(args)
register struct e_args *args;
EM_dostartmes(p)
register struct e_instr *p;
{
register struct e_args *arg;
if (listtype) {
EM_error = "Message not ended";
return;
}
arg = c_getarg(args, cst_ptyp);
arg = c_getarg(arg, 0);
C_mes_begin((int) (args->em_cst));
checkarg(&(p->em_arg), cst_ptyp);
C_mes_begin((int) (p->em_cst));
listtype = ps_mes;
}
@ -429,27 +395,27 @@ EM_mkcalls(line)
break;
case EM_MNEM:
/* normal instruction */
EM_doinstr(line->em_opcode, line->em_args);
EM_doinstr(line);
break;
case EM_DEFILB:
/* defining occurrence of an instruction label */
C_df_ilb(line->em_deflb);
C_df_ilb(line->em_ilb);
break;
case EM_DEFDLB:
/* defining occurrence of a global data label */
C_df_dlb(line->em_deflb);
C_df_dlb(line->em_dlb);
break;
case EM_DEFDNAM:
/* defining occurrence of a non-numeric data label */
C_df_dnam(line->em_defdnam);
C_df_dnam(line->em_dnam);
break;
case EM_PSEU:
/* pseudo */
EM_dopseudo(line->em_opcode, line->em_args);
EM_dopseudo(line);
break;
case EM_STARTMES:
/* start of a MES pseudo */
EM_dostartmes(line->em_arg);
EM_dostartmes(line);
break;
case EM_MESARG:
case EM_ENDMES:
@ -460,7 +426,7 @@ EM_mkcalls(line)
}
#endif
if (line->em_type == EM_MESARG) {
EM_docon(line->em_arg);
EM_docon(line);
break;
}
C_mes_end();

View file

@ -24,7 +24,8 @@ EM_mkcalls\ \-\ a module to read EM assembly code
.br
.B char *filename;
.PP
.B struct e_instr *EM_getinstr()
.B int EM_getinstr(instr)
.B struct e_instr *instr;
.PP
.B int EM_mkcalls(instr)
.br
@ -51,65 +52,83 @@ with an error message in \fIEM_error\fR.
\fIEM_close\fR must be called after all other calls to this package.
.PP
\fIEM_getinstr\fR reads an EM instruction, and
returns it as a pointer to a structure having the following
layout:
returns it in the structure pointed to by \fIinstr\fR.
This structure has the following layout:
.br
.PP
.ta \w'struct'u +\w'struct e_instr *\ \ \ \ \ \ \ \ \ 'u +\w'em_argtype\ \ \ \ \ \ 'u
.ta \w'struct\ \ \ 'u +\w'struct e_instr *\ \ \ \ \ \ 'u +\w'em_opcode\ \ \ 'u +\w'*emu_string\ \ \ 'u
.nf
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
struct e_arg {
int ems_argtype; /* type of this argument */
union e_simple_arg {
arith emu_cst; /* a cst */
label emu_dlb; /* a numeric data label */
label emu_ilb; /* an instruction label */
char *emu_dnam; /* a data label */
char *emu_pnam; /* a procedure name */
char *emu_string; /* a string (fcon,icon,ucon,scon) */
} ems_arg;
arith ems_szoroff;
};
#define ema_cst ems_arg.emu_cst
#define ema_dlb ems_arg.emu_dlb
#define ema_ilb ems_arg.emu_ilb
#define ema_dnam ems_arg.emu_dnam
#define ema_pnam ems_arg.emu_pnam
#define ema_string ems_arg.emu_string
struct e_instr {
int em_type; /* Type of this instruction */
union {
struct {
int emus_opcode; /* Opcode of instruction */
struct e_args *emus_args; /* Arguments of instruction */
} emu_mp;
label emu_deflb; /* Numeric label definition */
char *emu_defdnam; /* Non-numeric label definition */
struct e_args *emu_arg; /* For a message argument */
} em_i;
#define em_opcode \kaem_i.emu_mp.emus_opcode
#define em_args\h'|\nau'em_i.emu_mp.emus_args
#define em_deflb\h'|\nau'em_i.emu_deflb
#define em_defdnam\h'|\nau'em_i.emu_defdnam
#define em_arg\h'|\nau'em_i.emu_arg
};
.fi
.PP
Possible arguments to the EM instruction read are supplied in a linked list
of structures:
.PP
.nf
struct e_args {
struct e_args *em_next; /* Next argument */
short em_argtype; /* Type of this argument */
union {
arith emu_cst; /* A constant */
label emu_ilb; /* An instruction label */
char *emu_pnam; /* A procedure name (not including '$') */
struct {
label emus_dlb;
arith emus_noff;
} emu_ndlb; /* Numeric data label + offset */
struct {
char *emus_dnam;
arith emus_soff;
} emu_sdlb; /* String data label + offset */
struct {
char *emus_str;
arith emus_size;
} emu_con; /* An scon, icon, ucon or fcon */
} em_value;
#define em_cst\h'|\nau'em_value.emu_cst
#define em_ilb\h'|\nau'em_value.emu_ilb
#define em_pnam\h'|\nau'em_value.emu_pnam
#define em_dlb\h'|\nau'em_value.emu_ndlb.emus_dlb
#define em_noff\h'|\nau'em_value.emu_ndlb.emus_noff
#define em_dnam\h'|\nau'em_value.emu_sdlb.emus_dnam
#define em_soff\h'|\nau'em_value.emu_sdlb.emus_soff
#define em_str\h'|\nau'em_value.emu_con.emus_str
#define em_size\h'|\nau'em_value.emu_con.emus_size
int em_type; /* Type of this instr */
#define EM_MNEM 256 /* A machine instruction */
#define EM_PSEU 257 /* A pseudo */
#define EM_STARTMES 258 /* Start of a MES pseudo */
#define EM_MESARG 259 /* A member in a MES list */
#define EM_ENDMES 260 /* End of a MES pseudo */
#define EM_DEFILB 261 /* An instruction label definition */
#define EM_DEFDLB 262 /* A numeric data label definition */
#define EM_DEFDNAM 263 /* A non-numeric data label def */
#define EM_ERROR 264 /* Recoverable error */
#define EM_FATAL 265 /* Unrecoverable error */
#define EM_EOF 266 /* End of file */
int em_opcode;
struct e_arg em_arg;
};
extern arith
em_holorbsssize;
extern int
em_holorbssinit;
#define em_ilb em_arg.ema_ilb
#define em_dlb em_arg.ema_dlb
#define em_dnam em_arg.ema_dnam
#define em_argtype em_arg.ems_argtype
#define em_cst em_arg.ema_cst
#define em_pnam em_arg.ema_pnam
#define em_string em_arg.ema_string
#define em_off em_arg.ems_szoroff
#define em_size em_arg.ems_szoroff
#define em_exc1 em_arg.ema_cst
#define em_exc2 em_arg.ems_szoroff
#define em_holsize em_holorbsssize
#define em_bsssize em_holorbsssize
#define em_holinit em_holorbssinit
#define em_bssinit em_holorbssinit
extern char
*EM_error, *EM_filename;
extern unsigned int
EM_lineno;
extern int
EM_wordsize, EM_pointersize;
.fi
.PP
The named types \fBarith\fR and \fBlabel\fR refer to types on the local machine
@ -119,8 +138,10 @@ Common definitions are \fBlong\fR for \fBarith\fR and \fBunsigned int\fR for
\fBlabel\fR.
.PP
The \fIe_instr\fR structure consists of the fields
\fIem_type\fR, containing the type of this \fIe_instr\fR, and
\fIem_i\fR, containing its value of this \fIe_instr\fR.
\fIem_type\fR, containing the type of this \fIe_instr\fR,
\fIem_opcode\fR, containing the opcode of an instruction,
\fIem_arg\fR, containing a possible argument,
and two other fields for special purposes explained later.
.PP
The possible values of
\fIem_type\fR, defined in <em_comp.h>, are summarized below:
@ -136,21 +157,24 @@ Meaning
an EM machine instruction.
.br
.PD 0
.IP " em_args" \nau
.IP " em_arg" \nau
The \fIem_opcode\fR field
contains the opcode of the instruction, and \fIem_args\fR may indicate
arguments.
contains the opcode of the instruction, and \fIem_arg\fR may contain an
argument.
.IP "EM_PSEU em_opcode" \nau
an EM pseudo instruction.
.IP " em_args" \nau
.IP " em_arg" \nau
The \fIem_opcode\fR field
contains the opcode, and \fIem_args\fR may indicate arguments.
contains the opcode, and \fIem_arg\fR may contain an argument.
As consecutive CON-pseudos are allocated consecutively, a CON delivered by
\fIEM_getinstr\fR has exactly one argument.
If the CON-pseudo read has more, they are delivered as separate CON's.
The same holds for ROM-pseudos.
Also, if the length of a string constant exceeds 256 characters, it will be
delivered as several CON's or ROM's.
There are two "special" pseudo's, that use other variables, HOL and BSS.
They use them as indicated in the #defines.
The EXC pseudo has its arguments encoded as indicated in the #defines.
.IP "EM_STARTMES em_arg" \nau
the start of a MES pseudo.
.br
@ -160,19 +184,19 @@ The other arguments, if any, are delivered as separate EM_MESARG's.
an argument of a MES pseudo.
.IP "EM_ENDMES none" \nau
the end of a MES pseudo.
.IP "EM_DEFILB em_deflb" \nau
.IP "EM_DEFILB em_ilb" \nau
an instruction label definition.
.br
The field \fIem_deflb\fR contains the label (instruction labels are always
The field \fIem_ilb\fR contains the label (instruction labels are always
numeric).
.IP "EM_DEFDLB em_deflb" \nau
.IP "EM_DEFDLB em_dlb" \nau
a numeric data label definition.
.br
The field \fIem_deflb\fR contains the label.
.IP "EM_DEFDNAM em_defdnam" \nau
The field \fIem_dlb\fR contains the label.
.IP "EM_DEFDNAM em_dnam" \nau
a non-numeric data label definition.
.br
The field \fIem_defdnam\fR contains the label.
The field \fIem_dnam\fR contains the label.
.IP "EM_ERROR none" \nau
an error in the input that makes the rest of the data in the structure
meaningless.
@ -184,13 +208,16 @@ a fatal error.
.br
\fIEM_error\fR contains an
error message.
.IP "EM_EOF none" \nau
end of file
.PD
.PP
The \fIe_args\fR structure consists of the fields
\fIem_next\fR, containing a pointer to the next argument or null,
the field \fIem_argtype\fR, containing the type of this argument, and
the field \fIem_value\fR, containing the value of the argument.
The possible values of \fIem_argtype\fR, defined in <em_ptyp.h>,
The \fIe_arg\fR structure consists of the fields
the field \fIems_argtype\fR, containing the type of this argument or 0
if absent,
the field \fIems_arg\fR, containing the value of the argument,
and \fIems_szoroff\fR, containing an optional offset or size.
The possible values of \fIems_argtype\fR, defined in <em_ptyp.h>,
are summarized below:
.br
.ta \w'dlb_ptyp\ \ \ \ 'u +\w'em_opcode\ \ \ 'u
@ -200,50 +227,52 @@ are summarized below:
.di
.IP "Value Selector" \nau
Meaning
.IP "ilb_ptyp em_ilb" \nau
.IP "0 none" \nau
no argument.
.IP "ilb_ptyp emu_ilb" \nau
an instruction label.
.PD 0
.IP "nof_ptyp em_dlb" \nau
.IP "nof_ptyp emu_dlb" \nau
an offset from a numeric data label.
.IP " em_noff" \nau
.IP " ems_szoroff" \nau
The
\fIem_noff\fR field contains the offset and the
\fIem_dlb\fR field contains the label.
.IP "sof_ptyp em_dnam" \nau
\fIems_szodiff\fR field contains the offset and the
\fIemu_dlb\fR field contains the label.
.IP "sof_ptyp emu_dnam" \nau
an offset from a non-numeric data label.
.IP " em_soff" \nau
The \fIem_soff\fR field contains the offset and the \fIem_dnam\fR field
.IP " ems_szoroff" \nau
The \fIems_szoroff\fR field contains the offset and the \fIemu_dnam\fR field
contains the label, represented as a string.
.IP "cst_ptyp em_cst" \nau
.IP "cst_ptyp emu_cst" \nau
a numeric constant.
.IP "pro_ptyp em_pnam" \nau
.IP "pro_ptyp emu_pnam" \nau
a procedure name, not including the '$',
represented as a string.
.IP "str_ptyp em_str" \nau
.IP "str_ptyp emu_string" \nau
a string constant.
.IP " em_size" \nau
The string is found in \fIem_str\fR, represented as a row of bytes, of
length \fIem_size\fR.
.IP "ico_ptyp em_str" \nau
.IP " ems_szoroff" \nau
The string is found in \fIemu_string\fR, represented as a row of bytes, of
length \fIems_szoroff\fR.
.IP "ico_ptyp emu_string" \nau
an integer constant.
.IP " em_size" \nau
A string representation of the constant is found in \fIem_str\fR.
It has size \fIem_size\fR bytes on the target machine.
.IP "uco_ptyp em_str" \nau
.IP " ems_szoroff" \nau
A string representation of the constant is found in \fIemu_string\fR.
It has size \fIems_szoroff\fR bytes on the target machine.
.IP "uco_ptyp emu_string" \nau
an unsigned constant.
.IP " em_size" \nau
A string representation of the constant is found in \fIem_str\fR.
It has size \fIem_size\fR bytes on the target machine.
.IP "fco_ptyp em_str" \nau
.IP " ems_szoroff" \nau
A string representation of the constant is found in \fIemu_string\fR.
It has size \fIems_szoroff\fR bytes on the target machine.
.IP "fco_ptyp emu_string" \nau
a floating constant.
.IP " em_size" \nau
A string representation of the constant is found in \fIem_str\fR.
It has size \fIem_size\fR bytes on the target machine.
.IP " ems_szoroff" \nau
A string representation of the constant is found in \fIemu_string\fR.
It has size \fIems_szoroff\fR bytes on the target machine.
.PD
.PP
When an error occurs, \fIEM_error\fR is set to indicate the reason.
\fIEM_error\fR also is the only means of detecting whether an error
occurred. The EM_ERROR described above is only set when the error
\fIEM_getinstr\fR returns 1 if all goes well, 0 if it does not.
The EM_ERROR described above is only set when the error
is serious enough.
.PP
The routine \fIEM_mkcalls\fR "translates" the EM instruction indicated
@ -281,10 +310,8 @@ em_code(3)
A.S. Tanenbaum, H. v Staveren, E.G. Keizer, J.W. Stevenson, "\fBDescription
of a Machine Architecture for use with Block Structured Languages\fR",
Informatica Rapport IR-81, Vrije Universiteit, Amsterdam, 1983.
.SH DIAGNOSTICS
\fIEM_getinstr\fR returns a null pointer on end of file.
.SH REMARKS
All information must be considered to be contained in a static area so it
All strings must be considered to be contained in a static area, so
must be copied to be saved.
.SH BUGS
As CON's and ROM's may be delivered in several parts, the count fields in
@ -292,4 +319,4 @@ a static exchange may be wrong.
.PP
Please report bugs to the author.
.SH AUTHOR
Ceriel J.H. Jacobs <ceriel@vu44.UUCP>
Ceriel J.H. Jacobs <ceriel@cs.vu.nl>

View file

@ -60,26 +60,17 @@ _fill()
}
}
#define NARGS 3 /* Maximum number of arguments */
#define STRSIZ 256 /* Maximum length of strings */
static struct e_instr emhead; /* Where we put the head */
static struct e_args emargs[NARGS+2]; /* Where we put the arguments.
We need some more because some
arguments are constructed
*/
static struct e_args *i_emargs;
#define argentry() (i_emargs++)
static struct e_instr *emhead; /* Where we put the head */
static struct e_instr aheads[3];
static int ahead;
static struct string {
int length;
char str[STRSIZ + 1];
} strings[NARGS]; /* Room for strings */
static struct string *i_strings; /* Index of last one used */
#define stringentry() (i_strings++)
} string;
static struct e_args *argp; /* Indicates arguments yet to be
delivered
*/
#ifdef COMPACT
static arith strleft; /* count # of chars left to read
in a string
@ -104,11 +95,10 @@ static long wordmask[] = { /* allowed bits in a word */
};
static int wsize, psize; /* word size and pointer size */
int EM_wordsize, EM_pointersize;
#ifdef CHECKING
static char *argrange = "Argument range error";
#define check(expr) (expr || !EM_error || (EM_error = argrange))
#define check(expr) (expr || EM_error || (EM_error = argrange))
#else not CHECKING
#define check(x) /* nothing */
#endif CHECKING
@ -120,7 +110,7 @@ PRIVATE
xerror(s)
char *s;
{
if (emhead.em_type != EM_FATAL) emhead.em_type = EM_ERROR;
if (emhead->em_type != EM_FATAL) emhead->em_type = EM_ERROR;
if (!EM_error) EM_error = s;
}
@ -129,7 +119,7 @@ PRIVATE
xfatal(s)
char *s;
{
emhead.em_type = EM_FATAL;
emhead->em_type = EM_FATAL;
if (!EM_error) EM_error = s;
}
@ -196,68 +186,59 @@ PRIVATE
startmes(p)
register struct e_instr *p;
{
register struct e_args *ap;
ap = getarg(cst_ptyp);
p->em_arg = ap;
getarg(cst_ptyp, &(p->em_arg));
state = MES;
if (ap->em_cst == ms_emx) {
if (p->em_cst == ms_emx) {
if (wsize || psize) {
if (!EM_error) EM_error = "Duplicate ms_emx";
}
argp = ap = getarg(cst_ptyp);
wsize = ap->em_cst;
EM_wordsize = ap->em_cst;
ap->em_next = getarg(cst_ptyp);
ap = ap->em_next;
psize = ap->em_cst;
EM_pointersize = ap->em_cst;
p = &aheads[ahead++];
getarg(cst_ptyp, &(p->em_arg));
wsize = p->em_cst;
EM_wordsize = p->em_cst;
p->em_type = EM_MESARG;
p = &aheads[ahead++];
getarg(cst_ptyp, &(p->em_arg));
psize = p->em_cst;
EM_pointersize = p->em_cst;
p->em_type = EM_MESARG;
}
}
/* EM_getinstr: read an "EM_line"
*/
EXPORT struct e_instr *
EM_getinstr()
EXPORT int
EM_getinstr(p)
register struct e_instr *p;
{
register struct e_instr *p = &emhead;
register struct e_args *args;
i_emargs = emargs;
i_strings = strings;
EM_error = 0;
if (ahead) {
*p = aheads[--ahead];
return 1;
}
emhead = p;
#ifdef CHECKING
if (!EM_initialized) {
EM_error = "Initialization not done";
p->em_type = EM_FATAL;
return p;
return 0;
}
#endif CHECKING
if (argp) { /* We have some arguments left to deliver */
args = argp;
argp = args->em_next;
p->em_type = EM_MESARG;
p->em_arg = args;
args->em_next = 0;
return p;
}
if (!state) { /* All clear, get a new line */
p = gethead();
if (!p) { /* End of file */
return p;
}
gethead(p);
switch(p->em_type) {
case EM_EOF:
return EM_error == 0;
case EM_MNEM: {
register int i,j;
register struct e_args *ap;
extern char em_flag[];
extern short em_ptyp[];
p->em_args = 0;
j = em_flag[p->em_opcode - sp_fmnem] & EM_PAR;
i = em_ptyp[j];
if (j == PAR_NO) { /* No arguments */
@ -266,11 +247,11 @@ EM_getinstr()
#ifndef COMPACT
if (j == PAR_B) i = ptyp(sp_ilb2);
#endif COMPACT
ap = getarg(i);
getarg(i, &(p->em_arg));
#ifndef COMPACT
if (j == PAR_B) {
ap->em_cst = ap->em_ilb;
ap->em_argtype = cst_ptyp;
p->em_cst = p->em_ilb;
p->em_argtype = cst_ptyp;
}
#endif COMPACT
/* range checking
@ -278,48 +259,47 @@ EM_getinstr()
#ifdef CHECKING
if (wsize <= 4 && psize <= 4) switch(j) {
case PAR_B:
check(ap->em_cst <= 32767);
check(p->em_cst <= 32767);
/* Fall through */
case PAR_N:
check(ap->em_cst >= 0);
check(p->em_cst >= 0);
break;
case PAR_G:
if (ap->em_argtype == cst_ptyp) {
check(ap->em_cst >= 0);
if (p->em_argtype == cst_ptyp) {
check(p->em_cst >= 0);
}
/* Fall through */
case PAR_F:
/* ??? not in original em_decode or em_encode */
case PAR_L:
{ arith m = ap->em_cst >= 0 ? ap->em_cst :
- ap->em_cst;
{ arith m = p->em_cst >= 0 ? p->em_cst :
- p->em_cst;
/* Check that the number fits in a pointer */
check((m & ~wordmask[psize]) == 0);
break;
}
case PAR_W:
if (!ap) break;
check((ap->em_cst & ~wordmask[wsize]) == 0);
if (p->em_argtype == 0) break;
check((p->em_cst & ~wordmask[wsize]) == 0);
/* Fall through */
case PAR_S:
check(ap->em_cst > 0);
check(p->em_cst > 0);
/* Fall through */
case PAR_Z:
check(ap->em_cst >= 0 &&
ap->em_cst % wsize == 0);
check(p->em_cst >= 0 &&
p->em_cst % wsize == 0);
break;
case PAR_O:
check(ap->em_cst > 0 &&
( ap->em_cst % wsize == 0 ||
wsize % ap->em_cst == 0));
check(p->em_cst > 0 &&
( p->em_cst % wsize == 0 ||
wsize % p->em_cst == 0));
break;
case PAR_R:
check(ap->em_cst >= 0 && ap->em_cst <= 2);
check(p->em_cst >= 0 && p->em_cst <= 2);
break;
}
#endif CHECKING
p->em_args = ap;
#ifndef COMPACT
checkeol();
#endif COMPACT
@ -332,18 +312,20 @@ EM_getinstr()
type ROM or CON is in process
*/
{
register struct e_args *ap = 0, *ap1;
struct e_arg dummy;
switch(p->em_opcode) {
case ps_bss:
case ps_hol:
ap = getarg(cst_ptyp);
ap->em_next = ap1 = getarg(par_ptyp);
ap->em_next->em_next = ap1 = getarg(cst_ptyp);
getarg(cst_ptyp, &dummy);
em_holsize = dummy.ema_cst;
getarg(par_ptyp, &(p->em_arg));
getarg(cst_ptyp, &dummy);
em_holinit = dummy.ema_cst;
#ifdef CHECKING
/* Check that the last value is 0 or 1
*/
if (ap1->em_cst != 1 && ap1->em_cst != 0) {
if (em_holinit != 1 && em_holinit != 0) {
if (! EM_error)
EM_error="Third argument of hol/bss not 0/1";
}
@ -351,36 +333,41 @@ EM_getinstr()
break;
case ps_exa:
case ps_ina:
ap = getarg(lab_ptyp);
getarg(lab_ptyp, &(p->em_arg));
break;
case ps_exp:
case ps_inp:
ap = getarg(pro_ptyp);
getarg(pro_ptyp, &(p->em_arg));
break;
case ps_exc:
ap = getarg(cst_ptyp);
ap->em_next = getarg(cst_ptyp);
getarg(cst_ptyp, &dummy);
p->em_exc1 = dummy.ema_cst;
getarg(cst_ptyp, &dummy);
p->em_exc2 = dummy.ema_cst;
break;
case ps_pro:
ap = getarg(pro_ptyp);
ap->em_next = getarg(cst_ptyp|ptyp(sp_cend));
getarg(pro_ptyp, &(p->em_arg));
getarg(cst_ptyp|ptyp(sp_cend), &dummy);
if (dummy.ems_argtype == 0) {
p->em_off = -1;
}
else p->em_off = dummy.ema_cst;
break;
case ps_end:
ap = getarg(cst_ptyp|ptyp(sp_cend));
getarg(cst_ptyp|ptyp(sp_cend), &(p->em_arg));
break;
case ps_con:
ap = getarg(val_ptyp);
getarg(val_ptyp, &(p->em_arg));
state |= CON;
break;
case ps_rom:
ap = getarg(val_ptyp);
getarg(val_ptyp, &(p->em_arg));
state |= ROM;
break;
default:
xerror("Bad pseudo");
break;
}
p->em_args = ap;
}
#ifndef COMPACT
if (p->em_opcode != ps_con && p->em_opcode != ps_rom) {
@ -397,7 +384,7 @@ EM_getinstr()
psize = 2;
EM_error = "EM code should start with mes 2";
}
return p;
return EM_error == 0;
}
if (state & INSTRING) { /* We already delivered part of a string.
@ -406,11 +393,9 @@ EM_getinstr()
register struct string *s;
s = getstring(0);
args = argentry();
args->em_next = 0;
args->em_argtype = str_ptyp;
args->em_str = s->str;
args->em_size = s->length;
p->em_argtype = str_ptyp;
p->em_string = s->str;
p->em_size = s->length;
switch(state & PSEUMASK) {
default:
assert(0);
@ -418,50 +403,45 @@ EM_getinstr()
if (!EM_error)
EM_error = "String too long in message";
p->em_type = EM_MESARG;
p->em_arg = args;
break;
case CON:
p->em_type = EM_PSEU;
p->em_opcode = ps_con;
p->em_args = args;
break;
case ROM:
p->em_type = EM_PSEU;
p->em_opcode = ps_rom;
p->em_args = args;
break;
}
return p;
return EM_error == 0;
}
/* Here, we are in a state reading arguments */
args = getarg(any_ptyp);
getarg(any_ptyp, &(p->em_arg));
if (EM_error && p->em_type != EM_FATAL) {
return p;
return 0;
}
if (!args) { /* No more arguments */
if (p->em_argtype == 0) { /* No more arguments */
#ifndef COMPACT
checkeol();
#endif
if (state == MES) {
state = 0;
p->em_type = EM_ENDMES;
return p;
return EM_error == 0;
}
/* Here, we have to get the next instruction */
state = 0;
return EM_getinstr();
return EM_getinstr(p);
}
/* Here, there was an argument */
if (state == MES) {
p->em_type = EM_MESARG;
p->em_arg = args;
return p;
return EM_error == 0;
}
p->em_type = EM_PSEU;
p->em_args = args;
if (state == CON) p->em_opcode = ps_con;
else p->em_opcode = ps_rom;
return p;
return EM_error == 0;
}

View file

@ -169,7 +169,7 @@ getname()
register struct string *s;
register int c;
s = stringentry();
s = &string;
p = s->str;
c = getbyte();
@ -200,7 +200,7 @@ getstring()
register int c;
static int termc;
s = stringentry();
s = &string;
p = s->str;
if (!(state & INSTRING)) { /* Not reading a string yet */
@ -241,19 +241,20 @@ getstring()
return s;
}
PRIVATE struct e_args *gettyp();
PRIVATE gettyp();
PRIVATE int
offsetted(argtyp, ap)
arith *ap;
{
register int c;
register struct e_args *ap1;
if ((c = nospace()) == '+' || c == '-') {
ap1 = gettyp(cst_ptyp);
if (c == '-') *ap = -(ap1->em_cst);
else *ap = ap1->em_cst;
struct e_arg dummy;
gettyp(cst_ptyp, &dummy);
if (c == '-') *ap = -(dummy.ema_cst);
else *ap = dummy.ema_cst;
return sp_doff;
}
else *ap = 0;
@ -265,16 +266,15 @@ offsetted(argtyp, ap)
PRIVATE int
getnumber(c, ap)
register int c;
register struct e_args *ap;
register struct e_arg *ap;
{
register char *p;
char str[STRSIZ + 1];
register char *p = str;
int n;
register struct string *s = stringentry();
int expsign;
long str2long();
p = s->str;
ap->em_argtype = cst_ptyp;
ap->ems_argtype = cst_ptyp;
expsign = 0;
if (c == '+' || c == '-') {
@ -285,16 +285,14 @@ getnumber(c, ap)
if (! isdigit(c)) {
ungetbyte(c);
syntax("digit expected");
i_strings--;
return sp_cst4;
}
n = sp_cst4;
for (;;) {
if (p >= &(s->str[STRSIZ])) {
if (p >= &(str[STRSIZ])) {
syntax("number too long");
i_strings--;
return sp_cst4;
}
@ -325,26 +323,29 @@ getnumber(c, ap)
}
if (c == 'I' || c == 'U' || c == 'F') {
ap->em_str = s->str;
ap->em_size = gettyp(cst_ptyp)->em_cst;
struct e_arg dummy;
strcpy(string.str, str);
ap->ema_string = string.str;
gettyp(cst_ptyp, &dummy);
ap->ems_szoroff = dummy.ema_cst;
switch(c) {
case 'I':
ap->em_argtype = ico_ptyp;
ap->ems_argtype = ico_ptyp;
return sp_icon;
case 'U':
ap->em_argtype = uco_ptyp;
ap->ems_argtype = uco_ptyp;
return sp_ucon;
case 'F':
ap->em_argtype = fco_ptyp;
ap->ems_argtype = fco_ptyp;
return sp_fcon;
}
assert(0);
}
ungetbyte(c);
ap->em_cst = (arith) str2long(s->str, 10);
i_strings--;
ap->ema_cst = (arith) str2long(str, 10);
return sp_cst4;
}
@ -353,7 +354,7 @@ PRIVATE int getexpr();
PRIVATE int
getfactor(c, ap)
register int c;
register struct e_args *ap;
register struct e_arg *ap;
{
if (c == '(') {
if (getexpr(nospace(), ap) != sp_cst4) {
@ -371,7 +372,7 @@ getfactor(c, ap)
PRIVATE int
getterm(c, ap)
register int c;
register struct e_args *ap;
register struct e_arg *ap;
{
arith left;
@ -383,15 +384,15 @@ getterm(c, ap)
break;
}
left = ap->em_cst;
left = ap->ema_cst;
if (getfactor(nospace(), ap) != sp_cst4) {
syntax("factor expected");
break;
}
if (c == '*') ap->em_cst *= left;
else if (c == '/') ap->em_cst = left / ap->em_cst;
else ap->em_cst = left % ap->em_cst;
if (c == '*') ap->ema_cst *= left;
else if (c == '/') ap->ema_cst = left / ap->ema_cst;
else ap->ema_cst = left % ap->ema_cst;
}
return sp_cst4;
}
@ -399,7 +400,7 @@ getterm(c, ap)
PRIVATE int
getexpr(c, ap)
register int c;
register struct e_args *ap;
register struct e_arg *ap;
{
arith left;
@ -411,14 +412,14 @@ getexpr(c, ap)
break;
}
left = ap->em_cst;
left = ap->ema_cst;
if (getterm(nospace(), ap) != sp_cst4) {
syntax("term expected");
break;
}
if (c == '+') ap->em_cst += left;
else ap->em_cst = left - ap->em_cst;
if (c == '+') ap->ema_cst += left;
else ap->ema_cst = left - ap->ema_cst;
}
return sp_cst4;
}
@ -426,25 +427,22 @@ getexpr(c, ap)
PRIVATE int
get15u()
{
register struct e_args *ap = argentry();
struct e_arg dummy;
ap->em_next = 0;
if (getnumber(getbyte(), ap) != sp_cst4) {
if (getnumber(getbyte(), &dummy) != sp_cst4) {
syntax("integer expected");
}
else check((ap->em_cst & ~077777) == 0);
i_emargs--;
return (int) (ap->em_cst);
else check((dummy.ema_cst & ~077777) == 0);
return (int) (dummy.ema_cst);
}
PRIVATE struct e_args *
gettyp(typset)
PRIVATE
gettyp(typset, ap)
register struct e_arg *ap;
{
register int c, t;
register struct e_args *ap = argentry();
register int argtyp;
ap->em_next = 0;
if ((c = nospace()) == '\n') {
ungetbyte(c);
out("newline\n");
@ -453,31 +451,31 @@ gettyp(typset)
else if (isdigit(c) || c == '+' || c == '-' || c == '(') {
out("expr\n");
argtyp = getexpr(c, ap);
if (argtyp == sp_cst4 && fit16i(ap->em_cst)) argtyp = sp_cst2;
if (argtyp == sp_cst4 && fit16i(ap->ema_cst)) argtyp = sp_cst2;
}
else if (isalpha(c) || c == '_') {
out("name\n");
ungetbyte(c);
ap->em_dnam = getname()->str;
ap->em_argtype = sof_ptyp;
argtyp = offsetted(sp_dnam, &(ap->em_soff));
ap->ema_dnam = getname()->str;
ap->ems_argtype = sof_ptyp;
argtyp = offsetted(sp_dnam, &(ap->ems_szoroff));
}
else if (c == '.') {
out(".label\n");
ap->em_dlb = get15u();
ap->em_argtype = nof_ptyp;
argtyp = offsetted(sp_dlb2, &(ap->em_noff));
ap->ema_dlb = get15u();
ap->ems_argtype = nof_ptyp;
argtyp = offsetted(sp_dlb2, &(ap->ems_szoroff));
}
else if (c == '*') {
out("*label\n");
ap->em_ilb = get15u();
ap->em_argtype = ilb_ptyp;
ap->ema_ilb = get15u();
ap->ems_argtype = ilb_ptyp;
argtyp = sp_ilb2;
}
else if (c == '$') {
out("$name\n");
ap->em_pnam = getname()->str;
ap->em_argtype = pro_ptyp;
ap->ema_pnam = getname()->str;
ap->ems_argtype = pro_ptyp;
argtyp = sp_pnam;
}
else if (c == '"' || c == '\'') {
@ -486,34 +484,38 @@ gettyp(typset)
out("string\n");
ungetbyte(c);
s = getstring(0);
ap->em_str = s->str;
ap->em_size = s->length;
ap->em_argtype = str_ptyp;
ap->ema_string = s->str;
ap->ems_szoroff = s->length;
ap->ems_argtype = str_ptyp;
argtyp = sp_scon;
}
else if (c == '?') {
out("?\n");
argtyp = sp_cend;
ap->ems_argtype = 0;
}
else {
/* c != '\n', so "ungetbyte" not neccesary */
syntax("operand expected");
return ap;
return;
}
t = argtyp - sp_fspec;
assert(t >= 0 && t < 16);
if ((typset & (1 << t)) == 0) {
syntax("Bad argument type");
return ap;
return;
}
if (argtyp == sp_cend) return 0;
return ap;
if (argtyp == sp_cend) {
ap->ems_argtype = 0;
}
return;
}
PRIVATE struct e_args *
getarg(typset)
PRIVATE
getarg(typset, ap)
struct e_arg *ap;
{
register int c;
@ -527,7 +529,7 @@ getarg(typset)
}
}
argnum++;
return gettyp(typset);
return gettyp(typset, ap);
}
/* getmnem: We found the start of either an instruction or a pseudo.
@ -573,23 +575,19 @@ getmnem(c, p)
p->em_type = EM_PSEU;
break;
}
i_strings--;
}
PRIVATE
line_line()
{
register struct e_args *ap;
static char filebuf[STRSIZ + 1];
char *btscpy();
struct e_arg dummy;
ap = gettyp(ptyp(sp_cst2));
EM_lineno = ap->em_cst;
i_emargs--;
ap = gettyp(str_ptyp);
btscpy(filebuf, ap->em_str, (int) ap->em_size);
i_emargs--;
i_strings--;
gettyp(ptyp(sp_cst2), &dummy);
EM_lineno = dummy.ema_cst;
gettyp(str_ptyp, &dummy);
btscpy(filebuf, dummy.ema_string, (int) dummy.ems_szoroff);
EM_filename = filebuf;
}
@ -597,32 +595,29 @@ PRIVATE
getlabel(c, p)
register struct e_instr *p;
{
register struct e_args *ap;
ungetbyte(c);
ap = gettyp(lab_ptyp|ptyp(sp_cst2));
switch(ap->em_argtype) {
gettyp(lab_ptyp|ptyp(sp_cst2), &(p->em_arg));
switch(p->em_argtype) {
case cst_ptyp:
p->em_type = EM_DEFILB;
p->em_deflb = ap->em_cst;
p->em_ilb = p->em_cst;
break;
case sof_ptyp:
p->em_type = EM_DEFDNAM;
p->em_defdnam = ap->em_dnam;
break;
case nof_ptyp:
p->em_type = EM_DEFDLB;
p->em_deflb = ap->em_dlb;
break;
}
checkeol();
}
PRIVATE struct e_instr *
gethead()
PRIVATE
gethead(p)
struct e_instr *p;
{
register int c;
register struct e_instr *p = &emhead;
argnum = 1;
for (;;) {
@ -632,20 +627,23 @@ gethead()
do c = getbyte();
while (c != '\n' && c != EOF);
}
if (c == EOF) return 0;
if (c == EOF) {
p->em_type = EM_EOF;
return;
}
if (c == '\n') continue;
if (isspace(c)) {
c = nospace();
if (isalpha(c) || c == '_') {
getmnem(c, p);
return p;
return;
}
ungetbyte(c);
}
else if (c == '#') line_line();
else {
getlabel(c, p);
return p;
return;
}
checkeol();
}

View file

@ -39,39 +39,38 @@ get32()
PRIVATE struct string *getstring();
/* getarg : read an argument of any type, and check it against "typset"
if neccesary. Return a pointer to the argument.
if neccesary. Put result in "ap".
*/
PRIVATE struct e_args *
getarg(typset)
PRIVATE
getarg(typset, ap)
register struct e_arg *ap;
{
register struct e_args *ap = argentry();
register int i = getbyte();
#ifdef CHECKING
int argtyp;
#endif CHECKING
ap->em_next = 0;
switch(i) {
default:
if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) { /* A cst */
ap->em_cst = i - sp_zcst0;
ap->em_argtype = cst_ptyp;
ap->ema_cst = i - sp_zcst0;
ap->ems_argtype = cst_ptyp;
i = sp_cst2;
}
break;
case sp_dlb1: /* Numeric data label encoded in one byte */
ap->em_dlb = getbyte();
ap->em_noff = 0;
ap->em_argtype = nof_ptyp;
ap->ema_dlb = getbyte();
ap->ems_szoroff = 0;
ap->ems_argtype = nof_ptyp;
break;
case sp_dlb2: /* Numeric data label encoded in two bytes */
ap->em_dlb = get16();
ap->em_noff = 0;
ap->em_argtype = nof_ptyp;
ap->ema_dlb = get16();
ap->ems_szoroff = 0;
ap->ems_argtype = nof_ptyp;
#ifdef CHECKING
if (ap->em_dlb > 32767 && !EM_error) {
if (ap->ema_dlb > 32767 && !EM_error) {
EM_error = "Illegal data label";
break;
}
@ -79,15 +78,15 @@ getarg(typset)
break;
case sp_ilb1: /* Instruction label encoded in one byte */
ap->em_ilb = getbyte();
ap->em_argtype = ilb_ptyp;
ap->ema_ilb = getbyte();
ap->ems_argtype = ilb_ptyp;
break;
case sp_ilb2: /* Instruction label encoded in two bytes */
ap->em_ilb = get16();
ap->em_argtype = ilb_ptyp;
ap->ema_ilb = get16();
ap->ems_argtype = ilb_ptyp;
#ifdef CHECKING
if (ap->em_ilb > 32767 && !EM_error) {
if (ap->ema_ilb > 32767 && !EM_error) {
EM_error = "Illegal instruction label";
break;
}
@ -95,13 +94,13 @@ getarg(typset)
break;
case sp_cst2: /* A cst encoded in two bytes */
ap->em_cst = get16();
ap->em_argtype = cst_ptyp;
ap->ema_cst = get16();
ap->ems_argtype = cst_ptyp;
break;
case sp_cst4: /* A cst encoded in four bytes */
ap->em_cst = get32();
ap->em_argtype = cst_ptyp;
ap->ema_cst = get32();
ap->ems_argtype = cst_ptyp;
break;
case sp_pnam: /* A procedure name */
@ -114,8 +113,8 @@ getarg(typset)
xerror("Procedure name too long");
}
#endif CHECKING
ap->em_pnam = p->str;
ap->em_argtype = pro_ptyp;
ap->ema_pnam = p->str;
ap->ems_argtype = pro_ptyp;
break;
}
@ -129,25 +128,19 @@ getarg(typset)
xerror("Data label too long");
}
#endif CHECKING
ap->em_dnam = p->str;
ap->em_soff = 0;
ap->em_argtype = sof_ptyp;
ap->ema_dnam = p->str;
ap->ems_szoroff = 0;
ap->ems_argtype = sof_ptyp;
break;
}
case sp_doff: /* A data label + offset */
{
register struct e_args *ap1;
struct e_arg dummy;
ap1 = getarg(lab_ptyp);
*ap = *ap1;
i_emargs--;
ap1 = getarg(cst_ptyp);
if (ap->em_argtype == sof_ptyp) { /* non-numeric label */
ap->em_soff = ap1->em_cst;
}
else ap->em_noff = ap1->em_cst;
i_emargs--;
getarg(lab_ptyp, ap);
getarg(cst_ptyp, &dummy);
ap->ems_szoroff = dummy.ema_cst;
break;
}
@ -157,16 +150,16 @@ getarg(typset)
{
register struct string *p;
ap->em_size = getarg(cst_ptyp)->em_cst;
i_emargs--;
getarg(cst_ptyp, ap);
ap->ems_szoroff = ap->ema_cst;
p = getstring(0);
#ifdef CHECKING
if (state & INSTRING) {
xerror("Numeric constant too long");
}
#endif CHECKING
ap->em_argtype = ptyp(i);
ap->em_str = p->str;
ap->ems_argtype = ptyp(i);
ap->ema_string = p->str;
break;
}
@ -175,34 +168,37 @@ getarg(typset)
register struct string *p;
p = getstring(0);
ap->em_argtype = str_ptyp;
ap->em_str = p->str;
ap->em_size = p->length;
ap->ems_argtype = str_ptyp;
ap->ema_string = p->str;
ap->ems_szoroff = p->length;
break;
}
}
#ifdef CHECKING
argtyp = i;
if (EM_error) return 0;
if (EM_error) return;
if (i == EOF) {
xfatal("Unexpected EOF");
return 0;
return;
}
if ((i -= sp_fspec) < 0 || i >= 16) {
xerror("Illegal byte");
return 0;
return;
}
if ((typset & (1 << i)) == 0 && !EM_error) {
EM_error = "Bad argument type";
}
if (argtyp == sp_cend) return 0;
if (argtyp == sp_cend) {
ap->ems_argtype = 0;
}
#else not CHECKING
if (i == sp_cend) return 0;
if (i == sp_cend) {
ap->ems_argtype = 0;
}
#endif CHECKING
return ap;
}
#ifdef CHECKING
@ -238,13 +234,14 @@ getstring(isident)
{
register char *p;
register int n;
register struct string *s;
register struct string *s = &string;
if (!(state & INSTRING)) { /* Not reading a string yet */
struct e_args *ap = getarg(cst_ptyp);
struct e_arg dummy;
getarg(cst_ptyp, &dummy);
/* Read length of string */
i_emargs--;
strleft = ap->em_cst;
strleft = dummy.ema_cst;
#ifdef CHECKING
if (strleft < 0) {
xerror("Negative length in string");
@ -253,8 +250,6 @@ getstring(isident)
#endif CHECKING
}
s = stringentry();
if (strleft <= STRSIZ) { /* Handle the whole string */
n = strleft;
state &= ~INSTRING;
@ -286,11 +281,11 @@ getstring(isident)
/* gethead: read the start of an EM-line
*/
PRIVATE struct e_instr *
gethead()
PRIVATE
gethead(p)
register struct e_instr *p;
{
register int i;
register struct e_instr *p = &emhead;
EM_lineno++;
@ -298,7 +293,7 @@ gethead()
/* A mnemonic */
p->em_type = EM_MNEM;
p->em_opcode = i;
return p;
return;
}
if (i < sp_fpseu+sp_npseu && i >= sp_fpseu) { /* A pseudo */
@ -307,26 +302,26 @@ gethead()
}
else p->em_type = EM_PSEU;
p->em_opcode = i;
return p;
return;
}
if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) { /* Instruction label */
p->em_type = EM_DEFILB;
p->em_deflb = i - sp_filb0;
return p;
p->em_ilb = i - sp_filb0;
return;
}
switch(i) {
case sp_ilb1: /* Instruction label */
p->em_type = EM_DEFILB;
p->em_deflb = getbyte();
p->em_ilb = getbyte();
break;
case sp_ilb2: /* Instruction label */
p->em_type = EM_DEFILB;
p->em_deflb = get16();
p->em_ilb = get16();
#ifdef CHECKING
if (p->em_deflb > 32767 && !EM_error) {
if (p->em_ilb > 32767 && !EM_error) {
EM_error = "Illegal instruction label definition";
}
#endif CHECKING
@ -334,14 +329,14 @@ gethead()
case sp_dlb1: /* Numeric data label */
p->em_type = EM_DEFDLB;
p->em_deflb = getbyte();
p->em_dlb = getbyte();
break;
case sp_dlb2: /* Numeric data label */
p->em_type = EM_DEFDLB;
p->em_deflb = get16();
p->em_dlb = get16();
#ifdef CHECKING
if (p->em_deflb > 32767 && !EM_error) {
if (p->em_dlb > 32767 && !EM_error) {
EM_error = "Illegal data label definition";
}
#endif CHECKING
@ -353,19 +348,20 @@ gethead()
p->em_type = EM_DEFDNAM;
if (!(s = getstring(1))) {
p->em_defdnam = "";
p->em_dnam = "";
}
else p->em_defdnam = s->str;
else p->em_dnam = s->str;
break;
}
case EOF: /* End of file */
return 0;
p->em_type = EM_EOF;
return;
default:
xerror("Unknown opcode");
break;
}
return p;
return;
}