Initial revision
This commit is contained in:
375
util/opt/putline.c
Normal file
375
util/opt/putline.c
Normal file
@@ -0,0 +1,375 @@
|
||||
#include "param.h"
|
||||
#include "types.h"
|
||||
#include "assert.h"
|
||||
#include "../../h/em_spec.h"
|
||||
#include "../../h/em_pseu.h"
|
||||
#include "../../h/em_mnem.h"
|
||||
#include "../../h/em_flag.h"
|
||||
#include "alloc.h"
|
||||
#include "line.h"
|
||||
#include "lookup.h"
|
||||
#include "proinf.h"
|
||||
#include "optim.h"
|
||||
#include "ext.h"
|
||||
|
||||
/*
|
||||
* (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
*
|
||||
* This product is part of the Amsterdam Compiler Kit.
|
||||
*
|
||||
* Permission to use, sell, duplicate or disclose this software must be
|
||||
* obtained in writing. Requests for such permissions may be sent to
|
||||
*
|
||||
* Dr. Andrew S. Tanenbaum
|
||||
* Wiskundig Seminarium
|
||||
* Vrije Universiteit
|
||||
* Postbox 7161
|
||||
* 1007 MC Amsterdam
|
||||
* The Netherlands
|
||||
*
|
||||
* Author: Hans van Staveren
|
||||
*/
|
||||
|
||||
#define outbyte(b) putc(b,outfile)
|
||||
|
||||
putlines(lnp) register line_p lnp; {
|
||||
register arg_p ap;
|
||||
line_p temp;
|
||||
register instr;
|
||||
short curlin= -2;
|
||||
short thislin;
|
||||
|
||||
while ( lnp != (line_p) 0) {
|
||||
instr = lnp->l_instr&BMASK;
|
||||
switch(lnp->l_optyp) {
|
||||
case OPSYMBOL:
|
||||
if ((lnp->l_instr&BMASK) == ps_sym)
|
||||
outdef(lnp->l_a.la_sp);
|
||||
else
|
||||
outocc(lnp->l_a.la_sp);
|
||||
break;
|
||||
case OPSVAL:
|
||||
outocc(lnp->l_a.la_sval.lasv_sp);
|
||||
break;
|
||||
#ifdef LONGOFF
|
||||
case OPLVAL:
|
||||
outocc(lnp->l_a.la_lval.lalv_sp);
|
||||
break;
|
||||
#endif
|
||||
case OPLIST:
|
||||
ap = lnp->l_a.la_arg;
|
||||
while (ap != (arg_p) 0) {
|
||||
switch(ap->a_typ) {
|
||||
case ARGSYM:
|
||||
outocc(ap->a_a.a_sp);
|
||||
break;
|
||||
case ARGVAL:
|
||||
outocc(ap->a_a.a_val.av_sp);
|
||||
break;
|
||||
}
|
||||
ap = ap->a_next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* global symbols now taken care of
|
||||
*/
|
||||
|
||||
|
||||
switch(instr) {
|
||||
case ps_sym:
|
||||
break;
|
||||
case op_lni:
|
||||
if (curlin != -2)
|
||||
curlin++;
|
||||
outinst(instr);
|
||||
break;
|
||||
case op_lin:
|
||||
switch(lnp->l_optyp) {
|
||||
case OPNO:
|
||||
case OPOFFSET:
|
||||
case OPNUMLAB:
|
||||
case OPSYMBOL:
|
||||
case OPSVAL:
|
||||
case OPLVAL:
|
||||
case OPLIST:
|
||||
outinst(instr);
|
||||
goto processoperand;
|
||||
case OPSHORT:
|
||||
thislin = lnp->l_a.la_short;
|
||||
break;
|
||||
default:
|
||||
thislin = (lnp->l_optyp&BMASK)-Z_OPMINI;
|
||||
break;
|
||||
}
|
||||
if (thislin == curlin && !nflag) {
|
||||
temp = lnp->l_next;
|
||||
oldline(lnp);
|
||||
lnp = temp;
|
||||
OPTIM(O_LINGONE);
|
||||
continue;
|
||||
} else if (thislin == curlin+1 && !nflag) {
|
||||
instr = op_lni;
|
||||
outinst(instr);
|
||||
temp = lnp->l_next;
|
||||
oldline(lnp);
|
||||
OPTIM(O_LINLNI);
|
||||
lnp = newline(OPNO);
|
||||
lnp->l_next = temp;
|
||||
lnp->l_instr = instr;
|
||||
} else {
|
||||
outinst(instr);
|
||||
}
|
||||
curlin = thislin;
|
||||
break;
|
||||
case op_lab:
|
||||
curlin = -2;
|
||||
break;
|
||||
default:
|
||||
outinst(instr);
|
||||
}
|
||||
processoperand:
|
||||
switch(lnp->l_optyp) {
|
||||
case OPNO:
|
||||
if ((em_flag[instr-sp_fmnem]&EM_PAR)!=PAR_NO)
|
||||
outbyte( (byte) sp_cend) ;
|
||||
break;
|
||||
default:
|
||||
outint((lnp->l_optyp&BMASK)-Z_OPMINI);
|
||||
break;
|
||||
case OPSHORT:
|
||||
outint(lnp->l_a.la_short);
|
||||
break;
|
||||
#ifdef LONGOFF
|
||||
case OPOFFSET:
|
||||
outoff(lnp->l_a.la_offset);
|
||||
break;
|
||||
#endif
|
||||
case OPNUMLAB:
|
||||
if (instr == op_lab)
|
||||
numlab(lnp->l_a.la_np->n_repl);
|
||||
else if (instr < sp_fpseu) /* plain instruction */
|
||||
outint((short) lnp->l_a.la_np->n_repl->n_number);
|
||||
else
|
||||
outnum(lnp->l_a.la_np->n_repl);
|
||||
break;
|
||||
case OPSYMBOL:
|
||||
outsym(lnp->l_a.la_sp);
|
||||
break;
|
||||
case OPSVAL:
|
||||
outbyte( (byte) sp_doff) ;
|
||||
outsym(lnp->l_a.la_sval.lasv_sp);
|
||||
outint(lnp->l_a.la_sval.lasv_short);
|
||||
break;
|
||||
#ifdef LONGOFF
|
||||
case OPLVAL:
|
||||
outbyte( (byte) sp_doff) ;
|
||||
outsym(lnp->l_a.la_lval.lalv_sp);
|
||||
outoff(lnp->l_a.la_lval.lalv_offset);
|
||||
break;
|
||||
#endif
|
||||
case OPLIST:
|
||||
putargs(lnp->l_a.la_arg);
|
||||
switch(instr) {
|
||||
case ps_con:
|
||||
case ps_rom:
|
||||
case ps_mes:
|
||||
outbyte( (byte) sp_cend) ;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* instruction is output now.
|
||||
* remove its useless body
|
||||
*/
|
||||
|
||||
temp = lnp->l_next;
|
||||
oldline(lnp);
|
||||
lnp = temp;
|
||||
if (ferror(outfile))
|
||||
error("write error");
|
||||
}
|
||||
}
|
||||
|
||||
putargs(ap) register arg_p ap; {
|
||||
|
||||
while (ap != (arg_p) 0) {
|
||||
switch(ap->a_typ) {
|
||||
default:
|
||||
assert(FALSE);
|
||||
case ARGOFF:
|
||||
outoff(ap->a_a.a_offset);
|
||||
break;
|
||||
case ARGNUM:
|
||||
outnum(ap->a_a.a_np->n_repl);
|
||||
break;
|
||||
case ARGSYM:
|
||||
outsym(ap->a_a.a_sp);
|
||||
break;
|
||||
case ARGVAL:
|
||||
outbyte( (byte) sp_doff) ;
|
||||
outsym(ap->a_a.a_val.av_sp);
|
||||
outoff(ap->a_a.a_val.av_offset);
|
||||
break;
|
||||
case ARGSTR:
|
||||
outbyte( (byte) sp_scon) ;
|
||||
putstr(&ap->a_a.a_string);
|
||||
break;
|
||||
case ARGICN:
|
||||
outbyte( (byte) sp_icon) ;
|
||||
goto casecon;
|
||||
case ARGUCN:
|
||||
outbyte( (byte) sp_ucon) ;
|
||||
goto casecon;
|
||||
case ARGFCN:
|
||||
outbyte( (byte) sp_fcon) ;
|
||||
casecon:
|
||||
outint(ap->a_a.a_con.ac_length);
|
||||
putstr(&ap->a_a.a_con.ac_con);
|
||||
break;
|
||||
}
|
||||
ap = ap->a_next;
|
||||
}
|
||||
}
|
||||
|
||||
putstr(abp) register argb_p abp; {
|
||||
register argb_p tbp;
|
||||
register length;
|
||||
|
||||
length = 0;
|
||||
tbp = abp;
|
||||
while (tbp!= (argb_p) 0) {
|
||||
length += tbp->ab_index;
|
||||
tbp = tbp->ab_next;
|
||||
}
|
||||
outint(length);
|
||||
while (abp != (argb_p) 0) {
|
||||
for (length=0;length<abp->ab_index;length++)
|
||||
outbyte( (byte) abp->ab_contents[length] );
|
||||
abp = abp->ab_next;
|
||||
}
|
||||
}
|
||||
|
||||
outdef(sp) register sym_p sp; {
|
||||
|
||||
/*
|
||||
* The surrounding If statement is removed to be friendly
|
||||
* to Backend writers having to deal with assemblers
|
||||
* not following our conventions.
|
||||
if ((sp->s_flags&SYMOUT)==0) {
|
||||
*/
|
||||
sp->s_flags |= SYMOUT;
|
||||
if (sp->s_flags&SYMGLOBAL) {
|
||||
outinst(sp->s_flags&SYMPRO ? ps_exp : ps_exa);
|
||||
outsym(sp);
|
||||
}
|
||||
/*
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
outocc(sp) register sym_p sp; {
|
||||
|
||||
if ((sp->s_flags&SYMOUT)==0) {
|
||||
sp->s_flags |= SYMOUT;
|
||||
if ((sp->s_flags&SYMGLOBAL)==0) {
|
||||
outinst(sp->s_flags&SYMPRO ? ps_inp : ps_ina);
|
||||
outsym(sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outpro() {
|
||||
|
||||
outdef(curpro.symbol);
|
||||
outinst(ps_pro);
|
||||
outsym(curpro.symbol);
|
||||
outoff(curpro.localbytes);
|
||||
}
|
||||
|
||||
outend() {
|
||||
|
||||
outinst(ps_end);
|
||||
outoff(curpro.localbytes);
|
||||
}
|
||||
|
||||
outinst(m) {
|
||||
|
||||
outbyte( (byte) m );
|
||||
}
|
||||
|
||||
outoff(off) offset off; {
|
||||
|
||||
#ifdef LONGOFF
|
||||
if ((short) off == off)
|
||||
#endif
|
||||
outint((short) off);
|
||||
#ifdef LONGOFF
|
||||
else {
|
||||
outbyte( (byte) sp_cst4) ;
|
||||
outshort( (short) (off&0177777L) );
|
||||
outshort( (short) (off>>16) );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
outint(i) short i; {
|
||||
|
||||
if (i>= -sp_zcst0 && i< sp_ncst0-sp_zcst0)
|
||||
outbyte( (byte) (i+sp_zcst0+sp_fcst0) );
|
||||
else {
|
||||
outbyte( (byte) sp_cst2) ;
|
||||
outshort(i);
|
||||
}
|
||||
}
|
||||
|
||||
outshort(i) short i; {
|
||||
|
||||
outbyte( (byte) (i&BMASK) );
|
||||
outbyte( (byte) (i>>8) );
|
||||
}
|
||||
|
||||
numlab(np) register num_p np; {
|
||||
|
||||
if (np->n_number < sp_nilb0)
|
||||
outbyte( (byte) (np->n_number + sp_filb0) );
|
||||
else
|
||||
outnum(np);
|
||||
}
|
||||
|
||||
outnum(np) register num_p np; {
|
||||
|
||||
if(np->n_number<256) {
|
||||
outbyte( (byte) sp_ilb1) ;
|
||||
outbyte( (byte) (np->n_number) );
|
||||
} else {
|
||||
outbyte( (byte) sp_ilb2) ;
|
||||
outshort((short) np->n_number);
|
||||
}
|
||||
}
|
||||
|
||||
outsym(sp) register sym_p sp; {
|
||||
register byte *p;
|
||||
register unsigned num;
|
||||
|
||||
if (sp->s_name[0] == '.') {
|
||||
num = atoi(&sp->s_name[1]);
|
||||
if (num < 256) {
|
||||
outbyte( (byte) sp_dlb1) ;
|
||||
outbyte( (byte) (num) );
|
||||
} else {
|
||||
outbyte( (byte) sp_dlb2) ;
|
||||
outshort((short) num);
|
||||
}
|
||||
} else {
|
||||
p= sp->s_name;
|
||||
while (*p && p < &sp->s_name[IDL])
|
||||
p++;
|
||||
num = p - sp->s_name;
|
||||
outbyte( (byte) (sp->s_flags&SYMPRO ? sp_pnam : sp_dnam) );
|
||||
outint((short) num);
|
||||
p = sp->s_name;
|
||||
while (num--)
|
||||
outbyte( (byte) *p++ );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user