1984-05-17 13:57:07 +00:00
|
|
|
#ifndef NORCSID
|
|
|
|
static char rcsid[] = "$Header$";
|
|
|
|
#endif
|
|
|
|
|
1984-05-17 13:42:36 +00:00
|
|
|
#include "param.h"
|
|
|
|
#include "types.h"
|
1990-09-04 16:42:43 +00:00
|
|
|
#include "tes.h"
|
1984-05-17 13:42:36 +00:00
|
|
|
#include "assert.h"
|
|
|
|
#include "line.h"
|
|
|
|
#include "lookup.h"
|
|
|
|
#include "alloc.h"
|
|
|
|
#include "proinf.h"
|
1988-09-12 09:13:49 +00:00
|
|
|
#include <em_spec.h>
|
|
|
|
#include <em_pseu.h>
|
|
|
|
#include <em_mnem.h>
|
1990-07-25 17:10:40 +00:00
|
|
|
#include <em_mes.h>
|
1984-05-17 13:42:36 +00:00
|
|
|
#include "ext.h"
|
|
|
|
|
|
|
|
/*
|
1987-03-10 01:42:07 +00:00
|
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
1984-05-17 13:42:36 +00:00
|
|
|
*
|
|
|
|
* Author: Hans van Staveren
|
|
|
|
*/
|
|
|
|
|
1987-03-09 10:15:51 +00:00
|
|
|
#define local(x) ((((x)->s_flags&SYMKNOWN) == 0 && \
|
|
|
|
((x)->s_flags &= ~ SYMGLOBAL)),\
|
|
|
|
(x)->s_flags |= SYMSEEN)
|
|
|
|
#define global(x) ((((x)->s_flags&SYMKNOWN) == 0 && \
|
|
|
|
((x)->s_flags |= SYMGLOBAL)), \
|
|
|
|
(x)->s_flags |= SYMSEEN)
|
1984-05-17 13:42:36 +00:00
|
|
|
|
|
|
|
#define DTYPHOL 1
|
|
|
|
#define DTYPBSS 2
|
|
|
|
#define DTYPCON 3
|
|
|
|
#define DTYPROM 4
|
|
|
|
byte curdtyp;
|
|
|
|
bool goodrom;
|
|
|
|
short curfrag = 3; /* see also peephole.c */
|
|
|
|
offset rombuf[MAXROM];
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
backward() {
|
|
|
|
register line_p lnp;
|
|
|
|
line_p next;
|
|
|
|
register arg_p ap;
|
|
|
|
line_p i,p;
|
|
|
|
int n;
|
|
|
|
register sym_p sp;
|
|
|
|
|
|
|
|
i = p = (line_p) 0;
|
|
|
|
curdtyp=0;
|
|
|
|
for (lnp = curpro.lastline; lnp != (line_p) 0; lnp = next) {
|
|
|
|
next = lnp->l_next;
|
|
|
|
switch(lnp->l_optyp) {
|
|
|
|
case OPSYMBOL:
|
|
|
|
global(lnp->l_a.la_sp);
|
|
|
|
break;
|
|
|
|
case OPSVAL:
|
|
|
|
global(lnp->l_a.la_sval.lasv_sp);
|
|
|
|
break;
|
|
|
|
case OPLVAL:
|
|
|
|
global(lnp->l_a.la_lval.lalv_sp);
|
|
|
|
break;
|
|
|
|
case OPLIST:
|
|
|
|
ap = lnp->l_a.la_arg;
|
|
|
|
while (ap != (arg_p) 0 ) {
|
|
|
|
switch(ap->a_typ) {
|
|
|
|
case ARGSYM:
|
|
|
|
global(ap->a_a.a_sp);
|
|
|
|
break;
|
|
|
|
case ARGVAL:
|
|
|
|
global(ap->a_a.a_val.av_sp);
|
|
|
|
}
|
|
|
|
ap = ap->a_next;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* references to symbols are processed now.
|
|
|
|
* for plain instructions nothing else is needed
|
|
|
|
*/
|
|
|
|
|
|
|
|
switch(lnp->l_instr&BMASK) {
|
|
|
|
/*
|
|
|
|
* count all local occurences for register counts;
|
|
|
|
* op_lal is omitted and not by accident.
|
|
|
|
*/
|
|
|
|
case op_del:
|
|
|
|
case op_inl:
|
|
|
|
case op_ldl:
|
|
|
|
case op_lil:
|
|
|
|
case op_lol:
|
|
|
|
case op_sdl:
|
|
|
|
case op_sil:
|
|
|
|
case op_stl:
|
|
|
|
case op_zrl:
|
|
|
|
switch(lnp->l_optyp) {
|
|
|
|
case OPNO:
|
|
|
|
case OPNUMLAB:
|
|
|
|
case OPSYMBOL:
|
|
|
|
case OPSVAL:
|
|
|
|
case OPLVAL:
|
|
|
|
case OPLIST:
|
|
|
|
break;
|
|
|
|
case OPOFFSET:
|
|
|
|
incregusage(lnp->l_a.la_offset);
|
|
|
|
break;
|
|
|
|
case OPSHORT:
|
|
|
|
incregusage((offset)lnp->l_a.la_short);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
incregusage((offset)(lnp->l_optyp&BMASK)-Z_OPMINI);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* fall through !! */
|
|
|
|
default:
|
|
|
|
assert((lnp->l_instr&BMASK)<=op_last);
|
|
|
|
lnp->l_next = i;
|
|
|
|
i = lnp;
|
|
|
|
continue;
|
|
|
|
case ps_sym:
|
|
|
|
sp = lnp->l_a.la_sp;
|
|
|
|
local(sp);
|
|
|
|
if (curdtyp == DTYPROM && goodrom) {
|
|
|
|
sp->s_rom = newrom();
|
|
|
|
for (n=0;n<rc;n++)
|
|
|
|
sp->s_rom[n] = rombuf[n];
|
|
|
|
}
|
|
|
|
sp->s_frag = curfrag;
|
|
|
|
break;
|
|
|
|
case ps_hol:
|
|
|
|
curdtyp = DTYPHOL;
|
|
|
|
curfrag++;
|
|
|
|
break;
|
|
|
|
case ps_bss:
|
|
|
|
curdtyp = DTYPBSS;
|
|
|
|
curfrag++;
|
|
|
|
break;
|
|
|
|
case ps_con:
|
|
|
|
if (curdtyp != DTYPCON) {
|
|
|
|
curdtyp = DTYPCON;
|
|
|
|
curfrag++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ps_rom:
|
|
|
|
if (curdtyp != DTYPROM) {
|
|
|
|
curdtyp = DTYPROM;
|
|
|
|
curfrag++;
|
|
|
|
}
|
|
|
|
ap = lnp->l_a.la_arg;
|
|
|
|
rc = 0;
|
|
|
|
while (ap != (arg_p) 0 && rc < MAXROM) {
|
|
|
|
if (ap->a_typ == ARGOFF) {
|
|
|
|
rombuf[rc++] = ap->a_a.a_offset;
|
|
|
|
ap = ap->a_next;
|
|
|
|
} else
|
|
|
|
ap = (arg_p) 0;
|
|
|
|
}
|
|
|
|
goodrom = (rc >= 2);
|
|
|
|
break;
|
|
|
|
case ps_mes:
|
1990-08-01 14:36:45 +00:00
|
|
|
if (prodepth != 0 &&
|
|
|
|
(int) aoff(lnp->l_a.la_arg, 0) == ms_std) {
|
1990-07-25 17:10:40 +00:00
|
|
|
lnp->l_next = i;
|
|
|
|
i = lnp;
|
|
|
|
continue;
|
|
|
|
}
|
1984-05-17 13:42:36 +00:00
|
|
|
break;
|
|
|
|
case ps_inp:
|
|
|
|
case ps_ina:
|
|
|
|
local(lnp->l_a.la_sp);
|
|
|
|
case ps_exp:
|
|
|
|
case ps_exa:
|
|
|
|
case ps_exc:
|
|
|
|
oldline(lnp);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
lnp->l_next = p;
|
|
|
|
p = lnp;
|
|
|
|
}
|
|
|
|
if (prodepth != 0)
|
|
|
|
local(curpro.symbol);
|
|
|
|
instrs = i; pseudos = p; curpro.lastline = (line_p) 0;
|
|
|
|
}
|