2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
14 static char rcs_id[] = "$Id: assci.c,v 2.10 1994/06/24 10:15:26 ceriel Exp $" ;
18 * read compact code and fill in tables
24 static int oksizes; /* MES EMX,.,. seen */
26 static enum m_type { CON, ROM, HOLBSS } memtype ;
27 static int valtype; /* Transfer of type information between
28 valsize, inpseudo and putval
44 error("illegal data label .%d",tabval);
56 error("illegal instruction label %d",tabval);
81 if ( consiz<wordsize ?
82 wordsize%consiz!=0 : consiz%wordsize!=0 ) {
83 fatal("illegal object size") ;
92 register int l_byte, h_byte;
96 if ( h_byte>=128 ) h_byte -= 256 ;
97 return l_byte | (h_byte*256) ;
101 register int l_byte, h_byte;
105 return l_byte | (h_byte*256) ;
112 l = get8(); l |= (unsigned)get8()*256 ; l |= get8()*256L*256L ;
114 if ( h_byte>=128 ) h_byte -= 256 ;
115 return l | (h_byte*256L*256*256L) ;
122 if (i < sp_fmnem+sp_nmnem && i >= sp_fmnem) {
126 if (i < sp_fpseu+sp_npseu && i >= sp_fpseu) {
130 if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) {
131 tabval = i - sp_filb0;
141 if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) {
142 argval = i - sp_zcst0;
151 argtyp = t = table2();
154 if ((typset & t) == 0)
155 error("bad argument type %d",argtyp);
164 glob_t *getlab(status) {
166 return(glo2lookup(string,status));
169 char *getdig(str,number) char *str; register unsigned number; {
174 if ( number ) str= getdig(str,number) ;
175 *str++ = '0'+remain ;
179 make_string(n) unsigned n ; {
181 *getdig(&string[1],n)= 0;
190 if ( argval < 0 || argval >= MAXSTRING-1 )
191 fatal("string/identifier too long");
192 strlngth = n = argval;
204 getarg(ptyp(sp_pnam));
213 switch ( table2() ) {
215 if (g = xglolookup(string,SEARCHING)) {
216 if ((g->g_status&DEF) != 0)
221 p = searchproc(string,xprocs,oursize->n_xproc);
223 if ((p->p_status & DEF) != 0)
228 error("Unexpected byte after ms_ext") ;
232 while ( table2()!=sp_cend ) ;
238 switch(valtype=table2()) { /* valtype is used by putval and inpseudo */
255 fatal("value expected") ;
261 register line_t *n_lnp ;
263 if ( type>VALLOW ) type=VALLOW ;
264 n_lnp = lnp_cast getarea((unsigned)linesize[type]) ;
265 n_lnp->l_next = pstate.s_fline ;
266 pstate.s_fline = n_lnp ;
267 n_lnp->type1 = type ;
268 n_lnp->opoff = NO_OFF ;
274 * read module in compact EM1 code
282 } while (!eof_seen) ;
283 endproc() ; /* Throw away unwanted garbage */
284 if ( mod_sizes ) end_module();
285 /* mod_sizes is only false for rejected library modules */
292 * read one "line" of compact code.
297 fatal("unknown byte at start of \"line\""); /* NOTREACHED */
300 while ( pstate.s_prevstat != pst_cast 0 ) {
301 error("missing end") ; do_proc() ;
305 if ( pstate.s_curpro == prp_cast 0) {
306 error("instruction outside procedure");
309 if ( (em_flag[instr_no]&EM_PAR)==PAR_NO ) {
311 pstate.s_fline->instr_num= instr_no ;
315 * This instruction should have an opcode, so read it after
322 curglosym = glo2lookup(string,DEFINING);
323 curglosym->g_val.g_addr = databytes;
324 lastglosym = curglosym;
325 setline() ; line_num++ ;
326 if (table1() != sp_fpseu)
327 fatal("no pseudo after data label");
334 pstate.s_fline->ad.ad_lp = loclookup(tabval,DEFINING);
335 pstate.s_fline->instr_num = sp_ilb1;
340 * Now process argument
345 fatal("unknown byte at start of argument"); /*NOTREACHED*/
347 if ( (em_flag[instr_no]&EM_PAR)==PAR_B ) {
348 /* value indicates a label */
350 pstate.s_fline->ad.ad_lp=
351 loclookup((int)argval,OCCURRING) ;
353 if ( argval>=VAL1(VALLOW) && argval<=VAL1(VALHIGH)) {
355 pstate.s_fline->type1 = argval+VALMID ;
358 pstate.s_fline->ad.ad_i = argval;
359 pstate.s_fline->type1 = CONST;
365 pstate.s_fline->ad.ad_lp = loclookup(tabval,OCCURRING);
369 pstate.s_fline->ad.ad_gp = glo2lookup(string,OCCURRING);
373 pstate.s_fline->ad.ad_pp=prolookup(string,PRO_OCC);
376 if ( (em_flag[instr_no]&EM_PAR)!=PAR_W ) {
377 fatal("missing operand") ;
383 pstate.s_fline->ad.ad_df.df_i = argval ;
384 pstate.s_fline->ad.ad_df.df_gp= glo2lookup(string,OCCURRING) ;
387 pstate.s_fline->instr_num= instr_no ;
393 register proc_t *prptr;
399 * get operands of pseudo (if needed) and process it.
402 switch ( ctrunc(instr_no) ) {
406 cst = getint(); /* number of bytes */
419 typealign( ctrunc(instr_no)==ps_rom ? ROM : CON ) ;
420 while( (objsize=valsize())!=0 ) {
421 if ( valtype!=sp_scon) sizealign(objsize) ;
427 prptr= pstate.s_curpro ;
428 if ( prptr == prp_cast 0 ) fatal("unexpected END") ;
429 proctab[prptr->p_num].pr_off = textbytes;
431 printf("%6lu\t%6lo\t%5d\t%-12s\t%s",
433 prptr->p_num,prptr->p_name,curfile);
435 printf("(%.14s)",archhdr.ar_name);
438 par2 = proctab[prptr->p_num].pr_loc ;
439 if ( getarg(cst_ptyp|ptyp(sp_cend))==sp_cend ) {
441 fatal("size of local area unspecified") ;
444 if ( par2 != -1 && argval!=par2 ) {
445 fatal("inconsistent local area size") ;
447 proctab[prptr->p_num].pr_loc = argval ;
453 switch( int_cast getint() ) {
455 error("module with error") ; ertrap();
459 if ( wordsize!=getint() ) {
460 fatal("Inconsistent word size");
462 if ( ptrsize!=getint() ) {
463 fatal("Inconsistent pointer size");
467 wordsize=getint();ptrsize=getint();
468 if ( wordsize!=2 && wordsize!=4 ) {
469 fatal("Illegal word size");
471 if ( ptrsize!=2 && ptrsize!=4 ) {
472 fatal("Illegal pointer size");
481 intflags |= 020; break; /*floats used*/
487 werror("mes ms_ext must be first or second pseudo") ;
491 while (table2() != sp_cend)
497 if (par1 == 0 || par2 == 0)
499 exchange((int)par2,(int)par1) ;
511 if ( getarg(cst_ptyp|ptyp(sp_cend))==sp_cend ) {
516 prptr = prolookup(pars,PRO_DEF);
517 proctab[prptr->p_num].pr_loc = par2;
518 pstate.s_curpro=prptr;
521 prptr = prolookup(inproname(),PRO_INT);
524 prptr = prolookup(inproname(),PRO_EXT);
527 fatal("unknown pseudo");
529 if ( !mod_sizes ) fatal("Missing size specification");
530 if ( databytes>maxadr ) error("Maximum data area size exceeded") ;
535 /* Get line numbers correct */
537 if ( pstate.s_fline &&
538 ctrunc(pstate.s_fline->instr_num) == sp_fpseu ) {
539 /* Already one present */
540 pstate.s_fline->ad.ad_ln.ln_extra++ ;
543 pstate.s_fline->instr_num= sp_fpseu ;
544 pstate.s_fline->ad.ad_ln.ln_extra= 0 ;
545 pstate.s_fline->ad.ad_ln.ln_first= line_num ;
550 cons_t maxval(bits) int bits ; {
551 /* find the maximum positive value,
552 * fitting in 'bits' bits AND
553 * fitting in a 'cons_t' .
560 if ( val<0 ) return ~val ;
566 maxadr = maxval(8*ptrsize) ;
567 maxint = maxval(8*wordsize-1) ;
568 maxunsig = maxval(8*wordsize) ;
569 maxdint = maxval(2*8*wordsize-1) ;
570 maxdunsig = maxval(2*8*wordsize) ;
575 int l_of_p1, l_of_p2, l_of_before ;
576 register line_t *t_lnp,*a_lnp, *b_lnp ;
578 /* Since the lines are linked backwards it is easy
579 * to count the number of lines backwards.
580 * Each instr counts for 1, each pseudo for ln_extra + 1.
581 * The line numbers in error messages etc. are INCORRECT
585 line= line_num ; size=0 ;
586 newline(LINES) ; a_lnp=pstate.s_fline ;
587 a_lnp->instr_num= sp_fpseu ;
588 a_lnp->ad.ad_ln.ln_first= line ;
589 a_lnp->ad.ad_ln.ln_extra= -1 ;
590 for ( ; a_lnp ; a_lnp= a_lnp->l_next ) {
592 switch ( ctrunc(a_lnp->instr_num) ) {
594 line= a_lnp->ad.ad_ln.ln_first ;
595 size += a_lnp->ad.ad_ln.ln_extra ;
598 a_lnp->ad.ad_lp->l_min -= p2 ;
602 if ( size>=p1 ) break ;
604 if ( ( size-= p1 )>0 ) {
605 if ( ctrunc(a_lnp->instr_num) !=sp_fpseu ) {
606 fatal("EXC inconsistency") ;
608 doinsert(a_lnp,line,size-1) ;
609 a_lnp->ad.ad_ln.ln_extra -= size ;
612 if( a_lnp) doinsert(a_lnp,line,-1) ;
616 b_lnp= b_lnp->l_next ;
618 switch ( ctrunc(b_lnp->instr_num) ) {
620 size += b_lnp->ad.ad_ln.ln_extra ;
621 line = b_lnp->ad.ad_ln.ln_first ;
624 b_lnp->ad.ad_lp->l_min += p1 ;
628 if ( size>=p2 ) break ;
630 if ( !b_lnp ) { /* if a_lnp==0, so is b_lnp */
631 fatal("Cannot perform exchange") ;
633 if ( ( size-= p2 )>0 ) {
634 if ( ctrunc(b_lnp->instr_num) !=sp_fpseu ) {
635 fatal("EXC inconsistency") ;
637 doinsert(b_lnp,line,size-1) ;
638 b_lnp->ad.ad_ln.ln_extra -= size ;
640 doinsert(b_lnp,line,-1) ;
642 t_lnp = b_lnp->l_next ;
643 b_lnp->l_next = pstate.s_fline ;
644 pstate.s_fline= a_lnp->l_next ;
645 a_lnp->l_next=t_lnp ;
648 doinsert(lnp,first,extra) line_t *lnp ; {
649 /* Beware : s_fline will be clobbered and restored */
650 register line_t *t_lnp ;
652 t_lnp= pstate.s_fline;
653 pstate.s_fline= lnp->l_next ;
655 pstate.s_fline->instr_num= sp_fpseu ;
656 pstate.s_fline->ad.ad_ln.ln_first= first ;
657 pstate.s_fline->ad.ad_ln.ln_extra= extra ;
658 lnp->l_next= pstate.s_fline ;
659 pstate.s_fline= t_lnp; /* restore */
668 extloc(loclookup(tabval,OCCURRING));
671 extglob(glo2lookup(string,OCCURRING),(cons_t)0);
674 extglob(glo2lookup(string,OCCURRING),argval);
677 extpro(prolookup(string,PRO_OCC));
692 fatal("putval notreached") ;
698 static int absout = 0 ;
700 if ( absout ) return ;
701 if ( !oksizes ) fatal("missing size specification") ;
702 setmode(DATA_CONST) ;
703 extconst((cons_t)0) ;
704 databytes= wordsize ;
706 if ( wordsize<ABSSIZE ) {
707 register factor = ABSSIZE/wordsize - 1 ;
708 extadr( (cons_t) factor ) ;
709 databytes += factor * wordsize ;
715 typealign(new) enum m_type new ; {
716 if ( memtype==new ) return ;
721 sizealign(size) cons_t size ; {
722 align( size>wordsize ? wordsize : (int)size ) ;
725 align(size) int size ; {
726 while ( databytes%size ) {
727 setmode(DATA_BYTES) ;
733 extconst(n) cons_t n ; {
738 extbss(n) cons_t n ; {
739 cons_t objsize,amount ;
744 if ( n<0 ) werror("negative bss/hol size") ;
745 if ( table2()==sp_cend || table2()==sp_cend) {
746 werror("Unexpected end-of-line") ;
750 setmode(DATA_NUL) ; /* flush descriptor */
753 werror("Unexpected end-of-line");
756 if ( n%objsize != 0 ) error("BSS/HOL incompatible sizes");
760 if ( argval<0 || argval>1 ) error("illegal last argument") ;
773 n = (n + wordsize - 1) / wordsize;
774 while (n > MAXBYTE) {
784 extloc(lbp) register locl_t *lbp; {
787 * assemble a pointer constant from a local label.
791 data_reloc( chp_cast lbp,dataoff,RELLOC);
795 extglob(agbp,off) glob_t *agbp; cons_t off; {
796 register glob_t *gbp;
799 * generate a word of data that is defined by a global symbol.
800 * Various relocation has to be prepared here in some cases
804 if ( gbp->g_status&DEF ) {
805 extadr(gbp->g_val.g_addr+off);
807 data_reloc( chp_cast gbp,dataoff,RELGLO);
812 extpro(aprp) proc_t *aprp; {
814 * generate a addres that is defined by a procedure descriptor.
816 consiz= ptrsize ; setmode(DATA_UCON);
817 extarb((int)ptrsize,(long)(aprp->p_num));
825 * generate data for a string.
827 for(n=strlngth,s=string ; n--; ) {
828 setmode(DATA_BYTES) ;
839 * generate data for a floating constant initialized by a string.
844 for (n=strlngth ; n-- ;) {
845 if ( *s==0 ) error("Zero byte in initializer") ;
855 * generate data for a constant initialized by a string.
860 error("Size of initializer exceeds loader capability") ;
862 extarb((int)consiz,atol(string)) ;