Pristine Ack-5.5
[Ack-5.5.git] / lang / occam / comp / em.c
1 /* $Id: em.c,v 1.12 1994/06/24 12:26:49 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 #include "sizes.h"
7 #include "Lpars.h"
8 #include <em.h>
9 #include "em.h"
10
11 /* This file is used to shield code.c as much as possible from em dependant
12  * details.  It introduces some call overhead but not enough for a coffee
13  * break. (Sorry)
14  * Note that functions with a leading upper case letter normally decide between
15  * word or double word arith.
16  */
17
18 int wz = 4, pz = 4, vz = 4;
19 int Lflag;
20 static Lab=0;
21 char *Malloc();
22
23 void init()
24 {
25         C_init((arith) wz, (arith) pz);
26 }
27
28 void openfile(file) char *file;
29 {
30         if (C_open(file) < 0) {
31                 fatal("Could not open output file");
32         }
33 }
34
35 void meswp()
36 {
37         C_ms_emx((arith) wz, (arith) pz);
38 }
39
40 void maxdes()
41 {
42         long max = (1L << (8*wz-1)) - 1;
43         C_df_dnam("maxcdes");
44         rom(wz, 0L); rom(wz, max); rom(wz, (long) (wz+vz));
45         C_df_dnam("maxwdes");
46         rom(wz, 0L); rom(wz, max); rom(wz, (long) vz);
47         C_df_dnam("maxbdes");
48         rom(wz, 0L); rom(wz, max); rom(wz, 1L);
49 }
50
51 int new_label(L) register *L;
52 {
53         if (*L==0) *L= ++Lab;
54         return *L;
55 }
56
57 void Label(L) register L;
58 {
59         if (L!=0) C_df_ilb((label) L);
60 }
61
62 static Dot_label=0;
63
64 int new_dot_label(L) int *L;
65 {
66         return *L= ++Dot_label;
67 }
68
69 void dot_label(L) int L;
70 {
71         C_df_dlb((label) L);
72 }
73
74 void branch(L) int *L;
75 {
76         C_bra((label) new_label(L));
77 }
78
79 char *proc_label(L, name) register L; register char *name;
80 {
81         static char *lab=nil;
82         register char *n;
83
84         if (lab!=nil) free(lab);
85
86         lab=Malloc(strlen(name)+(1+sizeof(int)*3+1));
87                 /* That is: P<L><name>\0 */
88
89         sprint(lab, "P%d", L);
90
91         n=lab+strlen(lab);
92
93         while (*name!=0) {
94                 *n++ = *name=='.' ? '_' : *name;
95                 name++;
96         }
97         *n=0;
98         return lab;
99 }
100
101 void magic()    /* magic? should be called invisible */
102 {
103         C_magic();
104 }
105
106 void cwv()
107 {
108         if (vz>wz) {
109                 C_loc((arith) wz);
110                 C_loc((arith) vz);
111                 C_cii();
112         }
113 }
114
115 void cvw()
116 {
117         if (vz>wz) {
118                 C_loc((arith) vz);
119                 C_loc((arith) wz);
120                 C_cii();
121         }
122 }
123
124 void Loc(cst) long cst;
125 {
126         if (vz>wz) C_ldc((arith) cst); else C_loc((arith) cst);
127 }
128
129 void Lol(offset) int offset;
130 {
131         if (vz>wz) C_ldl((arith) offset); else C_lol((arith) offset);
132 }
133
134 void Lolp(offset) int offset;
135 {
136         if (pz>wz) C_ldl((arith) offset); else C_lol((arith) offset);
137 }
138
139 void Lil(offset) register offset;
140 {
141         if (vz>wz) {
142                 Lolp(offset);
143                 C_loi((arith) vz);
144         } else
145                 C_lil((arith) offset);
146 }
147
148 void Lof(offset) int offset;
149 {
150         if (vz>wz) C_ldf((arith) offset); else C_lof((arith) offset);
151 }
152
153 void Lofp(offset) int offset;
154 {
155         if (pz>wz) C_ldf((arith) offset); else C_lof((arith) offset);
156 }
157
158 void Lif(offset) register offset;
159 {
160         Lofp(offset);
161         C_loi((arith) vz);
162 }
163
164 void Stl(offset) int offset;
165 {
166         if (vz>wz) C_sdl((arith) offset); else C_stl((arith) offset);
167 }
168
169 void Inl(offset) register offset;
170 {
171         if (vz>wz) {
172                 C_ldl((arith) offset);
173                 C_ldc((arith) 1);
174                 C_adi((arith) vz);
175                 C_sdl((arith) offset);
176         } else
177                 C_inl((arith) offset);
178 }
179
180 void Del(offset) register offset;
181 {
182         if (vz>wz) {
183                 C_ldl((arith) offset);
184                 C_ldc((arith) 1);
185                 C_sbi((arith) vz);
186                 C_sdl((arith) offset);
187         } else
188                 C_del((arith) offset);
189 }
190
191 void Loe(name, offset) char *name; int offset;
192 {
193         if (vz>wz)
194                 C_lde_dnam(name, (arith) offset);
195         else
196                 C_loe_dnam(name, (arith) offset);
197 }
198
199 static int operators[]= { '<', '>', '=',  GE,  LE,  NE };
200
201 void bxx(pos, op, L) register pos, op, L;
202 {
203         register i;
204
205         if (op==AFTER) {
206                 C_sbi((arith) vz);
207                 if (vz>wz) {
208                         C_ldc((arith) 0);
209                         C_cmi((arith) vz);
210                 }
211                 if (pos) C_zle((label) L); else C_zgt((label) L);
212         } else {
213                 for (i=0; operators[i]!=op; i++) ;
214                 if (pos && (i+=3)>=6) i-=6;
215                 if (vz>wz) {
216                         C_cmi((arith) vz);
217                         switch(i) {
218                         case 0:
219                                 C_zlt((label) L);
220                                 break;
221                         case 1:
222                                 C_zgt((label) L);
223                                 break;
224                         case 2:
225                                 C_zeq((label) L);
226                                 break;
227                         case 3:
228                                 C_zge((label) L);
229                                 break;
230                         case 4:
231                                 C_zle((label) L);
232                                 break;
233                         case 5:
234                                 C_zne((label) L);
235                                 break;
236                         }
237                 } else {
238                         switch(i) {
239                         case 0:
240                                 C_blt((label) L);
241                                 break;
242                         case 1:
243                                 C_bgt((label) L);
244                                 break;
245                         case 2:
246                                 C_beq((label) L);
247                                 break;
248                         case 3:
249                                 C_bge((label) L);
250                                 break;
251                         case 4:
252                                 C_ble((label) L);
253                                 break;
254                         case 5:
255                                 C_bne((label) L);
256                                 break;
257                         }
258                 }
259         }
260 }
261
262 void Txx(op) register int op;
263 {
264         switch(op) {
265         case '<':
266                 C_tlt();
267                 break;
268         case '>':
269                 C_tgt();
270                 break;
271         case '=':
272                 C_teq();
273                 break;
274         case GE:
275                 C_tge();
276                 break;
277         case LE:
278                 C_tle();
279                 break;
280         case NE:
281                 C_tne();
282                 break;
283         }
284         cwv();
285         C_ngi((arith) vz);
286 }
287
288 void xxi(op) register op;
289 {
290         switch(op) {
291         case '+':
292                 C_adi((arith) vz);
293                 break;
294         case '-':
295                 C_sbi((arith) vz);
296                 break;
297         case '*':
298                 C_mli((arith) vz);
299                 break;
300         case '/':
301                 C_dvi((arith) vz);
302                 break;
303         case BS:
304                 C_rmi((arith) vz);
305                 break;
306         }
307 }
308
309 void aar()                      {       C_aar((arith) wz); }
310 void adp(offset) int offset;    {       C_adp((arith) offset); }
311 void and()                      {       C_and((arith) vz); }
312 void asp(size) int size;        {       C_asp((arith) size); }
313 void blm(size) int size;        {       C_blm((arith) size); }
314 void blt(lab) int lab;          {       C_blt((label) lab); }
315 void cal(lab) char *lab;        {       C_cal(lab); }
316 void cmi()                      {       C_cmi((arith) vz); }
317 void com()                      {       C_com((arith) vz); }
318 void del(offset) int offset;    {       C_del((arith) offset); }
319 void x_end(size) int size;      {       C_end((arith) size); }
320 void exp(lab) char *lab;        {       C_exp(lab); }
321 void ior()                      {       C_ior((arith) vz); }
322 void lae(lab, offset) char *lab; int offset;
323                                 {       C_lae_dnam(lab, (arith) offset); }
324 void laedot(lab) int lab;       {       C_lae_dlb((label) lab, (arith) 0); }
325 void lal(offset) int offset;    {       C_lal((arith) offset); }
326 void lar()                      {       C_lar((arith) wz); }
327 void ldc0()                     {       C_ldc((arith) 0); }
328 void ldl(offset) int offset;    {       C_ldl((arith) offset); }
329 void lfr(size) int size;        {       C_lfr((arith) size); }
330 void loc(cst) int cst;          {       C_loc((arith) cst); }
331 void loi(size) int size;        {       C_loi((arith) size); }
332 void lol(offset) int offset;    {       C_lol((arith) offset); }
333 void lor0()                     {       C_lor((arith) 0); }
334 void lxa(offset) int offset;    {       C_lxa((arith) offset); }
335 void lxl(offset) int offset;    {       C_lxl((arith) offset); }
336 void meserr()                   {       C_ms_err(); }
337 void ngi()                      {       C_ngi((arith) vz); }
338 void pro(lab) char *lab;        {       C_pro_narg(lab); }
339 void ret(size) int size;        {       C_ret((arith) size); }
340 void init_rt()                  {       C_cal("init");  }
341 void sli()                      {       C_sli((arith) vz); }
342 void sri()                      {       C_sri((arith) vz); }
343 void ste(lab, offset) char *lab; int offset;
344                                 {       C_ste_dnam(lab, (arith) offset); }
345 void sti(size) int size;        {       C_sti((arith) size); }
346 void stl(offset) int offset;    {       C_stl((arith) offset); }
347 void trp()                      {       C_trp(); }
348 void tst()                      {       /* No flags in EM */ }
349 void xor()                      {       C_xor((arith) vz); }
350 void zeq(lab) int lab;          {       C_zeq((label) lab); }
351 void zgt(lab) int lab;          {       C_zgt((label) lab); }
352 void zlt(lab) int lab;          {       C_zlt((label) lab); }
353 void zne(lab) int lab;          {       C_zne((label) lab); }
354
355 char *itoa(i) long i;
356 {
357         static char a[sizeof(long)*3];
358         sprint(a, "%ld", i);
359         return a;
360 }
361
362 void rom(size, c) int size; long c;
363 {
364         C_rom_icon(itoa(c), (arith) size);
365 }
366
367 void lin()
368 {
369         static oldline=0;
370         extern lineno;
371
372         if (Lflag) return;
373         if (lineno!=oldline)
374                 C_lin((arith) (oldline=lineno));
375 }
376
377 static struct ftree {
378         char *file;
379         int lab;
380         struct ftree *left, *right;
381 } std_f = { "stdin", 0, nil, nil }, *curr_f= &std_f, *main_f=nil;
382
383 char *curr_file="stdin";
384
385 static void do_fil(f) struct ftree *f;
386 {
387         if (Lflag) return;
388         if (f->lab==0) {
389                 dot_label(new_dot_label(&f->lab));
390                 C_rom_scon(f->file, (arith) (strlen(f->file)+1));
391         }
392         C_fil_dlb((label) f->lab, (arith) 0);
393 }
394
395 void fil()
396 {
397         do_fil(curr_f);
398 }
399
400 void main_fil()
401 {
402         do_fil(main_f==nil ? &std_f : main_f);
403 }
404
405 int set_file(f) char *f;
406 {
407         char *strcpy();
408         static struct ftree *ftop=nil;
409         register struct ftree *pf, **apf= &ftop;
410         register cmp;
411
412         while ((pf= *apf)!=nil && (cmp=strcmp(f, pf->file))!=0)
413                 apf= cmp<0 ? &pf->left : &pf->right;
414
415         if (pf==nil) {
416                 *apf= pf= (struct ftree *) Malloc(sizeof *pf);
417                 pf->file=strcpy(Malloc(strlen(f)+1), f);
418                 pf->lab=0;
419                 pf->left=pf->right=nil;
420         }
421         curr_f=pf;
422         curr_file=pf->file;
423         if (main_f==nil) {
424                 main_f=curr_f;
425                 return 0;
426         } else
427                 return curr_f!=main_f;
428 }
429
430 void par_begin()
431 {
432         C_zer((arith) pz);
433         C_lal((arith) curr_offset);
434         C_cal("pc_begin");
435         C_asp((arith) (2*pz));
436 }
437
438 void par_fork(NONZERO) int *NONZERO;
439 {
440         C_zer((arith) pz);
441         C_cal("pc_fork");
442         C_asp((arith) pz);
443         C_lfr((arith) wz);
444         C_zne((label) new_label(NONZERO));
445 }
446
447 void resumenext()
448 {
449         C_cal("resumenext");
450 }
451
452 void no_deadlock()
453 {
454         C_zre_dnam("deadlock", (arith) 0);
455 }
456
457 void par_end()
458 {
459         C_cal("parend");
460 }
461
462 void closefile()
463 {
464         C_close();
465 }