1 /* $Id: ca_put.c,v 1.8 1994/06/24 10:19:43 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".
12 #include "../share/types.h"
14 #include "../share/debug.h"
15 #include "../share/def.h"
16 #include "../share/map.h"
17 #include "../share/alloc.h"
19 #define outbyte(b) putc(b,outfile)
23 STATIC proc_p thispro;
30 STATIC coutshort(i) short i; {
32 outbyte( (byte) (i&BMASK) );
33 outbyte( (byte) (i>>8) );
36 STATIC coutint(i) short i; {
38 if (i>= -sp_zcst0 && i< sp_ncst0-sp_zcst0)
39 outbyte( (byte) (i+sp_zcst0+sp_fcst0) );
41 outbyte( (byte) sp_cst2) ;
46 STATIC coutoff(off) offset off; {
48 if ((short) off == off)
51 outbyte( (byte) sp_cst4) ;
52 coutshort( (short) (off&0177777L) );
53 coutshort( (short) (off>>16) );
63 register unsigned num;
68 outbyte( (byte) sp_dlb1) ;
69 outbyte( (byte) (num) );
71 outbyte( (byte) sp_dlb2) ;
72 coutshort((short) num);
76 while (*p && p < &s[IDL])
83 outbyte( (byte) *p++ );
91 if (dnames[dbl->d_id]) outsym(dnames[dbl->d_id],sp_dnam);
98 outsym(pnames[p->p_id],sp_pnam);
102 STATIC outddef(id) short id; {
107 dbl->d_flags2 |= DF_SYMOUT;
108 if (dbl->d_flags1 & DF_EXTERNAL) {
114 STATIC outpdef(p) proc_p p; {
115 p->p_flags2 |= PF_SYMOUT;
116 if (p->p_flags1 & PF_EXTERNAL) {
123 STATIC outdocc(obj) obj_p obj; {
127 if ((dbl->d_flags2 & DF_SYMOUT) == 0) {
128 dbl->d_flags2 |= DF_SYMOUT;
129 if (dnames[dbl->d_id] != 0 &&
130 (dbl->d_flags1 & DF_EXTERNAL) == 0) {
138 STATIC outpocc(p) proc_p p; {
139 if ((p->p_flags2 & PF_SYMOUT) == 0) {
140 p->p_flags2 |= PF_SYMOUT;
141 if ((p->p_flags1 & PF_EXTERNAL) == 0) {
149 STATIC coutobject(obj)
152 /* In general, an object is defined by a global data
153 * label and an offset. There are two special cases:
154 * the label is omitted if the object is part of the current
155 * hol block; the offset is omitted if it is 0 and the label
158 if (dnames[obj->o_dblock->d_id] == 0) {
161 if (obj->o_off == 0) {
162 outdsym(obj->o_dblock);
164 outbyte((byte) sp_doff);
165 outdsym(obj->o_dblock);
172 STATIC cputstr(abp) register argb_p abp; {
178 while (tbp!= (argb_p) 0) {
179 length += tbp->ab_index;
183 while (abp != (argb_p) 0) {
184 for (length=0;length<abp->ab_index;length++)
185 outbyte( (byte) abp->ab_contents[length] );
195 outbyte((byte) sp_ilb1);
198 outbyte((byte) sp_ilb2);
199 coutshort((short) n);
208 outbyte((byte) (n + sp_filb0));
221 while (ap != (arg_p) 0) {
224 coutoff(ap->a_a.a_offset);
227 coutobject(ap->a_a.a_obj);
230 outpsym(ap->a_a.a_proc);
233 outnum(ap->a_a.a_instrlab);
236 outbyte((byte) sp_scon);
237 cputstr(&ap->a_a.a_string);
240 outbyte((byte) sp_icon);
243 outbyte((byte) sp_ucon);
246 outbyte((byte) sp_fcon);
248 coutint(ap->a_a.a_con.ac_length);
249 cputstr(&ap->a_a.a_con.ac_con);
255 /* Avoid generating extremely long CON or ROM statements */
256 if (cnt++ > 10 && ap != (arg_p) 0 &&
257 (INSTR(lnp) == ps_con || INSTR(lnp) == ps_rom)) {
259 outbyte((byte) sp_cend);
267 STATIC outoperand(lnp)
270 /* Output the operand of instruction lnp */
274 if (INSTR(lnp) <= sp_lmnem &&
275 (em_flag[INSTR(lnp)-sp_fmnem]&EM_PAR) != PAR_NO) {
276 outbyte((byte) sp_cend);
280 if (INSTR(lnp) == ps_sym) {
281 outsym(dnames[SHORT(lnp)],sp_dnam);
287 coutoff(OFFSET(lnp));
290 if (INSTR(lnp) == op_lab) {
291 numlab(INSTRLAB(lnp));
293 if (INSTR(lnp) < sp_fpseu) {
294 coutint(INSTRLAB(lnp));
296 numlab(INSTRLAB(lnp));
301 coutobject(OBJ(lnp));
312 outbyte((byte) sp_cend);
313 /* list terminator */
323 STATIC outvisibility(lnp)
326 /* In EM names of datalabels and procedures can be made
327 * externally visible, so they can be used in other files.
328 * There are special EM pseudo-instructions to state
329 * explicitly that a certain identifier is externally
330 * visible (ps_exa,ps_exp) or invisible (ps_ina,ps_inp).
331 * If there is no such pseudo for a certain identifier,
332 * the identifier is external only if its first use
333 * in the current file is an applied occurrence.
334 * Unfortunately the global optimizer may change the
335 * order of defining and applied occurrences.
336 * In the first optimizer pass (ic) we record for each identifier
337 * whether it is external or not. If necessary we generate
338 * pseudo instructions here.
348 /* applied occurrence of a data label */
351 if (instr == ps_sym) {
353 /* defining occ. data label */
357 if (instr == ps_pro) {
359 /* defining occ. procedure */
365 for (ap = ARG(lnp); ap != (arg_p) 0; ap = ap->a_next) {
368 outdocc(ap->a_a.a_obj);
371 outpocc(ap->a_a.a_proc);
384 /* Output the lines in Campact assembly language
391 for (lnp = l; lnp != (line_p) 0; lnp = next) {
393 outvisibility(lnp); /* take care of visibiltity rules */
394 if (INSTR(lnp) != ps_sym && INSTR(lnp) != op_lab) {
401 /* fall through ... */
403 coutoff(thispro->p_localbytes);
407 if (lmap != (line_p *) 0) {
408 oldmap(lmap,llength);
416 /* write the magic number */