Initial revision
This commit is contained in:
190
util/ass/ass50.c
Normal file
190
util/ass/ass50.c
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* (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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
#include "ip_spec.h"
|
||||
|
||||
/*
|
||||
** Pass 5 of EM1 assembler/loader
|
||||
** Fix reloc tables
|
||||
** Write out code
|
||||
*/
|
||||
|
||||
pass_5() {
|
||||
register line_t *lnp;
|
||||
cons_t off1;
|
||||
char defined ;
|
||||
int afterlength, partype ;
|
||||
register int inslength, ope;
|
||||
char *op_curr ;
|
||||
|
||||
pass = 5;
|
||||
afterlength = 0;
|
||||
for (lnp = pstate.s_fline ; lnp ; lnp= lnp->l_next, line_num++ ) {
|
||||
ope = ctrunc(lnp->instr_num);
|
||||
if ( ope==sp_ilb1 ) continue ;
|
||||
if ( ope==sp_fpseu ) {
|
||||
line_num = lnp->ad.ad_ln.ln_first ;
|
||||
continue ;
|
||||
}
|
||||
off1 = parval(lnp,&defined);
|
||||
if ( (op_curr = lnp->opoff)==NO_OFF ) {
|
||||
fatal("opoff assertion failed") ;
|
||||
}
|
||||
inslength = oplength(*op_curr) ;
|
||||
afterlength += inslength ;
|
||||
|
||||
/*
|
||||
* Change absolute offset to a relative for branches.
|
||||
*/
|
||||
|
||||
|
||||
partype= em_flag[ope]&EM_PAR ;
|
||||
if ( partype==PAR_B && defined ) {
|
||||
off1 -= afterlength;
|
||||
}
|
||||
|
||||
#ifdef JOHAN
|
||||
if ( jflag ) {
|
||||
extern char em_mnem[][4] ;
|
||||
printf("%s %D\n",em_mnem[ope],off1) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( !defined && partype==PAR_G ) { /* must be external */
|
||||
text_reloc((lnp->type1==GLOSYM ?
|
||||
lnp->ad.ad_gp:lnp->ad.ad_df.df_gp),
|
||||
(FOFFSET)(textbytes+afterlength-inslength) ,
|
||||
op_curr-opchoice);
|
||||
xputarb(inslength,off1,tfile);
|
||||
textoff += inslength ;
|
||||
} else {
|
||||
genop(op_curr,off1,partype) ;
|
||||
}
|
||||
} /* end forloop */
|
||||
line_num-- ;
|
||||
|
||||
patchcase();
|
||||
textbytes += prog_size;
|
||||
if ( textbytes>maxadr ) fatal("Maximum code area size exceeded") ;
|
||||
|
||||
} /* end pass_5 */
|
||||
|
||||
genop(startc,value,i_flag) char *startc ; cons_t value ; int i_flag ; {
|
||||
char *currc ;
|
||||
register flag ;
|
||||
char opc ;
|
||||
|
||||
/*
|
||||
* Real code generation.
|
||||
*/
|
||||
|
||||
currc= startc ;
|
||||
flag = ctrunc(*currc++);
|
||||
opc = *currc++;
|
||||
if ( (flag&OPTYPE)!=OPNO ) {
|
||||
|
||||
if ( !opfit(flag,*currc,value,i_flag) ) {
|
||||
fatal("parameter value unsuitable for selected opcode") ;
|
||||
}
|
||||
if ( flag&OPWORD ) {
|
||||
if ( value%wordsize!=0 ) {
|
||||
error("parameter not word multiple");
|
||||
}
|
||||
value /= wordsize ;
|
||||
}
|
||||
if ( flag&OPNZ ) {
|
||||
if ( value<=0 ) error("negative parameter");
|
||||
value-- ;
|
||||
}
|
||||
}
|
||||
if ( flag&OPESC ) put8(ESC) ;
|
||||
|
||||
switch ( flag&OPTYPE ) {
|
||||
case OPMINI :
|
||||
opc += value<0 ? -1-value : value ;
|
||||
break ;
|
||||
case OPSHORT :
|
||||
if ( value<0 ) {
|
||||
opc += -1-(value>>8) ;
|
||||
} else {
|
||||
opc += value>>8 ;
|
||||
}
|
||||
break ;
|
||||
case OP32 :
|
||||
case OP64 :
|
||||
put8(ESC_L) ;
|
||||
}
|
||||
|
||||
#ifdef DUMP
|
||||
if ( c_flag ) {
|
||||
switch(flag&OPTYPE) {
|
||||
case OP32 :
|
||||
case OP64 :
|
||||
opcnt3[opc&0377]= 1 ;
|
||||
break ;
|
||||
default :
|
||||
if ( flag&OPESC ) opcnt2[opc&0377]= 1 ;
|
||||
else opcnt1[opc&0377]= 1 ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
put8(opc) ;
|
||||
switch( flag&OPTYPE ) {
|
||||
case OPNO:
|
||||
case OPMINI:
|
||||
break ;
|
||||
case OPSHORT:
|
||||
case OP8:
|
||||
put8((char)value) ;
|
||||
break ;
|
||||
case OP16:
|
||||
put16(int_cast value) ;
|
||||
break ;
|
||||
case OP32:
|
||||
put32(value) ;
|
||||
break ;
|
||||
case OP64:
|
||||
put64(value) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
patchcase() {
|
||||
register relc_t *r;
|
||||
register locl_t *k;
|
||||
|
||||
if ( r= pstate.s_fdata ) {
|
||||
r= r->r_next ;
|
||||
} else {
|
||||
r= f_data ;
|
||||
}
|
||||
for( ; r ; r= r->r_next ) {
|
||||
if (r->r_typ == RELLOC) {
|
||||
r->r_typ = RELADR;
|
||||
k = r->r_val.rel_lp;
|
||||
if (k->l_defined==YES)
|
||||
r->r_val.rel_i = k->l_min + textbytes;
|
||||
else
|
||||
error("case label at line %d undefined",
|
||||
k->l_min);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user