READ_EM(3ACK)

NAME
EM_open, EM_getinstr, EM_close, EM_mkcalls - a module to read EM assembly code

SYNOPSIS
#include <em_spec.h>
#include <em_mnem.h>
#include <em_pseu.h>
#include <em_flag.h>
#include <em_ptyp.h>
#include <em.h>
#include <em_comp.h>

int EM_open(filename)
EM_close()
char *filename;

struct e_instr *EM_getinstr()

int EM_mkcalls(instr)
struct e_instr *instr;

char *EM_error;

unsigned int EM_lineno;

char *EM_filename;

int EM_wordsize, EM_pointersize;

DESCRIPTION
This package provides routines to read EM assembly code. The object is to simplify the program writer's task of reading EM assembly code, either in compact or human-readable form.

EM_open must be called as initializer of the package. If filename is a null pointer, reading is done from standard input, otherwise it is done from the file filename. EM_open returns 1 on success and 0 on failure with an error message in EM_error. EM_close must be called after all other calls to this package.

EM_getinstr reads an EM instruction, and returns it as a pointer to a structure having the following layout:

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    em_i.emu_mp.emus_opcode
#define em_argsem_i.emu_mp.emus_args
#define em_deflbem_i.emu_deflb
#define em_defdnamem_i.emu_defdnam
#define em_argem_i.emu_arg
};

Possible arguments to the EM instruction read are supplied in a linked list of structures:

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_cstem_value.emu_cst
#define em_ilbem_value.emu_ilb
#define em_pnamem_value.emu_pnam
#define em_dlbem_value.emu_ndlb.emus_dlb
#define em_noffem_value.emu_ndlb.emus_noff
#define em_dnamem_value.emu_sdlb.emus_dnam
#define em_soffem_value.emu_sdlb.emus_soff
#define em_strem_value.emu_con.emus_str
#define em_sizeem_value.emu_con.emus_size
};

The named types arith and label refer to types on the local machine that are suitable for doing arithmetic and storing EM numeric labels respectively. Common definitions are long for arith and unsigned int for label.

The e_instr structure consists of the fields em_type, containing the type of this e_instr, and em_i, containing its value of this e_instr.

The possible values of em_type, defined in <em_comp.h>, are summarized below:

Value	Selector
    Meaning

EM_MNEM	em_opcode
    an EM machine instruction.
em_args
    The em_opcode field contains the opcode of the instruction, and em_args may indicate arguments.
EM_PSEU	em_opcode
    an EM pseudo instruction.
em_args
    The em_opcode field contains the opcode, and em_args may indicate arguments. As consecutive CON-pseudos are allocated consecutively, a CON delivered by EM_getinstr 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.
EM_STARTMES	em_arg
    the start of a MES pseudo.
    There is one argument: the message number. The other arguments, if any, are delivered as separate EM_MESARG's.
EM_MESARG	em_arg
    an argument of a MES pseudo.
EM_ENDMES	none
    the end of a MES pseudo.
EM_DEFILB	em_deflb
    an instruction label definition.
    The field em_deflb contains the label (instruction labels are always numeric).
EM_DEFDLB	em_deflb
    a numeric data label definition.
    The field em_deflb contains the label.
EM_DEFDNAM	em_defdnam
    a non-numeric data label definition.
    The field em_defdnam contains the label.
EM_ERROR	none
    an error in the input.
    EM_error contains an error message.
EM_FATAL	none
    a fatal error.
    EM_error contains an error message.

The e_args structure consists of the fields em_next, containing a pointer to the next argument or null, the field em_argtype, containing the type of this argument, and the field em_value, containing the value of the argument. The possible values of em_argtype, defined in <em_ptyp.h>, are summarized below:

Value	Selector
    Meaning

ilb_ptyp	em_ilb
    an instruction label.
nof_ptyp	em_dlb
    an offset from a numeric data label.
em_noff
    The em_noff field contains the offset and the em_dlb field contains the label.
sof_ptyp	em_dnam
    an offset from a non-numeric data label.
em_soff
    The em_soff field contains the offset and the em_dnam field contains the label, represented as a string.
cst_ptyp	em_cst
    a numeric constant.
pro_ptyp	em_pnam
    a procedure name, not including the '$', represented as a string.
str_ptyp	em_str
    a string constant.
em_size
    The string is found in em_str, represented as a row of bytes, of length em_size.
ico_ptyp	em_str
    an integer constant.
em_size
    A string representation of the constant is found in em_str. It has size em_size bytes on the target machine.
uco_ptyp	em_str
    an unsigned constant.
em_size
    A string representation of the constant is found in em_str. It has size em_size bytes on the target machine.
fco_ptyp	em_str
    a floating constant.
em_size
    A string representation of the constant is found in em_str. It has size em_size bytes on the target machine.

The routine EM_mkcalls "translates" the EM instruction indicated by instr into calls of the procedural interface defined in em_code(3L). It returns 1 if it succeeds, 0 if it fails for some reason. The reason can then be found in EM_error.

EM_lineno contains the line number of the last line read by EM_getinstr.

EM_filename contains a filename. It usually contains the value given as parameter to EM_open, but may have a different value, when the input was the result of some preprocessing.

EM_wordsize and EM_pointersize contain the wordsize and pointersize, but only after the first (pseudo-)instruction has successfully been read.

FILES
~em/modules/h/em.h
~em/h/em_ptyp.h
~em/modules/h/em_comp.h
~em/modules/lib/libread_emk.a: non-checking library for reading compact EM code
~em/modules/lib/libread_emkV.a: checking library for reading compact EM code
~em/modules/lib/libread_emeV.a: checking library for reading human-readable EM code

MODULES
em_code(3), string(3), system(3), ~em/lib/em_data.a

SEE ALSO
em_code(3)
A.S. Tanenbaum, H. v Staveren, E.G. Keizer, J.W. Stevenson, "Description of a Machine Architecture for use with Block Structured Languages", Informatica Rapport IR-81, Vrije Universiteit, Amsterdam, 1983.

DIAGNOSTICS
EM_getinstr returns a null pointer on end of file.

REMARKS
All information must be considered to be contained in a static area so it must be copied to be saved.

BUGS
As CON's and ROM's may be delivered in several parts, the count fields in a static exchange may be wrong.

Please report bugs to the author.

AUTHOR
Ceriel J.H. Jacobs <ceriel@vu44.UUCP>