.TH EM_CODE 3 "$Revision$" .ad .SH NAME emcode \- EM code interface for compilers .SH SYNOPSIS .nf .B #include .PP .B void C_init(wsize, psize) .B arith wsize, psize; .PP .B int C_open(filename) .B void C_close() .B int C_busy() .B char *filename; .PP .B void C_magic() .PP .B void C_df_dlb(l) .B void C_df_dnam(s) .B void C_df_ilb(l) .B label l; char *s; .PP .B void C_pro(s, l) .B void C_pro_narg(s) .B void C_end(l) .B void C_end_narg() .B char *s; arith l; .PP .B void C_exa_dlb(l) .B void C_exa_dnam(s) .B void C_exp(s) .B void C_ina_dlb(l) .B void C_ina_dnam(s) .B void C_inp(s) .B char *s; label l; .PP .BI "void C_bss_" cstp () .BI "void C_hol_" cstp () .BI "void C_con_" cstp () .BI "void C_rom_" cstp () .PP .B #include .B void C_mes_begin(ms) .BI "void C_" cstp () .B void C_mes_end() .B int ms; .PP .B void C_exc(c1, c2) .B arith c1, c2; .PP .BI "void C_" mnem () .BI "void C_" mnem _dlb() .BI "void C_" mnem _dnam() .BI "void C_" mnem _narg() .PP .B void C_insertpart(id) .B int id; .PP .B void C_beginpart(id) .B int id; .PP .B void C_endpart(id) .B int id; .PP .B int C_getid() .PP .B char *C_tmpdir; .PP .B #include .PP .B int C_out(p) .B struct e_instr *p; .PP .B char *C_error; .fi .SH DESCRIPTION This package provides a procedural EM code interface to be used in compilers and other EM code producing programs. The basic idea behind this package is to simplify the program writer's task of producing EM code in any form, either compact or human-readable EM assembly code or a sequence of procedure calls. .PP The named types .B arith and .B label refer to types on the local machine that are suitable for doing arithmetics and storing EM numeric labels respectively. Common definitions are .B long for .B arith and .B unsigned int for .BR label . .PP .B C_init() should be called to initialize the module. .I Wsize is the word size and .I psize the pointer size on the target machine. Checking implementations of this module use these values to check whether arguments of an instruction are legal. .PP .BI C_open( filename ) should be invoked as initialiser for a sequence of calls that produce EM code on file .IR filename . When .I filename is a null pointer, the code is produced on standard output. Some implementations, such as fast back ends, may ignore the parameter. .B C_close causes some internal buffers to be flushed and the output file to be closed. All subsequent routines, except for .BR C_busy , must be invoked between the calls to .B C_open and .BR C_close . .PP .B C_busy can be invoked in order to detect whether EM code is currently being generated, i.e. whether .B C_open is invoked without a corresponding .BR C_close . If this is the case, .B C_busy returns a 1. .PP .B C_magic() produces the EM magic word. .PP Two routines can be used to generate code for the definitions of global data labels: .BI C_df_dlb( l ) for numeric labels .BI . l and .BI C_df_dnam( s ) for alphanumeric labels .IR s . .PP .BI C_df_ilb( l ) produces EM code for instruction label .IR l . .PP The routines for producing the EM procedure delimiters are: .PP .RS .TS box; l|l. routine EM pattern = \&\fBC_pro(\fP\fIs\fP\fB,\ \fP\fIl\fP\fB)\fP \fBpro\ \fP\fIs\fP\fB,\ \fP\fIl\fP _ \&\fBC_pro_narg(\fP\fIs\fP\fB)\fP \fBpro\ \fP\fIs\fP\fB,\ ?\fP _ \&\fBC_end(\fP\fIl\fP\fB)\fP \fBend\ \fP\fIl\fP _ \&\fBC_end_narg()\fP \fBend\ ?\fP .TE .RE .PP A set of routines, concerning the scope definition pseudo instructions, is: .PP .RS .TS box; l|l. routine EM pattern = \&\fBC_exa_dnam(\fP\fIs\fP\fB)\fP \fBexa \fP\fIs\fP _ \&\fBC_exa_dlb(\fP\fIl\fP\fB)\fP \fBexa .\fP\fIl\fP _ \&\fBC_exp(\fP\fIs\fP\fB)\fP \fBexp $\fP\fIs\fP _ \&\fBC_ina_dnam(\fP\fIs\fP\fB)\fP \fBina \fP\fIs\fP _ \&\fBC_ina_dlb(\fP\fIl\fP\fB)\fP \fBina .\fP\fIl\fP _ \&\fBC_inp(\fP\fIs\fP\fB)\fP \fBinp $\fP\fIs\fP .TE .RE .PP In the set of .B storage-declaration pseudo instructions, we can distinguish four groups, one for each type of storage declaration: .BR con , .BR rom , .B bss and .BR hol . .PP The .BR con / rom instructions are generated by .BI C_con_ cstp and .BI C_rom_ cstp , respectively. The type of the initialization value and the number and type of the parameters are determined by .I cstp according to the following table: .PP .RS .TS box; l|l|l|l l|l|l|l l|n|l|l. \&\fIcstp\fP number of type of description parameters parameters = \&\fBcst\fP 1 \fBarith\fP word-sized integer of \fBarith\fP-type _ \&\fBicon\fP 2 \fBchar *\fP integer in string representation \fBarith\fP number of bytes on target machine _ \&\fBucon\fP 2 \fBchar *\fP unsigned integer in string representation \fBarith\fP number of bytes on target machine _ \&\fBfcon\fP 2 \fBchar *\fP floating in string representation \fBarith\fP number of bytes on target machine _ \&\fBscon\fP 2 \fBchar *\fP row of bytes \fBarith\fP length of the row of bytes _ \&\fBdnam\fP 2 \fBchar *\fP alphanumeric global data label \fBarith\fP offset (possibly 0) _ \&\fBdlb\fP 2 \fBlabel\fP numeric global data label \fBarith\fP offset (possibly 0) _ \&\fBilb\fP 1 \fBlabel\fP instruction label _ \&\fBpnam\fP 1 \fBchar *\fP procedure identifier .TE .RE .PP As an example of the use of the .BR con / rom routines, consider the following .B con instruction: .RS con 23I4, "hello world", .12, table + 12, *33 .RE A sequence of calls to get this, is .RS .nf C_con_icon("23", (arith)4); C_con_scon("hello world", (arith) 11); C_con_dlb((label)12, (arith)0); C_con_dnam("table", (arith)12); C_con_ilb((label)33); .fi .RE .PP A .B bss or .B hol instruction is produced by invoking .BI C_bss_ cstp or .BI C_hol_ cstp where .I cstp indicates the type of value that is used at initialisation. The parameter list of .BI C_bss_ cstp and .BI C_hol_ cstp is similar to that of the corresponding .BI C_con_ cstp, except that it is preceeded by an .BR arith -typed operand .I nbytes, and followed by an .BR int -typed operand .IR init ; .I nbytes indicates the number of bytes to reserve for the data; .I init has value 1 if the initialization is strictly necessary and 0 if not. Note that, according to the EM definition, an initialisation type of .B scon is not allowed in the .BR bss / hol instruction. .PP Another set of routines is that of the EM .B mes pseudo instructions. As there is an undefined number of messages and each type of message has its own number of parameters and each parameter its own type, the user is responsible for building his own message lists. Such a list consists of a list of .BI C_ cstp routine calls enclosed by .BI C_mes_begin( ms ) where .I ms is the message number, and .BR C_mes_end() . .PP .I C_exc produces the EM .B exc .IR c1 , c2 instruction. The use of this function may cause trouble in some implementations of this module. A fast back end, for instance, may refuse to implement .IR C_exc . The use of this function is therefore not recommended. .PP The final class of routines is that of the EM machine-instruction generating routines .BI C_ mnem, .BI C_ mnem _dlb , .BI C_ mnem _dnam and .BI C_ mnem _narg . The best way to describe them is according to section 11.3 of [EM]. Depending on the class of the argument (as indicated by a letter), one or more routines are available for each machine instruction. The following table gives an overview of the available routines for the EM machine instruction .IR mnem : .PP .RS .TS box; l|l|l|l l|l|l|l l|l|n|l. class routine(s) number of type of parameters parameter(s) = [\fBcdflnorsz\fP] \fBC_\fP\fImnem\fP 1 \fBarith\fP _ \&\fBw\fP \fBC_\fP\fImnem\fP 1 \fBarith\fP \fBC_\fP\fImnem\fP\fB_narg\fP 0 _ \&\fBg\fP \fBC_\fP\fImnem\fP 1 \fBarith\fP \fBC_\fP\fImnem\fP\fB_dnam\fP 2 \fBchar *\fP \fBarith\fP \fBC_\fP\fImnem\fP\fB_dlb\fP 2 \fBlabel\fP \fBarith\fP _ \&\fBp\fP \fBC_\fP\fImnem\fP 1 \fBchar *\fP _ \&\fBb\fP \fBC_\fP\fImnem\fP 1 \fBlabel\fP _ \&\fB\-\fP \fBC_\fP\fImnem\fP 0 .TE .RE .PP The available routines for, for example, the EM machine instruction .B adi (with argument class .BR w ) are .BI C_adi( w ) for .B adi with a given argument, and .B C_adi_narg() for .B adi with an argument on top of the stack. Likewise are the available routines for .BR loe (which instruction has argument class .BR g ): .BI C_loe( g ) where .I g is a constant, .BI C_loe_dnam( g , o ) where .I g is an alphanumeric label, and .BI C_loe_dlb( g , o ) where .I g is a numeric label. The latter two routines have the (possibly zero) offset .I o as second parameter. .PP The .IR C_insertpart , .IR C_beginpart , and .I C_endpart routines together implement a mechanism for re-arranging the generated code. A call to .I C_insertpart indicates that part .I id is to be inserted at the current position. The routines .I C_beginpart and .I C_endpart indicate begin and end of part .IR id . The order in which the parts are defined is not significant. However, when .I C_close is called, all parts that have been inserted, must also be defined. Parts may themselves again have sub-parts. .PP The routine .I C_getid can be used to obtain a valid and unique part .IR id . .PP On implementations with limited memory, the mechanism is implemented with a temporary file. The directory in which this file resides is indicated by .IR C_tmpdir . The default is the #define TMP_DIR from ~em/h/em_path.h. The user can change this by just changing .I C_tmpdir before calling .IR C_open. .PP .I C_out accepts a structure as delivered by the .I read_em module, and produces code for it. It returns 1 if it succeeds, 0 if it fails for some reason. The reason can then be found in \fIC_error\fP. The .I C_out routine replaces the EM_mkcalls routine. .SH FILES .nf ~em/modules/h/em.h ~em/modules/lib/libemk.a: library for generating compact EM code ~em/modules/lib/libeme.a: library for generating human-readable EM code ~em/lib.bin/em_data.a: library needed when using libeme.a .fi .SH MODULES .nf libemk.a: alloc(3), system(3), string(3) libeme.a: alloc(3), print(3), system(3), string(3) .fi .SH SEE ALSO read_em(3), em_mes(3) .SH REFERENCES .IP [EM] 6 Andrew S. Tanenbaum, Hans van Staveren, Ed G. Keizer, Johan W. Stevenson, .B "Description of a Machine Architecture for use with Block Structured Languages", Informatica Rapport IR-81, Vrije Universiteit, Amsterdam, 1983. .LP .SH DIAGNOSTICS .I C_open returns 1 if the open is successful and 0 if not. .PP When a read, write or open fails, the routine .I C_failed is called. The user can override its default definition by supplying his own. The default just gives an error message and quits. .PP When an error occurs with the .I C_insertpart mechanism, the routine .I C_internal_error is called. Again, the user can override its default definition by supplying his own. Such errors, however, are caused by a programming error of the user. .SH REMARKS Some of the routines in this module may be implemented as macros. So, do not try to take the address of these functions. .SH BUGS It is not possible to indicate that the argument of .B C_con_cst () must be seen as an unsigned value.