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 em_comp.h
m_C_mnem m_C_mnem
m_C_mnem_na m_C_mnem_na
m_C_funcs
mkcalls.c mkcalls.c
read_em.3 read_em.3
read_em.c read_em.c

View file

@ -6,6 +6,11 @@
/* Variables must be declared somewhere ... */ /* Variables must be declared somewhere ... */
#include <em_arith.h>
char *EM_error; char *EM_error;
char *EM_filename; char *EM_filename;
unsigned int EM_lineno; 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 $(COMPARE) man/read_em.3
pr: 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: opr:
make pr | opr make pr | opr
clean: 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) libread_emk.a: $(K_OFILES)
ar r 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 $(CC) -c $(CFLAGS) -DCHECKING read_em.c
mv read_em.o read_emeV.o 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 $(CC) -c $(CFLAGS) mkcalls.c
mv mkcalls.o makecalls.o 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 $(CC) -c $(CFLAGS) -DCHECKING mkcalls.c
mv mkcalls.o makecallsV.o mv mkcalls.o makecallsV.o
@ -94,7 +94,10 @@ C_mnem: m_C_mnem argtype
C_mnem_narg: m_C_mnem_na argtype C_mnem_narg: m_C_mnem_na argtype
sh m_C_mnem_na > C_mnem_narg 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) -DCOMPACT -DCHECKING -Cread_emkV $(KSRCFILES)
lint $(INCLUDES) $(DEFINES) -DCHECKING -Cread_emeV $(ESRCFILES) lint $(INCLUDES) $(DEFINES) -DCHECKING -Cread_emeV $(ESRCFILES)
mv llib-lread_emeV.ln llib-lread_emkV.ln $(MODULES)/lib mv llib-lread_emeV.ln llib-lread_emkV.ln $(MODULES)/lib

View file

@ -4,10 +4,30 @@
*/ */
/* $Header$ */ /* $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 { struct e_instr {
int em_type; /* Type of this instr */ int em_type; /* Type of this instr */
#define EM_MNEM 256 /* A machine instruction */ #define EM_MNEM 256 /* A machine instruction */
#define EM_PSEU 257 /* A pseudo */ #define EM_PSEU 257 /* A pseudo */
#define EM_STARTMES 258 /* Start of a MES pseudo */ #define EM_STARTMES 258 /* Start of a MES pseudo */
#define EM_MESARG 259 /* A member in a MES list */ #define EM_MESARG 259 /* A member in a MES list */
#define EM_ENDMES 260 /* End of a MES pseudo */ #define EM_ENDMES 260 /* End of a MES pseudo */
@ -16,54 +36,36 @@ struct e_instr {
#define EM_DEFDNAM 263 /* A non-numeric data label def */ #define EM_DEFDNAM 263 /* A non-numeric data label def */
#define EM_ERROR 264 /* Recoverable error */ #define EM_ERROR 264 /* Recoverable error */
#define EM_FATAL 265 /* Unrecoverable error */ #define EM_FATAL 265 /* Unrecoverable error */
union { #define EM_EOF 266 /* End of file */
struct { int em_opcode;
int emus_opcode; /* Opcode of instruction */ struct e_arg em_arg;
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
}; };
struct e_args { extern arith
struct e_args *em_next; /* Next argument */ em_holorbsssize;
short em_argtype; /* Type of this argument */ extern int
union { em_holorbssinit;
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 char *EM_error; #define em_ilb em_arg.ema_ilb
extern unsigned int EM_lineno; #define em_dlb em_arg.ema_dlb
extern char *EM_filename; #define em_dnam em_arg.ema_dnam
extern int EM_wordsize, EM_pointersize; #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,69 +1,64 @@
EM_TABLE=../../../etc/em_table 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 for i in - cdflnorswz p b
do do
list=`./argtype $i $EM_TABLE` list=`./argtype $i $EM_TABLE`
case $i in case $i in
-) args='()' -) args='()'
echo "/* no arguments */" echo " /* no arguments */"
;; ;;
cdflnorswz) cdflnorswz)
args='(arg->em_cst)' args='(p->em_cst)'
echo "/* one integer constant argument */" echo " /* one integer constant argument */"
;; ;;
p) p)
args='(arg->em_pnam)' args='(p->em_pnam)'
echo "/* a procedure name argument */" echo " /* a procedure name argument */"
;; ;;
b) b)
: Grumbl, an instruction label as argument is encoded in a sp_cst2 : 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 */" echo " /* An instruction label argument */"
;; ;;
esac esac
for i in $list for i in $list
do do
cat << EOF echo " case op_$i:"
case op_$i:
C_$i$args;
break;
EOF
done done
echo " (*C_funcs[p->em_opcode])$args; break;"
done done
list=`./argtype g $EM_TABLE` list=`./argtype g $EM_TABLE`
for i in $list
do
echo " case op_$i:"
done
cat << 'EOF' cat << 'EOF'
default: /* a "g" argument */
/* a "g" argument */ if (p->em_argtype == nof_ptyp) {
if (arg->em_argtype == nof_ptyp) { switch(p->em_opcode) {
switch(opcode) {
default:
EM_error = "Illegal mnemonic";
break;
EOF EOF
for i in $list for i in $list
do do
cat << EOF cat << EOF
case op_$i: case op_$i:
C_${i}_dlb(arg->em_dlb, arg->em_noff); C_${i}_dlb(p->em_dlb, p->em_off);
break; break;
EOF EOF
done done
cat << 'EOF' cat << 'EOF'
} }
} }
else if (arg->em_argtype == sof_ptyp) { else if (p->em_argtype == sof_ptyp) {
switch(opcode) { switch(p->em_opcode) {
default:
EM_error = "Illegal mnemonic";
break;
EOF EOF
for i in $list for i in $list
do do
cat << EOF cat << EOF
case op_$i: case op_$i:
C_${i}_dnam(arg->em_dnam, arg->em_soff); C_${i}_dnam(p->em_dnam, p->em_off);
break; break;
EOF EOF
done done
@ -71,21 +66,8 @@ cat << 'EOF'
} }
} }
else /*argtype == cst_ptyp */ { else /*argtype == cst_ptyp */ {
switch(opcode) { (*C_funcs[p->em_opcode])(p->em_cst);
default: break;
EM_error = "Illegal mnemonic";
break;
EOF
for i in $list
do
cat << EOF
case op_$i:
C_$i(arg->em_cst);
break;
EOF
done
cat << 'EOF'
}
} }
} }
EOF EOF

View file

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

View file

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

View file

@ -24,7 +24,8 @@ EM_mkcalls\ \-\ a module to read EM assembly code
.br .br
.B char *filename; .B char *filename;
.PP .PP
.B struct e_instr *EM_getinstr() .B int EM_getinstr(instr)
.B struct e_instr *instr;
.PP .PP
.B int EM_mkcalls(instr) .B int EM_mkcalls(instr)
.br .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. \fIEM_close\fR must be called after all other calls to this package.
.PP .PP
\fIEM_getinstr\fR reads an EM instruction, and \fIEM_getinstr\fR reads an EM instruction, and
returns it as a pointer to a structure having the following returns it in the structure pointed to by \fIinstr\fR.
layout: This structure has the following layout:
.br .br
.PP .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 .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 { struct e_instr {
int em_type; /* Type of this instruction */ int em_type; /* Type of this instr */
union { #define EM_MNEM 256 /* A machine instruction */
struct { #define EM_PSEU 257 /* A pseudo */
int emus_opcode; /* Opcode of instruction */ #define EM_STARTMES 258 /* Start of a MES pseudo */
struct e_args *emus_args; /* Arguments of instruction */ #define EM_MESARG 259 /* A member in a MES list */
} emu_mp; #define EM_ENDMES 260 /* End of a MES pseudo */
label emu_deflb; /* Numeric label definition */ #define EM_DEFILB 261 /* An instruction label definition */
char *emu_defdnam; /* Non-numeric label definition */ #define EM_DEFDLB 262 /* A numeric data label definition */
struct e_args *emu_arg; /* For a message argument */ #define EM_DEFDNAM 263 /* A non-numeric data label def */
} em_i; #define EM_ERROR 264 /* Recoverable error */
#define em_opcode \kaem_i.emu_mp.emus_opcode #define EM_FATAL 265 /* Unrecoverable error */
#define em_args\h'|\nau'em_i.emu_mp.emus_args #define EM_EOF 266 /* End of file */
#define em_deflb\h'|\nau'em_i.emu_deflb int em_opcode;
#define em_defdnam\h'|\nau'em_i.emu_defdnam struct e_arg em_arg;
#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
}; };
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 .fi
.PP .PP
The named types \fBarith\fR and \fBlabel\fR refer to types on the local machine 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. \fBlabel\fR.
.PP .PP
The \fIe_instr\fR structure consists of the fields The \fIe_instr\fR structure consists of the fields
\fIem_type\fR, containing the type of this \fIe_instr\fR, and \fIem_type\fR, containing the type of this \fIe_instr\fR,
\fIem_i\fR, containing its value 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 .PP
The possible values of The possible values of
\fIem_type\fR, defined in <em_comp.h>, are summarized below: \fIem_type\fR, defined in <em_comp.h>, are summarized below:
@ -136,21 +157,24 @@ Meaning
an EM machine instruction. an EM machine instruction.
.br .br
.PD 0 .PD 0
.IP " em_args" \nau .IP " em_arg" \nau
The \fIem_opcode\fR field The \fIem_opcode\fR field
contains the opcode of the instruction, and \fIem_args\fR may indicate contains the opcode of the instruction, and \fIem_arg\fR may contain an
arguments. argument.
.IP "EM_PSEU em_opcode" \nau .IP "EM_PSEU em_opcode" \nau
an EM pseudo instruction. an EM pseudo instruction.
.IP " em_args" \nau .IP " em_arg" \nau
The \fIem_opcode\fR field 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 As consecutive CON-pseudos are allocated consecutively, a CON delivered by
\fIEM_getinstr\fR has exactly one argument. \fIEM_getinstr\fR has exactly one argument.
If the CON-pseudo read has more, they are delivered as separate CON's. If the CON-pseudo read has more, they are delivered as separate CON's.
The same holds for ROM-pseudos. The same holds for ROM-pseudos.
Also, if the length of a string constant exceeds 256 characters, it will be Also, if the length of a string constant exceeds 256 characters, it will be
delivered as several CON's or ROM's. 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 .IP "EM_STARTMES em_arg" \nau
the start of a MES pseudo. the start of a MES pseudo.
.br .br
@ -160,19 +184,19 @@ The other arguments, if any, are delivered as separate EM_MESARG's.
an argument of a MES pseudo. an argument of a MES pseudo.
.IP "EM_ENDMES none" \nau .IP "EM_ENDMES none" \nau
the end of a MES pseudo. the end of a MES pseudo.
.IP "EM_DEFILB em_deflb" \nau .IP "EM_DEFILB em_ilb" \nau
an instruction label definition. an instruction label definition.
.br .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). numeric).
.IP "EM_DEFDLB em_deflb" \nau .IP "EM_DEFDLB em_dlb" \nau
a numeric data label definition. a numeric data label definition.
.br .br
The field \fIem_deflb\fR contains the label. The field \fIem_dlb\fR contains the label.
.IP "EM_DEFDNAM em_defdnam" \nau .IP "EM_DEFDNAM em_dnam" \nau
a non-numeric data label definition. a non-numeric data label definition.
.br .br
The field \fIem_defdnam\fR contains the label. The field \fIem_dnam\fR contains the label.
.IP "EM_ERROR none" \nau .IP "EM_ERROR none" \nau
an error in the input that makes the rest of the data in the structure an error in the input that makes the rest of the data in the structure
meaningless. meaningless.
@ -184,13 +208,16 @@ a fatal error.
.br .br
\fIEM_error\fR contains an \fIEM_error\fR contains an
error message. error message.
.IP "EM_EOF none" \nau
end of file
.PD .PD
.PP .PP
The \fIe_args\fR structure consists of the fields The \fIe_arg\fR structure consists of the fields
\fIem_next\fR, containing a pointer to the next argument or null, the field \fIems_argtype\fR, containing the type of this argument or 0
the field \fIem_argtype\fR, containing the type of this argument, and if absent,
the field \fIem_value\fR, containing the value of the argument. the field \fIems_arg\fR, containing the value of the argument,
The possible values of \fIem_argtype\fR, defined in <em_ptyp.h>, 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: are summarized below:
.br .br
.ta \w'dlb_ptyp\ \ \ \ 'u +\w'em_opcode\ \ \ 'u .ta \w'dlb_ptyp\ \ \ \ 'u +\w'em_opcode\ \ \ 'u
@ -200,50 +227,52 @@ are summarized below:
.di .di
.IP "Value Selector" \nau .IP "Value Selector" \nau
Meaning Meaning
.IP "ilb_ptyp em_ilb" \nau .IP "0 none" \nau
no argument.
.IP "ilb_ptyp emu_ilb" \nau
an instruction label. an instruction label.
.PD 0 .PD 0
.IP "nof_ptyp em_dlb" \nau .IP "nof_ptyp emu_dlb" \nau
an offset from a numeric data label. an offset from a numeric data label.
.IP " em_noff" \nau .IP " ems_szoroff" \nau
The The
\fIem_noff\fR field contains the offset and the \fIems_szodiff\fR field contains the offset and the
\fIem_dlb\fR field contains the label. \fIemu_dlb\fR field contains the label.
.IP "sof_ptyp em_dnam" \nau .IP "sof_ptyp emu_dnam" \nau
an offset from a non-numeric data label. an offset from a non-numeric data label.
.IP " em_soff" \nau .IP " ems_szoroff" \nau
The \fIem_soff\fR field contains the offset and the \fIem_dnam\fR field The \fIems_szoroff\fR field contains the offset and the \fIemu_dnam\fR field
contains the label, represented as a string. contains the label, represented as a string.
.IP "cst_ptyp em_cst" \nau .IP "cst_ptyp emu_cst" \nau
a numeric constant. a numeric constant.
.IP "pro_ptyp em_pnam" \nau .IP "pro_ptyp emu_pnam" \nau
a procedure name, not including the '$', a procedure name, not including the '$',
represented as a string. represented as a string.
.IP "str_ptyp em_str" \nau .IP "str_ptyp emu_string" \nau
a string constant. a string constant.
.IP " em_size" \nau .IP " ems_szoroff" \nau
The string is found in \fIem_str\fR, represented as a row of bytes, of The string is found in \fIemu_string\fR, represented as a row of bytes, of
length \fIem_size\fR. length \fIems_szoroff\fR.
.IP "ico_ptyp em_str" \nau .IP "ico_ptyp emu_string" \nau
an integer constant. an integer constant.
.IP " em_size" \nau .IP " ems_szoroff" \nau
A string representation of the constant is found in \fIem_str\fR. A string representation of the constant is found in \fIemu_string\fR.
It has size \fIem_size\fR bytes on the target machine. It has size \fIems_szoroff\fR bytes on the target machine.
.IP "uco_ptyp em_str" \nau .IP "uco_ptyp emu_string" \nau
an unsigned constant. an unsigned constant.
.IP " em_size" \nau .IP " ems_szoroff" \nau
A string representation of the constant is found in \fIem_str\fR. A string representation of the constant is found in \fIemu_string\fR.
It has size \fIem_size\fR bytes on the target machine. It has size \fIems_szoroff\fR bytes on the target machine.
.IP "fco_ptyp em_str" \nau .IP "fco_ptyp emu_string" \nau
a floating constant. a floating constant.
.IP " em_size" \nau .IP " ems_szoroff" \nau
A string representation of the constant is found in \fIem_str\fR. A string representation of the constant is found in \fIemu_string\fR.
It has size \fIem_size\fR bytes on the target machine. It has size \fIems_szoroff\fR bytes on the target machine.
.PD .PD
.PP .PP
When an error occurs, \fIEM_error\fR is set to indicate the reason. 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 \fIEM_getinstr\fR returns 1 if all goes well, 0 if it does not.
occurred. The EM_ERROR described above is only set when the error The EM_ERROR described above is only set when the error
is serious enough. is serious enough.
.PP .PP
The routine \fIEM_mkcalls\fR "translates" the EM instruction indicated 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 A.S. Tanenbaum, H. v Staveren, E.G. Keizer, J.W. Stevenson, "\fBDescription
of a Machine Architecture for use with Block Structured Languages\fR", of a Machine Architecture for use with Block Structured Languages\fR",
Informatica Rapport IR-81, Vrije Universiteit, Amsterdam, 1983. Informatica Rapport IR-81, Vrije Universiteit, Amsterdam, 1983.
.SH DIAGNOSTICS
\fIEM_getinstr\fR returns a null pointer on end of file.
.SH REMARKS .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. must be copied to be saved.
.SH BUGS .SH BUGS
As CON's and ROM's may be delivered in several parts, the count fields in 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 .PP
Please report bugs to the author. Please report bugs to the author.
.SH 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 */ #define STRSIZ 256 /* Maximum length of strings */
static struct e_instr emhead; /* Where we put the head */ static struct e_instr *emhead; /* Where we put the head */
static struct e_args emargs[NARGS+2]; /* Where we put the arguments. static struct e_instr aheads[3];
We need some more because some static int ahead;
arguments are constructed
*/
static struct e_args *i_emargs;
#define argentry() (i_emargs++)
static struct string { static struct string {
int length; int length;
char str[STRSIZ + 1]; char str[STRSIZ + 1];
} strings[NARGS]; /* Room for strings */ } string;
static struct string *i_strings; /* Index of last one used */
#define stringentry() (i_strings++)
static struct e_args *argp; /* Indicates arguments yet to be
delivered
*/
#ifdef COMPACT #ifdef COMPACT
static arith strleft; /* count # of chars left to read static arith strleft; /* count # of chars left to read
in a string in a string
@ -104,11 +95,10 @@ static long wordmask[] = { /* allowed bits in a word */
}; };
static int wsize, psize; /* word size and pointer size */ static int wsize, psize; /* word size and pointer size */
int EM_wordsize, EM_pointersize;
#ifdef CHECKING #ifdef CHECKING
static char *argrange = "Argument range error"; 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 #else not CHECKING
#define check(x) /* nothing */ #define check(x) /* nothing */
#endif CHECKING #endif CHECKING
@ -120,7 +110,7 @@ PRIVATE
xerror(s) xerror(s)
char *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; if (!EM_error) EM_error = s;
} }
@ -129,7 +119,7 @@ PRIVATE
xfatal(s) xfatal(s)
char *s; char *s;
{ {
emhead.em_type = EM_FATAL; emhead->em_type = EM_FATAL;
if (!EM_error) EM_error = s; if (!EM_error) EM_error = s;
} }
@ -196,68 +186,59 @@ PRIVATE
startmes(p) startmes(p)
register struct e_instr *p; register struct e_instr *p;
{ {
register struct e_args *ap;
ap = getarg(cst_ptyp); getarg(cst_ptyp, &(p->em_arg));
p->em_arg = ap;
state = MES; state = MES;
if (ap->em_cst == ms_emx) { if (p->em_cst == ms_emx) {
if (wsize || psize) { if (wsize || psize) {
if (!EM_error) EM_error = "Duplicate ms_emx"; if (!EM_error) EM_error = "Duplicate ms_emx";
} }
argp = ap = getarg(cst_ptyp); p = &aheads[ahead++];
wsize = ap->em_cst; getarg(cst_ptyp, &(p->em_arg));
EM_wordsize = ap->em_cst; wsize = p->em_cst;
ap->em_next = getarg(cst_ptyp); EM_wordsize = p->em_cst;
ap = ap->em_next; p->em_type = EM_MESARG;
psize = ap->em_cst; p = &aheads[ahead++];
EM_pointersize = ap->em_cst; 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" /* EM_getinstr: read an "EM_line"
*/ */
EXPORT struct e_instr * EXPORT int
EM_getinstr() 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; EM_error = 0;
if (ahead) {
*p = aheads[--ahead];
return 1;
}
emhead = p;
#ifdef CHECKING #ifdef CHECKING
if (!EM_initialized) { if (!EM_initialized) {
EM_error = "Initialization not done"; EM_error = "Initialization not done";
p->em_type = EM_FATAL; p->em_type = EM_FATAL;
return p; return 0;
} }
#endif CHECKING #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 */ if (!state) { /* All clear, get a new line */
p = gethead(); gethead(p);
if (!p) { /* End of file */
return p;
}
switch(p->em_type) { switch(p->em_type) {
case EM_EOF:
return EM_error == 0;
case EM_MNEM: { case EM_MNEM: {
register int i,j; register int i,j;
register struct e_args *ap;
extern char em_flag[]; extern char em_flag[];
extern short em_ptyp[]; extern short em_ptyp[];
p->em_args = 0;
j = em_flag[p->em_opcode - sp_fmnem] & EM_PAR; j = em_flag[p->em_opcode - sp_fmnem] & EM_PAR;
i = em_ptyp[j]; i = em_ptyp[j];
if (j == PAR_NO) { /* No arguments */ if (j == PAR_NO) { /* No arguments */
@ -266,11 +247,11 @@ EM_getinstr()
#ifndef COMPACT #ifndef COMPACT
if (j == PAR_B) i = ptyp(sp_ilb2); if (j == PAR_B) i = ptyp(sp_ilb2);
#endif COMPACT #endif COMPACT
ap = getarg(i); getarg(i, &(p->em_arg));
#ifndef COMPACT #ifndef COMPACT
if (j == PAR_B) { if (j == PAR_B) {
ap->em_cst = ap->em_ilb; p->em_cst = p->em_ilb;
ap->em_argtype = cst_ptyp; p->em_argtype = cst_ptyp;
} }
#endif COMPACT #endif COMPACT
/* range checking /* range checking
@ -278,48 +259,47 @@ EM_getinstr()
#ifdef CHECKING #ifdef CHECKING
if (wsize <= 4 && psize <= 4) switch(j) { if (wsize <= 4 && psize <= 4) switch(j) {
case PAR_B: case PAR_B:
check(ap->em_cst <= 32767); check(p->em_cst <= 32767);
/* Fall through */ /* Fall through */
case PAR_N: case PAR_N:
check(ap->em_cst >= 0); check(p->em_cst >= 0);
break; break;
case PAR_G: case PAR_G:
if (ap->em_argtype == cst_ptyp) { if (p->em_argtype == cst_ptyp) {
check(ap->em_cst >= 0); check(p->em_cst >= 0);
} }
/* Fall through */ /* Fall through */
case PAR_F: case PAR_F:
/* ??? not in original em_decode or em_encode */ /* ??? not in original em_decode or em_encode */
case PAR_L: case PAR_L:
{ arith m = ap->em_cst >= 0 ? ap->em_cst : { arith m = p->em_cst >= 0 ? p->em_cst :
- ap->em_cst; - p->em_cst;
/* Check that the number fits in a pointer */ /* Check that the number fits in a pointer */
check((m & ~wordmask[psize]) == 0); check((m & ~wordmask[psize]) == 0);
break; break;
} }
case PAR_W: case PAR_W:
if (!ap) break; if (p->em_argtype == 0) break;
check((ap->em_cst & ~wordmask[wsize]) == 0); check((p->em_cst & ~wordmask[wsize]) == 0);
/* Fall through */ /* Fall through */
case PAR_S: case PAR_S:
check(ap->em_cst > 0); check(p->em_cst > 0);
/* Fall through */ /* Fall through */
case PAR_Z: case PAR_Z:
check(ap->em_cst >= 0 && check(p->em_cst >= 0 &&
ap->em_cst % wsize == 0); p->em_cst % wsize == 0);
break; break;
case PAR_O: case PAR_O:
check(ap->em_cst > 0 && check(p->em_cst > 0 &&
( ap->em_cst % wsize == 0 || ( p->em_cst % wsize == 0 ||
wsize % ap->em_cst == 0)); wsize % p->em_cst == 0));
break; break;
case PAR_R: case PAR_R:
check(ap->em_cst >= 0 && ap->em_cst <= 2); check(p->em_cst >= 0 && p->em_cst <= 2);
break; break;
} }
#endif CHECKING #endif CHECKING
p->em_args = ap;
#ifndef COMPACT #ifndef COMPACT
checkeol(); checkeol();
#endif COMPACT #endif COMPACT
@ -332,18 +312,20 @@ EM_getinstr()
type ROM or CON is in process type ROM or CON is in process
*/ */
{ {
register struct e_args *ap = 0, *ap1; struct e_arg dummy;
switch(p->em_opcode) { switch(p->em_opcode) {
case ps_bss: case ps_bss:
case ps_hol: case ps_hol:
ap = getarg(cst_ptyp); getarg(cst_ptyp, &dummy);
ap->em_next = ap1 = getarg(par_ptyp); em_holsize = dummy.ema_cst;
ap->em_next->em_next = ap1 = getarg(cst_ptyp); getarg(par_ptyp, &(p->em_arg));
getarg(cst_ptyp, &dummy);
em_holinit = dummy.ema_cst;
#ifdef CHECKING #ifdef CHECKING
/* Check that the last value is 0 or 1 /* 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) if (! EM_error)
EM_error="Third argument of hol/bss not 0/1"; EM_error="Third argument of hol/bss not 0/1";
} }
@ -351,36 +333,41 @@ EM_getinstr()
break; break;
case ps_exa: case ps_exa:
case ps_ina: case ps_ina:
ap = getarg(lab_ptyp); getarg(lab_ptyp, &(p->em_arg));
break; break;
case ps_exp: case ps_exp:
case ps_inp: case ps_inp:
ap = getarg(pro_ptyp); getarg(pro_ptyp, &(p->em_arg));
break; break;
case ps_exc: case ps_exc:
ap = getarg(cst_ptyp); getarg(cst_ptyp, &dummy);
ap->em_next = getarg(cst_ptyp); p->em_exc1 = dummy.ema_cst;
getarg(cst_ptyp, &dummy);
p->em_exc2 = dummy.ema_cst;
break; break;
case ps_pro: case ps_pro:
ap = getarg(pro_ptyp); getarg(pro_ptyp, &(p->em_arg));
ap->em_next = getarg(cst_ptyp|ptyp(sp_cend)); getarg(cst_ptyp|ptyp(sp_cend), &dummy);
if (dummy.ems_argtype == 0) {
p->em_off = -1;
}
else p->em_off = dummy.ema_cst;
break; break;
case ps_end: case ps_end:
ap = getarg(cst_ptyp|ptyp(sp_cend)); getarg(cst_ptyp|ptyp(sp_cend), &(p->em_arg));
break; break;
case ps_con: case ps_con:
ap = getarg(val_ptyp); getarg(val_ptyp, &(p->em_arg));
state |= CON; state |= CON;
break; break;
case ps_rom: case ps_rom:
ap = getarg(val_ptyp); getarg(val_ptyp, &(p->em_arg));
state |= ROM; state |= ROM;
break; break;
default: default:
xerror("Bad pseudo"); xerror("Bad pseudo");
break; break;
} }
p->em_args = ap;
} }
#ifndef COMPACT #ifndef COMPACT
if (p->em_opcode != ps_con && p->em_opcode != ps_rom) { if (p->em_opcode != ps_con && p->em_opcode != ps_rom) {
@ -397,7 +384,7 @@ EM_getinstr()
psize = 2; psize = 2;
EM_error = "EM code should start with mes 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. if (state & INSTRING) { /* We already delivered part of a string.
@ -406,11 +393,9 @@ EM_getinstr()
register struct string *s; register struct string *s;
s = getstring(0); s = getstring(0);
args = argentry(); p->em_argtype = str_ptyp;
args->em_next = 0; p->em_string = s->str;
args->em_argtype = str_ptyp; p->em_size = s->length;
args->em_str = s->str;
args->em_size = s->length;
switch(state & PSEUMASK) { switch(state & PSEUMASK) {
default: default:
assert(0); assert(0);
@ -418,50 +403,45 @@ EM_getinstr()
if (!EM_error) if (!EM_error)
EM_error = "String too long in message"; EM_error = "String too long in message";
p->em_type = EM_MESARG; p->em_type = EM_MESARG;
p->em_arg = args;
break; break;
case CON: case CON:
p->em_type = EM_PSEU; p->em_type = EM_PSEU;
p->em_opcode = ps_con; p->em_opcode = ps_con;
p->em_args = args;
break; break;
case ROM: case ROM:
p->em_type = EM_PSEU; p->em_type = EM_PSEU;
p->em_opcode = ps_rom; p->em_opcode = ps_rom;
p->em_args = args;
break; break;
} }
return p; return EM_error == 0;
} }
/* Here, we are in a state reading arguments */ /* 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) { 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 #ifndef COMPACT
checkeol(); checkeol();
#endif #endif
if (state == MES) { if (state == MES) {
state = 0; state = 0;
p->em_type = EM_ENDMES; p->em_type = EM_ENDMES;
return p; return EM_error == 0;
} }
/* Here, we have to get the next instruction */ /* Here, we have to get the next instruction */
state = 0; state = 0;
return EM_getinstr(); return EM_getinstr(p);
} }
/* Here, there was an argument */ /* Here, there was an argument */
if (state == MES) { if (state == MES) {
p->em_type = EM_MESARG; p->em_type = EM_MESARG;
p->em_arg = args; return EM_error == 0;
return p;
} }
p->em_type = EM_PSEU; p->em_type = EM_PSEU;
p->em_args = args;
if (state == CON) p->em_opcode = ps_con; if (state == CON) p->em_opcode = ps_con;
else p->em_opcode = ps_rom; else p->em_opcode = ps_rom;
return p; return EM_error == 0;
} }

View file

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

View file

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