Pristine Ack-5.5
[Ack-5.5.git] / modules / src / em_code / em.c
1 /* $Id: em.c,v 1.10 1994/06/24 11:10:26 ceriel Exp $ */
2 /*
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".
5  */
6 /* EM CODE OUTPUT ROUTINES */
7
8 /*      I/O part of em_code module.
9         Also contains C_open, C_close
10 */
11 #include <alloc.h>
12 #include <em_arith.h>
13 #include "insert.h"
14 #include "em_private.h"
15
16 int             C_ontmpfile = 0;
17 int             C_sequential = 1;
18 Part            *C_curr_part;
19 int             (*C_outpart)(), (*C_swtout)(), (*C_swttmp)();
20
21 #ifdef INCORE
22 char            *C_BASE;
23 #endif
24
25 File            *C_ofp;
26
27 #ifndef INCORE
28 File            *C_tfr;
29 char            *C_tmpfile;
30 char            *strcpy(), *strcat();
31 char            *C_ibuf = 0;
32 long            C_current_out;
33 #endif
34
35 #if BUFSIZ <= 1024 && BIGMACHINE
36 #define BUFFERSIZ       8*BUFSIZ
37 #else
38 #define BUFFERSIZ       BUFSIZ
39 #endif
40
41 static char     obuf[BUFFERSIZ];
42 char            *C_top = &obuf[BUFFERSIZ];
43 #ifdef INCORE
44 char            *C_current_out = obuf;
45 #else
46 char            *C_opp = obuf;
47 #endif
48
49 void
50 C_flush() {
51 #ifdef INCORE
52         static unsigned int bufsiz;
53
54         if (C_ontmpfile) {
55                 if (C_BASE == 0) {
56                         C_BASE = Malloc(BUFFERSIZ);
57                         bufsiz = BUFFERSIZ;
58                         C_current_out = C_BASE;
59                 }
60                 else {
61                         C_BASE = Srealloc(C_BASE, (bufsiz << 1));
62                         C_current_out = C_BASE + bufsiz;
63                         bufsiz <<= 1;
64                 }
65                 C_top = C_BASE + bufsiz;
66                 return;
67         }
68 #endif
69         if (C_opp != obuf && sys_write(C_ofp, obuf, (int)(C_opp - obuf)) == 0) {
70                 C_ofp = 0;
71                 C_failed();
72         }
73         C_opp = obuf;
74 }
75
76 #ifndef INCORE
77 #define Xputbyte(c) if (C_ontmpfile) C_current_out++; put(c)
78 #else
79 #define Xputbyte(c) put(c)
80 #endif
81
82 void
83 C_putbyte(c)
84         int c;
85 {
86         Xputbyte(c);
87 }
88
89 #if BIGMACHINE
90 #define C_putbyte Xputbyte
91 #endif
92
93 /*ARGSUSED*/
94 void
95 C_init(w, p)
96         arith w, p;
97 {
98 }
99
100 int
101 C_open(nm)
102         char *nm;
103 {
104         /*      Open file "nm" for output
105         */
106
107         if (nm == 0)
108                 C_ofp = STDOUT; /* standard output      */
109         else
110         if (sys_open(nm, OP_WRITE, &C_ofp) == 0)
111                 return 0;
112         return 1;
113 }
114
115 void
116 C_close()
117 {
118         /*      Finish the code-generation.
119         */
120
121 #ifndef INCORE
122         C_flush();
123         if (C_tmpfile) {
124                 (*C_swttmp)();
125                 sys_close(C_ofp);
126 #else
127         if (C_BASE) {
128 #endif
129                 if (C_curr_part) {
130                         C_curr_part->p_parts->pp_end = C_current_out - C_BASE;
131                 }
132                 (*C_swtout)();
133                 if (! C_sequential) {
134                         (*C_outpart)(0);
135                 }
136 #ifndef INCORE
137                 sys_close(C_tfr);
138                 sys_remove(C_tmpfile);
139                 if (C_ibuf) free(C_ibuf);
140 #else
141                 free(C_BASE);
142 #endif
143         }
144         C_flush();
145         if (C_ofp != STDOUT)
146                 sys_close(C_ofp);
147         C_ofp = 0;
148 }
149
150 int
151 C_busy()
152 {
153         return C_ofp != 0; /* true if code is being generated */
154 }
155
156 #ifdef READABLE_EM
157 /*
158         The C_pt_*() functions serve as formatting functions of the
159         various EM language constructs.
160         See "Description of a Machine Architecture for use with
161         Block Structured Languages" par. 11.2 for the meaning of these
162         names.
163 */
164
165 void
166 C_magic()
167 {
168 }
169
170 /***    the readable code generating routines   ***/
171
172 static
173 wrs(s)
174         register char *s;
175 {
176         while (*s) {
177                 C_putbyte(*s++);
178         }
179 }
180
181 void
182 C_pt_dnam(s)
183         char *s;
184 {
185         wrs(s);
186 }
187
188 void
189 C_pt_ilb(l)
190         label l;
191 {
192         char buf[16];
193
194         sprint(buf, "*%ld", (long) l);
195         wrs(buf);
196 }
197
198 extern char em_mnem[][4];
199 extern char em_pseu[][4];
200
201 void
202 C_pt_op(x)
203 {
204         C_putbyte(' ');
205         wrs(em_mnem[x - sp_fmnem]);
206         C_putbyte(' ');
207 }
208
209 void
210 C_pt_cst(l)
211         arith l;
212 {
213         char buf[16];
214
215         sprint(buf, "%ld", (long) l);
216         wrs(buf);
217 }
218
219 void
220 C_pt_scon(x, y)
221         char *x;
222         arith y;
223 {
224         char xbuf[1024];
225         register char *p;
226         char *bts2str();
227
228         C_putbyte('\'');
229         p = bts2str(x, (int) y, xbuf);
230         while (*p) {
231                 if (*p == '\'') {
232                         C_putbyte('\\');
233                 }
234                 C_putbyte(*p++);
235         }
236         C_putbyte('\'');
237 }
238
239 void
240 C_pt_ps(x)
241 {
242         C_putbyte(' ');
243         wrs(em_pseu[x - sp_fpseu]);
244         C_putbyte(' ');
245 }
246
247 void
248 C_pt_dlb(l)
249         label l;
250 {
251         char buf[16];
252
253         sprint(buf, ".%ld", (long) l);
254         wrs(buf);
255 }
256
257 void
258 C_pt_doff(l, v)
259         label l;
260         arith v;
261 {
262         char buf[16];
263
264         C_pt_dlb(l);
265         if (v != 0) {
266                 sprint(buf,"+%ld", (long) v);
267                 wrs(buf);
268         }
269 }
270
271 void
272 C_pt_noff(s, v)
273         char *s;
274         arith v;
275 {
276         char buf[16];
277
278         wrs(s);
279         if (v != 0) {
280                 sprint(buf,"+%ld", (long) v);
281                 wrs(buf);
282         }
283 }
284
285 void
286 C_pt_pnam(s)
287         char *s;
288 {
289         C_putbyte('$');
290         wrs(s);
291 }
292
293 void
294 C_pt_dfilb(l)
295         label l;
296 {
297         char buf[16];
298
299         sprint(buf, "%ld", (long) l);
300         wrs(buf);
301 }
302
303 void
304 C_pt_wcon(sp, v, sz)    /* sp_icon, sp_ucon or sp_fcon with int repr    */
305         int sp;
306         char *v;
307         arith sz;
308 {
309         int ch = sp == sp_icon ? 'I' : sp == sp_ucon ? 'U' : 'F';
310
311         wrs(v);
312         C_putbyte(ch);
313         C_pt_cst(sz);
314 }
315
316 void
317 C_pt_nl() {
318         C_putbyte('\n');
319 }
320
321 void
322 C_pt_comma() {
323         C_putbyte(',');
324 }
325
326 void
327 C_pt_ccend() { 
328         C_putbyte('?');
329 }
330
331 #else /* READABLE_EM */
332
333 #define put8(x)         C_putbyte(x)
334 #define put16(x)        put8((int) x); put8((int) (x >> 8))
335 #define put32(x)        put16((int) x); put16((int) (x >> 16))
336
337 /*
338         The C_pt_*() functions serve as formatting functions of the
339         various EM language constructs.
340         See "Description of a Machine Architecture for use with
341         Block Structured Languages" par. 11.2 for the meaning of these
342         names.
343 */
344
345 void
346 C_magic()
347 {
348         put16(sp_magic);
349 }
350
351 /***    the compact code generating routines    ***/
352 #define fit16i(x)       ((x) >= (long)0xFFFF8000 && (x) <= (long)0x00007FFF)
353 #define fit8u(x)        ((x) <= 0xFF)           /* x is already unsigned */
354
355 void
356 C_pt_ilb(l)
357         register label l;
358 {
359         if (fit8u(l))   {
360                 put8(sp_ilb1);
361                 put8((int)l);
362         }
363         else    {
364                 put8(sp_ilb2);
365                 put16((int)l);
366         }
367 }
368
369 void
370 C_pt_dlb(l)
371         register label l;
372 {
373         if (fit8u(l))   {
374                 put8(sp_dlb1);
375                 put8((int)l);
376         }
377         else    {
378                 put8(sp_dlb2);
379                 put16((int)l);
380         }
381 }
382
383 void
384 C_pt_cst(l)
385         register arith l;
386 {
387         if (l >= (arith) -sp_zcst0 && l < (arith) (sp_ncst0 - sp_zcst0)) {
388                 /*      we can convert 'l' to an int because its value
389                         can be stored in a byte.
390                 */
391                 put8((int)l + (sp_zcst0 + sp_fcst0));
392         }
393         else
394         if (fit16i(l)) { /* the cast from long to int causes no trouble here */
395                 put8(sp_cst2);
396                 put16((int) l);
397         }
398         else    {
399                 put8(sp_cst4);
400                 put32(l);
401         }
402 }
403
404 void
405 C_pt_doff(l, v)
406         label l;
407         arith v;
408 {
409         if (v == 0) {
410                 C_pt_dlb(l);
411         }
412         else    {
413                 put8(sp_doff);
414                 C_pt_dlb(l);
415                 C_pt_cst(v);
416         }
417 }
418
419 void
420 C_pt_str(s)
421         register char *s;
422 {
423         register int len;
424
425         C_pt_cst((arith) (len = strlen(s)));
426         while (--len >= 0) {
427                 put8(*s++);
428         }
429 }
430
431 void
432 C_pt_dnam(s)
433         char *s;
434 {
435         put8(sp_dnam);
436         C_pt_str(s);
437 }
438
439 void
440 C_pt_noff(s, v)
441         char *s;
442         arith v;
443 {
444         if (v == 0) {
445                 C_pt_dnam(s);
446         }
447         else    {
448                 put8(sp_doff);
449                 C_pt_dnam(s);
450                 C_pt_cst(v);
451         }
452 }
453
454 void
455 C_pt_pnam(s)
456         char *s;
457 {
458         put8(sp_pnam);
459         C_pt_str(s);
460 }
461
462 void
463 C_pt_wcon(sp, v, sz)    /* sp_icon, sp_ucon or sp_fcon with int repr    */
464         int sp;
465         char *v;
466         arith sz;
467 {
468         /* how 'bout signextension int --> long ???     */
469         put8(sp);
470         C_pt_cst(sz);
471         C_pt_str(v);
472 }
473
474 void
475 C_pt_scon(b, n)
476         register char *b;
477         register arith n;
478 {
479         put8(sp_scon);
480         C_pt_cst(n);
481         while (--n >= 0) {
482                 put8(*b++);
483         }
484 }
485 #endif /* READABLE_EM */