Pristine Ack-5.5
[Ack-5.5.git] / modules / src / read_em / mkcalls.c
1 /* $Id: mkcalls.c,v 1.17 1994/06/24 11:21:18 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 /*      makecalls: expand a datastructure as delivered by "EM_getline"
7         into calls to the procedural interface.
8         Exported routine:
9                 EM_mkcalls
10 */
11
12 #include <em_spec.h>
13 #include <em_mnem.h>
14 #include <em_pseu.h>
15 #include <em_flag.h>
16 #include "em_ptyp.h"
17 #include <em.h>
18 #include "em_comp.h"
19 #include <assert.h>
20
21 extern char em_flag[];  /* One per EM instruction: indicates parameter kind */
22 extern short em_ptyp[]; /* One per parameter kind: indicates parameter type */
23
24 static int listtype = 0;        /* indicates pseudo when generating code for
25                                    variable length argument lists
26                                    (only for MES)
27                                 */
28
29 #ifdef CHECKING
30 /*      c_getarg: Check the argument indicated by "args".
31         The argument must be of a type allowed by "typset".
32         Return a pointer to the next argument.
33 */
34 PRIVATE int
35 checkarg(arg, typset)
36         register struct e_arg *arg;
37 {
38
39         if (((!typset) && arg->ema_argtype) ||
40             ((!arg->ema_argtype) && typset)) {
41                 /* End of arguments expected, but there are more, or
42                    an argument expected, but there is none
43                 */
44                 EM_error = "Illegal number of parameters";
45                 return 0;
46         }
47
48         if (!(arg->ema_argtype & typset)) {
49                 /* Type error */
50                 EM_error = "Illegal parameter type";
51                 return 0;
52         }
53         return 1;
54 }
55 #else /* not CHECKING */
56 #define checkarg(arg, x) 1
57 #endif /* CHECKING */
58
59 /*      EM_doinstr: An EM instruction
60 */
61 PRIVATE void
62 EM_doinstr(p)
63         register struct e_instr *p;
64 {
65         register int parametertype;     /* parametertype of the instruction */
66
67         parametertype = em_flag[p->em_opcode-sp_fmnem] & EM_PAR;
68 #ifdef CHECKING
69         if (parametertype != PAR_NO && parametertype != PAR_W) {
70                 if (p->em_argtype == 0) {
71                         EM_error = "Illegal number of parameters";
72                         return;
73                 }
74         }
75 #endif /* CHECKING */
76         switch(parametertype) {
77                 case PAR_NO:
78                         break;
79                 default:
80                         if (! checkarg(&(p->em_arg), em_ptyp[parametertype])) {
81                                 return;
82                         }
83                         break;
84                 case PAR_W:
85                         if (p->em_argtype != 0) {
86                                 if (! checkarg(&(p->em_arg), cst_ptyp)) return;
87                         }
88                         else {
89 #include "C_mnem_narg"
90                                 return;
91                         }
92                         break;
93         }
94 #include "C_mnem"
95 }
96
97 PRIVATE void
98 EM_dopseudo(p)
99         register struct e_instr *p;
100 {
101
102         switch(p->em_opcode) {
103                 case ps_exc: {
104                         C_exc(p->em_exc1, p->em_exc2);
105                         break;
106                 }
107                 case ps_hol: {
108                         if (! checkarg(&(p->em_arg), par_ptyp)) break;
109                         switch(p->em_argtype) {
110                             case cst_ptyp:
111                                 C_hol_cst(EM_holsize,
112                                           p->em_cst,
113                                           EM_holinit);
114                                 break;
115                             case ico_ptyp:
116                                 C_hol_icon(EM_holsize,
117                                            p->em_string,
118                                            p->em_size, 
119                                            EM_holinit);
120                                 break;
121                             case uco_ptyp:
122                                 C_hol_ucon(EM_holsize,
123                                            p->em_string,
124                                            p->em_size,
125                                            EM_holinit);
126                                 break;
127                             case fco_ptyp:
128                                 C_hol_fcon(EM_holsize,
129                                            p->em_string,
130                                            p->em_size, 
131                                            EM_holinit);
132                                 break;
133                             case sof_ptyp:
134                                 C_hol_dnam(EM_holsize,
135                                            p->em_dnam,
136                                            p->em_off, 
137                                            EM_holinit);
138                                 break;
139                             case nof_ptyp:
140                                 C_hol_dlb(EM_holsize,
141                                           p->em_dlb,
142                                           p->em_off, 
143                                           EM_holinit);
144                                 break;
145                             case ilb_ptyp:
146                                 C_hol_ilb(EM_holsize,
147                                           p->em_ilb, 
148                                           EM_holinit);
149                                 break;
150                             case pro_ptyp:
151                                 C_hol_pnam(EM_holsize,
152                                            p->em_pnam, 
153                                            EM_holinit);
154                                 break;
155                             default:
156                                 EM_error = "Illegal parameter type";
157                                 break;
158                         }
159                         break;
160                 }
161                 case ps_bss: {
162                         if (! checkarg(&(p->em_arg), par_ptyp)) break;
163                         switch(p->em_argtype) {
164                             case cst_ptyp:
165                                 C_bss_cst(EM_bsssize,
166                                           p->em_cst,
167                                           EM_bssinit);
168                                 break;
169                             case ico_ptyp:
170                                 C_bss_icon(EM_bsssize,
171                                            p->em_string,
172                                            p->em_size, 
173                                            EM_bssinit);
174                                 break;
175                             case uco_ptyp:
176                                 C_bss_ucon(EM_bsssize,
177                                            p->em_string,
178                                            p->em_size,
179                                            EM_bssinit);
180                                 break;
181                             case fco_ptyp:
182                                 C_bss_fcon(EM_bsssize,
183                                            p->em_string,
184                                            p->em_size, 
185                                            EM_bssinit);
186                                 break;
187                             case sof_ptyp:
188                                 C_bss_dnam(EM_bsssize,
189                                            p->em_dnam,
190                                            p->em_off, 
191                                            EM_bssinit);
192                                 break;
193                             case nof_ptyp:
194                                 C_bss_dlb(EM_bsssize,
195                                           p->em_dlb,
196                                           p->em_off, 
197                                           EM_bssinit);
198                                 break;
199                             case ilb_ptyp:
200                                 C_bss_ilb(EM_bsssize,
201                                           p->em_ilb, 
202                                           EM_bssinit);
203                                 break;
204                             case pro_ptyp:
205                                 C_bss_pnam(EM_bsssize, 
206                                            p->em_pnam, 
207                                            EM_bssinit);
208                                 break;
209                             default:
210                                 EM_error = "Illegal parameter type";
211                                 break;
212                         }
213                         break;
214                 }
215                 case ps_end:
216                         if (p->em_argtype != 0) {
217                                 if (! checkarg(&(p->em_arg), cst_ptyp)) break;
218                                 C_end(p->em_cst);
219                                 break;
220                         }
221                         C_end_narg();
222                         break;
223                 case ps_exa:
224                 case ps_ina:
225                         if (! checkarg(&(p->em_arg), lab_ptyp)) break;
226                         if (p->em_argtype == nof_ptyp) {
227                                 if (p->em_opcode == ps_exa) {
228                                         C_exa_dlb(p->em_dlb);
229                                 }
230                                 else    C_ina_dlb(p->em_dlb);
231                                 break;
232                         }
233                         if (p->em_opcode == ps_exa) {
234                                 C_exa_dnam(p->em_dnam);
235                         }
236                         else    C_ina_dnam(p->em_dnam);
237                         break;
238                 case ps_exp:
239                         if (! checkarg(&(p->em_arg), pro_ptyp)) break;
240                         C_exp(p->em_pnam);
241                         break;
242                 case ps_inp:
243                         if (! checkarg(&(p->em_arg), pro_ptyp)) break;
244                         C_inp(p->em_pnam);
245                         break;
246                 case ps_pro:
247                         if (! checkarg(&(p->em_arg), pro_ptyp)) break;
248                         if (p->em_nlocals >= 0) {
249                                 C_pro(p->em_pnam, p->em_nlocals);
250                         }
251                         else    C_pro_narg(p->em_pnam);
252                         break;
253                 case ps_con:
254                         if (! checkarg(&(p->em_arg), val_ptyp)) break;
255                         switch(p->em_argtype) {
256                                 case ilb_ptyp:
257                                         C_con_ilb(p->em_ilb);
258                                         break;
259                                 case nof_ptyp:
260                                         C_con_dlb(p->em_dlb, p->em_off);
261                                         break;
262                                 case sof_ptyp:
263                                         C_con_dnam(p->em_dnam, p->em_off);
264                                         break;
265                                 case cst_ptyp:
266                                         C_con_cst(p->em_cst);
267                                         break;
268                                 case pro_ptyp:
269                                         C_con_pnam(p->em_pnam);
270                                         break;
271                                 case str_ptyp:
272                                         C_con_scon(p->em_string, p->em_size);
273                                         break;
274                                 case ico_ptyp:
275                                         C_con_icon(p->em_string, p->em_size);
276                                         break;
277                                 case uco_ptyp:
278                                         C_con_ucon(p->em_string, p->em_size);
279                                         break;
280                                 case fco_ptyp:
281                                         C_con_fcon(p->em_string, p->em_size);
282                                         break;
283                                 default:
284                                         EM_error = "Illegal argument type";
285                                         return;
286                         }
287                         break;
288                 case ps_rom:
289                         if (! checkarg(&(p->em_arg), val_ptyp)) break;
290                         switch(p->em_argtype) {
291                                 case ilb_ptyp:
292                                         C_rom_ilb(p->em_ilb);
293                                         break;
294                                 case nof_ptyp:
295                                         C_rom_dlb(p->em_dlb, p->em_off);
296                                         break;
297                                 case sof_ptyp:
298                                         C_rom_dnam(p->em_dnam, p->em_off);
299                                         break;
300                                 case cst_ptyp:
301                                         C_rom_cst(p->em_cst);
302                                         break;
303                                 case pro_ptyp:
304                                         C_rom_pnam(p->em_pnam);
305                                         break;
306                                 case str_ptyp:
307                                         C_rom_scon(p->em_string, p->em_size);
308                                         break;
309                                 case ico_ptyp:
310                                         C_rom_icon(p->em_string, p->em_size);
311                                         break;
312                                 case uco_ptyp:
313                                         C_rom_ucon(p->em_string, p->em_size);
314                                         break;
315                                 case fco_ptyp:
316                                         C_rom_fcon(p->em_string, p->em_size);
317                                         break;
318                                 default:
319                                         EM_error = "Illegal argument type";
320                                         return;
321                         }
322                         break;
323                 default: 
324                         EM_error = "Illegal pseudo instruction";
325                         break;
326         }
327 }
328
329 PRIVATE void
330 EM_docon(p)
331         register struct e_instr *p;
332 {
333         checkarg(&(p->em_arg), val_ptyp);
334         switch(p->em_argtype) {
335                 case ilb_ptyp:
336                         C_ilb(p->em_ilb);
337                         break;
338                 case nof_ptyp:
339                         C_dlb(p->em_dlb, p->em_off);
340                         break;
341                 case sof_ptyp:
342                         C_dnam(p->em_dnam, p->em_off);
343                         break;
344                 case cst_ptyp:
345                         C_cst(p->em_cst);
346                         break;
347                 case pro_ptyp:
348                         C_pnam(p->em_pnam);
349                         break;
350                 case str_ptyp:
351                         C_scon(p->em_string, p->em_size);
352                         break;
353                 case ico_ptyp:
354                         C_icon(p->em_string, p->em_size);
355                         break;
356                 case uco_ptyp:
357                         C_ucon(p->em_string, p->em_size);
358                         break;
359                 case fco_ptyp:
360                         C_fcon(p->em_string, p->em_size);
361                         break;
362                 default:
363                         EM_error = "Illegal argument type";
364                         break;
365         }
366 }
367
368 PRIVATE void
369 EM_dostartmes(p)
370         register struct e_instr *p;
371 {
372
373         if (listtype) {
374                 EM_error = "Message not ended";
375                 return;
376         }
377         if (! checkarg(&(p->em_arg), cst_ptyp)) return;
378         C_mes_begin((int) (p->em_cst));
379         listtype = ps_mes;
380 }
381
382 EXPORT int
383 EM_mkcalls(line)
384         register struct e_instr *line;
385 {
386
387 #ifdef CHECKING
388         if (listtype && line->em_type != EM_MESARG && line->em_type != EM_ENDMES) {
389                 EM_error = "Message not ended";
390                 return 0;
391         }
392 #endif /* CHECKING */
393         EM_error = 0;
394         switch(line->em_type) {
395                 default:
396                         EM_error = "Illegal EM line";
397                         break;
398                 case EM_MNEM:
399                         /* normal instruction */
400                         EM_doinstr(line);
401                         break;
402                 case EM_DEFILB:
403                         /* defining occurrence of an instruction label */
404                         C_df_ilb(line->em_ilb);
405                         break;
406                 case EM_DEFDLB:
407                         /* defining occurrence of a global data label */
408                         C_df_dlb(line->em_dlb);
409                         break;
410                 case EM_DEFDNAM:
411                         /* defining occurrence of a non-numeric data label */
412                         C_df_dnam(line->em_dnam);
413                         break;
414                 case EM_PSEU:
415                         /* pseudo */
416                         EM_dopseudo(line);
417                         break;
418                 case EM_STARTMES:
419                         /* start of a MES pseudo */
420                         EM_dostartmes(line);
421                         break;
422                 case EM_MESARG:
423                 case EM_ENDMES:
424 #ifdef CHECKING
425                         if (!listtype) {
426                                 EM_error = "Message not started";
427                                 return 0;
428                         }
429 #endif
430                         if (line->em_type == EM_MESARG) {
431                                 EM_docon(line);
432                                 break;
433                         }
434                         C_mes_end();
435                         listtype = 0;
436                         break;
437         }
438         if (EM_error) return 0;
439         return 1;
440 }