ANSI C conversion of code, adapt man pages accordingly. Some autodocs added.
This commit is contained in:
parent
8b290cf68a
commit
3466e84f46
|
@ -6,7 +6,7 @@
|
|||
|
||||
/* Variables must be declared somewhere ... */
|
||||
|
||||
#include <em_arith.h>
|
||||
#include "em_arith.h"
|
||||
|
||||
char *EM_error = 0;
|
||||
char *EM_filename = 0;
|
||||
|
|
|
@ -2,22 +2,34 @@
|
|||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/** @file
|
||||
* A module to read EM assembly code in either
|
||||
* human readable format or in compact format.
|
||||
* It only permits to have one file open at a time,
|
||||
* because it contains global variables.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
#ifndef __EMCOMP_INCLUDED__
|
||||
#define __EMCOMP_INCLUDED__
|
||||
|
||||
#include <ansi.h>
|
||||
#include "em_arith.h"
|
||||
#include "em_label.h"
|
||||
|
||||
/** Represents instruction arguments. */
|
||||
struct e_arg {
|
||||
int ema_argtype; /* type of this argument */
|
||||
/** Type of this argument. The different argument
|
||||
* types are defined in `em_ptyp.h` */
|
||||
int ema_argtype;
|
||||
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) */
|
||||
} ema_arg;
|
||||
arith emu_cst; /**< a constant */
|
||||
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) */
|
||||
} ema_arg; /**< The actual argument, a union representing the args. */
|
||||
arith ema_szoroff;
|
||||
};
|
||||
#define ema_cst ema_arg.emu_cst
|
||||
|
@ -28,40 +40,53 @@ struct e_arg {
|
|||
#define ema_nlocals ema_szoroff
|
||||
#define ema_string ema_arg.emu_string
|
||||
|
||||
|
||||
/** Represents an instruction and its arguments. */
|
||||
struct e_instr {
|
||||
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;
|
||||
int em_type; /**< Type of this instruction
|
||||
, one of the EM_XXXX constants. */
|
||||
#define EM_MNEM 256 /**< A machine instruction type */
|
||||
#define EM_PSEU 257 /**< A pseudo instruction type */
|
||||
#define EM_STARTMES 258 /**< Start of a MES pseudo instruction */
|
||||
#define EM_MESARG 259 /**< A MES argument type */
|
||||
#define EM_ENDMES 260 /**< End of a MES type */
|
||||
#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 definition */
|
||||
#define EM_ERROR 264 /**< Recoverable error */
|
||||
#define EM_FATAL 265 /**< Unrecoverable error */
|
||||
#define EM_EOF 266 /**< End of file */
|
||||
int em_opcode; /**< opcode of the instruction. */
|
||||
struct e_arg em_arg; /**< argument of the instruction. */
|
||||
};
|
||||
|
||||
_PROTOTYPE(int EM_open, (char *));
|
||||
_PROTOTYPE(void EM_close, (void));
|
||||
_PROTOTYPE(int EM_getinstr, (struct e_instr *));
|
||||
_PROTOTYPE(int EM_mkcalls, (struct e_instr *));
|
||||
/** Initializes library to read from the specified file `filename`. If
|
||||
* `filename` is a NULL pointer, reading is done from standard input.
|
||||
* Returns 1 on success or 0 on failure with an error message in `EM_error`.
|
||||
*/
|
||||
int EM_open(char *filename);
|
||||
/** Closes the library by freeing the resources that were previously opened
|
||||
* using `EM_open()`.
|
||||
*/
|
||||
void EM_close(void);
|
||||
/** Reads the next EM instruction, and returns it in the structure pointed to by
|
||||
* `instr`. Returns 0 in case of error.
|
||||
*/
|
||||
int EM_getinstr(struct e_instr *instr);
|
||||
int EM_mkcalls(struct e_instr *instr);
|
||||
|
||||
extern arith
|
||||
EM_holsize;
|
||||
extern arith EM_holsize;
|
||||
/** The size of the BSS block in bytes. */
|
||||
#define EM_bsssize EM_holsize
|
||||
extern int
|
||||
EM_holinit;
|
||||
/** 1 if the value should be initialized to the specified value,
|
||||
* otherwise 0 */
|
||||
extern int EM_holinit;
|
||||
#define EM_bssinit EM_holinit
|
||||
|
||||
#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.ema_argtype
|
||||
|
||||
#define em_cst em_arg.ema_cst
|
||||
#define em_pnam em_arg.ema_pnam
|
||||
#define em_nlocals em_arg.ema_nlocals
|
||||
|
@ -75,8 +100,17 @@ extern int
|
|||
|
||||
extern char
|
||||
*EM_error, *EM_filename;
|
||||
extern unsigned int
|
||||
EM_lineno;
|
||||
extern int
|
||||
EM_wordsize, EM_pointersize;
|
||||
|
||||
/** Line number of the last line read by `EM_getinstr()`. */
|
||||
extern unsigned int EM_lineno;
|
||||
/** Word size in bytes for this EM assembly file. The
|
||||
* value is valid only after the first instruction
|
||||
* has been read.
|
||||
*/
|
||||
extern int EM_wordsize;
|
||||
/** Pointer size in bytes for this EM assembly file. The
|
||||
* value is valid only after the first instruction
|
||||
* has been read.
|
||||
*/
|
||||
extern int EM_pointersize;
|
||||
#endif /* __EMCOMP_INCLUDED__ */
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
EM_mkcalls
|
||||
*/
|
||||
|
||||
#include <em_spec.h>
|
||||
#include <em_mnem.h>
|
||||
#include <em_pseu.h>
|
||||
#include <em_flag.h>
|
||||
#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.h"
|
||||
#include "em_comp.h"
|
||||
#include <assert.h>
|
||||
|
||||
|
@ -31,9 +31,7 @@ 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 int
|
||||
checkarg(arg, typset)
|
||||
register struct e_arg *arg;
|
||||
PRIVATE int checkarg(register struct e_arg *arg, int typset)
|
||||
{
|
||||
|
||||
if (((!typset) && arg->ema_argtype) ||
|
||||
|
@ -58,9 +56,7 @@ checkarg(arg, typset)
|
|||
|
||||
/* EM_doinstr: An EM instruction
|
||||
*/
|
||||
PRIVATE void
|
||||
EM_doinstr(p)
|
||||
register struct e_instr *p;
|
||||
PRIVATE void EM_doinstr(register struct e_instr *p)
|
||||
{
|
||||
register int parametertype; /* parametertype of the instruction */
|
||||
|
||||
|
@ -94,9 +90,7 @@ EM_doinstr(p)
|
|||
#include "C_mnem.h"
|
||||
}
|
||||
|
||||
PRIVATE void
|
||||
EM_dopseudo(p)
|
||||
register struct e_instr *p;
|
||||
PRIVATE void EM_dopseudo(register struct e_instr *p)
|
||||
{
|
||||
|
||||
switch(p->em_opcode) {
|
||||
|
@ -326,9 +320,7 @@ EM_dopseudo(p)
|
|||
}
|
||||
}
|
||||
|
||||
PRIVATE void
|
||||
EM_docon(p)
|
||||
register struct e_instr *p;
|
||||
PRIVATE void EM_docon(register struct e_instr *p)
|
||||
{
|
||||
checkarg(&(p->em_arg), val_ptyp);
|
||||
switch(p->em_argtype) {
|
||||
|
@ -365,9 +357,7 @@ EM_docon(p)
|
|||
}
|
||||
}
|
||||
|
||||
PRIVATE void
|
||||
EM_dostartmes(p)
|
||||
register struct e_instr *p;
|
||||
PRIVATE void EM_dostartmes(register struct e_instr *p)
|
||||
{
|
||||
|
||||
if (listtype) {
|
||||
|
@ -379,9 +369,7 @@ EM_dostartmes(p)
|
|||
listtype = ps_mes;
|
||||
}
|
||||
|
||||
EXPORT int
|
||||
EM_mkcalls(line)
|
||||
register struct e_instr *line;
|
||||
EXPORT int EM_mkcalls(register struct e_instr *line)
|
||||
{
|
||||
|
||||
#ifdef CHECKING
|
||||
|
|
|
@ -18,18 +18,13 @@ EM_mkcalls\ \-\ a module to read EM assembly code
|
|||
.br
|
||||
.B #include <em_comp.h>
|
||||
.PP
|
||||
.B int EM_open(filename)
|
||||
.br
|
||||
.B char *filename;
|
||||
.B int EM_open(char* filename)
|
||||
.PP
|
||||
.B void EM_close()
|
||||
.B void EM_close(void)
|
||||
.PP
|
||||
.B int EM_getinstr(instr)
|
||||
.B struct e_instr *instr;
|
||||
.B int EM_getinstr(struct e_instr *instr)
|
||||
.PP
|
||||
.B int EM_mkcalls(instr)
|
||||
.br
|
||||
.B struct e_instr *instr;
|
||||
.B int EM_mkcalls(struct e_instr *instr)
|
||||
.PP
|
||||
.B char *EM_error;
|
||||
.PP
|
||||
|
@ -311,7 +306,7 @@ contain the wordsize and pointersize, but only after the first
|
|||
~em/modules/lib/libread_emeV.a: checking library for reading human-readable EM code
|
||||
.fi
|
||||
.SH MODULES
|
||||
em_code(3), string(3), system(3), ~em/lib.bin/em_data.a
|
||||
em_code(3), string(3), ~em/lib.bin/em_data.a
|
||||
.SH "SEE ALSO"
|
||||
em_code(3)
|
||||
.br
|
||||
|
|
|
@ -4,32 +4,31 @@
|
|||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* Read_em: a module to read either compact or human readable EM code.
|
||||
Exported are the following routines:
|
||||
EM_open() : has a parameter representing either a pointer to a
|
||||
filename or a null pointer, indicating that input is
|
||||
from standard input. This routine initializes for
|
||||
reading.
|
||||
EM_getinstr() : Delivers the next EM instruction in a format
|
||||
defined in <em_comp.h>.
|
||||
Imported are:
|
||||
The constants COMPACT (either defined or not defined) and
|
||||
CHECKING (again either defined or not defined),
|
||||
some routines from the system module. and the em_code module
|
||||
*/
|
||||
Exported are the following routines:
|
||||
EM_open() : has a parameter representing either a pointer to a
|
||||
filename or a null pointer, indicating that input is
|
||||
from standard input. This routine initializes for
|
||||
reading.
|
||||
EM_getinstr() : Delivers the next EM instruction in a format
|
||||
defined in <em_comp.h>.
|
||||
Imported are:
|
||||
The constants COMPACT (either defined or not defined) and
|
||||
CHECKING (again either defined or not defined),
|
||||
some routines from the system module. and the em_code module
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <alloc.h>
|
||||
#include <system.h>
|
||||
#include <em_label.h>
|
||||
#include <em_arith.h>
|
||||
#include <em_pseu.h>
|
||||
#include <em_spec.h>
|
||||
#include "alloc.h"
|
||||
#include "em_label.h"
|
||||
#include "em_arith.h"
|
||||
#include "em_pseu.h"
|
||||
#include "em_spec.h"
|
||||
#include "em_ptyp.h"
|
||||
#include "em_comp.h"
|
||||
#include <em_flag.h>
|
||||
#include <em_mes.h>
|
||||
#include "em_flag.h"
|
||||
#include "em_mes.h"
|
||||
|
||||
/* Buffered input */
|
||||
|
||||
|
@ -37,80 +36,76 @@
|
|||
#define ungetbyte(uch) ((uch) >= 0 && (*--_ich = (uch)))
|
||||
#define init_input() (_fill(), _ich--)
|
||||
|
||||
static File *fd;
|
||||
static FILE *fd;
|
||||
static char *_ich;
|
||||
|
||||
PRIVATE int
|
||||
_fill()
|
||||
PRIVATE int _fill(void)
|
||||
{
|
||||
static char text[BUFSIZ + 1];
|
||||
static int sz;
|
||||
|
||||
if (_ich && _ich < &text[sz]) return _ich++, '\0';
|
||||
if (_ich && _ich < &text[sz])
|
||||
return _ich++, '\0';
|
||||
_ich = text;
|
||||
if (sys_read(fd, text, BUFSIZ, &sz) &&
|
||||
sz > 0
|
||||
) {
|
||||
sz = fread(text, 1, BUFSIZ, fd);
|
||||
if (sz > 0)
|
||||
{
|
||||
text[sz] = '\0';
|
||||
return (*_ich++&0377);
|
||||
return (*_ich++ & 0377);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
sz = 0;
|
||||
text[0] = 0;
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
static struct e_instr *emhead; /* Where we put the head */
|
||||
static struct e_instr *emhead; /* Where we put the head */
|
||||
static struct e_instr aheads[3];
|
||||
static int ahead;
|
||||
|
||||
static struct string {
|
||||
static struct string
|
||||
{
|
||||
int length;
|
||||
unsigned int maxlen;
|
||||
char *str;
|
||||
} string;
|
||||
|
||||
static int state; /* What state are we in? */
|
||||
static int state; /* What state are we in? */
|
||||
#define CON 01 /* Reading a CON */
|
||||
#define ROM 02 /* Reading a ROM */
|
||||
#define MES 03 /* Reading a MES */
|
||||
#define PSEUMASK 03
|
||||
|
||||
static int EM_initialized; /* EM_open called? */
|
||||
static int EM_initialized; /* EM_open called? */
|
||||
|
||||
static long wordmask[] = { /* allowed bits in a word */
|
||||
0x00000000,
|
||||
0x000000FF,
|
||||
0x0000FFFF,
|
||||
0x00000000,
|
||||
0xFFFFFFFF
|
||||
};
|
||||
static long wordmask[] =
|
||||
{ /* allowed bits in a word */
|
||||
0x00000000, 0x000000FF, 0x0000FFFF, 0x00000000, 0xFFFFFFFF };
|
||||
|
||||
static int wsize, psize; /* word size and pointer size */
|
||||
static int wsize, psize; /* word size and pointer size */
|
||||
|
||||
#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 */
|
||||
|
||||
/* Error handling
|
||||
*/
|
||||
*/
|
||||
|
||||
PRIVATE void
|
||||
xerror(s)
|
||||
char *s;
|
||||
PRIVATE void xerror(char *s)
|
||||
{
|
||||
if (emhead->em_type != EM_FATAL) emhead->em_type = EM_ERROR;
|
||||
if (!EM_error) EM_error = s;
|
||||
if (emhead->em_type != EM_FATAL)
|
||||
emhead->em_type = EM_ERROR;
|
||||
if (!EM_error)
|
||||
EM_error = s;
|
||||
}
|
||||
|
||||
#ifdef COMPACT
|
||||
PRIVATE void
|
||||
xfatal(s)
|
||||
char *s;
|
||||
PRIVATE void xfatal(char *s)
|
||||
{
|
||||
emhead->em_type = EM_FATAL;
|
||||
if (!EM_error) EM_error = s;
|
||||
|
@ -122,33 +117,37 @@ xfatal(s)
|
|||
#endif /* COMPACT */
|
||||
|
||||
/* EM_open: Open input file, get magic word if COMPACT.
|
||||
*/
|
||||
EXPORT int
|
||||
EM_open(filename)
|
||||
char *filename;
|
||||
*/
|
||||
EXPORT int EM_open(char *filename)
|
||||
{
|
||||
if (EM_initialized) {
|
||||
if (EM_initialized)
|
||||
{
|
||||
EM_error = "EM_open already called";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (filename) {
|
||||
if (!sys_open(filename, OP_READ, &fd)) {
|
||||
|
||||
if (filename)
|
||||
{
|
||||
fd = fopen(filename, "rb");
|
||||
if (fd == NULL)
|
||||
{
|
||||
EM_error = "Could not open input file";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else fd = STDIN;
|
||||
else
|
||||
fd = stdin;
|
||||
EM_filename = filename;
|
||||
init_input();
|
||||
|
||||
#ifdef COMPACT
|
||||
if (get16() != sp_magic) {
|
||||
if (get16() != sp_magic)
|
||||
{
|
||||
EM_error = "Illegal magic word";
|
||||
return 0;
|
||||
}
|
||||
#else /* not COMPACT */
|
||||
inithash(); /* initialize hashtable */
|
||||
inithash(); /* initialize hashtable */
|
||||
#endif /* COMPACT */
|
||||
|
||||
EM_initialized = 1;
|
||||
|
@ -156,37 +155,36 @@ EM_open(filename)
|
|||
}
|
||||
|
||||
/* EM_close: Close input file
|
||||
*/
|
||||
EXPORT void
|
||||
EM_close()
|
||||
*/
|
||||
EXPORT void EM_close(void)
|
||||
{
|
||||
|
||||
if (fd != STDIN) {
|
||||
sys_close(fd);
|
||||
fd = STDIN;
|
||||
|
||||
if (fd != stdin)
|
||||
{
|
||||
fclose(fd);
|
||||
fd = stdin;
|
||||
}
|
||||
EM_initialized = 0;
|
||||
}
|
||||
|
||||
|
||||
/* startmes: handle the start of a message. The only important thing here
|
||||
is to get the wordsize and pointer size, and remember that they
|
||||
have already been read, not only to check that they are not specified
|
||||
again, but also to deliver the arguments on next calls to EM_getinstr.
|
||||
This is indicated by the variable "argp".
|
||||
*/
|
||||
PRIVATE void
|
||||
startmes(p)
|
||||
register struct e_instr *p;
|
||||
is to get the wordsize and pointer size, and remember that they
|
||||
have already been read, not only to check that they are not specified
|
||||
again, but also to deliver the arguments on next calls to EM_getinstr.
|
||||
This is indicated by the variable "argp".
|
||||
*/
|
||||
PRIVATE void startmes(register struct e_instr *p)
|
||||
{
|
||||
|
||||
getarg(cst_ptyp, &(p->em_arg));
|
||||
state = MES;
|
||||
|
||||
if (p->em_cst == ms_emx) {
|
||||
if (p->em_cst == ms_emx)
|
||||
{
|
||||
p = &aheads[ahead++];
|
||||
getarg(cst_ptyp, &(p->em_arg));
|
||||
if (wsize && p->em_cst != wsize && !EM_error) {
|
||||
if (wsize && p->em_cst != wsize && !EM_error)
|
||||
{
|
||||
EM_error = "Different wordsize in duplicate ms_emx";
|
||||
}
|
||||
wsize = p->em_cst;
|
||||
|
@ -194,7 +192,8 @@ startmes(p)
|
|||
p->em_type = EM_MESARG;
|
||||
p = &aheads[ahead++];
|
||||
getarg(cst_ptyp, &(p->em_arg));
|
||||
if (psize && p->em_cst != psize && !EM_error) {
|
||||
if (psize && p->em_cst != psize && !EM_error)
|
||||
{
|
||||
EM_error = "Different pointersize in duplicate ms_emx";
|
||||
}
|
||||
psize = p->em_cst;
|
||||
|
@ -203,123 +202,133 @@ startmes(p)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* EM_getinstr: read an "EM_line"
|
||||
*/
|
||||
EXPORT int
|
||||
EM_getinstr(p)
|
||||
register struct e_instr *p;
|
||||
*/
|
||||
EXPORT int EM_getinstr(register struct e_instr *p)
|
||||
{
|
||||
|
||||
EM_error = 0;
|
||||
if (ahead) {
|
||||
if (ahead)
|
||||
{
|
||||
register int i;
|
||||
|
||||
ahead--;
|
||||
*p = aheads[0];
|
||||
for (i = 0; i < ahead; i++) aheads[i] = aheads[i+1];
|
||||
for (i = 0; i < ahead; i++)
|
||||
aheads[i] = aheads[i + 1];
|
||||
return 1;
|
||||
}
|
||||
emhead = p;
|
||||
p->em_type = 0;
|
||||
#ifdef CHECKING
|
||||
if (!EM_initialized) {
|
||||
if (!EM_initialized)
|
||||
{
|
||||
EM_error = "Initialization not done";
|
||||
p->em_type = EM_FATAL;
|
||||
return 0;
|
||||
}
|
||||
#endif /* CHECKING */
|
||||
|
||||
if (!state) { /* All clear, get a new line */
|
||||
if (!state)
|
||||
{ /* All clear, get a new line */
|
||||
gethead(p);
|
||||
switch(p->em_type) {
|
||||
switch (p->em_type)
|
||||
{
|
||||
case EM_EOF:
|
||||
return EM_error == 0;
|
||||
case EM_MNEM: {
|
||||
register int i,j;
|
||||
case EM_MNEM:
|
||||
{
|
||||
register int i, j;
|
||||
extern char em_flag[];
|
||||
extern short em_ptyp[];
|
||||
extern short em_ptyp[];
|
||||
|
||||
j = em_flag[p->em_opcode - sp_fmnem] & EM_PAR;
|
||||
i = em_ptyp[j];
|
||||
if (j == PAR_NO) { /* No arguments */
|
||||
if (j == PAR_NO)
|
||||
{ /* No arguments */
|
||||
p->em_argtype = 0;
|
||||
}
|
||||
#ifndef COMPACT
|
||||
if (j == PAR_B) i = ptyp(sp_ilb2);
|
||||
if (j == PAR_B)
|
||||
i = ptyp(sp_ilb2);
|
||||
#endif /* COMPACT */
|
||||
if (j != PAR_NO) getarg(i, &(p->em_arg));
|
||||
if (j != PAR_NO)
|
||||
getarg(i, &(p->em_arg));
|
||||
#ifndef COMPACT
|
||||
if (j == PAR_B) {
|
||||
if (j == PAR_B)
|
||||
{
|
||||
p->em_cst = p->em_ilb;
|
||||
p->em_argtype = cst_ptyp;
|
||||
}
|
||||
#endif /* COMPACT */
|
||||
/* range checking
|
||||
*/
|
||||
*/
|
||||
#ifdef CHECKING
|
||||
if (wsize <= 4 && psize <= 4) switch(j) {
|
||||
case PAR_B:
|
||||
check(p->em_cst <= 32767);
|
||||
/* Fall through */
|
||||
case PAR_N:
|
||||
check(p->em_cst >= 0);
|
||||
break;
|
||||
case PAR_G:
|
||||
if (p->em_argtype != cst_ptyp) {
|
||||
if (wsize <= 4 && psize <= 4)
|
||||
switch (j)
|
||||
{
|
||||
case PAR_B:
|
||||
check(p->em_cst <= 32767);
|
||||
/* Fall through */
|
||||
case PAR_N:
|
||||
check(p->em_cst >= 0);
|
||||
break;
|
||||
}
|
||||
check(p->em_cst >= 0);
|
||||
/* Fall through */
|
||||
case PAR_F:
|
||||
/* ??? not in original em_decode or em_encode */
|
||||
case PAR_L:
|
||||
{ arith m = p->em_cst >= 0 ? p->em_cst :
|
||||
- p->em_cst;
|
||||
case PAR_G:
|
||||
if (p->em_argtype != cst_ptyp)
|
||||
{
|
||||
break;
|
||||
}
|
||||
check(p->em_cst >= 0);
|
||||
/* Fall through */
|
||||
case PAR_F:
|
||||
/* ??? not in original em_decode or em_encode */
|
||||
case PAR_L:
|
||||
{
|
||||
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 (p->em_argtype == 0) {
|
||||
p->em_cst = 0;
|
||||
/* Check that the number fits in a pointer */
|
||||
check((m & ~wordmask[psize]) == 0);
|
||||
break;
|
||||
}
|
||||
case PAR_W:
|
||||
if (p->em_argtype == 0)
|
||||
{
|
||||
p->em_cst = 0;
|
||||
break;
|
||||
}
|
||||
check((p->em_cst & ~wordmask[wsize]) == 0);
|
||||
/* Fall through */
|
||||
case PAR_S:
|
||||
check(p->em_cst > 0);
|
||||
/* Fall through */
|
||||
case PAR_Z:
|
||||
check((p->em_cst >= 0) && (p->em_cst % wsize == 0));
|
||||
break;
|
||||
case PAR_O:
|
||||
check(
|
||||
(p->em_cst > 0) && ( (p->em_cst % wsize == 0) || (wsize % p->em_cst == 0)));
|
||||
break;
|
||||
case PAR_R:
|
||||
check((p->em_cst >= 0) && (p->em_cst <= 2));
|
||||
break;
|
||||
}
|
||||
check((p->em_cst & ~wordmask[wsize]) == 0);
|
||||
/* Fall through */
|
||||
case PAR_S:
|
||||
check(p->em_cst > 0);
|
||||
/* Fall through */
|
||||
case PAR_Z:
|
||||
check(p->em_cst >= 0 &&
|
||||
p->em_cst % wsize == 0);
|
||||
break;
|
||||
case PAR_O:
|
||||
check(p->em_cst > 0 &&
|
||||
( p->em_cst % wsize == 0 ||
|
||||
wsize % p->em_cst == 0));
|
||||
break;
|
||||
case PAR_R:
|
||||
check(p->em_cst >= 0 && p->em_cst <= 2);
|
||||
break;
|
||||
}
|
||||
#endif /* CHECKING */
|
||||
#ifndef COMPACT
|
||||
checkeol();
|
||||
#endif /* COMPACT */
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EM_PSEU:
|
||||
/* handle a pseudo, read possible arguments. CON's and
|
||||
ROM's are handled especially: Only one argument is
|
||||
read, and a mark is set that an argument list of
|
||||
type ROM or CON is in process
|
||||
*/
|
||||
{
|
||||
ROM's are handled especially: Only one argument is
|
||||
read, and a mark is set that an argument list of
|
||||
type ROM or CON is in process
|
||||
*/
|
||||
{
|
||||
struct e_arg dummy;
|
||||
|
||||
switch(p->em_opcode) {
|
||||
switch (p->em_opcode)
|
||||
{
|
||||
case ps_bss:
|
||||
case ps_hol:
|
||||
getarg(cst_ptyp, &dummy);
|
||||
|
@ -329,10 +338,11 @@ EM_getinstr(p)
|
|||
EM_holinit = dummy.ema_cst;
|
||||
#ifdef CHECKING
|
||||
/* Check that the last value is 0 or 1
|
||||
*/
|
||||
if (EM_holinit != 1 && EM_holinit != 0) {
|
||||
if (! EM_error)
|
||||
EM_error="Third argument of hol/bss not 0/1";
|
||||
*/
|
||||
if (EM_holinit != 1 && EM_holinit != 0)
|
||||
{
|
||||
if (!EM_error)
|
||||
EM_error = "Third argument of hol/bss not 0/1";
|
||||
}
|
||||
#endif /* CHECKING */
|
||||
break;
|
||||
|
@ -352,14 +362,16 @@ EM_getinstr(p)
|
|||
break;
|
||||
case ps_pro:
|
||||
getarg(pro_ptyp, &(p->em_arg));
|
||||
getarg(cst_ptyp|ptyp(sp_cend), &dummy);
|
||||
if (dummy.ema_argtype == 0) {
|
||||
getarg(cst_ptyp | ptyp(sp_cend), &dummy);
|
||||
if (dummy.ema_argtype == 0)
|
||||
{
|
||||
p->em_nlocals = -1;
|
||||
}
|
||||
else p->em_nlocals = dummy.ema_cst;
|
||||
else
|
||||
p->em_nlocals = dummy.ema_cst;
|
||||
break;
|
||||
case ps_end:
|
||||
getarg(cst_ptyp|ptyp(sp_cend), &(p->em_arg));
|
||||
getarg(cst_ptyp | ptyp(sp_cend), &(p->em_arg));
|
||||
break;
|
||||
case ps_con:
|
||||
getarg(val_ptyp, &(p->em_arg));
|
||||
|
@ -373,9 +385,10 @@ EM_getinstr(p)
|
|||
xerror("Bad pseudo");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef COMPACT
|
||||
if (p->em_opcode != ps_con && p->em_opcode != ps_rom) {
|
||||
if (p->em_opcode != ps_con && p->em_opcode != ps_rom)
|
||||
{
|
||||
checkeol();
|
||||
}
|
||||
#endif /* COMPACT */
|
||||
|
@ -384,7 +397,8 @@ EM_getinstr(p)
|
|||
startmes(p);
|
||||
break;
|
||||
}
|
||||
if (!wsize && !EM_error) {
|
||||
if (!wsize && !EM_error)
|
||||
{
|
||||
wsize = 2;
|
||||
psize = 2;
|
||||
EM_error = "EM code should start with mes 2";
|
||||
|
@ -394,14 +408,17 @@ EM_getinstr(p)
|
|||
|
||||
/* Here, we are in a state reading arguments */
|
||||
getarg(any_ptyp, &(p->em_arg));
|
||||
if (EM_error && p->em_type != EM_FATAL) {
|
||||
if (EM_error && p->em_type != EM_FATAL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (p->em_argtype == 0) { /* No more arguments */
|
||||
if (p->em_argtype == 0)
|
||||
{ /* No more arguments */
|
||||
#ifndef COMPACT
|
||||
checkeol();
|
||||
#endif
|
||||
if (state == MES) {
|
||||
if (state == MES)
|
||||
{
|
||||
state = 0;
|
||||
p->em_type = EM_ENDMES;
|
||||
return EM_error == 0;
|
||||
|
@ -412,12 +429,15 @@ EM_getinstr(p)
|
|||
}
|
||||
|
||||
/* Here, there was an argument */
|
||||
if (state == MES) {
|
||||
if (state == MES)
|
||||
{
|
||||
p->em_type = EM_MESARG;
|
||||
return EM_error == 0;
|
||||
}
|
||||
p->em_type = EM_PSEU;
|
||||
if (state == CON) p->em_opcode = ps_con;
|
||||
else p->em_opcode = ps_rom;
|
||||
if (state == CON)
|
||||
p->em_opcode = ps_con;
|
||||
else
|
||||
p->em_opcode = ps_rom;
|
||||
return EM_error == 0;
|
||||
}
|
||||
|
|
|
@ -10,12 +10,13 @@
|
|||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <ack_string.h>
|
||||
#include <stdio.h>
|
||||
#include "ack_string.h"
|
||||
|
||||
/* #define XXX_YYY /* only for early debugging */
|
||||
/* #define XXX_YYY *//* only for early debugging */
|
||||
|
||||
#ifdef XXX_YYY
|
||||
#define out(str) (sys_write(STDOUT, str, strlen(str)))
|
||||
#define out(str) (fwrite(stdout, 1, str, strlen(str)))
|
||||
#else
|
||||
#define out(s)
|
||||
#endif
|
||||
|
@ -30,11 +31,17 @@ static int argnum; /* Number of arguments */
|
|||
|
||||
#define COMMENTSTARTER ';'
|
||||
|
||||
/* Forward declarations */
|
||||
PRIVATE void gettyp(int, register struct e_arg *);
|
||||
PRIVATE int getexpr(register int, register struct e_arg *);
|
||||
|
||||
/* External definitions */
|
||||
extern char em_mnem[][4];
|
||||
extern char em_pseu[][4];
|
||||
|
||||
/* inithash, pre_hash, hash: Simple hashtable mechanism
|
||||
*/
|
||||
PRIVATE int
|
||||
hash(s)
|
||||
register char *s;
|
||||
PRIVATE int hash(register char *s)
|
||||
{
|
||||
register int h = 0;
|
||||
|
||||
|
@ -45,9 +52,7 @@ hash(s)
|
|||
return h;
|
||||
}
|
||||
|
||||
PRIVATE void
|
||||
pre_hash(i, s)
|
||||
char *s;
|
||||
PRIVATE void pre_hash(int i, char *s)
|
||||
{
|
||||
register int h;
|
||||
|
||||
|
@ -65,11 +70,9 @@ pre_hash(i, s)
|
|||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
extern char em_mnem[][4];
|
||||
extern char em_pseu[][4];
|
||||
|
||||
PRIVATE void
|
||||
inithash()
|
||||
|
||||
PRIVATE void inithash(void)
|
||||
{
|
||||
register int i;
|
||||
|
||||
|
@ -87,8 +90,7 @@ inithash()
|
|||
/* nospace: skip until we find a non-space character. Also skip
|
||||
comments.
|
||||
*/
|
||||
PRIVATE int
|
||||
nospace()
|
||||
PRIVATE int nospace(void)
|
||||
{
|
||||
register int c;
|
||||
|
||||
|
@ -105,9 +107,7 @@ nospace()
|
|||
|
||||
/* syntax: Put an error message in EM_error and skip to the end of the line
|
||||
*/
|
||||
PRIVATE void
|
||||
syntax(s)
|
||||
char *s;
|
||||
PRIVATE void syntax(char *s)
|
||||
{
|
||||
register int c;
|
||||
|
||||
|
@ -119,8 +119,7 @@ syntax(s)
|
|||
|
||||
/* checkeol: check that we have a complete line (except maybe for spaces)
|
||||
*/
|
||||
PRIVATE void
|
||||
checkeol()
|
||||
PRIVATE void checkeol(void)
|
||||
{
|
||||
|
||||
if (nospace() != '\n') {
|
||||
|
@ -131,8 +130,7 @@ checkeol()
|
|||
|
||||
/* getescape: read a '\' escape sequence
|
||||
*/
|
||||
PRIVATE int
|
||||
getescape()
|
||||
PRIVATE int getescape(void)
|
||||
{
|
||||
register int c, j, r;
|
||||
|
||||
|
@ -164,8 +162,7 @@ getescape()
|
|||
|
||||
/* getname: Read a string of characters representing an identifier
|
||||
*/
|
||||
PRIVATE struct string *
|
||||
getname()
|
||||
PRIVATE struct string *getname(void)
|
||||
{
|
||||
register char *p;
|
||||
register struct string *s;
|
||||
|
@ -203,8 +200,7 @@ getname()
|
|||
|
||||
/* getstring: read a string of characters between quotes
|
||||
*/
|
||||
PRIVATE struct string *
|
||||
getstring()
|
||||
PRIVATE struct string *getstring(int isident)
|
||||
{
|
||||
register char *p;
|
||||
struct string *s;
|
||||
|
@ -253,11 +249,10 @@ getstring()
|
|||
return s;
|
||||
}
|
||||
|
||||
PRIVATE void gettyp();
|
||||
|
||||
PRIVATE int
|
||||
offsetted(argtyp, ap)
|
||||
arith *ap;
|
||||
|
||||
|
||||
PRIVATE int offsetted(int argtyp, arith *ap)
|
||||
{
|
||||
register int c;
|
||||
|
||||
|
@ -275,10 +270,7 @@ offsetted(argtyp, ap)
|
|||
return argtyp;
|
||||
}
|
||||
|
||||
PRIVATE int
|
||||
getnumber(c, ap)
|
||||
register int c;
|
||||
register struct e_arg *ap;
|
||||
PRIVATE int getnumber(register int c, register struct e_arg *ap)
|
||||
{
|
||||
char str[256 + 1];
|
||||
register char *p = str;
|
||||
|
@ -365,12 +357,8 @@ getnumber(c, ap)
|
|||
return sp_cst4;
|
||||
}
|
||||
|
||||
PRIVATE int getexpr();
|
||||
|
||||
PRIVATE int
|
||||
getfactor(c, ap)
|
||||
register int c;
|
||||
register struct e_arg *ap;
|
||||
PRIVATE int getfactor(register int c, register struct e_arg *ap)
|
||||
{
|
||||
if (c == '(') {
|
||||
if (getexpr(nospace(), ap) != sp_cst4) {
|
||||
|
@ -385,10 +373,7 @@ getfactor(c, ap)
|
|||
return getnumber(c, ap);
|
||||
}
|
||||
|
||||
PRIVATE int
|
||||
getterm(c, ap)
|
||||
register int c;
|
||||
register struct e_arg *ap;
|
||||
PRIVATE int getterm(register int c, register struct e_arg *ap)
|
||||
{
|
||||
arith left;
|
||||
|
||||
|
@ -413,10 +398,7 @@ getterm(c, ap)
|
|||
return sp_cst4;
|
||||
}
|
||||
|
||||
PRIVATE int
|
||||
getexpr(c, ap)
|
||||
register int c;
|
||||
register struct e_arg *ap;
|
||||
PRIVATE int getexpr(register int c, register struct e_arg *ap)
|
||||
{
|
||||
arith left;
|
||||
|
||||
|
@ -440,8 +422,7 @@ getexpr(c, ap)
|
|||
return sp_cst4;
|
||||
}
|
||||
|
||||
PRIVATE int
|
||||
get15u()
|
||||
PRIVATE int get15u(void)
|
||||
{
|
||||
struct e_arg dummy;
|
||||
|
||||
|
@ -452,9 +433,7 @@ get15u()
|
|||
return (int) (dummy.ema_cst);
|
||||
}
|
||||
|
||||
PRIVATE void
|
||||
gettyp(typset, ap)
|
||||
register struct e_arg *ap;
|
||||
PRIVATE void gettyp(int typset, register struct e_arg *ap)
|
||||
{
|
||||
register int c, t;
|
||||
register int argtyp;
|
||||
|
@ -528,9 +507,7 @@ gettyp(typset, ap)
|
|||
}
|
||||
}
|
||||
|
||||
PRIVATE void
|
||||
getarg(typset, ap)
|
||||
struct e_arg *ap;
|
||||
PRIVATE void getarg(int typset, struct e_arg *ap)
|
||||
{
|
||||
register int c;
|
||||
|
||||
|
@ -550,9 +527,7 @@ getarg(typset, ap)
|
|||
/* getmnem: We found the start of either an instruction or a pseudo.
|
||||
get the rest of it
|
||||
*/
|
||||
PRIVATE void
|
||||
getmnem(c, p)
|
||||
register struct e_instr *p;
|
||||
PRIVATE void getmnem(int c, register struct e_instr *p)
|
||||
{
|
||||
register int h;
|
||||
int i;
|
||||
|
@ -592,8 +567,7 @@ getmnem(c, p)
|
|||
}
|
||||
}
|
||||
|
||||
PRIVATE void
|
||||
line_line()
|
||||
PRIVATE void line_line(void)
|
||||
{
|
||||
static char filebuf[256 + 1];
|
||||
char *btscpy();
|
||||
|
@ -606,9 +580,7 @@ line_line()
|
|||
EM_filename = filebuf;
|
||||
}
|
||||
|
||||
PRIVATE void
|
||||
getlabel(c, p)
|
||||
register struct e_instr *p;
|
||||
PRIVATE void getlabel(int c, register struct e_instr *p)
|
||||
{
|
||||
|
||||
ungetbyte(c);
|
||||
|
@ -629,9 +601,7 @@ getlabel(c, p)
|
|||
checkeol();
|
||||
}
|
||||
|
||||
PRIVATE void
|
||||
gethead(p)
|
||||
register struct e_instr *p;
|
||||
PRIVATE void gethead(register struct e_instr *p)
|
||||
{
|
||||
register int c;
|
||||
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
|
||||
/* get16, get32: read a signed constant
|
||||
*/
|
||||
PRIVATE int
|
||||
get16()
|
||||
PRIVATE int get16(void)
|
||||
{
|
||||
register int l_byte, h_byte;
|
||||
|
||||
|
@ -22,8 +21,7 @@ get16()
|
|||
return l_byte | (h_byte << 8);
|
||||
}
|
||||
|
||||
PRIVATE arith
|
||||
get32()
|
||||
PRIVATE arith get32(void)
|
||||
{
|
||||
register arith l;
|
||||
register int h_byte;
|
||||
|
@ -41,9 +39,7 @@ PRIVATE struct string *getstring();
|
|||
/* getarg : read an argument of any type, and check it against "typset"
|
||||
if neccesary. Put result in "ap".
|
||||
*/
|
||||
PRIVATE void
|
||||
getarg(typset, ap)
|
||||
register struct e_arg *ap;
|
||||
PRIVATE void getarg(int typset, register struct e_arg *ap)
|
||||
{
|
||||
register int i = getbyte();
|
||||
#ifdef CHECKING
|
||||
|
@ -190,9 +186,7 @@ getarg(typset, ap)
|
|||
#ifdef CHECKING
|
||||
/* checkident: check that a string indeed represents an identifier
|
||||
*/
|
||||
PRIVATE int
|
||||
checkident(s)
|
||||
register struct string *s;
|
||||
PRIVATE int checkident(register struct string *s)
|
||||
{
|
||||
register char *p;
|
||||
register int n;
|
||||
|
@ -214,8 +208,7 @@ checkident(s)
|
|||
/* getstring: read a string from the input
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
PRIVATE struct string *
|
||||
getstring(isident)
|
||||
PRIVATE struct string *getstring(int isident)
|
||||
{
|
||||
register char *p;
|
||||
register int n;
|
||||
|
@ -259,9 +252,7 @@ getstring(isident)
|
|||
|
||||
/* gethead: read the start of an EM-line
|
||||
*/
|
||||
PRIVATE void
|
||||
gethead(p)
|
||||
register struct e_instr *p;
|
||||
PRIVATE void gethead(register struct e_instr *p)
|
||||
{
|
||||
register int i;
|
||||
|
||||
|
|
Loading…
Reference in a new issue