1 /* $Id: put.c,v 1.9 1994/06/24 10:30:48 ceriel Exp $ */
3 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4 * See the copyright notice in the ACK home directory, in the file "Copyright".
23 /* The output can be either 'typed' or 'untyped'. Typed data
24 * consists of a value preceded by a byte specifying what kind
25 * of value it is (e.g. 2 bytes constant, 4 bytes constant,
26 * proc-id, lab-id, string etc.). Untyped data consists
27 * of the value only. We use typed data for the EM text and
28 * untyped data for all other files.
40 while (ap != (arg_p) 0) {
41 outbyte((byte) ap->a_type & BMASK);
44 outoff(ap->a_a.a_offset);
47 outlab(ap->a_a.a_instrlab);
50 outobject(ap->a_a.a_obj);
53 outproc(ap->a_a.a_proc);
56 putstr(&ap->a_a.a_string);
61 outshort(ap->a_a.a_con.ac_length);
62 putstr(&ap->a_a.a_con.ac_con);
67 outbyte((byte) ARGCEND);
72 STATIC putstr(abp) register argb_p abp; {
78 while (tbp!= (argb_p) 0) {
79 length += tbp->ab_index;
83 while (abp != (argb_p) 0) {
84 for (length=0;length<abp->ab_index;length++)
85 outbyte( (byte) abp->ab_contents[length] );
91 outoff(off) offset off; {
93 outshort( (short) (off&0177777L) );
94 outshort( (short) (off>>16) );
98 outshort(i) short i; {
100 outbyte( (byte) (i&BMASK) );
101 outbyte( (byte) (i>>8) );
108 /* Write an integer to the output file. This routine is
109 * only used when outputting a bitvector-set. We expect an
110 * integer to be either a short or a long.
113 if (sizeof(int) == sizeof(short)) {
116 assert (sizeof(int) == sizeof(offset));
121 STATIC outlab(lid) lab_id lid; {
122 outshort((short) lid);
126 STATIC outobject(obj) obj_p obj; {
127 outshort((short) obj->o_id);
131 outproc(p) proc_p p; {
132 outshort((short) p->p_id);
140 /* Output the list of em instructions headed by l.
141 * Return the number of instruction written.
149 curoutp = lf; /* Set f to the EM-text output file */
150 for (lnp = l; lnp != (line_p) 0; lnp = next) {
155 outbyte((byte) instr);
156 outbyte((byte) TYPE(lnp));
159 outshort(SHORT(lnp));
165 outlab(INSTRLAB(lnp));
188 #define outmark(m) outbyte((byte) m)
191 STATIC putobjects(obj)
194 while (obj != (obj_p) 0) {
205 STATIC putvalues(arg)
208 while (arg != (arg_p) 0) {
209 assert(arg->a_type == ARGOFF);
211 outoff(arg->a_a.a_offset);
219 /* Write the datablock table to the data block file df. */
221 register dblock_p dbl;
224 register short n = 0;
226 curoutp = df; /* set f to the data block output file */
227 /* Count the number of objects */
228 for (dbl = head; dbl != (dblock_p) 0; dbl = dbl->d_next) {
229 for (obj = dbl->d_objlist; obj != (obj_p) 0;
234 outshort(n); /* The table is preceded by #objects . */
235 for (dbl = head; dbl != (dblock_p) 0; dbl = next) {
237 outmark(MARK_DBLOCK);
239 outbyte(dbl->d_pseudo);
241 outshort(dbl->d_fragmnr);
242 outbyte(dbl->d_flags1);
243 putobjects(dbl->d_objlist);
244 putvalues(dbl->d_values);
248 if (omap != (obj_p *) 0) {
249 oldmap((short **) omap,olength); /* release memory for omap */
262 /* A 'compact' set is represented externally as a row of words
263 * (its bitvector) preceded by its length.
269 for (i = 0; i <= DIVWL(s->v_size - 1); i++) {
270 outint(s->v_bits[i]);
276 putptable(head,pf,all)
283 register short n = 0;
284 /* Write the proc table */
287 /* Determine the number of procs */
288 for (p = head; p != (proc_p) 0; p = p->p_next) {
291 outshort(n); /* The table is preceded by its length. */
292 outshort ((all?1:0)); /* if all=false, only some of the attributes
294 for (p = head; p != (proc_p) 0; p = next) {
297 outbyte(p->p_flags1);
298 if (p->p_flags1 & PF_BODYSEEN) {
299 /* If we have no access to the EM text of the
300 * body of a procedure, we have no information
301 * about it whatsoever, so there is nothing
302 * to output in that case.
304 outshort(p->p_nrlabels);
305 outoff(p->p_localbytes);
306 outoff(p->p_nrformals);
308 outcset(p->p_change->c_ext);
309 outshort(p->p_change->c_flags);
310 outshort(p->p_use->u_flags);
311 outcset(p->p_calling);
312 Cdeleteset(p->p_change->c_ext);
313 oldchange(p->p_change);
315 Cdeleteset(p->p_calling);
321 if (pmap != (proc_p *) 0) {
322 oldmap((short **) pmap,plength); /* release memory for pmap */
333 outshort((short) l->lp_id);
340 if (b == (bblock_p) 0) {
343 outshort((short) b->b_id);
352 /* Auxiliary routine used by outlset. */
363 /* A 'long' set is represented externally as a
364 * a sequence of elements terminated by a 0 word.
365 * The procedural parameter p is a routine that
366 * prints an id (proc_id, obj_id etc.).
371 for (i = Lfirst(s); i != (Lindex) 0; i = Lnext(i,s)) {
379 putunit(kind,p,l,gf,lf)
386 register short n = 0;
392 outshort(0); /* No basic blocks */
398 /* Determine the number of basic blocks */
399 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
402 outshort(n); /* # basic blocks */
403 outshort(Lnrelems(p->p_loops)); /* # loops */
404 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
405 n = putlines(b->b_start,lf);
407 outblock(b); /* put its block_id */
408 outshort(n); /* #instructions of the block */
409 outlset(b->b_succ, outblock); /* put succ set */
410 outlset(b->b_pred, outblock); /* put pred set */
411 outblock(b->b_idom); /* put id of immediate dominator */
412 outlset(b->b_loops, outloop); /* put loop set */
413 outshort(b->b_flags);
415 /* The Control Flow Graph of every procedure is followed
416 * by a description of the loops of the procedure.
417 * Every loop contains an id, an entry block and a level.
419 for (pi = Lfirst(p->p_loops); pi != (Lindex) 0;
420 pi = Lnext(pi,p->p_loops)) {
421 lp = (loop_p) Lelem(pi);
422 outloop(lp); /* id */
423 outshort(lp->lp_level); /* nesting level */
424 outblock(lp->lp_entry); /* loop entry block */
425 outblock(lp->lp_end);
428 Ldeleteset(p->p_loops);
429 /* We will now release the memory of the basic blocks.
430 * Note that it would be incorrect to release a basic block
431 * after it has been written, because there may be references
432 * to it from other (later) blocks.
434 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
435 Ldeleteset(b->b_loops);
436 Ldeleteset(b->b_succ);
437 Ldeleteset(b->b_pred);
440 /* Release the memory for the lmap, lbmap, bmap, lpmap tables */
441 if (lmap != (line_p *) 0) oldmap((short **) lmap,llength);
442 if (lbmap != (bblock_p *) 0) oldmap((short **) lbmap,llength);
443 if (bmap != (bblock_p *) 0) oldmap((short **) bmap,blength);
444 if (lpmap != (loop_p *) 0) oldmap((short **) lpmap,lplength);