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 ;
451 proctab[prptr->p_num].pr_len =
452 textbytes - proctab[prptr->p_num].pr_off;
455 switch( int_cast getint() ) {
457 error("module with error") ; ertrap();
461 if ( wordsize!=getint() ) {
462 fatal("Inconsistent word size");
464 if ( ptrsize!=getint() ) {
465 fatal("Inconsistent pointer size");
469 wordsize=getint();ptrsize=getint();
470 if ( wordsize!=2 && wordsize!=4 ) {
471 fatal("Illegal word size");
473 if ( ptrsize!=2 && ptrsize!=4 ) {
474 fatal("Illegal pointer size");
483 intflags |= 020; break; /*floats used*/
489 werror("mes ms_ext must be first or second pseudo") ;
493 while (table2() != sp_cend)
499 if (par1 == 0 || par2 == 0)
501 exchange((int)par2,(int)par1) ;
513 if ( getarg(cst_ptyp|ptyp(sp_cend))==sp_cend ) {
518 prptr = prolookup(pars,PRO_DEF);
519 proctab[prptr->p_num].pr_loc = par2;
520 pstate.s_curpro=prptr;
523 prptr = prolookup(inproname(),PRO_INT);
526 prptr = prolookup(inproname(),PRO_EXT);
529 fatal("unknown pseudo");
531 if ( !mod_sizes ) fatal("Missing size specification");
532 if ( databytes>maxadr ) error("Maximum data area size exceeded") ;
537 /* Get line numbers correct */
539 if ( pstate.s_fline &&
540 ctrunc(pstate.s_fline->instr_num) == sp_fpseu ) {
541 /* Already one present */
542 pstate.s_fline->ad.ad_ln.ln_extra++ ;
545 pstate.s_fline->instr_num= sp_fpseu ;
546 pstate.s_fline->ad.ad_ln.ln_extra= 0 ;
547 pstate.s_fline->ad.ad_ln.ln_first= line_num ;
552 cons_t maxval(bits) int bits ; {
553 /* find the maximum positive value,
554 * fitting in 'bits' bits AND
555 * fitting in a 'cons_t' .
562 if ( val<0 ) return ~val ;
568 maxadr = maxval(8*ptrsize) ;
569 maxint = maxval(8*wordsize-1) ;
570 maxunsig = maxval(8*wordsize) ;
571 maxdint = maxval(2*8*wordsize-1) ;
572 maxdunsig = maxval(2*8*wordsize) ;
577 int l_of_p1, l_of_p2, l_of_before ;
578 register line_t *t_lnp,*a_lnp, *b_lnp ;
580 /* Since the lines are linked backwards it is easy
581 * to count the number of lines backwards.
582 * Each instr counts for 1, each pseudo for ln_extra + 1.
583 * The line numbers in error messages etc. are INCORRECT
587 line= line_num ; size=0 ;
588 newline(LINES) ; a_lnp=pstate.s_fline ;
589 a_lnp->instr_num= sp_fpseu ;
590 a_lnp->ad.ad_ln.ln_first= line ;
591 a_lnp->ad.ad_ln.ln_extra= -1 ;
592 for ( ; a_lnp ; a_lnp= a_lnp->l_next ) {
594 switch ( ctrunc(a_lnp->instr_num) ) {
596 line= a_lnp->ad.ad_ln.ln_first ;
597 size += a_lnp->ad.ad_ln.ln_extra ;
600 a_lnp->ad.ad_lp->l_min -= p2 ;
604 if ( size>=p1 ) break ;
606 if ( ( size-= p1 )>0 ) {
607 if ( ctrunc(a_lnp->instr_num) !=sp_fpseu ) {
608 fatal("EXC inconsistency") ;
610 doinsert(a_lnp,line,size-1) ;
611 a_lnp->ad.ad_ln.ln_extra -= size ;
614 if( a_lnp) doinsert(a_lnp,line,-1) ;
618 b_lnp= b_lnp->l_next ;
620 switch ( ctrunc(b_lnp->instr_num) ) {
622 size += b_lnp->ad.ad_ln.ln_extra ;
623 line = b_lnp->ad.ad_ln.ln_first ;
626 b_lnp->ad.ad_lp->l_min += p1 ;
630 if ( size>=p2 ) break ;
632 if ( !b_lnp ) { /* if a_lnp==0, so is b_lnp */
633 fatal("Cannot perform exchange") ;
635 if ( ( size-= p2 )>0 ) {
636 if ( ctrunc(b_lnp->instr_num) !=sp_fpseu ) {
637 fatal("EXC inconsistency") ;
639 doinsert(b_lnp,line,size-1) ;
640 b_lnp->ad.ad_ln.ln_extra -= size ;
642 doinsert(b_lnp,line,-1) ;
644 t_lnp = b_lnp->l_next ;
645 b_lnp->l_next = pstate.s_fline ;
646 pstate.s_fline= a_lnp->l_next ;
647 a_lnp->l_next=t_lnp ;
650 doinsert(lnp,first,extra) line_t *lnp ; {
651 /* Beware : s_fline will be clobbered and restored */
652 register line_t *t_lnp ;
654 t_lnp= pstate.s_fline;
655 pstate.s_fline= lnp->l_next ;
657 pstate.s_fline->instr_num= sp_fpseu ;
658 pstate.s_fline->ad.ad_ln.ln_first= first ;
659 pstate.s_fline->ad.ad_ln.ln_extra= extra ;
660 lnp->l_next= pstate.s_fline ;
661 pstate.s_fline= t_lnp; /* restore */
670 extloc(loclookup(tabval,OCCURRING));
673 extglob(glo2lookup(string,OCCURRING),(cons_t)0);
676 extglob(glo2lookup(string,OCCURRING),argval);
679 extpro(prolookup(string,PRO_OCC));
694 fatal("putval notreached") ;
700 static int absout = 0 ;
702 if ( absout ) return ;
703 if ( !oksizes ) fatal("missing size specification") ;
704 setmode(DATA_CONST) ;
705 extconst((cons_t)0) ;
706 databytes= wordsize ;
708 if ( wordsize<ABSSIZE ) {
709 register factor = ABSSIZE/wordsize - 1 ;
710 extadr( (cons_t) factor ) ;
711 databytes += factor * wordsize ;
717 typealign(new) enum m_type new ; {
718 if ( memtype==new ) return ;
723 sizealign(size) cons_t size ; {
724 align( size>wordsize ? wordsize : (int)size ) ;
727 align(size) int size ; {
728 while ( databytes%size ) {
729 setmode(DATA_BYTES) ;
735 extconst(n) cons_t n ; {
740 extbss(n) cons_t n ; {
741 cons_t objsize,amount ;
746 if ( n<0 ) werror("negative bss/hol size") ;
747 if ( table2()==sp_cend || table2()==sp_cend) {
748 werror("Unexpected end-of-line") ;
752 setmode(DATA_NUL) ; /* flush descriptor */
755 werror("Unexpected end-of-line");
758 if ( n%objsize != 0 ) error("BSS/HOL incompatible sizes");
762 if ( argval<0 || argval>1 ) error("illegal last argument") ;
775 n = (n + wordsize - 1) / wordsize;
776 while (n > MAXBYTE) {
786 extloc(lbp) register locl_t *lbp; {
789 * assemble a pointer constant from a local label.
793 data_reloc( chp_cast lbp,dataoff,RELLOC);
797 extglob(agbp,off) glob_t *agbp; cons_t off; {
798 register glob_t *gbp;
801 * generate a word of data that is defined by a global symbol.
802 * Various relocation has to be prepared here in some cases
806 if ( gbp->g_status&DEF ) {
807 extadr(gbp->g_val.g_addr+off);
809 data_reloc( chp_cast gbp,dataoff,RELGLO);
814 extpro(aprp) proc_t *aprp; {
816 * generate a addres that is defined by a procedure descriptor.
818 consiz= ptrsize ; setmode(DATA_UCON);
819 extarb((int)ptrsize,(long)(aprp->p_num));
827 * generate data for a string.
829 for(n=strlngth,s=string ; n--; ) {
830 setmode(DATA_BYTES) ;
841 * generate data for a floating constant initialized by a string.
846 for (n=strlngth ; n-- ;) {
847 if ( *s==0 ) error("Zero byte in initializer") ;
857 * generate data for a constant initialized by a string.
862 error("Size of initializer exceeds loader capability") ;
864 extarb((int)consiz,atol(string)) ;