Pristine Ack-5.5
[Ack-5.5.git] / util / ass / assci.c
1 /*
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".
4  *
5  */
6
7 #include        "ass00.h"
8 #include        "assex.h"
9 #include        <em_mes.h>
10 #include        <em_pseu.h>
11 #include        <em_ptyp.h>
12
13 #ifndef NORCSID
14 static char rcs_id[] = "$Id: assci.c,v 2.10 1994/06/24 10:15:26 ceriel Exp $" ;
15 #endif
16
17 /*
18  * read compact code and fill in tables
19  */
20
21 static  int     tabval;
22 static  cons_t  argval;
23
24 static  int     oksizes;        /* MES EMX,.,. seen */
25
26 static  enum    m_type { CON, ROM, HOLBSS }     memtype ;
27 static  int     valtype;        /* Transfer of type information between
28                                    valsize, inpseudo and putval
29                                 */
30
31 int table3(i) {
32
33         switch(i) {
34         case sp_ilb1:
35                 tabval = get8();
36                 break;
37         case sp_dlb1:
38                 make_string(get8());
39                 i= sp_dnam;
40                 break;
41         case sp_dlb2:
42                 tabval = get16();
43                 if ( tabval<0 ) {
44                         error("illegal data label .%d",tabval);
45                         tabval=0 ;
46                 }
47                 make_string(tabval);
48                 i= sp_dnam;
49                 break;
50         case sp_cst2:
51                 argval = get16();
52                 break;
53         case sp_ilb2:
54                 tabval = get16();
55                 if ( tabval<0 ) {
56                         error("illegal instruction label %d",tabval);
57                         tabval=0 ;
58                 }
59                 i = sp_ilb1;
60                 break;
61         case sp_cst4:
62                 i = sp_cst2;
63                 argval = get32();
64                 break;
65         case sp_dnam:
66         case sp_pnam:
67                 inident();
68                 break ;
69         case sp_scon:
70                 getstring() ;
71                 break;
72         case sp_doff:
73                 getarg(sym_ptyp);
74                 getarg(cst_ptyp);
75                 break;
76         case sp_icon:
77         case sp_ucon:
78         case sp_fcon:
79                 getarg(cst_ptyp);
80                 consiz = argval;
81                 if ( consiz<wordsize ?
82                         wordsize%consiz!=0 : consiz%wordsize!=0 ) {
83                         fatal("illegal object size") ;
84                 }
85                 getstring();
86                 break;
87         }
88         return(i);
89 }
90
91 int get16() {
92         register int l_byte, h_byte;
93
94         l_byte = get8();
95         h_byte = get8();
96         if ( h_byte>=128 ) h_byte -= 256 ;
97         return l_byte | (h_byte*256) ;
98 }
99
100 int getu16() {
101         register int l_byte, h_byte;
102
103         l_byte = get8();
104         h_byte = get8();
105         return l_byte | (h_byte*256) ;
106 }
107
108 cons_t get32() {
109         register cons_t l;
110         register int h_byte;
111
112         l = get8(); l |= (unsigned)get8()*256 ; l |= get8()*256L*256L ;
113         h_byte = get8() ;
114         if ( h_byte>=128 ) h_byte -= 256 ;
115         return l | (h_byte*256L*256*256L) ;
116 }
117
118 int table1() {
119         register i;
120
121         i = xget8();
122         if (i < sp_fmnem+sp_nmnem && i >= sp_fmnem) {
123                 tabval = i-sp_fmnem;
124                 return(sp_fmnem);
125         }
126         if (i < sp_fpseu+sp_npseu && i >= sp_fpseu) {
127                 tabval = i;
128                 return(sp_fpseu);
129         }
130         if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) {
131                 tabval = i - sp_filb0;
132                 return(sp_ilb1);
133         }
134         return(table3(i));
135 }
136
137 int table2() {
138         register i;
139
140         i = get8();
141         if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) {
142                 argval = i - sp_zcst0;
143                 return(sp_cst2);
144         }
145         return(table3(i));
146 }
147
148 int getarg(typset) {
149         register t,argtyp;
150
151         argtyp = t = table2();
152         t -= sp_fspec;
153         t = 1 << t;
154         if ((typset & t) == 0)
155                 error("bad argument type %d",argtyp);
156         return(argtyp);
157 }
158
159 cons_t getint() {
160         getarg(cst_ptyp);
161         return(argval);
162 }
163
164 glob_t *getlab(status) {
165         getarg(sym_ptyp);
166         return(glo2lookup(string,status));
167 }
168
169 char *getdig(str,number) char *str; register unsigned number; {
170         register int remain;
171
172         remain= number%10;
173         number /= 10;
174         if ( number ) str= getdig(str,number) ;
175         *str++ = '0'+remain ;
176         return str ;
177 }
178
179 make_string(n) unsigned n ; {
180         string[0] = '.';
181         *getdig(&string[1],n)= 0;
182 }
183
184
185 getstring() {
186         register char *p;
187         register n;
188
189         getarg(cst_ptyp);
190         if ( argval < 0 || argval >= MAXSTRING-1 )
191                 fatal("string/identifier too long");
192         strlngth = n = argval;
193         p = string;
194         while (--n >= 0)
195                 *p++ = get8();
196         *p = 0 ;
197 }
198
199 inident() {
200         getstring();
201 }
202
203 char *inproname() {
204         getarg(ptyp(sp_pnam));
205         return(string);
206 }
207
208 int needed() {
209         register glob_t *g;
210         register proc_t *p;
211
212         for(;;){
213                 switch ( table2() ) {
214                 case sp_dnam :
215                         if (g = xglolookup(string,SEARCHING)) {
216                                 if ((g->g_status&DEF) != 0)
217                                         continue ;
218                         } else continue ;
219                         break ;
220                 case sp_pnam :
221                         p = searchproc(string,xprocs,oursize->n_xproc);
222                         if (p->p_name) {
223                                 if ((p->p_status & DEF) != 0)
224                                         continue ;
225                         } else continue ;
226                         break ;
227                 default :
228                         error("Unexpected byte after ms_ext") ;
229                 case sp_cend :
230                         return FALSE ;
231                 }
232                 while ( table2()!=sp_cend ) ;
233                 return TRUE ;
234         }
235 }
236
237 cons_t valsize() {
238         switch(valtype=table2()) { /* valtype is used by putval and inpseudo */
239         case sp_cst2:
240                 return wordsize ;
241         case sp_ilb1:
242         case sp_dnam:
243         case sp_doff:
244         case sp_pnam:
245                 return ptrsize ;
246         case sp_scon:
247                 return strlngth ;
248         case sp_fcon:
249         case sp_icon:
250         case sp_ucon:
251                 return consiz ;
252         case sp_cend:
253                 return 0 ;
254         default:
255                 fatal("value expected") ;
256                 /* NOTREACHED */
257         }
258 }
259
260 newline(type) {
261         register line_t *n_lnp ;
262
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 ;
269 }
270
271 read_compact() {
272
273         /*
274          * read module in compact EM1 code
275          */
276         init_module();
277         pass = 1;
278         eof_seen = 0;
279         do {
280                 compact_line() ;
281                 line_num++;
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 */
286 }
287
288 int compact_line() {
289         register instr_no ;
290
291         /*
292          * read one "line" of compact code.
293          */
294         curglosym=0;
295         switch (table1()) {
296         default:
297                 fatal("unknown byte at start of \"line\""); /* NOTREACHED */
298         case EOF:
299                 eof_seen++ ;
300                 while ( pstate.s_prevstat != pst_cast 0 ) {
301                         error("missing end") ; do_proc() ;
302                 }
303                 return ;
304         case sp_fmnem:
305                 if ( pstate.s_curpro == prp_cast 0) {
306                         error("instruction outside procedure");
307                 }
308                 instr_no = tabval;
309                 if ( (em_flag[instr_no]&EM_PAR)==PAR_NO ) {
310                         newline(MISSING) ;
311                         pstate.s_fline->instr_num= instr_no ;
312                         return ;
313                 }
314                 /*
315                  * This instruction should have an opcode, so read it after
316                  * this switch.
317                  */
318                 break;
319         case sp_dnam:
320                 chkstart() ;
321                 align(wordsize) ;
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");
328         case sp_fpseu:
329                 inpseudo(tabval);
330                 setline() ;
331                 return ;
332         case sp_ilb1:
333                 newline(LOCSYM) ;
334                 pstate.s_fline->ad.ad_lp = loclookup(tabval,DEFINING);
335                 pstate.s_fline->instr_num = sp_ilb1;
336                 return ;
337         }
338
339         /*
340          * Now process argument
341          */
342
343         switch(table2()) {
344         default:
345                 fatal("unknown byte at start of argument"); /*NOTREACHED*/
346         case sp_cst2:
347                 if ( (em_flag[instr_no]&EM_PAR)==PAR_B ) {
348                         /* value indicates a label */
349                         newline(LOCSYM) ;
350                         pstate.s_fline->ad.ad_lp=
351                                 loclookup((int)argval,OCCURRING) ;
352                 } else {
353                         if ( argval>=VAL1(VALLOW) && argval<=VAL1(VALHIGH)) {
354                                 newline(VALLOW) ;
355                                 pstate.s_fline->type1 = argval+VALMID ;
356                         } else {
357                                 newline(CONST) ;
358                                 pstate.s_fline->ad.ad_i = argval;
359                                 pstate.s_fline->type1 = CONST;
360                         }
361                 }
362                 break;
363         case sp_ilb1:
364                 newline(LOCSYM) ;
365                 pstate.s_fline->ad.ad_lp = loclookup(tabval,OCCURRING);
366                 break;
367         case sp_dnam:
368                 newline(GLOSYM) ;
369                 pstate.s_fline->ad.ad_gp = glo2lookup(string,OCCURRING);
370                 break;
371         case sp_pnam:
372                 newline(PROCNAME) ;
373                 pstate.s_fline->ad.ad_pp=prolookup(string,PRO_OCC);
374                 break;
375         case sp_cend:
376                 if ( (em_flag[instr_no]&EM_PAR)!=PAR_W ) {
377                         fatal("missing operand") ;
378                 }
379                 newline(MISSING) ;
380                 break ;
381         case sp_doff:
382                 newline(GLOOFF) ;
383                 pstate.s_fline->ad.ad_df.df_i = argval ;
384                 pstate.s_fline->ad.ad_df.df_gp= glo2lookup(string,OCCURRING) ;
385                 break ;
386         }
387         pstate.s_fline->instr_num= instr_no ;
388         return ;
389 }
390
391 inpseudo(instr_no) {
392         cons_t cst;
393         register proc_t *prptr;
394         cons_t objsize;
395         cons_t par1,par2;
396         register char *pars;
397
398         /*
399          * get operands of pseudo (if needed) and process it.
400          */
401
402         switch ( ctrunc(instr_no) ) {
403         case ps_bss:
404                 chkstart() ;
405                 typealign(HOLBSS) ;
406                 cst = getint();   /* number of bytes */
407                 extbss(cst);
408                 break;
409         case ps_hol:
410                 chkstart() ;
411                 typealign(HOLBSS) ;
412                 holsize=getint();
413                 holbase=databytes;
414                 extbss(holsize);
415                 break;
416         case ps_rom:
417         case ps_con:
418                 chkstart() ;
419                 typealign( ctrunc(instr_no)==ps_rom ? ROM : CON ) ;
420                 while( (objsize=valsize())!=0 ) {
421                         if ( valtype!=sp_scon) sizealign(objsize) ;
422                         putval() ;
423                         databytes+=objsize ;
424                 }
425                 break;
426         case ps_end:
427                 prptr= pstate.s_curpro ;
428                 if ( prptr == prp_cast 0 ) fatal("unexpected END") ;
429                 proctab[prptr->p_num].pr_off = textbytes;
430                 if (procflag) {
431                         printf("%6lu\t%6lo\t%5d\t%-12s\t%s",
432                                 textbytes,textbytes,
433                                         prptr->p_num,prptr->p_name,curfile);
434                         if (archmode)
435                                 printf("(%.14s)",archhdr.ar_name);
436                         printf("\n");
437                 }
438                 par2 = proctab[prptr->p_num].pr_loc ;
439                 if ( getarg(cst_ptyp|ptyp(sp_cend))==sp_cend ) {
440                         if ( par2 == -1 ) {
441                                 fatal("size of local area unspecified") ;
442                         }
443                 } else {
444                         if ( par2 != -1 && argval!=par2 ) {
445                                 fatal("inconsistent local area size") ;
446                         }
447                         proctab[prptr->p_num].pr_loc = argval ;
448                 }
449                 setline();
450                 do_proc();
451                 break;
452         case ps_mes:
453                 switch( int_cast getint() ) {
454                 case ms_err:
455                         error("module with error") ; ertrap();
456                         /* NOTREACHED */
457                 case ms_emx:
458                         if ( oksizes ) {
459                                 if ( wordsize!=getint() ) {
460                                         fatal("Inconsistent word size");
461                                 }
462                                 if ( ptrsize!=getint() ) {
463                                         fatal("Inconsistent pointer size");
464                                 }
465                         } else {
466                                 oksizes++ ;
467                                 wordsize=getint();ptrsize=getint();
468                                 if ( wordsize!=2 && wordsize!=4 ) {
469                                         fatal("Illegal word size");
470                                 }
471                                 if ( ptrsize!=2 && ptrsize!=4 ) {
472                                         fatal("Illegal pointer size");
473                                 }
474                                 setsizes() ;
475                         }
476                         ++mod_sizes ;
477                         break;
478                 case ms_src:
479                         break;
480                 case ms_flt:
481                         intflags |= 020; break;  /*floats used*/
482                 case ms_ext:
483                         if ( !needed() ) {
484                                 eof_seen++ ;
485                         }
486                         if ( line_num>2 ) {
487                                 werror("mes ms_ext must be first or second pseudo") ;
488                         }
489                         return ;
490                 }
491                 while (table2() != sp_cend)
492                         ;
493                 break;
494         case ps_exc:
495                 par1 = getint();
496                 par2 = getint();
497                 if (par1 == 0 || par2 == 0)
498                         break;
499                 exchange((int)par2,(int)par1) ;
500                 break;
501         case ps_exa:
502                 getlab(EXTERNING);
503                 break;
504         case ps_ina:
505                 getlab(INTERNING);
506                 break;
507         case ps_pro:
508                 chkstart() ;
509                 initproc();
510                 pars = inproname();
511                 if ( getarg(cst_ptyp|ptyp(sp_cend))==sp_cend ) {
512                         par2 = -1 ;
513                 } else {
514                         par2 = argval ;
515                 }
516                 prptr = prolookup(pars,PRO_DEF);
517                 proctab[prptr->p_num].pr_loc = par2;
518                 pstate.s_curpro=prptr;
519                 break;
520         case ps_inp:
521                 prptr = prolookup(inproname(),PRO_INT);
522                 break;
523         case ps_exp:
524                 prptr = prolookup(inproname(),PRO_EXT);
525                 break;
526         default:
527                 fatal("unknown pseudo");
528         }
529         if ( !mod_sizes ) fatal("Missing size specification");
530         if ( databytes>maxadr ) error("Maximum data area size exceeded") ;
531 }
532
533 setline() {
534
535         /* Get line numbers correct */
536
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++ ;
541         } else {
542                 newline(LINES) ;
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 ;
546         }
547
548 }
549
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' .
554          */
555
556         cons_t val ;
557         val=1 ;
558         while ( bits-- ) {
559                 val<<= 1 ;
560                 if ( val<0 ) return ~val ;
561         }
562         return val-1 ;
563 }
564
565 setsizes() {
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)   ;
571 }
572
573 exchange(p1,p2) {
574         int size, line ;
575         int l_of_p1, l_of_p2, l_of_before ;
576         register line_t *t_lnp,*a_lnp, *b_lnp ;
577
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
582          * If exc's are used.
583          */
584
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 ) {
591                 line-- ;
592                 switch ( ctrunc(a_lnp->instr_num) ) {
593                 case sp_fpseu :
594                         line= a_lnp->ad.ad_ln.ln_first ;
595                         size += a_lnp->ad.ad_ln.ln_extra ;
596                         break ;
597                 case sp_ilb1 :
598                         a_lnp->ad.ad_lp->l_min -= p2 ;
599                         break ;
600                 }
601                 size++ ;
602                 if ( size>=p1 ) break ;
603         }
604         if ( ( size-= p1 )>0 ) {
605                 if ( ctrunc(a_lnp->instr_num) !=sp_fpseu ) {
606                         fatal("EXC inconsistency") ;
607                 }
608                 doinsert(a_lnp,line,size-1) ;
609                 a_lnp->ad.ad_ln.ln_extra -= size ;
610                 size=0 ;
611         } else  {
612                 if( a_lnp) doinsert(a_lnp,line,-1) ;
613         }
614         b_lnp= a_lnp ;
615         while ( b_lnp ) {
616                 b_lnp= b_lnp->l_next ;
617                 line-- ;
618                 switch ( ctrunc(b_lnp->instr_num) ) {
619                 case sp_fpseu :
620                         size += b_lnp->ad.ad_ln.ln_extra ;
621                         line = b_lnp->ad.ad_ln.ln_first ;
622                         break ;
623                 case sp_ilb1 :
624                         b_lnp->ad.ad_lp->l_min += p1 ;
625                         break ;
626                 }
627                 size++ ;
628                 if ( size>=p2 ) break ;
629         }
630         if ( !b_lnp ) { /* if a_lnp==0, so is b_lnp */
631                 fatal("Cannot perform exchange") ;
632         }
633         if ( ( size-= p2 )>0 ) {
634                 if ( ctrunc(b_lnp->instr_num) !=sp_fpseu ) {
635                         fatal("EXC inconsistency") ;
636                 }
637                 doinsert(b_lnp,line,size-1) ;
638                 b_lnp->ad.ad_ln.ln_extra -= size ;
639         } else  {
640                 doinsert(b_lnp,line,-1) ;
641         }
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 ;
646 }
647
648 doinsert(lnp,first,extra) line_t *lnp ; {
649         /* Beware : s_fline will be clobbered and restored */
650         register line_t *t_lnp ;
651
652         t_lnp= pstate.s_fline;
653         pstate.s_fline= lnp->l_next ;
654         newline(LINES) ;
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 */
660 }
661
662 putval() {
663         switch(valtype){
664         case sp_cst2:
665                 extconst(argval);
666                 return ;
667         case sp_ilb1:
668                 extloc(loclookup(tabval,OCCURRING));
669                 return ;
670         case sp_dnam:
671                 extglob(glo2lookup(string,OCCURRING),(cons_t)0);
672                 return ;
673         case sp_doff:
674                 extglob(glo2lookup(string,OCCURRING),argval);
675                 return ;
676         case sp_pnam:
677                 extpro(prolookup(string,PRO_OCC));
678                 return ;
679         case sp_scon:
680                 extstring() ;
681                 return ;
682         case sp_fcon:
683                 extxcon(DATA_FCON) ;
684                 return ;
685         case sp_icon:
686                 extvcon(DATA_ICON) ;
687                 return ;
688         case sp_ucon:
689                 extvcon(DATA_UCON) ;
690                 return ;
691         default:
692                 fatal("putval notreached") ;
693                 /* NOTREACHED */
694         }
695 }
696
697 chkstart() {
698         static int absout = 0 ;
699
700         if ( absout ) return ;
701         if ( !oksizes ) fatal("missing size specification") ;
702         setmode(DATA_CONST) ;
703         extconst((cons_t)0) ;
704         databytes= wordsize ;
705         setmode(DATA_REP) ;
706         if ( wordsize<ABSSIZE ) {
707                 register factor = ABSSIZE/wordsize - 1 ;
708                 extadr( (cons_t) factor ) ;
709                 databytes += factor * wordsize ;
710         }
711         absout++ ;
712         memtype= HOLBSS ;
713 }
714
715 typealign(new) enum m_type new ; {
716         if ( memtype==new ) return ;
717         align(wordsize);
718         memtype=new ;
719 }
720
721 sizealign(size) cons_t size ; {
722         align( size>wordsize ? wordsize : (int)size ) ;
723 }
724
725 align(size) int size ; {
726         while ( databytes%size ) {
727                 setmode(DATA_BYTES) ;
728                 ext8(0) ;
729                 databytes++ ;
730         }
731 }
732
733 extconst(n) cons_t n ; {
734         setmode(DATA_CONST);
735         extword(n);
736 }
737
738 extbss(n) cons_t n ; {
739         cons_t objsize,amount ;
740         cons_t sv_argval;
741         int sv_tabval;
742
743         if ( n<=0 ) {
744                 if ( n<0 ) werror("negative bss/hol size") ;
745                 if ( table2()==sp_cend || table2()==sp_cend) {
746                         werror("Unexpected end-of-line") ;
747                 }
748                 return ;
749         }
750         setmode(DATA_NUL) ; /* flush descriptor */
751         objsize= valsize();
752         if ( objsize==0 ) {
753                 werror("Unexpected end-of-line");
754                 return;
755         }
756         if ( n%objsize != 0 ) error("BSS/HOL incompatible sizes");
757         sv_tabval = tabval;
758         sv_argval = argval;
759         getarg(sp_cst2);
760         if ( argval<0 || argval>1 ) error("illegal last argument") ;
761         databytes +=n ;
762         if (argval == 1) {
763                 tabval = sv_tabval;
764                 argval = sv_argval;
765                 putval();
766                 amount= n/objsize ;
767                 if ( amount>1 ) {
768                         setmode(DATA_REP);
769                         extadr(amount-1) ;
770                 }
771         }
772         else {
773                 n = (n + wordsize - 1) / wordsize;
774                 while (n > MAXBYTE) {
775                         setmode(DATA_BSS);
776                         ext8(MAXBYTE);
777                         n -= MAXBYTE;
778                 }
779                 setmode(DATA_BSS);
780                 ext8((int) n);
781         }
782 }
783
784 extloc(lbp) register locl_t *lbp; {
785
786         /*
787          * assemble a pointer constant from a local label.
788          * For example  con *1
789          */
790         setmode(DATA_IPTR);
791         data_reloc( chp_cast lbp,dataoff,RELLOC);
792         extadr((cons_t)0);
793 }
794
795 extglob(agbp,off) glob_t *agbp; cons_t off; {
796         register glob_t *gbp;
797
798         /*
799          * generate a word of data that is defined by a global symbol.
800          * Various relocation has to be prepared here in some cases
801          */
802         gbp=agbp;
803         setmode(DATA_DPTR);
804         if ( gbp->g_status&DEF ) {
805                 extadr(gbp->g_val.g_addr+off);
806         } else {
807                 data_reloc( chp_cast gbp,dataoff,RELGLO);
808                 extadr(off);
809         }
810 }
811
812 extpro(aprp) proc_t *aprp; {
813         /*
814          * generate a addres that is defined by a procedure descriptor.
815          */
816         consiz= ptrsize ; setmode(DATA_UCON);
817         extarb((int)ptrsize,(long)(aprp->p_num));
818 }
819
820 extstring() {
821         register char *s;
822         register n ;
823
824         /*
825          * generate data for a string.
826          */
827         for(n=strlngth,s=string ; n--; ) {
828                 setmode(DATA_BYTES) ;
829                 ext8(*s++);
830         }
831         return ;
832 }
833
834 extxcon(header) {
835         register char *s ;
836         register n;
837
838         /*
839          * generate data for a floating constant initialized by a string.
840          */
841
842         setmode(header);
843         s = string ;
844         for (n=strlngth ; n-- ;) {
845                 if ( *s==0 ) error("Zero byte in initializer") ;
846                 ext8(*s++);
847         }
848         ext8(0);
849         return ;
850 }
851
852 extvcon(header) {
853         extern long atol() ;
854         /*
855          * generate data for a constant initialized by a string.
856          */
857
858         setmode(header);
859         if ( consiz>4 ) {
860                 error("Size of initializer exceeds loader capability") ;
861         }
862         extarb((int)consiz,atol(string)) ;
863         return ;
864 }